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 ¬if, 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