From 9365bf1ffd633b65bad7f95af90dcbb53e41652b Mon Sep 17 00:00:00 2001 From: "woojin.shin" Date: Thu, 18 Oct 2012 17:41:31 +0900 Subject: [PATCH] gps: fix for no gps signals after modem reset This fixes the problem that GPS doesn't work until reboot after modem reset. Bug: 7216911 Change-Id: Ibfee6a28850490548da2e0ccaefdabe9b826b5e9 Signed-off-by: Iliyan Malchev --- loc_api/loc_api_v02/loc_api_v02_client.c | 180 +++++++++++++++-------- 1 file changed, 118 insertions(+), 62 deletions(-) mode change 100755 => 100644 loc_api/loc_api_v02/loc_api_v02_client.c diff --git a/loc_api/loc_api_v02/loc_api_v02_client.c b/loc_api/loc_api_v02/loc_api_v02_client.c old mode 100755 new mode 100644 index 4d34adc4..bb745112 --- a/loc_api/loc_api_v02/loc_api_v02_client.c +++ b/loc_api/loc_api_v02/loc_api_v02_client.c @@ -71,7 +71,8 @@ #endif //LOC_UTIL_TARGET_OFF_TARGET //timeout in ms to wait for the service to come up -#define LOC_CLIENT_SERVICE_TIMEOUT (20000) +#define LOC_CLIENT_SERVICE_TIMEOUT_UNIT (4000) +#define LOC_CLIENT_SERVICE_TIMEOUT_TOTAL (60000) /* Table to relate eventId, size and mask value used to enable the event*/ typedef struct @@ -1401,14 +1402,17 @@ static bool validateRequest( static locClientStatusEnumType locClientQmiCtrlPointInit( locClientCallbackDataType *pLocClientCbData) { - uint32_t num_services, num_entries = 10; qmi_client_type clnt, notifier; - qmi_client_os_params os_params; - - // num instances of this service - qmi_service_info serviceInfo[5]; + bool notifierInitFlag = false; + locClientStatusEnumType status = eLOC_CLIENT_SUCCESS; + // instances of this service + qmi_service_info *pServiceInfo = NULL; + do + { + uint32_t num_services = 0, num_entries = 0; qmi_client_error_type rc = QMI_NO_ERR; + bool nosignal = false; // Get the service object for the qmiLoc Service qmi_idl_service_object_type locClientServiceObject = @@ -1419,73 +1423,107 @@ static locClientStatusEnumType locClientQmiCtrlPointInit( { LOC_LOGE("%s:%d]: qmiLoc_get_service_object_v02 failed\n" , __func__, __LINE__ ); - return(eLOC_CLIENT_FAILURE_INTERNAL); + status = eLOC_CLIENT_FAILURE_INTERNAL; + break; } - - // register for service notification - rc = qmi_client_notifier_init(locClientServiceObject, &os_params, ¬ifier); - - if(rc != QMI_NO_ERR) - { - LOC_LOGE("%s:%d]: qmi_client_notifier_init failed\n", - __func__, __LINE__ ); - return(eLOC_CLIENT_FAILURE_INTERNAL); - } - - /* If service is not up wait on a signal until the service is up - * or a timeout occurs. */ - - QMI_CCI_OS_SIGNAL_WAIT(&os_params, LOC_CLIENT_SERVICE_TIMEOUT); - - if(QMI_CCI_OS_SIGNAL_TIMED_OUT(&os_params)) - { - // timed out, return with error - LOC_LOGE("%s:%d]: timed out waiting for service\n", - __func__, __LINE__); - - return(eLOC_CLIENT_FAILURE_TIMEOUT); - } - else - { // get the service addressing information rc = qmi_client_get_service_list( locClientServiceObject, NULL, NULL, &num_services); - LOC_LOGV("%s:%d]: qmi_client_get_service_list() returned %d " - "num_services = %d\n", __func__, __LINE__, rc, - num_services); + LOC_LOGV("%s:%d]: qmi_client_get_service_list() first try rc %d, " + "num_services %d", __func__, __LINE__, rc, num_services); + + if (rc != QMI_NO_ERR) { + // bummer, service list is not up. + // We need to try again after a timed wait + qmi_client_os_params os_params; + int timeout = 0; + + // register for service notification + rc = qmi_client_notifier_init(locClientServiceObject, &os_params, ¬ifier); + notifierInitFlag = (NULL != notifier); + + if (rc != QMI_NO_ERR) { + LOC_LOGE("%s:%d]: qmi_client_notifier_init failed %d\n", + __func__, __LINE__, rc); + status = eLOC_CLIENT_FAILURE_INTERNAL; + break; + } + + do { + QMI_CCI_OS_SIGNAL_CLEAR(&os_params); + /* If service is not up wait on a signal until the service is up + * or a timeout occurs. */ + QMI_CCI_OS_SIGNAL_WAIT(&os_params, LOC_CLIENT_SERVICE_TIMEOUT_UNIT); + nosignal = QMI_CCI_OS_SIGNAL_TIMED_OUT(&os_params); + + // get the service addressing information + rc = qmi_client_get_service_list(locClientServiceObject, NULL, NULL, + &num_services); + + timeout += LOC_CLIENT_SERVICE_TIMEOUT_UNIT; + + LOC_LOGV("%s:%d]: qmi_client_get_service_list() rc %d, nosignal %d, " + "total timeout %d", __func__, __LINE__, rc, nosignal, timeout); + } while (timeout < LOC_CLIENT_SERVICE_TIMEOUT_TOTAL && nosignal && rc != QMI_NO_ERR); + } + + if (0 == num_services || rc != QMI_NO_ERR) { + if (!nosignal) { + LOC_LOGE("%s:%d]: qmi_client_get_service_list failed even though" + "service is up !!! Error %d \n", __func__, __LINE__, rc); + status = eLOC_CLIENT_FAILURE_INTERNAL; + } else { + LOC_LOGE("%s:%d]: qmi_client_get_service_list failed after retries," + " final Err %d", __func__, __LINE__, rc); + status = eLOC_CLIENT_FAILURE_TIMEOUT; + } + break; + } + + pServiceInfo = + (qmi_service_info *)malloc(num_services * sizeof(qmi_service_info)); + + if(NULL == pServiceInfo) + { + LOC_LOGE("%s:%d]: could not allocate memory for serviceInfo !!\n", + __func__, __LINE__); + + status = eLOC_CLIENT_FAILURE_INTERNAL; + break; + } + + //set the number of entries to get equal to the total number of + //services. + num_entries = num_services; + //populate the serviceInfo + rc = qmi_client_get_service_list( locClientServiceObject, pServiceInfo, + &num_entries, &num_services); + + + LOC_LOGV("%s:%d]: qmi_client_get_service_list()" + " returned %d num_entries = %d num_services = %d\n", + __func__, __LINE__, + rc, num_entries, num_services); if(rc != QMI_NO_ERR) { - LOC_LOGE("%s:%d]: qmi_client_get_service_list failed even though" - "service is up !!!\n", __func__, __LINE__); + LOC_LOGE("%s:%d]: qmi_client_get_service_list Error %d \n", + __func__, __LINE__, rc); - return(eLOC_CLIENT_FAILURE_INTERNAL); + status = eLOC_CLIENT_FAILURE_INTERNAL; + break; } - } - - //get service info to be used in qmi_client_init - rc = qmi_client_get_service_list( locClientServiceObject, serviceInfo, - &num_entries, &num_services); - - LOC_LOGV("%s:%d]: qmi_client_get_service_list()" - " returned %d num_entries = %d num_services = %d\n", - __func__, __LINE__, - rc, num_entries, num_services); - - if(rc != QMI_NO_ERR) - { - LOC_LOGE("%s:%d]: qmi_client_get_service_list Error %d \n", - __func__, __LINE__, rc); - - return(eLOC_CLIENT_FAILURE_INTERNAL); - } - LOC_LOGV("%s:%d]: passing the pointer %p to qmi_client_init \n", __func__, __LINE__, pLocClientCbData); + // initialize the client - rc = qmi_client_init(&serviceInfo[0], locClientServiceObject, + //sent the address of the first service found + // if IPC router is present, this will go to the service instance + // enumerated over IPC router, else it will go over the next transport where + // the service was enumerated. + rc = qmi_client_init(&pServiceInfo[0], locClientServiceObject, locClientIndCb, (void *) pLocClientCbData, NULL, &clnt); @@ -1493,7 +1531,9 @@ static locClientStatusEnumType locClientQmiCtrlPointInit( { LOC_LOGE("%s:%d]: qmi_client_init error %d\n", __func__, __LINE__, rc); - return(eLOC_CLIENT_FAILURE_INTERNAL); + + status = eLOC_CLIENT_FAILURE_INTERNAL; + break; } LOC_LOGV("%s:%d]: passing the pointer %p to" @@ -1508,14 +1548,30 @@ static locClientStatusEnumType locClientQmiCtrlPointInit( { LOC_LOGE("%s:%d]: could not register QCCI error callback error:%d\n", __func__, __LINE__, rc); - return (eLOC_CLIENT_FAILURE_INTERNAL); + + status = eLOC_CLIENT_FAILURE_INTERNAL; + break; } // copy the clnt handle returned in qmi_client_init memcpy(&(pLocClientCbData->userHandle), &clnt, sizeof(qmi_client_type)); - return(eLOC_CLIENT_SUCCESS); + status = eLOC_CLIENT_SUCCESS; + } while(0); + + /* release the notifier handle */ + if(true == notifierInitFlag) + { + qmi_client_release(notifier); + } + + if(NULL != pServiceInfo) + { + free((void *)pServiceInfo); + } + + return status; } //----------------------- END INTERNAL FUNCTIONS ----------------------------------------