541766cd287b414e8e54a03d950c19e9df1dfb5e
[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         // First lock to the queues mutexes
694         AT_RESPONSES_QUEUE_LOCK();
695         AT_SYNC_QUEUE_LOCK();
696 }
697
698 /*
699  * Responses queue
700  */
701
702 // Unlock the responses queue after queuing all the available requests
703 void at_responses_queue_unlock(void)
704 {
705         if(at_handling.responses_queue.responses_count <= 0 || at_handling.responses_queue.responses == NULL)
706                 return;
707
708         AT_RESPONSES_QUEUE_UNLOCK();
709 }
710
711 // Queue one response to the responses queue
712 int at_response_queue(struct at_response *response)
713 {
714         struct at_response **responses = NULL;
715         int responses_count = 0;
716         int index;
717         int count;
718
719         if(response == NULL)
720                 return -1;
721
722         AT_RESPONSES_LOCK();
723
724         // Save the previous data pointer and count
725         responses = at_handling.responses_queue.responses;
726         responses_count = at_handling.responses_queue.responses_count;
727
728         if(responses_count < 0)
729                 responses_count = 0;
730
731         // Index is the response index in the responses array
732         index = responses_count;
733         // Count is the total count of responses in the array
734         count = index + 1;
735
736         // Alloc the array with the new size
737         at_handling.responses_queue.responses = malloc(sizeof(struct at_response *) * count);
738         at_handling.responses_queue.responses_count = count;
739
740         // Copy and free previous data
741         if(responses != NULL && responses_count > 0) {
742                 memcpy(at_handling.responses_queue.responses, responses, sizeof(struct at_response *) * at_handling.responses_queue.responses_count);
743                 free(responses);
744         }
745
746         // Get the new data pointer and count
747         responses = at_handling.responses_queue.responses;
748         responses_count = at_handling.responses_queue.responses_count;
749
750         // Put the response in the queue
751         responses[index] = response;
752
753         LOGD("%d elements in the responses queue", responses_count);
754
755         AT_RESPONSES_UNLOCK();
756
757         return 0;
758 }
759
760 // Unqueue the oldest response in the queue
761 struct at_response *at_response_dequeue(void)
762 {
763         struct at_response *response = NULL;
764         struct at_response **responses = NULL;
765         int responses_count = 0;
766         int pos = -1;
767         int i;
768
769         AT_RESPONSES_LOCK();
770
771         // Save the previous data pointer and count
772         responses = at_handling.responses_queue.responses;
773         responses_count = at_handling.responses_queue.responses_count;
774
775         while(responses_count <= 0 || responses == NULL) {
776                 LOGE("No response queued, blocking!");
777
778                 AT_RESPONSES_UNLOCK();
779                 AT_RESPONSES_QUEUE_LOCK();
780                 AT_RESPONSES_LOCK();
781
782                 // Get the new data pointer and count
783                 responses = at_handling.responses_queue.responses;
784                 responses_count = at_handling.responses_queue.responses_count;
785
786                 LOGE("Unblocking: %d new responses queued!", responses_count);
787         }
788
789         for(i=0 ; i < responses_count ; i++) {
790                 if(responses[i] != NULL) {
791                         response = responses[i];
792                         pos = i;
793                         break;
794                 }
795         }
796
797         if(response == NULL || pos < 0) {
798                 LOGD("Found no valid response, aborting!");
799
800                 AT_RESPONSES_UNLOCK();
801                 return NULL;
802         }
803
804         // Empty the found position in the responses array
805         responses[pos] = NULL;
806
807         // Move the elements back
808         for(i=pos ; i < responses_count-1 ; i++) {
809                 responses[i] = responses[i+1];
810         }
811
812         // Empty the latest element
813         if(pos != responses_count-1) {
814                 responses[responses_count-1] = NULL;
815         }
816
817         responses_count--;
818
819         if(responses_count == 0) {
820                 free(responses);
821                 at_handling.responses_queue.responses = NULL;
822         }
823
824         at_handling.responses_queue.responses_count = responses_count;
825
826         LOGD("%d elements in the responses queue", responses_count);
827
828         AT_RESPONSES_UNLOCK();
829
830         return response;
831 }
832
833 /*
834  * Requests queue
835  */
836
837 // Queue one request to the requests queue
838 int at_request_queue(struct at_request *request)
839 {
840         struct at_request **requests = NULL;
841         int requests_count = 0;
842         int index;
843         int count;
844
845         if(request == NULL)
846                 return -1;
847
848         AT_REQUESTS_LOCK();
849
850         // Save the previous data pointer and count
851         requests = at_handling.requests_queue.requests;
852         requests_count = at_handling.requests_queue.requests_count;
853
854         if(requests_count < 0)
855                 requests_count = 0;
856
857         // Index is the request index in the requests array
858         index = requests_count;
859         // Count is the total count of requests in the array
860         count = index + 1;
861
862         // Alloc the array with the new size
863         at_handling.requests_queue.requests = malloc(sizeof(struct at_request *) * count);
864         at_handling.requests_queue.requests_count = count;
865
866         // Copy and free previous data
867         if(requests != NULL && requests_count > 0) {
868                 memcpy(at_handling.requests_queue.requests, requests, sizeof(struct at_request *) * at_handling.requests_queue.requests_count);
869                 free(requests);
870         }
871
872         // Get the new data pointer and count
873         requests = at_handling.requests_queue.requests;
874         requests_count = at_handling.requests_queue.requests_count;
875
876         // Put the request in the queue
877         requests[index] = request;
878
879         LOGD("%d elements in the requests queue", requests_count);
880
881         AT_REQUESTS_UNLOCK();
882
883         return 0;
884 }
885
886 // Unqueue the oldest request in the queue
887 struct at_request *at_request_dequeue(void)
888 {
889         struct at_request *request = NULL;
890         struct at_request **requests = NULL;
891         int requests_count = 0;
892         int pos = -1;
893         int i;
894
895         AT_REQUESTS_LOCK();
896
897         // Save the previous data pointer and count
898         requests = at_handling.requests_queue.requests;
899         requests_count = at_handling.requests_queue.requests_count;
900
901         if(requests_count <= 0 || requests == NULL) {
902                 LOGE("No requests queued!");
903
904                 AT_REQUESTS_UNLOCK();
905                 return NULL;
906         }
907
908         for(i=0 ; i < requests_count ; i++) {
909                 if(requests[i] != NULL) {
910                         request = requests[i];
911                         pos = i;
912                         break;
913                 }
914         }
915
916         if(requests == NULL || pos < 0) {
917                 LOGD("Found no valid request, aborting!");
918
919                 AT_REQUESTS_UNLOCK();
920                 return NULL;
921         }
922
923         // Empty the found position in the requests array
924         requests[pos] = NULL;
925
926         // Move the elements back
927         for(i=pos ; i < requests_count-1 ; i++) {
928                 requests[i] = requests[i+1];
929         }
930
931         // Empty the latest element
932         if(pos != requests_count-1) {
933                 requests[requests_count-1] = NULL;
934         }
935
936         requests_count--;
937
938         if(requests_count == 0) {
939                 free(requests);
940                 at_handling.requests_queue.requests = NULL;
941         }
942
943         at_handling.requests_queue.requests_count = requests_count;
944
945         LOGD("%d elements in the requests queue", requests_count);
946
947         AT_REQUESTS_UNLOCK();
948
949         return request;
950 }
951
952 /*
953  * Async requests queue
954  */
955
956 // Free the async request
957 void at_async_request_free(struct at_async_request *async_request)
958 {
959         if(async_request == NULL)
960                 return;
961
962         if(async_request->command)
963                 free(async_request->command);
964
965         memset(async_request, 0, sizeof(struct at_async_request));
966         async_request->handled = AT_RESPONSE_GARBAGE;
967 }
968
969 // Find an async request from its command
970 struct at_async_request *at_async_request_find_command(char *command)
971 {
972         struct at_async_request *async_request = NULL;
973         struct at_async_request **async_requests = NULL;
974         int async_requests_count = 0;
975         int i;
976
977         if(command == NULL)
978                 return NULL;
979
980         AT_ASYNC_LOCK();
981
982         // Save the previous data pointer and count
983         async_requests = at_handling.async_requests_queue.async_requests;
984         async_requests_count = at_handling.async_requests_queue.async_requests_count;
985
986         if(async_requests_count <= 0 || async_requests == NULL) {
987                 AT_ASYNC_UNLOCK();
988                 return NULL;
989         }
990
991         for(i=0 ; i < async_requests_count ; i++) {
992                 if(async_requests[i] != NULL && async_requests[i]->command != NULL) {
993                         if(at_commands_compare(command, async_requests[i]->command)) {
994                                 async_request = async_requests[i];
995                                 break;
996                         }
997                 }
998         }
999
1000         AT_ASYNC_UNLOCK();
1001
1002         return async_request;
1003 }
1004
1005 // Find an async request from its handled status
1006 struct at_async_request *at_async_request_find_handled(int handled)
1007 {
1008         struct at_async_request *async_request = NULL;
1009         struct at_async_request **async_requests = NULL;
1010         int async_requests_count = 0;
1011         int i;
1012
1013         AT_ASYNC_LOCK();
1014
1015         // Save the previous data pointer and count
1016         async_requests = at_handling.async_requests_queue.async_requests;
1017         async_requests_count = at_handling.async_requests_queue.async_requests_count;
1018
1019         if(async_requests_count <= 0 || async_requests == NULL) {
1020                 AT_ASYNC_UNLOCK();
1021                 return NULL;
1022         }
1023
1024         for(i=0 ; i < async_requests_count ; i++) {
1025                 if(async_requests[i] != NULL) {
1026                         if(async_requests[i]->handled == handled) {
1027                                 async_request = async_requests[i];
1028                                 break;
1029                         }
1030                 }
1031         }
1032
1033         AT_ASYNC_UNLOCK();
1034
1035         return async_request;
1036 }
1037
1038 // Find an async request from its request pointer
1039 struct at_async_request *at_async_request_find_request(struct at_request *request)
1040 {
1041         struct at_async_request *async_request = NULL;
1042         struct at_async_request **async_requests = NULL;
1043         int async_requests_count = 0;
1044         int i;
1045
1046         if(request == NULL)
1047                 return NULL;
1048
1049         AT_ASYNC_LOCK();
1050
1051         // Save the previous data pointer and count
1052         async_requests = at_handling.async_requests_queue.async_requests;
1053         async_requests_count = at_handling.async_requests_queue.async_requests_count;
1054
1055         if(async_requests_count <= 0 || async_requests == NULL) {
1056                 AT_ASYNC_UNLOCK();
1057                 return NULL;
1058         }
1059
1060         for(i=0 ; i < async_requests_count ; i++) {
1061                 if(async_requests[i] != NULL) {
1062                         if(async_requests[i]->request == request) {
1063                                 async_request = async_requests[i];
1064                                 break;
1065                         }
1066                 }
1067         }
1068
1069         AT_ASYNC_UNLOCK();
1070
1071         return async_request;
1072 }
1073
1074 // Find an async request from its response pointer
1075 struct at_async_request *at_async_request_find_response(struct at_response *response)
1076 {
1077         struct at_async_request *async_request = NULL;
1078         struct at_async_request **async_requests = NULL;
1079         int async_requests_count = 0;
1080         int i;
1081
1082         if(response == NULL)
1083                 return NULL;
1084
1085         AT_ASYNC_LOCK();
1086
1087         // Save the previous data pointer and count
1088         async_requests = at_handling.async_requests_queue.async_requests;
1089         async_requests_count = at_handling.async_requests_queue.async_requests_count;
1090
1091         if(async_requests_count <= 0 || async_requests == NULL) {
1092                 AT_ASYNC_UNLOCK();
1093                 return NULL;
1094         }
1095
1096         for(i=0 ; i < async_requests_count ; i++) {
1097                 if(async_requests[i] != NULL && async_requests[i]->response != NULL) {
1098                         if(async_requests[i]->response == response) {
1099                                 async_request = async_requests[i];
1100                                 break;
1101                         }
1102                 }
1103         }
1104
1105         AT_ASYNC_UNLOCK();
1106
1107         return async_request;
1108 }
1109
1110 // Queue one request to the async requests queue
1111 int at_async_request_queue(struct at_async_request *async_request)
1112 {
1113         struct at_async_request **async_requests = NULL;
1114         int async_requests_count = 0;
1115         int index;
1116         int count;
1117
1118         if(async_request == NULL)
1119                 return -1;
1120
1121         AT_ASYNC_LOCK();
1122
1123         // Save the previous data pointer and count
1124         async_requests = at_handling.async_requests_queue.async_requests;
1125         async_requests_count = at_handling.async_requests_queue.async_requests_count;
1126
1127         if(async_requests_count < 0)
1128                 async_requests_count = 0;
1129
1130         // Index is the sync request index in the sync requests array
1131         index = async_requests_count;
1132         // Count is the total count of sync requests in the array
1133         count = index + 1;
1134
1135         // Alloc the array with the new size
1136         at_handling.async_requests_queue.async_requests = malloc(sizeof(struct at_async_request *) * count);
1137         at_handling.async_requests_queue.async_requests_count = count;
1138
1139         // Copy and free previous data
1140         if(async_requests != NULL && async_requests_count > 0) {
1141                 memcpy(at_handling.async_requests_queue.async_requests, async_requests, sizeof(struct at_async_request *) * at_handling.async_requests_queue.async_requests_count);
1142                 free(async_requests);
1143         }
1144
1145         // Get the new data pointer and count
1146         async_requests = at_handling.async_requests_queue.async_requests;
1147         async_requests_count = at_handling.async_requests_queue.async_requests_count;
1148
1149         // Put the sync request in the queue
1150         async_requests[index] = async_request;
1151
1152         LOGD("%d elements in the async requests queue", async_requests_count);
1153
1154         AT_ASYNC_UNLOCK();
1155
1156         return 0;
1157 }
1158
1159 int at_async_response_dequeue(struct at_response *response)
1160 {
1161         struct at_async_request *async_request = NULL;
1162         int rc;
1163
1164         if(response == NULL)
1165                 return -1;
1166
1167         // First, try to grab the async request from the response, if it was already filled by sync dequeue
1168         async_request = at_async_request_find_response(response);
1169         if(async_request == NULL || async_request->func == NULL) {
1170                 // Then, try to find an unhandled response
1171
1172                 async_request = at_async_request_find_handled(AT_RESPONSE_UNHANDELD_REASON_STATUS);
1173                 if(async_request == NULL || async_request->func == NULL) {
1174                         // Finally, grab the async request from the command
1175
1176                         async_request = at_async_request_find_command(response->command);
1177                         if(async_request == NULL || async_request->func == NULL) {
1178                                 return -1;
1179                         }
1180                 }
1181
1182                 // FIXME: What if there is already a response with valid data?
1183
1184                 async_request->response = response;
1185         }
1186
1187         LOGD("Found a matching request for %s!", async_request->command);
1188
1189         // This prevents sync data not to be reported when the same command is issued in func and previous handled was unhandled for status reason
1190         async_request->handled = AT_RESPONSE_SENT;
1191
1192         at_async_request_dequeue(async_request);
1193
1194         rc = async_request->func(response, async_request->data, async_request->token);
1195
1196         // If the request was unhandled, update its status and requeue
1197         if(rc == AT_RESPONSE_UNHANDELD_REASON_STATUS) {
1198                 LOGD("Response not handled (missing status)");
1199                 async_request->handled = AT_RESPONSE_UNHANDELD_REASON_STATUS;
1200                 at_async_request_queue(async_request);
1201         } else if(rc == AT_RESPONSE_UNHANDELD_REASON_DATA) {
1202                 LOGD("Response not handled (missing data)");
1203                 async_request->handled = AT_RESPONSE_UNHANDELD_REASON_DATA;
1204                 at_async_request_queue(async_request);
1205         } else {
1206                 LOGD("Response was handled!");
1207
1208                 // We can free the request
1209                 at_async_request_free(async_request);
1210
1211                 // Send the next request in the queue
1212                 at_send_next_request();
1213         }
1214
1215         return 0;
1216 }
1217
1218 // Dequeue one async request (only remove from the queue)
1219 int at_async_request_dequeue(struct at_async_request *async_request)
1220 {
1221         struct at_async_request **async_requests = NULL;
1222         int async_requests_count = 0;
1223         int pos = -1;
1224         int i;
1225
1226         if(async_request == NULL)
1227                 return -1;
1228
1229         AT_ASYNC_LOCK();
1230
1231         // Save the previous data pointer and count
1232         async_requests = at_handling.async_requests_queue.async_requests;
1233         async_requests_count = at_handling.async_requests_queue.async_requests_count;
1234
1235         if(async_requests_count <= 0 || async_requests == NULL) {
1236                 LOGE("No async requests queued, aborting dequeue!");
1237
1238                 AT_ASYNC_UNLOCK();
1239                 return -1;
1240         }
1241
1242         for(i=0 ; i < async_requests_count ; i++) {
1243                 if(async_requests[i] == async_request) {
1244                         pos = i;
1245                         break;
1246                 }
1247         }
1248
1249         if(pos < 0) {
1250                 LOGD("Found no matching async request, aborting dequeue!");
1251
1252                 AT_ASYNC_UNLOCK();
1253                 return -1;
1254         }
1255
1256         // Empty the found position in the async requests array
1257         async_requests[pos] = NULL;
1258
1259         // Move the elements back
1260         for(i=pos ; i < async_requests_count-1 ; i++) {
1261                 async_requests[i] = async_requests[i+1];
1262         }
1263
1264         // Empty the latest element
1265         if(pos != async_requests_count-1) {
1266                 async_requests[async_requests_count-1] = NULL;
1267         }
1268
1269         async_requests_count--;
1270
1271         if(async_requests_count == 0) {
1272                 free(async_requests);
1273                 at_handling.async_requests_queue.async_requests = NULL;
1274         }
1275
1276         at_handling.async_requests_queue.async_requests_count = async_requests_count;
1277
1278         LOGD("%d elements in the async requests queue", async_requests_count);
1279
1280         AT_ASYNC_UNLOCK();
1281
1282         return 0;
1283 }
1284
1285 /*
1286  * Sync requests queue
1287  */
1288
1289 // Lock the sync requests queue
1290 void at_sync_requests_queue_lock(void)
1291 {
1292         AT_SYNC_QUEUE_LOCK();
1293 }
1294
1295 // Unlock the sync requests queue
1296 void at_sync_requests_queue_unlock(void)
1297 {
1298         AT_SYNC_QUEUE_UNLOCK();
1299 }
1300
1301 // Free the sync request
1302 void at_sync_request_free(struct at_sync_request *sync_request)
1303 {
1304         if(sync_request == NULL)
1305                 return;
1306
1307         if(sync_request->command)
1308                 free(sync_request->command);
1309
1310         memset(sync_request, 0, sizeof(struct at_sync_request));
1311         sync_request->handled = AT_RESPONSE_GARBAGE;
1312 }
1313
1314 // Whether the sync queue is empty
1315 int at_sync_queue_empty(void)
1316 {
1317         struct at_sync_request *sync_request = NULL;
1318         struct at_sync_request **sync_requests = NULL;
1319         int sync_requests_count;
1320
1321         int empty = 1;
1322
1323         AT_SYNC_LOCK();
1324
1325         // Save the previous data pointer and count
1326         sync_requests = at_handling.sync_requests_queue.sync_requests;
1327         sync_requests_count = at_handling.sync_requests_queue.sync_requests_count;
1328
1329         if(sync_requests_count <= 0 || sync_requests == NULL)
1330                 empty = 1;
1331         else
1332                 empty = 0;
1333
1334         AT_SYNC_UNLOCK();
1335
1336         return empty;
1337 }
1338
1339 // Find a sync request from its command
1340 struct at_sync_request *at_sync_request_find_command(char *command)
1341 {
1342         struct at_sync_request *sync_request = NULL;
1343         struct at_sync_request **sync_requests = NULL;
1344         int sync_requests_count = 0;
1345         int i;
1346
1347         if(command == NULL)
1348                 return NULL;
1349
1350         AT_SYNC_LOCK();
1351
1352         // Save the previous data pointer and count
1353         sync_requests = at_handling.sync_requests_queue.sync_requests;
1354         sync_requests_count = at_handling.sync_requests_queue.sync_requests_count;
1355
1356         if(sync_requests_count <= 0 || sync_requests == NULL) {
1357                 AT_SYNC_UNLOCK();
1358                 return NULL;
1359         }
1360
1361         for(i=0 ; i < sync_requests_count ; i++) {
1362                 if(sync_requests[i] != NULL && sync_requests[i]->command != NULL) {
1363                         if(at_commands_compare(command, sync_requests[i]->command)) {
1364                                 sync_request = sync_requests[i];
1365                                 break;
1366                         }
1367                 }
1368         }
1369
1370         AT_SYNC_UNLOCK();
1371
1372         return sync_request;
1373 }
1374
1375 // Find a sync request from its handled status
1376 struct at_sync_request *at_sync_request_find_handled(int handled)
1377 {
1378         struct at_sync_request *sync_request = NULL;
1379         struct at_sync_request **sync_requests = NULL;
1380         int sync_requests_count = 0;
1381         int i;
1382
1383         AT_SYNC_LOCK();
1384
1385         // Save the previous data pointer and count
1386         sync_requests = at_handling.sync_requests_queue.sync_requests;
1387         sync_requests_count = at_handling.sync_requests_queue.sync_requests_count;
1388
1389         if(sync_requests_count <= 0 || sync_requests == NULL) {
1390                 AT_SYNC_UNLOCK();
1391                 return NULL;
1392         }
1393
1394         for(i=0 ; i < sync_requests_count ; i++) {
1395                 if(sync_requests[i] != NULL) {
1396                         if(sync_requests[i]->handled == handled) {
1397                                 sync_request = sync_requests[i];
1398                                 break;
1399                         }
1400                 }
1401         }
1402
1403         AT_SYNC_UNLOCK();
1404
1405         return sync_request;
1406 }
1407
1408 // Find a sync request from its request pointer
1409 struct at_sync_request *at_sync_request_find_request(struct at_request *request)
1410 {
1411         struct at_sync_request *sync_request = NULL;
1412         struct at_sync_request **sync_requests = NULL;
1413         int sync_requests_count = 0;
1414         int i;
1415
1416         if(request == NULL)
1417                 return NULL;
1418
1419         AT_SYNC_LOCK();
1420
1421         // Save the previous data pointer and count
1422         sync_requests = at_handling.sync_requests_queue.sync_requests;
1423         sync_requests_count = at_handling.sync_requests_queue.sync_requests_count;
1424
1425         if(sync_requests_count <= 0 || sync_requests == NULL) {
1426                 AT_SYNC_UNLOCK();
1427                 return NULL;
1428         }
1429
1430         for(i=0 ; i < sync_requests_count ; i++) {
1431                 if(sync_requests[i] != NULL) {
1432                         if(sync_requests[i]->request == request) {
1433                                 sync_request = sync_requests[i];
1434                                 break;
1435                         }
1436                 }
1437         }
1438
1439         AT_SYNC_UNLOCK();
1440
1441         return sync_request;
1442 }
1443
1444 // Queue one request to the sync requests queue
1445 int at_sync_request_queue(struct at_sync_request *sync_request)
1446 {
1447         struct at_sync_request **sync_requests = NULL;
1448         int sync_requests_count = 0;
1449         int index;
1450         int count;
1451
1452         if(sync_request == NULL)
1453                 return -1;
1454
1455         AT_SYNC_LOCK();
1456
1457         // Save the previous data pointer and count
1458         sync_requests = at_handling.sync_requests_queue.sync_requests;
1459         sync_requests_count = at_handling.sync_requests_queue.sync_requests_count;
1460
1461         if(sync_requests_count < 0)
1462                 sync_requests_count = 0;
1463
1464         // Index is the sync request index in the sync requests array
1465         index = sync_requests_count;
1466         // Count is the total count of sync requests in the array
1467         count = index + 1;
1468
1469         // Alloc the array with the new size
1470         at_handling.sync_requests_queue.sync_requests = malloc(sizeof(struct at_sync_request *) * count);
1471         at_handling.sync_requests_queue.sync_requests_count = count;
1472
1473         // Copy and free previous data
1474         if(sync_requests != NULL && sync_requests_count > 0) {
1475                 memcpy(at_handling.sync_requests_queue.sync_requests, sync_requests, sizeof(struct at_sync_request *) * at_handling.sync_requests_queue.sync_requests_count);
1476                 free(sync_requests);
1477         }
1478
1479         // Get the new data pointer and count
1480         sync_requests = at_handling.sync_requests_queue.sync_requests;
1481         sync_requests_count = at_handling.sync_requests_queue.sync_requests_count;
1482
1483         // Put the sync request in the queue
1484         sync_requests[index] = sync_request;
1485
1486         LOGD("%d elements in the sync requests queue", sync_requests_count);
1487
1488         AT_SYNC_UNLOCK();
1489
1490         return 0;
1491 }
1492
1493 // Dequeue one response (that will or not be assigned to a sync request)
1494 int at_sync_response_dequeue(struct at_response *response)
1495 {
1496         struct at_sync_request *sync_request = NULL;
1497         struct at_async_request *async_request = NULL;
1498         int rc;
1499
1500         if(response == NULL)
1501                 return -1;
1502
1503         if(response->command != NULL && !at_sync_queue_empty()) {
1504                 if(response->status == AT_STATUS_UNDEF && (response->data == NULL || response->data_count <= 0)) {
1505                         // Check if this is a part of a queued sync command
1506
1507                         sync_request = at_sync_request_find_command(response->command);
1508                         if(sync_request != NULL && sync_request->handled == AT_RESPONSE_SENT) {
1509                                 // This will make this sync request the next one to get a status
1510
1511                                 sync_request->handled = AT_RESPONSE_UNHANDELD_REASON_STATUS;
1512
1513                                 LOGD("Skipping matching request with no status nor data!");
1514                                 at_response_free(response);
1515                                 return 0;
1516                         }
1517                 }
1518
1519                 // 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
1520
1521                 sync_request = at_sync_request_find_handled(AT_RESPONSE_SENT);
1522                 if(sync_request == NULL)
1523                         sync_request = at_sync_request_find_handled(AT_RESPONSE_UNHANDELD_REASON_STATUS);
1524
1525                 if(sync_request != NULL && sync_request->command != NULL) {
1526                         // If we catch an unsol or a response for another request, there is something wrong
1527
1528                         rc = at_commands_compare(response->command, sync_request->command);
1529                         if(!rc) {
1530                                 // We don't need to check on the async queue as requests are sent one at a time
1531
1532                                 LOGE("Got a response for another request, aborting!");
1533                                 AT_SYNC_QUEUE_UNLOCK();
1534                                 return -1;
1535                         }
1536                 } else {
1537                         // There is a command but we didn't send any sync request, so don't deal with it
1538
1539                         return -1;
1540                 }
1541         }
1542
1543         // If we have no status at this point, we have no use of the response
1544         if(response->status == AT_STATUS_UNDEF) {
1545                 return -1;
1546         }
1547
1548         // Have no command but a status
1549         if(response->command == NULL) {
1550                 async_request = at_async_request_find_handled(AT_RESPONSE_UNHANDELD_REASON_STATUS);
1551                 if(async_request != NULL) {
1552                         // 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
1553
1554                         async_request->response = response;
1555                         async_request->handled = AT_RESPONSE_SENT;
1556
1557                         LOGD("Found a status for a previous async request!");
1558
1559                         return -1;
1560                 }
1561
1562                 sync_request = at_sync_request_find_handled(AT_RESPONSE_UNHANDELD_REASON_STATUS);
1563                 if(sync_request != NULL) {
1564                         sync_request->handled = AT_RESPONSE_SENT;
1565                 }
1566
1567         }
1568
1569         if(sync_request == NULL) {
1570                 sync_request = at_sync_request_find_handled(AT_RESPONSE_SENT);
1571                 if(sync_request == NULL) {
1572                         LOGE("Got a status but no request waiting for it at all, this should never happend!");
1573                         return -1;
1574                 }
1575         }
1576
1577         sync_request->response = response;
1578         LOGD("Found a response for a sync request!");
1579
1580         AT_SYNC_QUEUE_UNLOCK();
1581
1582         return 0;
1583 }
1584
1585 // Dequeue one sync request (only remove from the queue)
1586 int at_sync_request_dequeue(struct at_sync_request *sync_request)
1587 {
1588         struct at_sync_request **sync_requests = NULL;
1589         int sync_requests_count = 0;
1590         int pos = -1;
1591         int i;
1592
1593         if(sync_request == NULL)
1594                 return -1;
1595
1596         AT_SYNC_LOCK();
1597
1598         // Save the previous data pointer and count
1599         sync_requests = at_handling.sync_requests_queue.sync_requests;
1600         sync_requests_count = at_handling.sync_requests_queue.sync_requests_count;
1601
1602         if(sync_requests_count <= 0 || sync_requests == NULL) {
1603                 LOGE("No sync requests queued, aborting dequeue!");
1604
1605                 AT_SYNC_UNLOCK();
1606                 return -1;
1607         }
1608
1609         for(i=0 ; i < sync_requests_count ; i++) {
1610                 if(sync_requests[i] == sync_request) {
1611                         pos = i;
1612                         break;
1613                 }
1614         }
1615
1616         if(pos < 0) {
1617                 LOGD("Found no matching sync request, aborting dequeue!");
1618
1619                 AT_SYNC_UNLOCK();
1620                 return -1;
1621         }
1622
1623         // Empty the found position in the sync requests array
1624         sync_requests[pos] = NULL;
1625
1626         // Move the elements back
1627         for(i=pos ; i < sync_requests_count-1 ; i++) {
1628                 sync_requests[i] = sync_requests[i+1];
1629         }
1630
1631         // Empty the latest element
1632         if(pos != sync_requests_count-1) {
1633                 sync_requests[sync_requests_count-1] = NULL;
1634         }
1635
1636         sync_requests_count--;
1637
1638         if(sync_requests_count == 0) {
1639                 free(sync_requests);
1640                 at_handling.sync_requests_queue.sync_requests = NULL;
1641         }
1642
1643         at_handling.sync_requests_queue.sync_requests_count = sync_requests_count;
1644
1645         LOGD("%d elements in the sync requests queue", sync_requests_count);
1646
1647         AT_SYNC_UNLOCK();
1648
1649         return 0;
1650 }
1651
1652 /*
1653  * Request
1654  */
1655
1656 int at_request_send(struct at_request *request)
1657 {
1658         char *string = NULL;
1659         int length = 0;
1660
1661         int offset_separator_begin = 0;
1662         int length_separator_begin = 0;
1663         int offset_command = 0;
1664         int length_command = 0;
1665         int offset_data_separator = 0;
1666         int length_data_separator = 0;
1667         int offset_data = 0;
1668         int length_data = 0;
1669         int offset_separator_end = 0;
1670         int length_separator_end = 0;
1671
1672         int i, p;
1673
1674         // TODO: Do we send \r\n or only \r, begining/end or just end?
1675         char separator[] = "\r\n";
1676         char data_separator[] = "=";
1677
1678         if(request->command == NULL)
1679                 return -1;
1680
1681         offset_separator_begin = 0;
1682         length_separator_begin = strlen(separator);
1683         length += length_separator_begin;
1684
1685         offset_command = length;
1686         length_command = strlen(request->command);
1687         length += length_command;
1688
1689         if(request->data != NULL) {
1690                 offset_data_separator = length;
1691                 length_data_separator = strlen(data_separator);
1692                 length += length_data_separator;
1693
1694                 offset_data = length;
1695                 length_data = strlen(request->data);
1696                 length += length_data;
1697         }
1698
1699         offset_separator_end = length;
1700         length_separator_end = strlen(separator);
1701         length += length_separator_end;
1702
1703         // Alloc final string
1704         string = calloc(1, length);
1705
1706         // Copy the data to the string
1707         memcpy(string + offset_separator_begin, separator, length_separator_begin);
1708         memcpy(string + offset_command, request->command, length_command);
1709         if(request->data != NULL) {
1710                 memcpy(string + offset_data_separator, data_separator, length_data_separator);
1711                 memcpy(string + offset_data, request->data, length_data);
1712         }
1713         memcpy(string + offset_separator_end, separator, length_separator_end);
1714
1715         // Log request
1716         RIL_LOG_LOCK();
1717         ril_data_log(string, length);
1718         ril_send_log(request);
1719         RIL_LOG_UNLOCK();
1720
1721         ril_device_send(ril_device, string, length);
1722
1723         free(string);
1724
1725         return 0;
1726 }
1727
1728 struct at_request *at_request_create(char *command, char *data)
1729 {
1730         struct at_request *request = NULL;
1731         int i;
1732
1733         if(command == NULL)
1734                 return NULL;
1735
1736         request = calloc(1, sizeof(struct at_request));
1737
1738         asprintf(&(request->command), "%s", command);
1739
1740         if(data != NULL) {
1741                 asprintf(&(request->data), "%s", data);
1742         }
1743
1744         return request;
1745 }
1746
1747 void at_request_free(struct at_request *request)
1748 {
1749         if(request->command != NULL) 
1750                 free(request->command);
1751
1752         if(request->data != NULL)
1753                 free(request->data);
1754
1755         if(request->error != NULL)
1756                 free(request->error);
1757
1758         memset(request, 0, sizeof(struct at_request *));
1759 }
1760
1761 int at_request_send_async(struct at_request *request, void *data, RIL_Token token, at_async_request_cb func)
1762 {
1763         struct at_async_request *async_request = NULL;
1764         int rc;
1765         int i;
1766
1767         if(request->command == NULL || func == NULL)
1768                 return -1;
1769
1770         async_request = calloc(1, sizeof(struct at_async_request));
1771         async_request->handled = AT_RESPONSE_WAITING;
1772         async_request->request = request;
1773         async_request->command = strdup(request->command);
1774         async_request->data = data;
1775         async_request->token = token;
1776         async_request->func = func;
1777
1778         rc = at_async_request_queue(async_request);
1779         if(rc < 0) {
1780                 LOGE("Unable to queue async request");
1781
1782                 at_async_request_free(async_request);
1783                 return -1;
1784         }
1785
1786         rc = at_request_queue(request);
1787         if(rc < 0) {
1788                 LOGE("Unable to queue request");
1789
1790                 // Better trying to dequeue too
1791                 at_async_request_dequeue(async_request);
1792                 at_async_request_free(async_request);
1793                 return NULL;
1794         }
1795
1796         // Try to send it now, don't fail if it can't
1797         at_send_next_request();
1798
1799         return 0;
1800 }
1801
1802 struct at_response *at_request_send_sync(struct at_request *request)
1803 {
1804         struct at_sync_request *sync_request = NULL;
1805         struct at_response *response = NULL;
1806         int rc;
1807         int i;
1808
1809         if(request->command == NULL)
1810                 return NULL;
1811
1812         sync_request = calloc(1, sizeof(struct at_sync_request));
1813         sync_request->handled = AT_RESPONSE_WAITING;
1814         sync_request->request = request;
1815         sync_request->command = strdup(request->command);
1816
1817         rc = at_sync_request_queue(sync_request);
1818         if(rc < 0) {
1819                 LOGE("Unable to queue sync request");
1820
1821                 at_sync_request_free(sync_request);
1822                 return NULL;
1823         }
1824
1825         rc = at_request_queue(request);
1826         if(rc < 0) {
1827                 LOGE("Unable to queue request");
1828
1829                 // Better trying to dequeue too
1830                 at_sync_request_dequeue(sync_request);
1831                 at_sync_request_free(sync_request);
1832                 return NULL;
1833         }
1834
1835         // Try to send it now, don't fail if it can't
1836         at_send_next_request();
1837
1838         // Block until there is a response available
1839         at_sync_requests_queue_lock();
1840
1841         if(sync_request->response == NULL) {
1842                 LOGE("Sync queue was unlocked but there is no response, aborting");
1843
1844                 // Better trying to dequeue too
1845                 at_sync_request_dequeue(sync_request);
1846                 at_sync_request_free(sync_request);
1847
1848                 // Send the next request in the queue
1849                 at_send_next_request();
1850
1851                 return NULL;
1852         }
1853
1854         response = sync_request->response;
1855
1856         at_sync_request_free(sync_request);
1857
1858         // Send the next request in the queue
1859         at_send_next_request();
1860
1861         return response;
1862 }
1863
1864 /*
1865  * Send
1866  */
1867
1868 int at_send_next_request(void)
1869 {
1870         struct at_sync_request *sync_request = NULL;
1871         struct at_async_request *async_request = NULL;
1872         struct at_async_request *async_request_sent = NULL;
1873         struct at_async_request *async_request_unhandled_status = NULL;
1874         struct at_async_request *async_request_unhandled_data = NULL;
1875         struct at_request *request = NULL;
1876         int rc;
1877
1878         // Unhandled requests are still going on too
1879         sync_request = at_sync_request_find_handled(AT_RESPONSE_SENT);
1880         async_request_sent = at_async_request_find_handled(AT_RESPONSE_SENT);
1881         async_request_unhandled_status = at_async_request_find_handled(AT_RESPONSE_UNHANDELD_REASON_STATUS);
1882         async_request_unhandled_data = at_async_request_find_handled(AT_RESPONSE_UNHANDELD_REASON_DATA);
1883
1884         if(sync_request != NULL || async_request_sent != NULL || async_request_unhandled_status != NULL || async_request_unhandled_data != NULL) {
1885                 LOGE("There are still unanswered requests!");
1886                 return -1;
1887         }
1888
1889         request = at_request_dequeue();
1890         if(request == NULL) {
1891                 LOGD("Nothing left to send!");
1892                 return -1;
1893         }
1894
1895         rc = at_request_send(request);
1896         if(rc < 0) {
1897                 LOGE("Unable to send request, aborting!");
1898                 at_request_free(request);
1899                 return -1;
1900         }
1901
1902         sync_request = at_sync_request_find_request(request);
1903         if(sync_request != NULL) {
1904                 sync_request->handled = AT_RESPONSE_SENT;
1905                 sync_request->request = NULL;
1906         }
1907
1908         async_request = at_async_request_find_request(request);
1909         if(async_request != NULL) {
1910                 async_request->handled = AT_RESPONSE_SENT;
1911                 async_request->request = NULL;
1912         }
1913
1914         at_request_free(request);
1915
1916         return 0;
1917 }
1918
1919 struct at_response *at_send_sync(char *command, char *data)
1920 {
1921         struct at_request *request = NULL;
1922         struct at_response *response = NULL;
1923
1924         request = at_request_create(command, data);
1925         if(request == NULL) {
1926                 LOGE("Unable to create request, aborting");
1927                 return -1;
1928         }
1929
1930         response = at_request_send_sync(request);
1931         if(response == NULL) {
1932                 at_request_free(request);
1933                 return NULL;
1934         }
1935
1936         return response;
1937 }
1938
1939 int at_send_expect_to_func(char *command, char *data, void *async_data, RIL_Token token, at_async_request_cb func)
1940 {
1941         struct at_request *request = NULL;
1942         int rc;
1943
1944         request = at_request_create(command, data);
1945         if(request == NULL) {
1946                 LOGE("Unable to create request, aborting");
1947                 return -1;
1948         }
1949
1950         rc = at_request_send_async(request, async_data, token, func);
1951         if(rc < 0) {
1952                 LOGE("Unable to send async request, aborting");
1953                 at_request_free(request);
1954                 return -1;
1955         }
1956
1957         return 0;
1958 }
1959
1960 int at_send_expect_status(char *command, char *data)
1961 {
1962         struct at_response *response = NULL;
1963         int status;
1964
1965         response = at_send_sync(command, data);
1966         if(response == NULL) {
1967                 LOGE("Unable to get sync response, aborting");
1968                 return -1;
1969         }
1970
1971         status = response->status;
1972
1973         at_response_free(response);
1974
1975         return status;
1976 }
1977
1978 int at_send_noresp(char *command, char *data)
1979 {
1980         struct at_response *response;
1981
1982         response = at_send(command, data);
1983         if(response != NULL) {
1984                 at_response_free(response);
1985                 return 0;
1986         } else {
1987                 return -1;
1988         }
1989 }
1990
1991 struct at_response *at_send_command(char *command)
1992 {
1993         return at_send(command, NULL);
1994 }
1995
1996 struct at_response *at_send(char *command, char *data)
1997 {
1998         struct at_request *request = NULL;
1999         struct at_response *response = NULL;
2000         int rc;
2001
2002         request = at_request_create(command, data);
2003         if(request == NULL) {
2004                 LOGE("Unable to create request, aborting!");
2005                 return -1;
2006         }
2007
2008         response = at_request_send_sync(request);
2009         if(response == NULL) {
2010                 LOGE("Unable to get sync response, aborting");
2011
2012                 at_request_free(request);
2013                 return -1;
2014         }
2015
2016         return response;
2017 }