Freeze/Device: Correct freeze process and refactor recv loop
authorPaul Kocialkowski <contact@paulk.fr>
Sun, 2 Sep 2012 19:49:44 +0000 (21:49 +0200)
committerPaul Kocialkowski <contact@paulk.fr>
Sun, 2 Sep 2012 19:49:44 +0000 (21:49 +0200)
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
at.c
device.c
hayes-ril.c

diff --git a/at.c b/at.c
index 2e40c22..7de2a08 100644 (file)
--- a/at.c
+++ b/at.c
@@ -1685,20 +1685,28 @@ int at_freeze_start(void)
 
        // Set all the sent requests to freezed state
        sync_request = at_sync_request_find_handled(AT_RESPONSE_SENT);
-       if(sync_request)
+       if(sync_request) {
+               LOGD("Freezing a pending request");
                sync_request->handled = AT_RESPONSE_SENT_FREEZED;
+       }
 
        async_request = at_async_request_find_handled(AT_RESPONSE_SENT);
-       if(async_request)
+       if(async_request) {
+               LOGD("Freezing a pending request");
                async_request->handled = AT_RESPONSE_SENT_FREEZED;
+       }
 
        async_request = at_async_request_find_handled(AT_RESPONSE_UNHANDELD_REASON_STATUS);
-       if(async_request)
+       if(async_request) {
+               LOGD("Freezing a pending request");
                async_request->handled = AT_RESPONSE_SENT_FREEZED;
+       }
 
        async_request = at_async_request_find_handled(AT_RESPONSE_UNHANDELD_REASON_DATA);
-       if(async_request)
+       if(async_request) {
+               LOGD("Freezing a pending request");
                async_request->handled = AT_RESPONSE_SENT_FREEZED;
+       }
 
        return 0;
 }
@@ -2016,20 +2024,20 @@ int at_send_next_request(void)
        if(at_freeze_get() == AT_FREEZE_SEND) {
                sync_request = at_sync_request_find_handled(AT_RESPONSE_UNFREEZE);
                if(sync_request != NULL) {
+                       LOGD("Found an unfreeze sync request!");
                        request = sync_request->request;
                        goto request_send;
                }
 
                async_request = at_async_request_find_handled(AT_RESPONSE_UNFREEZE);
                if(async_request != NULL) {
+                       LOGD("Found an unfreeze async request!");
                        request = async_request->request;
                        goto request_send;
                }
 
-               if(request == NULL) {
-                       LOGD("No request to send during freeze!");
-                       return -1;
-               }
+               LOGD("No unfreeze request to send!");
+               return 0;
        }
 
        // Unhandled requests are still going on too
@@ -2046,7 +2054,7 @@ int at_send_next_request(void)
        request = at_request_dequeue();
        if(request == NULL) {
                LOGD("Nothing left to send!");
-               return -1;
+               return 0;
        }
 
 request_send:
index 1993e48..b2e65de 100644 (file)
--- a/device.c
+++ b/device.c
@@ -431,89 +431,104 @@ int ril_device_transport_recv_loop(struct ril_device *ril_device_p)
        int responses_count = 0;
        int responses_queued = 0;
 
+       int failures = 0;
+       int run = 1;
+
        char *data = NULL;
        int length = 0;
        int rc;
-       int i, j;
+       int i;
 
-       // Return error after 5 consecutive poll/read failures
-       for(i=5 ; i > 0 ; i--) {
-               while(1) {
-                       rc = ril_device_transport_recv_poll(ril_device_p);
-                       if(rc < 0) {
-                               LOGE("Polling from transport recv failed!");
-                               break;
-                       }
+run_loop:
+       while(run) {
+               rc = ril_device_transport_recv_poll(ril_device_p);
+               if(rc < 0) {
+                       LOGE("Polling from transport recv failed!");
+                       break;
+               }
 
-                       length = rc;
+               length = rc;
 
-                       rc = ril_device_transport_recv(ril_device_p, &data, length);
-                       if(rc <= 0 || data == NULL) {
-                               LOGE("Reading from transport recv failed!");
-                               break;
-                       }
+               rc = ril_device_transport_recv(ril_device_p, &data, length);
+               if(rc <= 0 || data == NULL) {
+                       LOGE("Reading from transport recv failed!");
+                       break;
+               }
+
+               length = rc;
 
-                       length = rc;
+               // Read works now
+               if(failures)
+                       failures = 0;
 
-                       // Read works now
-                       if(i != 5)
-                                i = 5;
+               responses_count = at_responses_process(&responses, data, length);
+               responses_queued = 0;
 
-                       responses_count = at_responses_process(&responses, data, length);
-                       responses_queued = 0;
+               // Log response
+               RIL_LOG_LOCK();
+               ril_data_log(data, length);
+               RIL_LOG_UNLOCK();
 
+               // Good way to give the recv loop some sleep: call at_send_expect_status
+               for(i=0 ; i < responses_count ; i++) {
                        // Log response
                        RIL_LOG_LOCK();
-                       ril_data_log(data, length);
+                       ril_recv_log(responses[i]);
                        RIL_LOG_UNLOCK();
 
-                       // Good way to give the recv loop some sleep: call at_send_expect_status
-                       for(j=0 ; j < responses_count ; j++) {
-                               // Log response
-                               RIL_LOG_LOCK();
-                               ril_recv_log(responses[j]);
-                               RIL_LOG_UNLOCK();
-
-                               // Handle sync
-                               rc = at_sync_response_dequeue(responses[j]);
+                       // Handle sync
+                       rc = at_sync_response_dequeue(responses[i]);
+                       if(rc < 0) {
+                               rc = at_response_queue(responses[i]);
                                if(rc < 0) {
-                                       rc = at_response_queue(responses[j]);
-                                       if(rc < 0) {
-                                               LOGE("Failed to queue response, clearing!");
-                                               at_response_free(responses[j]);
-                                       } else {
-                                               responses_queued = 1;
-                                       }
+                                       LOGE("Failed to queue response, clearing!");
+                                       at_response_free(responses[i]);
+                               } else {
+                                       responses_queued = 1;
                                }
                        }
+               }
 
-                       // Unlock the queue after adding all the requests to the queue (if any)
-                       if(responses_queued)
-                               at_responses_queue_unlock();
+               // Unlock the queue after adding all the requests to the queue (if any)
+               if(responses_queued)
+                       at_responses_queue_unlock();
 
-                       free(data);
-               }
+               free(data);
+       }
+
+       LOGE("RIL device transport recv loop stopped!");
+       failures++;
 
-               // Freeze all the sent requests
-               at_freeze_start();
+       // Freeze all the sent requests
+       at_freeze_start();
+
+       if(failures < 4) {
+               LOGD("Reopening transport...");
 
-               // When poll/read failed, close and reopen the device
                ril_device_transport_close(ril_device_p);
-               rc = ril_device_transport_open(ril_device_p);
-               if(rc < 0) {
-                       LOGE("Unable to reopen transport");
-               } else {
-                       at_freeze_send();
-                       at_freeze_respawn();
-               }
+       } else if(failures < 7) {
+               LOGD("Powering off and on again...");
 
-               // Unfreeze all the requests
-               at_freeze_stop();
+               ril_device_transport_close(ril_device_p);
+               ril_device_power_off(ril_device_p);
+               ril_device_power_on(ril_device_p);
+
+               LOGD("Reopening transport...");
+       }
 
-               RIL_DEVICE_UNLOCK(ril_device_p);
+       rc = ril_device_transport_open(ril_device_p);
+       if(rc < 0) {
+               LOGE("Unable to reopen transport!");
+               at_freeze_stop();
+               run = 0;
+       } else {
+               at_freeze_send();
+               run = 1;
        }
 
-       return -1;
+       RIL_DEVICE_UNLOCK(ril_device_p);
+
+       goto run_loop;
 }
 
 void *ril_device_transport_recv_thread(void *data)
@@ -522,25 +537,11 @@ void *ril_device_transport_recv_thread(void *data)
        int rc;
        int i;
 
-       for(i = 5 ; i > 0 ; i--) {
-               rc = ril_device_transport_recv_loop(ril_device_p);
-               if(rc < 0) {
-                       LOGE("Recv loop failed too many times, restarting...");
-
-                       rc = ril_device_deinit(ril_device_p);
-                       if(rc < 0)
-                               break;
-
-                       usleep(500);
-
-                       rc = ril_device_init(ril_device_p);
-                       if(rc < 0)
-                               break;
-               }
-       }
+       rc = ril_device_transport_recv_loop(ril_device_p);
+       LOGE("RIL device transport recv thread returned with %d, aborting!", rc);
 
-       LOGE("Recv thread failed too many times, stopping it all...");
        ril_device_deinit(ril_device_p);
+       at_freeze_set(AT_FREEZE_ON);
 
        return NULL;
 }
index 4a66fd0..b11275a 100644 (file)
@@ -136,6 +136,13 @@ void *ril_dispatch(void *data)
 
                        if(response == NULL && at_freeze_get() == AT_FREEZE_SEND) {
                                ril_device_at_setup(ril_device);
+
+                               // Respawn freezed requests
+                               at_freeze_respawn();
+
+                               // Stop freeze state
+                               at_freeze_stop();
+
                                continue;
                        } else if(response == NULL) {
                                break;