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