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