AT: Better failure handling and removed wrong unlock
[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 && responses_count > 0) {
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 && responses_count > 0) {
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  * Response data parsing
465  */
466
467 char *at_response_data_parse_string(char *data, int length)
468 {
469         char *string = NULL;
470         int string_length = 0;
471         int mark = 0;
472         int quote = 0;
473         int i;
474
475         for(i=0 ; i < length ; i++) {
476                 if(data[i] == '"') {
477                         if(quote & AT_PARSE_DOUBLE_QUOTE) {
478                                 if(i - mark > 0) {
479                                         data[i] = '\0';
480
481                                         string_length = i - mark + 1;
482                                         string = strndup(data + mark, string_length);
483
484                                         if(!isprint(string[0])) {
485                                                 free(string);
486                                                 return NULL;
487                                         }
488                                         else {
489                                                 return string;
490                                         }
491                                 } else if(i - mark == 0) {
492                                         return strdup("");
493                                 }
494                         } else {
495                                 quote |= AT_PARSE_DOUBLE_QUOTE;
496                                 mark = i + 1;
497                         }
498                 }
499         }
500
501         // Only return the first string between a pair of "
502
503         return NULL;
504 }
505
506 int at_response_data_parse_numeric(char *data, int length)
507 {
508         int i;
509
510         for(i=0 ; i < length ; i++) {
511                 if(isdigit(data[i])) {
512                         return atoi(data + i);
513                 }
514         }
515
516         return 0;
517 }
518
519 /*
520  * Response data processing
521  */
522
523 int at_response_data_process_value(struct at_response_data ***response_data_p, int response_data_count, char *data, int length)
524 {
525         struct at_response_data **response_data = NULL;
526         char *response_data_string = NULL;
527         int response_data_numeric = 0;
528
529         int index = -1;
530         int count = 0;
531
532         if(response_data_p == NULL || data == NULL || length < 0) {
533                 LOGE("Failed to process AT response data value: wrong arguments!");
534                 return 0;
535         }
536
537         response_data = *response_data_p;
538
539         // Parse string
540         response_data_string = at_response_data_parse_string(data, length);
541         if(response_data_string != NULL) {
542                 // Index is the response data index in the response data array
543                 index = response_data_count;
544                 // Count is the total count of response data in the array
545                 count = index + 1;
546
547                 // Alloc the array with the new size
548                 *response_data_p = malloc(sizeof(struct at_response_data *) * count);
549
550                 // Copy and free previous data
551                 if(response_data != NULL && response_data_count > 0) {
552                         memcpy(*response_data_p, response_data, sizeof(struct at_response_data *) * response_data_count);
553                         free(response_data);
554                 }
555
556                 response_data = *response_data_p;
557
558                 // Alloc new structure and copy obtained data
559                 response_data[index] = calloc(1, sizeof(struct at_response_data));
560                 response_data[index]->type = AT_RESPONSE_DATA_STRING;
561                 response_data[index]->value.s = response_data_string;
562
563         } else {
564                 response_data_numeric = at_response_data_parse_numeric(data, length);
565
566                 // Index is the response data index in the response data array
567                 index = response_data_count;
568                 // Count is the total count of response data in the array
569                 count = index + 1;
570
571                 // Alloc the array with the new size
572                 *response_data_p = malloc(sizeof(struct at_response_data *) * count);
573
574                 // Copy and free previous data
575                 if(response_data != NULL && response_data_count > 0) {
576                         memcpy(*response_data_p, response_data, sizeof(struct at_response_data *) * response_data_count);
577                         free(response_data);
578                 }
579
580                 response_data = *response_data_p;
581
582                 // Alloc new structure and copy obtained data
583                 response_data[index] = calloc(1, sizeof(struct at_response_data));
584                 response_data[index]->type = AT_RESPONSE_DATA_NUMERIC;
585                 response_data[index]->value.n = response_data_numeric;
586         }
587
588         return count > response_data_count ? count : response_data_count;
589 }
590
591 int at_response_data_process(struct at_response_data ***response_data_p, char *data, int length)
592 {
593         int response_data_count = 0;
594         int count = 0;
595
596         char *string = NULL;
597         int string_length = 0;
598         int mark = 0;
599         int i;
600
601         if(response_data_p == NULL || data == NULL || length < 0) {
602                 LOGE("Failed to process AT response data: wrong arguments!");
603                 return 0;
604         }
605
606         for(i=0 ; i < length ; i++) {
607                 if(data[i] == ',') {
608                         if(i - mark > 0) {
609                                 data[i] = '\0';
610
611                                 string_length = i - mark + 1;
612                                 string = strndup(data + mark, string_length);
613
614                                 if(!isprint(string[0])) {
615                                         free(string);
616                                 }
617                                 else {
618                                         count = at_response_data_process_value(response_data_p, response_data_count, string, string_length);
619                                         if(count > response_data_count)
620                                                 response_data_count = count;
621
622                                         free(string);
623                                 }
624
625                                 mark = i + 1;
626                         }
627
628                         while(isspace(data[i+1])) {
629                                 mark = i + 2;
630                                 i++;
631                         }
632                 }
633         }
634
635         if(length - mark > 0) {
636                 for(i=mark ; i < length ; i++)
637                         if(!isprint(data[i]))
638                                 break;
639
640                 if(i - mark > 0) {
641                         string_length = i - mark + 1;
642                         string = calloc(1, string_length);
643
644                         memcpy(string, data + mark, string_length - 1);
645                         string[string_length - 1] = '\0';
646
647                         count = at_response_data_process_value(response_data_p, response_data_count, string, string_length);
648                         if(count > response_data_count)
649                                 response_data_count = count;
650
651                         free(string);
652                 }
653         }
654
655         return response_data_count;
656 }
657
658 void at_response_data_free(struct at_response_data **response_data, int response_data_count)
659 {
660         int i;
661
662         if(response_data == NULL || response_data_count <= 0)
663                 return;
664
665         for(i=0 ; i < response_data_count ; i++) {
666                 if(response_data[i] != NULL) {
667                         if(response_data[i]->type == AT_RESPONSE_DATA_STRING && response_data[i]->value.s != NULL) {
668                                 free(response_data[i]->value.s);
669                         }
670
671                         memset(response_data[i], 0, sizeof(struct at_response_data));
672                 }
673         }
674
675         free(response_data);
676 }
677
678 /*
679  * Handling
680  */
681
682 void at_handling_init(void)
683 {
684         memset(&at_handling, 0, sizeof(struct at_handling));
685
686         pthread_mutex_init(&(at_handling.responses_queue.queue_mutex), NULL);
687         pthread_mutex_init(&(at_handling.responses_queue.mutex), NULL);
688         pthread_mutex_init(&(at_handling.requests_queue.mutex), NULL);
689         pthread_mutex_init(&(at_handling.sync_requests_queue.queue_mutex), NULL);
690         pthread_mutex_init(&(at_handling.sync_requests_queue.mutex), NULL);
691         pthread_mutex_init(&(at_handling.async_requests_queue.mutex), NULL);
692
693         at_handling.freeze = AT_FREEZE_OFF;
694
695         // First lock to the queues mutexes
696         AT_RESPONSES_QUEUE_LOCK();
697         AT_SYNC_QUEUE_LOCK();
698 }
699
700 /*
701  * Responses queue
702  */
703
704 // Unlock the responses queue after queuing all the available requests
705 void at_responses_queue_unlock(void)
706 {
707         if(at_handling.responses_queue.responses_count <= 0 || at_handling.responses_queue.responses == NULL)
708                 return;
709
710         AT_RESPONSES_QUEUE_UNLOCK();
711 }
712
713 // Queue one response to the responses queue
714 int at_response_queue(struct at_response *response)
715 {
716         struct at_response **responses = NULL;
717         int responses_count = 0;
718         int index;
719         int count;
720
721         if(response == NULL)
722                 return -1;
723
724         AT_RESPONSES_LOCK();
725
726         // Save the previous data pointer and count
727         responses = at_handling.responses_queue.responses;
728         responses_count = at_handling.responses_queue.responses_count;
729
730         if(responses_count < 0)
731                 responses_count = 0;
732
733         // Index is the response index in the responses array
734         index = responses_count;
735         // Count is the total count of responses in the array
736         count = index + 1;
737
738         // Alloc the array with the new size
739         at_handling.responses_queue.responses = malloc(sizeof(struct at_response *) * count);
740         at_handling.responses_queue.responses_count = count;
741
742         // Copy and free previous data
743         if(responses != NULL && responses_count > 0) {
744                 memcpy(at_handling.responses_queue.responses, responses, sizeof(struct at_response *) * at_handling.responses_queue.responses_count);
745                 free(responses);
746         }
747
748         // Get the new data pointer and count
749         responses = at_handling.responses_queue.responses;
750         responses_count = at_handling.responses_queue.responses_count;
751
752         // Put the response in the queue
753         responses[index] = response;
754
755         LOGD("%d elements in the responses queue", responses_count);
756
757         AT_RESPONSES_UNLOCK();
758
759         return 0;
760 }
761
762 // Unqueue the oldest response in the queue
763 struct at_response *at_response_dequeue(void)
764 {
765         struct at_response *response = NULL;
766         struct at_response **responses = NULL;
767         int responses_count = 0;
768         int pos = -1;
769         int i;
770
771         AT_RESPONSES_LOCK();
772
773         // Save the previous data pointer and count
774         responses = at_handling.responses_queue.responses;
775         responses_count = at_handling.responses_queue.responses_count;
776
777         while(responses_count <= 0 || responses == NULL) {
778                 LOGE("No response queued, blocking!");
779
780                 AT_RESPONSES_UNLOCK();
781                 AT_RESPONSES_QUEUE_LOCK();
782                 AT_RESPONSES_LOCK();
783
784                 if(at_freeze_get() == AT_FREEZE_SEND) {
785                         AT_RESPONSES_UNLOCK();
786                         return NULL;
787                 }
788
789                 // Get the new data pointer and count
790                 responses = at_handling.responses_queue.responses;
791                 responses_count = at_handling.responses_queue.responses_count;
792
793                 LOGE("Unblocking: %d new responses queued!", responses_count);
794         }
795
796         for(i=0 ; i < responses_count ; i++) {
797                 if(responses[i] != NULL) {
798                         response = responses[i];
799                         pos = i;
800                         break;
801                 }
802         }
803
804         if(response == NULL || pos < 0) {
805                 LOGD("Found no valid response, aborting!");
806
807                 AT_RESPONSES_UNLOCK();
808                 return NULL;
809         }
810
811         // Empty the found position in the responses array
812         responses[pos] = NULL;
813
814         // Move the elements back
815         for(i=pos ; i < responses_count-1 ; i++) {
816                 responses[i] = responses[i+1];
817         }
818
819         // Empty the latest element
820         if(pos != responses_count-1) {
821                 responses[responses_count-1] = NULL;
822         }
823
824         responses_count--;
825
826         if(responses_count == 0) {
827                 free(responses);
828                 at_handling.responses_queue.responses = NULL;
829         }
830
831         at_handling.responses_queue.responses_count = responses_count;
832
833         LOGD("%d elements in the responses queue", responses_count);
834
835         AT_RESPONSES_UNLOCK();
836
837         return response;
838 }
839
840 /*
841  * Requests queue
842  */
843
844 // Queue one request to the requests queue
845 int at_request_queue(struct at_request *request)
846 {
847         struct at_request **requests = NULL;
848         int requests_count = 0;
849         int index;
850         int count;
851
852         if(request == NULL)
853                 return -1;
854
855         AT_REQUESTS_LOCK();
856
857         // Save the previous data pointer and count
858         requests = at_handling.requests_queue.requests;
859         requests_count = at_handling.requests_queue.requests_count;
860
861         if(requests_count < 0)
862                 requests_count = 0;
863
864         // Index is the request index in the requests array
865         index = requests_count;
866         // Count is the total count of requests in the array
867         count = index + 1;
868
869         // Alloc the array with the new size
870         at_handling.requests_queue.requests = malloc(sizeof(struct at_request *) * count);
871         at_handling.requests_queue.requests_count = count;
872
873         // Copy and free previous data
874         if(requests != NULL && requests_count > 0) {
875                 memcpy(at_handling.requests_queue.requests, requests, sizeof(struct at_request *) * at_handling.requests_queue.requests_count);
876                 free(requests);
877         }
878
879         // Get the new data pointer and count
880         requests = at_handling.requests_queue.requests;
881         requests_count = at_handling.requests_queue.requests_count;
882
883         // Put the request in the queue
884         requests[index] = request;
885
886         LOGD("%d elements in the requests queue", requests_count);
887
888         AT_REQUESTS_UNLOCK();
889
890         return 0;
891 }
892
893 // Unqueue a request in the queue
894 struct at_request *at_request_dequeue(struct at_request *request)
895 {
896         struct at_request **requests = NULL;
897         int requests_count = 0;
898         int pos = -1;
899         int i;
900
901         AT_REQUESTS_LOCK();
902
903         // Save the previous data pointer and count
904         requests = at_handling.requests_queue.requests;
905         requests_count = at_handling.requests_queue.requests_count;
906
907         if(requests_count <= 0 || requests == NULL) {
908                 LOGE("No requests queued!");
909
910                 AT_REQUESTS_UNLOCK();
911                 return NULL;
912         }
913
914         if(request == NULL) {
915                 for(i=0 ; i < requests_count ; i++) {
916                         if(requests[i] != NULL) {
917                                 request = requests[i];
918                                 pos = i;
919                                 break;
920                         }
921                 }
922         } else {
923                 for(i=0 ; i < requests_count ; i++) {
924                         if(requests[i] == request) {
925                                 pos = i;
926                                 break;
927                         }
928                 }
929         }
930
931         if(requests == NULL || pos < 0) {
932                 LOGD("Found no valid request, aborting!");
933
934                 AT_REQUESTS_UNLOCK();
935                 return NULL;
936         }
937
938         // Empty the found position in the requests array
939         requests[pos] = NULL;
940
941         // Move the elements back
942         for(i=pos ; i < requests_count-1 ; i++) {
943                 requests[i] = requests[i+1];
944         }
945
946         // Empty the latest element
947         if(pos != requests_count-1) {
948                 requests[requests_count-1] = NULL;
949         }
950
951         requests_count--;
952
953         if(requests_count == 0) {
954                 free(requests);
955                 at_handling.requests_queue.requests = NULL;
956         }
957
958         at_handling.requests_queue.requests_count = requests_count;
959
960         LOGD("%d elements in the requests queue", requests_count);
961
962         AT_REQUESTS_UNLOCK();
963
964         return request;
965 }
966
967 /*
968  * Async requests queue
969  */
970
971 // Free the async request
972 void at_async_request_free(struct at_async_request *async_request)
973 {
974         if(async_request == NULL)
975                 return;
976
977         if(async_request->command)
978                 free(async_request->command);
979
980         if(async_request->request)
981                 at_request_free(async_request->request);
982
983         memset(async_request, 0, sizeof(struct at_async_request));
984         async_request->handled = AT_RESPONSE_GARBAGE;
985 }
986
987 // Find an async request from its command
988 struct at_async_request *at_async_request_find_command(char *command)
989 {
990         struct at_async_request *async_request = NULL;
991         struct at_async_request **async_requests = NULL;
992         int async_requests_count = 0;
993         int i;
994
995         if(command == NULL)
996                 return NULL;
997
998         AT_ASYNC_LOCK();
999
1000         // Save the previous data pointer and count
1001         async_requests = at_handling.async_requests_queue.async_requests;
1002         async_requests_count = at_handling.async_requests_queue.async_requests_count;
1003
1004         if(async_requests_count <= 0 || async_requests == NULL) {
1005                 AT_ASYNC_UNLOCK();
1006                 return NULL;
1007         }
1008
1009         for(i=0 ; i < async_requests_count ; i++) {
1010                 if(async_requests[i] != NULL && async_requests[i]->command != NULL) {
1011                         if(at_commands_compare(command, async_requests[i]->command)) {
1012                                 async_request = async_requests[i];
1013                                 break;
1014                         }
1015                 }
1016         }
1017
1018         AT_ASYNC_UNLOCK();
1019
1020         return async_request;
1021 }
1022
1023 // Find an async request from its handled status
1024 struct at_async_request *at_async_request_find_handled(int handled)
1025 {
1026         struct at_async_request *async_request = NULL;
1027         struct at_async_request **async_requests = NULL;
1028         int async_requests_count = 0;
1029         int i;
1030
1031         AT_ASYNC_LOCK();
1032
1033         // Save the previous data pointer and count
1034         async_requests = at_handling.async_requests_queue.async_requests;
1035         async_requests_count = at_handling.async_requests_queue.async_requests_count;
1036
1037         if(async_requests_count <= 0 || async_requests == NULL) {
1038                 AT_ASYNC_UNLOCK();
1039                 return NULL;
1040         }
1041
1042         for(i=0 ; i < async_requests_count ; i++) {
1043                 if(async_requests[i] != NULL) {
1044                         if(async_requests[i]->handled == handled) {
1045                                 async_request = async_requests[i];
1046                                 break;
1047                         }
1048                 }
1049         }
1050
1051         AT_ASYNC_UNLOCK();
1052
1053         return async_request;
1054 }
1055
1056 // Find an async request from its request pointer
1057 struct at_async_request *at_async_request_find_request(struct at_request *request)
1058 {
1059         struct at_async_request *async_request = NULL;
1060         struct at_async_request **async_requests = NULL;
1061         int async_requests_count = 0;
1062         int i;
1063
1064         if(request == NULL)
1065                 return NULL;
1066
1067         AT_ASYNC_LOCK();
1068
1069         // Save the previous data pointer and count
1070         async_requests = at_handling.async_requests_queue.async_requests;
1071         async_requests_count = at_handling.async_requests_queue.async_requests_count;
1072
1073         if(async_requests_count <= 0 || async_requests == NULL) {
1074                 AT_ASYNC_UNLOCK();
1075                 return NULL;
1076         }
1077
1078         for(i=0 ; i < async_requests_count ; i++) {
1079                 if(async_requests[i] != NULL) {
1080                         if(async_requests[i]->request == request) {
1081                                 async_request = async_requests[i];
1082                                 break;
1083                         }
1084                 }
1085         }
1086
1087         AT_ASYNC_UNLOCK();
1088
1089         return async_request;
1090 }
1091
1092 // Find an async request from its response pointer
1093 struct at_async_request *at_async_request_find_response(struct at_response *response)
1094 {
1095         struct at_async_request *async_request = NULL;
1096         struct at_async_request **async_requests = NULL;
1097         int async_requests_count = 0;
1098         int i;
1099
1100         if(response == NULL)
1101                 return NULL;
1102
1103         AT_ASYNC_LOCK();
1104
1105         // Save the previous data pointer and count
1106         async_requests = at_handling.async_requests_queue.async_requests;
1107         async_requests_count = at_handling.async_requests_queue.async_requests_count;
1108
1109         if(async_requests_count <= 0 || async_requests == NULL) {
1110                 AT_ASYNC_UNLOCK();
1111                 return NULL;
1112         }
1113
1114         for(i=0 ; i < async_requests_count ; i++) {
1115                 if(async_requests[i] != NULL && async_requests[i]->response != NULL) {
1116                         if(async_requests[i]->response == response) {
1117                                 async_request = async_requests[i];
1118                                 break;
1119                         }
1120                 }
1121         }
1122
1123         AT_ASYNC_UNLOCK();
1124
1125         return async_request;
1126 }
1127
1128 // Queue one request to the async requests queue
1129 int at_async_request_queue(struct at_async_request *async_request)
1130 {
1131         struct at_async_request **async_requests = NULL;
1132         int async_requests_count = 0;
1133         int index;
1134         int count;
1135
1136         if(async_request == NULL)
1137                 return -1;
1138
1139         AT_ASYNC_LOCK();
1140
1141         // Save the previous data pointer and count
1142         async_requests = at_handling.async_requests_queue.async_requests;
1143         async_requests_count = at_handling.async_requests_queue.async_requests_count;
1144
1145         if(async_requests_count < 0)
1146                 async_requests_count = 0;
1147
1148         // Index is the sync request index in the sync requests array
1149         index = async_requests_count;
1150         // Count is the total count of sync requests in the array
1151         count = index + 1;
1152
1153         // Alloc the array with the new size
1154         at_handling.async_requests_queue.async_requests = malloc(sizeof(struct at_async_request *) * count);
1155         at_handling.async_requests_queue.async_requests_count = count;
1156
1157         // Copy and free previous data
1158         if(async_requests != NULL && async_requests_count > 0) {
1159                 memcpy(at_handling.async_requests_queue.async_requests, async_requests, sizeof(struct at_async_request *) * at_handling.async_requests_queue.async_requests_count);
1160                 free(async_requests);
1161         }
1162
1163         // Get the new data pointer and count
1164         async_requests = at_handling.async_requests_queue.async_requests;
1165         async_requests_count = at_handling.async_requests_queue.async_requests_count;
1166
1167         // Put the sync request in the queue
1168         async_requests[index] = async_request;
1169
1170         LOGD("%d elements in the async requests queue", async_requests_count);
1171
1172         AT_ASYNC_UNLOCK();
1173
1174         return 0;
1175 }
1176
1177 int at_async_response_dequeue(struct at_response *response)
1178 {
1179         struct at_async_request *async_request = NULL;
1180         int rc;
1181
1182         if(response == NULL)
1183                 return -1;
1184
1185         // First, try to grab the async request from the response, if it was already filled by sync dequeue
1186         async_request = at_async_request_find_response(response);
1187         if(async_request == NULL || async_request->func == NULL) {
1188                 // Then, try to find an unhandled response
1189
1190                 async_request = at_async_request_find_handled(AT_RESPONSE_UNHANDELD_REASON_STATUS);
1191                 if(async_request == NULL || async_request->func == NULL) {
1192                         // Finally, grab the async request from the command
1193
1194                         async_request = at_async_request_find_command(response->command);
1195                         if(async_request == NULL || async_request->func == NULL) {
1196                                 return -1;
1197                         }
1198                 }
1199
1200                 // FIXME: What if there is already a response with valid data?
1201
1202                 async_request->response = response;
1203         }
1204
1205         LOGD("Found a matching request for %s!", async_request->command);
1206
1207         // This prevents sync data not to be reported when the same command is issued in func and previous handled was unhandled for status reason
1208         async_request->handled = AT_RESPONSE_SENT;
1209
1210         at_async_request_dequeue(async_request);
1211
1212         rc = async_request->func(response, async_request->data, async_request->token);
1213
1214         // If the request was unhandled, update its status and requeue
1215         if(rc == AT_RESPONSE_UNHANDELD_REASON_STATUS) {
1216                 LOGD("Response not handled (missing status)");
1217                 async_request->handled = AT_RESPONSE_UNHANDELD_REASON_STATUS;
1218                 at_async_request_queue(async_request);
1219         } else if(rc == AT_RESPONSE_UNHANDELD_REASON_DATA) {
1220                 LOGD("Response not handled (missing data)");
1221                 async_request->handled = AT_RESPONSE_UNHANDELD_REASON_DATA;
1222                 at_async_request_queue(async_request);
1223         } else {
1224                 LOGD("Response was handled!");
1225
1226                 // We can free the request
1227                 at_async_request_free(async_request);
1228
1229                 // Send the next request in the queue
1230                 at_send_next_request();
1231         }
1232
1233         return 0;
1234 }
1235
1236 // Dequeue one async request (only remove from the queue)
1237 int at_async_request_dequeue(struct at_async_request *async_request)
1238 {
1239         struct at_async_request **async_requests = NULL;
1240         int async_requests_count = 0;
1241         int pos = -1;
1242         int i;
1243
1244         if(async_request == NULL)
1245                 return -1;
1246
1247         AT_ASYNC_LOCK();
1248
1249         // Save the previous data pointer and count
1250         async_requests = at_handling.async_requests_queue.async_requests;
1251         async_requests_count = at_handling.async_requests_queue.async_requests_count;
1252
1253         if(async_requests_count <= 0 || async_requests == NULL) {
1254                 LOGE("No async requests queued, aborting dequeue!");
1255
1256                 AT_ASYNC_UNLOCK();
1257                 return -1;
1258         }
1259
1260         for(i=0 ; i < async_requests_count ; i++) {
1261                 if(async_requests[i] == async_request) {
1262                         pos = i;
1263                         break;
1264                 }
1265         }
1266
1267         if(pos < 0) {
1268                 LOGD("Found no matching async request, aborting dequeue!");
1269
1270                 AT_ASYNC_UNLOCK();
1271                 return -1;
1272         }
1273
1274         // Empty the found position in the async requests array
1275         async_requests[pos] = NULL;
1276
1277         // Move the elements back
1278         for(i=pos ; i < async_requests_count-1 ; i++) {
1279                 async_requests[i] = async_requests[i+1];
1280         }
1281
1282         // Empty the latest element
1283         if(pos != async_requests_count-1) {
1284                 async_requests[async_requests_count-1] = NULL;
1285         }
1286
1287         async_requests_count--;
1288
1289         if(async_requests_count == 0) {
1290                 free(async_requests);
1291                 at_handling.async_requests_queue.async_requests = NULL;
1292         }
1293
1294         at_handling.async_requests_queue.async_requests_count = async_requests_count;
1295
1296         LOGD("%d elements in the async requests queue", async_requests_count);
1297
1298         AT_ASYNC_UNLOCK();
1299
1300         return 0;
1301 }
1302
1303 /*
1304  * Sync requests queue
1305  */
1306
1307 // Lock the sync requests queue
1308 void at_sync_requests_queue_lock(void)
1309 {
1310         AT_SYNC_QUEUE_LOCK();
1311 }
1312
1313 // Unlock the sync requests queue
1314 void at_sync_requests_queue_unlock(void)
1315 {
1316         AT_SYNC_QUEUE_UNLOCK();
1317 }
1318
1319 // Free the sync request
1320 void at_sync_request_free(struct at_sync_request *sync_request)
1321 {
1322         if(sync_request == NULL)
1323                 return;
1324
1325         if(sync_request->command)
1326                 free(sync_request->command);
1327
1328         if(sync_request->request)
1329                 at_request_free(sync_request->request);
1330
1331         memset(sync_request, 0, sizeof(struct at_sync_request));
1332         sync_request->handled = AT_RESPONSE_GARBAGE;
1333 }
1334
1335 // Whether the sync queue is empty
1336 int at_sync_queue_empty(void)
1337 {
1338         struct at_sync_request *sync_request = NULL;
1339         struct at_sync_request **sync_requests = NULL;
1340         int sync_requests_count;
1341
1342         int empty = 1;
1343
1344         AT_SYNC_LOCK();
1345
1346         // Save the previous data pointer and count
1347         sync_requests = at_handling.sync_requests_queue.sync_requests;
1348         sync_requests_count = at_handling.sync_requests_queue.sync_requests_count;
1349
1350         if(sync_requests_count <= 0 || sync_requests == NULL)
1351                 empty = 1;
1352         else
1353                 empty = 0;
1354
1355         AT_SYNC_UNLOCK();
1356
1357         return empty;
1358 }
1359
1360 // Find a sync request from its command
1361 struct at_sync_request *at_sync_request_find_command(char *command)
1362 {
1363         struct at_sync_request *sync_request = NULL;
1364         struct at_sync_request **sync_requests = NULL;
1365         int sync_requests_count = 0;
1366         int i;
1367
1368         if(command == NULL)
1369                 return NULL;
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                 AT_SYNC_UNLOCK();
1379                 return NULL;
1380         }
1381
1382         for(i=0 ; i < sync_requests_count ; i++) {
1383                 if(sync_requests[i] != NULL && sync_requests[i]->command != NULL) {
1384                         if(at_commands_compare(command, sync_requests[i]->command)) {
1385                                 sync_request = sync_requests[i];
1386                                 break;
1387                         }
1388                 }
1389         }
1390
1391         AT_SYNC_UNLOCK();
1392
1393         return sync_request;
1394 }
1395
1396 // Find a sync request from its handled status
1397 struct at_sync_request *at_sync_request_find_handled(int handled)
1398 {
1399         struct at_sync_request *sync_request = NULL;
1400         struct at_sync_request **sync_requests = NULL;
1401         int sync_requests_count = 0;
1402         int i;
1403
1404         AT_SYNC_LOCK();
1405
1406         // Save the previous data pointer and count
1407         sync_requests = at_handling.sync_requests_queue.sync_requests;
1408         sync_requests_count = at_handling.sync_requests_queue.sync_requests_count;
1409
1410         if(sync_requests_count <= 0 || sync_requests == NULL) {
1411                 AT_SYNC_UNLOCK();
1412                 return NULL;
1413         }
1414
1415         for(i=0 ; i < sync_requests_count ; i++) {
1416                 if(sync_requests[i] != NULL) {
1417                         if(sync_requests[i]->handled == handled) {
1418                                 sync_request = sync_requests[i];
1419                                 break;
1420                         }
1421                 }
1422         }
1423
1424         AT_SYNC_UNLOCK();
1425
1426         return sync_request;
1427 }
1428
1429 // Find a sync request from its request pointer
1430 struct at_sync_request *at_sync_request_find_request(struct at_request *request)
1431 {
1432         struct at_sync_request *sync_request = NULL;
1433         struct at_sync_request **sync_requests = NULL;
1434         int sync_requests_count = 0;
1435         int i;
1436
1437         if(request == NULL)
1438                 return NULL;
1439
1440         AT_SYNC_LOCK();
1441
1442         // Save the previous data pointer and count
1443         sync_requests = at_handling.sync_requests_queue.sync_requests;
1444         sync_requests_count = at_handling.sync_requests_queue.sync_requests_count;
1445
1446         if(sync_requests_count <= 0 || sync_requests == NULL) {
1447                 AT_SYNC_UNLOCK();
1448                 return NULL;
1449         }
1450
1451         for(i=0 ; i < sync_requests_count ; i++) {
1452                 if(sync_requests[i] != NULL) {
1453                         if(sync_requests[i]->request == request) {
1454                                 sync_request = sync_requests[i];
1455                                 break;
1456                         }
1457                 }
1458         }
1459
1460         AT_SYNC_UNLOCK();
1461
1462         return sync_request;
1463 }
1464
1465 // Queue one request to the sync requests queue
1466 int at_sync_request_queue(struct at_sync_request *sync_request)
1467 {
1468         struct at_sync_request **sync_requests = NULL;
1469         int sync_requests_count = 0;
1470         int index;
1471         int count;
1472
1473         if(sync_request == NULL)
1474                 return -1;
1475
1476         AT_SYNC_LOCK();
1477
1478         // Save the previous data pointer and count
1479         sync_requests = at_handling.sync_requests_queue.sync_requests;
1480         sync_requests_count = at_handling.sync_requests_queue.sync_requests_count;
1481
1482         if(sync_requests_count < 0)
1483                 sync_requests_count = 0;
1484
1485         // Index is the sync request index in the sync requests array
1486         index = sync_requests_count;
1487         // Count is the total count of sync requests in the array
1488         count = index + 1;
1489
1490         // Alloc the array with the new size
1491         at_handling.sync_requests_queue.sync_requests = malloc(sizeof(struct at_sync_request *) * count);
1492         at_handling.sync_requests_queue.sync_requests_count = count;
1493
1494         // Copy and free previous data
1495         if(sync_requests != NULL && sync_requests_count > 0) {
1496                 memcpy(at_handling.sync_requests_queue.sync_requests, sync_requests, sizeof(struct at_sync_request *) * at_handling.sync_requests_queue.sync_requests_count);
1497                 free(sync_requests);
1498         }
1499
1500         // Get the new data pointer and count
1501         sync_requests = at_handling.sync_requests_queue.sync_requests;
1502         sync_requests_count = at_handling.sync_requests_queue.sync_requests_count;
1503
1504         // Put the sync request in the queue
1505         sync_requests[index] = sync_request;
1506
1507         LOGD("%d elements in the sync requests queue", sync_requests_count);
1508
1509         AT_SYNC_UNLOCK();
1510
1511         return 0;
1512 }
1513
1514 // Dequeue one response (that will or not be assigned to a sync request)
1515 int at_sync_response_dequeue(struct at_response *response)
1516 {
1517         struct at_sync_request *sync_request = NULL;
1518         struct at_async_request *async_request = NULL;
1519         int rc;
1520
1521         if(response == NULL)
1522                 return -1;
1523
1524         if(response->command != NULL && !at_sync_queue_empty()) {
1525                 if(response->status == AT_STATUS_UNDEF && (response->data == NULL || response->data_count <= 0)) {
1526                         // Check if this is a part of a queued sync command
1527
1528                         sync_request = at_sync_request_find_command(response->command);
1529                         if(sync_request != NULL && sync_request->handled == AT_RESPONSE_SENT) {
1530                                 // This will make this sync request the next one to get a status
1531
1532                                 sync_request->handled = AT_RESPONSE_UNHANDELD_REASON_STATUS;
1533
1534                                 LOGD("Skipping matching request with no status nor data!");
1535                                 at_response_free(response);
1536                                 return 0;
1537                         }
1538                 }
1539
1540                 // 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
1541
1542                 sync_request = at_sync_request_find_handled(AT_RESPONSE_SENT);
1543                 if(sync_request == NULL)
1544                         sync_request = at_sync_request_find_handled(AT_RESPONSE_UNHANDELD_REASON_STATUS);
1545
1546                 if(sync_request != NULL && sync_request->command != NULL) {
1547                         // If we catch an unsol or a response for another request, there is something wrong
1548
1549                         rc = at_commands_compare(response->command, sync_request->command);
1550                         if(!rc) {
1551                                 // We don't need to check on the async queue as requests are sent one at a time
1552
1553                                 LOGE("Got a response for another request, aborting!");
1554                                 return -1;
1555                         }
1556                 } else {
1557                         // There is a command but we didn't send any sync request, so don't deal with it
1558
1559                         return -1;
1560                 }
1561         }
1562
1563         // If we have no status at this point, we have no use of the response
1564         if(response->status == AT_STATUS_UNDEF) {
1565                 return -1;
1566         }
1567
1568         // Have no command but a status
1569         if(response->command == NULL) {
1570                 async_request = at_async_request_find_handled(AT_RESPONSE_UNHANDELD_REASON_STATUS);
1571                 if(async_request != NULL) {
1572                         // 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
1573
1574                         async_request->response = response;
1575                         async_request->handled = AT_RESPONSE_SENT;
1576
1577                         LOGD("Found a status for a previous async request!");
1578
1579                         return -1;
1580                 }
1581
1582                 sync_request = at_sync_request_find_handled(AT_RESPONSE_UNHANDELD_REASON_STATUS);
1583                 if(sync_request != NULL) {
1584                         sync_request->handled = AT_RESPONSE_SENT;
1585                 }
1586
1587         }
1588
1589         if(sync_request == NULL) {
1590                 sync_request = at_sync_request_find_handled(AT_RESPONSE_SENT);
1591                 if(sync_request == NULL) {
1592                         LOGE("Got a status but no request waiting for it at all, this should never happend!");
1593                         return -1;
1594                 }
1595         }
1596
1597         sync_request->response = response;
1598         LOGD("Found a response for a sync request!");
1599
1600         AT_SYNC_QUEUE_UNLOCK();
1601
1602         return 0;
1603 }
1604
1605 // Dequeue one sync request (only remove from the queue)
1606 int at_sync_request_dequeue(struct at_sync_request *sync_request)
1607 {
1608         struct at_sync_request **sync_requests = NULL;
1609         int sync_requests_count = 0;
1610         int pos = -1;
1611         int i;
1612
1613         if(sync_request == NULL)
1614                 return -1;
1615
1616         AT_SYNC_LOCK();
1617
1618         // Save the previous data pointer and count
1619         sync_requests = at_handling.sync_requests_queue.sync_requests;
1620         sync_requests_count = at_handling.sync_requests_queue.sync_requests_count;
1621
1622         if(sync_requests_count <= 0 || sync_requests == NULL) {
1623                 LOGE("No sync requests queued, aborting dequeue!");
1624
1625                 AT_SYNC_UNLOCK();
1626                 return -1;
1627         }
1628
1629         for(i=0 ; i < sync_requests_count ; i++) {
1630                 if(sync_requests[i] == sync_request) {
1631                         pos = i;
1632                         break;
1633                 }
1634         }
1635
1636         if(pos < 0) {
1637                 LOGD("Found no matching sync request, aborting dequeue!");
1638
1639                 AT_SYNC_UNLOCK();
1640                 return -1;
1641         }
1642
1643         // Empty the found position in the sync requests array
1644         sync_requests[pos] = NULL;
1645
1646         // Move the elements back
1647         for(i=pos ; i < sync_requests_count-1 ; i++) {
1648                 sync_requests[i] = sync_requests[i+1];
1649         }
1650
1651         // Empty the latest element
1652         if(pos != sync_requests_count-1) {
1653                 sync_requests[sync_requests_count-1] = NULL;
1654         }
1655
1656         sync_requests_count--;
1657
1658         if(sync_requests_count == 0) {
1659                 free(sync_requests);
1660                 at_handling.sync_requests_queue.sync_requests = NULL;
1661         }
1662
1663         at_handling.sync_requests_queue.sync_requests_count = sync_requests_count;
1664
1665         LOGD("%d elements in the sync requests queue", sync_requests_count);
1666
1667         AT_SYNC_UNLOCK();
1668
1669         return 0;
1670 }
1671
1672 /*
1673  * Freeze
1674  */
1675
1676 void at_freeze_set(int freeze)
1677 {
1678         at_handling.freeze = freeze;
1679 }
1680
1681 int at_freeze_get(void)
1682 {
1683         return at_handling.freeze;
1684 }
1685
1686 int at_freeze_start(void)
1687 {
1688         struct at_sync_request *sync_request = NULL;
1689         struct at_async_request *async_request = NULL;
1690
1691         at_freeze_set(AT_FREEZE_ON);
1692
1693         // Set all the sent requests to freezed state
1694         sync_request = at_sync_request_find_handled(AT_RESPONSE_SENT);
1695         if(sync_request) {
1696                 LOGD("Freezing a pending request");
1697                 sync_request->handled = AT_RESPONSE_SENT_FREEZED;
1698         }
1699
1700         async_request = at_async_request_find_handled(AT_RESPONSE_SENT);
1701         if(async_request) {
1702                 LOGD("Freezing a pending request");
1703                 async_request->handled = AT_RESPONSE_SENT_FREEZED;
1704         }
1705
1706         async_request = at_async_request_find_handled(AT_RESPONSE_UNHANDELD_REASON_STATUS);
1707         if(async_request) {
1708                 LOGD("Freezing a pending request");
1709                 async_request->handled = AT_RESPONSE_SENT_FREEZED;
1710         }
1711
1712         async_request = at_async_request_find_handled(AT_RESPONSE_UNHANDELD_REASON_DATA);
1713         if(async_request) {
1714                 LOGD("Freezing a pending request");
1715                 async_request->handled = AT_RESPONSE_SENT_FREEZED;
1716         }
1717
1718         return 0;
1719 }
1720
1721 int at_freeze_stop(void)
1722 {
1723         at_freeze_set(AT_FREEZE_OFF);
1724
1725         return 0;
1726 }
1727
1728 int at_freeze_send(void)
1729 {
1730         // Allow requests send even though there are freezed requests
1731         at_freeze_set(AT_FREEZE_SEND);
1732
1733         // Unlock responses queue so that the dispatch loop can send setup
1734         AT_RESPONSES_QUEUE_UNLOCK();
1735
1736         return 0;
1737 }
1738
1739 int at_freeze_respawn(void)
1740 {
1741         struct at_sync_request *sync_request = NULL;
1742         struct at_async_request *async_request = NULL;
1743         int rc;
1744
1745         // Respawn the latest request
1746         at_freeze_set(AT_FREEZE_RESPAWN);
1747
1748         // There should only be one
1749         do {
1750                 sync_request = at_sync_request_find_handled(AT_RESPONSE_SENT_FREEZED);
1751                 if(sync_request) {
1752                         sync_request->handled = AT_RESPONSE_WAITING;
1753
1754                         rc = at_request_queue(sync_request->request);
1755                         if(rc < 0) {
1756                                 LOGE("Unable to queue request");
1757
1758                                 // Better trying to dequeue too
1759                                 at_sync_request_dequeue(sync_request);
1760                                 at_sync_request_free(sync_request);
1761                         } else {
1762                                 at_send_next_request();
1763                         }
1764                 }
1765         } while(sync_request != NULL);
1766
1767         do {
1768                 async_request = at_async_request_find_handled(AT_RESPONSE_SENT_FREEZED);
1769                 if(async_request) {
1770                         async_request->handled = AT_RESPONSE_WAITING;
1771
1772                         rc = at_request_queue(async_request->request);
1773                         if(rc < 0) {
1774                                 LOGE("Unable to queue request");
1775
1776                                 // Better trying to dequeue too
1777                                 at_async_request_dequeue(async_request);
1778                                 at_async_request_free(async_request);
1779                         } else {
1780                                 at_send_next_request();
1781                         }
1782                 }
1783         } while(async_request != NULL);
1784
1785         return 0;
1786 }
1787
1788 /*
1789  * Request
1790  */
1791
1792 int at_request_send(struct at_request *request)
1793 {
1794         char *string = NULL;
1795         int length = 0;
1796
1797         int offset_separator_begin = 0;
1798         int length_separator_begin = 0;
1799         int offset_command = 0;
1800         int length_command = 0;
1801         int offset_data_separator = 0;
1802         int length_data_separator = 0;
1803         int offset_data = 0;
1804         int length_data = 0;
1805         int offset_separator_end = 0;
1806         int length_separator_end = 0;
1807
1808         int i, p;
1809
1810         // TODO: Do we send \r\n or only \r, begining/end or just end?
1811         char separator[] = "\r\n";
1812         char data_separator[] = "=";
1813
1814         if(request->command == NULL)
1815                 return -1;
1816
1817         offset_separator_begin = 0;
1818         length_separator_begin = strlen(separator);
1819         length += length_separator_begin;
1820
1821         offset_command = length;
1822         length_command = strlen(request->command);
1823         length += length_command;
1824
1825         if(request->data != NULL) {
1826                 offset_data_separator = length;
1827                 length_data_separator = strlen(data_separator);
1828                 length += length_data_separator;
1829
1830                 offset_data = length;
1831                 length_data = strlen(request->data);
1832                 length += length_data;
1833         }
1834
1835         offset_separator_end = length;
1836         length_separator_end = strlen(separator);
1837         length += length_separator_end;
1838
1839         // Alloc final string
1840         string = calloc(1, length);
1841
1842         // Copy the data to the string
1843         memcpy(string + offset_separator_begin, separator, length_separator_begin);
1844         memcpy(string + offset_command, request->command, length_command);
1845         if(request->data != NULL) {
1846                 memcpy(string + offset_data_separator, data_separator, length_data_separator);
1847                 memcpy(string + offset_data, request->data, length_data);
1848         }
1849         memcpy(string + offset_separator_end, separator, length_separator_end);
1850
1851         // Log request
1852         RIL_LOG_LOCK();
1853         ril_data_log(string, length);
1854         ril_send_log(request);
1855         RIL_LOG_UNLOCK();
1856
1857         ril_device_transport_send(ril_device, string, length);
1858
1859         free(string);
1860
1861         return 0;
1862 }
1863
1864 struct at_request *at_request_create(char *command, char *data)
1865 {
1866         struct at_request *request = NULL;
1867         int i;
1868
1869         if(command == NULL)
1870                 return NULL;
1871
1872         request = calloc(1, sizeof(struct at_request));
1873
1874         asprintf(&(request->command), "%s", command);
1875
1876         if(data != NULL) {
1877                 asprintf(&(request->data), "%s", data);
1878         }
1879
1880         return request;
1881 }
1882
1883 void at_request_free(struct at_request *request)
1884 {
1885         if(request->command != NULL) 
1886                 free(request->command);
1887
1888         if(request->data != NULL)
1889                 free(request->data);
1890
1891         if(request->error != NULL)
1892                 free(request->error);
1893
1894         memset(request, 0, sizeof(struct at_request *));
1895 }
1896
1897 int at_request_send_async(struct at_request *request, void *data, RIL_Token token, at_async_request_cb func)
1898 {
1899         struct at_async_request *async_request = NULL;
1900         int rc;
1901         int i;
1902
1903         if(request->command == NULL || func == NULL)
1904                 return -1;
1905
1906         async_request = calloc(1, sizeof(struct at_async_request));
1907         async_request->handled = AT_RESPONSE_WAITING;
1908         async_request->request = request;
1909         async_request->command = strdup(request->command);
1910         async_request->data = data;
1911         async_request->token = token;
1912         async_request->func = func;
1913
1914         if(at_freeze_get() == AT_FREEZE_SEND)
1915                 async_request->handled = AT_RESPONSE_UNFREEZE;
1916
1917         rc = at_async_request_queue(async_request);
1918         if(rc < 0) {
1919                 LOGE("Unable to queue async request");
1920
1921                 at_async_request_free(async_request);
1922                 return -1;
1923         }
1924
1925         // Do not queue the request when sending while freeze
1926         if(at_freeze_get() == AT_FREEZE_SEND)
1927                 goto request_send;
1928
1929         rc = at_request_queue(request);
1930         if(rc < 0) {
1931                 LOGE("Unable to queue request");
1932
1933                 // Better trying to dequeue too
1934                 at_async_request_dequeue(async_request);
1935                 at_async_request_free(async_request);
1936                 return NULL;
1937         }
1938
1939 request_send:
1940         // Try to send it now, don't fail if it can't
1941         at_send_next_request();
1942
1943         return 0;
1944 }
1945
1946 struct at_response *at_request_send_sync(struct at_request *request)
1947 {
1948         struct at_sync_request *sync_request = NULL;
1949         struct at_response *response = NULL;
1950         int rc;
1951         int i;
1952
1953         if(request->command == NULL)
1954                 return NULL;
1955
1956         sync_request = calloc(1, sizeof(struct at_sync_request));
1957         sync_request->handled = AT_RESPONSE_WAITING;
1958         sync_request->request = request;
1959         sync_request->command = strdup(request->command);
1960
1961         if(at_freeze_get() == AT_FREEZE_SEND)
1962                 sync_request->handled = AT_RESPONSE_UNFREEZE;
1963
1964         rc = at_sync_request_queue(sync_request);
1965         if(rc < 0) {
1966                 LOGE("Unable to queue sync request");
1967
1968                 at_sync_request_free(sync_request);
1969                 return NULL;
1970         }
1971
1972         // Do not queue the request when sending while freeze
1973         if(at_freeze_get() == AT_FREEZE_SEND)
1974                 goto request_send;
1975
1976         rc = at_request_queue(request);
1977         if(rc < 0) {
1978                 LOGE("Unable to queue request");
1979
1980                 // Better trying to dequeue too
1981                 at_sync_request_dequeue(sync_request);
1982                 at_sync_request_free(sync_request);
1983                 return NULL;
1984         }
1985
1986 request_send:
1987         // Try to send it now, don't fail if it can't
1988         at_send_next_request();
1989
1990         // Block until there is a response available
1991         at_sync_requests_queue_lock();
1992
1993         if(sync_request->response == NULL) {
1994                 LOGE("Sync queue was unlocked but there is no response, aborting");
1995
1996                 // Remove the request
1997                 at_request_dequeue(request);
1998
1999                 // Better trying to dequeue too
2000                 at_sync_request_dequeue(sync_request);
2001                 at_sync_request_free(sync_request);
2002
2003                 // Send the next request in the queue
2004                 at_send_next_request();
2005
2006                 return NULL;
2007         }
2008
2009         response = sync_request->response;
2010
2011         at_sync_request_dequeue(sync_request);
2012         at_sync_request_free(sync_request);
2013
2014         // Send the next request in the queue
2015         at_send_next_request();
2016
2017         return response;
2018 }
2019
2020 /*
2021  * Send
2022  */
2023
2024 int at_send_next_request(void)
2025 {
2026         struct at_sync_request *sync_request = NULL;
2027         struct at_async_request *async_request = NULL;
2028         struct at_async_request *async_request_sent = NULL;
2029         struct at_async_request *async_request_unhandled_status = NULL;
2030         struct at_async_request *async_request_unhandled_data = NULL;
2031         struct at_request *request = NULL;
2032         int rc;
2033
2034         if(at_freeze_get() == AT_FREEZE_SEND) {
2035                 sync_request = at_sync_request_find_handled(AT_RESPONSE_UNFREEZE);
2036                 if(sync_request != NULL) {
2037                         LOGD("Found an unfreeze sync request!");
2038                         request = sync_request->request;
2039                         goto request_send;
2040                 }
2041
2042                 async_request = at_async_request_find_handled(AT_RESPONSE_UNFREEZE);
2043                 if(async_request != NULL) {
2044                         LOGD("Found an unfreeze async request!");
2045                         request = async_request->request;
2046                         goto request_send;
2047                 }
2048
2049                 LOGD("No unfreeze request to send!");
2050                 return 0;
2051         }
2052
2053         // Unhandled requests are still going on too
2054         sync_request = at_sync_request_find_handled(AT_RESPONSE_SENT);
2055         async_request_sent = at_async_request_find_handled(AT_RESPONSE_SENT);
2056         async_request_unhandled_status = at_async_request_find_handled(AT_RESPONSE_UNHANDELD_REASON_STATUS);
2057         async_request_unhandled_data = at_async_request_find_handled(AT_RESPONSE_UNHANDELD_REASON_DATA);
2058
2059         if(sync_request != NULL || async_request_sent != NULL || async_request_unhandled_status != NULL || async_request_unhandled_data != NULL) {
2060                 LOGE("There are still unanswered requests!");
2061                 return -1;
2062         }
2063
2064         request = at_request_dequeue(NULL);
2065         if(request == NULL) {
2066                 LOGD("Nothing left to send!");
2067                 return 0;
2068         }
2069
2070 request_send:
2071         rc = at_request_send(request);
2072         if(rc < 0) {
2073                 LOGE("Unable to send request, aborting!");
2074                 at_request_free(request);
2075                 return -1;
2076         }
2077
2078         sync_request = at_sync_request_find_request(request);
2079         if(sync_request != NULL)
2080                 sync_request->handled = AT_RESPONSE_SENT;
2081
2082         async_request = at_async_request_find_request(request);
2083         if(async_request != NULL)
2084                 async_request->handled = AT_RESPONSE_SENT;
2085
2086         return 0;
2087 }
2088
2089 struct at_response *at_send_sync(char *command, char *data)
2090 {
2091         struct at_request *request = NULL;
2092         struct at_response *response = NULL;
2093
2094         request = at_request_create(command, data);
2095         if(request == NULL) {
2096                 LOGE("Unable to create request, aborting");
2097                 return -1;
2098         }
2099
2100         response = at_request_send_sync(request);
2101         if(response == NULL) {
2102                 at_request_free(request);
2103                 return NULL;
2104         }
2105
2106         return response;
2107 }
2108
2109 int at_send_expect_to_func(char *command, char *data, void *async_data, RIL_Token token, at_async_request_cb func)
2110 {
2111         struct at_request *request = NULL;
2112         int rc;
2113
2114         request = at_request_create(command, data);
2115         if(request == NULL) {
2116                 LOGE("Unable to create request, aborting");
2117                 return -1;
2118         }
2119
2120         rc = at_request_send_async(request, async_data, token, func);
2121         if(rc < 0) {
2122                 LOGE("Unable to send async request, aborting");
2123                 at_request_free(request);
2124                 return -1;
2125         }
2126
2127         return 0;
2128 }
2129
2130 int at_send_expect_status(char *command, char *data)
2131 {
2132         struct at_response *response = NULL;
2133         int status;
2134
2135         response = at_send_sync(command, data);
2136         if(response == NULL) {
2137                 LOGE("Unable to get sync response, aborting");
2138                 return -1;
2139         }
2140
2141         status = response->status;
2142
2143         at_response_free(response);
2144
2145         return status;
2146 }
2147
2148 int at_send_noresp(char *command, char *data)
2149 {
2150         struct at_response *response;
2151
2152         response = at_send(command, data);
2153         if(response != NULL) {
2154                 at_response_free(response);
2155                 return 0;
2156         } else {
2157                 return -1;
2158         }
2159 }
2160
2161 struct at_response *at_send_command(char *command)
2162 {
2163         return at_send(command, NULL);
2164 }
2165
2166 struct at_response *at_send(char *command, char *data)
2167 {
2168         struct at_request *request = NULL;
2169         struct at_response *response = NULL;
2170         int rc;
2171
2172         request = at_request_create(command, data);
2173         if(request == NULL) {
2174                 LOGE("Unable to create request, aborting!");
2175                 return -1;
2176         }
2177
2178         response = at_request_send_sync(request);
2179         if(response == NULL) {
2180                 LOGE("Unable to get sync response, aborting");
2181
2182                 at_request_free(request);
2183                 return -1;
2184         }
2185
2186         return response;
2187 }