2 * This file is part of hayes-ril.
4 * Copyright (C) 2012 Paul Kocialkowski <contact@paulk.fr>
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #define LOG_TAG "RIL-AT"
23 #include <utils/Log.h>
25 #include <hayes-ril.h>
31 struct at_handling at_handling;
37 int at_strings_compare(char *major, char *minor)
39 int major_length = strlen(major);
40 int minor_length = strlen(minor);
42 // We can't check against the whole major string
43 if(major_length > minor_length)
46 if(strncmp(major, minor, major_length) == 0)
52 int at_strings_raw_compare(char *major, char *minor)
54 int major_length = strlen(major);
56 // Only consider major length (minor might not have \0)
57 if(strncmp(major, minor, major_length) == 0)
63 // Major is response string, minor is request (reference) string
64 int at_commands_compare(char *major, char *minor)
68 // Assume major is corect
70 if(at_strings_compare(major, minor))
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);
77 if(at_strings_compare("AT", major) && !at_strings_compare("AT", minor) && strlen(major) > 2)
78 return at_strings_compare(major + 2, minor);
83 void at_string_clean(char *string, int length)
87 for(i=length-1; i >= 0 ; i--) {
88 if(!isprint(string[i]))
93 int at_status_error(int status)
96 case AT_STATUS_CONNECT:
109 int at_line_parse_status(char *data, int length, char **error_p)
111 char *response_command = NULL;
112 char *response_error = NULL;
113 int response_error_length = 0;
117 if(at_strings_compare("OK", data)) {
122 if(at_strings_compare("CONNECT", data)) {
124 return AT_STATUS_CONNECT;
127 if(at_strings_compare("ERROR", data)) {
129 return AT_STATUS_ERROR;
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;
139 if(response_command != NULL)
140 free(response_command);
142 return AT_STATUS_CME_ERROR;
145 return AT_STATUS_UNDEF;
148 int at_line_parse_command_data(char *data, int length, char **response_command, char **response_data)
151 int string_length = 0;
152 int close_your_eyes = 0;
157 for(i=0 ; i < length ; i++) {
158 if(data[i] == ':' && mark == 0) {
162 string_length = i + 1;
163 string = strndup(data, string_length);
165 if(!isprint(string[0])) {
168 *response_command = string;
174 while(isspace(data[i+1])) {
181 if(close_your_eyes & AT_PARSE_DOUBLE_QUOTE)
182 close_your_eyes &= ~AT_PARSE_DOUBLE_QUOTE;
184 close_your_eyes |= AT_PARSE_DOUBLE_QUOTE;
187 if(data[i] == '\'') {
188 if(close_your_eyes & AT_PARSE_SINGLE_QUOTE)
189 close_your_eyes &= ~AT_PARSE_SINGLE_QUOTE;
191 close_your_eyes |= AT_PARSE_SINGLE_QUOTE;
194 // Found = or ? outside of any quotes: assume no data
195 if(!close_your_eyes && (data[i] == '=' || data[i] == '?') && mark == 0) {
198 string_length = i + 1;
199 string = strndup(data, string_length);
201 if(!isprint(string[0])) {
204 *response_command = string;
212 if(length - mark > 0) {
213 string_length = length - mark;
214 string = strndup(data + mark, string_length);
217 *response_command = string;
220 *response_data = string;
221 return string_length;
229 * Responses line processor
232 int at_responses_process_line(struct at_response ***responses_p, int responses_count, char *data, int length)
234 struct at_response **responses = NULL;
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;
242 char **response_previous_data = NULL;
243 int response_data_count = 0;
249 if(responses_p == NULL || data == NULL || length < 0) {
250 LOGE("Failed to process AT response: wrong arguments!");
254 responses = *responses_p;
257 response_status = at_line_parse_status(data, length, &response_error);
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;
266 // Do not alloc a new response
273 // Alloc a new response
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
280 // Alloc the array with the new size
281 *responses_p = malloc(sizeof(struct at_response *) * count);
283 // Copy and free previous data
284 if(responses != NULL && responses_count > 0) {
285 memcpy(*responses_p, responses, sizeof(struct at_response *) * responses_count);
289 responses = *responses_p;
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;
297 // Parse command and data
298 response_data_length = at_line_parse_command_data(data, length, &response_command, &response_data);
300 if(response_command == NULL) {
301 LOGE("Failed to parse command!");
302 return responses_count;
305 at_string_clean(response_command, strlen(response_command) + 1);
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
317 // Alloc a new response
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
324 // Alloc the array with the new size
325 *responses_p = malloc(sizeof(struct at_response *) * count);
327 // Copy and free previous data
328 if(responses != NULL && responses_count > 0) {
329 memcpy(*responses_p, responses, sizeof(struct at_response *) * responses_count);
333 responses = *responses_p;
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;
341 if(response_data_length > 0 && response_data != NULL) {
342 at_string_clean(response_data, response_data_length);
344 response_previous_data = responses[index]->data;
346 // Data count is the total count of elements in the request data
347 response_data_count = responses[index]->data_count + 1;
349 // Alloc the array with the new size
350 responses[index]->data = malloc(sizeof(char *) * response_data_count);
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);
358 responses[index]->data_count = response_data_count;
359 responses[index]->data[response_data_count - 1] = response_data;
363 return count > responses_count ? count : responses_count;
367 * Responses structures processing
370 int at_responses_process(struct at_response ***responses_p, char *data, int length)
372 int responses_count = 0;
376 int string_length = 0;
380 if(responses_p == NULL || data == NULL || length < 0) {
381 LOGE("Failed to process AT response: wrong arguments!");
385 for(i=0 ; i < length ; i++) {
386 if(data[i] == '\r' || data[i] == ';') {
390 string_length = i - mark + 1;
391 string = strndup(data + mark, string_length);
393 if(!isprint(string[0])) {
397 count = at_responses_process_line(responses_p, responses_count, string, string_length);
398 if(count > responses_count)
399 responses_count = count;
407 while(isspace(data[i+1])) {
414 if(length - mark > 0) {
415 for(i=mark ; i < length ; i++)
416 if(!isprint(data[i]))
420 string_length = i - mark + 1;
421 string = calloc(1, string_length);
423 memcpy(string, data + mark, string_length - 1);
424 string[string_length - 1] = '\0';
426 count = at_responses_process_line(responses_p, responses_count, string , string_length);
427 if(count > responses_count)
428 responses_count = count;
434 return responses_count;
437 void at_response_free(struct at_response *response)
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;
449 free(response->data);
450 response->data_count = 0;
453 if(response->command != NULL)
454 free(response->command);
456 if(response->error != NULL)
457 free(response->error);
459 memset(response, 0, sizeof(struct at_response));
464 * Response data parsing
467 char *at_response_data_parse_string(char *data, int length)
470 int string_length = 0;
475 for(i=0 ; i < length ; i++) {
477 if(quote & AT_PARSE_DOUBLE_QUOTE) {
481 string_length = i - mark + 1;
482 string = strndup(data + mark, string_length);
484 if(!isprint(string[0])) {
491 } else if(i - mark == 0) {
495 quote |= AT_PARSE_DOUBLE_QUOTE;
501 // Only return the first string between a pair of "
506 int at_response_data_parse_numeric(char *data, int length)
510 for(i=0 ; i < length ; i++) {
511 if(isdigit(data[i])) {
512 return atoi(data + i);
520 * Response data processing
523 int at_response_data_process_value(struct at_response_data ***response_data_p, int response_data_count, char *data, int length)
525 struct at_response_data **response_data = NULL;
526 char *response_data_string = NULL;
527 int response_data_numeric = 0;
532 if(response_data_p == NULL || data == NULL || length < 0) {
533 LOGE("Failed to process AT response data value: wrong arguments!");
537 response_data = *response_data_p;
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
547 // Alloc the array with the new size
548 *response_data_p = malloc(sizeof(struct at_response_data *) * count);
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);
556 response_data = *response_data_p;
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;
564 response_data_numeric = at_response_data_parse_numeric(data, length);
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
571 // Alloc the array with the new size
572 *response_data_p = malloc(sizeof(struct at_response_data *) * count);
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);
580 response_data = *response_data_p;
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;
588 return count > response_data_count ? count : response_data_count;
591 int at_response_data_process(struct at_response_data ***response_data_p, char *data, int length)
593 int response_data_count = 0;
597 int string_length = 0;
601 if(response_data_p == NULL || data == NULL || length < 0) {
602 LOGE("Failed to process AT response data: wrong arguments!");
606 for(i=0 ; i < length ; i++) {
611 string_length = i - mark + 1;
612 string = strndup(data + mark, string_length);
614 if(!isprint(string[0])) {
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;
628 while(isspace(data[i+1])) {
635 if(length - mark > 0) {
636 for(i=mark ; i < length ; i++)
637 if(!isprint(data[i]))
641 string_length = i - mark + 1;
642 string = calloc(1, string_length);
644 memcpy(string, data + mark, string_length - 1);
645 string[string_length - 1] = '\0';
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;
655 return response_data_count;
658 void at_response_data_free(struct at_response_data **response_data, int response_data_count)
662 if(response_data == NULL || response_data_count <= 0)
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);
671 memset(response_data[i], 0, sizeof(struct at_response_data));
682 void at_handling_init(void)
684 memset(&at_handling, 0, sizeof(struct at_handling));
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);
693 at_handling.freeze = AT_FREEZE_OFF;
695 // First lock to the queues mutexes
696 AT_RESPONSES_QUEUE_LOCK();
697 AT_SYNC_QUEUE_LOCK();
704 // Unlock the responses queue after queuing all the available requests
705 void at_responses_queue_unlock(void)
707 if(at_handling.responses_queue.responses_count <= 0 || at_handling.responses_queue.responses == NULL)
710 AT_RESPONSES_QUEUE_UNLOCK();
713 // Queue one response to the responses queue
714 int at_response_queue(struct at_response *response)
716 struct at_response **responses = NULL;
717 int responses_count = 0;
726 // Save the previous data pointer and count
727 responses = at_handling.responses_queue.responses;
728 responses_count = at_handling.responses_queue.responses_count;
730 if(responses_count < 0)
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
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;
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);
748 // Get the new data pointer and count
749 responses = at_handling.responses_queue.responses;
750 responses_count = at_handling.responses_queue.responses_count;
752 // Put the response in the queue
753 responses[index] = response;
755 LOGD("%d elements in the responses queue", responses_count);
757 AT_RESPONSES_UNLOCK();
762 // Unqueue the oldest response in the queue
763 struct at_response *at_response_dequeue(void)
765 struct at_response *response = NULL;
766 struct at_response **responses = NULL;
767 int responses_count = 0;
773 // Save the previous data pointer and count
774 responses = at_handling.responses_queue.responses;
775 responses_count = at_handling.responses_queue.responses_count;
777 while(responses_count <= 0 || responses == NULL) {
778 LOGE("No response queued, blocking!");
780 AT_RESPONSES_UNLOCK();
781 AT_RESPONSES_QUEUE_LOCK();
784 if(at_freeze_get() == AT_FREEZE_SEND) {
785 AT_RESPONSES_UNLOCK();
789 // Get the new data pointer and count
790 responses = at_handling.responses_queue.responses;
791 responses_count = at_handling.responses_queue.responses_count;
793 LOGE("Unblocking: %d new responses queued!", responses_count);
796 for(i=0 ; i < responses_count ; i++) {
797 if(responses[i] != NULL) {
798 response = responses[i];
804 if(response == NULL || pos < 0) {
805 LOGD("Found no valid response, aborting!");
807 AT_RESPONSES_UNLOCK();
811 // Empty the found position in the responses array
812 responses[pos] = NULL;
814 // Move the elements back
815 for(i=pos ; i < responses_count-1 ; i++) {
816 responses[i] = responses[i+1];
819 // Empty the latest element
820 if(pos != responses_count-1) {
821 responses[responses_count-1] = NULL;
826 if(responses_count == 0) {
828 at_handling.responses_queue.responses = NULL;
831 at_handling.responses_queue.responses_count = responses_count;
833 LOGD("%d elements in the responses queue", responses_count);
835 AT_RESPONSES_UNLOCK();
844 // Queue one request to the requests queue
845 int at_request_queue(struct at_request *request)
847 struct at_request **requests = NULL;
848 int requests_count = 0;
857 // Save the previous data pointer and count
858 requests = at_handling.requests_queue.requests;
859 requests_count = at_handling.requests_queue.requests_count;
861 if(requests_count < 0)
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
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;
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);
879 // Get the new data pointer and count
880 requests = at_handling.requests_queue.requests;
881 requests_count = at_handling.requests_queue.requests_count;
883 // Put the request in the queue
884 requests[index] = request;
886 LOGD("%d elements in the requests queue", requests_count);
888 AT_REQUESTS_UNLOCK();
893 // Unqueue the oldest request in the queue
894 struct at_request *at_request_dequeue(void)
896 struct at_request *request = NULL;
897 struct at_request **requests = NULL;
898 int requests_count = 0;
904 // Save the previous data pointer and count
905 requests = at_handling.requests_queue.requests;
906 requests_count = at_handling.requests_queue.requests_count;
908 if(requests_count <= 0 || requests == NULL) {
909 LOGE("No requests queued!");
911 AT_REQUESTS_UNLOCK();
915 for(i=0 ; i < requests_count ; i++) {
916 if(requests[i] != NULL) {
917 request = requests[i];
923 if(requests == NULL || pos < 0) {
924 LOGD("Found no valid request, aborting!");
926 AT_REQUESTS_UNLOCK();
930 // Empty the found position in the requests array
931 requests[pos] = NULL;
933 // Move the elements back
934 for(i=pos ; i < requests_count-1 ; i++) {
935 requests[i] = requests[i+1];
938 // Empty the latest element
939 if(pos != requests_count-1) {
940 requests[requests_count-1] = NULL;
945 if(requests_count == 0) {
947 at_handling.requests_queue.requests = NULL;
950 at_handling.requests_queue.requests_count = requests_count;
952 LOGD("%d elements in the requests queue", requests_count);
954 AT_REQUESTS_UNLOCK();
960 * Async requests queue
963 // Free the async request
964 void at_async_request_free(struct at_async_request *async_request)
966 if(async_request == NULL)
969 if(async_request->command)
970 free(async_request->command);
972 if(async_request->request)
973 at_request_free(async_request->request);
975 memset(async_request, 0, sizeof(struct at_async_request));
976 async_request->handled = AT_RESPONSE_GARBAGE;
979 // Find an async request from its command
980 struct at_async_request *at_async_request_find_command(char *command)
982 struct at_async_request *async_request = NULL;
983 struct at_async_request **async_requests = NULL;
984 int async_requests_count = 0;
992 // Save the previous data pointer and count
993 async_requests = at_handling.async_requests_queue.async_requests;
994 async_requests_count = at_handling.async_requests_queue.async_requests_count;
996 if(async_requests_count <= 0 || async_requests == NULL) {
1001 for(i=0 ; i < async_requests_count ; i++) {
1002 if(async_requests[i] != NULL && async_requests[i]->command != NULL) {
1003 if(at_commands_compare(command, async_requests[i]->command)) {
1004 async_request = async_requests[i];
1012 return async_request;
1015 // Find an async request from its handled status
1016 struct at_async_request *at_async_request_find_handled(int handled)
1018 struct at_async_request *async_request = NULL;
1019 struct at_async_request **async_requests = NULL;
1020 int async_requests_count = 0;
1025 // Save the previous data pointer and count
1026 async_requests = at_handling.async_requests_queue.async_requests;
1027 async_requests_count = at_handling.async_requests_queue.async_requests_count;
1029 if(async_requests_count <= 0 || async_requests == NULL) {
1034 for(i=0 ; i < async_requests_count ; i++) {
1035 if(async_requests[i] != NULL) {
1036 if(async_requests[i]->handled == handled) {
1037 async_request = async_requests[i];
1045 return async_request;
1048 // Find an async request from its request pointer
1049 struct at_async_request *at_async_request_find_request(struct at_request *request)
1051 struct at_async_request *async_request = NULL;
1052 struct at_async_request **async_requests = NULL;
1053 int async_requests_count = 0;
1061 // Save the previous data pointer and count
1062 async_requests = at_handling.async_requests_queue.async_requests;
1063 async_requests_count = at_handling.async_requests_queue.async_requests_count;
1065 if(async_requests_count <= 0 || async_requests == NULL) {
1070 for(i=0 ; i < async_requests_count ; i++) {
1071 if(async_requests[i] != NULL) {
1072 if(async_requests[i]->request == request) {
1073 async_request = async_requests[i];
1081 return async_request;
1084 // Find an async request from its response pointer
1085 struct at_async_request *at_async_request_find_response(struct at_response *response)
1087 struct at_async_request *async_request = NULL;
1088 struct at_async_request **async_requests = NULL;
1089 int async_requests_count = 0;
1092 if(response == NULL)
1097 // Save the previous data pointer and count
1098 async_requests = at_handling.async_requests_queue.async_requests;
1099 async_requests_count = at_handling.async_requests_queue.async_requests_count;
1101 if(async_requests_count <= 0 || async_requests == NULL) {
1106 for(i=0 ; i < async_requests_count ; i++) {
1107 if(async_requests[i] != NULL && async_requests[i]->response != NULL) {
1108 if(async_requests[i]->response == response) {
1109 async_request = async_requests[i];
1117 return async_request;
1120 // Queue one request to the async requests queue
1121 int at_async_request_queue(struct at_async_request *async_request)
1123 struct at_async_request **async_requests = NULL;
1124 int async_requests_count = 0;
1128 if(async_request == NULL)
1133 // Save the previous data pointer and count
1134 async_requests = at_handling.async_requests_queue.async_requests;
1135 async_requests_count = at_handling.async_requests_queue.async_requests_count;
1137 if(async_requests_count < 0)
1138 async_requests_count = 0;
1140 // Index is the sync request index in the sync requests array
1141 index = async_requests_count;
1142 // Count is the total count of sync requests in the array
1145 // Alloc the array with the new size
1146 at_handling.async_requests_queue.async_requests = malloc(sizeof(struct at_async_request *) * count);
1147 at_handling.async_requests_queue.async_requests_count = count;
1149 // Copy and free previous data
1150 if(async_requests != NULL && async_requests_count > 0) {
1151 memcpy(at_handling.async_requests_queue.async_requests, async_requests, sizeof(struct at_async_request *) * at_handling.async_requests_queue.async_requests_count);
1152 free(async_requests);
1155 // Get the new data pointer and count
1156 async_requests = at_handling.async_requests_queue.async_requests;
1157 async_requests_count = at_handling.async_requests_queue.async_requests_count;
1159 // Put the sync request in the queue
1160 async_requests[index] = async_request;
1162 LOGD("%d elements in the async requests queue", async_requests_count);
1169 int at_async_response_dequeue(struct at_response *response)
1171 struct at_async_request *async_request = NULL;
1174 if(response == NULL)
1177 // First, try to grab the async request from the response, if it was already filled by sync dequeue
1178 async_request = at_async_request_find_response(response);
1179 if(async_request == NULL || async_request->func == NULL) {
1180 // Then, try to find an unhandled response
1182 async_request = at_async_request_find_handled(AT_RESPONSE_UNHANDELD_REASON_STATUS);
1183 if(async_request == NULL || async_request->func == NULL) {
1184 // Finally, grab the async request from the command
1186 async_request = at_async_request_find_command(response->command);
1187 if(async_request == NULL || async_request->func == NULL) {
1192 // FIXME: What if there is already a response with valid data?
1194 async_request->response = response;
1197 LOGD("Found a matching request for %s!", async_request->command);
1199 // This prevents sync data not to be reported when the same command is issued in func and previous handled was unhandled for status reason
1200 async_request->handled = AT_RESPONSE_SENT;
1202 at_async_request_dequeue(async_request);
1204 rc = async_request->func(response, async_request->data, async_request->token);
1206 // If the request was unhandled, update its status and requeue
1207 if(rc == AT_RESPONSE_UNHANDELD_REASON_STATUS) {
1208 LOGD("Response not handled (missing status)");
1209 async_request->handled = AT_RESPONSE_UNHANDELD_REASON_STATUS;
1210 at_async_request_queue(async_request);
1211 } else if(rc == AT_RESPONSE_UNHANDELD_REASON_DATA) {
1212 LOGD("Response not handled (missing data)");
1213 async_request->handled = AT_RESPONSE_UNHANDELD_REASON_DATA;
1214 at_async_request_queue(async_request);
1216 LOGD("Response was handled!");
1218 // We can free the request
1219 at_async_request_free(async_request);
1221 // Send the next request in the queue
1222 at_send_next_request();
1228 // Dequeue one async request (only remove from the queue)
1229 int at_async_request_dequeue(struct at_async_request *async_request)
1231 struct at_async_request **async_requests = NULL;
1232 int async_requests_count = 0;
1236 if(async_request == NULL)
1241 // Save the previous data pointer and count
1242 async_requests = at_handling.async_requests_queue.async_requests;
1243 async_requests_count = at_handling.async_requests_queue.async_requests_count;
1245 if(async_requests_count <= 0 || async_requests == NULL) {
1246 LOGE("No async requests queued, aborting dequeue!");
1252 for(i=0 ; i < async_requests_count ; i++) {
1253 if(async_requests[i] == async_request) {
1260 LOGD("Found no matching async request, aborting dequeue!");
1266 // Empty the found position in the async requests array
1267 async_requests[pos] = NULL;
1269 // Move the elements back
1270 for(i=pos ; i < async_requests_count-1 ; i++) {
1271 async_requests[i] = async_requests[i+1];
1274 // Empty the latest element
1275 if(pos != async_requests_count-1) {
1276 async_requests[async_requests_count-1] = NULL;
1279 async_requests_count--;
1281 if(async_requests_count == 0) {
1282 free(async_requests);
1283 at_handling.async_requests_queue.async_requests = NULL;
1286 at_handling.async_requests_queue.async_requests_count = async_requests_count;
1288 LOGD("%d elements in the async requests queue", async_requests_count);
1296 * Sync requests queue
1299 // Lock the sync requests queue
1300 void at_sync_requests_queue_lock(void)
1302 AT_SYNC_QUEUE_LOCK();
1305 // Unlock the sync requests queue
1306 void at_sync_requests_queue_unlock(void)
1308 AT_SYNC_QUEUE_UNLOCK();
1311 // Free the sync request
1312 void at_sync_request_free(struct at_sync_request *sync_request)
1314 if(sync_request == NULL)
1317 if(sync_request->command)
1318 free(sync_request->command);
1320 if(sync_request->request)
1321 at_request_free(sync_request->request);
1323 memset(sync_request, 0, sizeof(struct at_sync_request));
1324 sync_request->handled = AT_RESPONSE_GARBAGE;
1327 // Whether the sync queue is empty
1328 int at_sync_queue_empty(void)
1330 struct at_sync_request *sync_request = NULL;
1331 struct at_sync_request **sync_requests = NULL;
1332 int sync_requests_count;
1338 // Save the previous data pointer and count
1339 sync_requests = at_handling.sync_requests_queue.sync_requests;
1340 sync_requests_count = at_handling.sync_requests_queue.sync_requests_count;
1342 if(sync_requests_count <= 0 || sync_requests == NULL)
1352 // Find a sync request from its command
1353 struct at_sync_request *at_sync_request_find_command(char *command)
1355 struct at_sync_request *sync_request = NULL;
1356 struct at_sync_request **sync_requests = NULL;
1357 int sync_requests_count = 0;
1365 // Save the previous data pointer and count
1366 sync_requests = at_handling.sync_requests_queue.sync_requests;
1367 sync_requests_count = at_handling.sync_requests_queue.sync_requests_count;
1369 if(sync_requests_count <= 0 || sync_requests == NULL) {
1374 for(i=0 ; i < sync_requests_count ; i++) {
1375 if(sync_requests[i] != NULL && sync_requests[i]->command != NULL) {
1376 if(at_commands_compare(command, sync_requests[i]->command)) {
1377 sync_request = sync_requests[i];
1385 return sync_request;
1388 // Find a sync request from its handled status
1389 struct at_sync_request *at_sync_request_find_handled(int handled)
1391 struct at_sync_request *sync_request = NULL;
1392 struct at_sync_request **sync_requests = NULL;
1393 int sync_requests_count = 0;
1398 // Save the previous data pointer and count
1399 sync_requests = at_handling.sync_requests_queue.sync_requests;
1400 sync_requests_count = at_handling.sync_requests_queue.sync_requests_count;
1402 if(sync_requests_count <= 0 || sync_requests == NULL) {
1407 for(i=0 ; i < sync_requests_count ; i++) {
1408 if(sync_requests[i] != NULL) {
1409 if(sync_requests[i]->handled == handled) {
1410 sync_request = sync_requests[i];
1418 return sync_request;
1421 // Find a sync request from its request pointer
1422 struct at_sync_request *at_sync_request_find_request(struct at_request *request)
1424 struct at_sync_request *sync_request = NULL;
1425 struct at_sync_request **sync_requests = NULL;
1426 int sync_requests_count = 0;
1434 // Save the previous data pointer and count
1435 sync_requests = at_handling.sync_requests_queue.sync_requests;
1436 sync_requests_count = at_handling.sync_requests_queue.sync_requests_count;
1438 if(sync_requests_count <= 0 || sync_requests == NULL) {
1443 for(i=0 ; i < sync_requests_count ; i++) {
1444 if(sync_requests[i] != NULL) {
1445 if(sync_requests[i]->request == request) {
1446 sync_request = sync_requests[i];
1454 return sync_request;
1457 // Queue one request to the sync requests queue
1458 int at_sync_request_queue(struct at_sync_request *sync_request)
1460 struct at_sync_request **sync_requests = NULL;
1461 int sync_requests_count = 0;
1465 if(sync_request == NULL)
1470 // Save the previous data pointer and count
1471 sync_requests = at_handling.sync_requests_queue.sync_requests;
1472 sync_requests_count = at_handling.sync_requests_queue.sync_requests_count;
1474 if(sync_requests_count < 0)
1475 sync_requests_count = 0;
1477 // Index is the sync request index in the sync requests array
1478 index = sync_requests_count;
1479 // Count is the total count of sync requests in the array
1482 // Alloc the array with the new size
1483 at_handling.sync_requests_queue.sync_requests = malloc(sizeof(struct at_sync_request *) * count);
1484 at_handling.sync_requests_queue.sync_requests_count = count;
1486 // Copy and free previous data
1487 if(sync_requests != NULL && sync_requests_count > 0) {
1488 memcpy(at_handling.sync_requests_queue.sync_requests, sync_requests, sizeof(struct at_sync_request *) * at_handling.sync_requests_queue.sync_requests_count);
1489 free(sync_requests);
1492 // Get the new data pointer and count
1493 sync_requests = at_handling.sync_requests_queue.sync_requests;
1494 sync_requests_count = at_handling.sync_requests_queue.sync_requests_count;
1496 // Put the sync request in the queue
1497 sync_requests[index] = sync_request;
1499 LOGD("%d elements in the sync requests queue", sync_requests_count);
1506 // Dequeue one response (that will or not be assigned to a sync request)
1507 int at_sync_response_dequeue(struct at_response *response)
1509 struct at_sync_request *sync_request = NULL;
1510 struct at_async_request *async_request = NULL;
1513 if(response == NULL)
1516 if(response->command != NULL && !at_sync_queue_empty()) {
1517 if(response->status == AT_STATUS_UNDEF && (response->data == NULL || response->data_count <= 0)) {
1518 // Check if this is a part of a queued sync command
1520 sync_request = at_sync_request_find_command(response->command);
1521 if(sync_request != NULL && sync_request->handled == AT_RESPONSE_SENT) {
1522 // This will make this sync request the next one to get a status
1524 sync_request->handled = AT_RESPONSE_UNHANDELD_REASON_STATUS;
1526 LOGD("Skipping matching request with no status nor data!");
1527 at_response_free(response);
1532 // 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
1534 sync_request = at_sync_request_find_handled(AT_RESPONSE_SENT);
1535 if(sync_request == NULL)
1536 sync_request = at_sync_request_find_handled(AT_RESPONSE_UNHANDELD_REASON_STATUS);
1538 if(sync_request != NULL && sync_request->command != NULL) {
1539 // If we catch an unsol or a response for another request, there is something wrong
1541 rc = at_commands_compare(response->command, sync_request->command);
1543 // We don't need to check on the async queue as requests are sent one at a time
1545 LOGE("Got a response for another request, aborting!");
1546 AT_SYNC_QUEUE_UNLOCK();
1550 // There is a command but we didn't send any sync request, so don't deal with it
1556 // If we have no status at this point, we have no use of the response
1557 if(response->status == AT_STATUS_UNDEF) {
1561 // Have no command but a status
1562 if(response->command == NULL) {
1563 async_request = at_async_request_find_handled(AT_RESPONSE_UNHANDELD_REASON_STATUS);
1564 if(async_request != NULL) {
1565 // 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
1567 async_request->response = response;
1568 async_request->handled = AT_RESPONSE_SENT;
1570 LOGD("Found a status for a previous async request!");
1575 sync_request = at_sync_request_find_handled(AT_RESPONSE_UNHANDELD_REASON_STATUS);
1576 if(sync_request != NULL) {
1577 sync_request->handled = AT_RESPONSE_SENT;
1582 if(sync_request == NULL) {
1583 sync_request = at_sync_request_find_handled(AT_RESPONSE_SENT);
1584 if(sync_request == NULL) {
1585 LOGE("Got a status but no request waiting for it at all, this should never happend!");
1590 sync_request->response = response;
1591 LOGD("Found a response for a sync request!");
1593 AT_SYNC_QUEUE_UNLOCK();
1598 // Dequeue one sync request (only remove from the queue)
1599 int at_sync_request_dequeue(struct at_sync_request *sync_request)
1601 struct at_sync_request **sync_requests = NULL;
1602 int sync_requests_count = 0;
1606 if(sync_request == NULL)
1611 // Save the previous data pointer and count
1612 sync_requests = at_handling.sync_requests_queue.sync_requests;
1613 sync_requests_count = at_handling.sync_requests_queue.sync_requests_count;
1615 if(sync_requests_count <= 0 || sync_requests == NULL) {
1616 LOGE("No sync requests queued, aborting dequeue!");
1622 for(i=0 ; i < sync_requests_count ; i++) {
1623 if(sync_requests[i] == sync_request) {
1630 LOGD("Found no matching sync request, aborting dequeue!");
1636 // Empty the found position in the sync requests array
1637 sync_requests[pos] = NULL;
1639 // Move the elements back
1640 for(i=pos ; i < sync_requests_count-1 ; i++) {
1641 sync_requests[i] = sync_requests[i+1];
1644 // Empty the latest element
1645 if(pos != sync_requests_count-1) {
1646 sync_requests[sync_requests_count-1] = NULL;
1649 sync_requests_count--;
1651 if(sync_requests_count == 0) {
1652 free(sync_requests);
1653 at_handling.sync_requests_queue.sync_requests = NULL;
1656 at_handling.sync_requests_queue.sync_requests_count = sync_requests_count;
1658 LOGD("%d elements in the sync requests queue", sync_requests_count);
1669 void at_freeze_set(int freeze)
1671 at_handling.freeze = freeze;
1674 int at_freeze_get(void)
1676 return at_handling.freeze;
1679 int at_freeze_start(void)
1681 struct at_sync_request *sync_request = NULL;
1682 struct at_async_request *async_request = NULL;
1684 at_freeze_set(AT_FREEZE_ON);
1686 // Set all the sent requests to freezed state
1687 sync_request = at_sync_request_find_handled(AT_RESPONSE_SENT);
1689 sync_request->handled = AT_RESPONSE_SENT_FREEZED;
1691 async_request = at_async_request_find_handled(AT_RESPONSE_SENT);
1693 async_request->handled = AT_RESPONSE_SENT_FREEZED;
1695 async_request = at_async_request_find_handled(AT_RESPONSE_UNHANDELD_REASON_STATUS);
1697 async_request->handled = AT_RESPONSE_SENT_FREEZED;
1699 async_request = at_async_request_find_handled(AT_RESPONSE_UNHANDELD_REASON_DATA);
1701 async_request->handled = AT_RESPONSE_SENT_FREEZED;
1706 int at_freeze_stop(void)
1708 at_freeze_set(AT_FREEZE_OFF);
1713 int at_freeze_send(void)
1715 // Allow requests send even though there are freezed requests
1716 at_freeze_set(AT_FREEZE_SEND);
1718 // Unlock responses queue so that the dispatch loop can send setup
1719 AT_RESPONSES_QUEUE_UNLOCK();
1724 int at_freeze_respawn(void)
1726 struct at_sync_request *sync_request = NULL;
1727 struct at_async_request *async_request = NULL;
1730 // Respawn the latest request
1731 at_freeze_set(AT_FREEZE_RESPAWN);
1733 // There should only be one
1735 sync_request = at_sync_request_find_handled(AT_RESPONSE_SENT_FREEZED);
1737 sync_request->handled = AT_RESPONSE_WAITING;
1739 rc = at_request_queue(sync_request->request);
1741 LOGE("Unable to queue request");
1743 // Better trying to dequeue too
1744 at_sync_request_dequeue(sync_request);
1745 at_sync_request_free(sync_request);
1747 at_send_next_request();
1750 } while(sync_request != NULL);
1753 async_request = at_async_request_find_handled(AT_RESPONSE_SENT_FREEZED);
1755 async_request->handled = AT_RESPONSE_WAITING;
1757 rc = at_request_queue(async_request->request);
1759 LOGE("Unable to queue request");
1761 // Better trying to dequeue too
1762 at_async_request_dequeue(async_request);
1763 at_async_request_free(async_request);
1765 at_send_next_request();
1768 } while(async_request != NULL);
1777 int at_request_send(struct at_request *request)
1779 char *string = NULL;
1782 int offset_separator_begin = 0;
1783 int length_separator_begin = 0;
1784 int offset_command = 0;
1785 int length_command = 0;
1786 int offset_data_separator = 0;
1787 int length_data_separator = 0;
1788 int offset_data = 0;
1789 int length_data = 0;
1790 int offset_separator_end = 0;
1791 int length_separator_end = 0;
1795 // TODO: Do we send \r\n or only \r, begining/end or just end?
1796 char separator[] = "\r\n";
1797 char data_separator[] = "=";
1799 if(request->command == NULL)
1802 offset_separator_begin = 0;
1803 length_separator_begin = strlen(separator);
1804 length += length_separator_begin;
1806 offset_command = length;
1807 length_command = strlen(request->command);
1808 length += length_command;
1810 if(request->data != NULL) {
1811 offset_data_separator = length;
1812 length_data_separator = strlen(data_separator);
1813 length += length_data_separator;
1815 offset_data = length;
1816 length_data = strlen(request->data);
1817 length += length_data;
1820 offset_separator_end = length;
1821 length_separator_end = strlen(separator);
1822 length += length_separator_end;
1824 // Alloc final string
1825 string = calloc(1, length);
1827 // Copy the data to the string
1828 memcpy(string + offset_separator_begin, separator, length_separator_begin);
1829 memcpy(string + offset_command, request->command, length_command);
1830 if(request->data != NULL) {
1831 memcpy(string + offset_data_separator, data_separator, length_data_separator);
1832 memcpy(string + offset_data, request->data, length_data);
1834 memcpy(string + offset_separator_end, separator, length_separator_end);
1838 ril_data_log(string, length);
1839 ril_send_log(request);
1842 ril_device_transport_send(ril_device, string, length);
1849 struct at_request *at_request_create(char *command, char *data)
1851 struct at_request *request = NULL;
1857 request = calloc(1, sizeof(struct at_request));
1859 asprintf(&(request->command), "%s", command);
1862 asprintf(&(request->data), "%s", data);
1868 void at_request_free(struct at_request *request)
1870 if(request->command != NULL)
1871 free(request->command);
1873 if(request->data != NULL)
1874 free(request->data);
1876 if(request->error != NULL)
1877 free(request->error);
1879 memset(request, 0, sizeof(struct at_request *));
1882 int at_request_send_async(struct at_request *request, void *data, RIL_Token token, at_async_request_cb func)
1884 struct at_async_request *async_request = NULL;
1888 if(request->command == NULL || func == NULL)
1891 async_request = calloc(1, sizeof(struct at_async_request));
1892 async_request->handled = AT_RESPONSE_WAITING;
1893 async_request->request = request;
1894 async_request->command = strdup(request->command);
1895 async_request->data = data;
1896 async_request->token = token;
1897 async_request->func = func;
1899 if(at_freeze_get() == AT_FREEZE_SEND)
1900 async_request->handled = AT_RESPONSE_UNFREEZE;
1902 rc = at_async_request_queue(async_request);
1904 LOGE("Unable to queue async request");
1906 at_async_request_free(async_request);
1910 // Do not queue the request when sending while freeze
1911 if(at_freeze_get() == AT_FREEZE_SEND)
1914 rc = at_request_queue(request);
1916 LOGE("Unable to queue request");
1918 // Better trying to dequeue too
1919 at_async_request_dequeue(async_request);
1920 at_async_request_free(async_request);
1925 // Try to send it now, don't fail if it can't
1926 at_send_next_request();
1931 struct at_response *at_request_send_sync(struct at_request *request)
1933 struct at_sync_request *sync_request = NULL;
1934 struct at_response *response = NULL;
1938 if(request->command == NULL)
1941 sync_request = calloc(1, sizeof(struct at_sync_request));
1942 sync_request->handled = AT_RESPONSE_WAITING;
1943 sync_request->request = request;
1944 sync_request->command = strdup(request->command);
1946 if(at_freeze_get() == AT_FREEZE_SEND)
1947 sync_request->handled = AT_RESPONSE_UNFREEZE;
1949 rc = at_sync_request_queue(sync_request);
1951 LOGE("Unable to queue sync request");
1953 at_sync_request_free(sync_request);
1957 // Do not queue the request when sending while freeze
1958 if(at_freeze_get() == AT_FREEZE_SEND)
1961 rc = at_request_queue(request);
1963 LOGE("Unable to queue request");
1965 // Better trying to dequeue too
1966 at_sync_request_dequeue(sync_request);
1967 at_sync_request_free(sync_request);
1972 // Try to send it now, don't fail if it can't
1973 at_send_next_request();
1975 // Block until there is a response available
1976 at_sync_requests_queue_lock();
1978 if(sync_request->response == NULL) {
1979 LOGE("Sync queue was unlocked but there is no response, aborting");
1981 // Better trying to dequeue too
1982 at_sync_request_dequeue(sync_request);
1983 at_sync_request_free(sync_request);
1985 // Send the next request in the queue
1986 at_send_next_request();
1991 response = sync_request->response;
1993 at_sync_request_dequeue(sync_request);
1994 at_sync_request_free(sync_request);
1996 // Send the next request in the queue
1997 at_send_next_request();
2006 int at_send_next_request(void)
2008 struct at_sync_request *sync_request = NULL;
2009 struct at_async_request *async_request = NULL;
2010 struct at_async_request *async_request_sent = NULL;
2011 struct at_async_request *async_request_unhandled_status = NULL;
2012 struct at_async_request *async_request_unhandled_data = NULL;
2013 struct at_request *request = NULL;
2016 if(at_freeze_get() == AT_FREEZE_SEND) {
2017 sync_request = at_sync_request_find_handled(AT_RESPONSE_UNFREEZE);
2018 if(sync_request != NULL) {
2019 request = sync_request->request;
2023 async_request = at_async_request_find_handled(AT_RESPONSE_UNFREEZE);
2024 if(async_request != NULL) {
2025 request = async_request->request;
2029 if(request == NULL) {
2030 LOGD("No request to send during freeze!");
2035 // Unhandled requests are still going on too
2036 sync_request = at_sync_request_find_handled(AT_RESPONSE_SENT);
2037 async_request_sent = at_async_request_find_handled(AT_RESPONSE_SENT);
2038 async_request_unhandled_status = at_async_request_find_handled(AT_RESPONSE_UNHANDELD_REASON_STATUS);
2039 async_request_unhandled_data = at_async_request_find_handled(AT_RESPONSE_UNHANDELD_REASON_DATA);
2041 if(sync_request != NULL || async_request_sent != NULL || async_request_unhandled_status != NULL || async_request_unhandled_data != NULL) {
2042 LOGE("There are still unanswered requests!");
2046 request = at_request_dequeue();
2047 if(request == NULL) {
2048 LOGD("Nothing left to send!");
2053 rc = at_request_send(request);
2055 LOGE("Unable to send request, aborting!");
2056 at_request_free(request);
2060 sync_request = at_sync_request_find_request(request);
2061 if(sync_request != NULL)
2062 sync_request->handled = AT_RESPONSE_SENT;
2064 async_request = at_async_request_find_request(request);
2065 if(async_request != NULL)
2066 async_request->handled = AT_RESPONSE_SENT;
2071 struct at_response *at_send_sync(char *command, char *data)
2073 struct at_request *request = NULL;
2074 struct at_response *response = NULL;
2076 request = at_request_create(command, data);
2077 if(request == NULL) {
2078 LOGE("Unable to create request, aborting");
2082 response = at_request_send_sync(request);
2083 if(response == NULL) {
2084 at_request_free(request);
2091 int at_send_expect_to_func(char *command, char *data, void *async_data, RIL_Token token, at_async_request_cb func)
2093 struct at_request *request = NULL;
2096 request = at_request_create(command, data);
2097 if(request == NULL) {
2098 LOGE("Unable to create request, aborting");
2102 rc = at_request_send_async(request, async_data, token, func);
2104 LOGE("Unable to send async request, aborting");
2105 at_request_free(request);
2112 int at_send_expect_status(char *command, char *data)
2114 struct at_response *response = NULL;
2117 response = at_send_sync(command, data);
2118 if(response == NULL) {
2119 LOGE("Unable to get sync response, aborting");
2123 status = response->status;
2125 at_response_free(response);
2130 int at_send_noresp(char *command, char *data)
2132 struct at_response *response;
2134 response = at_send(command, data);
2135 if(response != NULL) {
2136 at_response_free(response);
2143 struct at_response *at_send_command(char *command)
2145 return at_send(command, NULL);
2148 struct at_response *at_send(char *command, char *data)
2150 struct at_request *request = NULL;
2151 struct at_response *response = NULL;
2154 request = at_request_create(command, data);
2155 if(request == NULL) {
2156 LOGE("Unable to create request, aborting!");
2160 response = at_request_send_sync(request);
2161 if(response == NULL) {
2162 LOGE("Unable to get sync response, aborting");
2164 at_request_free(request);