Home | History | Annotate | Download | only in loc_api_v02
      1 /* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
      2  *
      3  * Redistribution and use in source and binary forms, with or without
      4  * modification, are permitted provided that the following conditions are
      5  * met:
      6  *     * Redistributions of source code must retain the above copyright
      7  *       notice, this list of conditions and the following disclaimer.
      8  *     * Redistributions in binary form must reproduce the above
      9  *       copyright notice, this list of conditions and the following
     10  *       disclaimer in the documentation and/or other materials provided
     11  *       with the distribution.
     12  *     * Neither the name of The Linux Foundatoin, nor the names of its
     13  *       contributors may be used to endorse or promote products derived
     14  *       from this software without specific prior written permission.
     15  *
     16  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
     17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     23  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     25  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     26  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 #define LOG_NDEBUG 0
     30 #define LOG_TAG "LocSvc_ApiV02"
     31 
     32 #include <stdio.h>
     33 #include <stdlib.h>
     34 #include <string.h>
     35 #include <math.h>
     36 #include <dlfcn.h>
     37 
     38 #include <hardware/gps.h>
     39 
     40 #ifndef USE_GLIB
     41 #include <utils/SystemClock.h>
     42 #endif /* USE_GLIB */
     43 #include <LocApiV02.h>
     44 #include <loc_api_v02_log.h>
     45 #include <loc_api_sync_req.h>
     46 #include <loc_api_v02_client.h>
     47 #include <loc_util_log.h>
     48 #include <gps_extended.h>
     49 #include "platform_lib_includes.h"
     50 
     51 using namespace loc_core;
     52 
     53 /* Doppler Conversion from M/S to NS/S */
     54 #define MPS_TO_NSPS         (1.0/0.299792458)
     55 
     56 /* Default session id ; TBD needs incrementing for each */
     57 #define LOC_API_V02_DEF_SESSION_ID (1)
     58 
     59 /* UMTS CP Address key*/
     60 #define LOC_NI_NOTIF_KEY_ADDRESS           "Address"
     61 
     62 /* GPS SV Id offset */
     63 #define GPS_SV_ID_OFFSET        (1)
     64 
     65 /* GLONASS SV Id offset */
     66 #define GLONASS_SV_ID_OFFSET    (65)
     67 
     68 /* SV ID range */
     69 #define SV_ID_RANGE             (32)
     70 
     71 #define BDS_SV_ID_OFFSET         (201)
     72 
     73 /* BeiDou SV ID RANGE*/
     74 #define BDS_SV_ID_RANGE          QMI_LOC_DELETE_MAX_BDS_SV_INFO_LENGTH_V02
     75 
     76 /* GPS week unknown*/
     77 #define C_GPS_WEEK_UNKNOWN      (65535)
     78 
     79 /* seconds per week*/
     80 #define WEEK_MSECS              (60*60*24*7*1000)
     81 
     82 /* number of QMI_LOC messages that need to be checked*/
     83 #define NUMBER_OF_MSG_TO_BE_CHECKED        (3)
     84 
     85 /* static event callbacks that call the LocApiV02 callbacks*/
     86 
     87 /* global event callback, call the eventCb function in loc api adapter v02
     88    instance */
     89 static void globalEventCb(locClientHandleType clientHandle,
     90                           uint32_t eventId,
     91                           const locClientEventIndUnionType eventPayload,
     92                           void*  pClientCookie)
     93 {
     94   MODEM_LOG_CALLFLOW(%s, loc_get_v02_event_name(eventId));
     95   LocApiV02 *locApiV02Instance =
     96       (LocApiV02 *)pClientCookie;
     97 
     98   LOC_LOGV ("%s:%d] client = %p, event id = %d, client cookie ptr = %p\n",
     99                   __func__,  __LINE__,  clientHandle, eventId, pClientCookie);
    100 
    101   // return if null is passed
    102   if( NULL == locApiV02Instance)
    103   {
    104     LOC_LOGE ("%s:%d] NULL object passed : client = %p, event id = %d\n",
    105                   __func__,  __LINE__,  clientHandle, eventId);
    106     return;
    107   }
    108   locApiV02Instance->eventCb(clientHandle, eventId, eventPayload);
    109 }
    110 
    111 /* global response callback, it calls the sync request process
    112    indication function to unblock the request that is waiting on this
    113    response indication*/
    114 static void globalRespCb(locClientHandleType clientHandle,
    115                          uint32_t respId,
    116                          const locClientRespIndUnionType respPayload,
    117                          uint32_t respPayloadSize,
    118                          void*  pClientCookie)
    119 {
    120   MODEM_LOG_CALLFLOW(%s, loc_get_v02_event_name(respId));
    121   LocApiV02 *locApiV02Instance =
    122         (LocApiV02 *)pClientCookie;
    123 
    124   LOC_LOGV ("%s:%d] client = %p, resp id = %d, client cookie ptr = %p\n",
    125                   __func__,  __LINE__,  clientHandle, respId, pClientCookie);
    126 
    127   if( NULL == locApiV02Instance)
    128   {
    129     LOC_LOGE ("%s:%d] NULL object passed : client = %p, resp id = %d\n",
    130                   __func__,  __LINE__,  clientHandle, respId);
    131     return;
    132   }
    133 
    134   // process the sync call
    135   // use pDeleteAssistDataInd as a dummy pointer
    136   loc_sync_process_ind(clientHandle, respId,
    137           (void *)respPayload.pDeleteAssistDataInd, respPayloadSize);
    138 }
    139 
    140 /* global error callback, it will call the handle service down
    141    function in the loc api adapter instance. */
    142 static void globalErrorCb (locClientHandleType clientHandle,
    143                            locClientErrorEnumType errorId,
    144                            void *pClientCookie)
    145 {
    146   LocApiV02 *locApiV02Instance =
    147           (LocApiV02 *)pClientCookie;
    148 
    149   LOC_LOGV ("%s:%d] client = %p, error id = %d\n, client cookie ptr = %p\n",
    150                   __func__,  __LINE__,  clientHandle, errorId, pClientCookie);
    151   if( NULL == locApiV02Instance)
    152   {
    153     LOC_LOGE ("%s:%d] NULL object passed : client = %p, error id = %d\n",
    154                   __func__,  __LINE__,  clientHandle, errorId);
    155     return;
    156   }
    157   locApiV02Instance->errorCb(clientHandle, errorId);
    158 }
    159 
    160 /* global structure containing the callbacks */
    161 locClientCallbacksType globalCallbacks =
    162 {
    163     sizeof(locClientCallbacksType),
    164     globalEventCb,
    165     globalRespCb,
    166     globalErrorCb
    167 };
    168 
    169 /* Constructor for LocApiV02 */
    170 LocApiV02 :: LocApiV02(const MsgTask* msgTask,
    171                        LOC_API_ADAPTER_EVENT_MASK_T exMask,
    172                        ContextBase* context):
    173     LocApiBase(msgTask, exMask, context),
    174     clientHandle(LOC_CLIENT_INVALID_HANDLE_VALUE),
    175     dsClientIface(NULL),
    176     dsClientHandle(NULL),
    177     mGnssMeasurementSupported(sup_unknown),
    178     mQmiMask(0), mInSession(false),
    179     mEngineOn(false), mMeasurementsStarted(false)
    180 {
    181   // initialize loc_sync_req interface
    182   loc_sync_req_init();
    183 }
    184 
    185 /* Destructor for LocApiV02 */
    186 LocApiV02 :: ~LocApiV02()
    187 {
    188     close();
    189 }
    190 
    191 LocApiBase* getLocApi(const MsgTask *msgTask,
    192                       LOC_API_ADAPTER_EVENT_MASK_T exMask,
    193                       ContextBase* context)
    194 {
    195     LOC_LOGD("%s:%d]: Creating new LocApiV02", __func__, __LINE__);
    196     return new LocApiV02(msgTask, exMask, context);
    197 }
    198 
    199 /* Initialize a loc api v02 client AND
    200    check which loc message are supported by modem */
    201 enum loc_api_adapter_err
    202 LocApiV02 :: open(LOC_API_ADAPTER_EVENT_MASK_T mask)
    203 {
    204   enum loc_api_adapter_err rtv = LOC_API_ADAPTER_ERR_SUCCESS;
    205   LOC_API_ADAPTER_EVENT_MASK_T newMask = mMask | (mask & ~mExcludedMask);
    206   locClientEventMaskType qmiMask = convertMask(newMask);
    207   LOC_LOGD("%s:%d]: Enter mMask: %x; mask: %x; newMask: %x mQmiMask: %lld qmiMask: %lld",
    208            __func__, __LINE__, mMask, mask, newMask, mQmiMask, qmiMask);
    209   /* If the client is already open close it first */
    210   if(LOC_CLIENT_INVALID_HANDLE_VALUE == clientHandle)
    211   {
    212     locClientStatusEnumType status = eLOC_CLIENT_SUCCESS;
    213 
    214     LOC_LOGV ("%s:%d]: reference to this = %p passed in \n",
    215               __func__, __LINE__, this);
    216     /* initialize the loc api v02 interface, note that
    217        the locClientOpen() function will block if the
    218        service is unavailable for a fixed time out */
    219 
    220     // it is important to cap the mask here, because not all LocApi's
    221     // can enable the same bits, e.g. foreground and bckground.
    222     status = locClientOpen(adjustMaskForNoSession(qmiMask), &globalCallbacks,
    223                            &clientHandle, (void *)this);
    224     mMask = newMask;
    225     mQmiMask = qmiMask;
    226     if (eLOC_CLIENT_SUCCESS != status ||
    227         clientHandle == LOC_CLIENT_INVALID_HANDLE_VALUE )
    228     {
    229       mMask = 0;
    230       mQmiMask = 0;
    231       LOC_LOGE ("%s:%d]: locClientOpen failed, status = %s\n", __func__,
    232                 __LINE__, loc_get_v02_client_status_name(status));
    233       rtv = LOC_API_ADAPTER_ERR_FAILURE;
    234     } else {
    235         uint64_t supportedMsgList = 0;
    236         const uint32_t msgArray[NUMBER_OF_MSG_TO_BE_CHECKED] =
    237         {
    238             // For - LOC_API_ADAPTER_MESSAGE_LOCATION_BATCHING
    239             QMI_LOC_GET_BATCH_SIZE_REQ_V02,
    240 
    241             // For - LOC_API_ADAPTER_MESSAGE_BATCHED_GENFENCE_BREACH
    242             QMI_LOC_EVENT_GEOFENCE_BATCHED_BREACH_NOTIFICATION_IND_V02,
    243 
    244             // For - LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_TRACKING
    245             QMI_LOC_START_DBT_REQ_V02
    246         };
    247 
    248         // check the modem
    249         status = locClientSupportMsgCheck(clientHandle,
    250                                           msgArray,
    251                                           NUMBER_OF_MSG_TO_BE_CHECKED,
    252                                           &supportedMsgList);
    253         if (eLOC_CLIENT_SUCCESS != status) {
    254             LOC_LOGE("%s:%d]: Failed to checking QMI_LOC message supported. \n",
    255                      __func__, __LINE__);
    256         }
    257 
    258         /** if batching is supported , check if the adaptive batching or
    259             distance-based batching is supported. */
    260         uint32_t messageChecker = 1 << LOC_API_ADAPTER_MESSAGE_LOCATION_BATCHING;
    261         if ((messageChecker & supportedMsgList) == messageChecker) {
    262             locClientReqUnionType req_union;
    263             locClientStatusEnumType status = eLOC_CLIENT_SUCCESS;
    264             qmiLocQueryAonConfigReqMsgT_v02 queryAonConfigReq;
    265             qmiLocQueryAonConfigIndMsgT_v02 queryAonConfigInd;
    266 
    267             memset(&queryAonConfigReq, 0, sizeof(queryAonConfigReq));
    268             memset(&queryAonConfigInd, 0, sizeof(queryAonConfigInd));
    269             queryAonConfigReq.transactionId = LOC_API_V02_DEF_SESSION_ID;
    270 
    271             req_union.pQueryAonConfigReq = &queryAonConfigReq;
    272             status = loc_sync_send_req(clientHandle,
    273                                        QMI_LOC_QUERY_AON_CONFIG_REQ_V02,
    274                                        req_union,
    275                                        LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
    276                                        QMI_LOC_QUERY_AON_CONFIG_IND_V02,
    277                                        &queryAonConfigInd);
    278 
    279             if (status == eLOC_CLIENT_FAILURE_UNSUPPORTED) {
    280                 LOC_LOGE("%s:%d]: Query AON config is not supported.\n", __func__, __LINE__);
    281             } else {
    282                 if (status != eLOC_CLIENT_SUCCESS ||
    283                     queryAonConfigInd.status != eQMI_LOC_SUCCESS_V02) {
    284                     LOC_LOGE("%s:%d]: Query AON config failed."
    285                              " status: %s, ind status:%s\n",
    286                              __func__, __LINE__,
    287                              loc_get_v02_client_status_name(status),
    288                              loc_get_v02_qmi_status_name(queryAonConfigInd.status));
    289                 } else {
    290                     LOC_LOGD("%s:%d]: Query AON config succeeded. aonCapability is %d.\n",
    291                              __func__, __LINE__, queryAonConfigInd.aonCapability);
    292                     if (queryAonConfigInd.aonCapability_valid) {
    293                         if (queryAonConfigInd.aonCapability |
    294                             QMI_LOC_MASK_AON_TIME_BASED_BATCHING_SUPPORTED_V02) {
    295                             LOC_LOGD("%s:%d]: LB 1.0 is supported.\n", __func__, __LINE__);
    296                         }
    297                         if (queryAonConfigInd.aonCapability |
    298                             QMI_LOC_MASK_AON_AUTO_BATCHING_SUPPORTED_V02) {
    299                             LOC_LOGD("%s:%d]: LB 1.5 is supported.\n", __func__, __LINE__);
    300                             supportedMsgList |=
    301                                 (1 << LOC_API_ADAPTER_MESSAGE_ADAPTIVE_LOCATION_BATCHING);
    302                         }
    303                         if (queryAonConfigInd.aonCapability |
    304                             QMI_LOC_MASK_AON_DISTANCE_BASED_BATCHING_SUPPORTED_V02) {
    305                             LOC_LOGD("%s:%d]: LB 2.0 is supported.\n", __func__, __LINE__);
    306                             supportedMsgList |=
    307                                 (1 << LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_LOCATION_BATCHING);
    308                         }
    309                         if (queryAonConfigInd.aonCapability |
    310                             QMI_LOC_MASK_AON_DISTANCE_BASED_TRACKING_SUPPORTED_V02) {
    311                             LOC_LOGD("%s:%d]: DBT 2.0 is supported.\n", __func__, __LINE__);
    312                         }
    313                         if (queryAonConfigInd.aonCapability |
    314                             QMI_LOC_MASK_AON_UPDATE_TBF_SUPPORTED_V02) {
    315                             LOC_LOGD("%s:%d]: Updating tracking TBF on the fly is supported.\n",
    316                             __func__, __LINE__);
    317                             supportedMsgList |=
    318                                 (1 << LOC_API_ADAPTER_MESSAGE_UPDATE_TBF_ON_THE_FLY);
    319                         }
    320                     } else {
    321                         LOC_LOGE("%s:%d]: AON capability is invalid.\n", __func__, __LINE__);
    322                     }
    323                 }
    324             }
    325         }
    326         LOC_LOGV("%s:%d]: supportedMsgList is %lld. \n",
    327                  __func__, __LINE__, supportedMsgList);
    328         // save the supported message list
    329         saveSupportedMsgList(supportedMsgList);
    330     }
    331   } else if (newMask != mMask) {
    332     // it is important to cap the mask here, because not all LocApi's
    333     // can enable the same bits, e.g. foreground and background.
    334     if (!registerEventMask(qmiMask)) {
    335       // we do not update mMask here, because it did not change
    336       // as the mask update has failed.
    337       rtv = LOC_API_ADAPTER_ERR_FAILURE;
    338     }
    339     else {
    340         mMask = newMask;
    341         mQmiMask = qmiMask;
    342     }
    343   }
    344   LOC_LOGD("%s:%d]: Exit mMask: %x; mask: %x mQmiMask: %llx qmiMask: %llx",
    345            __func__, __LINE__, mMask, mask, mQmiMask, qmiMask);
    346 
    347   if (LOC_API_ADAPTER_ERR_SUCCESS == rtv) {
    348       cacheGnssMeasurementSupport();
    349   }
    350 
    351   return rtv;
    352 }
    353 
    354 bool LocApiV02 :: registerEventMask(locClientEventMaskType qmiMask)
    355 {
    356     if (!mInSession) {
    357         qmiMask = adjustMaskForNoSession(qmiMask);
    358     }
    359     LOC_LOGD("%s:%d]: mQmiMask=%lld qmiMask=%lld",
    360              __func__, __LINE__, mQmiMask, qmiMask);
    361     return locClientRegisterEventMask(clientHandle, qmiMask);
    362 }
    363 
    364 locClientEventMaskType LocApiV02 :: adjustMaskForNoSession(locClientEventMaskType qmiMask)
    365 {
    366     LOC_LOGD("%s:%d]: before qmiMask=%lld",
    367              __func__, __LINE__, qmiMask);
    368     locClientEventMaskType clearMask = QMI_LOC_EVENT_MASK_POSITION_REPORT_V02 |
    369                                        QMI_LOC_EVENT_MASK_GNSS_SV_INFO_V02 |
    370                                        QMI_LOC_EVENT_MASK_NMEA_V02 |
    371                                        QMI_LOC_EVENT_MASK_ENGINE_STATE_V02 |
    372                                        QMI_LOC_EVENT_MASK_GNSS_MEASUREMENT_REPORT_V02;
    373 
    374     qmiMask = qmiMask & ~clearMask;
    375     LOC_LOGD("%s:%d]: after qmiMask=%lld",
    376              __func__, __LINE__, qmiMask);
    377     return qmiMask;
    378 }
    379 
    380 enum loc_api_adapter_err LocApiV02 :: close()
    381 {
    382   enum loc_api_adapter_err rtv =
    383       // success if either client is already invalid, or
    384       // we successfully close the handle
    385       (LOC_CLIENT_INVALID_HANDLE_VALUE == clientHandle ||
    386        eLOC_CLIENT_SUCCESS == locClientClose(&clientHandle)) ?
    387       LOC_API_ADAPTER_ERR_SUCCESS : LOC_API_ADAPTER_ERR_FAILURE;
    388 
    389   mMask = 0;
    390   clientHandle = LOC_CLIENT_INVALID_HANDLE_VALUE;
    391 
    392   return rtv;
    393 }
    394 
    395 /* start positioning session */
    396 enum loc_api_adapter_err LocApiV02 :: startFix(const LocPosMode& fixCriteria)
    397 {
    398   locClientStatusEnumType status;
    399   locClientReqUnionType req_union;
    400 
    401   qmiLocStartReqMsgT_v02 start_msg;
    402 
    403   qmiLocSetOperationModeReqMsgT_v02 set_mode_msg;
    404   qmiLocSetOperationModeIndMsgT_v02 set_mode_ind;
    405 
    406     // clear all fields, validity masks
    407   memset (&start_msg, 0, sizeof(start_msg));
    408   memset (&set_mode_msg, 0, sizeof(set_mode_msg));
    409   memset (&set_mode_ind, 0, sizeof(set_mode_ind));
    410 
    411   LOC_LOGV("%s:%d]: start \n", __func__, __LINE__);
    412   fixCriteria.logv();
    413 
    414   mInSession = true;
    415   mMeasurementsStarted = true;
    416   registerEventMask(mQmiMask);
    417 
    418   // fill in the start request
    419   switch(fixCriteria.mode)
    420   {
    421     case LOC_POSITION_MODE_MS_BASED:
    422       set_mode_msg.operationMode = eQMI_LOC_OPER_MODE_MSB_V02;
    423       break;
    424 
    425     case LOC_POSITION_MODE_MS_ASSISTED:
    426       set_mode_msg.operationMode = eQMI_LOC_OPER_MODE_MSA_V02;
    427       break;
    428 
    429     case LOC_POSITION_MODE_RESERVED_4:
    430       set_mode_msg.operationMode = eQMI_LOC_OPER_MODE_CELL_ID_V02;
    431         break;
    432 
    433     case LOC_POSITION_MODE_RESERVED_5:
    434       set_mode_msg.operationMode = eQMI_LOC_OPER_MODE_WWAN_V02;
    435         break;
    436 
    437     default:
    438       set_mode_msg.operationMode = eQMI_LOC_OPER_MODE_STANDALONE_V02;
    439       break;
    440   }
    441 
    442   req_union.pSetOperationModeReq = &set_mode_msg;
    443 
    444   // send the mode first, before the start message.
    445   status = loc_sync_send_req(clientHandle,
    446                              QMI_LOC_SET_OPERATION_MODE_REQ_V02,
    447                              req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
    448                              QMI_LOC_SET_OPERATION_MODE_IND_V02,
    449                              &set_mode_ind); // NULL?
    450    //When loc_sync_send_req status is time out, more likely the response was lost.
    451    //startFix will continue as though it is succeeded.
    452   if ((status != eLOC_CLIENT_SUCCESS && status != eLOC_CLIENT_FAILURE_TIMEOUT) ||
    453        eQMI_LOC_SUCCESS_V02 != set_mode_ind.status)
    454   {
    455     LOC_LOGE ("%s:%d]: set opertion mode failed status = %s, "
    456                    "ind..status = %s\n", __func__, __LINE__,
    457               loc_get_v02_client_status_name(status),
    458               loc_get_v02_qmi_status_name(set_mode_ind.status));
    459   } else {
    460       if (status == eLOC_CLIENT_FAILURE_TIMEOUT)
    461       {
    462           LOC_LOGE ("%s:%d]: set operation mode timed out\n", __func__, __LINE__);
    463       }
    464       start_msg.minInterval_valid = 1;
    465       start_msg.minInterval = fixCriteria.min_interval;
    466 
    467       if (fixCriteria.preferred_accuracy >= 0) {
    468           start_msg.horizontalAccuracyLevel_valid = 1;
    469 
    470           if (fixCriteria.preferred_accuracy <= 100)
    471           {
    472               // fix needs high accuracy
    473               start_msg.horizontalAccuracyLevel =  eQMI_LOC_ACCURACY_HIGH_V02;
    474           }
    475           else if (fixCriteria.preferred_accuracy <= 1000)
    476           {
    477               //fix needs med accuracy
    478               start_msg.horizontalAccuracyLevel =  eQMI_LOC_ACCURACY_MED_V02;
    479           }
    480           else
    481           {
    482               //fix needs low accuracy
    483               start_msg.horizontalAccuracyLevel =  eQMI_LOC_ACCURACY_LOW_V02;
    484           }
    485       }
    486 
    487       start_msg.fixRecurrence_valid = 1;
    488       if(GPS_POSITION_RECURRENCE_SINGLE == fixCriteria.recurrence)
    489       {
    490           start_msg.fixRecurrence = eQMI_LOC_RECURRENCE_SINGLE_V02;
    491       }
    492       else
    493       {
    494           start_msg.fixRecurrence = eQMI_LOC_RECURRENCE_PERIODIC_V02;
    495       }
    496 
    497       //dummy session id
    498       // TBD: store session ID, check for session id in pos reports.
    499       start_msg.sessionId = LOC_API_V02_DEF_SESSION_ID;
    500 
    501       if (fixCriteria.credentials[0] != 0) {
    502           int size1 = sizeof(start_msg.applicationId.applicationName);
    503           int size2 = sizeof(fixCriteria.credentials);
    504           int len = ((size1 < size2) ? size1 : size2) - 1;
    505           memcpy(start_msg.applicationId.applicationName,
    506                  fixCriteria.credentials,
    507                  len);
    508 
    509           size1 = sizeof(start_msg.applicationId.applicationProvider);
    510           size2 = sizeof(fixCriteria.provider);
    511           len = ((size1 < size2) ? size1 : size2) - 1;
    512           memcpy(start_msg.applicationId.applicationProvider,
    513                  fixCriteria.provider,
    514                  len);
    515 
    516           start_msg.applicationId_valid = 1;
    517       }
    518 
    519       // config Altitude Assumed
    520       start_msg.configAltitudeAssumed_valid = 1;
    521       start_msg.configAltitudeAssumed = eQMI_LOC_ALTITUDE_ASSUMED_IN_GNSS_SV_INFO_DISABLED_V02;
    522 
    523       req_union.pStartReq = &start_msg;
    524 
    525       status = locClientSendReq (clientHandle, QMI_LOC_START_REQ_V02,
    526                                  req_union );
    527   }
    528 
    529   return convertErr(status);
    530 }
    531 
    532 /* stop a positioning session */
    533 enum loc_api_adapter_err LocApiV02 :: stopFix()
    534 {
    535   locClientStatusEnumType status;
    536   locClientReqUnionType req_union;
    537 
    538   qmiLocStopReqMsgT_v02 stop_msg;
    539 
    540   LOC_LOGD(" %s:%d]: stop called \n", __func__, __LINE__);
    541 
    542   memset(&stop_msg, 0, sizeof(stop_msg));
    543 
    544   // dummy session id
    545   stop_msg.sessionId = LOC_API_V02_DEF_SESSION_ID;
    546 
    547   req_union.pStopReq = &stop_msg;
    548 
    549   status = locClientSendReq(clientHandle,
    550                             QMI_LOC_STOP_REQ_V02,
    551                             req_union);
    552 
    553   mInSession = false;
    554   // if engine on never happend, deregister events
    555   // without waiting for Engine Off
    556   if (!mEngineOn) {
    557       registerEventMask(mQmiMask);
    558   }
    559 
    560   if( eLOC_CLIENT_SUCCESS != status)
    561   {
    562       LOC_LOGE("%s:%d]: error = %s\n",__func__, __LINE__,
    563                loc_get_v02_client_status_name(status));
    564   }
    565 
    566   return convertErr(status);
    567 }
    568 
    569 /* set the positioning fix criteria */
    570 enum loc_api_adapter_err LocApiV02 :: setPositionMode(
    571   const LocPosMode& posMode)
    572 {
    573     if(isInSession())
    574     {
    575         //fix is in progress, send a restart
    576         LOC_LOGD ("%s:%d]: fix is in progress restarting the fix with new "
    577                   "criteria\n", __func__, __LINE__);
    578 
    579         return( startFix(posMode));
    580     }
    581 
    582     return LOC_API_ADAPTER_ERR_SUCCESS;
    583 }
    584 
    585 /* inject time into the position engine */
    586 enum loc_api_adapter_err LocApiV02 ::
    587     setTime(GpsUtcTime time, int64_t timeReference, int uncertainty)
    588 {
    589   locClientReqUnionType req_union;
    590   locClientStatusEnumType status;
    591   qmiLocInjectUtcTimeReqMsgT_v02  inject_time_msg;
    592   qmiLocInjectUtcTimeIndMsgT_v02 inject_time_ind;
    593 
    594   memset(&inject_time_msg, 0, sizeof(inject_time_msg));
    595 
    596   inject_time_ind.status = eQMI_LOC_GENERAL_FAILURE_V02;
    597 
    598   inject_time_msg.timeUtc = time;
    599 
    600   inject_time_msg.timeUtc += (int64_t)(ELAPSED_MILLIS_SINCE_BOOT_PLATFORM_LIB_ABSTRACTION - timeReference);
    601 
    602   inject_time_msg.timeUnc = uncertainty;
    603 
    604   req_union.pInjectUtcTimeReq = &inject_time_msg;
    605 
    606   LOC_LOGV ("%s:%d]: uncertainty = %d\n", __func__, __LINE__,
    607                  uncertainty);
    608 
    609   status = loc_sync_send_req(clientHandle,
    610                              QMI_LOC_INJECT_UTC_TIME_REQ_V02,
    611                              req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
    612                              QMI_LOC_INJECT_UTC_TIME_IND_V02,
    613                              &inject_time_ind);
    614 
    615   if (status != eLOC_CLIENT_SUCCESS ||
    616       eQMI_LOC_SUCCESS_V02 != inject_time_ind.status)
    617   {
    618     LOC_LOGE ("%s:%d] status = %s, ind..status = %s\n", __func__,  __LINE__,
    619               loc_get_v02_client_status_name(status),
    620               loc_get_v02_qmi_status_name(inject_time_ind.status));
    621   }
    622 
    623   return convertErr(status);
    624 }
    625 
    626 /* inject position into the position engine */
    627 enum loc_api_adapter_err LocApiV02 ::
    628     injectPosition(double latitude, double longitude, float accuracy)
    629 {
    630   locClientReqUnionType req_union;
    631   locClientStatusEnumType status;
    632   qmiLocInjectPositionReqMsgT_v02 inject_pos_msg;
    633   qmiLocInjectPositionIndMsgT_v02 inject_pos_ind;
    634 
    635   memset(&inject_pos_msg, 0, sizeof(inject_pos_msg));
    636 
    637   inject_pos_msg.latitude_valid = 1;
    638   inject_pos_msg.latitude = latitude;
    639 
    640   inject_pos_msg.longitude_valid = 1;
    641   inject_pos_msg.longitude = longitude;
    642 
    643   inject_pos_msg.horUncCircular_valid = 1;
    644 
    645   inject_pos_msg.horUncCircular = accuracy; //meters assumed
    646   if (inject_pos_msg.horUncCircular < 1000) {
    647       inject_pos_msg.horUncCircular = 1000;
    648   }
    649 
    650   inject_pos_msg.horConfidence_valid = 1;
    651 
    652   inject_pos_msg.horConfidence = 68; //1 std dev assumed as specified by API
    653 
    654   inject_pos_msg.rawHorUncCircular_valid = 1;
    655 
    656   inject_pos_msg.rawHorUncCircular = accuracy; //meters assumed
    657 
    658   inject_pos_msg.rawHorConfidence_valid = 1;
    659 
    660   inject_pos_msg.rawHorConfidence = 68; //1 std dev assumed as specified by API
    661 
    662     /* Log */
    663   LOC_LOGD("%s:%d]: Lat=%lf, Lon=%lf, Acc=%.2lf rawAcc=%.2lf", __func__, __LINE__,
    664                 inject_pos_msg.latitude, inject_pos_msg.longitude,
    665                 inject_pos_msg.horUncCircular, inject_pos_msg.rawHorUncCircular);
    666 
    667   req_union.pInjectPositionReq = &inject_pos_msg;
    668 
    669   status = loc_sync_send_req(clientHandle,
    670                              QMI_LOC_INJECT_POSITION_REQ_V02,
    671                              req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
    672                              QMI_LOC_INJECT_POSITION_IND_V02,
    673                              &inject_pos_ind);
    674 
    675   if (status != eLOC_CLIENT_SUCCESS ||
    676       eQMI_LOC_SUCCESS_V02 != inject_pos_ind.status)
    677   {
    678     LOC_LOGE ("%s:%d]: error! status = %s, inject_pos_ind.status = %s\n",
    679               __func__, __LINE__,
    680               loc_get_v02_client_status_name(status),
    681               loc_get_v02_qmi_status_name(inject_pos_ind.status));
    682   }
    683 
    684   return convertErr(status);
    685 }
    686 
    687 /* delete assistance date */
    688 enum loc_api_adapter_err LocApiV02 ::  deleteAidingData(GpsAidingData f)
    689 {
    690   locClientReqUnionType req_union;
    691   locClientStatusEnumType status;
    692   qmiLocDeleteAssistDataReqMsgT_v02 delete_req;
    693   qmiLocDeleteAssistDataIndMsgT_v02 delete_resp;
    694 
    695   memset(&delete_req, 0, sizeof(delete_req));
    696   memset(&delete_resp, 0, sizeof(delete_resp));
    697 
    698   if( f == GPS_DELETE_ALL )
    699   {
    700     delete_req.deleteAllFlag = true;
    701   }
    702 
    703   else
    704   {
    705     /* to keep track of svInfoList for GPS and GLO*/
    706     uint32_t curr_sv_len = 0;
    707     uint32_t curr_sv_idx = 0;
    708     uint32_t sv_id =  0;
    709 
    710     if((f & GPS_DELETE_EPHEMERIS ) || ( f & GPS_DELETE_ALMANAC ))
    711     {
    712       /* do delete for all GPS SV's */
    713 
    714       curr_sv_len += SV_ID_RANGE;
    715 
    716       sv_id = GPS_SV_ID_OFFSET;
    717 
    718       delete_req.deleteSvInfoList_valid = 1;
    719 
    720       delete_req.deleteSvInfoList_len = curr_sv_len;
    721 
    722       LOC_LOGV("%s:%d]: Delete GPS SV info for index %d to %d"
    723                     "and sv id %d to %d \n",
    724                     __func__, __LINE__, curr_sv_idx, curr_sv_len - 1,
    725                     sv_id, sv_id+SV_ID_RANGE-1);
    726 
    727       for( uint32_t i = curr_sv_idx; i< curr_sv_len ; i++, sv_id++ )
    728       {
    729         delete_req.deleteSvInfoList[i].gnssSvId = sv_id;
    730 
    731         delete_req.deleteSvInfoList[i].system = eQMI_LOC_SV_SYSTEM_GPS_V02;
    732 
    733         if(f & GPS_DELETE_EPHEMERIS )
    734         {
    735           // set ephemeris mask for all GPS SV's
    736           delete_req.deleteSvInfoList[i].deleteSvInfoMask |=
    737             QMI_LOC_MASK_DELETE_EPHEMERIS_V02;
    738         }
    739 
    740         if( f & GPS_DELETE_ALMANAC )
    741         {
    742           delete_req.deleteSvInfoList[i].deleteSvInfoMask |=
    743             QMI_LOC_MASK_DELETE_ALMANAC_V02;
    744         }
    745       }
    746       // increment the current index
    747       curr_sv_idx += SV_ID_RANGE;
    748 
    749     }
    750 
    751     if(f & GPS_DELETE_POSITION )
    752     {
    753       delete_req.deleteGnssDataMask_valid = 1;
    754       delete_req.deleteGnssDataMask |= QMI_LOC_MASK_DELETE_POSITION_V02;
    755     }
    756 
    757     if(f & GPS_DELETE_TIME )
    758     {
    759       delete_req.deleteGnssDataMask_valid = 1;
    760       delete_req.deleteGnssDataMask |= QMI_LOC_MASK_DELETE_TIME_V02;
    761     }
    762 
    763     if(f & GPS_DELETE_IONO )
    764     {
    765       delete_req.deleteGnssDataMask_valid = 1;
    766       delete_req.deleteGnssDataMask |= QMI_LOC_MASK_DELETE_IONO_V02;
    767     }
    768 
    769     if(f & GPS_DELETE_UTC )
    770     {
    771       delete_req.deleteGnssDataMask_valid = 1;
    772       delete_req.deleteGnssDataMask |= QMI_LOC_MASK_DELETE_UTC_V02;
    773     }
    774 
    775     if(f & GPS_DELETE_HEALTH )
    776     {
    777       delete_req.deleteGnssDataMask_valid = 1;
    778       delete_req.deleteGnssDataMask |= QMI_LOC_MASK_DELETE_HEALTH_V02;
    779     }
    780 
    781     if(f & GPS_DELETE_SVDIR )
    782     {
    783       delete_req.deleteGnssDataMask_valid = 1;
    784       delete_req.deleteGnssDataMask |= QMI_LOC_MASK_DELETE_GPS_SVDIR_V02;
    785     }
    786     if(f & GPS_DELETE_SADATA )
    787     {
    788       delete_req.deleteGnssDataMask_valid = 1;
    789       delete_req.deleteGnssDataMask |= QMI_LOC_MASK_DELETE_SADATA_V02;
    790     }
    791     if(f & GPS_DELETE_RTI )
    792     {
    793       delete_req.deleteGnssDataMask_valid = 1;
    794       delete_req.deleteGnssDataMask |= QMI_LOC_MASK_DELETE_RTI_V02;
    795     }
    796     if(f & GPS_DELETE_CELLDB_INFO )
    797     {
    798       delete_req.deleteCellDbDataMask_valid = 1;
    799       delete_req.deleteCellDbDataMask =
    800         ( QMI_LOC_MASK_DELETE_CELLDB_POS_V02 |
    801           QMI_LOC_MASK_DELETE_CELLDB_LATEST_GPS_POS_V02 |
    802           QMI_LOC_MASK_DELETE_CELLDB_OTA_POS_V02 |
    803           QMI_LOC_MASK_DELETE_CELLDB_EXT_REF_POS_V02 |
    804           QMI_LOC_MASK_DELETE_CELLDB_TIMETAG_V02 |
    805           QMI_LOC_MASK_DELETE_CELLDB_CELLID_V02 |
    806           QMI_LOC_MASK_DELETE_CELLDB_CACHED_CELLID_V02 |
    807           QMI_LOC_MASK_DELETE_CELLDB_LAST_SRV_CELL_V02 |
    808           QMI_LOC_MASK_DELETE_CELLDB_CUR_SRV_CELL_V02 |
    809           QMI_LOC_MASK_DELETE_CELLDB_NEIGHBOR_INFO_V02) ;
    810 
    811     }
    812 #ifndef PDK_FEATURE_SET
    813 #endif
    814 
    815   }
    816 
    817   req_union.pDeleteAssistDataReq = &delete_req;
    818 
    819   status = loc_sync_send_req(clientHandle,
    820                              QMI_LOC_DELETE_ASSIST_DATA_REQ_V02,
    821                              req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
    822                              QMI_LOC_DELETE_ASSIST_DATA_IND_V02,
    823                              &delete_resp);
    824 
    825   if (status != eLOC_CLIENT_SUCCESS ||
    826       eQMI_LOC_SUCCESS_V02 != delete_resp.status)
    827   {
    828     LOC_LOGE ("%s:%d]: error! status = %s, delete_resp.status = %s\n",
    829               __func__, __LINE__,
    830               loc_get_v02_client_status_name(status),
    831               loc_get_v02_qmi_status_name(delete_resp.status));
    832   }
    833 
    834   return convertErr(status);
    835 }
    836 
    837 /* send NI user repsonse to the engine */
    838 enum loc_api_adapter_err LocApiV02 ::
    839     informNiResponse(GpsUserResponseType userResponse,
    840                      const void* passThroughData)
    841 {
    842   locClientReqUnionType req_union;
    843   locClientStatusEnumType status;
    844 
    845   qmiLocNiUserRespReqMsgT_v02 ni_resp;
    846   qmiLocNiUserRespIndMsgT_v02 ni_resp_ind;
    847 
    848   qmiLocEventNiNotifyVerifyReqIndMsgT_v02 *request_pass_back =
    849     (qmiLocEventNiNotifyVerifyReqIndMsgT_v02 *)passThroughData;
    850 
    851   memset(&ni_resp,0, sizeof(ni_resp));
    852 
    853   memset(&ni_resp_ind,0, sizeof(ni_resp_ind));
    854 
    855   switch (userResponse)
    856   {
    857     case GPS_NI_RESPONSE_ACCEPT:
    858       ni_resp.userResp = eQMI_LOC_NI_LCS_NOTIFY_VERIFY_ACCEPT_V02;
    859       break;
    860    case GPS_NI_RESPONSE_DENY:
    861       ni_resp.userResp = eQMI_LOC_NI_LCS_NOTIFY_VERIFY_DENY_V02;
    862       break;
    863    case GPS_NI_RESPONSE_NORESP:
    864       ni_resp.userResp = eQMI_LOC_NI_LCS_NOTIFY_VERIFY_NORESP_V02;
    865       break;
    866    default:
    867       return LOC_API_ADAPTER_ERR_INVALID_PARAMETER;
    868   }
    869 
    870   LOC_LOGV(" %s:%d]: NI response: %d\n", __func__, __LINE__,
    871                 ni_resp.userResp);
    872 
    873   ni_resp.notificationType = request_pass_back->notificationType;
    874 
    875   // copy SUPL payload from request
    876   if(request_pass_back->NiSuplInd_valid == 1)
    877   {
    878      ni_resp.NiSuplPayload_valid = 1;
    879      memcpy(&(ni_resp.NiSuplPayload), &(request_pass_back->NiSuplInd),
    880             sizeof(qmiLocNiSuplNotifyVerifyStructT_v02));
    881 
    882   }
    883   // should this be an "else if"?? we don't need to decide
    884 
    885   // copy UMTS-CP payload from request
    886   if( request_pass_back->NiUmtsCpInd_valid == 1 )
    887   {
    888      ni_resp.NiUmtsCpPayload_valid = 1;
    889      memcpy(&(ni_resp.NiUmtsCpPayload), &(request_pass_back->NiUmtsCpInd),
    890             sizeof(qmiLocNiUmtsCpNotifyVerifyStructT_v02));
    891   }
    892 
    893   //copy Vx payload from the request
    894   if( request_pass_back->NiVxInd_valid == 1)
    895   {
    896      ni_resp.NiVxPayload_valid = 1;
    897      memcpy(&(ni_resp.NiVxPayload), &(request_pass_back->NiVxInd),
    898             sizeof(qmiLocNiVxNotifyVerifyStructT_v02));
    899   }
    900 
    901   // copy Vx service interaction payload from the request
    902   if(request_pass_back->NiVxServiceInteractionInd_valid == 1)
    903   {
    904      ni_resp.NiVxServiceInteractionPayload_valid = 1;
    905      memcpy(&(ni_resp.NiVxServiceInteractionPayload),
    906             &(request_pass_back->NiVxServiceInteractionInd),
    907             sizeof(qmiLocNiVxServiceInteractionStructT_v02));
    908   }
    909 
    910   // copy Network Initiated SUPL Version 2 Extension
    911   if (request_pass_back->NiSuplVer2ExtInd_valid == 1)
    912   {
    913      ni_resp.NiSuplVer2ExtPayload_valid = 1;
    914      memcpy(&(ni_resp.NiSuplVer2ExtPayload),
    915             &(request_pass_back->NiSuplVer2ExtInd),
    916             sizeof(qmiLocNiSuplVer2ExtStructT_v02));
    917   }
    918 
    919   // copy SUPL Emergency Notification
    920   if(request_pass_back->suplEmergencyNotification_valid)
    921   {
    922      ni_resp.suplEmergencyNotification_valid = 1;
    923      memcpy(&(ni_resp.suplEmergencyNotification),
    924             &(request_pass_back->suplEmergencyNotification),
    925             sizeof(qmiLocEmergencyNotificationStructT_v02));
    926   }
    927 
    928   req_union.pNiUserRespReq = &ni_resp;
    929 
    930   status = loc_sync_send_req (
    931      clientHandle, QMI_LOC_NI_USER_RESPONSE_REQ_V02,
    932      req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
    933      QMI_LOC_NI_USER_RESPONSE_IND_V02, &ni_resp_ind);
    934 
    935   if (status != eLOC_CLIENT_SUCCESS ||
    936       eQMI_LOC_SUCCESS_V02 != ni_resp_ind.status)
    937   {
    938     LOC_LOGE ("%s:%d]: error! status = %s, ni_resp_ind.status = %s\n",
    939               __func__, __LINE__,
    940               loc_get_v02_client_status_name(status),
    941               loc_get_v02_qmi_status_name(ni_resp_ind.status));
    942   }
    943 
    944   return convertErr(status);
    945 }
    946 
    947 /* Set UMTs SLP server URL */
    948 enum loc_api_adapter_err LocApiV02 :: setServer(
    949   const char* url, int len)
    950 {
    951   locClientReqUnionType req_union;
    952   locClientStatusEnumType status;
    953   qmiLocSetServerReqMsgT_v02 set_server_req;
    954   qmiLocSetServerIndMsgT_v02 set_server_ind;
    955 
    956   if(len < 0 || len > sizeof(set_server_req.urlAddr))
    957   {
    958     LOC_LOGE("%s:%d]: len = %d greater than max allowed url length\n",
    959                   __func__, __LINE__, len);
    960 
    961     return LOC_API_ADAPTER_ERR_INVALID_PARAMETER;
    962   }
    963 
    964   memset(&set_server_req, 0, sizeof(set_server_req));
    965 
    966   LOC_LOGD("%s:%d]:, url = %s, len = %d\n", __func__, __LINE__, url, len);
    967 
    968   set_server_req.serverType = eQMI_LOC_SERVER_TYPE_UMTS_SLP_V02;
    969 
    970   set_server_req.urlAddr_valid = 1;
    971 
    972   strlcpy(set_server_req.urlAddr, url, sizeof(set_server_req.urlAddr));
    973 
    974   req_union.pSetServerReq = &set_server_req;
    975 
    976   status = loc_sync_send_req(clientHandle,
    977                              QMI_LOC_SET_SERVER_REQ_V02,
    978                              req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
    979                              QMI_LOC_SET_SERVER_IND_V02,
    980                              &set_server_ind);
    981 
    982   if (status != eLOC_CLIENT_SUCCESS ||
    983          eQMI_LOC_SUCCESS_V02 != set_server_ind.status)
    984   {
    985     LOC_LOGE ("%s:%d]: error status = %s, set_server_ind.status = %s\n",
    986               __func__,__LINE__,
    987               loc_get_v02_client_status_name(status),
    988               loc_get_v02_qmi_status_name(set_server_ind.status));
    989   }
    990 
    991   return convertErr(status);
    992 }
    993 
    994 enum loc_api_adapter_err LocApiV02 ::
    995     setServer(unsigned int ip, int port, LocServerType type)
    996 {
    997   locClientReqUnionType req_union;
    998   locClientStatusEnumType status;
    999   qmiLocSetServerReqMsgT_v02 set_server_req;
   1000   qmiLocSetServerIndMsgT_v02 set_server_ind;
   1001   qmiLocServerTypeEnumT_v02 set_server_cmd;
   1002 
   1003   switch (type) {
   1004   case LOC_AGPS_MPC_SERVER:
   1005       set_server_cmd = eQMI_LOC_SERVER_TYPE_CDMA_MPC_V02;
   1006       break;
   1007   case LOC_AGPS_CUSTOM_PDE_SERVER:
   1008       set_server_cmd = eQMI_LOC_SERVER_TYPE_CUSTOM_PDE_V02;
   1009       break;
   1010   default:
   1011       set_server_cmd = eQMI_LOC_SERVER_TYPE_CDMA_PDE_V02;
   1012       break;
   1013   }
   1014 
   1015   memset(&set_server_req, 0, sizeof(set_server_req));
   1016 
   1017   LOC_LOGD("%s:%d]:, ip = %u, port = %d\n", __func__, __LINE__, ip, port);
   1018 
   1019   set_server_req.serverType = set_server_cmd;
   1020   set_server_req.ipv4Addr_valid = 1;
   1021   set_server_req.ipv4Addr.addr = ip;
   1022   set_server_req.ipv4Addr.port = port;
   1023 
   1024   req_union.pSetServerReq = &set_server_req;
   1025 
   1026   status = loc_sync_send_req(clientHandle,
   1027                              QMI_LOC_SET_SERVER_REQ_V02,
   1028                              req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
   1029                              QMI_LOC_SET_SERVER_IND_V02,
   1030                              &set_server_ind);
   1031 
   1032   if (status != eLOC_CLIENT_SUCCESS ||
   1033       eQMI_LOC_SUCCESS_V02 != set_server_ind.status)
   1034   {
   1035     LOC_LOGE ("%s:%d]: error status = %s, set_server_ind.status = %s\n",
   1036               __func__,__LINE__,
   1037               loc_get_v02_client_status_name(status),
   1038               loc_get_v02_qmi_status_name(set_server_ind.status));
   1039   }
   1040 
   1041   return convertErr(status);
   1042 }
   1043 
   1044 /* Inject XTRA data, this module breaks down the XTRA
   1045    file into "chunks" and injects them one at a time */
   1046 enum loc_api_adapter_err LocApiV02 :: setXtraData(
   1047   char* data, int length)
   1048 {
   1049   locClientStatusEnumType status = eLOC_CLIENT_SUCCESS;
   1050   int     total_parts;
   1051   uint8_t   part;
   1052   uint16_t  len_injected;
   1053 
   1054   locClientReqUnionType req_union;
   1055   qmiLocInjectPredictedOrbitsDataReqMsgT_v02 inject_xtra;
   1056   qmiLocInjectPredictedOrbitsDataIndMsgT_v02 inject_xtra_ind;
   1057 
   1058   req_union.pInjectPredictedOrbitsDataReq = &inject_xtra;
   1059 
   1060   LOC_LOGD("%s:%d]: xtra size = %d\n", __func__, __LINE__, length);
   1061 
   1062   inject_xtra.formatType_valid = 1;
   1063   inject_xtra.formatType = eQMI_LOC_PREDICTED_ORBITS_XTRA_V02;
   1064   inject_xtra.totalSize = length;
   1065 
   1066   total_parts = ((length - 1) / QMI_LOC_MAX_PREDICTED_ORBITS_PART_LEN_V02) + 1;
   1067 
   1068   inject_xtra.totalParts = total_parts;
   1069 
   1070   len_injected = 0; // O bytes injected
   1071 
   1072   // XTRA injection starts with part 1
   1073   for (part = 1; part <= total_parts; part++)
   1074   {
   1075     inject_xtra.partNum = part;
   1076 
   1077     if (QMI_LOC_MAX_PREDICTED_ORBITS_PART_LEN_V02 > (length - len_injected))
   1078     {
   1079       inject_xtra.partData_len = length - len_injected;
   1080     }
   1081     else
   1082     {
   1083       inject_xtra.partData_len = QMI_LOC_MAX_PREDICTED_ORBITS_PART_LEN_V02;
   1084     }
   1085 
   1086     // copy data into the message
   1087     memcpy(inject_xtra.partData, data+len_injected, inject_xtra.partData_len);
   1088 
   1089     LOC_LOGD("[%s:%d] part %d/%d, len = %d, total injected = %d\n",
   1090                   __func__, __LINE__,
   1091                   inject_xtra.partNum, total_parts, inject_xtra.partData_len,
   1092                   len_injected);
   1093 
   1094     status = loc_sync_send_req( clientHandle,
   1095                                 QMI_LOC_INJECT_PREDICTED_ORBITS_DATA_REQ_V02,
   1096                                 req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
   1097                                 QMI_LOC_INJECT_PREDICTED_ORBITS_DATA_IND_V02,
   1098                                 &inject_xtra_ind);
   1099 
   1100     if (status != eLOC_CLIENT_SUCCESS ||
   1101         eQMI_LOC_SUCCESS_V02 != inject_xtra_ind.status ||
   1102         inject_xtra.partNum != inject_xtra_ind.partNum)
   1103     {
   1104       LOC_LOGE ("%s:%d]: failed status = %s, inject_pos_ind.status = %s,"
   1105                      " part num = %d, ind.partNum = %d\n", __func__, __LINE__,
   1106                 loc_get_v02_client_status_name(status),
   1107                 loc_get_v02_qmi_status_name(inject_xtra_ind.status),
   1108                 inject_xtra.partNum, inject_xtra_ind.partNum);
   1109     } else {
   1110       len_injected += inject_xtra.partData_len;
   1111       LOC_LOGD("%s:%d]: XTRA injected length: %d\n", __func__, __LINE__,
   1112                len_injected);
   1113     }
   1114   }
   1115 
   1116   return convertErr(status);
   1117 }
   1118 
   1119 /* Request the Xtra Server Url from the modem */
   1120 enum loc_api_adapter_err LocApiV02 :: requestXtraServer()
   1121 {
   1122   locClientStatusEnumType status = eLOC_CLIENT_SUCCESS;
   1123 
   1124   locClientReqUnionType req_union;
   1125   qmiLocGetPredictedOrbitsDataSourceIndMsgT_v02 request_xtra_server_ind;
   1126 
   1127   status = loc_sync_send_req( clientHandle,
   1128                               QMI_LOC_GET_PREDICTED_ORBITS_DATA_SOURCE_REQ_V02,
   1129                               req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
   1130                               QMI_LOC_GET_PREDICTED_ORBITS_DATA_SOURCE_IND_V02,
   1131                               &request_xtra_server_ind);
   1132 
   1133   if (status == eLOC_CLIENT_SUCCESS &&
   1134       eQMI_LOC_SUCCESS_V02 == request_xtra_server_ind.status &&
   1135       false != request_xtra_server_ind.serverList_valid &&
   1136       0 != request_xtra_server_ind.serverList.serverList_len)
   1137   {
   1138     if (request_xtra_server_ind.serverList.serverList_len == 1)
   1139     {
   1140       reportXtraServer(request_xtra_server_ind.serverList.serverList[0].serverUrl,
   1141                        "",
   1142                        "",
   1143                        QMI_LOC_MAX_SERVER_ADDR_LENGTH_V02);
   1144     }
   1145     else if (request_xtra_server_ind.serverList.serverList_len == 2)
   1146     {
   1147       reportXtraServer(request_xtra_server_ind.serverList.serverList[0].serverUrl,
   1148                        request_xtra_server_ind.serverList.serverList[1].serverUrl,
   1149                        "",
   1150                        QMI_LOC_MAX_SERVER_ADDR_LENGTH_V02);
   1151     }
   1152     else
   1153     {
   1154       reportXtraServer(request_xtra_server_ind.serverList.serverList[0].serverUrl,
   1155                        request_xtra_server_ind.serverList.serverList[1].serverUrl,
   1156                        request_xtra_server_ind.serverList.serverList[2].serverUrl,
   1157                        QMI_LOC_MAX_SERVER_ADDR_LENGTH_V02);
   1158     }
   1159   }
   1160 
   1161   return convertErr(status);
   1162 }
   1163 
   1164 enum loc_api_adapter_err LocApiV02 :: atlOpenStatus(
   1165   int handle, int is_succ, char* apn, AGpsBearerType bear,
   1166   AGpsType agpsType)
   1167 {
   1168   locClientStatusEnumType result = eLOC_CLIENT_SUCCESS;
   1169   locClientReqUnionType req_union;
   1170   qmiLocInformLocationServerConnStatusReqMsgT_v02 conn_status_req;
   1171   qmiLocInformLocationServerConnStatusIndMsgT_v02 conn_status_ind;
   1172 
   1173 
   1174   LOC_LOGD("%s:%d]: ATL open handle = %d, is_succ = %d, "
   1175                 "APN = [%s], bearer = %d \n",  __func__, __LINE__,
   1176                 handle, is_succ, apn, bear);
   1177 
   1178   memset(&conn_status_req, 0, sizeof(conn_status_req));
   1179   memset(&conn_status_ind, 0, sizeof(conn_status_ind));
   1180 
   1181         // Fill in data
   1182   conn_status_req.connHandle = handle;
   1183 
   1184   conn_status_req.requestType = eQMI_LOC_SERVER_REQUEST_OPEN_V02;
   1185 
   1186   if(is_succ)
   1187   {
   1188     conn_status_req.statusType = eQMI_LOC_SERVER_REQ_STATUS_SUCCESS_V02;
   1189 
   1190     if(apn != NULL)
   1191         strlcpy(conn_status_req.apnProfile.apnName, apn,
   1192                 sizeof(conn_status_req.apnProfile.apnName) );
   1193 
   1194     switch(bear)
   1195     {
   1196     case AGPS_APN_BEARER_IPV4:
   1197         conn_status_req.apnProfile.pdnType =
   1198             eQMI_LOC_APN_PROFILE_PDN_TYPE_IPV4_V02;
   1199         conn_status_req.apnProfile_valid = 1;
   1200         break;
   1201 
   1202     case AGPS_APN_BEARER_IPV6:
   1203         conn_status_req.apnProfile.pdnType =
   1204             eQMI_LOC_APN_PROFILE_PDN_TYPE_IPV6_V02;
   1205         conn_status_req.apnProfile_valid = 1;
   1206         break;
   1207 
   1208     case AGPS_APN_BEARER_IPV4V6:
   1209         conn_status_req.apnProfile.pdnType =
   1210             eQMI_LOC_APN_PROFILE_PDN_TYPE_IPV4V6_V02;
   1211         conn_status_req.apnProfile_valid = 1;
   1212         break;
   1213 
   1214     case AGPS_APN_BEARER_INVALID:
   1215         conn_status_req.apnProfile_valid = 0;
   1216         break;
   1217 
   1218     default:
   1219         LOC_LOGE("%s:%d]:invalid bearer type\n",__func__,__LINE__);
   1220         conn_status_req.apnProfile_valid = 0;
   1221         return LOC_API_ADAPTER_ERR_INVALID_HANDLE;
   1222     }
   1223 
   1224   }
   1225   else
   1226   {
   1227     conn_status_req.statusType = eQMI_LOC_SERVER_REQ_STATUS_FAILURE_V02;
   1228   }
   1229 
   1230   req_union.pInformLocationServerConnStatusReq = &conn_status_req;
   1231 
   1232   result = loc_sync_send_req(clientHandle,
   1233                              QMI_LOC_INFORM_LOCATION_SERVER_CONN_STATUS_REQ_V02,
   1234                              req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
   1235                              QMI_LOC_INFORM_LOCATION_SERVER_CONN_STATUS_IND_V02,
   1236                              &conn_status_ind);
   1237 
   1238   if(result != eLOC_CLIENT_SUCCESS ||
   1239      eQMI_LOC_SUCCESS_V02 != conn_status_ind.status)
   1240   {
   1241     LOC_LOGE ("%s:%d]: Error status = %s, ind..status = %s ",
   1242               __func__, __LINE__,
   1243               loc_get_v02_client_status_name(result),
   1244               loc_get_v02_qmi_status_name(conn_status_ind.status));
   1245   }
   1246 
   1247   return convertErr(result);
   1248 
   1249 }
   1250 
   1251 
   1252 /* close atl connection */
   1253 enum loc_api_adapter_err LocApiV02 :: atlCloseStatus(
   1254   int handle, int is_succ)
   1255 {
   1256   locClientStatusEnumType result = eLOC_CLIENT_SUCCESS;
   1257   locClientReqUnionType req_union;
   1258   qmiLocInformLocationServerConnStatusReqMsgT_v02 conn_status_req;
   1259   qmiLocInformLocationServerConnStatusIndMsgT_v02 conn_status_ind;
   1260 
   1261   LOC_LOGD("%s:%d]: ATL close handle = %d, is_succ = %d\n",
   1262                  __func__, __LINE__,  handle, is_succ);
   1263 
   1264   memset(&conn_status_req, 0, sizeof(conn_status_req));
   1265   memset(&conn_status_ind, 0, sizeof(conn_status_ind));
   1266 
   1267         // Fill in data
   1268   conn_status_req.connHandle = handle;
   1269 
   1270   conn_status_req.requestType = eQMI_LOC_SERVER_REQUEST_CLOSE_V02;
   1271 
   1272   if(is_succ)
   1273   {
   1274     conn_status_req.statusType = eQMI_LOC_SERVER_REQ_STATUS_SUCCESS_V02;
   1275   }
   1276   else
   1277   {
   1278     conn_status_req.statusType = eQMI_LOC_SERVER_REQ_STATUS_FAILURE_V02;
   1279   }
   1280 
   1281   req_union.pInformLocationServerConnStatusReq = &conn_status_req;
   1282 
   1283   result = loc_sync_send_req(clientHandle,
   1284                              QMI_LOC_INFORM_LOCATION_SERVER_CONN_STATUS_REQ_V02,
   1285                              req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
   1286                              QMI_LOC_INFORM_LOCATION_SERVER_CONN_STATUS_IND_V02,
   1287                              &conn_status_ind);
   1288 
   1289   if(result != eLOC_CLIENT_SUCCESS ||
   1290      eQMI_LOC_SUCCESS_V02 != conn_status_ind.status)
   1291   {
   1292     LOC_LOGE ("%s:%d]: Error status = %s, ind..status = %s ",
   1293               __func__, __LINE__,
   1294               loc_get_v02_client_status_name(result),
   1295               loc_get_v02_qmi_status_name(conn_status_ind.status));
   1296   }
   1297 
   1298   return convertErr(result);
   1299 }
   1300 
   1301 /* set the SUPL version */
   1302 enum loc_api_adapter_err LocApiV02 :: setSUPLVersion(uint32_t version)
   1303 {
   1304   locClientStatusEnumType result = eLOC_CLIENT_SUCCESS;
   1305   locClientReqUnionType req_union;
   1306 
   1307   qmiLocSetProtocolConfigParametersReqMsgT_v02 supl_config_req;
   1308   qmiLocSetProtocolConfigParametersIndMsgT_v02 supl_config_ind;
   1309 
   1310   LOC_LOGD("%s:%d]: supl version = %d\n",  __func__, __LINE__, version);
   1311 
   1312 
   1313   memset(&supl_config_req, 0, sizeof(supl_config_req));
   1314   memset(&supl_config_ind, 0, sizeof(supl_config_ind));
   1315 
   1316    supl_config_req.suplVersion_valid = 1;
   1317    // SUPL version from MSByte to LSByte:
   1318    // (reserved)(major version)(minor version)(serviceIndicator)
   1319 
   1320    supl_config_req.suplVersion = (version == 0x00020000)?
   1321      eQMI_LOC_SUPL_VERSION_2_0_V02 : eQMI_LOC_SUPL_VERSION_1_0_V02;
   1322 
   1323   req_union.pSetProtocolConfigParametersReq = &supl_config_req;
   1324 
   1325   result = loc_sync_send_req(clientHandle,
   1326                              QMI_LOC_SET_PROTOCOL_CONFIG_PARAMETERS_REQ_V02,
   1327                              req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
   1328                              QMI_LOC_SET_PROTOCOL_CONFIG_PARAMETERS_IND_V02,
   1329                              &supl_config_ind);
   1330 
   1331   if(result != eLOC_CLIENT_SUCCESS ||
   1332      eQMI_LOC_SUCCESS_V02 != supl_config_ind.status)
   1333   {
   1334     LOC_LOGE ("%s:%d]: Error status = %s, ind..status = %s ",
   1335               __func__, __LINE__,
   1336               loc_get_v02_client_status_name(result),
   1337               loc_get_v02_qmi_status_name(supl_config_ind.status));
   1338   }
   1339 
   1340   return convertErr(result);
   1341 }
   1342 
   1343 /* set the configuration for LTE positioning profile (LPP) */
   1344 enum loc_api_adapter_err LocApiV02 :: setLPPConfig(uint32_t profile)
   1345 {
   1346   locClientStatusEnumType result = eLOC_CLIENT_SUCCESS;
   1347   locClientReqUnionType req_union;
   1348   qmiLocSetProtocolConfigParametersReqMsgT_v02 lpp_config_req;
   1349   qmiLocSetProtocolConfigParametersIndMsgT_v02 lpp_config_ind;
   1350 
   1351   LOC_LOGD("%s:%d]: lpp profile = %d\n",  __func__, __LINE__, profile);
   1352 
   1353   memset(&lpp_config_req, 0, sizeof(lpp_config_req));
   1354   memset(&lpp_config_ind, 0, sizeof(lpp_config_ind));
   1355 
   1356   lpp_config_req.lppConfig_valid = 1;
   1357 
   1358   lpp_config_req.lppConfig = profile;
   1359 
   1360   req_union.pSetProtocolConfigParametersReq = &lpp_config_req;
   1361 
   1362   result = loc_sync_send_req(clientHandle,
   1363                              QMI_LOC_SET_PROTOCOL_CONFIG_PARAMETERS_REQ_V02,
   1364                              req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
   1365                              QMI_LOC_SET_PROTOCOL_CONFIG_PARAMETERS_IND_V02,
   1366                              &lpp_config_ind);
   1367 
   1368   if(result != eLOC_CLIENT_SUCCESS ||
   1369      eQMI_LOC_SUCCESS_V02 != lpp_config_ind.status)
   1370   {
   1371     LOC_LOGE ("%s:%d]: Error status = %s, ind..status = %s ",
   1372               __func__, __LINE__,
   1373               loc_get_v02_client_status_name(result),
   1374               loc_get_v02_qmi_status_name(lpp_config_ind.status));
   1375   }
   1376 
   1377   return convertErr(result);
   1378 }
   1379 
   1380 /* set the Sensor Configuration */
   1381 enum loc_api_adapter_err LocApiV02 :: setSensorControlConfig(
   1382     int sensorsDisabled, int sensorProvider)
   1383 {
   1384   locClientStatusEnumType result = eLOC_CLIENT_SUCCESS;
   1385   locClientReqUnionType req_union;
   1386 
   1387   qmiLocSetSensorControlConfigReqMsgT_v02 sensor_config_req;
   1388   qmiLocSetSensorControlConfigIndMsgT_v02 sensor_config_ind;
   1389 
   1390   LOC_LOGD("%s:%d]: sensors disabled = %d\n",  __func__, __LINE__, sensorsDisabled);
   1391 
   1392   memset(&sensor_config_req, 0, sizeof(sensor_config_req));
   1393   memset(&sensor_config_ind, 0, sizeof(sensor_config_ind));
   1394 
   1395   sensor_config_req.sensorsUsage_valid = 1;
   1396   sensor_config_req.sensorsUsage = (sensorsDisabled == 1) ? eQMI_LOC_SENSOR_CONFIG_SENSOR_USE_DISABLE_V02
   1397                                     : eQMI_LOC_SENSOR_CONFIG_SENSOR_USE_ENABLE_V02;
   1398 
   1399   sensor_config_req.sensorProvider_valid = 1;
   1400   sensor_config_req.sensorProvider = (sensorProvider == 1 || sensorProvider == 4) ?
   1401       eQMI_LOC_SENSOR_CONFIG_USE_PROVIDER_SSC_V02 :
   1402       eQMI_LOC_SENSOR_CONFIG_USE_PROVIDER_NATIVE_V02;
   1403 
   1404   req_union.pSetSensorControlConfigReq = &sensor_config_req;
   1405 
   1406   result = loc_sync_send_req(clientHandle,
   1407                              QMI_LOC_SET_SENSOR_CONTROL_CONFIG_REQ_V02,
   1408                              req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
   1409                              QMI_LOC_SET_SENSOR_CONTROL_CONFIG_IND_V02,
   1410                              &sensor_config_ind);
   1411 
   1412   if(result != eLOC_CLIENT_SUCCESS ||
   1413      eQMI_LOC_SUCCESS_V02 != sensor_config_ind.status)
   1414   {
   1415     LOC_LOGE ("%s:%d]: Error status = %s, ind..status = %s ",
   1416               __func__, __LINE__,
   1417               loc_get_v02_client_status_name(result),
   1418               loc_get_v02_qmi_status_name(sensor_config_ind.status));
   1419   }
   1420 
   1421   return convertErr(result);
   1422 }
   1423 
   1424 /* set the Sensor Properties */
   1425 enum loc_api_adapter_err LocApiV02 :: setSensorProperties(bool gyroBiasVarianceRandomWalk_valid, float gyroBiasVarianceRandomWalk,
   1426                             bool accelBiasVarianceRandomWalk_valid, float accelBiasVarianceRandomWalk,
   1427                             bool angleBiasVarianceRandomWalk_valid, float angleBiasVarianceRandomWalk,
   1428                             bool rateBiasVarianceRandomWalk_valid, float rateBiasVarianceRandomWalk,
   1429                             bool velocityBiasVarianceRandomWalk_valid, float velocityBiasVarianceRandomWalk)
   1430 {
   1431   locClientStatusEnumType result = eLOC_CLIENT_SUCCESS;
   1432   locClientReqUnionType req_union;
   1433 
   1434   qmiLocSetSensorPropertiesReqMsgT_v02 sensor_prop_req;
   1435   qmiLocSetSensorPropertiesIndMsgT_v02 sensor_prop_ind;
   1436 
   1437   LOC_LOGI("%s:%d]: sensors prop: gyroBiasRandomWalk = %f, accelRandomWalk = %f, "
   1438            "angleRandomWalk = %f, rateRandomWalk = %f, velocityRandomWalk = %f\n",
   1439                  __func__, __LINE__, gyroBiasVarianceRandomWalk, accelBiasVarianceRandomWalk,
   1440            angleBiasVarianceRandomWalk, rateBiasVarianceRandomWalk, velocityBiasVarianceRandomWalk);
   1441 
   1442   memset(&sensor_prop_req, 0, sizeof(sensor_prop_req));
   1443   memset(&sensor_prop_ind, 0, sizeof(sensor_prop_ind));
   1444 
   1445   /* Set the validity bit and value for each sensor property */
   1446   sensor_prop_req.gyroBiasVarianceRandomWalk_valid = gyroBiasVarianceRandomWalk_valid;
   1447   sensor_prop_req.gyroBiasVarianceRandomWalk = gyroBiasVarianceRandomWalk;
   1448 
   1449   sensor_prop_req.accelerationRandomWalkSpectralDensity_valid = accelBiasVarianceRandomWalk_valid;
   1450   sensor_prop_req.accelerationRandomWalkSpectralDensity = accelBiasVarianceRandomWalk;
   1451 
   1452   sensor_prop_req.angleRandomWalkSpectralDensity_valid = angleBiasVarianceRandomWalk_valid;
   1453   sensor_prop_req.angleRandomWalkSpectralDensity = angleBiasVarianceRandomWalk;
   1454 
   1455   sensor_prop_req.rateRandomWalkSpectralDensity_valid = rateBiasVarianceRandomWalk_valid;
   1456   sensor_prop_req.rateRandomWalkSpectralDensity = rateBiasVarianceRandomWalk;
   1457 
   1458   sensor_prop_req.velocityRandomWalkSpectralDensity_valid = velocityBiasVarianceRandomWalk_valid;
   1459   sensor_prop_req.velocityRandomWalkSpectralDensity = velocityBiasVarianceRandomWalk;
   1460 
   1461   req_union.pSetSensorPropertiesReq = &sensor_prop_req;
   1462 
   1463   result = loc_sync_send_req(clientHandle,
   1464                              QMI_LOC_SET_SENSOR_PROPERTIES_REQ_V02,
   1465                              req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
   1466                              QMI_LOC_SET_SENSOR_PROPERTIES_IND_V02,
   1467                              &sensor_prop_ind);
   1468 
   1469   if(result != eLOC_CLIENT_SUCCESS ||
   1470      eQMI_LOC_SUCCESS_V02 != sensor_prop_ind.status)
   1471   {
   1472     LOC_LOGE ("%s:%d]: Error status = %s, ind..status = %s ",
   1473               __func__, __LINE__,
   1474               loc_get_v02_client_status_name(result),
   1475               loc_get_v02_qmi_status_name(sensor_prop_ind.status));
   1476   }
   1477 
   1478   return convertErr(result);
   1479 }
   1480 
   1481 /* set the Sensor Performance Config */
   1482 enum loc_api_adapter_err LocApiV02 :: setSensorPerfControlConfig(int controlMode,
   1483                                                                         int accelSamplesPerBatch, int accelBatchesPerSec,
   1484                                                                         int gyroSamplesPerBatch, int gyroBatchesPerSec,
   1485                                                                         int accelSamplesPerBatchHigh, int accelBatchesPerSecHigh,
   1486                                                                         int gyroSamplesPerBatchHigh, int gyroBatchesPerSecHigh,
   1487                                                                         int algorithmConfig)
   1488 {
   1489   locClientStatusEnumType result = eLOC_CLIENT_SUCCESS;
   1490   locClientReqUnionType req_union;
   1491 
   1492   qmiLocSetSensorPerformanceControlConfigReqMsgT_v02 sensor_perf_config_req;
   1493   qmiLocSetSensorPerformanceControlConfigIndMsgT_v02 sensor_perf_config_ind;
   1494 
   1495   LOC_LOGD("%s:%d]: Sensor Perf Control Config (performanceControlMode)(%u) "
   1496                 "accel(#smp,#batches) (%u,%u) gyro(#smp,#batches) (%u,%u) "
   1497                 "accel_high(#smp,#batches) (%u,%u) gyro_high(#smp,#batches) (%u,%u) "
   1498                 "algorithmConfig(%u)\n",
   1499                 __FUNCTION__,
   1500                 __LINE__,
   1501                 controlMode,
   1502                 accelSamplesPerBatch,
   1503                 accelBatchesPerSec,
   1504                 gyroSamplesPerBatch,
   1505                 gyroBatchesPerSec,
   1506                 accelSamplesPerBatchHigh,
   1507                 accelBatchesPerSecHigh,
   1508                 gyroSamplesPerBatchHigh,
   1509                 gyroBatchesPerSecHigh,
   1510                 algorithmConfig
   1511                 );
   1512 
   1513   memset(&sensor_perf_config_req, 0, sizeof(sensor_perf_config_req));
   1514   memset(&sensor_perf_config_ind, 0, sizeof(sensor_perf_config_ind));
   1515 
   1516   sensor_perf_config_req.performanceControlMode_valid = 1;
   1517   sensor_perf_config_req.performanceControlMode = (qmiLocSensorPerformanceControlModeEnumT_v02)controlMode;
   1518   sensor_perf_config_req.accelSamplingSpec_valid = 1;
   1519   sensor_perf_config_req.accelSamplingSpec.batchesPerSecond = accelBatchesPerSec;
   1520   sensor_perf_config_req.accelSamplingSpec.samplesPerBatch = accelSamplesPerBatch;
   1521   sensor_perf_config_req.gyroSamplingSpec_valid = 1;
   1522   sensor_perf_config_req.gyroSamplingSpec.batchesPerSecond = gyroBatchesPerSec;
   1523   sensor_perf_config_req.gyroSamplingSpec.samplesPerBatch = gyroSamplesPerBatch;
   1524   sensor_perf_config_req.accelSamplingSpecHigh_valid = 1;
   1525   sensor_perf_config_req.accelSamplingSpecHigh.batchesPerSecond = accelBatchesPerSecHigh;
   1526   sensor_perf_config_req.accelSamplingSpecHigh.samplesPerBatch = accelSamplesPerBatchHigh;
   1527   sensor_perf_config_req.gyroSamplingSpecHigh_valid = 1;
   1528   sensor_perf_config_req.gyroSamplingSpecHigh.batchesPerSecond = gyroBatchesPerSecHigh;
   1529   sensor_perf_config_req.gyroSamplingSpecHigh.samplesPerBatch = gyroSamplesPerBatchHigh;
   1530   sensor_perf_config_req.algorithmConfig_valid = 1;
   1531   sensor_perf_config_req.algorithmConfig = algorithmConfig;
   1532 
   1533   req_union.pSetSensorPerformanceControlConfigReq = &sensor_perf_config_req;
   1534 
   1535   result = loc_sync_send_req(clientHandle,
   1536                              QMI_LOC_SET_SENSOR_PERFORMANCE_CONTROL_CONFIGURATION_REQ_V02,
   1537                              req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
   1538                              QMI_LOC_SET_SENSOR_PERFORMANCE_CONTROL_CONFIGURATION_IND_V02,
   1539                              &sensor_perf_config_ind);
   1540 
   1541   if(result != eLOC_CLIENT_SUCCESS ||
   1542      eQMI_LOC_SUCCESS_V02 != sensor_perf_config_ind.status)
   1543   {
   1544     LOC_LOGE ("%s:%d]: Error status = %s, ind..status = %s ",
   1545               __func__, __LINE__,
   1546               loc_get_v02_client_status_name(result),
   1547               loc_get_v02_qmi_status_name(sensor_perf_config_ind.status));
   1548   }
   1549 
   1550   return convertErr(result);
   1551 }
   1552 
   1553 /* set the External Power Config */
   1554 enum loc_api_adapter_err LocApiV02 :: setExtPowerConfig(int isBatteryCharging)
   1555 {
   1556   locClientStatusEnumType result = eLOC_CLIENT_SUCCESS;
   1557   locClientReqUnionType req_union;
   1558 
   1559   qmiLocSetExternalPowerConfigReqMsgT_v02 ext_pwr_req;
   1560   qmiLocGetExternalPowerConfigIndMsgT_v02 ext_pwr_ind;
   1561 
   1562   LOC_LOGI("%s:%d]: Ext Pwr Config (isBatteryCharging)(%u)",
   1563                 __FUNCTION__,
   1564                 __LINE__,
   1565                 isBatteryCharging
   1566                 );
   1567 
   1568   memset(&ext_pwr_req, 0, sizeof(ext_pwr_req));
   1569   memset(&ext_pwr_ind, 0, sizeof(ext_pwr_ind));
   1570 
   1571   switch(isBatteryCharging)
   1572   {
   1573     /* Charging */
   1574     case 1:
   1575       ext_pwr_req.externalPowerState = eQMI_LOC_EXTERNAL_POWER_CONNECTED_V02;
   1576       break;
   1577 
   1578     /* Not charging */
   1579     case 0:
   1580       ext_pwr_req.externalPowerState = eQMI_LOC_EXTERNAL_POWER_NOT_CONNECTED_V02;
   1581       break;
   1582 
   1583     default:
   1584       LOC_LOGE("%s:%d]: Invalid ext power state = %d!",
   1585                     __FUNCTION__,
   1586                     __LINE__,
   1587                     isBatteryCharging);
   1588       return LOC_API_ADAPTER_ERR_INVALID_PARAMETER;
   1589       break;
   1590   }
   1591 
   1592   req_union.pSetExternalPowerConfigReq = &ext_pwr_req;
   1593 
   1594   result = loc_sync_send_req(clientHandle,
   1595                              QMI_LOC_SET_EXTERNAL_POWER_CONFIG_REQ_V02,
   1596                              req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
   1597                              QMI_LOC_SET_EXTERNAL_POWER_CONFIG_IND_V02,
   1598                              &ext_pwr_ind);
   1599 
   1600   if(result != eLOC_CLIENT_SUCCESS ||
   1601      eQMI_LOC_SUCCESS_V02 != ext_pwr_ind.status)
   1602   {
   1603     LOC_LOGE ("%s:%d]: Error status = %d, ind..status = %d ",
   1604                     __func__, __LINE__, result, ext_pwr_ind.status);
   1605   }
   1606 
   1607   return convertErr(result);
   1608 }
   1609 
   1610 /* set the Positioning Protocol on A-GLONASS system */
   1611 enum loc_api_adapter_err LocApiV02 :: setAGLONASSProtocol(unsigned long aGlonassProtocol)
   1612 {
   1613   locClientStatusEnumType result = eLOC_CLIENT_SUCCESS;
   1614   locClientReqUnionType req_union;
   1615   qmiLocSetProtocolConfigParametersReqMsgT_v02 aGlonassProtocol_req;
   1616   qmiLocSetProtocolConfigParametersIndMsgT_v02 aGlonassProtocol_ind;
   1617 
   1618   memset(&aGlonassProtocol_req, 0, sizeof(aGlonassProtocol_req));
   1619   memset(&aGlonassProtocol_ind, 0, sizeof(aGlonassProtocol_ind));
   1620 
   1621   aGlonassProtocol_req.assistedGlonassProtocolMask_valid = 1;
   1622   aGlonassProtocol_req.assistedGlonassProtocolMask = aGlonassProtocol;
   1623 
   1624   req_union.pSetProtocolConfigParametersReq = &aGlonassProtocol_req;
   1625 
   1626   LOC_LOGD("%s:%d]: aGlonassProtocolMask = 0x%x\n",  __func__, __LINE__,
   1627                              aGlonassProtocol_req.assistedGlonassProtocolMask);
   1628 
   1629   result = loc_sync_send_req(clientHandle,
   1630                              QMI_LOC_SET_PROTOCOL_CONFIG_PARAMETERS_REQ_V02,
   1631                              req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
   1632                              QMI_LOC_SET_PROTOCOL_CONFIG_PARAMETERS_IND_V02,
   1633                              &aGlonassProtocol_ind);
   1634 
   1635   if(result != eLOC_CLIENT_SUCCESS ||
   1636      eQMI_LOC_SUCCESS_V02 != aGlonassProtocol_ind.status)
   1637   {
   1638     LOC_LOGE ("%s:%d]: Error status = %s, ind..status = %s ",
   1639               __func__, __LINE__,
   1640               loc_get_v02_client_status_name(result),
   1641               loc_get_v02_qmi_status_name(aGlonassProtocol_ind.status));
   1642   }
   1643 
   1644   return convertErr(result);
   1645 }
   1646 
   1647 /* Convert event mask from loc eng to loc_api_v02 format */
   1648 locClientEventMaskType LocApiV02 :: convertMask(
   1649   LOC_API_ADAPTER_EVENT_MASK_T mask)
   1650 {
   1651   locClientEventMaskType eventMask = 0;
   1652   LOC_LOGD("%s:%d]: adapter mask = %u\n", __func__, __LINE__, mask);
   1653 
   1654   if (mask & LOC_API_ADAPTER_BIT_PARSED_POSITION_REPORT)
   1655       eventMask |= QMI_LOC_EVENT_MASK_POSITION_REPORT_V02;
   1656 
   1657   if (mask & LOC_API_ADAPTER_BIT_SATELLITE_REPORT)
   1658       eventMask |= QMI_LOC_EVENT_MASK_GNSS_SV_INFO_V02;
   1659 
   1660   /* treat NMEA_1Hz and NMEA_POSITION_REPORT the same*/
   1661   if ((mask & LOC_API_ADAPTER_BIT_NMEA_POSITION_REPORT) ||
   1662       (mask & LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT) )
   1663       eventMask |= QMI_LOC_EVENT_MASK_NMEA_V02;
   1664 
   1665   if (mask & LOC_API_ADAPTER_BIT_NI_NOTIFY_VERIFY_REQUEST)
   1666       eventMask |= QMI_LOC_EVENT_MASK_NI_NOTIFY_VERIFY_REQ_V02;
   1667 
   1668   if (mask & LOC_API_ADAPTER_BIT_ASSISTANCE_DATA_REQUEST)
   1669   {
   1670     // TBD: This needs to be decoupled in the HAL
   1671     eventMask |= QMI_LOC_EVENT_MASK_INJECT_PREDICTED_ORBITS_REQ_V02;
   1672     eventMask |= QMI_LOC_EVENT_MASK_INJECT_TIME_REQ_V02;
   1673     eventMask |= QMI_LOC_EVENT_MASK_INJECT_POSITION_REQ_V02;
   1674   }
   1675 
   1676   if (mask & LOC_API_ADAPTER_BIT_STATUS_REPORT)
   1677   {
   1678       eventMask |= (QMI_LOC_EVENT_MASK_ENGINE_STATE_V02);
   1679   }
   1680 
   1681   if (mask & LOC_API_ADAPTER_BIT_LOCATION_SERVER_REQUEST)
   1682       eventMask |= QMI_LOC_EVENT_MASK_LOCATION_SERVER_CONNECTION_REQ_V02;
   1683 
   1684   if (mask & LOC_API_ADAPTER_BIT_REQUEST_WIFI)
   1685       eventMask |= QMI_LOC_EVENT_MASK_WIFI_REQ_V02;
   1686 
   1687   if (mask & LOC_API_ADAPTER_BIT_SENSOR_STATUS)
   1688       eventMask |= QMI_LOC_EVENT_MASK_SENSOR_STREAMING_READY_STATUS_V02;
   1689 
   1690   if (mask & LOC_API_ADAPTER_BIT_REQUEST_TIME_SYNC)
   1691       eventMask |= QMI_LOC_EVENT_MASK_TIME_SYNC_REQ_V02;
   1692 
   1693   if (mask & LOC_API_ADAPTER_BIT_REPORT_SPI)
   1694       eventMask |= QMI_LOC_EVENT_MASK_SET_SPI_STREAMING_REPORT_V02;
   1695 
   1696   if (mask & LOC_API_ADAPTER_BIT_REPORT_NI_GEOFENCE)
   1697       eventMask |= QMI_LOC_EVENT_MASK_NI_GEOFENCE_NOTIFICATION_V02;
   1698 
   1699   if (mask & LOC_API_ADAPTER_BIT_GEOFENCE_GEN_ALERT)
   1700       eventMask |= QMI_LOC_EVENT_MASK_GEOFENCE_GEN_ALERT_V02;
   1701 
   1702   if (mask & LOC_API_ADAPTER_BIT_REPORT_GENFENCE_BREACH)
   1703       eventMask |= QMI_LOC_EVENT_MASK_GEOFENCE_BREACH_NOTIFICATION_V02;
   1704 
   1705   if (mask & LOC_API_ADAPTER_BIT_BATCHED_GENFENCE_BREACH_REPORT)
   1706       eventMask |= QMI_LOC_EVENT_MASK_GEOFENCE_BATCH_BREACH_NOTIFICATION_V02;
   1707 
   1708   if (mask & LOC_API_ADAPTER_BIT_REPORT_GENFENCE_DWELL)
   1709       eventMask |= QMI_LOC_EVENT_MASK_GEOFENCE_BATCH_DWELL_NOTIFICATION_V02;
   1710 
   1711   if (mask & LOC_API_ADAPTER_BIT_PEDOMETER_CTRL)
   1712       eventMask |= QMI_LOC_EVENT_MASK_PEDOMETER_CONTROL_V02;
   1713 
   1714   if (mask & LOC_API_ADAPTER_BIT_MOTION_CTRL)
   1715       eventMask |= QMI_LOC_EVENT_MASK_MOTION_DATA_CONTROL_V02;
   1716 
   1717   if (mask & LOC_API_ADAPTER_BIT_REQUEST_WIFI_AP_DATA)
   1718       eventMask |= QMI_LOC_EVENT_MASK_INJECT_WIFI_AP_DATA_REQ_V02;
   1719 
   1720   if(mask & LOC_API_ADAPTER_BIT_BATCH_FULL)
   1721       eventMask |= QMI_LOC_EVENT_MASK_BATCH_FULL_NOTIFICATION_V02;
   1722 
   1723   if(mask & LOC_API_ADAPTER_BIT_BATCHED_POSITION_REPORT)
   1724       eventMask |= QMI_LOC_EVENT_MASK_LIVE_BATCHED_POSITION_REPORT_V02;
   1725 
   1726   // for GDT
   1727   if(mask & LOC_API_ADAPTER_BIT_GDT_UPLOAD_BEGIN_REQ)
   1728       eventMask |= QMI_LOC_EVENT_MASK_GDT_UPLOAD_BEGIN_REQ_V02;
   1729 
   1730   if(mask & LOC_API_ADAPTER_BIT_GDT_UPLOAD_END_REQ)
   1731       eventMask |= QMI_LOC_EVENT_MASK_GDT_UPLOAD_END_REQ_V02;
   1732 
   1733   if (mask & LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT)
   1734       eventMask |= QMI_LOC_EVENT_MASK_GNSS_MEASUREMENT_REPORT_V02;
   1735 
   1736   if(mask & LOC_API_ADAPTER_BIT_REQUEST_TIMEZONE)
   1737       eventMask |= QMI_LOC_EVENT_MASK_GET_TIME_ZONE_REQ_V02;
   1738   return eventMask;
   1739 }
   1740 
   1741 qmiLocLockEnumT_v02 LocApiV02 :: convertGpsLockMask(LOC_GPS_LOCK_MASK lockMask)
   1742 {
   1743     /* GPS HAL uses power voting through GPS Lock mask.
   1744        When QCA1530 daemon is present two values are used: 101 and 103.*/
   1745     if ( 101 == lockMask || 103 == lockMask )
   1746     {
   1747         return (qmiLocLockEnumT_v02)lockMask;
   1748     }
   1749     if (isGpsLockAll(lockMask))
   1750         return eQMI_LOC_LOCK_ALL_V02;
   1751     if (isGpsLockMO(lockMask))
   1752         return eQMI_LOC_LOCK_MI_V02;
   1753     if (isGpsLockMT(lockMask))
   1754         return eQMI_LOC_LOCK_MT_V02;
   1755     if (isGpsLockNone(lockMask))
   1756         return eQMI_LOC_LOCK_NONE_V02;
   1757     return (qmiLocLockEnumT_v02)lockMask;
   1758 }
   1759 
   1760 /* Convert error from loc_api_v02 to loc eng format*/
   1761 enum loc_api_adapter_err LocApiV02 :: convertErr(
   1762   locClientStatusEnumType status)
   1763 {
   1764   switch( status)
   1765   {
   1766     case eLOC_CLIENT_SUCCESS:
   1767       return LOC_API_ADAPTER_ERR_SUCCESS;
   1768 
   1769     case eLOC_CLIENT_FAILURE_GENERAL:
   1770       return LOC_API_ADAPTER_ERR_GENERAL_FAILURE;
   1771 
   1772     case eLOC_CLIENT_FAILURE_UNSUPPORTED:
   1773       return LOC_API_ADAPTER_ERR_UNSUPPORTED;
   1774 
   1775     case eLOC_CLIENT_FAILURE_INVALID_PARAMETER:
   1776       return LOC_API_ADAPTER_ERR_INVALID_PARAMETER;
   1777 
   1778     case eLOC_CLIENT_FAILURE_ENGINE_BUSY:
   1779       return LOC_API_ADAPTER_ERR_ENGINE_BUSY;
   1780 
   1781     case eLOC_CLIENT_FAILURE_PHONE_OFFLINE:
   1782       return LOC_API_ADAPTER_ERR_PHONE_OFFLINE;
   1783 
   1784     case eLOC_CLIENT_FAILURE_TIMEOUT:
   1785       return LOC_API_ADAPTER_ERR_TIMEOUT;
   1786 
   1787     case eLOC_CLIENT_FAILURE_INVALID_HANDLE:
   1788       return LOC_API_ADAPTER_ERR_INVALID_HANDLE;
   1789 
   1790     case eLOC_CLIENT_FAILURE_SERVICE_NOT_PRESENT:
   1791       return LOC_API_ADAPTER_ERR_SERVICE_NOT_PRESENT;
   1792 
   1793     case eLOC_CLIENT_FAILURE_INTERNAL:
   1794       return LOC_API_ADAPTER_ERR_INTERNAL;
   1795 
   1796     default:
   1797       return LOC_API_ADAPTER_ERR_FAILURE;
   1798   }
   1799 }
   1800 
   1801 /* convert position report to loc eng format and send the converted
   1802    position to loc eng */
   1803 
   1804 void LocApiV02 :: reportPosition (
   1805   const qmiLocEventPositionReportIndMsgT_v02 *location_report_ptr)
   1806 {
   1807     UlpLocation location;
   1808     LocPosTechMask tech_Mask = LOC_POS_TECH_MASK_DEFAULT;
   1809     LOC_LOGD("Reporting position from V2 Adapter\n");
   1810     memset(&location, 0, sizeof (UlpLocation));
   1811     location.size = sizeof(location);
   1812     GpsLocationExtended locationExtended;
   1813     memset(&locationExtended, 0, sizeof (GpsLocationExtended));
   1814     locationExtended.size = sizeof(locationExtended);
   1815     // Process the position from final and intermediate reports
   1816 
   1817     if( (location_report_ptr->sessionStatus == eQMI_LOC_SESS_STATUS_SUCCESS_V02) ||
   1818         (location_report_ptr->sessionStatus == eQMI_LOC_SESS_STATUS_IN_PROGRESS_V02)
   1819         )
   1820     {
   1821         // Latitude & Longitude
   1822         if( (1 == location_report_ptr->latitude_valid) &&
   1823             (1 == location_report_ptr->longitude_valid))
   1824         {
   1825             location.gpsLocation.flags  |= GPS_LOCATION_HAS_LAT_LONG;
   1826             location.gpsLocation.latitude  = location_report_ptr->latitude;
   1827             location.gpsLocation.longitude = location_report_ptr->longitude;
   1828 
   1829             // Time stamp (UTC)
   1830             if(location_report_ptr->timestampUtc_valid == 1)
   1831             {
   1832                 location.gpsLocation.timestamp = location_report_ptr->timestampUtc;
   1833             }
   1834 
   1835             // Altitude
   1836             if(location_report_ptr->altitudeWrtEllipsoid_valid == 1  )
   1837             {
   1838                 location.gpsLocation.flags  |= GPS_LOCATION_HAS_ALTITUDE;
   1839                 location.gpsLocation.altitude = location_report_ptr->altitudeWrtEllipsoid;
   1840             }
   1841 
   1842             // Speed
   1843             if(location_report_ptr->speedHorizontal_valid == 1)
   1844             {
   1845                 location.gpsLocation.flags  |= GPS_LOCATION_HAS_SPEED;
   1846                 location.gpsLocation.speed = location_report_ptr->speedHorizontal;
   1847             }
   1848 
   1849             // Heading
   1850             if(location_report_ptr->heading_valid == 1)
   1851             {
   1852                 location.gpsLocation.flags  |= GPS_LOCATION_HAS_BEARING;
   1853                 location.gpsLocation.bearing = location_report_ptr->heading;
   1854             }
   1855 
   1856             // Uncertainty (circular)
   1857             if (location_report_ptr->horUncCircular_valid) {
   1858                 location.gpsLocation.flags |= GPS_LOCATION_HAS_ACCURACY;
   1859                 location.gpsLocation.accuracy = location_report_ptr->horUncCircular;
   1860             } else if (location_report_ptr->horUncEllipseSemiMinor_valid &&
   1861                        location_report_ptr->horUncEllipseSemiMajor_valid) {
   1862                 location.gpsLocation.flags |= GPS_LOCATION_HAS_ACCURACY;
   1863                 location.gpsLocation.accuracy =
   1864                     sqrt((location_report_ptr->horUncEllipseSemiMinor *
   1865                           location_report_ptr->horUncEllipseSemiMinor) +
   1866                          (location_report_ptr->horUncEllipseSemiMajor *
   1867                           location_report_ptr->horUncEllipseSemiMajor));
   1868             }
   1869 
   1870             // Technology Mask
   1871             tech_Mask |= location_report_ptr->technologyMask;
   1872 
   1873             //Mark the location source as from GNSS
   1874             location.gpsLocation.flags |= LOCATION_HAS_SOURCE_INFO;
   1875             location.position_source = ULP_LOCATION_IS_FROM_GNSS;
   1876             if (location_report_ptr->magneticDeviation_valid)
   1877             {
   1878                 locationExtended.flags |= GPS_LOCATION_EXTENDED_HAS_MAG_DEV;
   1879                 locationExtended.magneticDeviation = location_report_ptr->magneticDeviation;
   1880             }
   1881 
   1882             if (location_report_ptr->DOP_valid)
   1883             {
   1884                 locationExtended.flags |= GPS_LOCATION_EXTENDED_HAS_DOP;
   1885                 locationExtended.pdop = location_report_ptr->DOP.PDOP;
   1886                 locationExtended.hdop = location_report_ptr->DOP.HDOP;
   1887                 locationExtended.vdop = location_report_ptr->DOP.VDOP;
   1888             }
   1889 
   1890             if (location_report_ptr->altitudeWrtMeanSeaLevel_valid)
   1891             {
   1892                 locationExtended.flags |= GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL;
   1893                 locationExtended.altitudeMeanSeaLevel = location_report_ptr->altitudeWrtMeanSeaLevel;
   1894             }
   1895 
   1896             if (location_report_ptr->vertUnc_valid)
   1897             {
   1898                locationExtended.flags |= GPS_LOCATION_EXTENDED_HAS_VERT_UNC;
   1899                locationExtended.vert_unc = location_report_ptr->vertUnc;
   1900             }
   1901 
   1902             if (location_report_ptr->speedUnc_valid)
   1903             {
   1904                locationExtended.flags |= GPS_LOCATION_EXTENDED_HAS_SPEED_UNC;
   1905                locationExtended.speed_unc = location_report_ptr->speedUnc;
   1906             }
   1907             if (location_report_ptr->headingUnc_valid)
   1908             {
   1909                locationExtended.flags |= GPS_LOCATION_EXTENDED_HAS_BEARING_UNC;
   1910                locationExtended.bearing_unc = location_report_ptr->headingUnc;
   1911             }
   1912             if (location_report_ptr->horReliability_valid)
   1913             {
   1914                locationExtended.flags |= GPS_LOCATION_EXTENDED_HAS_HOR_RELIABILITY;
   1915                switch(location_report_ptr->horReliability)
   1916                {
   1917                   case eQMI_LOC_RELIABILITY_NOT_SET_V02 :
   1918                     locationExtended.horizontal_reliability = LOC_RELIABILITY_NOT_SET;
   1919                     break;
   1920                   case eQMI_LOC_RELIABILITY_VERY_LOW_V02 :
   1921                     locationExtended.horizontal_reliability = LOC_RELIABILITY_VERY_LOW;
   1922                     break;
   1923                   case eQMI_LOC_RELIABILITY_LOW_V02 :
   1924                     locationExtended.horizontal_reliability = LOC_RELIABILITY_LOW;
   1925                     break;
   1926                   case eQMI_LOC_RELIABILITY_MEDIUM_V02 :
   1927                     locationExtended.horizontal_reliability = LOC_RELIABILITY_MEDIUM;
   1928                     break;
   1929                   case eQMI_LOC_RELIABILITY_HIGH_V02 :
   1930                     locationExtended.horizontal_reliability = LOC_RELIABILITY_HIGH;
   1931                     break;
   1932                   default:
   1933                     locationExtended.horizontal_reliability = LOC_RELIABILITY_NOT_SET;
   1934                     break;
   1935                }
   1936             }
   1937             if (location_report_ptr->vertReliability_valid)
   1938             {
   1939                locationExtended.flags |= GPS_LOCATION_EXTENDED_HAS_VERT_RELIABILITY;
   1940                switch(location_report_ptr->vertReliability)
   1941                {
   1942                   case eQMI_LOC_RELIABILITY_NOT_SET_V02 :
   1943                     locationExtended.vertical_reliability = LOC_RELIABILITY_NOT_SET;
   1944                     break;
   1945                   case eQMI_LOC_RELIABILITY_VERY_LOW_V02 :
   1946                     locationExtended.vertical_reliability = LOC_RELIABILITY_VERY_LOW;
   1947                     break;
   1948                   case eQMI_LOC_RELIABILITY_LOW_V02 :
   1949                     locationExtended.vertical_reliability = LOC_RELIABILITY_LOW;
   1950                     break;
   1951                   case eQMI_LOC_RELIABILITY_MEDIUM_V02 :
   1952                     locationExtended.vertical_reliability = LOC_RELIABILITY_MEDIUM;
   1953                     break;
   1954                   case eQMI_LOC_RELIABILITY_HIGH_V02 :
   1955                     locationExtended.vertical_reliability = LOC_RELIABILITY_HIGH;
   1956                     break;
   1957                   default:
   1958                     locationExtended.vertical_reliability = LOC_RELIABILITY_NOT_SET;
   1959                     break;
   1960                }
   1961             }
   1962 
   1963             if((0 == location_report_ptr->latitude) &&
   1964                (0 == location_report_ptr->latitude) &&
   1965                (1 == location_report_ptr->horReliability_valid) &&
   1966                (eQMI_LOC_RELIABILITY_NOT_SET_V02 ==
   1967                    location_report_ptr->horReliability))
   1968             {
   1969                 /*Only BlankNMEA sentence needs to be processed and sent, position
   1970                  * shall not be sent to framework if both lat,long is 0 & horReliability
   1971                  * not set, hence we report session failure status */
   1972                 LocApiBase::reportPosition( location,
   1973                                 locationExtended,
   1974                                 (void*)location_report_ptr,
   1975                                 LOC_SESS_FAILURE,
   1976                                 tech_Mask);
   1977             }
   1978             else
   1979             {
   1980             LocApiBase::reportPosition( location,
   1981                             locationExtended,
   1982                             (void*)location_report_ptr,
   1983                             (location_report_ptr->sessionStatus
   1984                              == eQMI_LOC_SESS_STATUS_IN_PROGRESS_V02 ?
   1985                              LOC_SESS_INTERMEDIATE : LOC_SESS_SUCCESS),
   1986                             tech_Mask);
   1987         }
   1988     }
   1989     }
   1990     else
   1991     {
   1992         LocApiBase::reportPosition(location,
   1993                                    locationExtended,
   1994                                    NULL,
   1995                                    LOC_SESS_FAILURE);
   1996 
   1997         LOC_LOGD("%s:%d]: Ignoring position report with sess status = %d, "
   1998                       "fix id = %u\n", __func__, __LINE__,
   1999                       location_report_ptr->sessionStatus,
   2000                       location_report_ptr->fixId );
   2001     }
   2002 }
   2003 
   2004 /* convert satellite report to loc eng format and  send the converted
   2005    report to loc eng */
   2006 void  LocApiV02 :: reportSv (
   2007   const qmiLocEventGnssSvInfoIndMsgT_v02 *gnss_report_ptr)
   2008 {
   2009   GnssSvStatus      SvStatus;
   2010   GpsLocationExtended locationExtended;
   2011   int              num_svs_max, i;
   2012   const qmiLocSvInfoStructT_v02 *sv_info_ptr;
   2013 
   2014   LOC_LOGV ("%s:%d]: num of sv = %d, validity = %d, altitude assumed = %u \n",
   2015             __func__, __LINE__, gnss_report_ptr->svList_len,
   2016             gnss_report_ptr->svList_valid,
   2017             gnss_report_ptr->altitudeAssumed);
   2018 
   2019   num_svs_max = 0;
   2020   memset (&SvStatus, 0, sizeof (GnssSvStatus));
   2021   memset(&locationExtended, 0, sizeof (GpsLocationExtended));
   2022 
   2023   SvStatus.size = sizeof(GnssSvStatus);
   2024   locationExtended.size = sizeof(locationExtended);
   2025   if(gnss_report_ptr->svList_valid == 1)
   2026   {
   2027     num_svs_max = gnss_report_ptr->svList_len;
   2028     if(num_svs_max > GNSS_MAX_SVS)
   2029     {
   2030       num_svs_max = GNSS_MAX_SVS;
   2031     }
   2032     SvStatus.num_svs = 0;
   2033     for(i = 0; i < num_svs_max; i++)
   2034     {
   2035       sv_info_ptr = &(gnss_report_ptr->svList[i]);
   2036       if((sv_info_ptr->validMask & QMI_LOC_SV_INFO_MASK_VALID_SYSTEM_V02) &&
   2037          (sv_info_ptr->validMask & QMI_LOC_SV_INFO_MASK_VALID_GNSS_SVID_V02)
   2038          && (sv_info_ptr->gnssSvId != 0 ))
   2039       {
   2040         GnssSvFlags flags = GNSS_SV_FLAGS_NONE;
   2041 
   2042         SvStatus.gnss_sv_list[SvStatus.num_svs].size = sizeof(GnssSvInfo);
   2043         switch (sv_info_ptr->system)
   2044         {
   2045           case eQMI_LOC_SV_SYSTEM_GPS_V02:
   2046             SvStatus.gnss_sv_list[SvStatus.num_svs].svid = sv_info_ptr->gnssSvId;
   2047             SvStatus.gnss_sv_list[SvStatus.num_svs].constellation = GNSS_CONSTELLATION_GPS;
   2048             break;
   2049 
   2050           case eQMI_LOC_SV_SYSTEM_GALILEO_V02:
   2051             SvStatus.gnss_sv_list[SvStatus.num_svs].svid = sv_info_ptr->gnssSvId-300;
   2052             SvStatus.gnss_sv_list[SvStatus.num_svs].constellation = GNSS_CONSTELLATION_GALILEO;
   2053             break;
   2054 
   2055           case eQMI_LOC_SV_SYSTEM_SBAS_V02:
   2056             SvStatus.gnss_sv_list[SvStatus.num_svs].svid = sv_info_ptr->gnssSvId;
   2057             SvStatus.gnss_sv_list[SvStatus.num_svs].constellation = GNSS_CONSTELLATION_SBAS;
   2058             break;
   2059 
   2060           case eQMI_LOC_SV_SYSTEM_GLONASS_V02:
   2061             SvStatus.gnss_sv_list[SvStatus.num_svs].svid = sv_info_ptr->gnssSvId;
   2062             SvStatus.gnss_sv_list[SvStatus.num_svs].constellation = GNSS_CONSTELLATION_GLONASS;
   2063             break;
   2064 
   2065           case eQMI_LOC_SV_SYSTEM_BDS_V02:
   2066             SvStatus.gnss_sv_list[SvStatus.num_svs].svid = sv_info_ptr->gnssSvId - 200;
   2067             SvStatus.gnss_sv_list[SvStatus.num_svs].constellation = GNSS_CONSTELLATION_BEIDOU;
   2068             break;
   2069 
   2070           case eQMI_LOC_SV_SYSTEM_QZSS_V02:
   2071             SvStatus.gnss_sv_list[SvStatus.num_svs].svid = sv_info_ptr->gnssSvId;
   2072             SvStatus.gnss_sv_list[SvStatus.num_svs].constellation = GNSS_CONSTELLATION_QZSS;
   2073             break;
   2074 
   2075           case eQMI_LOC_SV_SYSTEM_COMPASS_V02:
   2076           default:
   2077             SvStatus.gnss_sv_list[SvStatus.num_svs].svid = sv_info_ptr->gnssSvId;
   2078             SvStatus.gnss_sv_list[SvStatus.num_svs].constellation = GNSS_CONSTELLATION_UNKNOWN;
   2079             break;
   2080         }
   2081 
   2082         if (sv_info_ptr->validMask & QMI_LOC_SV_INFO_MASK_VALID_SNR_V02)
   2083         {
   2084           SvStatus.gnss_sv_list[SvStatus.num_svs].c_n0_dbhz = sv_info_ptr->snr;
   2085         }
   2086 
   2087         if (sv_info_ptr->validMask & QMI_LOC_SV_INFO_MASK_VALID_ELEVATION_V02)
   2088         {
   2089             SvStatus.gnss_sv_list[SvStatus.num_svs].elevation = sv_info_ptr->elevation;
   2090         }
   2091 
   2092         if (sv_info_ptr->validMask & QMI_LOC_SV_INFO_MASK_VALID_AZIMUTH_V02)
   2093         {
   2094           SvStatus.gnss_sv_list[SvStatus.num_svs].azimuth = sv_info_ptr->azimuth;
   2095         }
   2096 
   2097         if (sv_info_ptr->validMask &
   2098              QMI_LOC_SV_INFO_MASK_VALID_SVINFO_MASK_V02)
   2099         {
   2100           if (sv_info_ptr->svInfoMask &
   2101                QMI_LOC_SVINFO_MASK_HAS_EPHEMERIS_V02)
   2102           {
   2103               flags |= GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA;
   2104           }
   2105           if (sv_info_ptr->svInfoMask &
   2106              QMI_LOC_SVINFO_MASK_HAS_ALMANAC_V02)
   2107           {
   2108               flags |= GNSS_SV_FLAGS_HAS_ALMANAC_DATA;
   2109           }
   2110         }
   2111 
   2112         /* Even if modem stops tracking some SVs, it reports them in the measurement
   2113         report with Ephermeris/Alamanac data with 0 SNR. So in addition to check for
   2114         availability of Alm or Eph data, also check for SNR > 0 to indicate SV is
   2115         used in fix. */
   2116         if ((sv_info_ptr->validMask &
   2117              QMI_LOC_SV_INFO_MASK_VALID_PROCESS_STATUS_V02)
   2118              &&
   2119              (sv_info_ptr->svStatus == eQMI_LOC_SV_STATUS_TRACK_V02)
   2120              &&
   2121              (sv_info_ptr->snr > 0)
   2122              &&
   2123              ((flags & GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA)||(flags & GNSS_SV_FLAGS_HAS_ALMANAC_DATA)))
   2124         {
   2125             flags |= GNSS_SV_FLAGS_USED_IN_FIX;
   2126         }
   2127 
   2128         SvStatus.gnss_sv_list[SvStatus.num_svs].flags = flags;
   2129 
   2130         SvStatus.num_svs++;
   2131       }
   2132     }
   2133   }
   2134 
   2135   if (SvStatus.num_svs >= 0)
   2136   {
   2137     LOC_LOGV ("%s:%d]: firing SV callback\n", __func__, __LINE__);
   2138     LocApiBase::reportSv(SvStatus,
   2139                          locationExtended,
   2140                          (void*)gnss_report_ptr);
   2141   }
   2142 }
   2143 
   2144 /* convert engine state report to loc eng format and send the converted
   2145    report to loc eng */
   2146 void LocApiV02 :: reportEngineState (
   2147     const qmiLocEventEngineStateIndMsgT_v02 *engine_state_ptr)
   2148 {
   2149 
   2150   LOC_LOGV("%s:%d]: state = %d\n", __func__, __LINE__,
   2151                  engine_state_ptr->engineState);
   2152 
   2153   struct MsgUpdateEngineState : public LocMsg {
   2154       LocApiV02* mpLocApiV02;
   2155       bool mEngineOn;
   2156       inline MsgUpdateEngineState(LocApiV02* pLocApiV02, bool engineOn) :
   2157                  LocMsg(), mpLocApiV02(pLocApiV02), mEngineOn(engineOn) {}
   2158       inline virtual void proc() const {
   2159           // If EngineOn is true and InSession is false and Engine is just turned off,
   2160           // then unregister the gps tracking specific event masks
   2161           if (mpLocApiV02->mEngineOn && !mpLocApiV02->mInSession && !mEngineOn) {
   2162               mpLocApiV02->registerEventMask(mpLocApiV02->mQmiMask);
   2163           }
   2164           mpLocApiV02->mEngineOn = mEngineOn;
   2165 
   2166           if (mEngineOn) {
   2167               // if EngineOn and not InSession, then we have already stopped
   2168               // the fix, so do not send ENGINE_ON
   2169               if (mpLocApiV02->mInSession) {
   2170                   mpLocApiV02->reportStatus(GPS_STATUS_ENGINE_ON);
   2171                   mpLocApiV02->reportStatus(GPS_STATUS_SESSION_BEGIN);
   2172               }
   2173           } else {
   2174               mpLocApiV02->reportStatus(GPS_STATUS_SESSION_END);
   2175               mpLocApiV02->reportStatus(GPS_STATUS_ENGINE_OFF);
   2176           }
   2177       }
   2178   };
   2179 
   2180   if (engine_state_ptr->engineState == eQMI_LOC_ENGINE_STATE_ON_V02)
   2181   {
   2182     sendMsg(new MsgUpdateEngineState(this, true));
   2183   }
   2184   else if (engine_state_ptr->engineState == eQMI_LOC_ENGINE_STATE_OFF_V02)
   2185   {
   2186     sendMsg(new MsgUpdateEngineState(this, false));
   2187   }
   2188   else
   2189   {
   2190     reportStatus(GPS_STATUS_NONE);
   2191   }
   2192 
   2193 }
   2194 
   2195 /* convert fix session state report to loc eng format and send the converted
   2196    report to loc eng */
   2197 void LocApiV02 :: reportFixSessionState (
   2198     const qmiLocEventFixSessionStateIndMsgT_v02 *fix_session_state_ptr)
   2199 {
   2200   GpsStatusValue status;
   2201   LOC_LOGD("%s:%d]: state = %d\n", __func__, __LINE__,
   2202                 fix_session_state_ptr->sessionState);
   2203 
   2204   status = GPS_STATUS_NONE;
   2205   if (fix_session_state_ptr->sessionState == eQMI_LOC_FIX_SESSION_STARTED_V02)
   2206   {
   2207     status = GPS_STATUS_SESSION_BEGIN;
   2208   }
   2209   else if (fix_session_state_ptr->sessionState
   2210            == eQMI_LOC_FIX_SESSION_FINISHED_V02)
   2211   {
   2212     status = GPS_STATUS_SESSION_END;
   2213   }
   2214   reportStatus(status);
   2215 }
   2216 
   2217 /* convert NMEA report to loc eng format and send the converted
   2218    report to loc eng */
   2219 void LocApiV02 :: reportNmea (
   2220   const qmiLocEventNmeaIndMsgT_v02 *nmea_report_ptr)
   2221 {
   2222 
   2223   LocApiBase::reportNmea(nmea_report_ptr->nmea,
   2224                          strlen(nmea_report_ptr->nmea));
   2225 
   2226   LOC_LOGD("NMEA <%s", nmea_report_ptr->nmea);
   2227 }
   2228 
   2229 /* convert and report an ATL request to loc engine */
   2230 void LocApiV02 :: reportAtlRequest(
   2231   const qmiLocEventLocationServerConnectionReqIndMsgT_v02 * server_request_ptr)
   2232 {
   2233   uint32_t connHandle = server_request_ptr->connHandle;
   2234   // service ATL open request; copy the WWAN type
   2235   if(server_request_ptr->requestType == eQMI_LOC_SERVER_REQUEST_OPEN_V02 )
   2236   {
   2237     AGpsType agpsType;
   2238     switch(server_request_ptr->wwanType)
   2239     {
   2240     case eQMI_LOC_WWAN_TYPE_INTERNET_V02:
   2241       agpsType = AGPS_TYPE_WWAN_ANY;
   2242       requestATL(connHandle, agpsType);
   2243       break;
   2244     case eQMI_LOC_WWAN_TYPE_AGNSS_V02:
   2245       agpsType = AGPS_TYPE_SUPL;
   2246       requestATL(connHandle, agpsType);
   2247       break;
   2248     case eQMI_LOC_WWAN_TYPE_AGNSS_EMERGENCY_V02:
   2249       requestSuplES(connHandle);
   2250       break;
   2251     default:
   2252       agpsType = AGPS_TYPE_WWAN_ANY;
   2253       requestATL(connHandle, agpsType);
   2254       break;
   2255     }
   2256   }
   2257   // service the ATL close request
   2258   else if (server_request_ptr->requestType == eQMI_LOC_SERVER_REQUEST_CLOSE_V02)
   2259   {
   2260     releaseATL(connHandle);
   2261   }
   2262 }
   2263 
   2264 /* conver the NI report to loc eng format and send t loc engine */
   2265 void LocApiV02 :: reportNiRequest(
   2266     const qmiLocEventNiNotifyVerifyReqIndMsgT_v02 *ni_req_ptr)
   2267 {
   2268   GpsNiNotification notif;
   2269 
   2270   /* initialize the notification*/
   2271   memset(notif.extras, 0, sizeof notif.extras);
   2272   memset(notif.text, 0, sizeof notif.text);
   2273   memset(notif.requestor_id, 0, sizeof notif.requestor_id);
   2274 
   2275   /* NI timeout gets overwritten in LocApiEngAdapter,
   2276      initializing to 0 here */
   2277   notif.timeout     = 0;
   2278 
   2279   notif.text_encoding = GPS_ENC_NONE ;
   2280 
   2281   notif.requestor_id_encoding = GPS_ENC_UNKNOWN;
   2282 
   2283   notif.notify_flags       = 0;
   2284 
   2285   notif.default_response   = GPS_NI_RESPONSE_NORESP;
   2286 
   2287   /*Handle Vx request */
   2288   if(ni_req_ptr->NiVxInd_valid == 1)
   2289   {
   2290      const qmiLocNiVxNotifyVerifyStructT_v02 *vx_req = &(ni_req_ptr->NiVxInd);
   2291 
   2292      notif.ni_type     = GPS_NI_TYPE_VOICE;
   2293 
   2294      // Requestor ID, the requestor id recieved is NULL terminated
   2295      hexcode(notif.requestor_id, sizeof notif.requestor_id,
   2296              (char *)vx_req->requestorId, vx_req->requestorId_len );
   2297   }
   2298 
   2299   /* Handle UMTS CP request*/
   2300   else if(ni_req_ptr->NiUmtsCpInd_valid == 1)
   2301   {
   2302     const qmiLocNiUmtsCpNotifyVerifyStructT_v02 *umts_cp_req =
   2303        &ni_req_ptr->NiUmtsCpInd;
   2304 
   2305     notif.ni_type     = GPS_NI_TYPE_UMTS_CTRL_PLANE;
   2306 
   2307     /* notificationText should always be a NULL terminated string */
   2308     hexcode(notif.text, sizeof notif.text,
   2309             (char *)umts_cp_req->notificationText,
   2310             umts_cp_req->notificationText_len);
   2311 
   2312     /* Store requestor ID */
   2313     hexcode(notif.requestor_id, sizeof(notif.requestor_id),
   2314             (char *)umts_cp_req->requestorId.codedString,
   2315             umts_cp_req->requestorId.codedString_len);
   2316 
   2317    /* convert encodings */
   2318     notif.text_encoding = convertNiEncoding(umts_cp_req->dataCodingScheme);
   2319 
   2320     notif.requestor_id_encoding =
   2321       convertNiEncoding(umts_cp_req->requestorId.dataCodingScheme);
   2322 
   2323     /* LCS address (using extras field) */
   2324     if ( umts_cp_req->clientAddress_len != 0)
   2325     {
   2326       char lcs_addr[32]; // Decoded LCS address for UMTS CP NI
   2327 
   2328       // Copy LCS Address into notif.extras in the format: Address = 012345
   2329       strlcat(notif.extras, LOC_NI_NOTIF_KEY_ADDRESS, sizeof (notif.extras));
   2330       strlcat(notif.extras, " = ", sizeof notif.extras);
   2331       int addr_len = 0;
   2332       const char *address_source = NULL;
   2333       address_source = (char *)umts_cp_req->clientAddress;
   2334       // client Address is always NULL terminated
   2335       addr_len = decodeAddress(lcs_addr, sizeof(lcs_addr), address_source,
   2336                                umts_cp_req->clientAddress_len);
   2337 
   2338       // The address is ASCII string
   2339       if (addr_len)
   2340       {
   2341         strlcat(notif.extras, lcs_addr, sizeof notif.extras);
   2342       }
   2343     }
   2344 
   2345   }
   2346   else if(ni_req_ptr->NiSuplInd_valid == 1)
   2347   {
   2348     const qmiLocNiSuplNotifyVerifyStructT_v02 *supl_req =
   2349       &ni_req_ptr->NiSuplInd;
   2350 
   2351     notif.ni_type     = GPS_NI_TYPE_UMTS_SUPL;
   2352 
   2353     // Client name
   2354     if (supl_req->valid_flags & QMI_LOC_SUPL_CLIENT_NAME_MASK_V02)
   2355     {
   2356       hexcode(notif.text, sizeof(notif.text),
   2357               (char *)supl_req->clientName.formattedString,
   2358               supl_req->clientName.formattedString_len);
   2359       LOC_LOGV("%s:%d]: SUPL NI: client_name: %s \n", __func__, __LINE__,
   2360           notif.text);
   2361     }
   2362     else
   2363     {
   2364       LOC_LOGV("%s:%d]: SUPL NI: client_name not present.",
   2365           __func__, __LINE__);
   2366     }
   2367 
   2368     // Requestor ID
   2369     if (supl_req->valid_flags & QMI_LOC_SUPL_REQUESTOR_ID_MASK_V02)
   2370     {
   2371       hexcode(notif.requestor_id, sizeof notif.requestor_id,
   2372               (char*)supl_req->requestorId.formattedString,
   2373               supl_req->requestorId.formattedString_len );
   2374 
   2375       LOC_LOGV("%s:%d]: SUPL NI: requestor_id: %s \n", __func__, __LINE__,
   2376           notif.requestor_id);
   2377     }
   2378     else
   2379     {
   2380       LOC_LOGV("%s:%d]: SUPL NI: requestor_id not present.",
   2381           __func__, __LINE__);
   2382     }
   2383 
   2384     // Encoding type
   2385     if (supl_req->valid_flags & QMI_LOC_SUPL_DATA_CODING_SCHEME_MASK_V02)
   2386     {
   2387       notif.text_encoding = convertNiEncoding(supl_req->dataCodingScheme);
   2388 
   2389       notif.requestor_id_encoding = convertNiEncoding(supl_req->dataCodingScheme);
   2390     }
   2391     else
   2392     {
   2393       notif.text_encoding = notif.requestor_id_encoding = GPS_ENC_UNKNOWN;
   2394     }
   2395 
   2396     // ES SUPL
   2397     if(ni_req_ptr->suplEmergencyNotification_valid ==1)
   2398     {
   2399         const qmiLocEmergencyNotificationStructT_v02 *supl_emergency_request =
   2400         &ni_req_ptr->suplEmergencyNotification;
   2401 
   2402         notif.ni_type = GPS_NI_TYPE_EMERGENCY_SUPL;
   2403     }
   2404 
   2405   } //ni_req_ptr->NiSuplInd_valid == 1
   2406   else
   2407   {
   2408     LOC_LOGE("%s:%d]: unknown request event \n",__func__, __LINE__);
   2409     return;
   2410   }
   2411 
   2412   // Set default_response & notify_flags
   2413   convertNiNotifyVerifyType(&notif, ni_req_ptr->notificationType);
   2414 
   2415   qmiLocEventNiNotifyVerifyReqIndMsgT_v02 *ni_req_copy_ptr =
   2416     (qmiLocEventNiNotifyVerifyReqIndMsgT_v02 *)malloc(sizeof(*ni_req_copy_ptr));
   2417 
   2418   if( NULL != ni_req_copy_ptr)
   2419   {
   2420     memcpy(ni_req_copy_ptr, ni_req_ptr, sizeof(*ni_req_copy_ptr));
   2421 
   2422     requestNiNotify(notif, (const void*)ni_req_copy_ptr);
   2423   }
   2424   else
   2425   {
   2426     LOC_LOGE("%s:%d]: Error copying NI request\n", __func__, __LINE__);
   2427   }
   2428 
   2429 }
   2430 
   2431 /* Report the Xtra Server Url from the modem to HAL*/
   2432 void LocApiV02 :: reportXtraServerUrl(
   2433                 const qmiLocEventInjectPredictedOrbitsReqIndMsgT_v02*
   2434                 server_request_ptr)
   2435 {
   2436 
   2437   if (server_request_ptr->serverList.serverList_len == 1)
   2438   {
   2439     reportXtraServer(server_request_ptr->serverList.serverList[0].serverUrl,
   2440                      "",
   2441                      "",
   2442                      QMI_LOC_MAX_SERVER_ADDR_LENGTH_V02);
   2443   }
   2444   else if (server_request_ptr->serverList.serverList_len == 2)
   2445   {
   2446     reportXtraServer(server_request_ptr->serverList.serverList[0].serverUrl,
   2447                      server_request_ptr->serverList.serverList[1].serverUrl,
   2448                      "",
   2449                      QMI_LOC_MAX_SERVER_ADDR_LENGTH_V02);
   2450   }
   2451   else
   2452   {
   2453     reportXtraServer(server_request_ptr->serverList.serverList[0].serverUrl,
   2454                      server_request_ptr->serverList.serverList[1].serverUrl,
   2455                      server_request_ptr->serverList.serverList[2].serverUrl,
   2456                      QMI_LOC_MAX_SERVER_ADDR_LENGTH_V02);
   2457   }
   2458 
   2459 }
   2460 
   2461 /* convert Ni Encoding type from QMI_LOC to loc eng format */
   2462 GpsNiEncodingType LocApiV02 ::convertNiEncoding(
   2463   qmiLocNiDataCodingSchemeEnumT_v02 loc_encoding)
   2464 {
   2465    GpsNiEncodingType enc = GPS_ENC_UNKNOWN;
   2466 
   2467    switch (loc_encoding)
   2468    {
   2469      case eQMI_LOC_NI_SUPL_UTF8_V02:
   2470        enc = GPS_ENC_SUPL_UTF8;
   2471        break;
   2472      case eQMI_LOC_NI_SUPL_UCS2_V02:
   2473        enc = GPS_ENC_SUPL_UCS2;
   2474        break;
   2475      case eQMI_LOC_NI_SUPL_GSM_DEFAULT_V02:
   2476        enc = GPS_ENC_SUPL_GSM_DEFAULT;
   2477        break;
   2478      case eQMI_LOC_NI_SS_LANGUAGE_UNSPEC_V02:
   2479        enc = GPS_ENC_SUPL_GSM_DEFAULT; // SS_LANGUAGE_UNSPEC = GSM
   2480        break;
   2481      default:
   2482        break;
   2483    }
   2484 
   2485    return enc;
   2486 }
   2487 
   2488 /*convert NI notify verify type from QMI LOC to loc eng format*/
   2489 bool LocApiV02 :: convertNiNotifyVerifyType (
   2490   GpsNiNotification *notif,
   2491   qmiLocNiNotifyVerifyEnumT_v02 notif_priv)
   2492 {
   2493   switch (notif_priv)
   2494    {
   2495    case eQMI_LOC_NI_USER_NO_NOTIFY_NO_VERIFY_V02:
   2496       notif->notify_flags = 0;
   2497       break;
   2498 
   2499    case eQMI_LOC_NI_USER_NOTIFY_ONLY_V02:
   2500       notif->notify_flags = GPS_NI_NEED_NOTIFY;
   2501       break;
   2502 
   2503    case eQMI_LOC_NI_USER_NOTIFY_VERIFY_ALLOW_NO_RESP_V02:
   2504       notif->notify_flags = GPS_NI_NEED_NOTIFY | GPS_NI_NEED_VERIFY;
   2505       notif->default_response = GPS_NI_RESPONSE_ACCEPT;
   2506       break;
   2507 
   2508    case eQMI_LOC_NI_USER_NOTIFY_VERIFY_NOT_ALLOW_NO_RESP_V02:
   2509       notif->notify_flags = GPS_NI_NEED_NOTIFY | GPS_NI_NEED_VERIFY;
   2510       notif->default_response = GPS_NI_RESPONSE_DENY;
   2511       break;
   2512 
   2513    case eQMI_LOC_NI_USER_NOTIFY_VERIFY_PRIVACY_OVERRIDE_V02:
   2514       notif->notify_flags = GPS_NI_PRIVACY_OVERRIDE;
   2515       break;
   2516 
   2517    default:
   2518       return false;
   2519    }
   2520 
   2521    return true;
   2522 }
   2523 
   2524 /* convert and report GNSS measurement data to loc eng */
   2525 void LocApiV02 :: reportGnssMeasurementData(
   2526   const qmiLocEventGnssSvMeasInfoIndMsgT_v02& gnss_measurement_report_ptr)
   2527 {
   2528     LOC_LOGV ("%s:%d]: entering\n", __func__, __LINE__);
   2529 
   2530     GnssData gnssMeasurementData;
   2531     memset (&gnssMeasurementData, 0, sizeof(GnssData));
   2532 
   2533     int svMeasurment_len = 0;
   2534 
   2535     // size
   2536     gnssMeasurementData.size = sizeof(GnssData);
   2537 
   2538     // number of measurements
   2539     if (gnss_measurement_report_ptr.svMeasurement_valid) {
   2540         svMeasurment_len =
   2541             gnss_measurement_report_ptr.svMeasurement_len;
   2542         gnssMeasurementData.measurement_count = svMeasurment_len;
   2543         LOC_LOGV ("%s:%d]: there are %d valid SV measurements\n",
   2544                   __func__, __LINE__, svMeasurment_len);
   2545     } else {
   2546         LOC_LOGV ("%s:%d]: there are no valid SV measurements\n",
   2547                   __func__, __LINE__);
   2548     }
   2549 
   2550     LOC_LOGV("%s:%d]: There are %d GNSS measurements\n",
   2551         __func__, __LINE__, svMeasurment_len);
   2552     if (gnss_measurement_report_ptr.system == eQMI_LOC_SV_SYSTEM_GPS_V02) {
   2553 
   2554         // the array of measurements
   2555         int index = 0;
   2556         while(svMeasurment_len > 0) {
   2557             convertGnssMeasurements(gnssMeasurementData.measurements[index],
   2558                                    gnss_measurement_report_ptr.svMeasurement[index]);
   2559             index++;
   2560             svMeasurment_len--;
   2561         }
   2562 
   2563         // the GPS clock time reading
   2564         convertGnssClock(gnssMeasurementData.clock,
   2565                         gnss_measurement_report_ptr);
   2566 
   2567         // calling the base
   2568         LOC_LOGV ("%s:%d]: calling LocApiBase::reportGnssMeasurementData.\n",
   2569                   __func__, __LINE__);
   2570         LocApiBase::reportGnssMeasurementData(gnssMeasurementData);
   2571     } else {
   2572         LOC_LOGV ("%s:%d]: There is no GPS measurement, constellation=%d\n",
   2573                   __func__, __LINE__, gnss_measurement_report_ptr.system);
   2574     }
   2575 }
   2576 
   2577 /*convert GnssMeasurement type from QMI LOC to loc eng format*/
   2578 void LocApiV02 :: convertGnssMeasurements (GnssMeasurement& gnssMeasurement,
   2579     const qmiLocSVMeasurementStructT_v02& gnss_measurement_info)
   2580 {
   2581     LOC_LOGV ("%s:%d]: entering\n", __func__, __LINE__);
   2582 
   2583     // size
   2584     gnssMeasurement.size = sizeof(GnssMeasurement);
   2585 
   2586     // flag initiation
   2587     GnssMeasurementFlags flags = 0;
   2588 
   2589     // svid
   2590     gnssMeasurement.svid = gnss_measurement_info.gnssSvId;
   2591 
   2592     // constellation
   2593     gnssMeasurement.constellation = GNSS_CONSTELLATION_GPS;
   2594 
   2595     // time_offset_ns
   2596     if (0 != gnss_measurement_info.measLatency)
   2597     {
   2598         LOC_LOGV("%s:%d]: measLatency is not 0\n", __func__, __LINE__);
   2599     }
   2600     gnssMeasurement.time_offset_ns = 0.0;
   2601 
   2602     // state & received_sv_time_in_ns & received_gps_tow_uncertainty_ns
   2603     uint64_t validMask = gnss_measurement_info.measurementStatus &
   2604                          gnss_measurement_info.validMeasStatusMask;
   2605     uint64_t bitSynMask = QMI_LOC_MASK_MEAS_STATUS_BE_CONFIRM_V02 |
   2606                           QMI_LOC_MASK_MEAS_STATUS_SB_VALID_V02;
   2607     double gpsTowUncNs = (double)gnss_measurement_info.svTimeSpeed.svTimeUncMs * 1e6;
   2608 
   2609     if (validMask & QMI_LOC_MASK_MEAS_STATUS_MS_VALID_V02) {
   2610         /* sub-frame decode & TOW decode */
   2611         gnssMeasurement.state = GNSS_MEASUREMENT_STATE_SUBFRAME_SYNC |
   2612                                 GNSS_MEASUREMENT_STATE_TOW_DECODED |
   2613                                 GNSS_MEASUREMENT_STATE_BIT_SYNC |
   2614                                 GNSS_MEASUREMENT_STATE_CODE_LOCK;
   2615         gnssMeasurement.received_sv_time_in_ns =
   2616             (int64_t)(((double)gnss_measurement_info.svTimeSpeed.svTimeMs +
   2617              (double)gnss_measurement_info.svTimeSpeed.svTimeSubMs) * 1e6);
   2618 
   2619         gnssMeasurement.received_sv_time_uncertainty_in_ns = (int64_t)gpsTowUncNs;
   2620 
   2621     } else if ((validMask & bitSynMask) == bitSynMask) {
   2622         /* bit sync */
   2623         gnssMeasurement.state = GNSS_MEASUREMENT_STATE_BIT_SYNC |
   2624                                 GNSS_MEASUREMENT_STATE_CODE_LOCK;
   2625         gnssMeasurement.received_sv_time_in_ns =
   2626             (int64_t)(fmod(((double)gnss_measurement_info.svTimeSpeed.svTimeMs +
   2627                   (double)gnss_measurement_info.svTimeSpeed.svTimeSubMs), 20) * 1e6);
   2628         gnssMeasurement.received_sv_time_uncertainty_in_ns = (int64_t)gpsTowUncNs;
   2629 
   2630     } else if (validMask & QMI_LOC_MASK_MEAS_STATUS_SM_VALID_V02) {
   2631         /* code lock */
   2632         gnssMeasurement.state = GNSS_MEASUREMENT_STATE_CODE_LOCK;
   2633         gnssMeasurement.received_sv_time_in_ns =
   2634              (int64_t)((double)gnss_measurement_info.svTimeSpeed.svTimeSubMs * 1e6);
   2635         gnssMeasurement.received_sv_time_uncertainty_in_ns = (int64_t)gpsTowUncNs;
   2636 
   2637     } else {
   2638         /* by default */
   2639         gnssMeasurement.state = GNSS_MEASUREMENT_STATE_UNKNOWN;
   2640         gnssMeasurement.received_sv_time_in_ns = 0;
   2641         gnssMeasurement.received_sv_time_uncertainty_in_ns = 0;
   2642     }
   2643 
   2644     // c_n0_dbhz
   2645     gnssMeasurement.c_n0_dbhz = gnss_measurement_info.CNo/10.0;
   2646 
   2647     if (QMI_LOC_MASK_MEAS_STATUS_VELOCITY_FINE_V02 == (gnss_measurement_info.measurementStatus & QMI_LOC_MASK_MEAS_STATUS_VELOCITY_FINE_V02))
   2648     {
   2649         LOC_LOGV ("%s:%d]: FINE mS=0x%4X fS=%f fSU=%f dS=%f dSU=%f\n", __func__, __LINE__, gnss_measurement_info.measurementStatus,
   2650         gnss_measurement_info.fineSpeed, gnss_measurement_info.fineSpeedUnc,
   2651         gnss_measurement_info.svTimeSpeed.dopplerShift, gnss_measurement_info.svTimeSpeed.dopplerShiftUnc);
   2652         // pseudorange_rate_mps
   2653         gnssMeasurement.pseudorange_rate_mps = gnss_measurement_info.fineSpeed;
   2654 
   2655         // pseudorange_rate_uncertainty_mps
   2656         gnssMeasurement.pseudorange_rate_uncertainty_mps = gnss_measurement_info.fineSpeedUnc;
   2657     }
   2658     else
   2659     {
   2660         LOC_LOGV ("%s:%d]: COARSE mS=0x%4X fS=%f fSU=%f dS=%f dSU=%f\n", __func__, __LINE__, gnss_measurement_info.measurementStatus,
   2661         gnss_measurement_info.fineSpeed, gnss_measurement_info.fineSpeedUnc,
   2662         gnss_measurement_info.svTimeSpeed.dopplerShift, gnss_measurement_info.svTimeSpeed.dopplerShiftUnc);
   2663         // pseudorange_rate_mps
   2664         gnssMeasurement.pseudorange_rate_mps = gnss_measurement_info.svTimeSpeed.dopplerShift;
   2665 
   2666         // pseudorange_rate_uncertainty_mps
   2667         gnssMeasurement.pseudorange_rate_uncertainty_mps = gnss_measurement_info.svTimeSpeed.dopplerShiftUnc;
   2668     }
   2669 
   2670     // accumulated_delta_range_state
   2671     gnssMeasurement.accumulated_delta_range_state = GNSS_ADR_STATE_UNKNOWN;
   2672 
   2673     // multipath_indicator
   2674     gnssMeasurement.multipath_indicator = GNSS_MULTIPATH_INDICATOR_UNKNOWN;
   2675 
   2676     gnssMeasurement.flags = flags;
   2677 
   2678     LOC_LOGV(" %s:%d]: GNSS measurement raw data received form modem: \n", __func__, __LINE__);
   2679     LOC_LOGV(" Input => gnssSvId=%d CNo=%d measurementStatus=0x%04x%04x\n",
   2680              gnss_measurement_info.gnssSvId,                                    // %d
   2681              gnss_measurement_info.CNo,                                         // %d
   2682              (uint32_t)(gnss_measurement_info.measurementStatus >> 32),         // %04x Upper 32
   2683              (uint32_t)(gnss_measurement_info.measurementStatus & 0xFFFFFFFF)); // %04x Lower 32
   2684 
   2685     LOC_LOGV("  dopplerShift=%f dopplerShiftUnc=%f fineSpeed=%f fineSpeedUnc=%f\n",
   2686              gnss_measurement_info.svTimeSpeed.dopplerShift,                    // %f
   2687              gnss_measurement_info.svTimeSpeed.dopplerShiftUnc,                 // %f
   2688              gnss_measurement_info.fineSpeed,                                   // %f
   2689              gnss_measurement_info.fineSpeedUnc);                               // %f
   2690 
   2691     LOC_LOGV("  svTimeMs=%u svTimeSubMs=%f svTimeUncMs=%f\n",
   2692              gnss_measurement_info.svTimeSpeed.svTimeMs,                        // %u
   2693              gnss_measurement_info.svTimeSpeed.svTimeSubMs,                     // %f
   2694              gnss_measurement_info.svTimeSpeed.svTimeUncMs);                    // %f
   2695 
   2696     LOC_LOGV("  svStatus=0x%02x validMeasStatusMask=0x%04x%04x\n",
   2697              (uint32_t)(gnss_measurement_info.svStatus),                        // %02x
   2698              (uint32_t)(gnss_measurement_info.validMeasStatusMask >> 32),       // %04x Upper 32
   2699              (uint32_t)(gnss_measurement_info.validMeasStatusMask & 0xFFFFFFFF));   // %04x Lower 32
   2700 
   2701     LOC_LOGV(" %s:%d]: GNSS measurement data after conversion:\n", __func__, __LINE__);
   2702     LOC_LOGV(" Output => size=%d svid=%d time_offset_ns=%f state=%d\n",
   2703              gnssMeasurement.size,                              // %d
   2704              gnssMeasurement.svid,                               // %d
   2705              gnssMeasurement.time_offset_ns,                    // %f
   2706              gnssMeasurement.state);                            // %d
   2707 
   2708     LOC_LOGV("  received_sv_time_in_ns=%lld received_sv_time_uncertainty_in_ns=%lld c_n0_dbhz=%g\n",
   2709              gnssMeasurement.received_sv_time_in_ns,            // %lld
   2710              gnssMeasurement.received_sv_time_uncertainty_in_ns,// %lld
   2711              gnssMeasurement.c_n0_dbhz);                        // %g
   2712 
   2713     LOC_LOGV("  pseudorange_rate_mps=%g pseudorange_rate_uncertainty_mps=%g\n",
   2714              gnssMeasurement.pseudorange_rate_mps,              // %g
   2715              gnssMeasurement.pseudorange_rate_uncertainty_mps); // %g
   2716 }
   2717 
   2718 /*convert GnssClock type from QMI LOC to loc eng format*/
   2719 void LocApiV02 :: convertGnssClock (GnssClock& gnssClock,
   2720     const qmiLocEventGnssSvMeasInfoIndMsgT_v02& gnss_measurement_info)
   2721 {
   2722     static uint32_t oldRefFCount = 0;
   2723     static uint32_t newRefFCount = 0;
   2724     static uint32_t oldDiscCount = 0;
   2725     static uint32_t newDiscCount = 0;
   2726     static uint32_t localDiscCount = 0;
   2727 
   2728     LOC_LOGV ("%s:%d]: entering\n", __func__, __LINE__);
   2729 
   2730     // size
   2731     gnssClock.size = sizeof(GnssClock);
   2732 
   2733     // flag initiation
   2734     GnssClockFlags flags = 0;
   2735 
   2736     if (gnss_measurement_info.systemTimeExt_valid &&
   2737         gnss_measurement_info.numClockResets_valid) {
   2738         newRefFCount = gnss_measurement_info.systemTimeExt.refFCount;
   2739         newDiscCount = gnss_measurement_info.numClockResets;
   2740         if ((true == mMeasurementsStarted) ||
   2741             (oldDiscCount != newDiscCount) ||
   2742             (newRefFCount <= oldRefFCount))
   2743         {
   2744             if (true == mMeasurementsStarted)
   2745             {
   2746                 mMeasurementsStarted = false;
   2747             }
   2748             localDiscCount++;
   2749         }
   2750         oldDiscCount = newDiscCount;
   2751         oldRefFCount = newRefFCount;
   2752 
   2753         // time_ns & time_uncertainty_ns
   2754         gnssClock.time_ns = (int64_t)gnss_measurement_info.systemTimeExt.refFCount * 1e6;
   2755         gnssClock.hw_clock_discontinuity_count = localDiscCount;
   2756         gnssClock.time_uncertainty_ns = 0.0;
   2757 
   2758         if (gnss_measurement_info.systemTime_valid) {
   2759             uint16_t systemWeek = gnss_measurement_info.systemTime.systemWeek;
   2760             uint32_t systemMsec = gnss_measurement_info.systemTime.systemMsec;
   2761             float sysClkBias = gnss_measurement_info.systemTime.systemClkTimeBias;
   2762             float sysClkUncMs = gnss_measurement_info.systemTime.systemClkTimeUncMs;
   2763             bool isTimeValid = (sysClkUncMs <= 16.0f); // 16ms
   2764             double gps_time_ns;
   2765 
   2766             if (systemWeek != C_GPS_WEEK_UNKNOWN && isTimeValid) {
   2767                 // full_bias_ns, bias_ns & bias_uncertainty_ns
   2768                 double temp = (double)(systemWeek)* (double)WEEK_MSECS + (double)systemMsec;
   2769                 gps_time_ns = (double)temp*1e6 - (double)((int)(sysClkBias*1e6));
   2770                 gnssClock.full_bias_ns = (int64_t)(gnssClock.time_ns - gps_time_ns);
   2771                 gnssClock.bias_ns = (double)(gnssClock.time_ns - gps_time_ns) - gnssClock.full_bias_ns;
   2772                 gnssClock.bias_uncertainty_ns = (double)sysClkUncMs * 1e6;
   2773                 flags |= (GNSS_CLOCK_HAS_FULL_BIAS | GNSS_CLOCK_HAS_BIAS | GNSS_CLOCK_HAS_BIAS_UNCERTAINTY);
   2774             }
   2775         }
   2776     }
   2777 
   2778     // drift_nsps & drift_uncertainty_nsps
   2779     if (gnss_measurement_info.rcvrClockFrequencyInfo_valid)
   2780     {
   2781         double driftMPS = gnss_measurement_info.rcvrClockFrequencyInfo.clockDrift;
   2782         double driftUncMPS = gnss_measurement_info.rcvrClockFrequencyInfo.clockDriftUnc;
   2783 
   2784         gnssClock.drift_nsps = driftMPS * MPS_TO_NSPS;
   2785         gnssClock.drift_uncertainty_nsps = driftUncMPS * MPS_TO_NSPS;
   2786 
   2787         flags |= (GNSS_CLOCK_HAS_DRIFT | GNSS_CLOCK_HAS_DRIFT_UNCERTAINTY);
   2788     }
   2789 
   2790     gnssClock.flags = flags;
   2791 
   2792     LOC_LOGV(" %s:%d]: GNSS measurement clock data received from modem: \n", __func__, __LINE__);
   2793     LOC_LOGV(" Input => systemTime_valid=%d systemTimeExt_valid=%d numClockResets_valid=%d\n",
   2794              gnss_measurement_info.systemTime_valid,                      // %d
   2795              gnss_measurement_info.systemTimeExt_valid,                   // %d
   2796         gnss_measurement_info.numClockResets_valid);                 // %d
   2797 
   2798     LOC_LOGV("  systemWeek=%d systemMsec=%d systemClkTimeBias=%f\n",
   2799              gnss_measurement_info.systemTime.systemWeek,                 // %d
   2800              gnss_measurement_info.systemTime.systemMsec,                 // %d
   2801         gnss_measurement_info.systemTime.systemClkTimeBias);         // %f
   2802 
   2803     LOC_LOGV("  systemClkTimeUncMs=%f refFCount=%d numClockResets=%d\n",
   2804              gnss_measurement_info.systemTime.systemClkTimeUncMs,         // %f
   2805         gnss_measurement_info.systemTimeExt.refFCount,               // %d
   2806         gnss_measurement_info.numClockResets);                       // %d
   2807 
   2808     LOC_LOGV("  clockDrift=%f clockDriftUnc=%f\n",
   2809         gnss_measurement_info.rcvrClockFrequencyInfo.clockDrift,     // %f
   2810         gnss_measurement_info.rcvrClockFrequencyInfo.clockDriftUnc); // %f
   2811 
   2812 
   2813     LOC_LOGV(" %s:%d]: GNSS measurement clock after conversion: \n", __func__, __LINE__);
   2814     LOC_LOGV(" Output => time_ns=%lld\n",
   2815         gnssClock.time_ns);                          // %lld
   2816 
   2817     LOC_LOGV("  full_bias_ns=%lld bias_ns=%g bias_uncertainty_ns=%g\n",
   2818         gnssClock.full_bias_ns,                      // %lld
   2819         gnssClock.bias_ns,                           // %g
   2820         gnssClock.bias_uncertainty_ns);              // %g
   2821 
   2822     LOC_LOGV("  drift_nsps=%g drift_uncertainty_nsps=%g\n",
   2823         gnssClock.drift_nsps,                        // %g
   2824         gnssClock.drift_uncertainty_nsps);           // %g
   2825 
   2826     LOC_LOGV("  hw_clock_discontinuity_count=%d flags=0x%04x\n",
   2827         gnssClock.hw_clock_discontinuity_count,     // %lld
   2828         gnssClock.flags);                           // %04x
   2829 }
   2830 
   2831 /* event callback registered with the loc_api v02 interface */
   2832 void LocApiV02 :: eventCb(locClientHandleType clientHandle,
   2833   uint32_t eventId, locClientEventIndUnionType eventPayload)
   2834 {
   2835   LOC_LOGD("%s:%d]: event id = %d\n", __func__, __LINE__,
   2836                 eventId);
   2837 
   2838   switch(eventId)
   2839   {
   2840     //Position Report
   2841     case QMI_LOC_EVENT_POSITION_REPORT_IND_V02:
   2842       reportPosition(eventPayload.pPositionReportEvent);
   2843       break;
   2844 
   2845     // Satellite report
   2846     case QMI_LOC_EVENT_GNSS_SV_INFO_IND_V02:
   2847       reportSv(eventPayload.pGnssSvInfoReportEvent);
   2848       break;
   2849 
   2850     // Status report
   2851     case QMI_LOC_EVENT_ENGINE_STATE_IND_V02:
   2852       reportEngineState(eventPayload.pEngineState);
   2853       break;
   2854 
   2855     case QMI_LOC_EVENT_FIX_SESSION_STATE_IND_V02:
   2856       reportFixSessionState(eventPayload.pFixSessionState);
   2857       break;
   2858 
   2859     // NMEA
   2860     case QMI_LOC_EVENT_NMEA_IND_V02:
   2861       reportNmea(eventPayload.pNmeaReportEvent);
   2862       break;
   2863 
   2864     // XTRA request
   2865     case QMI_LOC_EVENT_INJECT_PREDICTED_ORBITS_REQ_IND_V02:
   2866       LOC_LOGD("%s:%d]: XTRA download request\n", __func__,
   2867                     __LINE__);
   2868       reportXtraServerUrl(eventPayload.pInjectPredictedOrbitsReqEvent);
   2869       requestXtraData();
   2870       break;
   2871 
   2872     // time request
   2873     case QMI_LOC_EVENT_INJECT_TIME_REQ_IND_V02:
   2874       LOC_LOGD("%s:%d]: Time request\n", __func__,
   2875                     __LINE__);
   2876       requestTime();
   2877       break;
   2878 
   2879     //position request
   2880     case QMI_LOC_EVENT_INJECT_POSITION_REQ_IND_V02:
   2881       LOC_LOGD("%s:%d]: Position request\n", __func__,
   2882                     __LINE__);
   2883       requestLocation();
   2884       break;
   2885 
   2886     // NI request
   2887     case QMI_LOC_EVENT_NI_NOTIFY_VERIFY_REQ_IND_V02:
   2888       reportNiRequest(eventPayload.pNiNotifyVerifyReqEvent);
   2889       break;
   2890 
   2891     // AGPS connection request
   2892     case QMI_LOC_EVENT_LOCATION_SERVER_CONNECTION_REQ_IND_V02:
   2893       reportAtlRequest(eventPayload.pLocationServerConnReqEvent);
   2894       break;
   2895 
   2896     // GNSS Measurement Report
   2897     case QMI_LOC_EVENT_GNSS_MEASUREMENT_REPORT_IND_V02:
   2898       reportGnssMeasurementData(*eventPayload.pGnssSvRawInfoEvent);
   2899       break;
   2900   }
   2901 }
   2902 
   2903 /* Call the service LocAdapterBase down event*/
   2904 void LocApiV02 :: errorCb(locClientHandleType handle,
   2905                              locClientErrorEnumType errorId)
   2906 {
   2907   if(errorId == eLOC_CLIENT_ERROR_SERVICE_UNAVAILABLE)
   2908   {
   2909     LOC_LOGE("%s:%d]: Service unavailable error\n",
   2910                   __func__, __LINE__);
   2911 
   2912     handleEngineDownEvent();
   2913 
   2914     /* immediately send the engine up event so that
   2915     the loc engine re-initializes the adapter and the
   2916     loc-api_v02 interface */
   2917 
   2918     handleEngineUpEvent();
   2919   }
   2920 }
   2921 
   2922 static void ds_client_global_event_cb(ds_client_status_enum_type result,
   2923                                        void *loc_adapter_cookie)
   2924 {
   2925     LocApiV02 *locApiV02Instance = (LocApiV02 *)loc_adapter_cookie;
   2926 
   2927     locApiV02Instance->ds_client_event_cb(result);
   2928     return;
   2929 }
   2930 
   2931 void LocApiV02::ds_client_event_cb(ds_client_status_enum_type result)
   2932 {
   2933     if(result == E_DS_CLIENT_DATA_CALL_CONNECTED) {
   2934         LOC_LOGD("%s:%d]: Emergency call is up", __func__, __LINE__);
   2935         reportDataCallOpened();
   2936     }
   2937     else if(result == E_DS_CLIENT_DATA_CALL_DISCONNECTED) {
   2938         LOC_LOGE("%s:%d]: Emergency call is stopped", __func__, __LINE__);
   2939         reportDataCallClosed();
   2940     }
   2941     return;
   2942 }
   2943 
   2944 static const ds_client_cb_data ds_client_cb = {
   2945     ds_client_global_event_cb
   2946 };
   2947 
   2948 int LocApiV02 :: initDataServiceClient()
   2949 {
   2950     int ret=0;
   2951     if (NULL == dsLibraryHandle)
   2952     {
   2953       dsLibraryHandle = dlopen(DS_CLIENT_LIB_NAME, RTLD_NOW);
   2954       if (NULL == dsLibraryHandle)
   2955       {
   2956         const char * err = dlerror();
   2957         if (NULL == err)
   2958         {
   2959           err = "Unknown";
   2960         }
   2961         LOC_LOGE("%s:%d]: failed to load library %s; error=%s",
   2962                  __func__, __LINE__,
   2963                  DS_CLIENT_LIB_NAME,
   2964                  err);
   2965         ret = 1;
   2966       }
   2967       if (NULL != dsLibraryHandle)
   2968       {
   2969         ds_client_get_iface_fn *getIface = NULL;
   2970 
   2971         getIface = (ds_client_get_iface_fn*)dlsym(dsLibraryHandle,
   2972                                                   DS_CLIENT_GET_INTERFACE_FN);
   2973         if (NULL != getIface)
   2974         {
   2975           dsClientIface = getIface();
   2976         }
   2977         else
   2978         {
   2979           const char * err = dlerror();
   2980           if (NULL == err)
   2981           {
   2982             err = "Unknown";
   2983           }
   2984           LOC_LOGE("%s:%d]: failed to find symbol %s; error=%s",
   2985                    __func__, __LINE__,
   2986                    DS_CLIENT_GET_INTERFACE_FN,
   2987                    err);
   2988         }
   2989       }
   2990     }
   2991     if (NULL != dsClientIface && NULL != dsClientIface->pfn_init)
   2992     {
   2993       ds_client_status_enum_type dsret = dsClientIface->pfn_init();
   2994       if (dsret != E_DS_CLIENT_SUCCESS)
   2995       {
   2996         LOC_LOGE("%s:%d]: Error during client initialization %d",
   2997                  __func__, __LINE__,
   2998                  (int)dsret);
   2999 
   3000         ret = 3;
   3001       }
   3002     }
   3003     else
   3004     {
   3005       ret = 2;
   3006     }
   3007     LOC_LOGD("%s:%d]: ret = %d\n", __func__, __LINE__,ret);
   3008     return ret;
   3009 }
   3010 
   3011 int LocApiV02 :: openAndStartDataCall()
   3012 {
   3013     loc_api_adapter_err ret = LOC_API_ADAPTER_ERR_GENERAL_FAILURE;
   3014     int profile_index = -1;
   3015     int pdp_type = -1;
   3016     ds_client_status_enum_type result = E_DS_CLIENT_FAILURE_NOT_INITIALIZED;
   3017 
   3018     if (NULL != dsClientIface &&
   3019         NULL != dsClientIface->pfn_open_call &&
   3020         NULL != dsClientIface->pfn_start_call)
   3021     {
   3022       result = dsClientIface->pfn_open_call(&dsClientHandle,
   3023                                             &ds_client_cb,
   3024                                             (void *)this,
   3025                                             &profile_index,
   3026                                             &pdp_type);
   3027     }
   3028     if (E_DS_CLIENT_SUCCESS == result)
   3029     {
   3030         result = dsClientIface->pfn_start_call(dsClientHandle,
   3031                                                profile_index,
   3032                                                pdp_type);
   3033 
   3034         if(result == E_DS_CLIENT_SUCCESS) {
   3035             LOC_LOGD("%s:%d]: Request to start Emergency call sent\n",
   3036                  __func__, __LINE__);
   3037         ret = LOC_API_ADAPTER_ERR_SUCCESS;
   3038         }
   3039         else {
   3040             LOC_LOGE("%s:%d]: Unable to bring up emergency call using DS. result = %d",
   3041                  __func__, __LINE__, (int)result);
   3042             ret = LOC_API_ADAPTER_ERR_UNSUPPORTED;
   3043         }
   3044     }
   3045     else if(result == E_DS_CLIENT_RETRY_LATER) {
   3046         LOC_LOGE("%s:%d]: Could not start emergency call. Retry after delay\n",
   3047                  __func__, __LINE__);
   3048         ret = LOC_API_ADAPTER_ERR_ENGINE_BUSY;
   3049     }
   3050     else {
   3051         LOC_LOGE("%s:%d]: Unable to bring up emergency call using DS. ret = %d",
   3052                  __func__, __LINE__, (int)ret);
   3053         ret = LOC_API_ADAPTER_ERR_UNSUPPORTED;
   3054     }
   3055 
   3056     return (int)ret;
   3057 }
   3058 
   3059 void LocApiV02 :: stopDataCall()
   3060 {
   3061     ds_client_status_enum_type ret = E_DS_CLIENT_FAILURE_NOT_INITIALIZED;
   3062 
   3063     if (NULL != dsClientIface &&
   3064         NULL != dsClientIface->pfn_stop_call)
   3065     {
   3066       ret = dsClientIface->pfn_stop_call(dsClientHandle);
   3067     }
   3068 
   3069     if (ret == E_DS_CLIENT_SUCCESS) {
   3070         LOC_LOGD("%s:%d]: Request to Close SUPL ES call sent",
   3071                  __func__, __LINE__);
   3072     }
   3073     else {
   3074         if (ret == E_DS_CLIENT_FAILURE_INVALID_HANDLE) {
   3075             LOC_LOGE("%s:%d]: Conn handle not found for SUPL ES",
   3076                      __func__, __LINE__);
   3077         }
   3078         LOC_LOGE("%s:%d]: Could not close SUPL ES call. Ret: %d",
   3079                  __func__, __LINE__, ret);
   3080     }
   3081     return;
   3082 }
   3083 
   3084 void LocApiV02 :: closeDataCall()
   3085 {
   3086   int ret = 1;
   3087 
   3088   if (NULL != dsClientIface &&
   3089       NULL != dsClientIface->pfn_close_call)
   3090   {
   3091     dsClientIface->pfn_close_call(&dsClientHandle);
   3092     ret = 0;
   3093   }
   3094 
   3095   LOC_LOGD("%s:%d]: Release data client handle; ret=%d",
   3096            __func__, __LINE__, ret);
   3097 }
   3098 
   3099 enum loc_api_adapter_err LocApiV02 ::
   3100 getWwanZppFix(GpsLocation &zppLoc)
   3101 {
   3102     locClientReqUnionType req_union;
   3103     qmiLocGetAvailWwanPositionReqMsgT_v02 zpp_req;
   3104     qmiLocGetAvailWwanPositionIndMsgT_v02 zpp_ind;
   3105     memset(&zpp_ind, 0, sizeof(zpp_ind));
   3106     memset(&zpp_req, 0, sizeof(zpp_req));
   3107     memset(&zppLoc, 0, sizeof(zppLoc));
   3108 
   3109     req_union.pGetAvailWwanPositionReq = &zpp_req;
   3110 
   3111     LOC_LOGD("%s:%d]: Get ZPP Fix from available wwan position\n", __func__, __LINE__);
   3112 
   3113     locClientStatusEnumType status =
   3114         loc_sync_send_req(clientHandle,
   3115                           QMI_LOC_GET_AVAILABLE_WWAN_POSITION_REQ_V02,
   3116                           req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
   3117                           QMI_LOC_GET_AVAILABLE_WWAN_POSITION_IND_V02,
   3118                           &zpp_ind);
   3119 
   3120     if (status != eLOC_CLIENT_SUCCESS ||
   3121         eQMI_LOC_SUCCESS_V02 != zpp_ind.status) {
   3122         LOC_LOGD ("%s:%d]: getWwanZppFix may not be supported by modem"
   3123                   " so will fallback to getBestAvailableZppFix"
   3124                   " status = %s, zpp_ind.status = %s ",
   3125                   __func__, __LINE__,
   3126                   loc_get_v02_client_status_name(status),
   3127                   loc_get_v02_qmi_status_name(zpp_ind.status));
   3128 
   3129         LocPosTechMask tech_mask;
   3130         loc_api_adapter_err ret;
   3131         ret = getBestAvailableZppFix(zppLoc, tech_mask);
   3132         if (ret == LOC_API_ADAPTER_ERR_SUCCESS &&
   3133             tech_mask != LOC_POS_TECH_MASK_DEFAULT &&
   3134             tech_mask & LOC_POS_TECH_MASK_CELLID) {
   3135             return LOC_API_ADAPTER_ERR_SUCCESS;
   3136         } else {
   3137             LOC_LOGD ("%s:%d]: getBestAvailableZppFix failed or"
   3138                   " technoloy source includes GNSS that is not allowed"
   3139                   " ret = %u, tech_mask = 0x%X ",
   3140                   __func__, __LINE__, ret, tech_mask);
   3141             return LOC_API_ADAPTER_ERR_GENERAL_FAILURE;
   3142         }
   3143     }
   3144 
   3145     LOC_LOGD("Got Zpp fix location validity (lat:%d, lon:%d, timestamp:%d accuracy:%d)",
   3146              zpp_ind.latitude_valid,
   3147              zpp_ind.longitude_valid,
   3148              zpp_ind.timestampUtc_valid,
   3149              zpp_ind.horUncCircular_valid);
   3150 
   3151     LOC_LOGD("(%.7f, %.7f), timestamp %llu, accuracy %f",
   3152              zpp_ind.latitude,
   3153              zpp_ind.longitude,
   3154              zpp_ind.timestampUtc,
   3155              zpp_ind.horUncCircular);
   3156 
   3157     zppLoc.size = sizeof(GpsLocation);
   3158     if (zpp_ind.timestampUtc_valid) {
   3159         zppLoc.timestamp = zpp_ind.timestampUtc;
   3160     }
   3161     else {
   3162         /* The UTC time from modem is not valid.
   3163         In this case, we use current system time instead.*/
   3164 
   3165         struct timespec time_info_current;
   3166         clock_gettime(CLOCK_REALTIME,&time_info_current);
   3167         zppLoc.timestamp = (time_info_current.tv_sec)*1e3 +
   3168                            (time_info_current.tv_nsec)/1e6;
   3169         LOC_LOGD("zpp timestamp got from system: %llu", zppLoc.timestamp);
   3170     }
   3171 
   3172     if ((zpp_ind.latitude_valid == false) ||
   3173         (zpp_ind.longitude_valid == false) ||
   3174         (zpp_ind.horUncCircular_valid == false)) {
   3175         return LOC_API_ADAPTER_ERR_GENERAL_FAILURE;
   3176     }
   3177 
   3178     zppLoc.flags = GPS_LOCATION_HAS_LAT_LONG | GPS_LOCATION_HAS_ACCURACY;
   3179     zppLoc.latitude = zpp_ind.latitude;
   3180     zppLoc.longitude = zpp_ind.longitude;
   3181     zppLoc.accuracy = zpp_ind.horUncCircular;
   3182 
   3183     if (zpp_ind.altitudeWrtEllipsoid_valid) {
   3184         zppLoc.flags |= GPS_LOCATION_HAS_ALTITUDE;
   3185         zppLoc.altitude = zpp_ind.altitudeWrtEllipsoid;
   3186     }
   3187 
   3188     return LOC_API_ADAPTER_ERR_SUCCESS;
   3189 }
   3190 
   3191 enum loc_api_adapter_err LocApiV02 :: getBestAvailableZppFix(GpsLocation & zppLoc)
   3192 {
   3193     LocPosTechMask tech_mask;
   3194     return getBestAvailableZppFix(zppLoc, tech_mask);
   3195 }
   3196 
   3197 enum loc_api_adapter_err LocApiV02 ::
   3198 getBestAvailableZppFix(GpsLocation &zppLoc, LocPosTechMask &tech_mask)
   3199 {
   3200     locClientReqUnionType req_union;
   3201 
   3202     qmiLocGetBestAvailablePositionIndMsgT_v02 zpp_ind;
   3203     qmiLocGetBestAvailablePositionReqMsgT_v02 zpp_req;
   3204 
   3205     memset(&zpp_ind, 0, sizeof(zpp_ind));
   3206     memset(&zpp_req, 0, sizeof(zpp_req));
   3207     memset(&zppLoc, 0, sizeof(zppLoc));
   3208     tech_mask = LOC_POS_TECH_MASK_DEFAULT;
   3209 
   3210     req_union.pGetBestAvailablePositionReq = &zpp_req;
   3211 
   3212     LOC_LOGD("%s:%d]: Get ZPP Fix from best available source\n", __func__, __LINE__);
   3213 
   3214     locClientStatusEnumType status =
   3215         loc_sync_send_req(clientHandle,
   3216                           QMI_LOC_GET_BEST_AVAILABLE_POSITION_REQ_V02,
   3217                           req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
   3218                           QMI_LOC_GET_BEST_AVAILABLE_POSITION_IND_V02,
   3219                           &zpp_ind);
   3220 
   3221     if (status != eLOC_CLIENT_SUCCESS ||
   3222         eQMI_LOC_SUCCESS_V02 != zpp_ind.status) {
   3223         LOC_LOGE ("%s:%d]: error! status = %s, zpp_ind.status = %s\n",
   3224                   __func__, __LINE__,
   3225                   loc_get_v02_client_status_name(status),
   3226                   loc_get_v02_qmi_status_name(zpp_ind.status));
   3227     } else {
   3228         LOC_LOGD("Got Zpp fix location validity (lat:%d, lon:%d, timestamp:%d accuracy:%d)"
   3229                  " (%.7f, %.7f), timestamp %llu, accuracy %f",
   3230                  zpp_ind.latitude_valid,
   3231                  zpp_ind.longitude_valid,
   3232                  zpp_ind.timestampUtc_valid,
   3233                  zpp_ind.horUncCircular_valid,
   3234                  zpp_ind.latitude,
   3235                  zpp_ind.longitude,
   3236                  zpp_ind.timestampUtc,
   3237                  zpp_ind.horUncCircular);
   3238 
   3239         zppLoc.size = sizeof(GpsLocation);
   3240         if (zpp_ind.timestampUtc_valid) {
   3241             zppLoc.timestamp = zpp_ind.timestampUtc;
   3242         }
   3243         else {
   3244             /* The UTC time from modem is not valid.
   3245             In this case, we use current system time instead.*/
   3246 
   3247             struct timespec time_info_current;
   3248             clock_gettime(CLOCK_REALTIME,&time_info_current);
   3249             zppLoc.timestamp = (time_info_current.tv_sec)*1e3 +
   3250                                (time_info_current.tv_nsec)/1e6;
   3251             LOC_LOGD("zpp timestamp got from system: %llu", zppLoc.timestamp);
   3252         }
   3253 
   3254         if (zpp_ind.latitude_valid &&
   3255             zpp_ind.longitude_valid &&
   3256             zpp_ind.horUncCircular_valid ) {
   3257             zppLoc.flags = GPS_LOCATION_HAS_LAT_LONG | GPS_LOCATION_HAS_ACCURACY;
   3258             zppLoc.latitude = zpp_ind.latitude;
   3259             zppLoc.longitude = zpp_ind.longitude;
   3260             zppLoc.accuracy = zpp_ind.horUncCircular;
   3261 
   3262             if (zpp_ind.altitudeWrtEllipsoid_valid) {
   3263                 zppLoc.flags |= GPS_LOCATION_HAS_ALTITUDE;
   3264                 zppLoc.altitude = zpp_ind.altitudeWrtEllipsoid;
   3265             }
   3266 
   3267             if (zpp_ind.horSpeed_valid) {
   3268                 zppLoc.flags |= GPS_LOCATION_HAS_SPEED;
   3269                 zppLoc.speed = zpp_ind.horSpeed;
   3270             }
   3271 
   3272             if (zpp_ind.heading_valid) {
   3273                 zppLoc.flags |= GPS_LOCATION_HAS_BEARING;
   3274                 zppLoc.bearing = zpp_ind.heading;
   3275             }
   3276 
   3277             if (zpp_ind.technologyMask_valid) {
   3278                 tech_mask = zpp_ind.technologyMask;
   3279             }
   3280         }
   3281     }
   3282 
   3283     return convertErr(status);
   3284 }
   3285 
   3286 /*Values for lock
   3287   1 = Do not lock any position sessions
   3288   2 = Lock MI position sessions
   3289   3 = Lock MT position sessions
   3290   4 = Lock all position sessions
   3291 
   3292   Returns values:
   3293   zero on success; non-zero on failure
   3294 */
   3295 int LocApiV02 :: setGpsLock(LOC_GPS_LOCK_MASK lockMask)
   3296 {
   3297     qmiLocSetEngineLockReqMsgT_v02 setEngineLockReq;
   3298     qmiLocSetEngineLockIndMsgT_v02 setEngineLockInd;
   3299     locClientStatusEnumType status;
   3300     locClientReqUnionType req_union;
   3301     int ret=0;
   3302 
   3303     LOC_LOGD("%s:%d]: Set Gps Lock: %x\n", __func__, __LINE__, lockMask);
   3304     setEngineLockReq.lockType = convertGpsLockMask(lockMask);
   3305     req_union.pSetEngineLockReq = &setEngineLockReq;
   3306     memset(&setEngineLockInd, 0, sizeof(setEngineLockInd));
   3307     status = loc_sync_send_req(clientHandle,
   3308                                QMI_LOC_SET_ENGINE_LOCK_REQ_V02,
   3309                                req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
   3310                                QMI_LOC_SET_ENGINE_LOCK_IND_V02,
   3311                                &setEngineLockInd);
   3312 
   3313     if(status != eLOC_CLIENT_SUCCESS || setEngineLockInd.status != eQMI_LOC_SUCCESS_V02) {
   3314         LOC_LOGE("%s:%d]: Set engine lock failed. status: %s, ind status:%s\n",
   3315                  __func__, __LINE__,
   3316                  loc_get_v02_client_status_name(status),
   3317                  loc_get_v02_qmi_status_name(setEngineLockInd.status));
   3318         ret = -1;
   3319     }
   3320     LOC_LOGD("%s:%d]: exit\n", __func__, __LINE__);
   3321     return ret;
   3322 }
   3323 /*
   3324   Returns
   3325   Current value of GPS Lock on success
   3326   -1 on failure
   3327 */
   3328 int LocApiV02 :: getGpsLock()
   3329 {
   3330     qmiLocGetEngineLockReqMsgT_v02 getEngineLockReq;
   3331     qmiLocGetEngineLockIndMsgT_v02 getEngineLockInd;
   3332     locClientStatusEnumType status;
   3333     locClientReqUnionType req_union;
   3334     int ret=0;
   3335     LOC_LOGD("%s:%d]: Enter\n", __func__, __LINE__);
   3336     memset(&getEngineLockInd, 0, sizeof(getEngineLockInd));
   3337 
   3338     //Passing req_union as a parameter even though this request has no payload
   3339     //since NULL or 0 gives an error during compilation
   3340     status = loc_sync_send_req(clientHandle,
   3341                                QMI_LOC_GET_ENGINE_LOCK_REQ_V02,
   3342                                req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
   3343                                QMI_LOC_GET_ENGINE_LOCK_IND_V02,
   3344                                &getEngineLockInd);
   3345     if(status != eLOC_CLIENT_SUCCESS || getEngineLockInd.status != eQMI_LOC_SUCCESS_V02) {
   3346         LOC_LOGE("%s:%d]: Set engine lock failed. status: %s, ind status:%s\n",
   3347                  __func__, __LINE__,
   3348                  loc_get_v02_client_status_name(status),
   3349                  loc_get_v02_qmi_status_name(getEngineLockInd.status));
   3350         ret = -1;
   3351     }
   3352     else {
   3353         if(getEngineLockInd.lockType_valid) {
   3354             ret = (int)getEngineLockInd.lockType;
   3355             LOC_LOGD("%s:%d]: Lock Type: %d\n", __func__, __LINE__, ret);
   3356         }
   3357         else {
   3358             LOC_LOGE("%s:%d]: Lock Type not valid\n", __func__, __LINE__);
   3359             ret = -1;
   3360         }
   3361     }
   3362     LOC_LOGD("%s:%d]: Exit\n", __func__, __LINE__);
   3363     return ret;
   3364 }
   3365 
   3366 enum loc_api_adapter_err LocApiV02:: setXtraVersionCheck(enum xtra_version_check check)
   3367 {
   3368     qmiLocSetXtraVersionCheckReqMsgT_v02 req;
   3369     qmiLocSetXtraVersionCheckIndMsgT_v02 ind;
   3370     locClientStatusEnumType status;
   3371     locClientReqUnionType req_union;
   3372     enum loc_api_adapter_err ret = LOC_API_ADAPTER_ERR_SUCCESS;
   3373 
   3374     LOC_LOGD("%s:%d]: Enter. check: %d", __func__, __LINE__, check);
   3375     memset(&req, 0, sizeof(req));
   3376     memset(&ind, 0, sizeof(ind));
   3377     switch (check) {
   3378     case DISABLED:
   3379         req.xtraVersionCheckMode = eQMI_LOC_XTRA_VERSION_CHECK_DISABLE_V02;
   3380         break;
   3381     case AUTO:
   3382         req.xtraVersionCheckMode = eQMI_LOC_XTRA_VERSION_CHECK_AUTO_V02;
   3383         break;
   3384     case XTRA2:
   3385         req.xtraVersionCheckMode = eQMI_LOC_XTRA_VERSION_CHECK_XTRA2_V02;
   3386         break;
   3387     case XTRA3:
   3388         req.xtraVersionCheckMode = eQMI_LOC_XTRA_VERSION_CHECK_XTRA3_V02;
   3389         break;
   3390     default:
   3391         req.xtraVersionCheckMode = eQMI_LOC_XTRA_VERSION_CHECK_DISABLE_V02;
   3392         break;
   3393     }
   3394 
   3395     req_union.pSetXtraVersionCheckReq = &req;
   3396     status = loc_sync_send_req(clientHandle,
   3397                                QMI_LOC_SET_XTRA_VERSION_CHECK_REQ_V02,
   3398                                req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
   3399                                QMI_LOC_SET_XTRA_VERSION_CHECK_IND_V02,
   3400                                &ind);
   3401     if(status != eLOC_CLIENT_SUCCESS || ind.status != eQMI_LOC_SUCCESS_V02) {
   3402         LOC_LOGE("%s:%d]: Set xtra version check failed. status: %s, ind status:%s\n",
   3403                  __func__, __LINE__,
   3404                  loc_get_v02_client_status_name(status),
   3405                  loc_get_v02_qmi_status_name(ind.status));
   3406         ret = LOC_API_ADAPTER_ERR_GENERAL_FAILURE;
   3407     }
   3408 
   3409     LOC_LOGD("%s:%d]: Exit. ret: %d", __func__, __LINE__, (int)ret);
   3410     return ret;
   3411 }
   3412 
   3413 void LocApiV02 :: installAGpsCert(const DerEncodedCertificate* pData,
   3414                                   size_t numberOfCerts,
   3415                                   uint32_t slotBitMask)
   3416 {
   3417     LOC_LOGD("%s:%d]:, slot mask=%u number of certs=%u",
   3418             __func__, __LINE__, slotBitMask, numberOfCerts);
   3419 
   3420     uint8_t certIndex = 0;
   3421     for (uint8_t slot = 0; slot <= AGPS_CERTIFICATE_MAX_SLOTS-1; slot++, slotBitMask >>= 1)
   3422     {
   3423         if (slotBitMask & 1) //slot is writable
   3424         {
   3425             if (certIndex < numberOfCerts && pData[certIndex].data && pData[certIndex].length > 0)
   3426             {
   3427                 LOC_LOGD("%s:%d]:, Inject cert#%u slot=%u length=%u",
   3428                          __func__, __LINE__, certIndex, slot, pData[certIndex].length);
   3429 
   3430                 locClientReqUnionType req_union;
   3431                 locClientStatusEnumType status;
   3432                 qmiLocInjectSuplCertificateReqMsgT_v02 injectCertReq;
   3433                 qmiLocInjectSuplCertificateIndMsgT_v02 injectCertInd;
   3434 
   3435                 memset(&injectCertReq, 0, sizeof(injectCertReq));
   3436                 injectCertReq.suplCertId = slot;
   3437                 injectCertReq.suplCertData_len = pData[certIndex].length;
   3438                 memcpy(injectCertReq.suplCertData, pData[certIndex].data, pData[certIndex].length);
   3439 
   3440                 req_union.pInjectSuplCertificateReq = &injectCertReq;
   3441 
   3442                 status = loc_sync_send_req(clientHandle,
   3443                                            QMI_LOC_INJECT_SUPL_CERTIFICATE_REQ_V02,
   3444                                            req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
   3445                                            QMI_LOC_INJECT_SUPL_CERTIFICATE_IND_V02,
   3446                                            &injectCertInd);
   3447 
   3448                 if (status != eLOC_CLIENT_SUCCESS ||
   3449                     eQMI_LOC_SUCCESS_V02 != injectCertInd.status)
   3450                 {
   3451                     LOC_LOGE ("%s:%d]: inject-error status = %s, set_server_ind.status = %s",
   3452                               __func__,__LINE__,
   3453                               loc_get_v02_client_status_name(status),
   3454                               loc_get_v02_qmi_status_name(injectCertInd.status));
   3455                 }
   3456 
   3457                 certIndex++; //move to next cert
   3458 
   3459             } else {
   3460 
   3461                 LOC_LOGD("%s:%d]:, Delete slot=%u",
   3462                          __func__, __LINE__, slot);
   3463 
   3464                 // A fake cert is injected first before delete is called to workaround
   3465                 // an issue that is seen with trying to delete an empty slot.
   3466                 {
   3467                     locClientReqUnionType req_union;
   3468                     locClientStatusEnumType status;
   3469                     qmiLocInjectSuplCertificateReqMsgT_v02 injectFakeCertReq;
   3470                     qmiLocInjectSuplCertificateIndMsgT_v02 injectFakeCertInd;
   3471 
   3472                     memset(&injectFakeCertReq, 0, sizeof(injectFakeCertReq));
   3473                     injectFakeCertReq.suplCertId = slot;
   3474                     injectFakeCertReq.suplCertData_len = 1;
   3475                     injectFakeCertReq.suplCertData[0] = 1;
   3476 
   3477                     req_union.pInjectSuplCertificateReq = &injectFakeCertReq;
   3478 
   3479                     status = loc_sync_send_req(clientHandle,
   3480                                        QMI_LOC_INJECT_SUPL_CERTIFICATE_REQ_V02,
   3481                                        req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
   3482                                        QMI_LOC_INJECT_SUPL_CERTIFICATE_IND_V02,
   3483                                        &injectFakeCertInd);
   3484 
   3485                     if (status != eLOC_CLIENT_SUCCESS ||
   3486                         eQMI_LOC_SUCCESS_V02 != injectFakeCertInd.status)
   3487                     {
   3488                         LOC_LOGE ("%s:%d]: inject-fake-error status = %s, set_server_ind.status = %s",
   3489                                   __func__,__LINE__,
   3490                                   loc_get_v02_client_status_name(status),
   3491                                   loc_get_v02_qmi_status_name(injectFakeCertInd.status));
   3492                     }
   3493                 }
   3494 
   3495                 locClientReqUnionType req_union;
   3496                 locClientStatusEnumType status;
   3497                 qmiLocDeleteSuplCertificateReqMsgT_v02 deleteCertReq;
   3498                 qmiLocDeleteSuplCertificateIndMsgT_v02 deleteCertInd;
   3499 
   3500                 memset(&deleteCertReq, 0, sizeof(deleteCertReq));
   3501                 deleteCertReq.suplCertId = slot;
   3502                 deleteCertReq.suplCertId_valid = 1;
   3503 
   3504                 req_union.pDeleteSuplCertificateReq = &deleteCertReq;
   3505 
   3506                 status = loc_sync_send_req(clientHandle,
   3507                                            QMI_LOC_DELETE_SUPL_CERTIFICATE_REQ_V02,
   3508                                            req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
   3509                                            QMI_LOC_DELETE_SUPL_CERTIFICATE_IND_V02,
   3510                                            &deleteCertInd);
   3511 
   3512                 if (status != eLOC_CLIENT_SUCCESS ||
   3513                     eQMI_LOC_SUCCESS_V02 != deleteCertInd.status)
   3514                 {
   3515                     LOC_LOGE("%s:%d]: delete-error status = %s, set_server_ind.status = %s",
   3516                               __func__,__LINE__,
   3517                               loc_get_v02_client_status_name(status),
   3518                               loc_get_v02_qmi_status_name(deleteCertInd.status));
   3519                 }
   3520             }
   3521         } else {
   3522             LOC_LOGD("%s:%d]:, Not writable slot=%u",
   3523                      __func__, __LINE__, slot);
   3524         }
   3525     }
   3526 }
   3527 
   3528 /*
   3529   Returns
   3530   0: update the gps reporting event successfully
   3531   -1: on failure
   3532 */
   3533 int LocApiV02 :: updateRegistrationMask(LOC_API_ADAPTER_EVENT_MASK_T event,
   3534                                         loc_registration_mask_status isEnabled)
   3535 {
   3536     LOC_LOGD("%s:%d]: Enter\n", __func__, __LINE__);
   3537 
   3538     return open((isEnabled == LOC_REGISTRATION_MASK_ENABLED)?(mMask|event):(mMask&~event));
   3539 }
   3540 
   3541 bool LocApiV02 :: gnssConstellationConfig()
   3542 {
   3543     return mGnssMeasurementSupported == sup_yes;
   3544 }
   3545 
   3546 void LocApiV02 :: cacheGnssMeasurementSupport()
   3547 {
   3548     if (sup_unknown == mGnssMeasurementSupported) {
   3549         if ((mQmiMask & QMI_LOC_EVENT_MASK_POSITION_REPORT_V02) ==
   3550             QMI_LOC_EVENT_MASK_POSITION_REPORT_V02) {
   3551             /*for GNSS Measurement service, use
   3552               QMI_LOC_SET_GNSS_CONSTELL_REPORT_CONFIG_V02
   3553               to check if modem support this feature or not*/
   3554             LOC_LOGD("%s:%d]: set GNSS measurement to report gps measurement only.\n",
   3555                      __func__, __LINE__);
   3556 
   3557             qmiLocSetGNSSConstRepConfigReqMsgT_v02 setGNSSConstRepConfigReq;
   3558             qmiLocSetGNSSConstRepConfigIndMsgT_v02 setGNSSConstRepConfigInd;
   3559             memset(&setGNSSConstRepConfigReq, 0, sizeof(setGNSSConstRepConfigReq));
   3560             memset(&setGNSSConstRepConfigInd, 0, sizeof(setGNSSConstRepConfigInd));
   3561 
   3562             locClientStatusEnumType status;
   3563             locClientReqUnionType req_union;
   3564 
   3565             setGNSSConstRepConfigReq.measReportConfig_valid = true;
   3566             setGNSSConstRepConfigReq.measReportConfig = eQMI_SYSTEM_GPS_V02;
   3567             req_union.pSetGNSSConstRepConfigReq = &setGNSSConstRepConfigReq;
   3568 
   3569             status = loc_sync_send_req(clientHandle,
   3570                                        QMI_LOC_SET_GNSS_CONSTELL_REPORT_CONFIG_V02,
   3571                                        req_union,
   3572                                        LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
   3573                                        QMI_LOC_SET_GNSS_CONSTELL_REPORT_CONFIG_IND_V02,
   3574                                        &setGNSSConstRepConfigInd);
   3575 
   3576             if(status != eLOC_CLIENT_SUCCESS ||
   3577                setGNSSConstRepConfigInd.status != eQMI_LOC_SUCCESS_V02) {
   3578                 LOC_LOGD("%s:%d]: Set GNSS constellation failed."
   3579                          " status: %s, ind status:%s\n",
   3580                          __func__, __LINE__,
   3581                          loc_get_v02_client_status_name(status),
   3582                          loc_get_v02_qmi_status_name(setGNSSConstRepConfigInd.status));
   3583                 mGnssMeasurementSupported = sup_no;
   3584             } else {
   3585                 LOC_LOGD("%s:%d]: Set GNSS constellation succeeded.\n",
   3586                          __func__, __LINE__);
   3587                 mGnssMeasurementSupported = sup_yes;
   3588             }
   3589         }
   3590     }
   3591 
   3592     LOC_LOGV("%s:%d]: mGnssMeasurementSupported is %d\n", __func__, __LINE__, mGnssMeasurementSupported);
   3593 }
   3594