Home | History | Annotate | Download | only in src
      1 /* Copyright (c) 2011-2014, 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 Foundation, 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_NDDEBUG 0
     30 #define LOG_TAG "LocSvc_api_rpc"
     31 
     32 #include <unistd.h>
     33 #include <math.h>
     34 #ifndef USE_GLIB
     35 #include <utils/SystemClock.h>
     36 #endif /* USE_GLIB */
     37 #include <LocApiRpc.h>
     38 #include <LocAdapterBase.h>
     39 #include <loc_api_fixup.h>
     40 #include <loc_api_rpc_glue.h>
     41 #include <loc_log.h>
     42 #include <loc_api_log.h>
     43 #ifdef USE_GLIB
     44 #include <glib.h>
     45 #endif
     46 #include <librpc.h>
     47 #include <platform_lib_includes.h>
     48 
     49 using namespace loc_core;
     50 
     51 #define LOC_XTRA_INJECT_DEFAULT_TIMEOUT (3100)
     52 #define XTRA_BLOCK_SIZE                 (3072)
     53 #define LOC_IOCTL_DEFAULT_TIMEOUT 1000 // 1000 milli-seconds
     54 #define LOC_NI_NOTIF_KEY_ADDRESS           "Address"
     55 
     56 /*===========================================================================
     57 FUNCTION    loc_event_cb
     58 
     59 DESCRIPTION
     60    This is the callback function registered by loc_open.
     61 
     62 DEPENDENCIES
     63    N/A
     64 
     65 RETURN VALUE
     66    RPC_LOC_API_SUCCESS
     67 
     68 SIDE EFFECTS
     69    N/A
     70 
     71 ===========================================================================*/
     72 static int32 loc_event_cb
     73 (
     74     void*                                user,
     75     rpc_loc_client_handle_type           client_handle,
     76     rpc_loc_event_mask_type              loc_event,
     77     const rpc_loc_event_payload_u_type*  loc_event_payload
     78 )
     79 {
     80     MODEM_LOG_CALLFLOW(%s, loc_get_event_name(loc_event));
     81     loc_callback_log(loc_event, loc_event_payload);
     82     int32 ret_val = ((LocApiRpc*)user)->locEventCB(client_handle, loc_event, loc_event_payload);
     83     EXIT_LOG(%d, ret_val);
     84     return ret_val;
     85 }
     86 
     87 /*===========================================================================
     88 FUNCTION    loc_eng_rpc_global_cb
     89 
     90 DESCRIPTION
     91    This is the callback function registered by loc_open for RPC global events
     92 
     93 DEPENDENCIES
     94    N/A
     95 
     96 RETURN VALUE
     97    RPC_LOC_API_SUCCESS
     98 
     99 SIDE EFFECTS
    100    N/A
    101 
    102 ===========================================================================*/
    103 static void loc_rpc_global_cb(void* user, CLIENT* clnt, enum rpc_reset_event event)
    104 {
    105     MODEM_LOG_CALLFLOW(%s, loc_get_rpc_reset_event_name(event));
    106     ((LocApiRpc*)user)->locRpcGlobalCB(clnt, event);
    107     EXIT_LOG(%p, VOID_RET);
    108 }
    109 
    110 const LOC_API_ADAPTER_EVENT_MASK_T LocApiRpc::maskAll =
    111     LOC_API_ADAPTER_BIT_PARSED_POSITION_REPORT |
    112     LOC_API_ADAPTER_BIT_SATELLITE_REPORT |
    113     LOC_API_ADAPTER_BIT_LOCATION_SERVER_REQUEST |
    114     LOC_API_ADAPTER_BIT_ASSISTANCE_DATA_REQUEST |
    115     LOC_API_ADAPTER_BIT_IOCTL_REPORT |
    116     LOC_API_ADAPTER_BIT_STATUS_REPORT |
    117     LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT |
    118     LOC_API_ADAPTER_BIT_NI_NOTIFY_VERIFY_REQUEST;
    119 
    120 const rpc_loc_event_mask_type LocApiRpc::locBits[] =
    121 {
    122     RPC_LOC_EVENT_PARSED_POSITION_REPORT,
    123     RPC_LOC_EVENT_SATELLITE_REPORT,
    124     RPC_LOC_EVENT_NMEA_1HZ_REPORT,
    125     RPC_LOC_EVENT_NMEA_POSITION_REPORT,
    126     RPC_LOC_EVENT_NI_NOTIFY_VERIFY_REQUEST,
    127     RPC_LOC_EVENT_ASSISTANCE_DATA_REQUEST,
    128     RPC_LOC_EVENT_LOCATION_SERVER_REQUEST,
    129     RPC_LOC_EVENT_IOCTL_REPORT,
    130     RPC_LOC_EVENT_STATUS_REPORT,
    131     RPC_LOC_EVENT_WPS_NEEDED_REQUEST
    132 };
    133 
    134 LocApiRpc*
    135 LocApiRpc::createLocApiRpc(const MsgTask* msgTask,
    136                      LOC_API_ADAPTER_EVENT_MASK_T exMask,
    137                      ContextBase* context)
    138 {
    139     if (NULL == msgTask) {
    140         return NULL;
    141     }
    142     return new LocApiRpc(msgTask, exMask, context);
    143 }
    144 
    145 // constructor
    146 LocApiRpc::LocApiRpc(const MsgTask* msgTask,
    147                      LOC_API_ADAPTER_EVENT_MASK_T exMask,
    148                      ContextBase* context) :
    149     LocApiBase(msgTask, exMask, context),
    150     client_handle(RPC_LOC_CLIENT_HANDLE_INVALID),
    151     dataEnableLastSet(-1)
    152 {
    153     memset(apnLastSet, 0, sizeof(apnLastSet));
    154     loc_api_glue_init();
    155 }
    156 
    157 LocApiRpc::~LocApiRpc()
    158 {
    159     close();
    160 }
    161 
    162 rpc_loc_event_mask_type
    163 LocApiRpc::convertMask(LOC_API_ADAPTER_EVENT_MASK_T mask)
    164 {
    165     rpc_loc_event_mask_type newMask = 0;
    166 
    167     for (unsigned int i = 0, bit=1; 0 != mask; i++, bit<<=1) {
    168         if (mask & bit) {
    169             newMask |= locBits[i];
    170             mask ^= bit;
    171         }
    172     }
    173 
    174     return newMask;
    175 }
    176 
    177 rpc_loc_lock_e_type
    178 LocApiRpc::convertGpsLockMask(LOC_GPS_LOCK_MASK lockMask)
    179 {
    180     if (isGpsLockAll(lockMask))
    181         return RPC_LOC_LOCK_ALL;
    182     if (isGpsLockMO(lockMask))
    183         return RPC_LOC_LOCK_MI;
    184     if (isGpsLockMT(lockMask))
    185         return RPC_LOC_LOCK_MT;
    186     if (isGpsLockNone(lockMask))
    187         return RPC_LOC_LOCK_NONE;
    188     return (rpc_loc_lock_e_type)lockMask;
    189 }
    190 
    191 enum loc_api_adapter_err
    192 LocApiRpc::convertErr(int rpcErr)
    193 {
    194     switch(rpcErr)
    195     {
    196     case RPC_LOC_API_SUCCESS:
    197         return LOC_API_ADAPTER_ERR_SUCCESS;
    198     case RPC_LOC_API_GENERAL_FAILURE:
    199         return LOC_API_ADAPTER_ERR_GENERAL_FAILURE;
    200     case RPC_LOC_API_UNSUPPORTED:
    201         return LOC_API_ADAPTER_ERR_UNSUPPORTED;
    202     case RPC_LOC_API_INVALID_HANDLE:
    203         return LOC_API_ADAPTER_ERR_INVALID_HANDLE;
    204     case RPC_LOC_API_INVALID_PARAMETER:
    205         return LOC_API_ADAPTER_ERR_INVALID_PARAMETER;
    206     case RPC_LOC_API_ENGINE_BUSY:
    207         return LOC_API_ADAPTER_ERR_ENGINE_BUSY;
    208     case RPC_LOC_API_PHONE_OFFLINE:
    209         return LOC_API_ADAPTER_ERR_PHONE_OFFLINE;
    210     case RPC_LOC_API_TIMEOUT:
    211         return LOC_API_ADAPTER_ERR_TIMEOUT;
    212     case RPC_LOC_API_RPC_MODEM_RESTART:
    213         return LOC_API_ADAPTER_ERR_ENGINE_DOWN;
    214     case RPC_LOC_API_RPC_FAILURE:
    215         return LOC_API_ADAPTER_ERR_FAILURE;
    216     default:
    217         return LOC_API_ADAPTER_ERR_UNKNOWN;
    218     }
    219 }
    220 
    221 void LocApiRpc::locRpcGlobalCB(CLIENT* clnt, enum rpc_reset_event event)
    222 {
    223     static rpc_loc_engine_state_e_type last_state = RPC_LOC_ENGINE_STATE_MAX;
    224 
    225     switch (event) {
    226     case RPC_SUBSYSTEM_RESTART_BEGIN:
    227         if (RPC_LOC_ENGINE_STATE_OFF != last_state) {
    228             last_state = RPC_LOC_ENGINE_STATE_OFF;
    229             handleEngineDownEvent();
    230         }
    231         break;
    232     case RPC_SUBSYSTEM_RESTART_END:
    233         if (RPC_LOC_ENGINE_STATE_ON != last_state) {
    234             last_state = RPC_LOC_ENGINE_STATE_ON;
    235             handleEngineUpEvent();
    236         }
    237         break;
    238     }
    239 }
    240 
    241 int32 LocApiRpc::locEventCB(rpc_loc_client_handle_type client_handle,
    242                      rpc_loc_event_mask_type loc_event,
    243                      const rpc_loc_event_payload_u_type* loc_event_payload)
    244 {
    245     // Parsed report
    246     if (loc_event & RPC_LOC_EVENT_PARSED_POSITION_REPORT)
    247     {
    248         reportPosition(&loc_event_payload->rpc_loc_event_payload_u_type_u.
    249                        parsed_location_report);
    250     }
    251 
    252     // Satellite report
    253     if (loc_event & RPC_LOC_EVENT_SATELLITE_REPORT)
    254     {
    255         reportSv(&loc_event_payload->rpc_loc_event_payload_u_type_u.gnss_report);
    256     }
    257 
    258     // Status report
    259     if (loc_event & RPC_LOC_EVENT_STATUS_REPORT)
    260     {
    261         reportStatus(&loc_event_payload->rpc_loc_event_payload_u_type_u.status_report);
    262     }
    263 
    264     // NMEA
    265     if (loc_event & RPC_LOC_EVENT_NMEA_1HZ_REPORT)
    266     {
    267         reportNmea(&(loc_event_payload->rpc_loc_event_payload_u_type_u.nmea_report));
    268     }
    269     // XTRA support: supports only XTRA download
    270     if (loc_event & RPC_LOC_EVENT_ASSISTANCE_DATA_REQUEST)
    271     {
    272         if (loc_event_payload->rpc_loc_event_payload_u_type_u.assist_data_request.event ==
    273             RPC_LOC_ASSIST_DATA_PREDICTED_ORBITS_REQ)
    274         {
    275             requestXtraData();
    276         } else if (loc_event_payload->rpc_loc_event_payload_u_type_u.assist_data_request.event ==
    277                    RPC_LOC_ASSIST_DATA_TIME_REQ)
    278         {
    279             requestTime();
    280         } else if (loc_event_payload->rpc_loc_event_payload_u_type_u.assist_data_request.event ==
    281                    RPC_LOC_ASSIST_DATA_POSITION_INJECTION_REQ)
    282         {
    283             requestLocation();
    284         }
    285     }
    286 
    287     // AGPS data request
    288     if (loc_event & RPC_LOC_EVENT_LOCATION_SERVER_REQUEST)
    289     {
    290         ATLEvent(&loc_event_payload->rpc_loc_event_payload_u_type_u.
    291                  loc_server_request);
    292     }
    293 
    294     // NI notify request
    295     if (loc_event & RPC_LOC_EVENT_NI_NOTIFY_VERIFY_REQUEST)
    296     {
    297         NIEvent(&loc_event_payload->rpc_loc_event_payload_u_type_u.ni_request);
    298     }
    299 
    300     return RPC_LOC_API_SUCCESS;//We simply want to return sucess here as we do not want to
    301     // cause any issues in RPC thread context
    302 }
    303 
    304 enum loc_api_adapter_err
    305 LocApiRpc::open(LOC_API_ADAPTER_EVENT_MASK_T mask)
    306 {
    307     enum loc_api_adapter_err ret_val = LOC_API_ADAPTER_ERR_SUCCESS;
    308 
    309     // RPC does not dynamically update the event mask. And in the
    310     // case of RPC, all we support are positioning (gps + agps)
    311     // masks anyways, so we simply mask all of them on always.
    312     // After doing so the first time in a power cycle, we know there
    313     // will the following if condition will never be true any more.
    314     mask = maskAll;
    315 
    316     if (mask != mMask) {
    317         if (RPC_LOC_CLIENT_HANDLE_INVALID != client_handle) {
    318             close();
    319         }
    320 
    321         mMask = mask;
    322         // it is important to cap the mask here, because not all LocApi's
    323         // can enable the same bits, e.g. foreground and bckground.
    324         client_handle = loc_open(convertMask(mask),
    325                                  loc_event_cb,
    326                                  loc_rpc_global_cb, this);
    327 
    328         if (client_handle < 0) {
    329             mMask = 0;
    330             client_handle = RPC_LOC_CLIENT_HANDLE_INVALID;
    331             ret_val = LOC_API_ADAPTER_ERR_INVALID_HANDLE;
    332         }
    333     }
    334 
    335     return ret_val;
    336 }
    337 
    338 enum loc_api_adapter_err
    339 LocApiRpc::close()
    340 {
    341     if (RPC_LOC_CLIENT_HANDLE_INVALID != client_handle) {
    342         loc_clear(client_handle);
    343     }
    344 
    345     loc_close(client_handle);
    346     mMask = 0;
    347     client_handle = RPC_LOC_CLIENT_HANDLE_INVALID;
    348 
    349     return LOC_API_ADAPTER_ERR_SUCCESS;
    350 }
    351 
    352 enum loc_api_adapter_err
    353 LocApiRpc::startFix(const LocPosMode& posMode) {
    354    LOC_LOGD("LocApiRpc::startFix() called");
    355    return convertErr(
    356        loc_start_fix(client_handle)
    357        );
    358 }
    359 
    360 enum loc_api_adapter_err
    361 LocApiRpc::stopFix() {
    362    LOC_LOGD("LocApiRpc::stopFix() called");
    363    return convertErr(
    364        loc_stop_fix(client_handle)
    365        );
    366 }
    367 
    368 enum loc_api_adapter_err
    369 LocApiRpc::setPositionMode(const LocPosMode& posMode)
    370 {
    371     rpc_loc_ioctl_data_u_type    ioctl_data;
    372     rpc_loc_fix_criteria_s_type *fix_criteria_ptr =
    373         &ioctl_data.rpc_loc_ioctl_data_u_type_u.fix_criteria;
    374     rpc_loc_ioctl_e_type         ioctl_type = RPC_LOC_IOCTL_SET_FIX_CRITERIA;
    375     rpc_loc_operation_mode_e_type op_mode;
    376     int                          ret_val;
    377     const LocPosMode* fixCriteria = &posMode;
    378 
    379     ALOGD ("loc_eng_set_position mode, client = %d, interval = %d, mode = %d\n",
    380           (int32) client_handle, fixCriteria->min_interval, fixCriteria->mode);
    381 
    382     switch (fixCriteria->mode)
    383     {
    384     case LOC_POSITION_MODE_MS_BASED:
    385         op_mode = RPC_LOC_OPER_MODE_MSB;
    386         break;
    387     case LOC_POSITION_MODE_MS_ASSISTED:
    388         op_mode = RPC_LOC_OPER_MODE_MSA;
    389         break;
    390     case LOC_POSITION_MODE_RESERVED_1:
    391         op_mode = RPC_LOC_OPER_MODE_SPEED_OPTIMAL;
    392         break;
    393     case LOC_POSITION_MODE_RESERVED_2:
    394         op_mode = RPC_LOC_OPER_MODE_ACCURACY_OPTIMAL;
    395         break;
    396     case LOC_POSITION_MODE_RESERVED_3:
    397         op_mode = RPC_LOC_OPER_MODE_DATA_OPTIMAL;
    398         break;
    399     case LOC_POSITION_MODE_RESERVED_4:
    400     case LOC_POSITION_MODE_RESERVED_5:
    401         op_mode = RPC_LOC_OPER_MODE_MSA;
    402         fix_criteria_ptr->preferred_response_time  = 0;
    403         break;
    404     default:
    405         op_mode = RPC_LOC_OPER_MODE_STANDALONE;
    406     }
    407 
    408     fix_criteria_ptr->valid_mask = RPC_LOC_FIX_CRIT_VALID_PREFERRED_OPERATION_MODE |
    409                                    RPC_LOC_FIX_CRIT_VALID_RECURRENCE_TYPE;
    410     fix_criteria_ptr->min_interval = fixCriteria->min_interval;
    411     fix_criteria_ptr->preferred_operation_mode = op_mode;
    412 
    413     fix_criteria_ptr->min_interval = fixCriteria->min_interval;
    414     fix_criteria_ptr->valid_mask |= RPC_LOC_FIX_CRIT_VALID_MIN_INTERVAL;
    415 
    416     if (fixCriteria->preferred_accuracy > 0) {
    417         fix_criteria_ptr->preferred_accuracy = fixCriteria->preferred_accuracy;
    418         fix_criteria_ptr->valid_mask |= RPC_LOC_FIX_CRIT_VALID_PREFERRED_ACCURACY;
    419     }
    420     if (fixCriteria->preferred_time > 0) {
    421         fix_criteria_ptr->preferred_response_time = fixCriteria->preferred_time;
    422         fix_criteria_ptr->valid_mask |= RPC_LOC_FIX_CRIT_VALID_PREFERRED_RESPONSE_TIME;
    423     }
    424 
    425     switch (fixCriteria->recurrence) {
    426     case GPS_POSITION_RECURRENCE_SINGLE:
    427         fix_criteria_ptr->recurrence_type = RPC_LOC_SINGLE_FIX;
    428         break;
    429     case GPS_POSITION_RECURRENCE_PERIODIC:
    430     default:
    431         fix_criteria_ptr->recurrence_type = RPC_LOC_PERIODIC_FIX;
    432         break;
    433     }
    434     ioctl_data.disc = ioctl_type;
    435 
    436     ret_val = loc_eng_ioctl (client_handle,
    437                              ioctl_type,
    438                              &ioctl_data,
    439                              LOC_IOCTL_DEFAULT_TIMEOUT,
    440                              NULL /* No output information is expected*/);
    441 
    442     return convertErr(ret_val);
    443 }
    444 
    445 enum loc_api_adapter_err
    446 LocApiRpc::setTime(GpsUtcTime time, int64_t timeReference, int uncertainty)
    447 {
    448     rpc_loc_ioctl_data_u_type        ioctl_data;
    449     rpc_loc_assist_data_time_s_type *time_info_ptr;
    450     rpc_loc_ioctl_e_type             ioctl_type = RPC_LOC_IOCTL_INJECT_UTC_TIME;
    451     int                              ret_val;
    452 
    453     LOC_LOGD ("loc_eng_inject_time, uncertainty = %d\n", uncertainty);
    454 
    455     time_info_ptr = &ioctl_data.rpc_loc_ioctl_data_u_type_u.assistance_data_time;
    456     time_info_ptr->time_utc = time;
    457     time_info_ptr->time_utc += (int64_t)(ELAPSED_MILLIS_SINCE_BOOT_PLATFORM_LIB_ABSTRACTION - timeReference);
    458     time_info_ptr->uncertainty = uncertainty; // Uncertainty in ms
    459 
    460     ioctl_data.disc = ioctl_type;
    461 
    462     ret_val = loc_eng_ioctl (client_handle,
    463                              ioctl_type,
    464                              &ioctl_data,
    465                              LOC_IOCTL_DEFAULT_TIMEOUT,
    466                              NULL /* No output information is expected*/);
    467 
    468     return convertErr(ret_val);
    469 }
    470 
    471 enum loc_api_adapter_err
    472 LocApiRpc::injectPosition(double latitude, double longitude, float accuracy)
    473 {
    474     /* IOCTL data */
    475     rpc_loc_ioctl_data_u_type ioctl_data;
    476     rpc_loc_assist_data_pos_s_type *assistance_data_position =
    477         &ioctl_data.rpc_loc_ioctl_data_u_type_u.assistance_data_position;
    478     int                          ret_val;
    479 
    480     /************************************************
    481      * Fill in latitude, longitude & accuracy
    482      ************************************************/
    483 
    484     /* This combo is required */
    485     assistance_data_position->valid_mask =
    486         RPC_LOC_ASSIST_POS_VALID_LATITUDE |
    487         RPC_LOC_ASSIST_POS_VALID_LONGITUDE |
    488         RPC_LOC_ASSIST_POS_VALID_HOR_UNC_CIRCULAR |
    489         RPC_LOC_ASSIST_POS_VALID_CONFIDENCE_HORIZONTAL;
    490 
    491     assistance_data_position->latitude = latitude;
    492     assistance_data_position->longitude = longitude;
    493     assistance_data_position->hor_unc_circular = accuracy; /* Meters assumed */
    494     assistance_data_position->confidence_horizontal = 63;  /* 63% (1 std dev) assumed */
    495 
    496     /* Log */
    497     LOC_LOGD("Inject coarse position Lat=%lf, Lon=%lf, Acc=%.2lf\n",
    498              (double) assistance_data_position->latitude,
    499              (double) assistance_data_position->longitude,
    500              (double) assistance_data_position->hor_unc_circular);
    501 
    502     ret_val = loc_eng_ioctl( client_handle,
    503                              RPC_LOC_IOCTL_INJECT_POSITION,
    504                              &ioctl_data,
    505                              LOC_IOCTL_DEFAULT_TIMEOUT,
    506                              NULL /* No output information is expected*/);
    507     return convertErr(ret_val);
    508 }
    509 
    510 enum loc_api_adapter_err
    511 LocApiRpc::informNiResponse(GpsUserResponseType userResponse,
    512                                    const void* passThroughData)
    513 {
    514     rpc_loc_ioctl_data_u_type data;
    515     rpc_loc_ioctl_callback_s_type callback_payload;
    516 
    517     memcpy(&data.rpc_loc_ioctl_data_u_type_u.user_verify_resp.ni_event_pass_back,
    518            passThroughData, sizeof (rpc_loc_ni_event_s_type));
    519 
    520     rpc_loc_ni_user_resp_e_type resp;
    521     switch (userResponse)
    522     {
    523     case GPS_NI_RESPONSE_ACCEPT:
    524         data.rpc_loc_ioctl_data_u_type_u.user_verify_resp.user_resp =
    525             RPC_LOC_NI_LCS_NOTIFY_VERIFY_ACCEPT;
    526         break;
    527     case GPS_NI_RESPONSE_DENY:
    528         data.rpc_loc_ioctl_data_u_type_u.user_verify_resp.user_resp =
    529             RPC_LOC_NI_LCS_NOTIFY_VERIFY_DENY;
    530         break;
    531     case GPS_NI_RESPONSE_NORESP:
    532     default:
    533         data.rpc_loc_ioctl_data_u_type_u.user_verify_resp.user_resp =
    534             RPC_LOC_NI_LCS_NOTIFY_VERIFY_NORESP;
    535         break;
    536     }
    537 
    538     return convertErr(
    539         loc_eng_ioctl(client_handle,
    540                       RPC_LOC_IOCTL_INFORM_NI_USER_RESPONSE,
    541                       &data,
    542                       LOC_IOCTL_DEFAULT_TIMEOUT,
    543                       &callback_payload)
    544         );
    545 }
    546 
    547 enum loc_api_adapter_err
    548 LocApiRpc::setAPN(char* apn, int len, boolean force)
    549 {
    550     enum loc_api_adapter_err rtv = LOC_API_ADAPTER_ERR_SUCCESS;
    551     int size = sizeof(apnLastSet);
    552     if (force || memcmp(apnLastSet, apn, size)) {
    553         if (len < size) {
    554             // size will be not larger than its original value
    555             size = len + 1;
    556         }
    557         memcpy(apnLastSet, apn, size);
    558 
    559         if (!isInSession()) {
    560             rpc_loc_ioctl_data_u_type ioctl_data = {RPC_LOC_IOCTL_SET_LBS_APN_PROFILE, {0}};
    561             ioctl_data.rpc_loc_ioctl_data_u_type_u.apn_profiles[0].srv_system_type = LOC_APN_PROFILE_SRV_SYS_MAX;
    562             ioctl_data.rpc_loc_ioctl_data_u_type_u.apn_profiles[0].pdp_type = LOC_APN_PROFILE_PDN_TYPE_IPV4;
    563             memcpy(&(ioctl_data.rpc_loc_ioctl_data_u_type_u.apn_profiles[0].apn_name), apn, size);
    564 
    565             rtv = convertErr(
    566                 loc_eng_ioctl (client_handle,
    567                                RPC_LOC_IOCTL_SET_LBS_APN_PROFILE,
    568                                &ioctl_data,
    569                                LOC_IOCTL_DEFAULT_TIMEOUT,
    570                                NULL)
    571                 );
    572         }
    573     }
    574     return rtv;
    575 }
    576 
    577 void LocApiRpc::setInSession(bool inSession)
    578 {
    579     if (!inSession) {
    580         enableData(dataEnableLastSet, true);
    581         setAPN(apnLastSet, sizeof(apnLastSet)-1, true);
    582     }
    583 }
    584 
    585 enum loc_api_adapter_err
    586 LocApiRpc::setServer(const char* url, int len)
    587 {
    588     rpc_loc_ioctl_data_u_type         ioctl_data;
    589     rpc_loc_server_info_s_type       *server_info_ptr;
    590     rpc_loc_ioctl_e_type              ioctl_cmd;
    591 
    592     ioctl_cmd = RPC_LOC_IOCTL_SET_UMTS_SLP_SERVER_ADDR;
    593     ioctl_data.disc = ioctl_cmd;
    594     server_info_ptr = &ioctl_data.rpc_loc_ioctl_data_u_type_u.server_addr;
    595     server_info_ptr->addr_type = RPC_LOC_SERVER_ADDR_URL;
    596     server_info_ptr->addr_info.disc = server_info_ptr->addr_type;
    597     server_info_ptr->addr_info.rpc_loc_server_addr_u_type_u.url.length = len;
    598 #if (AMSS_VERSION==3200)
    599     server_info_ptr->addr_info.rpc_loc_server_addr_u_type_u.url.addr.addr_val = (char*) url;
    600     server_info_ptr->addr_info.rpc_loc_server_addr_u_type_u.url.addr.addr_len= len;
    601 #else
    602     strlcpy(server_info_ptr->addr_info.rpc_loc_server_addr_u_type_u.url.addr, url,
    603             sizeof server_info_ptr->addr_info.rpc_loc_server_addr_u_type_u.url.addr);
    604 #endif /* #if (AMSS_VERSION==3200) */
    605     LOC_LOGD ("loc_eng_set_server, addr = %s\n", url);
    606 
    607     return convertErr(
    608         loc_eng_ioctl (client_handle,
    609                        ioctl_cmd,
    610                        &ioctl_data,
    611                        LOC_IOCTL_DEFAULT_TIMEOUT,
    612                        NULL /* No output information is expected*/)
    613         );
    614 }
    615 
    616 enum loc_api_adapter_err
    617 LocApiRpc::setServer(unsigned int ip, int port, LocServerType type)
    618 {
    619     rpc_loc_ioctl_data_u_type         ioctl_data;
    620     rpc_loc_server_info_s_type       *server_info_ptr;
    621     rpc_loc_ioctl_e_type              ioctl_cmd;
    622 
    623     switch (type) {
    624     case LOC_AGPS_MPC_SERVER:
    625         ioctl_cmd = RPC_LOC_IOCTL_SET_CDMA_MPC_SERVER_ADDR;
    626         break;
    627     case LOC_AGPS_CUSTOM_PDE_SERVER:
    628         ioctl_cmd = RPC_LOC_IOCTL_SET_CUSTOM_PDE_SERVER_ADDR;
    629         break;
    630     default:
    631         ioctl_cmd = RPC_LOC_IOCTL_SET_CDMA_PDE_SERVER_ADDR;
    632         break;
    633     }
    634     ioctl_data.disc = ioctl_cmd;
    635     server_info_ptr = &ioctl_data.rpc_loc_ioctl_data_u_type_u.server_addr;
    636     server_info_ptr->addr_type = RPC_LOC_SERVER_ADDR_IPV4;
    637     server_info_ptr->addr_info.disc = server_info_ptr->addr_type;
    638     server_info_ptr->addr_info.rpc_loc_server_addr_u_type_u.ipv4.addr = ip;
    639     server_info_ptr->addr_info.rpc_loc_server_addr_u_type_u.ipv4.port = port;
    640     LOC_LOGD ("setServer, addr = %X:%d\n", (unsigned int) ip, (unsigned int) port);
    641 
    642     return convertErr(
    643         loc_eng_ioctl (client_handle,
    644                        ioctl_cmd,
    645                        &ioctl_data,
    646                        LOC_IOCTL_DEFAULT_TIMEOUT,
    647                        NULL /* No output information is expected*/)
    648         );
    649 }
    650 
    651 enum loc_api_adapter_err
    652 LocApiRpc::enableData(int enable, boolean force)
    653 {
    654     enum loc_api_adapter_err rtv = LOC_API_ADAPTER_ERR_SUCCESS;
    655     if (force || dataEnableLastSet != enable) {
    656         dataEnableLastSet = enable;
    657 
    658         if (!isInSession()) {
    659             rpc_loc_ioctl_data_u_type ioctl_data = {RPC_LOC_IOCTL_SET_DATA_ENABLE, {0}};
    660 
    661             ioctl_data.rpc_loc_ioctl_data_u_type_u.data_enable = enable;
    662             rtv =  convertErr(
    663                 loc_eng_ioctl (client_handle,
    664                                RPC_LOC_IOCTL_SET_DATA_ENABLE,
    665                                &ioctl_data,
    666                                LOC_IOCTL_DEFAULT_TIMEOUT,
    667                                NULL)
    668                 );
    669         }
    670     }
    671     return rtv;
    672 }
    673 
    674 enum loc_api_adapter_err
    675 LocApiRpc::deleteAidingData(GpsAidingData bits)
    676 {
    677     rpc_loc_ioctl_data_u_type ioctl_data = {RPC_LOC_IOCTL_DELETE_ASSIST_DATA, {0}};
    678     ioctl_data.rpc_loc_ioctl_data_u_type_u.assist_data_delete.type = bits;
    679 
    680     return convertErr(
    681         loc_eng_ioctl (client_handle,
    682                        RPC_LOC_IOCTL_DELETE_ASSIST_DATA,
    683                        &ioctl_data,
    684                        LOC_IOCTL_DEFAULT_TIMEOUT,
    685                        NULL)
    686         );
    687 }
    688 
    689 void LocApiRpc::reportPosition(const rpc_loc_parsed_position_s_type *location_report_ptr)
    690 {
    691     LocPosTechMask tech_Mask = LOC_POS_TECH_MASK_DEFAULT;
    692 
    693     UlpLocation location = {0};
    694     GpsLocationExtended locationExtended = {0};
    695 
    696     location.size = sizeof(location);
    697     locationExtended.size = sizeof(locationExtended);
    698     if (location_report_ptr->valid_mask & RPC_LOC_POS_VALID_SESSION_STATUS)
    699     {
    700         // Process the position from final and intermediate reports
    701         if (location_report_ptr->session_status == RPC_LOC_SESS_STATUS_SUCCESS ||
    702             location_report_ptr->session_status == RPC_LOC_SESS_STATUS_IN_PROGESS)
    703         {
    704             // Latitude & Longitude
    705             if ((location_report_ptr->valid_mask & RPC_LOC_POS_VALID_LATITUDE) &&
    706                 (location_report_ptr->valid_mask & RPC_LOC_POS_VALID_LONGITUDE) &&
    707                 (location_report_ptr->latitude != 0 ||
    708                  location_report_ptr->longitude != 0))
    709             {
    710                 location.gpsLocation.flags    |= GPS_LOCATION_HAS_LAT_LONG;
    711                 location.gpsLocation.latitude  = location_report_ptr->latitude;
    712                 location.gpsLocation.longitude = location_report_ptr->longitude;
    713 
    714                 // Time stamp (UTC)
    715                 if (location_report_ptr->valid_mask & RPC_LOC_POS_VALID_TIMESTAMP_UTC)
    716                 {
    717                     location.gpsLocation.timestamp = location_report_ptr->timestamp_utc;
    718                 }
    719 
    720                 // Altitude
    721                 if (location_report_ptr->valid_mask &  RPC_LOC_POS_VALID_ALTITUDE_WRT_ELLIPSOID )
    722                 {
    723                     location.gpsLocation.flags    |= GPS_LOCATION_HAS_ALTITUDE;
    724                     location.gpsLocation.altitude = location_report_ptr->altitude_wrt_ellipsoid;
    725                 }
    726 
    727                 // Speed
    728                 if (location_report_ptr->valid_mask & RPC_LOC_POS_VALID_SPEED_HORIZONTAL)
    729                 {
    730                     location.gpsLocation.flags    |= GPS_LOCATION_HAS_SPEED;
    731                     location.gpsLocation.speed = location_report_ptr->speed_horizontal;
    732                 }
    733 
    734                 // Heading
    735                 if (location_report_ptr->valid_mask &  RPC_LOC_POS_VALID_HEADING)
    736                 {
    737                     location.gpsLocation.flags    |= GPS_LOCATION_HAS_BEARING;
    738                     location.gpsLocation.bearing = location_report_ptr->heading;
    739                 }
    740 
    741                 // Uncertainty (circular)
    742                 if ( (location_report_ptr->valid_mask & RPC_LOC_POS_VALID_HOR_UNC_CIRCULAR) )
    743                 {
    744                     location.gpsLocation.flags    |= GPS_LOCATION_HAS_ACCURACY;
    745                     location.gpsLocation.accuracy = location_report_ptr->hor_unc_circular;
    746                 }
    747 
    748                 // Technology Mask
    749 
    750                 tech_Mask  |= location_report_ptr->technology_mask;
    751                 //Mark the location source as from GNSS
    752                 location.gpsLocation.flags |= LOCATION_HAS_SOURCE_INFO;
    753                 location.position_source = ULP_LOCATION_IS_FROM_GNSS;
    754                 if (location_report_ptr->valid_mask & RPC_LOC_POS_VALID_ALTITUDE_WRT_MEAN_SEA_LEVEL)
    755                 {
    756                     locationExtended.flags |= GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL;
    757                     locationExtended.altitudeMeanSeaLevel = location_report_ptr->altitude_wrt_mean_sea_level;
    758                 }
    759 
    760                 if (location_report_ptr->valid_mask &  RPC_LOC_POS_VALID_MAGNETIC_VARIATION )
    761                 {
    762                     locationExtended.flags |= GPS_LOCATION_EXTENDED_HAS_MAG_DEV;
    763                     locationExtended.magneticDeviation = location_report_ptr->magnetic_deviation;
    764                 }
    765 
    766                 if (location_report_ptr->valid_mask & RPC_LOC_POS_VALID_VERTICAL_UNC)
    767                 {
    768                    locationExtended.flags |= GPS_LOCATION_EXTENDED_HAS_VERT_UNC;
    769                    locationExtended.vert_unc = location_report_ptr->vert_unc;
    770                 }
    771 
    772                 if (location_report_ptr->valid_mask & RPC_LOC_POS_VALID_SPEED_UNC)
    773                 {
    774                    locationExtended.flags |= GPS_LOCATION_EXTENDED_HAS_SPEED_UNC;
    775                    locationExtended.speed_unc = location_report_ptr->speed_unc;
    776                 }
    777 
    778                 LOC_LOGV("reportPosition: fire callback\n");
    779                 enum loc_sess_status fixStatus =
    780                     (location_report_ptr->session_status
    781                      == RPC_LOC_SESS_STATUS_IN_PROGESS ?
    782                      LOC_SESS_INTERMEDIATE : LOC_SESS_SUCCESS);
    783                 LocApiBase::reportPosition(location,
    784                                            locationExtended,
    785                                            (void*)location_report_ptr,
    786                                            fixStatus,
    787                                            tech_Mask);
    788             }
    789         }
    790         else
    791         {
    792             LocApiBase::reportPosition(location,
    793                                        locationExtended,
    794                                        NULL,
    795                                        LOC_SESS_FAILURE);
    796             LOC_LOGV("loc_eng_report_position: ignore position report "
    797                      "when session status = %d\n",
    798                      location_report_ptr->session_status);
    799         }
    800     }
    801     else
    802     {
    803         LOC_LOGV("loc_eng_report_position: ignore position report "
    804                  "when session status is not set\n");
    805     }
    806 }
    807 
    808 void LocApiRpc::reportSv(const rpc_loc_gnss_info_s_type *gnss_report_ptr)
    809 {
    810     QtiGnssSvStatus     SvStatus = {0};
    811     GpsLocationExtended locationExtended = {0};
    812     locationExtended.size = sizeof(locationExtended);
    813     int             num_svs_max = 0;
    814     const rpc_loc_sv_info_s_type *sv_info_ptr;
    815 
    816     if (gnss_report_ptr->valid_mask & RPC_LOC_GNSS_INFO_VALID_SV_COUNT)
    817     {
    818         num_svs_max = gnss_report_ptr->sv_count;
    819         if (num_svs_max > GPS_MAX_SVS)
    820         {
    821             num_svs_max = GPS_MAX_SVS;
    822         }
    823     }
    824 
    825     if (gnss_report_ptr->valid_mask & RPC_LOC_GNSS_INFO_VALID_SV_LIST)
    826     {
    827         SvStatus.num_svs = 0;
    828 
    829         for (int i = 0; i < num_svs_max; i++)
    830         {
    831             sv_info_ptr = &(gnss_report_ptr->sv_list.sv_list_val[i]);
    832             if (sv_info_ptr->valid_mask & RPC_LOC_SV_INFO_VALID_SYSTEM)
    833             {
    834                 if (sv_info_ptr->system == RPC_LOC_SV_SYSTEM_GPS)
    835                 {
    836                     SvStatus.sv_list[SvStatus.num_svs].size = sizeof(GpsSvInfo);
    837                     SvStatus.sv_list[SvStatus.num_svs].prn = sv_info_ptr->prn;
    838 
    839                     // We only have the data field to report gps eph and alm mask
    840                     if ((sv_info_ptr->valid_mask & RPC_LOC_SV_INFO_VALID_HAS_EPH) &&
    841                         (sv_info_ptr->has_eph == 1))
    842                     {
    843                         SvStatus.ephemeris_mask |= (1 << (sv_info_ptr->prn-1));
    844                     }
    845 
    846                     if ((sv_info_ptr->valid_mask & RPC_LOC_SV_INFO_VALID_HAS_ALM) &&
    847                         (sv_info_ptr->has_alm == 1))
    848                     {
    849                         SvStatus.almanac_mask |= (1 << (sv_info_ptr->prn-1));
    850                     }
    851 
    852                     if ((sv_info_ptr->valid_mask & RPC_LOC_SV_INFO_VALID_PROCESS_STATUS) &&
    853                         (sv_info_ptr->process_status == RPC_LOC_SV_STATUS_TRACK))
    854                     {
    855                         SvStatus.gps_used_in_fix_mask |= (1 << (sv_info_ptr->prn-1));
    856                     }
    857                 }
    858                 // SBAS: GPS RPN: 120-151,
    859                 // In exteneded measurement report, we follow nmea standard, which is from 33-64.
    860                 else if (sv_info_ptr->system == RPC_LOC_SV_SYSTEM_SBAS)
    861                 {
    862                     SvStatus.sv_list[SvStatus.num_svs].prn = sv_info_ptr->prn + 33 - 120;
    863                 }
    864                 // Gloness: Slot id: 1-32
    865                 // In extended measurement report, we follow nmea standard, which is 65-96
    866                 else if (sv_info_ptr->system == RPC_LOC_SV_SYSTEM_GLONASS)
    867                 {
    868                     if ((sv_info_ptr->valid_mask & RPC_LOC_SV_INFO_VALID_PROCESS_STATUS) &&
    869                         (sv_info_ptr->process_status == RPC_LOC_SV_STATUS_TRACK))
    870                     {
    871                         SvStatus.glo_used_in_fix_mask |= (1 << (sv_info_ptr->prn-1));
    872                     }
    873 
    874                     SvStatus.sv_list[SvStatus.num_svs].prn = sv_info_ptr->prn + (65-1);
    875                 }
    876                 // Unsupported SV system
    877                 else
    878                 {
    879                     continue;
    880                 }
    881             }
    882 
    883             if (sv_info_ptr->valid_mask & RPC_LOC_SV_INFO_VALID_SNR)
    884             {
    885                 SvStatus.sv_list[SvStatus.num_svs].snr = sv_info_ptr->snr;
    886             }
    887 
    888             if (sv_info_ptr->valid_mask & RPC_LOC_SV_INFO_VALID_ELEVATION)
    889             {
    890                 SvStatus.sv_list[SvStatus.num_svs].elevation = sv_info_ptr->elevation;
    891             }
    892 
    893             if (sv_info_ptr->valid_mask & RPC_LOC_SV_INFO_VALID_AZIMUTH)
    894             {
    895                 SvStatus.sv_list[SvStatus.num_svs].azimuth = sv_info_ptr->azimuth;
    896             }
    897 
    898             SvStatus.num_svs++;
    899         }
    900     }
    901 
    902     if ((gnss_report_ptr->valid_mask & RPC_LOC_GNSS_INFO_VALID_POS_DOP) &&
    903         (gnss_report_ptr->valid_mask & RPC_LOC_GNSS_INFO_VALID_HOR_DOP) &&
    904         (gnss_report_ptr->valid_mask & RPC_LOC_GNSS_INFO_VALID_VERT_DOP))
    905     {
    906         locationExtended.flags |= GPS_LOCATION_EXTENDED_HAS_DOP;
    907         locationExtended.pdop = gnss_report_ptr->position_dop;
    908         locationExtended.hdop = gnss_report_ptr->horizontal_dop;
    909         locationExtended.vdop = gnss_report_ptr->vertical_dop;
    910     }
    911 
    912     if (SvStatus.num_svs >= 0)
    913     {
    914         LocApiBase::reportSv(SvStatus,
    915                              locationExtended,
    916                              (void*)gnss_report_ptr);
    917     }
    918 }
    919 
    920 void LocApiRpc::reportStatus(const rpc_loc_status_event_s_type *status_report_ptr)
    921 {
    922 
    923     if (status_report_ptr->event == RPC_LOC_STATUS_EVENT_ENGINE_STATE) {
    924         if (status_report_ptr->payload.rpc_loc_status_event_payload_u_type_u.engine_state == RPC_LOC_ENGINE_STATE_ON)
    925         {
    926             LocApiBase::reportStatus(GPS_STATUS_ENGINE_ON);
    927             LocApiBase::reportStatus(GPS_STATUS_SESSION_BEGIN);
    928         }
    929         else if (status_report_ptr->payload.rpc_loc_status_event_payload_u_type_u.engine_state == RPC_LOC_ENGINE_STATE_OFF)
    930         {
    931             LocApiBase::reportStatus(GPS_STATUS_SESSION_END);
    932             LocApiBase::reportStatus(GPS_STATUS_ENGINE_OFF);
    933         }
    934         else
    935         {
    936             LocApiBase::reportStatus(GPS_STATUS_NONE);
    937         }
    938     }
    939 
    940 }
    941 
    942 void LocApiRpc::reportNmea(const rpc_loc_nmea_report_s_type *nmea_report_ptr)
    943 {
    944 
    945 #if (AMSS_VERSION==3200)
    946     LocApiBase::reportNmea(nmea_report_ptr->nmea_sentences.nmea_sentences_val,
    947                            nmea_report_ptr->nmea_sentences.nmea_sentences_len);
    948 #else
    949     LocApiBase::reportNmea(nmea_report_ptr->nmea_sentences,
    950                            nmea_report_ptr->length);
    951     LOC_LOGD("loc_eng_report_nmea: $%c%c%c\n",
    952              nmea_report_ptr->nmea_sentences[3],
    953              nmea_report_ptr->nmea_sentences[4],
    954              nmea_report_ptr->nmea_sentences[5]);
    955 #endif /* #if (AMSS_VERSION==3200) */
    956 }
    957 
    958 enum loc_api_adapter_err
    959 LocApiRpc::setXtraData(char* data, int length)
    960 {
    961     int     rpc_ret_val = RPC_LOC_API_GENERAL_FAILURE;
    962     int     total_parts;
    963     uint8   part;
    964     uint16  part_len;
    965     uint16  len_injected;
    966     rpc_loc_ioctl_data_u_type            ioctl_data;
    967     rpc_loc_ioctl_e_type                 ioctl_type = RPC_LOC_IOCTL_INJECT_PREDICTED_ORBITS_DATA;
    968     rpc_loc_predicted_orbits_data_s_type *predicted_orbits_data_ptr;
    969 
    970     LOC_LOGD("qct_loc_eng_inject_xtra_data, xtra size = %d, data ptr = 0x%lx\n", length, (long) data);
    971 
    972     predicted_orbits_data_ptr = &ioctl_data.rpc_loc_ioctl_data_u_type_u.predicted_orbits_data;
    973     predicted_orbits_data_ptr->format_type = RPC_LOC_PREDICTED_ORBITS_XTRA;
    974     predicted_orbits_data_ptr->total_size = length;
    975     total_parts = (length - 1) / XTRA_BLOCK_SIZE + 1;
    976     predicted_orbits_data_ptr->total_parts = total_parts;
    977 
    978     len_injected = 0; // O bytes injected
    979     ioctl_data.disc = ioctl_type;
    980 
    981     // XTRA injection starts with part 1
    982     for (part = 1; part <= total_parts; part++)
    983     {
    984         predicted_orbits_data_ptr->part = part;
    985         predicted_orbits_data_ptr->part_len = XTRA_BLOCK_SIZE;
    986         if (XTRA_BLOCK_SIZE > (length - len_injected))
    987         {
    988             predicted_orbits_data_ptr->part_len = length - len_injected;
    989         }
    990         predicted_orbits_data_ptr->data_ptr.data_ptr_len = predicted_orbits_data_ptr->part_len;
    991         predicted_orbits_data_ptr->data_ptr.data_ptr_val = data + len_injected;
    992 
    993         LOC_LOGD("qct_loc_eng_inject_xtra_data, part %d/%d, len = %d, total = %d\n",
    994                  predicted_orbits_data_ptr->part,
    995                  total_parts,
    996                  predicted_orbits_data_ptr->part_len,
    997                  len_injected);
    998 
    999         if (part < total_parts)
   1000         {
   1001             // No callback in this case
   1002             rpc_ret_val = loc_ioctl (client_handle,
   1003                                      ioctl_type,
   1004                                      &ioctl_data);
   1005 
   1006             if (rpc_ret_val != RPC_LOC_API_SUCCESS)
   1007             {
   1008                 LOC_LOGE("loc_ioctl for xtra error: %s\n", loc_get_ioctl_status_name(rpc_ret_val));
   1009                 break;
   1010             }
   1011             //Add a delay of 10 ms so that repeated RPC calls dont starve the modem processor
   1012             usleep(10 * 1000);
   1013         }
   1014         else // part == total_parts
   1015         {
   1016             // Last part injection, will need to wait for callback
   1017             if (!loc_eng_ioctl(client_handle,
   1018                                ioctl_type,
   1019                                &ioctl_data,
   1020                                LOC_XTRA_INJECT_DEFAULT_TIMEOUT,
   1021                                NULL))
   1022             {
   1023                 rpc_ret_val = RPC_LOC_API_GENERAL_FAILURE;
   1024             }
   1025             break; // done with injection
   1026         }
   1027 
   1028         len_injected += predicted_orbits_data_ptr->part_len;
   1029         LOC_LOGD("loc_ioctl XTRA injected length: %d\n", len_injected);
   1030     }
   1031 
   1032     return convertErr(rpc_ret_val);
   1033 }
   1034 
   1035 /* Request the Xtra Server Url from the modem */
   1036 enum loc_api_adapter_err
   1037 LocApiRpc::requestXtraServer()
   1038 {
   1039     loc_api_adapter_err           err;
   1040     rpc_loc_ioctl_data_u_type     data;
   1041     rpc_loc_ioctl_callback_s_type callback_data;
   1042 
   1043     err = convertErr(loc_eng_ioctl(client_handle,
   1044                                    RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_SOURCE,
   1045                                    &data,
   1046                                    LOC_IOCTL_DEFAULT_TIMEOUT,
   1047                                    &callback_data));
   1048 
   1049     if (LOC_API_ADAPTER_ERR_SUCCESS != err)
   1050     {
   1051         LOC_LOGE("RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_SOURCE failed!: err=%d\n", err);
   1052         return err;
   1053     }
   1054     else if (RPC_LOC_SESS_STATUS_SUCCESS != callback_data.status)
   1055     {
   1056         LOC_LOGE("RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_SOURCE failed!: status=%ld\n", callback_data.status);
   1057         return LOC_API_ADAPTER_ERR_GENERAL_FAILURE;
   1058     }
   1059     else if (RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_SOURCE != callback_data.type)
   1060     {
   1061         LOC_LOGE("RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_SOURCE is not the type expected! type=%d\n", callback_data.type);
   1062         return LOC_API_ADAPTER_ERR_GENERAL_FAILURE;
   1063     }
   1064     else if (RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_SOURCE != callback_data.data.disc)
   1065     {
   1066         LOC_LOGE("RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_SOURCE is not the disc expected! disc=%d\n", callback_data.data.disc);
   1067         return LOC_API_ADAPTER_ERR_GENERAL_FAILURE;
   1068     }
   1069 
   1070     reportXtraServer(callback_data.data.rpc_loc_ioctl_callback_data_u_type_u.
   1071                      predicted_orbits_data_source.servers[0],
   1072                      callback_data.data.rpc_loc_ioctl_callback_data_u_type_u.
   1073                      predicted_orbits_data_source.servers[1],
   1074                      callback_data.data.rpc_loc_ioctl_callback_data_u_type_u.
   1075                      predicted_orbits_data_source.servers[2],
   1076                      255);
   1077 
   1078     return LOC_API_ADAPTER_ERR_SUCCESS;
   1079 }
   1080 
   1081 enum loc_api_adapter_err
   1082 LocApiRpc::atlOpenStatus(int handle, int is_succ, char* apn, AGpsBearerType bearer, AGpsType agpsType)
   1083 {
   1084     rpc_loc_server_open_status_e_type open_status = is_succ ? RPC_LOC_SERVER_OPEN_SUCCESS : RPC_LOC_SERVER_OPEN_FAIL;
   1085    rpc_loc_ioctl_data_u_type           ioctl_data;
   1086 
   1087     if (AGPS_TYPE_INVALID == agpsType) {
   1088         rpc_loc_server_open_status_s_type  *conn_open_status_ptr =
   1089             &ioctl_data.rpc_loc_ioctl_data_u_type_u.conn_open_status;
   1090 
   1091         // Fill in data
   1092         ioctl_data.disc = RPC_LOC_IOCTL_INFORM_SERVER_OPEN_STATUS;
   1093         conn_open_status_ptr->conn_handle = handle;
   1094         conn_open_status_ptr->open_status = open_status;
   1095 #if (AMSS_VERSION==3200)
   1096         conn_open_status_ptr->apn_name = apn; /* requires APN */
   1097 #else
   1098         if (is_succ) {
   1099             strlcpy(conn_open_status_ptr->apn_name, apn,
   1100                     sizeof conn_open_status_ptr->apn_name);
   1101         } else {
   1102             conn_open_status_ptr->apn_name[0] = 0;
   1103         }
   1104 #endif /* #if (AMSS_VERSION==3200) */
   1105 
   1106         LOC_LOGD("ATL RPC_LOC_IOCTL_INFORM_SERVER_OPEN_STATUS open %s, APN name = [%s]\n",
   1107                  log_succ_fail_string(is_succ),
   1108                  apn);
   1109     } else {
   1110         rpc_loc_server_multi_open_status_s_type  *conn_multi_open_status_ptr =
   1111             &ioctl_data.rpc_loc_ioctl_data_u_type_u.multi_conn_open_status;
   1112 
   1113         // Fill in data
   1114         ioctl_data.disc = RPC_LOC_IOCTL_INFORM_SERVER_MULTI_OPEN_STATUS;
   1115         conn_multi_open_status_ptr->conn_handle = handle;
   1116         conn_multi_open_status_ptr->open_status = open_status;
   1117         if (is_succ) {
   1118             strlcpy(conn_multi_open_status_ptr->apn_name, apn,
   1119                     sizeof conn_multi_open_status_ptr->apn_name);
   1120         } else {
   1121             conn_multi_open_status_ptr->apn_name[0] = 0;
   1122         }
   1123 
   1124         switch(bearer)
   1125         {
   1126         case AGPS_APN_BEARER_IPV4:
   1127             conn_multi_open_status_ptr->pdp_type = RPC_LOC_SERVER_PDP_IP;
   1128             break;
   1129         case AGPS_APN_BEARER_IPV6:
   1130             conn_multi_open_status_ptr->pdp_type = RPC_LOC_SERVER_PDP_IPV6;
   1131             break;
   1132         case AGPS_APN_BEARER_IPV4V6:
   1133             conn_multi_open_status_ptr->pdp_type = RPC_LOC_SERVER_PDP_IPV4V6;
   1134             break;
   1135         default:
   1136             conn_multi_open_status_ptr->pdp_type = RPC_LOC_SERVER_PDP_PPP;
   1137         }
   1138 
   1139         LOC_LOGD("ATL RPC_LOC_IOCTL_INFORM_SERVER_MULTI_OPEN_STATUS open %s, APN name = [%s], pdp_type = %d\n",
   1140                  log_succ_fail_string(is_succ),
   1141                  apn,
   1142                  conn_multi_open_status_ptr->pdp_type);
   1143     }
   1144 
   1145     // Make the IOCTL call
   1146     return convertErr(
   1147         loc_eng_ioctl(client_handle,
   1148                       ioctl_data.disc,
   1149                       &ioctl_data,
   1150                       LOC_IOCTL_DEFAULT_TIMEOUT,
   1151                       NULL)
   1152         );
   1153 }
   1154 
   1155 enum loc_api_adapter_err
   1156 LocApiRpc::atlCloseStatus(int handle, int is_succ)
   1157 {
   1158     rpc_loc_ioctl_data_u_type           ioctl_data;
   1159     ioctl_data.disc = RPC_LOC_IOCTL_INFORM_SERVER_CLOSE_STATUS;
   1160 
   1161     rpc_loc_server_close_status_s_type *conn_close_status_ptr =
   1162         &ioctl_data.rpc_loc_ioctl_data_u_type_u.conn_close_status;
   1163     conn_close_status_ptr->conn_handle = handle;
   1164     conn_close_status_ptr->close_status = is_succ ? RPC_LOC_SERVER_CLOSE_SUCCESS : RPC_LOC_SERVER_CLOSE_FAIL;
   1165 
   1166     // Make the IOCTL call
   1167     return convertErr(
   1168         loc_eng_ioctl(client_handle,
   1169                       ioctl_data.disc,
   1170                       &ioctl_data,
   1171                       LOC_IOCTL_DEFAULT_TIMEOUT,
   1172                       NULL)
   1173         );
   1174 }
   1175 
   1176 void LocApiRpc::ATLEvent(const rpc_loc_server_request_s_type *server_request_ptr)
   1177 {
   1178     int connHandle;
   1179     AGpsType agps_type;
   1180 
   1181     LOC_LOGV("RPC_LOC_EVENT_ASSISTANCE_DATA_REQUEST event %s)",
   1182              loc_get_event_atl_open_name(server_request_ptr->event));
   1183     switch (server_request_ptr->event)
   1184     {
   1185     case RPC_LOC_SERVER_REQUEST_MULTI_OPEN:
   1186         connHandle = server_request_ptr->payload.rpc_loc_server_request_u_type_u.multi_open_req.conn_handle;
   1187         if (server_request_ptr->payload.rpc_loc_server_request_u_type_u.multi_open_req.connection_type
   1188             == RPC_LOC_SERVER_CONNECTION_LBS) {
   1189             agps_type = AGPS_TYPE_SUPL;
   1190             LOC_LOGV("ATLEvent: event - RPC_LOC_SERVER_REQUEST_MULTI_OPEN\n            type - AGPS_TYPE_SUPL\n            handle - %d", connHandle);
   1191         } else {
   1192             agps_type = AGPS_TYPE_WWAN_ANY;
   1193             LOC_LOGV("ATLEvent: event - RPC_LOC_SERVER_REQUEST_MULTI_OPEN\n            type - AGPS_TYPE_WWAN_ANY\n            handle - %d", connHandle);
   1194         }
   1195         requestATL(connHandle, agps_type);
   1196         break;
   1197     case RPC_LOC_SERVER_REQUEST_OPEN:
   1198         connHandle = server_request_ptr->payload.rpc_loc_server_request_u_type_u.open_req.conn_handle;
   1199         LOC_LOGV("ATLEvent: event - RPC_LOC_SERVER_REQUEST_OPEN\n            handle - %d", connHandle);
   1200         requestATL(connHandle, AGPS_TYPE_INVALID);
   1201         break;
   1202     case RPC_LOC_SERVER_REQUEST_CLOSE:
   1203         connHandle = server_request_ptr->payload.rpc_loc_server_request_u_type_u.close_req.conn_handle;
   1204         LOC_LOGV("ATLEvent: event - RPC_LOC_SERVER_REQUEST_CLOSE\n            handle - %d", connHandle);
   1205         releaseATL(connHandle);
   1206         break;
   1207     default:
   1208         LOC_LOGE("ATLEvent: event type %d invalid", server_request_ptr->event);
   1209    }
   1210 }
   1211 
   1212 void LocApiRpc::NIEvent(const rpc_loc_ni_event_s_type *ni_req)
   1213 {
   1214     GpsNiNotification notif = {0};
   1215 
   1216     switch (ni_req->event)
   1217     {
   1218     case RPC_LOC_NI_EVENT_VX_NOTIFY_VERIFY_REQ:
   1219     {
   1220         const rpc_loc_ni_vx_notify_verify_req_s_type *vx_req =
   1221             &ni_req->payload.rpc_loc_ni_event_payload_u_type_u.vx_req;
   1222         LOC_LOGI("VX Notification");
   1223         notif.ni_type = GPS_NI_TYPE_VOICE;
   1224         // Requestor ID
   1225         hexcode(notif.requestor_id, sizeof notif.requestor_id,
   1226                 vx_req->requester_id.requester_id,
   1227                 vx_req->requester_id.requester_id_length);
   1228         notif.text_encoding = 0; // No text and no encoding
   1229         notif.requestor_id_encoding = convertNiEncodingType(vx_req->encoding_scheme);
   1230         NIEventFillVerfiyType(notif, vx_req->notification_priv_type);
   1231     }
   1232         break;
   1233 
   1234     case RPC_LOC_NI_EVENT_UMTS_CP_NOTIFY_VERIFY_REQ:
   1235     {
   1236         const rpc_loc_ni_umts_cp_notify_verify_req_s_type *umts_cp_req =
   1237             &ni_req->payload.rpc_loc_ni_event_payload_u_type_u.umts_cp_req;
   1238         LOC_LOGI("UMTS CP Notification\n");
   1239         notif.ni_type= GPS_NI_TYPE_UMTS_CTRL_PLANE;         // Stores notification text
   1240 #if (AMSS_VERSION==3200)
   1241         hexcode(notif.text, sizeof notif.text,
   1242                 umts_cp_req->notification_text.notification_text_val,
   1243                 umts_cp_req->notification_length);
   1244         hexcode(notif.requestor_id, sizeof notif.requestor_id,
   1245                 umts_cp_req->requestor_id.requestor_id_string.requestor_id_string_val,
   1246                 umts_cp_req->requestor_id.string_len);
   1247 #else
   1248         hexcode(notif.text, sizeof notif.text,
   1249                 umts_cp_req->notification_text,
   1250                 umts_cp_req->notification_length);
   1251         hexcode(notif.requestor_id, sizeof notif.requestor_id,
   1252                 umts_cp_req->requestor_id.requestor_id_string,
   1253                 umts_cp_req->requestor_id.string_len);
   1254 #endif
   1255         notif.text_encoding = convertNiEncodingType(umts_cp_req->datacoding_scheme);
   1256         notif.requestor_id_encoding = notif.text_encoding;
   1257         NIEventFillVerfiyType(notif, umts_cp_req->notification_priv_type);
   1258 
   1259         // LCS address (using extras field)
   1260         if (umts_cp_req->ext_client_address_data.ext_client_address_len != 0)
   1261         {
   1262             // Copy LCS Address into notif.extras in the format: Address = 012345
   1263             strlcat(notif.extras, LOC_NI_NOTIF_KEY_ADDRESS, sizeof notif.extras);
   1264             strlcat(notif.extras, " = ", sizeof notif.extras);
   1265             int addr_len = 0;
   1266             const char *address_source = NULL;
   1267 
   1268 #if (AMSS_VERSION==3200)
   1269             address_source = umts_cp_req->ext_client_address_data.ext_client_address.ext_client_address_val;
   1270 #else
   1271             address_source = umts_cp_req->ext_client_address_data.ext_client_address;
   1272 #endif /* #if (AMSS_VERSION==3200) */
   1273 
   1274             char lcs_addr[32]; // Decoded LCS address for UMTS CP NI
   1275             addr_len = decodeAddress(lcs_addr, sizeof lcs_addr, address_source,
   1276                                      umts_cp_req->ext_client_address_data.ext_client_address_len);
   1277 
   1278             // The address is ASCII string
   1279             if (addr_len)
   1280             {
   1281                 strlcat(notif.extras, lcs_addr, sizeof notif.extras);
   1282             }
   1283         }
   1284     }
   1285         break;
   1286 
   1287     case RPC_LOC_NI_EVENT_SUPL_NOTIFY_VERIFY_REQ:
   1288     {
   1289         const rpc_loc_ni_supl_notify_verify_req_s_type *supl_req =
   1290             &ni_req->payload.rpc_loc_ni_event_payload_u_type_u.supl_req;
   1291         LOC_LOGI("SUPL Notification\n");
   1292         notif.ni_type = GPS_NI_TYPE_UMTS_SUPL;
   1293 
   1294         if (supl_req->flags & RPC_LOC_NI_CLIENT_NAME_PRESENT)
   1295         {
   1296 #if (AMSS_VERSION==3200)
   1297             hexcode(notif.text, sizeof notif.text,
   1298                     supl_req->client_name.client_name_string.client_name_string_val,   /* buffer */
   1299                     supl_req->client_name.string_len                                   /* length */
   1300             );
   1301 #else
   1302             hexcode(notif.text, sizeof notif.text,
   1303                             supl_req->client_name.client_name_string,   /* buffer */
   1304                             supl_req->client_name.string_len            /* length */
   1305             );
   1306 #endif /* #if (AMSS_VERSION==3200) */
   1307             LOC_LOGV("SUPL NI: client_name: %s len=%d", notif.text, supl_req->client_name.string_len);
   1308         }
   1309         else {
   1310             LOC_LOGV("SUPL NI: client_name not present.");
   1311         }
   1312 
   1313         // Requestor ID
   1314         if (supl_req->flags & RPC_LOC_NI_REQUESTOR_ID_PRESENT)
   1315         {
   1316 #if (AMSS_VERSION==3200)
   1317             hexcode(notif.requestor_id, sizeof notif.requestor_id,
   1318                     supl_req->requestor_id.requestor_id_string.requestor_id_string_val,  /* buffer */
   1319                     supl_req->requestor_id.string_len                                    /* length */
   1320                 );
   1321 #else
   1322             hexcode(notif.requestor_id, sizeof notif.requestor_id,
   1323                     supl_req->requestor_id.requestor_id_string,  /* buffer */
   1324                     supl_req->requestor_id.string_len            /* length */
   1325                 );
   1326 #endif /* #if (AMSS_VERSION==3200) */
   1327             LOC_LOGV("SUPL NI: requestor_id: %s len=%d", notif.requestor_id, supl_req->requestor_id.string_len);
   1328         }
   1329         else {
   1330             LOC_LOGV("SUPL NI: requestor_id not present.");
   1331         }
   1332 
   1333         // Encoding type
   1334         if (supl_req->flags & RPC_LOC_NI_ENCODING_TYPE_PRESENT)
   1335         {
   1336             notif.text_encoding = convertNiEncodingType(supl_req->datacoding_scheme);
   1337             notif.requestor_id_encoding = notif.text_encoding;
   1338         }
   1339         else {
   1340             notif.text_encoding = notif.requestor_id_encoding = GPS_ENC_UNKNOWN;
   1341         }
   1342 
   1343         NIEventFillVerfiyType(notif, ni_req->payload.rpc_loc_ni_event_payload_u_type_u.supl_req.notification_priv_type);
   1344     }
   1345         break;
   1346 
   1347     default:
   1348         LOC_LOGE("Unknown NI event: %x\n", (int) ni_req->event);
   1349         return;
   1350     }
   1351 
   1352     // this copy will get freed in loc_eng_ni when loc_ni_respond() is called
   1353     rpc_loc_ni_event_s_type *copy = (rpc_loc_ni_event_s_type *)malloc(sizeof(*copy));
   1354     memcpy(copy, ni_req, sizeof(*copy));
   1355     requestNiNotify(notif, (const void*)copy);
   1356 }
   1357 
   1358 int LocApiRpc::NIEventFillVerfiyType(GpsNiNotification &notif,
   1359                                 rpc_loc_ni_notify_verify_e_type notif_priv)
   1360 {
   1361    switch (notif_priv)
   1362    {
   1363    case RPC_LOC_NI_USER_NO_NOTIFY_NO_VERIFY:
   1364        notif.notify_flags = 0;
   1365        notif.default_response = GPS_NI_RESPONSE_NORESP;
   1366        return 1;
   1367    case RPC_LOC_NI_USER_NOTIFY_ONLY:
   1368        notif.notify_flags = GPS_NI_NEED_NOTIFY;
   1369        notif.default_response = GPS_NI_RESPONSE_NORESP;
   1370        return 1;
   1371    case RPC_LOC_NI_USER_NOTIFY_VERIFY_ALLOW_NO_RESP:
   1372        notif.notify_flags = GPS_NI_NEED_NOTIFY | GPS_NI_NEED_VERIFY;
   1373        notif.default_response = GPS_NI_RESPONSE_ACCEPT;
   1374        return 1;
   1375    case RPC_LOC_NI_USER_NOTIFY_VERIFY_NOT_ALLOW_NO_RESP:
   1376        notif.notify_flags = GPS_NI_NEED_NOTIFY | GPS_NI_NEED_VERIFY;
   1377        notif.default_response = GPS_NI_RESPONSE_DENY;
   1378        return 1;
   1379    case RPC_LOC_NI_USER_PRIVACY_OVERRIDE:
   1380        notif.notify_flags = GPS_NI_PRIVACY_OVERRIDE;
   1381        notif.default_response = GPS_NI_RESPONSE_NORESP;
   1382        return 1;
   1383    default:
   1384       return 0;
   1385    }
   1386 }
   1387 
   1388 enum loc_api_adapter_err
   1389 LocApiRpc::setSUPLVersion(uint32_t version)
   1390 {
   1391    rpc_loc_ioctl_data_u_type ioctl_data = {RPC_LOC_IOCTL_SET_SUPL_VERSION, {0}};
   1392    ioctl_data.rpc_loc_ioctl_data_u_type_u.supl_version = (int)version;
   1393    return convertErr(
   1394        loc_eng_ioctl (client_handle,
   1395                       RPC_LOC_IOCTL_SET_SUPL_VERSION,
   1396                       &ioctl_data,
   1397                       LOC_IOCTL_DEFAULT_TIMEOUT,
   1398                       NULL)
   1399        );
   1400 }
   1401 
   1402 GpsNiEncodingType LocApiRpc::convertNiEncodingType(int loc_encoding)
   1403 {
   1404    switch (loc_encoding)
   1405    {
   1406    case RPC_LOC_NI_SUPL_UTF8:
   1407        return GPS_ENC_SUPL_UTF8;
   1408    case RPC_LOC_NI_SUPL_UCS2:
   1409        return GPS_ENC_SUPL_UCS2;
   1410    case RPC_LOC_NI_SUPL_GSM_DEFAULT:
   1411       return GPS_ENC_SUPL_GSM_DEFAULT;
   1412    case RPC_LOC_NI_SS_LANGUAGE_UNSPEC:
   1413       return GPS_ENC_SUPL_GSM_DEFAULT; // SS_LANGUAGE_UNSPEC = GSM
   1414    default:
   1415        return GPS_ENC_UNKNOWN;
   1416    }
   1417 }
   1418 
   1419 LocApiBase* getLocApi(const MsgTask* msgTask,
   1420                       LOC_API_ADAPTER_EVENT_MASK_T exMask,
   1421                       ContextBase *context) {
   1422     return new LocApiRpc(msgTask, exMask, context);
   1423 }
   1424 
   1425 /*Values for lock
   1426   1 = Do not lock any position sessions
   1427   2 = Lock MI position sessions
   1428   3 = Lock MT position sessions
   1429   4 = Lock all position sessions
   1430 */
   1431 int LocApiRpc::setGpsLock(LOC_GPS_LOCK_MASK lockMask)
   1432 {
   1433     rpc_loc_ioctl_data_u_type    ioctl_data;
   1434     boolean ret_val;
   1435     LOC_LOGD("%s:%d]: lock: %x\n", __func__, __LINE__, lockMask);
   1436     ioctl_data.rpc_loc_ioctl_data_u_type_u.engine_lock = convertGpsLockMask(lockMask);
   1437     ioctl_data.disc = RPC_LOC_IOCTL_SET_ENGINE_LOCK;
   1438     ret_val = loc_eng_ioctl (loc_eng_data.client_handle,
   1439                             RPC_LOC_IOCTL_SET_ENGINE_LOCK,
   1440                             &ioctl_data,
   1441                             LOC_IOCTL_DEFAULT_TIMEOUT,
   1442                             NULL /* No output information is expected*/);
   1443 
   1444     LOC_LOGD("%s:%d]: ret_val: %d\n", __func__, __LINE__, (int)ret_val);
   1445     return (ret_val == TRUE ? 0 : -1);
   1446 }
   1447 
   1448 /*
   1449   Returns
   1450   Current value of GPS lock on success
   1451   -1 on failure
   1452 */
   1453 int LocApiRpc :: getGpsLock()
   1454 {
   1455     rpc_loc_ioctl_data_u_type    ioctl_data;
   1456     rpc_loc_ioctl_callback_s_type callback_payload;
   1457     boolean ret_val;
   1458     int ret=0;
   1459     LOC_LOGD("%s:%d]: Enter\n", __func__, __LINE__);
   1460     ret_val = loc_eng_ioctl (loc_eng_data.client_handle,
   1461                             RPC_LOC_IOCTL_GET_ENGINE_LOCK,
   1462                             &ioctl_data,
   1463                             LOC_IOCTL_DEFAULT_TIMEOUT,
   1464                             &callback_payload);
   1465     if(ret_val == TRUE) {
   1466         ret = (int)callback_payload.data.engine_lock;
   1467         LOC_LOGD("%s:%d]: Lock type: %d\n", __func__, __LINE__, ret);
   1468     }
   1469     else {
   1470         LOC_LOGE("%s:%d]: Ioctl failed", __func__, __LINE__);
   1471         ret = -1;
   1472     }
   1473     LOC_LOGD("%s:%d]: Exit\n", __func__, __LINE__);
   1474     return ret;
   1475 }
   1476