Reworked AT queuing, with queues for send, recv, async recv and sync recv
[hayes-ril.git] / at.c
1 /*
2  * This file is part of hayes-ril.
3  *
4  * Copyright (C) 2012 Paul Kocialkowski <contact@paulk.fr>
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 #include <string.h>
20 #include <ctype.h>
21
22 #define LOG_TAG "RIL-AT"
23 #include <utils/Log.h>
24
25 #include <hayes-ril.h>
26
27 /*
28  * Globals
29  */
30
31 struct at_handling at_handling;
32
33 /*
34  * Utilities
35  */
36
37 int at_strings_compare(char *major, char *minor)
38 {
39         int major_length = strlen(major);
40         int minor_length = strlen(minor);
41
42         // We can't check against the whole major string
43         if(major_length > minor_length)
44                 return 0;
45
46         if(strncmp(major, minor, major_length) == 0)
47                 return 1;
48         else
49                 return 0;
50 }
51
52 int at_strings_raw_compare(char *major, char *minor)
53 {
54         int major_length = strlen(major);
55
56         // Only consider major length (minor might not have \0)
57         if(strncmp(major, minor, major_length) == 0)
58                 return 1;
59         else
60                 return 0;
61 }
62
63 // Major is response string, minor is request (reference) string
64 int at_commands_compare(char *major, char *minor)
65 {
66         int rc;
67
68         // Assume major is corect
69
70         if(at_strings_compare(major, minor))
71                 return 1;
72
73         // Compare without AT prefix
74         if(at_strings_compare("AT", minor) && !at_strings_compare("AT", major) && strlen(minor) > 2)
75                 return at_strings_compare(major, minor + 2);
76
77         if(at_strings_compare("AT", major) && !at_strings_compare("AT", minor) && strlen(major) > 2)
78                 return at_strings_compare(major + 2, minor);
79
80         return 0;
81 }
82
83 void at_string_clean(char *string, int length)
84 {
85         int i=0;
86
87         for(i=length-1; i >= 0 ; i--) {
88                 if(!isprint(string[i]))
89                         string[i] = '\0';
90         }
91 }
92
93 int at_status_error(int status)
94 {
95         switch(status) {
96                 case AT_STATUS_CONNECT:
97                         return 0;
98                 case AT_STATUS_OK:
99                         return 0;
100                 default:
101                         return 1;
102         }
103 }
104
105 /*
106  * Line parsers
107  */
108
109 int at_line_parse_status(char *data, int length, char **error_p)
110 {
111         char *response_command = NULL;
112         char *response_error = NULL;
113         int response_error_length = 0;
114
115         *error_p = NULL;
116
117         if(at_strings_compare("OK", data)) {
118                 *error_p = NULL;
119                 return AT_STATUS_OK;
120         }
121
122         if(at_strings_compare("CONNECT", data)) {
123                 *error_p = NULL;
124                 return AT_STATUS_CONNECT;
125         }
126
127         if(at_strings_compare("ERROR", data)) {
128                 *error_p = NULL;
129                 return AT_STATUS_ERROR;
130         }
131
132         if(at_strings_compare("+CME ERROR", data)) {
133                 response_error_length = at_line_parse_command_data(data, length, &response_command, &response_error);
134                 if(response_error != NULL && response_error_length > 0) {
135                         at_string_clean(response_error, strlen(response_error) + 1);
136                         *error_p = response_error;
137                 }
138
139                 if(response_command != NULL)
140                         free(response_command);
141
142                 return AT_STATUS_CME_ERROR;
143         }
144
145         return AT_STATUS_UNDEF;
146 }
147
148 int at_line_parse_command_data(char *data, int length, char **response_command, char **response_data)
149 {
150         char *string = NULL;
151         int string_length = 0;
152         int close_your_eyes = 0;
153         int mark = 0;
154         int i;
155
156
157         for(i=0 ; i < length ; i++) {
158                 if(data[i] == ':' && mark == 0) {
159                         if(i > 0) {
160                                 data[i] = '\0';
161
162                                 string_length = i + 1;
163                                 string = strndup(data, string_length);
164
165                                 if(!isprint(string[0])) {
166                                         free(string);
167                                 } else {
168                                         *response_command = string;
169                                 }
170
171                                 mark = i + 1;
172                         }
173
174                         while(isspace(data[i+1])) {
175                                 mark = i + 2;
176                                 i++;
177                         }
178                 }
179
180                 if(data[i] == '"') {
181                         if(close_your_eyes & AT_PARSE_DOUBLE_QUOTE)
182                                 close_your_eyes &= ~AT_PARSE_DOUBLE_QUOTE;
183                         else
184                                 close_your_eyes |= AT_PARSE_DOUBLE_QUOTE;
185                 }
186
187                 if(data[i] == '\'') {
188                         if(close_your_eyes & AT_PARSE_SINGLE_QUOTE)
189                                 close_your_eyes &= ~AT_PARSE_SINGLE_QUOTE;
190                         else
191                                 close_your_eyes |= AT_PARSE_SINGLE_QUOTE;
192                 }
193
194                 // Found = or ? outside of any quotes: assume no data
195                 if(!close_your_eyes && (data[i] == '=' || data[i] == '?') && mark == 0) {
196                         data[i] = '\0';
197
198                         string_length = i + 1;
199                         string = strndup(data, string_length);
200
201                         if(!isprint(string[0])) {
202                                 free(string);
203                         } else {
204                                 *response_command = string;
205                         }
206
207                         return 0;
208                 }
209         }
210
211
212         if(length - mark > 0) {
213                 string_length = length - mark;
214                 string = strndup(data + mark, string_length);
215
216                 if(mark == 0) {
217                         *response_command = string;
218                         return 0;
219                 } else {
220                         *response_data = string;
221                         return string_length;
222                 }
223         }
224
225         return 0;
226 }
227
228 /*
229  * Responses line processor
230  */
231
232 int at_responses_process_line(struct at_response ***responses_p, int responses_count, char *data, int length)
233 {
234         struct at_response **responses = NULL;
235
236         char *response_command = NULL;
237         char *response_data = NULL;
238         int response_data_length = 0;
239         char *response_error = NULL;
240         int response_status = 0;
241
242         char **response_previous_data = NULL;
243         int response_data_count = 0;
244
245         int index = -1;
246         int count = 0;
247         int i;
248
249         if(responses_p == NULL || data == NULL || length < 0) {
250                 LOGE("Failed to process AT response: wrong arguments!");
251                 return 0;
252         }
253
254         responses = *responses_p;
255
256         // Parse status
257         response_status = at_line_parse_status(data, length, &response_error);
258
259         if(response_status != AT_STATUS_UNDEF) {
260                 if(responses_count > 0 && responses != NULL) {
261                         for(i=responses_count-1 ; i >= 0; i--) {
262                                 if(responses[i]->status == AT_STATUS_UNDEF) {
263                                         responses[i]->status = response_status;
264                                         responses[i]->error = response_error;
265
266                                         // Do not alloc a new response
267                                         if(index == -1)
268                                                 index = i;
269                                 }
270                         }
271                 }
272
273                 // Alloc a new response
274                 if(index == -1) {
275                         // Index is the request index in the requests array
276                         index = responses_count;
277                         // Count is the total count of requests in the array
278                         count = index + 1;
279
280                         // Alloc the array with the new size
281                         *responses_p = malloc(sizeof(struct at_response *) * count);
282
283                         // Copy and free previous data
284                         if(responses != NULL) {
285                                 memcpy(*responses_p, responses, sizeof(struct at_response *) * responses_count);
286                                 free(responses);
287                         }
288
289                         responses = *responses_p;
290
291                         // Alloc new structure and copy obtained data
292                         responses[index] = calloc(1, sizeof(struct at_response));
293                         responses[index]->status = response_status;
294                         responses[index]->error = response_error;
295                 }
296         } else {
297                 // Parse command and data
298                 response_data_length = at_line_parse_command_data(data, length, &response_command, &response_data);
299
300                 if(response_command == NULL) {
301                         LOGE("Failed to parse command!");
302                         return responses_count;
303                 }
304
305                 at_string_clean(response_command, strlen(response_command) + 1);
306
307                 if(responses_count > 0 && responses != NULL) {
308                         for(i=responses_count-1 ; i >= 0; i--) {
309                                 if(responses[i]->command != NULL) {
310                                         if(at_commands_compare(responses[i]->command, response_command))
311                                                 // Do not alloc a new response
312                                                 index = i;
313                                 }
314                         }
315                 }
316
317                 // Alloc a new response
318                 if(index == -1) {
319                         // Index is the request index in the requests array
320                         index = responses_count;
321                         // Count is the total count of requests in the array
322                         count = index + 1;
323
324                         // Alloc the array with the new size
325                         *responses_p = malloc(sizeof(struct at_response *) * count);
326
327                         // Copy and free previous data
328                         if(responses != NULL) {
329                                 memcpy(*responses_p, responses, sizeof(struct at_response *) * responses_count);
330                                 free(responses);
331                         }
332
333                         responses = *responses_p;
334
335                         // Alloc new structure and copy obtained data
336                         responses[index] = calloc(1, sizeof(struct at_response));
337                         responses[index]->command = response_command;
338                         responses[index]->status = AT_STATUS_UNDEF;
339                 }
340
341                 if(response_data_length > 0 && response_data != NULL) {
342                         at_string_clean(response_data, response_data_length);
343
344                         response_previous_data = responses[index]->data;
345
346                         // Data count is the total count of elements in the request data
347                         response_data_count = responses[index]->data_count + 1;
348
349                         // Alloc the array with the new size
350                         responses[index]->data = malloc(sizeof(char *) * response_data_count);
351
352                         // Copy and free previous data
353                         if(response_previous_data != NULL) {
354                                 memcpy(responses[index]->data, response_previous_data, sizeof(char *) * responses[index]->data_count);
355                                 free(response_previous_data);
356                         }
357
358                         responses[index]->data_count = response_data_count;
359                         responses[index]->data[response_data_count - 1] = response_data;
360                 }
361         }
362
363         return count > responses_count ? count : responses_count;
364 }
365
366 /*
367  * Responses structures processing
368  */
369
370 int at_responses_process(struct at_response ***responses_p, char *data, int length)
371 {
372         int responses_count = 0;
373         int count = 0;
374
375         char *string = NULL;
376         int string_length = 0;
377         int mark = 0;
378         int i;
379
380         if(responses_p == NULL || data == NULL || length < 0) {
381                 LOGE("Failed to process AT response: wrong arguments!");
382                 return 0;
383         }
384
385         for(i=0 ; i < length ; i++) {
386                 if(data[i] == '\r' || data[i] == ';') {
387                         if(i - mark > 0) {
388                                 data[i] = '\0';
389
390                                 string_length = i - mark + 1;
391                                 string = strndup(data + mark, string_length);
392
393                                 if(!isprint(string[0])) {
394                                         free(string);
395                                 }
396                                 else {
397                                         count = at_responses_process_line(responses_p, responses_count, string, string_length);
398                                         if(count > responses_count)
399                                                 responses_count = count;
400
401                                         free(string);
402                                 }
403
404                                 mark = i + 1;
405                         }
406
407                         while(isspace(data[i+1])) {
408                                 mark = i + 2;
409                                 i++;
410                         }
411                 }
412         }
413
414         if(length - mark > 0) {
415                 for(i=mark ; i < length ; i++)
416                         if(!isprint(data[i]))
417                                 break;
418
419                 if(i - mark > 0) {
420                         string_length = i - mark + 1;
421                         string = calloc(1, string_length);
422
423                         memcpy(string, data + mark, string_length - 1);
424                         string[string_length - 1] = '\0';
425
426                         count = at_responses_process_line(responses_p, responses_count, string , string_length);
427                         if(count > responses_count)
428                                 responses_count = count;
429
430                         free(string);
431                 }
432         }
433
434         return responses_count;
435 }
436
437 void at_response_free(struct at_response *response)
438 {
439         int i;
440
441         if(response->data_count > 0 && response->data != NULL) {
442                 for(i=0 ; i < response->data_count ; i++) {
443                         if(response->data[i] != NULL) {
444                                 free(response->data[i]);
445                                 response->data[i] = NULL;
446                         }
447                 }
448
449                 free(response->data);
450                 response->data_count = 0;
451         }
452
453         if(response->command != NULL)
454                 free(response->command);
455
456         if(response->error != NULL)
457                 free(response->error);
458
459         memset(response, 0, sizeof(struct at_response));
460
461 }
462
463 /*
464  * Handling
465  */
466
467 void at_handling_init(void)
468 {
469         memset(&at_handling, 0, sizeof(struct at_handling));
470
471         pthread_mutex_init(&(at_handling.responses_queue.queue_mutex), NULL);
472         pthread_mutex_init(&(at_handling.responses_queue.mutex), NULL);
473         pthread_mutex_init(&(at_handling.requests_queue.mutex), NULL);
474         pthread_mutex_init(&(at_handling.sync_requests_queue.queue_mutex), NULL);
475         pthread_mutex_init(&(at_handling.sync_requests_queue.mutex), NULL);
476         pthread_mutex_init(&(at_handling.async_requests_queue.mutex), NULL);
477
478         // First lock to the queues mutexes
479         AT_RESPONSES_QUEUE_LOCK();
480         AT_SYNC_QUEUE_LOCK();
481 }
482
483 /*
484  * Responses queue
485  */
486
487 // Unlock the responses queue after queuing all the available requests
488 void at_responses_queue_unlock(void)
489 {
490         if(at_handling.responses_queue.responses_count <= 0 || at_handling.responses_queue.responses == NULL)
491                 return;
492
493         AT_RESPONSES_QUEUE_UNLOCK();
494 }
495
496 // Queue one response to the responses queue
497 int at_response_queue(struct at_response *response)
498 {
499         struct at_response **responses = NULL;
500         int responses_count = 0;
501         int index;
502         int count;
503
504         if(response == NULL)
505                 return -1;
506
507         AT_RESPONSES_LOCK();
508
509         // Save the previous data pointer and count
510         responses = at_handling.responses_queue.responses;
511         responses_count = at_handling.responses_queue.responses_count;
512
513         if(responses_count < 0)
514                 responses_count = 0;
515
516         // Index is the response index in the responses array
517         index = responses_count;
518         // Count is the total count of responses in the array
519         count = index + 1;
520
521         // Alloc the array with the new size
522         at_handling.responses_queue.responses = malloc(sizeof(struct at_response *) * count);
523         at_handling.responses_queue.responses_count = count;
524
525         // Copy and free previous data
526         if(responses != NULL && responses_count > 0) {
527                 memcpy(at_handling.responses_queue.responses, responses, sizeof(struct at_response *) * at_handling.responses_queue.responses_count);
528                 free(responses);
529         }
530
531         // Get the new data pointer and count
532         responses = at_handling.responses_queue.responses;
533         responses_count = at_handling.responses_queue.responses_count;
534
535         // Put the response in the queue
536         responses[index] = response;
537
538         LOGD("%d elements in the responses queue", responses_count);
539
540         AT_RESPONSES_UNLOCK();
541
542         return 0;
543 }
544
545 // Unqueue the oldest response in the queue
546 struct at_response *at_response_dequeue(void)
547 {
548         struct at_response *response = NULL;
549         struct at_response **responses = NULL;
550         int responses_count = 0;
551         int pos = -1;
552         int i;
553
554         AT_RESPONSES_LOCK();
555
556         // Save the previous data pointer and count
557         responses = at_handling.responses_queue.responses;
558         responses_count = at_handling.responses_queue.responses_count;
559
560         while(responses_count <= 0 || responses == NULL) {
561                 LOGE("No response queued, blocking!");
562
563                 AT_RESPONSES_UNLOCK();
564                 AT_RESPONSES_QUEUE_LOCK();
565                 AT_RESPONSES_LOCK();
566
567                 // Get the new data pointer and count
568                 responses = at_handling.responses_queue.responses;
569                 responses_count = at_handling.responses_queue.responses_count;
570
571                 LOGE("Unblocking: %d new responses queued!", responses_count);
572         }
573
574         for(i=0 ; i < responses_count ; i++) {
575                 if(responses[i] != NULL) {
576                         response = responses[i];
577                         pos = i;
578                         break;
579                 }
580         }
581
582         if(response == NULL || pos < 0) {
583                 LOGD("Found no valid response, aborting!");
584
585                 AT_RESPONSES_UNLOCK();
586                 return NULL;
587         }
588
589         // Empty the found position in the responses array
590         responses[pos] = NULL;
591
592         // Move the elements back
593         for(i=pos ; i < responses_count-1 ; i++) {
594                 responses[i] = responses[i+1];
595         }
596
597         // Empty the latest element
598         if(pos != responses_count-1) {
599                 responses[responses_count-1] = NULL;
600         }
601
602         responses_count--;
603
604         if(responses_count == 0) {
605                 free(responses);
606                 at_handling.responses_queue.responses = NULL;
607         }
608
609         at_handling.responses_queue.responses_count = responses_count;
610
611         LOGD("%d elements in the responses queue", responses_count);
612
613         AT_RESPONSES_UNLOCK();
614
615         return response;
616 }
617
618 /*
619  * Requests queue
620  */
621
622 // Queue one request to the requests queue
623 int at_request_queue(struct at_request *request)
624 {
625         struct at_request **requests = NULL;
626         int requests_count = 0;
627         int index;
628         int count;
629
630         if(request == NULL)
631                 return -1;
632
633         AT_REQUESTS_LOCK();
634
635         // Save the previous data pointer and count
636         requests = at_handling.requests_queue.requests;
637         requests_count = at_handling.requests_queue.requests_count;
638
639         if(requests_count < 0)
640                 requests_count = 0;
641
642         // Index is the request index in the requests array
643         index = requests_count;
644         // Count is the total count of requests in the array
645         count = index + 1;
646
647         // Alloc the array with the new size
648         at_handling.requests_queue.requests = malloc(sizeof(struct at_request *) * count);
649         at_handling.requests_queue.requests_count = count;
650
651         // Copy and free previous data
652         if(requests != NULL && requests_count > 0) {
653                 memcpy(at_handling.requests_queue.requests, requests, sizeof(struct at_request *) * at_handling.requests_queue.requests_count);
654                 free(requests);
655         }
656
657         // Get the new data pointer and count
658         requests = at_handling.requests_queue.requests;
659         requests_count = at_handling.requests_queue.requests_count;
660
661         // Put the request in the queue
662         requests[index] = request;
663
664         LOGD("%d elements in the requests queue", requests_count);
665
666         AT_REQUESTS_UNLOCK();
667
668         return 0;
669 }
670
671 // Unqueue the oldest request in the queue
672 struct at_request *at_request_dequeue(void)
673 {
674         struct at_request *request = NULL;
675         struct at_request **requests = NULL;
676         int requests_count = 0;
677         int pos = -1;
678         int i;
679
680         AT_REQUESTS_LOCK();
681
682         // Save the previous data pointer and count
683         requests = at_handling.requests_queue.requests;
684         requests_count = at_handling.requests_queue.requests_count;
685
686         if(requests_count <= 0 || requests == NULL) {
687                 LOGE("No requests queued!");
688
689                 AT_REQUESTS_UNLOCK();
690                 return NULL;
691         }
692
693         for(i=0 ; i < requests_count ; i++) {
694                 if(requests[i] != NULL) {
695                         request = requests[i];
696                         pos = i;
697                         break;
698                 }
699         }
700
701         if(requests == NULL || pos < 0) {
702                 LOGD("Found no valid request, aborting!");
703
704                 AT_REQUESTS_UNLOCK();
705                 return NULL;
706         }
707
708         // Empty the found position in the requests array
709         requests[pos] = NULL;
710
711         // Move the elements back
712         for(i=pos ; i < requests_count-1 ; i++) {
713                 requests[i] = requests[i+1];
714         }
715
716         // Empty the latest element
717         if(pos != requests_count-1) {
718                 requests[requests_count-1] = NULL;
719         }
720
721         requests_count--;
722
723         if(requests_count == 0) {
724                 free(requests);
725                 at_handling.requests_queue.requests = NULL;
726         }
727
728         at_handling.requests_queue.requests_count = requests_count;
729
730         LOGD("%d elements in the requests queue", requests_count);
731
732         AT_REQUESTS_UNLOCK();
733
734         return request;
735 }
736
737 /*
738  * Async requests queue
739  */
740
741 // Free the async request
742 void at_async_request_free(struct at_async_request *async_request)
743 {
744         if(async_request == NULL)
745                 return;
746
747         if(async_request->command)
748                 free(async_request->command);
749
750         memset(async_request, 0, sizeof(struct at_async_request));
751         async_request->handled = AT_RESPONSE_GARBAGE;
752 }
753
754 // Find an async request from its command
755 struct at_async_request *at_async_request_find_command(char *command)
756 {
757         struct at_async_request *async_request = NULL;
758         struct at_async_request **async_requests = NULL;
759         int async_requests_count = 0;
760         int i;
761
762         if(command == NULL)
763                 return NULL;
764
765         AT_ASYNC_LOCK();
766
767         // Save the previous data pointer and count
768         async_requests = at_handling.async_requests_queue.async_requests;
769         async_requests_count = at_handling.async_requests_queue.async_requests_count;
770
771         if(async_requests_count <= 0 || async_requests == NULL) {
772                 AT_ASYNC_UNLOCK();
773                 return NULL;
774         }
775
776         for(i=0 ; i < async_requests_count ; i++) {
777                 if(async_requests[i] != NULL && async_requests[i]->command != NULL) {
778                         if(at_commands_compare(command, async_requests[i]->command)) {
779                                 async_request = async_requests[i];
780                                 break;
781                         }
782                 }
783         }
784
785         AT_ASYNC_UNLOCK();
786
787         return async_request;
788 }
789
790 // Find an async request from its handled status
791 struct at_async_request *at_async_request_find_handled(int handled)
792 {
793         struct at_async_request *async_request = NULL;
794         struct at_async_request **async_requests = NULL;
795         int async_requests_count = 0;
796         int i;
797
798         AT_ASYNC_LOCK();
799
800         // Save the previous data pointer and count
801         async_requests = at_handling.async_requests_queue.async_requests;
802         async_requests_count = at_handling.async_requests_queue.async_requests_count;
803
804         if(async_requests_count <= 0 || async_requests == NULL) {
805                 AT_ASYNC_UNLOCK();
806                 return NULL;
807         }
808
809         for(i=0 ; i < async_requests_count ; i++) {
810                 if(async_requests[i] != NULL) {
811                         if(async_requests[i]->handled == handled) {
812                                 async_request = async_requests[i];
813                                 break;
814                         }
815                 }
816         }
817
818         AT_ASYNC_UNLOCK();
819
820         return async_request;
821 }
822
823 // Find an async request from its request pointer
824 struct at_async_request *at_async_request_find_request(struct at_request *request)
825 {
826         struct at_async_request *async_request = NULL;
827         struct at_async_request **async_requests = NULL;
828         int async_requests_count = 0;
829         int i;
830
831         if(request == NULL)
832                 return NULL;
833
834         AT_ASYNC_LOCK();
835
836         // Save the previous data pointer and count
837         async_requests = at_handling.async_requests_queue.async_requests;
838         async_requests_count = at_handling.async_requests_queue.async_requests_count;
839
840         if(async_requests_count <= 0 || async_requests == NULL) {
841                 AT_ASYNC_UNLOCK();
842                 return NULL;
843         }
844
845         for(i=0 ; i < async_requests_count ; i++) {
846                 if(async_requests[i] != NULL) {
847                         if(async_requests[i]->request == request) {
848                                 async_request = async_requests[i];
849                                 break;
850                         }
851                 }
852         }
853
854         AT_ASYNC_UNLOCK();
855
856         return async_request;
857 }
858
859 // Find an async request from its response pointer
860 struct at_async_request *at_async_request_find_response(struct at_response *response)
861 {
862         struct at_async_request *async_request = NULL;
863         struct at_async_request **async_requests = NULL;
864         int async_requests_count = 0;
865         int i;
866
867         if(response == NULL)
868                 return NULL;
869
870         AT_ASYNC_LOCK();
871
872         // Save the previous data pointer and count
873         async_requests = at_handling.async_requests_queue.async_requests;
874         async_requests_count = at_handling.async_requests_queue.async_requests_count;
875
876         if(async_requests_count <= 0 || async_requests == NULL) {
877                 AT_ASYNC_UNLOCK();
878                 return NULL;
879         }
880
881         for(i=0 ; i < async_requests_count ; i++) {
882                 if(async_requests[i] != NULL && async_requests[i]->response != NULL) {
883                         if(async_requests[i]->response == response) {
884                                 async_request = async_requests[i];
885                                 break;
886                         }
887                 }
888         }
889
890         AT_ASYNC_UNLOCK();
891
892         return async_request;
893 }
894
895 // Queue one request to the async requests queue
896 int at_async_request_queue(struct at_async_request *async_request)
897 {
898         struct at_async_request **async_requests = NULL;
899         int async_requests_count = 0;
900         int index;
901         int count;
902
903         if(async_request == NULL)
904                 return -1;
905
906         AT_ASYNC_LOCK();
907
908         // Save the previous data pointer and count
909         async_requests = at_handling.async_requests_queue.async_requests;
910         async_requests_count = at_handling.async_requests_queue.async_requests_count;
911
912         if(async_requests_count < 0)
913                 async_requests_count = 0;
914
915         // Index is the sync request index in the sync requests array
916         index = async_requests_count;
917         // Count is the total count of sync requests in the array
918         count = index + 1;
919
920         // Alloc the array with the new size
921         at_handling.async_requests_queue.async_requests = malloc(sizeof(struct at_async_request *) * count);
922         at_handling.async_requests_queue.async_requests_count = count;
923
924         // Copy and free previous data
925         if(async_requests != NULL && async_requests_count > 0) {
926                 memcpy(at_handling.async_requests_queue.async_requests, async_requests, sizeof(struct at_async_request *) * at_handling.async_requests_queue.async_requests_count);
927                 free(async_requests);
928         }
929
930         // Get the new data pointer and count
931         async_requests = at_handling.async_requests_queue.async_requests;
932         async_requests_count = at_handling.async_requests_queue.async_requests_count;
933
934         // Put the sync request in the queue
935         async_requests[index] = async_request;
936
937         LOGD("%d elements in the async requests queue", async_requests_count);
938
939         AT_ASYNC_UNLOCK();
940
941         return 0;
942 }
943
944 int at_async_response_dequeue(struct at_response *response)
945 {
946         struct at_async_request *async_request = NULL;
947         int rc;
948
949         if(response == NULL)
950                 return -1;
951
952         // First, try to grab the async request from the response, if it was already filled by sync dequeue
953         async_request = at_async_request_find_response(response);
954         if(async_request == NULL || async_request->func == NULL) {
955                 // Grab the async request from the command
956
957                 async_request = at_async_request_find_command(response->command);
958                 if(async_request == NULL || async_request->func == NULL) {
959                         return -1;
960                 }
961
962                 // FIXME: What if there is already a response with valid data?
963
964                 async_request->response = response;
965         }
966
967         LOGD("Found a matching request for %s!", async_request->command);
968
969         // This prevents sync data not to be reported when the same command is issued in func and previous handled was unhandled for status reason
970         async_request->handled = AT_RESPONSE_SENT;
971
972         at_async_request_dequeue(async_request);
973
974         rc = async_request->func(response, async_request->data, async_request->token);
975
976         // If the request was unhandled, update its status and requeue
977         if(rc == AT_RESPONSE_UNHANDELD_REASON_STATUS) {
978                 LOGD("Response not handled (missing status)");
979                 async_request->handled = AT_RESPONSE_UNHANDELD_REASON_STATUS;
980                 at_async_request_queue(async_request);
981         } else if(rc == AT_RESPONSE_UNHANDELD_REASON_DATA) {
982                 LOGD("Response not handled (missing data)");
983                 async_request->handled = AT_RESPONSE_UNHANDELD_REASON_DATA;
984                 at_async_request_queue(async_request);
985         } else {
986                 // We can free the request
987                 at_async_request_free(async_request);
988
989                 // Send the next request in the queue
990                 at_send_next_request();
991         }
992
993         return 0;
994 }
995
996 // Dequeue one async request (only remove from the queue)
997 int at_async_request_dequeue(struct at_async_request *async_request)
998 {
999         struct at_async_request **async_requests = NULL;
1000         int async_requests_count = 0;
1001         int pos = -1;
1002         int i;
1003
1004         if(async_request == NULL)
1005                 return -1;
1006
1007         AT_ASYNC_LOCK();
1008
1009         // Save the previous data pointer and count
1010         async_requests = at_handling.async_requests_queue.async_requests;
1011         async_requests_count = at_handling.async_requests_queue.async_requests_count;
1012
1013         if(async_requests_count <= 0 || async_requests == NULL) {
1014                 LOGE("No async requests queued, aborting dequeue!");
1015
1016                 AT_ASYNC_UNLOCK();
1017                 return -1;
1018         }
1019
1020         for(i=0 ; i < async_requests_count ; i++) {
1021                 if(async_requests[i] == async_request) {
1022                         pos = i;
1023                         break;
1024                 }
1025         }
1026
1027         if(pos < 0) {
1028                 LOGD("Found no matching async request, aborting dequeue!");
1029
1030                 AT_ASYNC_UNLOCK();
1031                 return -1;
1032         }
1033
1034         // Empty the found position in the async requests array
1035         async_requests[pos] = NULL;
1036
1037         // Move the elements back
1038         for(i=pos ; i < async_requests_count-1 ; i++) {
1039                 async_requests[i] = async_requests[i+1];
1040         }
1041
1042         // Empty the latest element
1043         if(pos != async_requests_count-1) {
1044                 async_requests[async_requests_count-1] = NULL;
1045         }
1046
1047         async_requests_count--;
1048
1049         if(async_requests_count == 0) {
1050                 free(async_requests);
1051                 at_handling.async_requests_queue.async_requests = NULL;
1052         }
1053
1054         at_handling.async_requests_queue.async_requests_count = async_requests_count;
1055
1056         LOGD("%d elements in the async requests queue", async_requests_count);
1057
1058         AT_ASYNC_UNLOCK();
1059
1060         return 0;
1061 }
1062
1063 /*
1064  * Sync requests queue
1065  */
1066
1067 // Lock the sync requests queue
1068 void at_sync_requests_queue_lock(void)
1069 {
1070         AT_SYNC_QUEUE_LOCK();
1071 }
1072
1073 // Unlock the sync requests queue
1074 void at_sync_requests_queue_unlock(void)
1075 {
1076         AT_SYNC_QUEUE_UNLOCK();
1077 }
1078
1079 // Free the sync request
1080 void at_sync_request_free(struct at_sync_request *sync_request)
1081 {
1082         if(sync_request == NULL)
1083                 return;
1084
1085         if(sync_request->command)
1086                 free(sync_request->command);
1087
1088         memset(sync_request, 0, sizeof(struct at_sync_request));
1089         sync_request->handled = AT_RESPONSE_GARBAGE;
1090 }
1091
1092 // Whether the sync queue is empty
1093 int at_sync_queue_empty(void)
1094 {
1095         struct at_sync_request *sync_request = NULL;
1096         struct at_sync_request **sync_requests = NULL;
1097         int sync_requests_count;
1098
1099         int empty = 1;
1100
1101         AT_SYNC_LOCK();
1102
1103         // Save the previous data pointer and count
1104         sync_requests = at_handling.sync_requests_queue.sync_requests;
1105         sync_requests_count = at_handling.sync_requests_queue.sync_requests_count;
1106
1107         if(sync_requests_count <= 0 || sync_requests == NULL)
1108                 empty = 1;
1109         else
1110                 empty = 0;
1111
1112         AT_SYNC_UNLOCK();
1113
1114         return empty;
1115 }
1116
1117 // Find a sync request from its command
1118 struct at_sync_request *at_sync_request_find_command(char *command)
1119 {
1120         struct at_sync_request *sync_request = NULL;
1121         struct at_sync_request **sync_requests = NULL;
1122         int sync_requests_count = 0;
1123         int i;
1124
1125         if(command == NULL)
1126                 return NULL;
1127
1128         AT_SYNC_LOCK();
1129
1130         // Save the previous data pointer and count
1131         sync_requests = at_handling.sync_requests_queue.sync_requests;
1132         sync_requests_count = at_handling.sync_requests_queue.sync_requests_count;
1133
1134         if(sync_requests_count <= 0 || sync_requests == NULL) {
1135                 AT_SYNC_UNLOCK();
1136                 return NULL;
1137         }
1138
1139         for(i=0 ; i < sync_requests_count ; i++) {
1140                 if(sync_requests[i] != NULL && sync_requests[i]->command != NULL) {
1141                         if(at_commands_compare(command, sync_requests[i]->command)) {
1142                                 sync_request = sync_requests[i];
1143                                 break;
1144                         }
1145                 }
1146         }
1147
1148         AT_SYNC_UNLOCK();
1149
1150         return sync_request;
1151 }
1152
1153 // Find a sync request from its handled status
1154 struct at_sync_request *at_sync_request_find_handled(int handled)
1155 {
1156         struct at_sync_request *sync_request = NULL;
1157         struct at_sync_request **sync_requests = NULL;
1158         int sync_requests_count = 0;
1159         int i;
1160
1161         AT_SYNC_LOCK();
1162
1163         // Save the previous data pointer and count
1164         sync_requests = at_handling.sync_requests_queue.sync_requests;
1165         sync_requests_count = at_handling.sync_requests_queue.sync_requests_count;
1166
1167         if(sync_requests_count <= 0 || sync_requests == NULL) {
1168                 AT_SYNC_UNLOCK();
1169                 return NULL;
1170         }
1171
1172         for(i=0 ; i < sync_requests_count ; i++) {
1173                 if(sync_requests[i] != NULL) {
1174                         if(sync_requests[i]->handled == handled) {
1175                                 sync_request = sync_requests[i];
1176                                 break;
1177                         }
1178                 }
1179         }
1180
1181         AT_SYNC_UNLOCK();
1182
1183         return sync_request;
1184 }
1185
1186 // Find a sync request from its request pointer
1187 struct at_sync_request *at_sync_request_find_request(struct at_request *request)
1188 {
1189         struct at_sync_request *sync_request = NULL;
1190         struct at_sync_request **sync_requests = NULL;
1191         int sync_requests_count = 0;
1192         int i;
1193
1194         if(request == NULL)
1195                 return NULL;
1196
1197         AT_SYNC_LOCK();
1198
1199         // Save the previous data pointer and count
1200         sync_requests = at_handling.sync_requests_queue.sync_requests;
1201         sync_requests_count = at_handling.sync_requests_queue.sync_requests_count;
1202
1203         if(sync_requests_count <= 0 || sync_requests == NULL) {
1204                 AT_SYNC_UNLOCK();
1205                 return NULL;
1206         }
1207
1208         for(i=0 ; i < sync_requests_count ; i++) {
1209                 if(sync_requests[i] != NULL) {
1210                         if(sync_requests[i]->request == request) {
1211                                 sync_request = sync_requests[i];
1212                                 break;
1213                         }
1214                 }
1215         }
1216
1217         AT_SYNC_UNLOCK();
1218
1219         return sync_request;
1220 }
1221
1222 // Queue one request to the sync requests queue
1223 int at_sync_request_queue(struct at_sync_request *sync_request)
1224 {
1225         struct at_sync_request **sync_requests = NULL;
1226         int sync_requests_count = 0;
1227         int index;
1228         int count;
1229
1230         if(sync_request == NULL)
1231                 return -1;
1232
1233         AT_SYNC_LOCK();
1234
1235         // Save the previous data pointer and count
1236         sync_requests = at_handling.sync_requests_queue.sync_requests;
1237         sync_requests_count = at_handling.sync_requests_queue.sync_requests_count;
1238
1239         if(sync_requests_count < 0)
1240                 sync_requests_count = 0;
1241
1242         // Index is the sync request index in the sync requests array
1243         index = sync_requests_count;
1244         // Count is the total count of sync requests in the array
1245         count = index + 1;
1246
1247         // Alloc the array with the new size
1248         at_handling.sync_requests_queue.sync_requests = malloc(sizeof(struct at_sync_request *) * count);
1249         at_handling.sync_requests_queue.sync_requests_count = count;
1250
1251         // Copy and free previous data
1252         if(sync_requests != NULL && sync_requests_count > 0) {
1253                 memcpy(at_handling.sync_requests_queue.sync_requests, sync_requests, sizeof(struct at_sync_request *) * at_handling.sync_requests_queue.sync_requests_count);
1254                 free(sync_requests);
1255         }
1256
1257         // Get the new data pointer and count
1258         sync_requests = at_handling.sync_requests_queue.sync_requests;
1259         sync_requests_count = at_handling.sync_requests_queue.sync_requests_count;
1260
1261         // Put the sync request in the queue
1262         sync_requests[index] = sync_request;
1263
1264         LOGD("%d elements in the sync requests queue", sync_requests_count);
1265
1266         AT_SYNC_UNLOCK();
1267
1268         return 0;
1269 }
1270
1271 // Dequeue one response (that will or not be assigned to a sync request)
1272 int at_sync_response_dequeue(struct at_response *response)
1273 {
1274         struct at_sync_request *sync_request = NULL;
1275         struct at_async_request *async_request = NULL;
1276         int rc;
1277
1278         if(response == NULL)
1279                 return -1;
1280
1281         if(response->command != NULL && !at_sync_queue_empty()) {
1282                 if(response->status == AT_STATUS_UNDEF && (response->data == NULL || response->data_count <= 0)) {
1283                         // Check if this is a part of a queued sync command
1284
1285                         sync_request = at_sync_request_find_command(response->command);
1286                         if(sync_request != NULL && sync_request->handled == AT_RESPONSE_SENT) {
1287                                 // This will make this sync request the next one to get a status
1288
1289                                 sync_request->handled = AT_RESPONSE_UNHANDELD_REASON_STATUS;
1290
1291                                 LOGD("Skipping matching request with no status nor data!");
1292                                 at_response_free(response);
1293                                 return 0;
1294                         }
1295                 }
1296
1297                 // FIXME: What if we get some data for the sync request here, but not with the status yet => set response already => next time if there is already a response, grab its data
1298
1299                 sync_request = at_sync_request_find_handled(AT_RESPONSE_SENT);
1300                 if(sync_request != NULL && sync_request->command != NULL) {
1301                         // If we catch an unsol or a response for another request, there is something wrong
1302
1303                         rc = at_commands_compare(response->command, sync_request->command);
1304                         if(!rc) {
1305                                 // We don't need to check on the async queue as requests are sent one at a time
1306
1307                                 LOGE("Got a response for another request, aborting!");
1308                                 AT_SYNC_QUEUE_UNLOCK();
1309                                 return -1;
1310                         }
1311                 } else {
1312                         // There is a command but we didn't send any sync request, so don't deal with it
1313
1314                         return -1;
1315                 }
1316         }
1317
1318         // If we have no status at this point, we have no use of the response
1319         if(response->status == AT_STATUS_UNDEF) {
1320                 return -1;
1321         }
1322
1323         // Have no command but a status
1324         if(response->command == NULL) {
1325                 async_request = at_async_request_find_handled(AT_RESPONSE_UNHANDELD_REASON_STATUS);
1326                 if(async_request != NULL) {
1327                         // FIXME: What if there was already a response with data but no status? We would override data => make a mix of both and free one
1328
1329                         async_request->response = response;
1330                         async_request->handled = AT_RESPONSE_SENT;
1331
1332                         LOGD("Found a status for a previous async request!");
1333
1334                         return -1;
1335                 }
1336
1337                 sync_request = at_sync_request_find_handled(AT_RESPONSE_UNHANDELD_REASON_STATUS);
1338                 if(sync_request != NULL) {
1339                         sync_request->handled = AT_RESPONSE_SENT;
1340                 }
1341
1342         }
1343
1344         if(sync_request == NULL) {
1345                 sync_request = at_sync_request_find_handled(AT_RESPONSE_SENT);
1346                 if(sync_request == NULL) {
1347                         LOGE("Got a status but no request waiting for it at all, this should never happend!");
1348                         return -1;
1349                 }
1350         }
1351
1352         sync_request->response = response;
1353         LOGD("Found a response for a sync request!");
1354
1355         AT_SYNC_QUEUE_UNLOCK();
1356
1357         return 0;
1358 }
1359
1360 // Dequeue one sync request (only remove from the queue)
1361 int at_sync_request_dequeue(struct at_sync_request *sync_request)
1362 {
1363         struct at_sync_request **sync_requests = NULL;
1364         int sync_requests_count = 0;
1365         int pos = -1;
1366         int i;
1367
1368         if(sync_request == NULL)
1369                 return -1;
1370
1371         AT_SYNC_LOCK();
1372
1373         // Save the previous data pointer and count
1374         sync_requests = at_handling.sync_requests_queue.sync_requests;
1375         sync_requests_count = at_handling.sync_requests_queue.sync_requests_count;
1376
1377         if(sync_requests_count <= 0 || sync_requests == NULL) {
1378                 LOGE("No sync requests queued, aborting dequeue!");
1379
1380                 AT_SYNC_UNLOCK();
1381                 return -1;
1382         }
1383
1384         for(i=0 ; i < sync_requests_count ; i++) {
1385                 if(sync_requests[i] == sync_request) {
1386                         pos = i;
1387                         break;
1388                 }
1389         }
1390
1391         if(pos < 0) {
1392                 LOGD("Found no matching sync request, aborting dequeue!");
1393
1394                 AT_SYNC_UNLOCK();
1395                 return -1;
1396         }
1397
1398         // Empty the found position in the sync requests array
1399         sync_requests[pos] = NULL;
1400
1401         // Move the elements back
1402         for(i=pos ; i < sync_requests_count-1 ; i++) {
1403                 sync_requests[i] = sync_requests[i+1];
1404         }
1405
1406         // Empty the latest element
1407         if(pos != sync_requests_count-1) {
1408                 sync_requests[sync_requests_count-1] = NULL;
1409         }
1410
1411         sync_requests_count--;
1412
1413         if(sync_requests_count == 0) {
1414                 free(sync_requests);
1415                 at_handling.sync_requests_queue.sync_requests = NULL;
1416         }
1417
1418         at_handling.sync_requests_queue.sync_requests_count = sync_requests_count;
1419
1420         LOGD("%d elements in the sync requests queue", sync_requests_count);
1421
1422         AT_SYNC_UNLOCK();
1423
1424         return 0;
1425 }
1426
1427 /*
1428  * Request
1429  */
1430
1431 int at_request_send(struct at_request *request)
1432 {
1433         char *string = NULL;
1434         int length = 0;
1435
1436         int offset_separator_begin = 0;
1437         int length_separator_begin = 0;
1438         int offset_command = 0;
1439         int length_command = 0;
1440         int offset_data_separator = 0;
1441         int length_data_separator = 0;
1442         int offset_data = 0;
1443         int length_data = 0;
1444         int offset_separator_end = 0;
1445         int length_separator_end = 0;
1446
1447         int i, p;
1448
1449         // TODO: Do we send \r\n or only \r, begining/end or just end?
1450         char separator[] = "\r\n";
1451         char data_separator[] = "=";
1452
1453         if(request->command == NULL)
1454                 return -1;
1455
1456         offset_separator_begin = 0;
1457         length_separator_begin = strlen(separator);
1458         length += length_separator_begin;
1459
1460         offset_command = length;
1461         length_command = strlen(request->command);
1462         length += length_command;
1463
1464         if(request->data != NULL) {
1465                 offset_data_separator = length;
1466                 length_data_separator = strlen(data_separator);
1467                 length += length_data_separator;
1468
1469                 offset_data = length;
1470                 length_data = strlen(request->data);
1471                 length += length_data;
1472         }
1473
1474         offset_separator_end = length;
1475         length_separator_end = strlen(separator);
1476         length += length_separator_end;
1477
1478         // Alloc final string
1479         string = calloc(1, length);
1480
1481         // Copy the data to the string
1482         memcpy(string + offset_separator_begin, separator, length_separator_begin);
1483         memcpy(string + offset_command, request->command, length_command);
1484         if(request->data != NULL) {
1485                 memcpy(string + offset_data_separator, data_separator, length_data_separator);
1486                 memcpy(string + offset_data, request->data, length_data);
1487         }
1488         memcpy(string + offset_separator_end, separator, length_separator_end);
1489
1490         // Log request
1491         RIL_LOG_LOCK();
1492         ril_data_log(string, length);
1493         ril_send_log(request);
1494         RIL_LOG_UNLOCK();
1495
1496         ril_device_send(ril_device, string, length);
1497
1498         free(string);
1499
1500         return 0;
1501 }
1502
1503 struct at_request *at_request_create(char *command, char *data)
1504 {
1505         struct at_request *request = NULL;
1506         int i;
1507
1508         if(command == NULL)
1509                 return NULL;
1510
1511         request = calloc(1, sizeof(struct at_request));
1512
1513         asprintf(&(request->command), "%s", command);
1514
1515         if(data != NULL) {
1516                 asprintf(&(request->data), "%s", data);
1517         }
1518
1519         return request;
1520 }
1521
1522 void at_request_free(struct at_request *request)
1523 {
1524         if(request->command != NULL) 
1525                 free(request->command);
1526
1527         if(request->data != NULL)
1528                 free(request->data);
1529
1530         if(request->error != NULL)
1531                 free(request->error);
1532
1533         memset(request, 0, sizeof(struct at_request *));
1534 }
1535
1536 /*
1537  * Send
1538  */
1539
1540 int at_send_next_request(void)
1541 {
1542         struct at_sync_request *sync_request = NULL;
1543         struct at_async_request *async_request = NULL;
1544         struct at_request *request = NULL;
1545         int rc;
1546
1547         sync_request = at_sync_request_find_handled(AT_RESPONSE_SENT);
1548         async_request = at_async_request_find_handled(AT_RESPONSE_SENT);
1549
1550         if(sync_request != NULL || async_request != NULL) {
1551                 LOGE("There are still unanswered requests!");
1552                 return -1;
1553         }
1554
1555         request = at_request_dequeue();
1556         if(request == NULL) {
1557                 LOGD("Nothing left to send!");
1558                 return -1;
1559         }
1560
1561         rc = at_request_send(request);
1562         if(rc < 0) {
1563                 LOGE("Unable to send request, aborting!");
1564                 at_request_free(request);
1565                 return -1;
1566         }
1567
1568         sync_request = at_sync_request_find_request(request);
1569         if(sync_request != NULL) {
1570                 sync_request->handled = AT_RESPONSE_SENT;
1571                 sync_request->request = NULL;
1572         }
1573
1574         async_request = at_async_request_find_request(request);
1575         if(async_request != NULL) {
1576                 async_request->handled = AT_RESPONSE_SENT;
1577                 async_request->request = NULL;
1578         }
1579
1580         at_request_free(request);
1581
1582         return 0;
1583 }
1584
1585 int at_send_async(struct at_request *request, void *data, RIL_Token token, at_async_request_cb func)
1586 {
1587         struct at_async_request *async_request = NULL;
1588         int rc;
1589         int i;
1590
1591         if(request->command == NULL || func == NULL)
1592                 return -1;
1593
1594         async_request = calloc(1, sizeof(struct at_async_request));
1595         async_request->handled = AT_RESPONSE_WAITING;
1596         async_request->request = request;
1597         async_request->command = strdup(request->command);
1598         async_request->data = data;
1599         async_request->token = token;
1600         async_request->func = func;
1601
1602         rc = at_async_request_queue(async_request);
1603         if(rc < 0) {
1604                 LOGE("Unable to queue async request");
1605
1606                 at_async_request_free(async_request);
1607                 return -1;
1608         }
1609
1610         rc = at_request_queue(request);
1611         if(rc < 0) {
1612                 LOGE("Unable to queue request");
1613
1614                 // Better trying to dequeue too
1615                 at_async_request_dequeue(async_request);
1616                 at_async_request_free(async_request);
1617                 return NULL;
1618         }
1619
1620         // Try to send it now, don't fail if it can't
1621         at_send_next_request();
1622
1623         return 0;
1624 }
1625
1626 struct at_response *at_send_sync(struct at_request *request)
1627 {
1628         struct at_sync_request *sync_request = NULL;
1629         struct at_response *response = NULL;
1630         int rc;
1631         int i;
1632
1633         if(request->command == NULL)
1634                 return NULL;
1635
1636         sync_request = calloc(1, sizeof(struct at_sync_request));
1637         sync_request->handled = AT_RESPONSE_WAITING;
1638         sync_request->request = request;
1639         sync_request->command = strdup(request->command);
1640
1641         rc = at_sync_request_queue(sync_request);
1642         if(rc < 0) {
1643                 LOGE("Unable to queue sync request");
1644
1645                 at_sync_request_free(sync_request);
1646                 return NULL;
1647         }
1648
1649         rc = at_request_queue(request);
1650         if(rc < 0) {
1651                 LOGE("Unable to queue request");
1652
1653                 // Better trying to dequeue too
1654                 at_sync_request_dequeue(sync_request);
1655                 at_sync_request_free(sync_request);
1656                 return NULL;
1657         }
1658
1659         // Try to send it now, don't fail if it can't
1660         at_send_next_request();
1661
1662         // Block until there is a response available
1663         at_sync_requests_queue_lock();
1664
1665         if(sync_request->response == NULL) {
1666                 LOGE("Sync queue was unlocked but there is no response, aborting");
1667
1668                 // Better trying to dequeue too
1669                 at_sync_request_dequeue(sync_request);
1670                 at_sync_request_free(sync_request);
1671
1672                 // Send the next request in the queue
1673                 at_send_next_request();
1674
1675                 return NULL;
1676         }
1677
1678         response = sync_request->response;
1679
1680         at_sync_request_free(sync_request);
1681
1682         // Send the next request in the queue
1683         at_send_next_request();
1684
1685         return response;
1686 }
1687
1688 int at_send_expect_to_func(char *command, char *data, void *async_data, RIL_Token token, at_async_request_cb func)
1689 {
1690         struct at_request *request = NULL;
1691         int rc;
1692
1693         request = at_request_create(command, data);
1694         if(request == NULL) {
1695                 LOGE("Unable to create request, aborting");
1696                 return -1;
1697         }
1698
1699         rc = at_send_async(request, async_data, token, func);
1700         if(rc < 0) {
1701                 LOGE("Unable to send async request, aborting");
1702
1703                 at_request_free(request);
1704                 return -1;
1705         }
1706
1707         return 0;
1708 }
1709
1710 int at_send_expect_status(char *command, char *data)
1711 {
1712         struct at_request *request = NULL;
1713         struct at_response *response = NULL;
1714         int status;
1715
1716         request = at_request_create(command, data);
1717         if(request == NULL) {
1718                 LOGE("Unable to create request, aborting");
1719                 return -1;
1720         }
1721
1722         response = at_send_sync(request);
1723         if(response == NULL) {
1724                 LOGE("Unable to get sync response, aborting");
1725
1726                 at_request_free(request);
1727                 return -1;
1728         }
1729
1730         status = response->status;
1731
1732         at_request_free(request);
1733         at_response_free(response);
1734
1735         return status;
1736 }
1737
1738 int at_send_noresp(char *command, char *data)
1739 {
1740         struct at_response *response;
1741
1742         response = at_send(command, data);
1743         if(response != NULL) {
1744                 at_response_free(response);
1745                 return 0;
1746         } else {
1747                 return -1;
1748         }
1749 }
1750
1751 struct at_response *at_send_command(char *command)
1752 {
1753         return at_send(command, NULL);
1754 }
1755
1756 struct at_response *at_send(char *command, char *data)
1757 {
1758         struct at_request *request = NULL;
1759         struct at_response *response = NULL;
1760         int rc;
1761
1762         request = at_request_create(command, data);
1763         if(request == NULL) {
1764                 LOGE("Unable to create request, aborting!");
1765                 return -1;
1766         }
1767
1768         response = at_send_sync(request);
1769         if(response == NULL) {
1770                 LOGE("Unable to get sync response, aborting");
1771
1772                 at_request_free(request);
1773                 return -1;
1774         }
1775
1776         return response;
1777 }