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