2698 lines
89 KiB
C++
2698 lines
89 KiB
C++
/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met:
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above
|
|
* copyright notice, this list of conditions and the following
|
|
* disclaimer in the documentation and/or other materials provided
|
|
* with the distribution.
|
|
* * Neither the name of The Linux Foundatoin, nor the names of its
|
|
* contributors may be used to endorse or promote products derived
|
|
* from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#define LOG_NDEBUG 0
|
|
#define LOG_TAG "LocSvc_ApiV02"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <math.h>
|
|
|
|
#include <hardware/gps.h>
|
|
|
|
#include <LocApiV02.h>
|
|
#include <loc_api_v02_log.h>
|
|
#include <loc_api_sync_req.h>
|
|
#include <loc_util_log.h>
|
|
#include <gps_extended.h>
|
|
#include "platform_lib_time.h"
|
|
|
|
using namespace loc_core;
|
|
|
|
/* Default session id ; TBD needs incrementing for each */
|
|
#define LOC_API_V02_DEF_SESSION_ID (1)
|
|
|
|
/* UMTS CP Address key*/
|
|
#define LOC_NI_NOTIF_KEY_ADDRESS "Address"
|
|
|
|
/* GPS SV Id offset */
|
|
#define GPS_SV_ID_OFFSET (1)
|
|
|
|
/* GLONASS SV Id offset */
|
|
#define GLONASS_SV_ID_OFFSET (65)
|
|
|
|
/* SV ID range */
|
|
#define SV_ID_RANGE (32)
|
|
|
|
|
|
#define BDS_SV_ID_OFFSET (201)
|
|
|
|
/* BeiDou SV ID RANGE*/
|
|
#define BDS_SV_ID_RANGE QMI_LOC_DELETE_MAX_BDS_SV_INFO_LENGTH_V02
|
|
|
|
/* static event callbacks that call the LocApiV02 callbacks*/
|
|
|
|
/* global event callback, call the eventCb function in loc api adapter v02
|
|
instance */
|
|
static void globalEventCb(locClientHandleType clientHandle,
|
|
uint32_t eventId,
|
|
const locClientEventIndUnionType eventPayload,
|
|
void* pClientCookie)
|
|
{
|
|
MODEM_LOG_CALLFLOW(%s, loc_get_v02_event_name(eventId));
|
|
LocApiV02 *locApiV02Instance =
|
|
(LocApiV02 *)pClientCookie;
|
|
|
|
LOC_LOGV ("%s:%d] client = %p, event id = %d, client cookie ptr = %p\n",
|
|
__func__, __LINE__, clientHandle, eventId, pClientCookie);
|
|
|
|
// return if null is passed
|
|
if( NULL == locApiV02Instance)
|
|
{
|
|
LOC_LOGE ("%s:%d] NULL object passed : client = %p, event id = %d\n",
|
|
__func__, __LINE__, clientHandle, eventId);
|
|
return;
|
|
}
|
|
locApiV02Instance->eventCb(clientHandle, eventId, eventPayload);
|
|
}
|
|
|
|
/* global response callback, it calls the sync request process
|
|
indication function to unblock the request that is waiting on this
|
|
response indication*/
|
|
static void globalRespCb(locClientHandleType clientHandle,
|
|
uint32_t respId,
|
|
const locClientRespIndUnionType respPayload,
|
|
void* pClientCookie)
|
|
{
|
|
MODEM_LOG_CALLFLOW(%s, loc_get_v02_event_name(respId));
|
|
LocApiV02 *locApiV02Instance =
|
|
(LocApiV02 *)pClientCookie;
|
|
|
|
|
|
LOC_LOGV ("%s:%d] client = %p, resp id = %d, client cookie ptr = %p\n",
|
|
__func__, __LINE__, clientHandle, respId, pClientCookie);
|
|
|
|
if( NULL == locApiV02Instance)
|
|
{
|
|
LOC_LOGE ("%s:%d] NULL object passed : client = %p, resp id = %d\n",
|
|
__func__, __LINE__, clientHandle, respId);
|
|
return;
|
|
}
|
|
// process the sync call
|
|
// use pDeleteAssistDataInd as a dummy pointer
|
|
loc_sync_process_ind(clientHandle, respId,
|
|
(void *)respPayload.pDeleteAssistDataInd);
|
|
}
|
|
|
|
/* global error callback, it will call the handle service down
|
|
function in the loc api adapter instance. */
|
|
static void globalErrorCb (locClientHandleType clientHandle,
|
|
locClientErrorEnumType errorId,
|
|
void *pClientCookie)
|
|
{
|
|
LocApiV02 *locApiV02Instance =
|
|
(LocApiV02 *)pClientCookie;
|
|
|
|
LOC_LOGV ("%s:%d] client = %p, error id = %d\n, client cookie ptr = %p\n",
|
|
__func__, __LINE__, clientHandle, errorId, pClientCookie);
|
|
if( NULL == locApiV02Instance)
|
|
{
|
|
LOC_LOGE ("%s:%d] NULL object passed : client = %p, error id = %d\n",
|
|
__func__, __LINE__, clientHandle, errorId);
|
|
return;
|
|
}
|
|
locApiV02Instance->errorCb(clientHandle, errorId);
|
|
}
|
|
|
|
/* global structure containing the callbacks */
|
|
locClientCallbacksType globalCallbacks =
|
|
{
|
|
sizeof(locClientCallbacksType),
|
|
globalEventCb,
|
|
globalRespCb,
|
|
globalErrorCb
|
|
};
|
|
|
|
/* Constructor for LocApiV02 */
|
|
LocApiV02 :: LocApiV02(const MsgTask* msgTask,
|
|
LOC_API_ADAPTER_EVENT_MASK_T exMask):
|
|
LocApiBase(msgTask, exMask),
|
|
clientHandle(LOC_CLIENT_INVALID_HANDLE_VALUE),
|
|
dsClientHandle(NULL)
|
|
{
|
|
// initialize loc_sync_req interface
|
|
loc_sync_req_init();
|
|
}
|
|
|
|
/* Destructor for LocApiV02 */
|
|
LocApiV02 :: ~LocApiV02()
|
|
{
|
|
close();
|
|
}
|
|
|
|
/* Initialize a loc api v02 client */
|
|
enum loc_api_adapter_err
|
|
LocApiV02 :: open(LOC_API_ADAPTER_EVENT_MASK_T mask)
|
|
{
|
|
enum loc_api_adapter_err rtv = LOC_API_ADAPTER_ERR_SUCCESS;
|
|
LOC_API_ADAPTER_EVENT_MASK_T newMask = mMask | (mask & ~mExcludedMask);
|
|
LOC_LOGD("%s:%d]: Enter mMask: %x; mask: %x; newMask: %x\n",
|
|
__func__, __LINE__, mMask, mask, newMask);
|
|
/* If the client is already open close it first */
|
|
if(LOC_CLIENT_INVALID_HANDLE_VALUE == clientHandle)
|
|
{
|
|
locClientStatusEnumType status = eLOC_CLIENT_SUCCESS;
|
|
|
|
LOC_LOGV ("%s:%d]: reference to this = %p passed in \n",
|
|
__func__, __LINE__, this);
|
|
/* initialize the loc api v02 interface, note that
|
|
the locClientOpen() function will block if the
|
|
service is unavailable for a fixed time out */
|
|
|
|
// it is important to cap the mask here, because not all LocApi's
|
|
// can enable the same bits, e.g. foreground and bckground.
|
|
status = locClientOpen(convertMask(newMask), &globalCallbacks,
|
|
&clientHandle, (void *)this);
|
|
mMask = newMask;
|
|
if (eLOC_CLIENT_SUCCESS != status ||
|
|
clientHandle == LOC_CLIENT_INVALID_HANDLE_VALUE )
|
|
{
|
|
mMask = 0;
|
|
LOC_LOGE ("%s:%d]: locClientOpen failed, status = %s\n", __func__,
|
|
__LINE__, loc_get_v02_client_status_name(status));
|
|
rtv = LOC_API_ADAPTER_ERR_FAILURE;
|
|
}
|
|
} else if (newMask != mMask) {
|
|
// it is important to cap the mask here, because not all LocApi's
|
|
// can enable the same bits, e.g. foreground and bckground.
|
|
if (! locClientRegisterEventMask(clientHandle, convertMask(newMask))) {
|
|
// we do not update mMask here, because it did not change
|
|
// as the mask update has failed.
|
|
rtv = LOC_API_ADAPTER_ERR_FAILURE;
|
|
}
|
|
else
|
|
mMask = newMask;
|
|
}
|
|
LOC_LOGD("%s:%d]: Exit mMask: %x; mask: %x\n",
|
|
__func__, __LINE__, mMask, mask);
|
|
|
|
return rtv;
|
|
}
|
|
|
|
enum loc_api_adapter_err LocApiV02 :: close()
|
|
{
|
|
enum loc_api_adapter_err rtv =
|
|
// success if either client is already invalid, or
|
|
// we successfully close the handle
|
|
(LOC_CLIENT_INVALID_HANDLE_VALUE == clientHandle ||
|
|
eLOC_CLIENT_SUCCESS == locClientClose(&clientHandle)) ?
|
|
LOC_API_ADAPTER_ERR_SUCCESS : LOC_API_ADAPTER_ERR_FAILURE;
|
|
|
|
mMask = 0;
|
|
clientHandle = LOC_CLIENT_INVALID_HANDLE_VALUE;
|
|
|
|
return rtv;
|
|
}
|
|
|
|
/* start positioning session */
|
|
enum loc_api_adapter_err LocApiV02 :: startFix(const LocPosMode& fixCriteria)
|
|
{
|
|
locClientStatusEnumType status;
|
|
locClientReqUnionType req_union;
|
|
|
|
qmiLocStartReqMsgT_v02 start_msg;
|
|
|
|
qmiLocSetOperationModeReqMsgT_v02 set_mode_msg;
|
|
qmiLocSetOperationModeIndMsgT_v02 set_mode_ind;
|
|
|
|
// clear all fields, validity masks
|
|
memset (&start_msg, 0, sizeof(start_msg));
|
|
memset (&set_mode_msg, 0, sizeof(set_mode_msg));
|
|
memset (&set_mode_ind, 0, sizeof(set_mode_ind));
|
|
|
|
LOC_LOGV("%s:%d]: start \n", __func__, __LINE__);
|
|
fixCriteria.logv();
|
|
|
|
// fill in the start request
|
|
switch(fixCriteria.mode)
|
|
{
|
|
case LOC_POSITION_MODE_MS_BASED:
|
|
set_mode_msg.operationMode = eQMI_LOC_OPER_MODE_MSB_V02;
|
|
break;
|
|
|
|
case LOC_POSITION_MODE_MS_ASSISTED:
|
|
set_mode_msg.operationMode = eQMI_LOC_OPER_MODE_MSA_V02;
|
|
break;
|
|
|
|
case LOC_POSITION_MODE_RESERVED_4:
|
|
set_mode_msg.operationMode = eQMI_LOC_OPER_MODE_CELL_ID_V02;
|
|
break;
|
|
|
|
case LOC_POSITION_MODE_RESERVED_5:
|
|
set_mode_msg.operationMode = eQMI_LOC_OPER_MODE_WWAN_V02;
|
|
break;
|
|
|
|
default:
|
|
set_mode_msg.operationMode = eQMI_LOC_OPER_MODE_STANDALONE_V02;
|
|
break;
|
|
}
|
|
|
|
req_union.pSetOperationModeReq = &set_mode_msg;
|
|
|
|
// send the mode first, before the start message.
|
|
status = loc_sync_send_req(clientHandle,
|
|
QMI_LOC_SET_OPERATION_MODE_REQ_V02,
|
|
req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
|
|
QMI_LOC_SET_OPERATION_MODE_IND_V02,
|
|
&set_mode_ind); // NULL?
|
|
|
|
if (status != eLOC_CLIENT_SUCCESS ||
|
|
eQMI_LOC_SUCCESS_V02 != set_mode_ind.status)
|
|
{
|
|
LOC_LOGE ("%s:%d]: set opertion mode failed status = %s, "
|
|
"ind..status = %s\n", __func__, __LINE__,
|
|
loc_get_v02_client_status_name(status),
|
|
loc_get_v02_qmi_status_name(set_mode_ind.status));
|
|
|
|
return LOC_API_ADAPTER_ERR_GENERAL_FAILURE; // error
|
|
}
|
|
|
|
start_msg.minInterval_valid = 1;
|
|
start_msg.minInterval = fixCriteria.min_interval;
|
|
|
|
if (fixCriteria.preferred_accuracy >= 0) {
|
|
start_msg.horizontalAccuracyLevel_valid = 1;
|
|
|
|
if (fixCriteria.preferred_accuracy <= 100)
|
|
{
|
|
// fix needs high accuracy
|
|
start_msg.horizontalAccuracyLevel = eQMI_LOC_ACCURACY_HIGH_V02;
|
|
}
|
|
else if (fixCriteria.preferred_accuracy <= 1000)
|
|
{
|
|
//fix needs med accuracy
|
|
start_msg.horizontalAccuracyLevel = eQMI_LOC_ACCURACY_MED_V02;
|
|
}
|
|
else
|
|
{
|
|
//fix needs low accuracy
|
|
start_msg.horizontalAccuracyLevel = eQMI_LOC_ACCURACY_LOW_V02;
|
|
}
|
|
}
|
|
|
|
start_msg.fixRecurrence_valid = 1;
|
|
if(GPS_POSITION_RECURRENCE_SINGLE == fixCriteria.recurrence)
|
|
{
|
|
start_msg.fixRecurrence = eQMI_LOC_RECURRENCE_SINGLE_V02;
|
|
}
|
|
else
|
|
{
|
|
start_msg.fixRecurrence = eQMI_LOC_RECURRENCE_PERIODIC_V02;
|
|
}
|
|
|
|
//dummy session id
|
|
// TBD: store session ID, check for session id in pos reports.
|
|
start_msg.sessionId = LOC_API_V02_DEF_SESSION_ID;
|
|
|
|
if (fixCriteria.credentials[0] != 0) {
|
|
int size1 = sizeof(start_msg.applicationId.applicationName);
|
|
int size2 = sizeof(fixCriteria.credentials);
|
|
int len = ((size1 < size2) ? size1 : size2) - 1;
|
|
memcpy(start_msg.applicationId.applicationName,
|
|
fixCriteria.credentials,
|
|
len);
|
|
|
|
size1 = sizeof(start_msg.applicationId.applicationProvider);
|
|
size2 = sizeof(fixCriteria.provider);
|
|
len = ((size1 < size2) ? size1 : size2) - 1;
|
|
memcpy(start_msg.applicationId.applicationProvider,
|
|
fixCriteria.provider,
|
|
len);
|
|
|
|
start_msg.applicationId_valid = 1;
|
|
}
|
|
|
|
// config Altitude Assumed
|
|
start_msg.configAltitudeAssumed_valid = 1;
|
|
start_msg.configAltitudeAssumed = eQMI_LOC_ALTITUDE_ASSUMED_IN_GNSS_SV_INFO_DISABLED_V02;
|
|
|
|
req_union.pStartReq = &start_msg;
|
|
|
|
status = locClientSendReq (clientHandle, QMI_LOC_START_REQ_V02,
|
|
req_union );
|
|
|
|
if( eLOC_CLIENT_SUCCESS == status)
|
|
{
|
|
return LOC_API_ADAPTER_ERR_SUCCESS;
|
|
}
|
|
|
|
return LOC_API_ADAPTER_ERR_GENERAL_FAILURE;
|
|
}
|
|
|
|
/* stop a positioning session */
|
|
enum loc_api_adapter_err LocApiV02 :: stopFix()
|
|
{
|
|
locClientStatusEnumType status;
|
|
locClientReqUnionType req_union;
|
|
|
|
qmiLocStopReqMsgT_v02 stop_msg;
|
|
|
|
LOC_LOGD(" %s:%d]: stop called \n", __func__, __LINE__);
|
|
|
|
memset(&stop_msg, 0, sizeof(stop_msg));
|
|
|
|
// dummy session id
|
|
stop_msg.sessionId = LOC_API_V02_DEF_SESSION_ID;
|
|
|
|
req_union.pStopReq = &stop_msg;
|
|
|
|
status = locClientSendReq(clientHandle,
|
|
QMI_LOC_STOP_REQ_V02,
|
|
req_union);
|
|
|
|
if( eLOC_CLIENT_SUCCESS == status)
|
|
{
|
|
return LOC_API_ADAPTER_ERR_SUCCESS;
|
|
}
|
|
|
|
LOC_LOGE("%s:%d]: error = %s\n",__func__, __LINE__,
|
|
loc_get_v02_client_status_name(status));
|
|
return (LOC_API_ADAPTER_ERR_GENERAL_FAILURE);
|
|
}
|
|
|
|
/* set the positioning fix criteria */
|
|
enum loc_api_adapter_err LocApiV02 :: setPositionMode(
|
|
const LocPosMode& posMode)
|
|
{
|
|
if(isInSession())
|
|
{
|
|
//fix is in progress, send a restart
|
|
LOC_LOGD ("%s:%d]: fix is in progress restarting the fix with new "
|
|
"criteria\n", __func__, __LINE__);
|
|
|
|
return( startFix(posMode));
|
|
}
|
|
|
|
return LOC_API_ADAPTER_ERR_SUCCESS;
|
|
}
|
|
|
|
/* inject time into the position engine */
|
|
enum loc_api_adapter_err LocApiV02 ::
|
|
setTime(GpsUtcTime time, int64_t timeReference, int uncertainty)
|
|
{
|
|
locClientReqUnionType req_union;
|
|
locClientStatusEnumType status;
|
|
qmiLocInjectUtcTimeReqMsgT_v02 inject_time_msg;
|
|
qmiLocInjectUtcTimeIndMsgT_v02 inject_time_ind;
|
|
|
|
memset(&inject_time_msg, 0, sizeof(inject_time_msg));
|
|
|
|
inject_time_ind.status = eQMI_LOC_GENERAL_FAILURE_V02;
|
|
|
|
inject_time_msg.timeUtc = time;
|
|
|
|
inject_time_msg.timeUtc += (int64_t)(platform_lib_abstraction_elapsed_millis_since_boot() - timeReference);
|
|
|
|
inject_time_msg.timeUnc = uncertainty;
|
|
|
|
req_union.pInjectUtcTimeReq = &inject_time_msg;
|
|
|
|
LOC_LOGV ("%s:%d]: uncertainty = %d\n", __func__, __LINE__,
|
|
uncertainty);
|
|
|
|
status = loc_sync_send_req(clientHandle,
|
|
QMI_LOC_INJECT_UTC_TIME_REQ_V02,
|
|
req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
|
|
QMI_LOC_INJECT_UTC_TIME_IND_V02,
|
|
&inject_time_ind);
|
|
|
|
if (status != eLOC_CLIENT_SUCCESS ||
|
|
eQMI_LOC_SUCCESS_V02 != inject_time_ind.status)
|
|
{
|
|
LOC_LOGE ("%s:%d] status = %s, ind..status = %s\n", __func__, __LINE__,
|
|
loc_get_v02_client_status_name(status),
|
|
loc_get_v02_qmi_status_name(inject_time_ind.status));
|
|
|
|
return LOC_API_ADAPTER_ERR_GENERAL_FAILURE;
|
|
}
|
|
|
|
return LOC_API_ADAPTER_ERR_SUCCESS;
|
|
}
|
|
|
|
/* inject position into the position engine */
|
|
enum loc_api_adapter_err LocApiV02 ::
|
|
injectPosition(double latitude, double longitude, float accuracy)
|
|
{
|
|
locClientReqUnionType req_union;
|
|
locClientStatusEnumType status;
|
|
qmiLocInjectPositionReqMsgT_v02 inject_pos_msg;
|
|
qmiLocInjectPositionIndMsgT_v02 inject_pos_ind;
|
|
|
|
memset(&inject_pos_msg, 0, sizeof(inject_pos_msg));
|
|
|
|
inject_pos_msg.latitude_valid = 1;
|
|
inject_pos_msg.latitude = latitude;
|
|
|
|
inject_pos_msg.longitude_valid = 1;
|
|
inject_pos_msg.longitude = longitude;
|
|
|
|
inject_pos_msg.horUncCircular_valid = 1;
|
|
|
|
inject_pos_msg.horUncCircular = accuracy; //meters assumed
|
|
|
|
inject_pos_msg.horConfidence_valid = 1;
|
|
|
|
inject_pos_msg.horConfidence = 63; // 63% (1 std dev assumed)
|
|
|
|
/* Log */
|
|
LOC_LOGD("%s:%d]: Lat=%lf, Lon=%lf, Acc=%.2lf\n", __func__, __LINE__,
|
|
inject_pos_msg.latitude, inject_pos_msg.longitude,
|
|
inject_pos_msg.horUncCircular);
|
|
|
|
req_union.pInjectPositionReq = &inject_pos_msg;
|
|
|
|
status = loc_sync_send_req(clientHandle,
|
|
QMI_LOC_INJECT_POSITION_REQ_V02,
|
|
req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
|
|
QMI_LOC_INJECT_POSITION_IND_V02,
|
|
&inject_pos_ind);
|
|
|
|
if (status != eLOC_CLIENT_SUCCESS ||
|
|
eQMI_LOC_SUCCESS_V02 != inject_pos_ind.status)
|
|
{
|
|
LOC_LOGE ("%s:%d]: error! status = %s, inject_pos_ind.status = %s\n",
|
|
__func__, __LINE__,
|
|
loc_get_v02_client_status_name(status),
|
|
loc_get_v02_qmi_status_name(inject_pos_ind.status));
|
|
|
|
return LOC_API_ADAPTER_ERR_GENERAL_FAILURE;
|
|
}
|
|
|
|
return LOC_API_ADAPTER_ERR_SUCCESS;
|
|
}
|
|
|
|
/* delete assistance date */
|
|
enum loc_api_adapter_err LocApiV02 :: deleteAidingData(GpsAidingData f)
|
|
{
|
|
locClientReqUnionType req_union;
|
|
locClientStatusEnumType status;
|
|
qmiLocDeleteAssistDataReqMsgT_v02 delete_req;
|
|
qmiLocDeleteAssistDataIndMsgT_v02 delete_resp;
|
|
|
|
memset(&delete_req, 0, sizeof(delete_req));
|
|
memset(&delete_resp, 0, sizeof(delete_resp));
|
|
|
|
if( f == GPS_DELETE_ALL )
|
|
{
|
|
delete_req.deleteAllFlag = true;
|
|
}
|
|
|
|
else
|
|
{
|
|
/* to keep track of svInfoList for GPS and GLO*/
|
|
uint32_t curr_sv_len = 0;
|
|
uint32_t curr_sv_idx = 0;
|
|
uint32_t sv_id = 0;
|
|
|
|
if((f & GPS_DELETE_EPHEMERIS ) || ( f & GPS_DELETE_ALMANAC ))
|
|
{
|
|
/* do delete for all GPS SV's */
|
|
|
|
curr_sv_len += SV_ID_RANGE;
|
|
|
|
sv_id = GPS_SV_ID_OFFSET;
|
|
|
|
delete_req.deleteSvInfoList_valid = 1;
|
|
|
|
delete_req.deleteSvInfoList_len = curr_sv_len;
|
|
|
|
LOC_LOGV("%s:%d]: Delete GPS SV info for index %d to %d"
|
|
"and sv id %d to %d \n",
|
|
__func__, __LINE__, curr_sv_idx, curr_sv_len - 1,
|
|
sv_id, sv_id+SV_ID_RANGE-1);
|
|
|
|
for( uint32_t i = curr_sv_idx; i< curr_sv_len ; i++, sv_id++ )
|
|
{
|
|
delete_req.deleteSvInfoList[i].gnssSvId = sv_id;
|
|
|
|
delete_req.deleteSvInfoList[i].system = eQMI_LOC_SV_SYSTEM_GPS_V02;
|
|
|
|
if(f & GPS_DELETE_EPHEMERIS )
|
|
{
|
|
// set ephemeris mask for all GPS SV's
|
|
delete_req.deleteSvInfoList[i].deleteSvInfoMask |=
|
|
QMI_LOC_MASK_DELETE_EPHEMERIS_V02;
|
|
}
|
|
|
|
if( f & GPS_DELETE_ALMANAC )
|
|
{
|
|
delete_req.deleteSvInfoList[i].deleteSvInfoMask |=
|
|
QMI_LOC_MASK_DELETE_ALMANAC_V02;
|
|
}
|
|
}
|
|
// increment the current index
|
|
curr_sv_idx += SV_ID_RANGE;
|
|
|
|
}
|
|
|
|
if( f & GPS_DELETE_TIME_GPS )
|
|
{
|
|
delete_req.deleteGnssDataMask_valid = 1;
|
|
delete_req.deleteGnssDataMask |= QMI_LOC_MASK_DELETE_GPS_TIME_V02;
|
|
}
|
|
|
|
if(f & GPS_DELETE_POSITION )
|
|
{
|
|
delete_req.deleteGnssDataMask_valid = 1;
|
|
delete_req.deleteGnssDataMask |= QMI_LOC_MASK_DELETE_POSITION_V02;
|
|
}
|
|
|
|
if(f & GPS_DELETE_TIME )
|
|
{
|
|
delete_req.deleteGnssDataMask_valid = 1;
|
|
delete_req.deleteGnssDataMask |= QMI_LOC_MASK_DELETE_TIME_V02;
|
|
}
|
|
|
|
if(f & GPS_DELETE_IONO )
|
|
{
|
|
delete_req.deleteGnssDataMask_valid = 1;
|
|
delete_req.deleteGnssDataMask |= QMI_LOC_MASK_DELETE_IONO_V02;
|
|
}
|
|
|
|
if(f & GPS_DELETE_UTC )
|
|
{
|
|
delete_req.deleteGnssDataMask_valid = 1;
|
|
delete_req.deleteGnssDataMask |= QMI_LOC_MASK_DELETE_UTC_V02;
|
|
}
|
|
|
|
if(f & GPS_DELETE_HEALTH )
|
|
{
|
|
delete_req.deleteGnssDataMask_valid = 1;
|
|
delete_req.deleteGnssDataMask |= QMI_LOC_MASK_DELETE_HEALTH_V02;
|
|
}
|
|
|
|
if(f & GPS_DELETE_SVDIR )
|
|
{
|
|
delete_req.deleteGnssDataMask_valid = 1;
|
|
delete_req.deleteGnssDataMask |= QMI_LOC_MASK_DELETE_GPS_SVDIR_V02;
|
|
}
|
|
if(f & GPS_DELETE_SADATA )
|
|
{
|
|
delete_req.deleteGnssDataMask_valid = 1;
|
|
delete_req.deleteGnssDataMask |= QMI_LOC_MASK_DELETE_SADATA_V02;
|
|
}
|
|
if(f & GPS_DELETE_RTI )
|
|
{
|
|
delete_req.deleteGnssDataMask_valid = 1;
|
|
delete_req.deleteGnssDataMask |= QMI_LOC_MASK_DELETE_RTI_V02;
|
|
}
|
|
if(f & GPS_DELETE_CELLDB_INFO )
|
|
{
|
|
delete_req.deleteCellDbDataMask_valid = 1;
|
|
delete_req.deleteCellDbDataMask =
|
|
( QMI_LOC_MASK_DELETE_CELLDB_POS_V02 |
|
|
QMI_LOC_MASK_DELETE_CELLDB_LATEST_GPS_POS_V02 |
|
|
QMI_LOC_MASK_DELETE_CELLDB_OTA_POS_V02 |
|
|
QMI_LOC_MASK_DELETE_CELLDB_EXT_REF_POS_V02 |
|
|
QMI_LOC_MASK_DELETE_CELLDB_TIMETAG_V02 |
|
|
QMI_LOC_MASK_DELETE_CELLDB_CELLID_V02 |
|
|
QMI_LOC_MASK_DELETE_CELLDB_CACHED_CELLID_V02 |
|
|
QMI_LOC_MASK_DELETE_CELLDB_LAST_SRV_CELL_V02 |
|
|
QMI_LOC_MASK_DELETE_CELLDB_CUR_SRV_CELL_V02 |
|
|
QMI_LOC_MASK_DELETE_CELLDB_NEIGHBOR_INFO_V02) ;
|
|
|
|
}
|
|
if(f & GPS_DELETE_ALMANAC_CORR )
|
|
{
|
|
delete_req.deleteGnssDataMask_valid = 1;
|
|
delete_req.deleteGnssDataMask |= QMI_LOC_MASK_DELETE_GPS_ALM_CORR_V02;
|
|
}
|
|
if(f & GPS_DELETE_FREQ_BIAS_EST )
|
|
{
|
|
delete_req.deleteGnssDataMask_valid = 1;
|
|
delete_req.deleteGnssDataMask |= QMI_LOC_MASK_DELETE_FREQ_BIAS_EST_V02;
|
|
}
|
|
if ( (f & GLO_DELETE_EPHEMERIS ) || (f & GLO_DELETE_ALMANAC ))
|
|
{
|
|
/* do delete for all GLONASS SV's (65 - 96)
|
|
*/
|
|
curr_sv_len += SV_ID_RANGE;
|
|
|
|
sv_id = GLONASS_SV_ID_OFFSET;
|
|
|
|
delete_req.deleteSvInfoList_valid = 1;
|
|
|
|
delete_req.deleteSvInfoList_len = curr_sv_len;
|
|
|
|
LOC_LOGV("%s:%d]: Delete GLO SV info for index %d to %d"
|
|
"and sv id %d to %d \n",
|
|
__func__, __LINE__, curr_sv_idx, curr_sv_len - 1,
|
|
sv_id, sv_id+SV_ID_RANGE-1);
|
|
|
|
|
|
for( uint32_t i = curr_sv_idx; i< curr_sv_len ; i++, sv_id++ )
|
|
{
|
|
delete_req.deleteSvInfoList[i].gnssSvId = sv_id;
|
|
|
|
delete_req.deleteSvInfoList[i].system = eQMI_LOC_SV_SYSTEM_GLONASS_V02;
|
|
|
|
// set ephemeris mask for all GLO SV's
|
|
if(f & GLO_DELETE_EPHEMERIS)
|
|
delete_req.deleteSvInfoList[i].deleteSvInfoMask |=
|
|
QMI_LOC_MASK_DELETE_EPHEMERIS_V02;
|
|
// set almanac mask for all GLO SV's
|
|
if(f & GLO_DELETE_ALMANAC)
|
|
delete_req.deleteSvInfoList[i].deleteSvInfoMask |=
|
|
QMI_LOC_MASK_DELETE_ALMANAC_V02;
|
|
}
|
|
curr_sv_idx += SV_ID_RANGE;
|
|
}
|
|
|
|
if(f & GLO_DELETE_SVDIR )
|
|
{
|
|
delete_req.deleteGnssDataMask_valid = 1;
|
|
delete_req.deleteGnssDataMask |= QMI_LOC_MASK_DELETE_GLO_SVDIR_V02;
|
|
}
|
|
|
|
if(f & GLO_DELETE_SVSTEER )
|
|
{
|
|
delete_req.deleteGnssDataMask_valid = 1;
|
|
delete_req.deleteGnssDataMask |= QMI_LOC_MASK_DELETE_GLO_SVSTEER_V02;
|
|
}
|
|
|
|
if(f & GLO_DELETE_ALMANAC_CORR )
|
|
{
|
|
delete_req.deleteGnssDataMask_valid = 1;
|
|
delete_req.deleteGnssDataMask |= QMI_LOC_MASK_DELETE_GLO_ALM_CORR_V02;
|
|
}
|
|
|
|
if(f & GLO_DELETE_TIME )
|
|
{
|
|
delete_req.deleteGnssDataMask_valid = 1;
|
|
delete_req.deleteGnssDataMask |= QMI_LOC_MASK_DELETE_GLO_TIME_V02;
|
|
}
|
|
|
|
if ( (f & BDS_DELETE_EPHEMERIS ) || (f & BDS_DELETE_ALMANAC ))
|
|
{
|
|
/*Delete BeiDou SV info*/
|
|
|
|
sv_id = BDS_SV_ID_OFFSET;
|
|
|
|
delete_req.deleteBdsSvInfoList_valid = 1;
|
|
|
|
delete_req.deleteBdsSvInfoList_len = BDS_SV_ID_RANGE;
|
|
|
|
LOC_LOGV("%s:%d]: Delete BDS SV info for index 0 to %d"
|
|
"and sv id %d to %d \n",
|
|
__func__, __LINE__,
|
|
BDS_SV_ID_RANGE - 1,
|
|
sv_id, sv_id+BDS_SV_ID_RANGE - 1);
|
|
|
|
for( uint32_t i = 0; i < BDS_SV_ID_RANGE; i++, sv_id++ )
|
|
{
|
|
delete_req.deleteBdsSvInfoList[i].gnssSvId = sv_id;
|
|
|
|
// set ephemeris mask for all BDS SV's
|
|
if(f & BDS_DELETE_EPHEMERIS)
|
|
delete_req.deleteBdsSvInfoList[i].deleteSvInfoMask |=
|
|
QMI_LOC_MASK_DELETE_EPHEMERIS_V02;
|
|
if(f & BDS_DELETE_ALMANAC)
|
|
delete_req.deleteBdsSvInfoList[i].deleteSvInfoMask |=
|
|
QMI_LOC_MASK_DELETE_ALMANAC_V02;
|
|
}
|
|
curr_sv_idx += BDS_SV_ID_RANGE;
|
|
}
|
|
|
|
if(f & BDS_DELETE_SVDIR )
|
|
{
|
|
delete_req.deleteGnssDataMask_valid = 1;
|
|
delete_req.deleteGnssDataMask |= QMI_LOC_MASK_DELETE_BDS_SVDIR_V02;
|
|
}
|
|
|
|
if(f & BDS_DELETE_SVSTEER )
|
|
{
|
|
delete_req.deleteGnssDataMask_valid = 1;
|
|
delete_req.deleteGnssDataMask |= QMI_LOC_MASK_DELETE_BDS_SVSTEER_V02;
|
|
}
|
|
|
|
if(f & BDS_DELETE_ALMANAC_CORR )
|
|
{
|
|
delete_req.deleteGnssDataMask_valid = 1;
|
|
delete_req.deleteGnssDataMask |= QMI_LOC_MASK_DELETE_BDS_ALM_CORR_V02;
|
|
}
|
|
|
|
if(f & BDS_DELETE_TIME )
|
|
{
|
|
delete_req.deleteGnssDataMask_valid = 1;
|
|
delete_req.deleteGnssDataMask |= QMI_LOC_MASK_DELETE_BDS_TIME_V02;
|
|
}
|
|
|
|
}
|
|
|
|
req_union.pDeleteAssistDataReq = &delete_req;
|
|
|
|
status = loc_sync_send_req(clientHandle,
|
|
QMI_LOC_DELETE_ASSIST_DATA_REQ_V02,
|
|
req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
|
|
QMI_LOC_DELETE_ASSIST_DATA_IND_V02,
|
|
&delete_resp);
|
|
|
|
if (status != eLOC_CLIENT_SUCCESS ||
|
|
eQMI_LOC_SUCCESS_V02 != delete_resp.status)
|
|
{
|
|
LOC_LOGE ("%s:%d]: error! status = %s, delete_resp.status = %s\n",
|
|
__func__, __LINE__,
|
|
loc_get_v02_client_status_name(status),
|
|
loc_get_v02_qmi_status_name(delete_resp.status));
|
|
|
|
return LOC_API_ADAPTER_ERR_GENERAL_FAILURE;
|
|
}
|
|
|
|
return LOC_API_ADAPTER_ERR_SUCCESS;
|
|
}
|
|
|
|
/* send NI user repsonse to the engine */
|
|
enum loc_api_adapter_err LocApiV02 ::
|
|
informNiResponse(GpsUserResponseType userResponse,
|
|
const void* passThroughData)
|
|
{
|
|
locClientReqUnionType req_union;
|
|
locClientStatusEnumType status;
|
|
|
|
qmiLocNiUserRespReqMsgT_v02 ni_resp;
|
|
qmiLocNiUserRespIndMsgT_v02 ni_resp_ind;
|
|
|
|
qmiLocEventNiNotifyVerifyReqIndMsgT_v02 *request_pass_back =
|
|
(qmiLocEventNiNotifyVerifyReqIndMsgT_v02 *)passThroughData;
|
|
|
|
memset(&ni_resp,0, sizeof(ni_resp));
|
|
|
|
memset(&ni_resp_ind,0, sizeof(ni_resp_ind));
|
|
|
|
switch (userResponse)
|
|
{
|
|
case GPS_NI_RESPONSE_ACCEPT:
|
|
ni_resp.userResp = eQMI_LOC_NI_LCS_NOTIFY_VERIFY_ACCEPT_V02;
|
|
break;
|
|
case GPS_NI_RESPONSE_DENY:
|
|
ni_resp.userResp = eQMI_LOC_NI_LCS_NOTIFY_VERIFY_DENY_V02;
|
|
break;
|
|
case GPS_NI_RESPONSE_NORESP:
|
|
ni_resp.userResp = eQMI_LOC_NI_LCS_NOTIFY_VERIFY_NORESP_V02;
|
|
break;
|
|
default:
|
|
return LOC_API_ADAPTER_ERR_INVALID_PARAMETER;
|
|
}
|
|
|
|
LOC_LOGV(" %s:%d]: NI response: %d\n", __func__, __LINE__,
|
|
ni_resp.userResp);
|
|
|
|
ni_resp.notificationType = request_pass_back->notificationType;
|
|
|
|
// copy SUPL payload from request
|
|
if(request_pass_back->NiSuplInd_valid == 1)
|
|
{
|
|
ni_resp.NiSuplPayload_valid = 1;
|
|
memcpy(&(ni_resp.NiSuplPayload), &(request_pass_back->NiSuplInd),
|
|
sizeof(qmiLocNiSuplNotifyVerifyStructT_v02));
|
|
|
|
}
|
|
// should this be an "else if"?? we don't need to decide
|
|
|
|
// copy UMTS-CP payload from request
|
|
if( request_pass_back->NiUmtsCpInd_valid == 1 )
|
|
{
|
|
ni_resp.NiUmtsCpPayload_valid = 1;
|
|
memcpy(&(ni_resp.NiUmtsCpPayload), &(request_pass_back->NiUmtsCpInd),
|
|
sizeof(qmiLocNiUmtsCpNotifyVerifyStructT_v02));
|
|
}
|
|
|
|
//copy Vx payload from the request
|
|
if( request_pass_back->NiVxInd_valid == 1)
|
|
{
|
|
ni_resp.NiVxPayload_valid = 1;
|
|
memcpy(&(ni_resp.NiVxPayload), &(request_pass_back->NiVxInd),
|
|
sizeof(qmiLocNiVxNotifyVerifyStructT_v02));
|
|
}
|
|
|
|
// copy Vx service interaction payload from the request
|
|
if(request_pass_back->NiVxServiceInteractionInd_valid == 1)
|
|
{
|
|
ni_resp.NiVxServiceInteractionPayload_valid = 1;
|
|
memcpy(&(ni_resp.NiVxServiceInteractionPayload),
|
|
&(request_pass_back->NiVxServiceInteractionInd),
|
|
sizeof(qmiLocNiVxServiceInteractionStructT_v02));
|
|
}
|
|
|
|
// copy Network Initiated SUPL Version 2 Extension
|
|
if (request_pass_back->NiSuplVer2ExtInd_valid == 1)
|
|
{
|
|
ni_resp.NiSuplVer2ExtPayload_valid = 1;
|
|
memcpy(&(ni_resp.NiSuplVer2ExtPayload),
|
|
&(request_pass_back->NiSuplVer2ExtInd),
|
|
sizeof(qmiLocNiSuplVer2ExtStructT_v02));
|
|
}
|
|
|
|
// copy SUPL Emergency Notification
|
|
if(request_pass_back->suplEmergencyNotification_valid)
|
|
{
|
|
ni_resp.suplEmergencyNotification_valid = 1;
|
|
memcpy(&(ni_resp.suplEmergencyNotification),
|
|
&(request_pass_back->suplEmergencyNotification),
|
|
sizeof(qmiLocEmergencyNotificationStructT_v02));
|
|
}
|
|
|
|
req_union.pNiUserRespReq = &ni_resp;
|
|
|
|
status = loc_sync_send_req (
|
|
clientHandle, QMI_LOC_NI_USER_RESPONSE_REQ_V02,
|
|
req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
|
|
QMI_LOC_NI_USER_RESPONSE_IND_V02, &ni_resp_ind);
|
|
|
|
if (status != eLOC_CLIENT_SUCCESS ||
|
|
eQMI_LOC_SUCCESS_V02 != ni_resp_ind.status)
|
|
{
|
|
LOC_LOGE ("%s:%d]: error! status = %s, ni_resp_ind.status = %s\n",
|
|
__func__, __LINE__,
|
|
loc_get_v02_client_status_name(status),
|
|
loc_get_v02_qmi_status_name(ni_resp_ind.status));
|
|
|
|
return LOC_API_ADAPTER_ERR_GENERAL_FAILURE;
|
|
}
|
|
|
|
return LOC_API_ADAPTER_ERR_SUCCESS;
|
|
}
|
|
|
|
/* Set UMTs SLP server URL */
|
|
enum loc_api_adapter_err LocApiV02 :: setServer(
|
|
const char* url, int len)
|
|
{
|
|
locClientReqUnionType req_union;
|
|
locClientStatusEnumType status;
|
|
qmiLocSetServerReqMsgT_v02 set_server_req;
|
|
qmiLocSetServerIndMsgT_v02 set_server_ind;
|
|
|
|
if(len <=0 || len > sizeof(set_server_req.urlAddr))
|
|
{
|
|
LOC_LOGE("%s:%d]: len = %d greater than max allowed url length\n",
|
|
__func__, __LINE__, len);
|
|
|
|
return LOC_API_ADAPTER_ERR_INVALID_PARAMETER;
|
|
}
|
|
|
|
memset(&set_server_req, 0, sizeof(set_server_req));
|
|
|
|
LOC_LOGD("%s:%d]:, url = %s, len = %d\n", __func__, __LINE__, url, len);
|
|
|
|
set_server_req.serverType = eQMI_LOC_SERVER_TYPE_UMTS_SLP_V02;
|
|
|
|
set_server_req.urlAddr_valid = 1;
|
|
|
|
strlcpy(set_server_req.urlAddr, url, sizeof(set_server_req.urlAddr));
|
|
|
|
req_union.pSetServerReq = &set_server_req;
|
|
|
|
status = loc_sync_send_req(clientHandle,
|
|
QMI_LOC_SET_SERVER_REQ_V02,
|
|
req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
|
|
QMI_LOC_SET_SERVER_IND_V02,
|
|
&set_server_ind);
|
|
|
|
if (status != eLOC_CLIENT_SUCCESS ||
|
|
eQMI_LOC_SUCCESS_V02 != set_server_ind.status)
|
|
{
|
|
LOC_LOGE ("%s:%d]: error status = %s, set_server_ind.status = %s\n",
|
|
__func__,__LINE__,
|
|
loc_get_v02_client_status_name(status),
|
|
loc_get_v02_qmi_status_name(set_server_ind.status));
|
|
|
|
return LOC_API_ADAPTER_ERR_GENERAL_FAILURE;
|
|
}
|
|
|
|
return LOC_API_ADAPTER_ERR_SUCCESS;
|
|
}
|
|
|
|
enum loc_api_adapter_err LocApiV02 ::
|
|
setServer(unsigned int ip, int port, LocServerType type)
|
|
{
|
|
locClientReqUnionType req_union;
|
|
locClientStatusEnumType status;
|
|
qmiLocSetServerReqMsgT_v02 set_server_req;
|
|
qmiLocSetServerIndMsgT_v02 set_server_ind;
|
|
qmiLocServerTypeEnumT_v02 set_server_cmd;
|
|
|
|
switch (type) {
|
|
case LOC_AGPS_MPC_SERVER:
|
|
set_server_cmd = eQMI_LOC_SERVER_TYPE_CDMA_MPC_V02;
|
|
break;
|
|
case LOC_AGPS_CUSTOM_PDE_SERVER:
|
|
set_server_cmd = eQMI_LOC_SERVER_TYPE_CUSTOM_PDE_V02;
|
|
break;
|
|
default:
|
|
set_server_cmd = eQMI_LOC_SERVER_TYPE_CDMA_PDE_V02;
|
|
break;
|
|
}
|
|
|
|
memset(&set_server_req, 0, sizeof(set_server_req));
|
|
|
|
LOC_LOGD("%s:%d]:, ip = %u, port = %d\n", __func__, __LINE__, ip, port);
|
|
|
|
set_server_req.serverType = set_server_cmd;
|
|
set_server_req.ipv4Addr_valid = 1;
|
|
set_server_req.ipv4Addr.addr = ip;
|
|
set_server_req.ipv4Addr.port = port;
|
|
|
|
req_union.pSetServerReq = &set_server_req;
|
|
|
|
status = loc_sync_send_req(clientHandle,
|
|
QMI_LOC_SET_SERVER_REQ_V02,
|
|
req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
|
|
QMI_LOC_SET_SERVER_IND_V02,
|
|
&set_server_ind);
|
|
|
|
if (status != eLOC_CLIENT_SUCCESS ||
|
|
eQMI_LOC_SUCCESS_V02 != set_server_ind.status)
|
|
{
|
|
LOC_LOGE ("%s:%d]: error status = %s, set_server_ind.status = %s\n",
|
|
__func__,__LINE__,
|
|
loc_get_v02_client_status_name(status),
|
|
loc_get_v02_qmi_status_name(set_server_ind.status));
|
|
|
|
return LOC_API_ADAPTER_ERR_GENERAL_FAILURE;
|
|
}
|
|
|
|
return LOC_API_ADAPTER_ERR_SUCCESS;
|
|
}
|
|
|
|
/* Inject XTRA data, this module breaks down the XTRA
|
|
file into "chunks" and injects them one at a time */
|
|
enum loc_api_adapter_err LocApiV02 :: setXtraData(
|
|
char* data, int length)
|
|
{
|
|
locClientStatusEnumType status = eLOC_CLIENT_SUCCESS;
|
|
int total_parts;
|
|
uint8_t part;
|
|
uint16_t len_injected;
|
|
|
|
locClientReqUnionType req_union;
|
|
qmiLocInjectPredictedOrbitsDataReqMsgT_v02 inject_xtra;
|
|
qmiLocInjectPredictedOrbitsDataIndMsgT_v02 inject_xtra_ind;
|
|
|
|
req_union.pInjectPredictedOrbitsDataReq = &inject_xtra;
|
|
|
|
LOC_LOGD("%s:%d]: xtra size = %d\n", __func__, __LINE__, length);
|
|
|
|
inject_xtra.formatType_valid = 1;
|
|
inject_xtra.formatType = eQMI_LOC_PREDICTED_ORBITS_XTRA_V02;
|
|
inject_xtra.totalSize = length;
|
|
|
|
total_parts = ((length - 1) / QMI_LOC_MAX_PREDICTED_ORBITS_PART_LEN_V02) + 1;
|
|
|
|
inject_xtra.totalParts = total_parts;
|
|
|
|
len_injected = 0; // O bytes injected
|
|
|
|
// XTRA injection starts with part 1
|
|
for (part = 1; part <= total_parts; part++)
|
|
{
|
|
inject_xtra.partNum = part;
|
|
|
|
if (QMI_LOC_MAX_PREDICTED_ORBITS_PART_LEN_V02 > (length - len_injected))
|
|
{
|
|
inject_xtra.partData_len = length - len_injected;
|
|
}
|
|
else
|
|
{
|
|
inject_xtra.partData_len = QMI_LOC_MAX_PREDICTED_ORBITS_PART_LEN_V02;
|
|
}
|
|
|
|
// copy data into the message
|
|
memcpy(inject_xtra.partData, data+len_injected, inject_xtra.partData_len);
|
|
|
|
LOC_LOGD("[%s:%d] part %d/%d, len = %d, total injected = %d\n",
|
|
__func__, __LINE__,
|
|
inject_xtra.partNum, total_parts, inject_xtra.partData_len,
|
|
len_injected);
|
|
|
|
status = loc_sync_send_req( clientHandle,
|
|
QMI_LOC_INJECT_PREDICTED_ORBITS_DATA_REQ_V02,
|
|
req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
|
|
QMI_LOC_INJECT_PREDICTED_ORBITS_DATA_IND_V02,
|
|
&inject_xtra_ind);
|
|
|
|
if (status != eLOC_CLIENT_SUCCESS ||
|
|
eQMI_LOC_SUCCESS_V02 != inject_xtra_ind.status ||
|
|
inject_xtra.partNum != inject_xtra_ind.partNum)
|
|
{
|
|
LOC_LOGE ("%s:%d]: failed status = %s, inject_pos_ind.status = %s,"
|
|
" part num = %d, ind.partNum = %d\n", __func__, __LINE__,
|
|
loc_get_v02_client_status_name(status),
|
|
loc_get_v02_qmi_status_name(inject_xtra_ind.status),
|
|
inject_xtra.partNum, inject_xtra_ind.partNum);
|
|
|
|
return LOC_API_ADAPTER_ERR_GENERAL_FAILURE;
|
|
break;
|
|
}
|
|
|
|
len_injected += inject_xtra.partData_len;
|
|
LOC_LOGD("%s:%d]: XTRA injected length: %d\n", __func__, __LINE__,
|
|
len_injected);
|
|
}
|
|
|
|
return LOC_API_ADAPTER_ERR_SUCCESS;
|
|
}
|
|
|
|
/* Request the Xtra Server Url from the modem */
|
|
enum loc_api_adapter_err LocApiV02 :: requestXtraServer()
|
|
{
|
|
locClientStatusEnumType status = eLOC_CLIENT_SUCCESS;
|
|
|
|
locClientReqUnionType req_union;
|
|
qmiLocGetPredictedOrbitsDataSourceIndMsgT_v02 request_xtra_server_ind;
|
|
|
|
status = loc_sync_send_req( clientHandle,
|
|
QMI_LOC_GET_PREDICTED_ORBITS_DATA_SOURCE_REQ_V02,
|
|
req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
|
|
QMI_LOC_GET_PREDICTED_ORBITS_DATA_SOURCE_IND_V02,
|
|
&request_xtra_server_ind);
|
|
|
|
if (status != eLOC_CLIENT_SUCCESS ||
|
|
eQMI_LOC_SUCCESS_V02 != request_xtra_server_ind.status ||
|
|
false == request_xtra_server_ind.serverList_valid ||
|
|
0 == request_xtra_server_ind.serverList.serverList_len)
|
|
{
|
|
return LOC_API_ADAPTER_ERR_GENERAL_FAILURE;
|
|
}
|
|
|
|
|
|
if (request_xtra_server_ind.serverList.serverList_len == 1)
|
|
{
|
|
reportXtraServer(request_xtra_server_ind.serverList.serverList[0].serverUrl,
|
|
"",
|
|
"",
|
|
QMI_LOC_MAX_SERVER_ADDR_LENGTH_V02);
|
|
}
|
|
else if (request_xtra_server_ind.serverList.serverList_len == 2)
|
|
{
|
|
reportXtraServer(request_xtra_server_ind.serverList.serverList[0].serverUrl,
|
|
request_xtra_server_ind.serverList.serverList[1].serverUrl,
|
|
"",
|
|
QMI_LOC_MAX_SERVER_ADDR_LENGTH_V02);
|
|
}
|
|
else
|
|
{
|
|
reportXtraServer(request_xtra_server_ind.serverList.serverList[0].serverUrl,
|
|
request_xtra_server_ind.serverList.serverList[1].serverUrl,
|
|
request_xtra_server_ind.serverList.serverList[2].serverUrl,
|
|
QMI_LOC_MAX_SERVER_ADDR_LENGTH_V02);
|
|
}
|
|
|
|
return LOC_API_ADAPTER_ERR_SUCCESS;
|
|
}
|
|
|
|
enum loc_api_adapter_err LocApiV02 :: atlOpenStatus(
|
|
int handle, int is_succ, char* apn, AGpsBearerType bear,
|
|
AGpsType agpsType)
|
|
{
|
|
locClientStatusEnumType result = eLOC_CLIENT_SUCCESS;
|
|
locClientReqUnionType req_union;
|
|
qmiLocInformLocationServerConnStatusReqMsgT_v02 conn_status_req;
|
|
qmiLocInformLocationServerConnStatusIndMsgT_v02 conn_status_ind;
|
|
|
|
|
|
LOC_LOGD("%s:%d]: ATL open handle = %d, is_succ = %d, "
|
|
"APN = [%s], bearer = %d \n", __func__, __LINE__,
|
|
handle, is_succ, apn, bear);
|
|
|
|
memset(&conn_status_req, 0, sizeof(conn_status_req));
|
|
memset(&conn_status_ind, 0, sizeof(conn_status_ind));
|
|
|
|
// Fill in data
|
|
conn_status_req.connHandle = handle;
|
|
|
|
conn_status_req.requestType = eQMI_LOC_SERVER_REQUEST_OPEN_V02;
|
|
|
|
if(is_succ)
|
|
{
|
|
conn_status_req.statusType = eQMI_LOC_SERVER_REQ_STATUS_SUCCESS_V02;
|
|
|
|
if(apn != NULL)
|
|
strlcpy(conn_status_req.apnProfile.apnName, apn,
|
|
sizeof(conn_status_req.apnProfile.apnName) );
|
|
|
|
switch(bear)
|
|
{
|
|
case AGPS_APN_BEARER_IPV4:
|
|
conn_status_req.apnProfile.pdnType =
|
|
eQMI_LOC_APN_PROFILE_PDN_TYPE_IPV4_V02;
|
|
conn_status_req.apnProfile_valid = 1;
|
|
break;
|
|
|
|
case AGPS_APN_BEARER_IPV6:
|
|
conn_status_req.apnProfile.pdnType =
|
|
eQMI_LOC_APN_PROFILE_PDN_TYPE_IPV6_V02;
|
|
conn_status_req.apnProfile_valid = 1;
|
|
break;
|
|
|
|
case AGPS_APN_BEARER_IPV4V6:
|
|
conn_status_req.apnProfile.pdnType =
|
|
eQMI_LOC_APN_PROFILE_PDN_TYPE_IPV4V6_V02;
|
|
conn_status_req.apnProfile_valid = 1;
|
|
break;
|
|
|
|
case AGPS_APN_BEARER_INVALID:
|
|
conn_status_req.apnProfile_valid = 0;
|
|
break;
|
|
|
|
default:
|
|
LOC_LOGE("%s:%d]:invalid bearer type\n",__func__,__LINE__);
|
|
conn_status_req.apnProfile_valid = 0;
|
|
return LOC_API_ADAPTER_ERR_INVALID_HANDLE;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
conn_status_req.statusType = eQMI_LOC_SERVER_REQ_STATUS_FAILURE_V02;
|
|
}
|
|
|
|
req_union.pInformLocationServerConnStatusReq = &conn_status_req;
|
|
|
|
result = loc_sync_send_req(clientHandle,
|
|
QMI_LOC_INFORM_LOCATION_SERVER_CONN_STATUS_REQ_V02,
|
|
req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
|
|
QMI_LOC_INFORM_LOCATION_SERVER_CONN_STATUS_IND_V02,
|
|
&conn_status_ind);
|
|
|
|
if(result != eLOC_CLIENT_SUCCESS ||
|
|
eQMI_LOC_SUCCESS_V02 != conn_status_ind.status)
|
|
{
|
|
LOC_LOGE ("%s:%d]: Error status = %s, ind..status = %s ",
|
|
__func__, __LINE__,
|
|
loc_get_v02_client_status_name(result),
|
|
loc_get_v02_qmi_status_name(conn_status_ind.status));
|
|
|
|
return LOC_API_ADAPTER_ERR_GENERAL_FAILURE;
|
|
}
|
|
|
|
return LOC_API_ADAPTER_ERR_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
/* close atl connection */
|
|
enum loc_api_adapter_err LocApiV02 :: atlCloseStatus(
|
|
int handle, int is_succ)
|
|
{
|
|
locClientStatusEnumType result = eLOC_CLIENT_SUCCESS;
|
|
locClientReqUnionType req_union;
|
|
qmiLocInformLocationServerConnStatusReqMsgT_v02 conn_status_req;
|
|
qmiLocInformLocationServerConnStatusIndMsgT_v02 conn_status_ind;
|
|
|
|
LOC_LOGD("%s:%d]: ATL close handle = %d, is_succ = %d\n",
|
|
__func__, __LINE__, handle, is_succ);
|
|
|
|
memset(&conn_status_req, 0, sizeof(conn_status_req));
|
|
memset(&conn_status_ind, 0, sizeof(conn_status_ind));
|
|
|
|
// Fill in data
|
|
conn_status_req.connHandle = handle;
|
|
|
|
conn_status_req.requestType = eQMI_LOC_SERVER_REQUEST_CLOSE_V02;
|
|
|
|
if(is_succ)
|
|
{
|
|
conn_status_req.statusType = eQMI_LOC_SERVER_REQ_STATUS_SUCCESS_V02;
|
|
}
|
|
else
|
|
{
|
|
conn_status_req.statusType = eQMI_LOC_SERVER_REQ_STATUS_FAILURE_V02;
|
|
}
|
|
|
|
req_union.pInformLocationServerConnStatusReq = &conn_status_req;
|
|
|
|
result = loc_sync_send_req(clientHandle,
|
|
QMI_LOC_INFORM_LOCATION_SERVER_CONN_STATUS_REQ_V02,
|
|
req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
|
|
QMI_LOC_INFORM_LOCATION_SERVER_CONN_STATUS_IND_V02,
|
|
&conn_status_ind);
|
|
|
|
if(result != eLOC_CLIENT_SUCCESS ||
|
|
eQMI_LOC_SUCCESS_V02 != conn_status_ind.status)
|
|
{
|
|
LOC_LOGE ("%s:%d]: Error status = %s, ind..status = %s ",
|
|
__func__, __LINE__,
|
|
loc_get_v02_client_status_name(result),
|
|
loc_get_v02_qmi_status_name(conn_status_ind.status));
|
|
|
|
return LOC_API_ADAPTER_ERR_GENERAL_FAILURE;
|
|
}
|
|
|
|
return LOC_API_ADAPTER_ERR_SUCCESS;
|
|
}
|
|
|
|
/* set the SUPL version */
|
|
enum loc_api_adapter_err LocApiV02 :: setSUPLVersion(uint32_t version)
|
|
{
|
|
locClientStatusEnumType result = eLOC_CLIENT_SUCCESS;
|
|
locClientReqUnionType req_union;
|
|
|
|
qmiLocSetProtocolConfigParametersReqMsgT_v02 supl_config_req;
|
|
qmiLocSetProtocolConfigParametersIndMsgT_v02 supl_config_ind;
|
|
|
|
LOC_LOGD("%s:%d]: supl version = %d\n", __func__, __LINE__, version);
|
|
|
|
|
|
memset(&supl_config_req, 0, sizeof(supl_config_req));
|
|
memset(&supl_config_ind, 0, sizeof(supl_config_ind));
|
|
|
|
supl_config_req.suplVersion_valid = 1;
|
|
// SUPL version from MSByte to LSByte:
|
|
// (reserved)(major version)(minor version)(serviceIndicator)
|
|
|
|
supl_config_req.suplVersion = (version == 0x00020000)?
|
|
eQMI_LOC_SUPL_VERSION_2_0_V02 : eQMI_LOC_SUPL_VERSION_1_0_V02;
|
|
|
|
req_union.pSetProtocolConfigParametersReq = &supl_config_req;
|
|
|
|
result = loc_sync_send_req(clientHandle,
|
|
QMI_LOC_SET_PROTOCOL_CONFIG_PARAMETERS_REQ_V02,
|
|
req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
|
|
QMI_LOC_SET_PROTOCOL_CONFIG_PARAMETERS_IND_V02,
|
|
&supl_config_ind);
|
|
|
|
if(result != eLOC_CLIENT_SUCCESS ||
|
|
eQMI_LOC_SUCCESS_V02 != supl_config_ind.status)
|
|
{
|
|
LOC_LOGE ("%s:%d]: Error status = %s, ind..status = %s ",
|
|
__func__, __LINE__,
|
|
loc_get_v02_client_status_name(result),
|
|
loc_get_v02_qmi_status_name(supl_config_ind.status));
|
|
|
|
return LOC_API_ADAPTER_ERR_GENERAL_FAILURE;
|
|
}
|
|
|
|
return LOC_API_ADAPTER_ERR_SUCCESS;
|
|
}
|
|
|
|
/* set the configuration for LTE positioning profile (LPP) */
|
|
enum loc_api_adapter_err LocApiV02 :: setLPPConfig(uint32_t profile)
|
|
{
|
|
locClientStatusEnumType result = eLOC_CLIENT_SUCCESS;
|
|
locClientReqUnionType req_union;
|
|
qmiLocSetProtocolConfigParametersReqMsgT_v02 lpp_config_req;
|
|
qmiLocSetProtocolConfigParametersIndMsgT_v02 lpp_config_ind;
|
|
|
|
LOC_LOGD("%s:%d]: lpp profile = %d\n", __func__, __LINE__, profile);
|
|
|
|
memset(&lpp_config_req, 0, sizeof(lpp_config_req));
|
|
memset(&lpp_config_ind, 0, sizeof(lpp_config_ind));
|
|
|
|
lpp_config_req.lppConfig_valid = 1;
|
|
|
|
lpp_config_req.lppConfig = profile;
|
|
|
|
req_union.pSetProtocolConfigParametersReq = &lpp_config_req;
|
|
|
|
result = loc_sync_send_req(clientHandle,
|
|
QMI_LOC_SET_PROTOCOL_CONFIG_PARAMETERS_REQ_V02,
|
|
req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
|
|
QMI_LOC_SET_PROTOCOL_CONFIG_PARAMETERS_IND_V02,
|
|
&lpp_config_ind);
|
|
|
|
if(result != eLOC_CLIENT_SUCCESS ||
|
|
eQMI_LOC_SUCCESS_V02 != lpp_config_ind.status)
|
|
{
|
|
LOC_LOGE ("%s:%d]: Error status = %s, ind..status = %s ",
|
|
__func__, __LINE__,
|
|
loc_get_v02_client_status_name(result),
|
|
loc_get_v02_qmi_status_name(lpp_config_ind.status));
|
|
|
|
return LOC_API_ADAPTER_ERR_GENERAL_FAILURE;
|
|
}
|
|
return LOC_API_ADAPTER_ERR_SUCCESS;
|
|
}
|
|
|
|
/* set the Sensor Configuration */
|
|
enum loc_api_adapter_err LocApiV02 :: setSensorControlConfig(int sensorsDisabled)
|
|
{
|
|
locClientStatusEnumType result = eLOC_CLIENT_SUCCESS;
|
|
locClientReqUnionType req_union;
|
|
|
|
qmiLocSetSensorControlConfigReqMsgT_v02 sensor_config_req;
|
|
qmiLocSetSensorControlConfigIndMsgT_v02 sensor_config_ind;
|
|
|
|
LOC_LOGD("%s:%d]: sensors disabled = %d\n", __func__, __LINE__, sensorsDisabled);
|
|
|
|
memset(&sensor_config_req, 0, sizeof(sensor_config_req));
|
|
memset(&sensor_config_ind, 0, sizeof(sensor_config_ind));
|
|
|
|
sensor_config_req.sensorsUsage_valid = 1;
|
|
sensor_config_req.sensorsUsage = (sensorsDisabled == 1) ? eQMI_LOC_SENSOR_CONFIG_SENSOR_USE_DISABLE_V02
|
|
: eQMI_LOC_SENSOR_CONFIG_SENSOR_USE_ENABLE_V02;
|
|
|
|
req_union.pSetSensorControlConfigReq = &sensor_config_req;
|
|
|
|
result = loc_sync_send_req(clientHandle,
|
|
QMI_LOC_SET_SENSOR_CONTROL_CONFIG_REQ_V02,
|
|
req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
|
|
QMI_LOC_SET_SENSOR_CONTROL_CONFIG_IND_V02,
|
|
&sensor_config_ind);
|
|
|
|
if(result != eLOC_CLIENT_SUCCESS ||
|
|
eQMI_LOC_SUCCESS_V02 != sensor_config_ind.status)
|
|
{
|
|
LOC_LOGE ("%s:%d]: Error status = %s, ind..status = %s ",
|
|
__func__, __LINE__,
|
|
loc_get_v02_client_status_name(result),
|
|
loc_get_v02_qmi_status_name(sensor_config_ind.status));
|
|
|
|
return LOC_API_ADAPTER_ERR_GENERAL_FAILURE;
|
|
}
|
|
|
|
return LOC_API_ADAPTER_ERR_SUCCESS;
|
|
}
|
|
|
|
/* set the Sensor Properties */
|
|
enum loc_api_adapter_err LocApiV02 :: 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)
|
|
{
|
|
locClientStatusEnumType result = eLOC_CLIENT_SUCCESS;
|
|
locClientReqUnionType req_union;
|
|
|
|
qmiLocSetSensorPropertiesReqMsgT_v02 sensor_prop_req;
|
|
qmiLocSetSensorPropertiesIndMsgT_v02 sensor_prop_ind;
|
|
|
|
LOC_LOGI("%s:%d]: sensors prop: gyroBiasRandomWalk = %f, accelRandomWalk = %f, "
|
|
"angleRandomWalk = %f, rateRandomWalk = %f, velocityRandomWalk = %f\n",
|
|
__func__, __LINE__, gyroBiasVarianceRandomWalk, accelBiasVarianceRandomWalk,
|
|
angleBiasVarianceRandomWalk, rateBiasVarianceRandomWalk, velocityBiasVarianceRandomWalk);
|
|
|
|
memset(&sensor_prop_req, 0, sizeof(sensor_prop_req));
|
|
memset(&sensor_prop_ind, 0, sizeof(sensor_prop_ind));
|
|
|
|
/* Set the validity bit and value for each sensor property */
|
|
sensor_prop_req.gyroBiasVarianceRandomWalk_valid = gyroBiasVarianceRandomWalk_valid;
|
|
sensor_prop_req.gyroBiasVarianceRandomWalk = gyroBiasVarianceRandomWalk;
|
|
|
|
sensor_prop_req.accelerationRandomWalkSpectralDensity_valid = accelBiasVarianceRandomWalk_valid;
|
|
sensor_prop_req.accelerationRandomWalkSpectralDensity = accelBiasVarianceRandomWalk;
|
|
|
|
sensor_prop_req.angleRandomWalkSpectralDensity_valid = angleBiasVarianceRandomWalk_valid;
|
|
sensor_prop_req.angleRandomWalkSpectralDensity = angleBiasVarianceRandomWalk;
|
|
|
|
sensor_prop_req.rateRandomWalkSpectralDensity_valid = rateBiasVarianceRandomWalk_valid;
|
|
sensor_prop_req.rateRandomWalkSpectralDensity = rateBiasVarianceRandomWalk;
|
|
|
|
sensor_prop_req.velocityRandomWalkSpectralDensity_valid = velocityBiasVarianceRandomWalk_valid;
|
|
sensor_prop_req.velocityRandomWalkSpectralDensity = velocityBiasVarianceRandomWalk;
|
|
|
|
req_union.pSetSensorPropertiesReq = &sensor_prop_req;
|
|
|
|
result = loc_sync_send_req(clientHandle,
|
|
QMI_LOC_SET_SENSOR_PROPERTIES_REQ_V02,
|
|
req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
|
|
QMI_LOC_SET_SENSOR_PROPERTIES_IND_V02,
|
|
&sensor_prop_ind);
|
|
|
|
if(result != eLOC_CLIENT_SUCCESS ||
|
|
eQMI_LOC_SUCCESS_V02 != sensor_prop_ind.status)
|
|
{
|
|
LOC_LOGE ("%s:%d]: Error status = %s, ind..status = %s ",
|
|
__func__, __LINE__,
|
|
loc_get_v02_client_status_name(result),
|
|
loc_get_v02_qmi_status_name(sensor_prop_ind.status));
|
|
|
|
return LOC_API_ADAPTER_ERR_GENERAL_FAILURE;
|
|
}
|
|
|
|
return LOC_API_ADAPTER_ERR_SUCCESS;
|
|
}
|
|
|
|
/* set the Sensor Performance Config */
|
|
enum loc_api_adapter_err LocApiV02 :: setSensorPerfControlConfig(int controlMode,
|
|
int accelSamplesPerBatch, int accelBatchesPerSec,
|
|
int gyroSamplesPerBatch, int gyroBatchesPerSec,
|
|
int accelSamplesPerBatchHigh, int accelBatchesPerSecHigh,
|
|
int gyroSamplesPerBatchHigh, int gyroBatchesPerSecHigh,
|
|
int algorithmConfig)
|
|
{
|
|
locClientStatusEnumType result = eLOC_CLIENT_SUCCESS;
|
|
locClientReqUnionType req_union;
|
|
|
|
qmiLocSetSensorPerformanceControlConfigReqMsgT_v02 sensor_perf_config_req;
|
|
qmiLocSetSensorPerformanceControlConfigIndMsgT_v02 sensor_perf_config_ind;
|
|
|
|
LOC_LOGD("%s:%d]: Sensor Perf Control Config (performanceControlMode)(%u) "
|
|
"accel(#smp,#batches) (%u,%u) gyro(#smp,#batches) (%u,%u) "
|
|
"accel_high(#smp,#batches) (%u,%u) gyro_high(#smp,#batches) (%u,%u) "
|
|
"algorithmConfig(%u)\n",
|
|
__FUNCTION__,
|
|
__LINE__,
|
|
controlMode,
|
|
accelSamplesPerBatch,
|
|
accelBatchesPerSec,
|
|
gyroSamplesPerBatch,
|
|
gyroBatchesPerSec,
|
|
accelSamplesPerBatchHigh,
|
|
accelBatchesPerSecHigh,
|
|
gyroSamplesPerBatchHigh,
|
|
gyroBatchesPerSecHigh,
|
|
algorithmConfig
|
|
);
|
|
|
|
memset(&sensor_perf_config_req, 0, sizeof(sensor_perf_config_req));
|
|
memset(&sensor_perf_config_ind, 0, sizeof(sensor_perf_config_ind));
|
|
|
|
sensor_perf_config_req.performanceControlMode_valid = 1;
|
|
sensor_perf_config_req.performanceControlMode = (qmiLocSensorPerformanceControlModeEnumT_v02)controlMode;
|
|
sensor_perf_config_req.accelSamplingSpec_valid = 1;
|
|
sensor_perf_config_req.accelSamplingSpec.batchesPerSecond = accelBatchesPerSec;
|
|
sensor_perf_config_req.accelSamplingSpec.samplesPerBatch = accelSamplesPerBatch;
|
|
sensor_perf_config_req.gyroSamplingSpec_valid = 1;
|
|
sensor_perf_config_req.gyroSamplingSpec.batchesPerSecond = gyroBatchesPerSec;
|
|
sensor_perf_config_req.gyroSamplingSpec.samplesPerBatch = gyroSamplesPerBatch;
|
|
sensor_perf_config_req.accelSamplingSpecHigh_valid = 1;
|
|
sensor_perf_config_req.accelSamplingSpecHigh.batchesPerSecond = accelBatchesPerSecHigh;
|
|
sensor_perf_config_req.accelSamplingSpecHigh.samplesPerBatch = accelSamplesPerBatchHigh;
|
|
sensor_perf_config_req.gyroSamplingSpecHigh_valid = 1;
|
|
sensor_perf_config_req.gyroSamplingSpecHigh.batchesPerSecond = gyroBatchesPerSecHigh;
|
|
sensor_perf_config_req.gyroSamplingSpecHigh.samplesPerBatch = gyroSamplesPerBatchHigh;
|
|
sensor_perf_config_req.algorithmConfig_valid = 1;
|
|
sensor_perf_config_req.algorithmConfig = algorithmConfig;
|
|
|
|
req_union.pSetSensorPerformanceControlConfigReq = &sensor_perf_config_req;
|
|
|
|
result = loc_sync_send_req(clientHandle,
|
|
QMI_LOC_SET_SENSOR_PERFORMANCE_CONTROL_CONFIGURATION_REQ_V02,
|
|
req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
|
|
QMI_LOC_SET_SENSOR_PERFORMANCE_CONTROL_CONFIGURATION_IND_V02,
|
|
&sensor_perf_config_ind);
|
|
|
|
if(result != eLOC_CLIENT_SUCCESS ||
|
|
eQMI_LOC_SUCCESS_V02 != sensor_perf_config_ind.status)
|
|
{
|
|
LOC_LOGE ("%s:%d]: Error status = %s, ind..status = %s ",
|
|
__func__, __LINE__,
|
|
loc_get_v02_client_status_name(result),
|
|
loc_get_v02_qmi_status_name(sensor_perf_config_ind.status));
|
|
|
|
return LOC_API_ADAPTER_ERR_GENERAL_FAILURE;
|
|
}
|
|
|
|
return LOC_API_ADAPTER_ERR_SUCCESS;
|
|
}
|
|
|
|
/* set the External Power Config */
|
|
enum loc_api_adapter_err LocApiV02 :: setExtPowerConfig(int isBatteryCharging)
|
|
{
|
|
locClientStatusEnumType result = eLOC_CLIENT_SUCCESS;
|
|
locClientReqUnionType req_union;
|
|
|
|
qmiLocSetExternalPowerConfigReqMsgT_v02 ext_pwr_req;
|
|
qmiLocGetExternalPowerConfigIndMsgT_v02 ext_pwr_ind;
|
|
|
|
LOC_LOGI("%s:%d]: Ext Pwr Config (isBatteryCharging)(%u)",
|
|
__FUNCTION__,
|
|
__LINE__,
|
|
isBatteryCharging
|
|
);
|
|
|
|
memset(&ext_pwr_req, 0, sizeof(ext_pwr_req));
|
|
memset(&ext_pwr_ind, 0, sizeof(ext_pwr_ind));
|
|
|
|
switch(isBatteryCharging)
|
|
{
|
|
/* Charging */
|
|
case 1:
|
|
ext_pwr_req.externalPowerState = eQMI_LOC_EXTERNAL_POWER_CONNECTED_V02;
|
|
break;
|
|
|
|
/* Not charging */
|
|
case 0:
|
|
ext_pwr_req.externalPowerState = eQMI_LOC_EXTERNAL_POWER_NOT_CONNECTED_V02;
|
|
break;
|
|
|
|
default:
|
|
LOC_LOGE("%s:%d]: Invalid ext power state = %d!",
|
|
__FUNCTION__,
|
|
__LINE__,
|
|
isBatteryCharging);
|
|
return LOC_API_ADAPTER_ERR_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
|
|
req_union.pSetExternalPowerConfigReq = &ext_pwr_req;
|
|
|
|
result = loc_sync_send_req(clientHandle,
|
|
QMI_LOC_SET_EXTERNAL_POWER_CONFIG_REQ_V02,
|
|
req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
|
|
QMI_LOC_SET_EXTERNAL_POWER_CONFIG_IND_V02,
|
|
&ext_pwr_ind);
|
|
|
|
if(result != eLOC_CLIENT_SUCCESS ||
|
|
eQMI_LOC_SUCCESS_V02 != ext_pwr_ind.status)
|
|
{
|
|
LOC_LOGE ("%s:%d]: Error status = %d, ind..status = %d ",
|
|
__func__, __LINE__, result, ext_pwr_ind.status);
|
|
|
|
return LOC_API_ADAPTER_ERR_GENERAL_FAILURE;
|
|
}
|
|
|
|
return LOC_API_ADAPTER_ERR_SUCCESS;
|
|
}
|
|
|
|
/* set the Positioning Protocol on A-GLONASS system */
|
|
enum loc_api_adapter_err LocApiV02 :: setAGLONASSProtocol(unsigned long aGlonassProtocol)
|
|
{
|
|
locClientStatusEnumType result = eLOC_CLIENT_SUCCESS;
|
|
locClientReqUnionType req_union;
|
|
qmiLocSetProtocolConfigParametersReqMsgT_v02 aGlonassProtocol_req;
|
|
qmiLocSetProtocolConfigParametersIndMsgT_v02 aGlonassProtocol_ind;
|
|
|
|
memset(&aGlonassProtocol_req, 0, sizeof(aGlonassProtocol_req));
|
|
memset(&aGlonassProtocol_ind, 0, sizeof(aGlonassProtocol_ind));
|
|
|
|
aGlonassProtocol_req.assistedGlonassProtocolMask_valid = 1;
|
|
aGlonassProtocol_req.assistedGlonassProtocolMask = aGlonassProtocol;
|
|
|
|
req_union.pSetProtocolConfigParametersReq = &aGlonassProtocol_req;
|
|
|
|
LOC_LOGD("%s:%d]: aGlonassProtocolMask = 0x%x\n", __func__, __LINE__,
|
|
aGlonassProtocol_req.assistedGlonassProtocolMask);
|
|
|
|
result = loc_sync_send_req(clientHandle,
|
|
QMI_LOC_SET_PROTOCOL_CONFIG_PARAMETERS_REQ_V02,
|
|
req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
|
|
QMI_LOC_SET_PROTOCOL_CONFIG_PARAMETERS_IND_V02,
|
|
&aGlonassProtocol_ind);
|
|
|
|
if(result != eLOC_CLIENT_SUCCESS ||
|
|
eQMI_LOC_SUCCESS_V02 != aGlonassProtocol_ind.status)
|
|
{
|
|
LOC_LOGE ("%s:%d]: Error status = %s, ind..status = %s ",
|
|
__func__, __LINE__,
|
|
loc_get_v02_client_status_name(result),
|
|
loc_get_v02_qmi_status_name(aGlonassProtocol_ind.status));
|
|
|
|
return LOC_API_ADAPTER_ERR_GENERAL_FAILURE;
|
|
}
|
|
return LOC_API_ADAPTER_ERR_SUCCESS;
|
|
}
|
|
|
|
/* Convert event mask from loc eng to loc_api_v02 format */
|
|
locClientEventMaskType LocApiV02 :: convertMask(
|
|
LOC_API_ADAPTER_EVENT_MASK_T mask)
|
|
{
|
|
locClientEventMaskType eventMask = 0;
|
|
LOC_LOGD("%s:%d]: adapter mask = %u\n", __func__, __LINE__, mask);
|
|
|
|
if (mask & LOC_API_ADAPTER_BIT_PARSED_POSITION_REPORT)
|
|
eventMask |= QMI_LOC_EVENT_MASK_POSITION_REPORT_V02;
|
|
|
|
if (mask & LOC_API_ADAPTER_BIT_SATELLITE_REPORT)
|
|
eventMask |= QMI_LOC_EVENT_MASK_GNSS_SV_INFO_V02;
|
|
|
|
/* treat NMEA_1Hz and NMEA_POSITION_REPORT the same*/
|
|
if ((mask & LOC_API_ADAPTER_BIT_NMEA_POSITION_REPORT) ||
|
|
(mask & LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT) )
|
|
eventMask |= QMI_LOC_EVENT_MASK_NMEA_V02;
|
|
|
|
if (mask & LOC_API_ADAPTER_BIT_NI_NOTIFY_VERIFY_REQUEST)
|
|
eventMask |= QMI_LOC_EVENT_MASK_NI_NOTIFY_VERIFY_REQ_V02;
|
|
|
|
if (mask & LOC_API_ADAPTER_BIT_ASSISTANCE_DATA_REQUEST)
|
|
{
|
|
// TBD: This needs to be decoupled in the HAL
|
|
eventMask |= QMI_LOC_EVENT_MASK_INJECT_PREDICTED_ORBITS_REQ_V02;
|
|
eventMask |= QMI_LOC_EVENT_MASK_INJECT_TIME_REQ_V02;
|
|
eventMask |= QMI_LOC_EVENT_MASK_INJECT_POSITION_REQ_V02;
|
|
}
|
|
|
|
if (mask & LOC_API_ADAPTER_BIT_STATUS_REPORT)
|
|
{
|
|
eventMask |= (QMI_LOC_EVENT_MASK_ENGINE_STATE_V02);
|
|
}
|
|
|
|
if (mask & LOC_API_ADAPTER_BIT_LOCATION_SERVER_REQUEST)
|
|
eventMask |= QMI_LOC_EVENT_MASK_LOCATION_SERVER_CONNECTION_REQ_V02;
|
|
|
|
if (mask & LOC_API_ADAPTER_REQUEST_WIFI)
|
|
eventMask |= QMI_LOC_EVENT_MASK_WIFI_REQ_V02;
|
|
|
|
if (mask & LOC_API_ADAPTER_SENSOR_STATUS)
|
|
eventMask |= QMI_LOC_EVENT_MASK_SENSOR_STREAMING_READY_STATUS_V02;
|
|
|
|
if (mask & LOC_API_ADAPTER_REQUEST_TIME_SYNC)
|
|
eventMask |= QMI_LOC_EVENT_MASK_TIME_SYNC_REQ_V02;
|
|
|
|
if (mask & LOC_API_ADAPTER_REPORT_SPI)
|
|
eventMask |= QMI_LOC_EVENT_MASK_SET_SPI_STREAMING_REPORT_V02;
|
|
|
|
if (mask & LOC_API_ADAPTER_REPORT_NI_GEOFENCE)
|
|
eventMask |= QMI_LOC_EVENT_MASK_NI_GEOFENCE_NOTIFICATION_V02;
|
|
|
|
if (mask & LOC_API_ADAPTER_GEOFENCE_GEN_ALERT)
|
|
eventMask |= QMI_LOC_EVENT_MASK_GEOFENCE_GEN_ALERT_V02;
|
|
|
|
if (mask & LOC_API_ADAPTER_REPORT_GENFENCE_BREACH)
|
|
eventMask |= QMI_LOC_EVENT_MASK_GEOFENCE_BREACH_NOTIFICATION_V02;
|
|
|
|
if (mask & LOC_API_ADAPTER_PEDOMETER_CTRL)
|
|
eventMask |= QMI_LOC_EVENT_MASK_PEDOMETER_CONTROL_V02;
|
|
|
|
if (mask & LOC_API_ADAPTER_MOTION_CTRL)
|
|
eventMask |= QMI_LOC_EVENT_MASK_MOTION_DATA_CONTROL_V02;
|
|
|
|
if (mask & LOC_API_ADAPTER_REQUEST_WIFI_AP_DATA)
|
|
eventMask |= QMI_LOC_EVENT_MASK_INJECT_WIFI_AP_DATA_REQ_V02;
|
|
|
|
if(mask & LOC_API_ADAPTER_BIT_BATCH_FULL)
|
|
eventMask |= QMI_LOC_EVENT_MASK_BATCH_FULL_NOTIFICATION_V02;
|
|
|
|
if(mask & LOC_API_ADAPTER_BIT_BATCHED_POSITION_REPORT)
|
|
eventMask |= QMI_LOC_EVENT_MASK_LIVE_BATCHED_POSITION_REPORT_V02;
|
|
|
|
return eventMask;
|
|
}
|
|
|
|
/* Convert error from loc_api_v02 to loc eng format*/
|
|
enum loc_api_adapter_err LocApiV02 :: convertErr(
|
|
locClientStatusEnumType status)
|
|
{
|
|
switch( status)
|
|
{
|
|
case LOC_API_ADAPTER_ERR_SUCCESS:
|
|
return LOC_API_ADAPTER_ERR_SUCCESS;
|
|
|
|
case eLOC_CLIENT_FAILURE_GENERAL:
|
|
return LOC_API_ADAPTER_ERR_GENERAL_FAILURE;
|
|
|
|
case eLOC_CLIENT_FAILURE_UNSUPPORTED:
|
|
return LOC_API_ADAPTER_ERR_UNSUPPORTED;
|
|
|
|
case eLOC_CLIENT_FAILURE_INVALID_PARAMETER:
|
|
return LOC_API_ADAPTER_ERR_INVALID_PARAMETER;
|
|
|
|
case eLOC_CLIENT_FAILURE_ENGINE_BUSY:
|
|
return LOC_API_ADAPTER_ERR_ENGINE_BUSY;
|
|
|
|
case eLOC_CLIENT_FAILURE_PHONE_OFFLINE:
|
|
return LOC_API_ADAPTER_ERR_PHONE_OFFLINE;
|
|
|
|
case eLOC_CLIENT_FAILURE_TIMEOUT:
|
|
return LOC_API_ADAPTER_ERR_TIMEOUT;
|
|
|
|
case eLOC_CLIENT_FAILURE_INVALID_HANDLE:
|
|
return LOC_API_ADAPTER_ERR_INVALID_HANDLE;
|
|
|
|
case eLOC_CLIENT_FAILURE_SERVICE_NOT_PRESENT:
|
|
return LOC_API_ADAPTER_ERR_SERVICE_NOT_PRESENT;
|
|
|
|
default:
|
|
return LOC_API_ADAPTER_ERR_FAILURE;
|
|
}
|
|
}
|
|
|
|
/* convert position report to loc eng format and send the converted
|
|
position to loc eng */
|
|
|
|
void LocApiV02 :: reportPosition (
|
|
const qmiLocEventPositionReportIndMsgT_v02 *location_report_ptr)
|
|
{
|
|
UlpLocation location;
|
|
LocPosTechMask tech_Mask = LOC_POS_TECH_MASK_DEFAULT;
|
|
LOC_LOGD("Reporting postion from V2 Adapter\n");
|
|
memset(&location, 0, sizeof (UlpLocation));
|
|
location.size = sizeof(location);
|
|
GpsLocationExtended locationExtended;
|
|
memset(&locationExtended, 0, sizeof (GpsLocationExtended));
|
|
locationExtended.size = sizeof(locationExtended);
|
|
// Process the position from final and intermediate reports
|
|
|
|
if( (location_report_ptr->sessionStatus == eQMI_LOC_SESS_STATUS_SUCCESS_V02) ||
|
|
(location_report_ptr->sessionStatus == eQMI_LOC_SESS_STATUS_IN_PROGRESS_V02)
|
|
)
|
|
{
|
|
// Latitude & Longitude
|
|
if( (location_report_ptr->latitude_valid == 1 ) &&
|
|
(location_report_ptr->longitude_valid == 1) &&
|
|
(location_report_ptr->latitude != 0 ||
|
|
location_report_ptr->longitude!= 0))
|
|
{
|
|
location.gpsLocation.flags |= GPS_LOCATION_HAS_LAT_LONG;
|
|
location.gpsLocation.latitude = location_report_ptr->latitude;
|
|
location.gpsLocation.longitude = location_report_ptr->longitude;
|
|
|
|
// Time stamp (UTC)
|
|
if(location_report_ptr->timestampUtc_valid == 1)
|
|
{
|
|
location.gpsLocation.timestamp = location_report_ptr->timestampUtc;
|
|
}
|
|
|
|
// Altitude
|
|
if(location_report_ptr->altitudeWrtEllipsoid_valid == 1 )
|
|
{
|
|
location.gpsLocation.flags |= GPS_LOCATION_HAS_ALTITUDE;
|
|
location.gpsLocation.altitude = location_report_ptr->altitudeWrtEllipsoid;
|
|
}
|
|
|
|
// Speed
|
|
if((location_report_ptr->speedHorizontal_valid == 1) &&
|
|
(location_report_ptr->speedVertical_valid ==1 ) )
|
|
{
|
|
location.gpsLocation.flags |= GPS_LOCATION_HAS_SPEED;
|
|
location.gpsLocation.speed = sqrt(
|
|
(location_report_ptr->speedHorizontal *
|
|
location_report_ptr->speedHorizontal) +
|
|
(location_report_ptr->speedVertical *
|
|
location_report_ptr->speedVertical) );
|
|
}
|
|
|
|
// Heading
|
|
if(location_report_ptr->heading_valid == 1)
|
|
{
|
|
location.gpsLocation.flags |= GPS_LOCATION_HAS_BEARING;
|
|
location.gpsLocation.bearing = location_report_ptr->heading;
|
|
}
|
|
|
|
// Uncertainty (circular)
|
|
if( (location_report_ptr->horUncCircular_valid ) )
|
|
{
|
|
location.gpsLocation.flags |= GPS_LOCATION_HAS_ACCURACY;
|
|
location.gpsLocation.accuracy = location_report_ptr->horUncCircular;
|
|
}
|
|
|
|
// Technology Mask
|
|
tech_Mask |= location_report_ptr->technologyMask;
|
|
|
|
//Mark the location source as from GNSS
|
|
location.gpsLocation.flags |= LOCATION_HAS_SOURCE_INFO;
|
|
location.position_source = ULP_LOCATION_IS_FROM_GNSS;
|
|
if (location_report_ptr->magneticDeviation_valid)
|
|
{
|
|
locationExtended.flags |= GPS_LOCATION_EXTENDED_HAS_MAG_DEV;
|
|
locationExtended.magneticDeviation = location_report_ptr->magneticDeviation;
|
|
}
|
|
|
|
if (location_report_ptr->DOP_valid)
|
|
{
|
|
locationExtended.flags |= GPS_LOCATION_EXTENDED_HAS_DOP;
|
|
locationExtended.pdop = location_report_ptr->DOP.PDOP;
|
|
locationExtended.hdop = location_report_ptr->DOP.HDOP;
|
|
locationExtended.vdop = location_report_ptr->DOP.VDOP;
|
|
}
|
|
|
|
if (location_report_ptr->altitudeWrtMeanSeaLevel_valid)
|
|
{
|
|
locationExtended.flags |= GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL;
|
|
locationExtended.altitudeMeanSeaLevel = location_report_ptr->altitudeWrtMeanSeaLevel;
|
|
}
|
|
|
|
if (location_report_ptr->vertUnc_valid)
|
|
{
|
|
locationExtended.flags |= GPS_LOCATION_EXTENDED_HAS_VERT_UNC;
|
|
locationExtended.vert_unc = location_report_ptr->vertUnc;
|
|
}
|
|
|
|
if (location_report_ptr->speedUnc_valid )
|
|
{
|
|
locationExtended.flags |= GPS_LOCATION_EXTENDED_HAS_SPEED_UNC;
|
|
locationExtended.speed_unc = location_report_ptr->speedUnc;
|
|
}
|
|
|
|
LocApiBase::reportPosition( location,
|
|
locationExtended,
|
|
(void*)location_report_ptr,
|
|
(location_report_ptr->sessionStatus
|
|
== eQMI_LOC_SESS_STATUS_IN_PROGRESS_V02 ?
|
|
LOC_SESS_INTERMEDIATE : LOC_SESS_SUCCESS),
|
|
tech_Mask);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LocApiBase::reportPosition(location,
|
|
locationExtended,
|
|
NULL,
|
|
LOC_SESS_FAILURE);
|
|
|
|
LOC_LOGD("%s:%d]: Ignoring position report with sess status = %d, "
|
|
"fix id = %u\n", __func__, __LINE__,
|
|
location_report_ptr->sessionStatus,
|
|
location_report_ptr->fixId );
|
|
}
|
|
}
|
|
|
|
/* convert satellite report to loc eng format and send the converted
|
|
report to loc eng */
|
|
void LocApiV02 :: reportSv (
|
|
const qmiLocEventGnssSvInfoIndMsgT_v02 *gnss_report_ptr)
|
|
{
|
|
GpsSvStatus SvStatus;
|
|
GpsLocationExtended locationExtended;
|
|
int num_svs_max, i;
|
|
const qmiLocSvInfoStructT_v02 *sv_info_ptr;
|
|
|
|
LOC_LOGV ("%s:%d]: num of sv = %d\n", __func__, __LINE__,
|
|
gnss_report_ptr->svList_len);
|
|
|
|
num_svs_max = 0;
|
|
memset (&SvStatus, 0, sizeof (GpsSvStatus));
|
|
memset(&locationExtended, 0, sizeof (GpsLocationExtended));
|
|
locationExtended.size = sizeof(locationExtended);
|
|
if(gnss_report_ptr->svList_valid == 1)
|
|
{
|
|
num_svs_max = gnss_report_ptr->svList_len;
|
|
if(num_svs_max > GPS_MAX_SVS)
|
|
{
|
|
num_svs_max = GPS_MAX_SVS;
|
|
}
|
|
SvStatus.num_svs = 0;
|
|
for(i = 0; i < num_svs_max; i++)
|
|
{
|
|
sv_info_ptr = &(gnss_report_ptr->svList[i]);
|
|
if((sv_info_ptr->validMask & QMI_LOC_SV_INFO_MASK_VALID_SYSTEM_V02) &&
|
|
(sv_info_ptr->validMask & QMI_LOC_SV_INFO_MASK_VALID_GNSS_SVID_V02)
|
|
&& (sv_info_ptr->gnssSvId != 0 ))
|
|
{
|
|
if(sv_info_ptr->system == eQMI_LOC_SV_SYSTEM_GPS_V02)
|
|
{
|
|
SvStatus.sv_list[SvStatus.num_svs].size = sizeof(GpsSvStatus);
|
|
SvStatus.sv_list[SvStatus.num_svs].prn = (int)sv_info_ptr->gnssSvId;
|
|
|
|
// We only have the data field to report gps eph and alm mask
|
|
if(sv_info_ptr->validMask &
|
|
QMI_LOC_SV_INFO_MASK_VALID_SVINFO_MASK_V02)
|
|
{
|
|
if(sv_info_ptr->svInfoMask &
|
|
QMI_LOC_SVINFO_MASK_HAS_EPHEMERIS_V02)
|
|
{
|
|
SvStatus.ephemeris_mask |= (1 << (sv_info_ptr->gnssSvId-1));
|
|
}
|
|
if(sv_info_ptr->svInfoMask &
|
|
QMI_LOC_SVINFO_MASK_HAS_ALMANAC_V02)
|
|
{
|
|
SvStatus.almanac_mask |= (1 << (sv_info_ptr->gnssSvId-1));
|
|
}
|
|
}
|
|
|
|
if((sv_info_ptr->validMask &
|
|
QMI_LOC_SV_INFO_MASK_VALID_PROCESS_STATUS_V02)
|
|
&&
|
|
(sv_info_ptr->svStatus == eQMI_LOC_SV_STATUS_TRACK_V02))
|
|
{
|
|
SvStatus.used_in_fix_mask |= (1 << (sv_info_ptr->gnssSvId-1));
|
|
}
|
|
}
|
|
// SBAS: GPS PRN: 120-151,
|
|
// In exteneded measurement report, we follow nmea standard,
|
|
// which is from 33-64.
|
|
else if(sv_info_ptr->system == eQMI_LOC_SV_SYSTEM_SBAS_V02)
|
|
{
|
|
SvStatus.sv_list[SvStatus.num_svs].prn =
|
|
sv_info_ptr->gnssSvId + 33 - 120;
|
|
}
|
|
// Gloness: Slot id: 1-32
|
|
// In extended measurement report, we follow nmea standard,
|
|
// which is 65-96
|
|
else if(sv_info_ptr->system == eQMI_LOC_SV_SYSTEM_GLONASS_V02)
|
|
{
|
|
SvStatus.sv_list[SvStatus.num_svs].prn =
|
|
sv_info_ptr->gnssSvId + (65-1);
|
|
}
|
|
//BeiDou: Slot id: 1-37
|
|
//In extended measurement report, we follow nmea standard,
|
|
//which is 201-237
|
|
else if(sv_info_ptr->system == eQMI_LOC_SV_SYSTEM_BDS_V02)
|
|
{
|
|
SvStatus.sv_list[SvStatus.num_svs].prn =
|
|
sv_info_ptr->gnssSvId;
|
|
}
|
|
// QZSS: PRN is 193 to 197
|
|
// In extended measurement report, we follow nmea standard,
|
|
// which is 193 to 197.
|
|
else if(sv_info_ptr->system == eQMI_LOC_SV_SYSTEM_QZSS_V02)
|
|
{
|
|
SvStatus.sv_list[SvStatus.num_svs].prn =
|
|
sv_info_ptr->gnssSvId;
|
|
}
|
|
// Unsupported SV system
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if(sv_info_ptr->validMask & QMI_LOC_SV_INFO_MASK_VALID_SNR_V02 )
|
|
{
|
|
SvStatus.sv_list[SvStatus.num_svs].snr = sv_info_ptr->snr;
|
|
}
|
|
|
|
if(sv_info_ptr->validMask & QMI_LOC_SV_INFO_MASK_VALID_ELEVATION_V02)
|
|
{
|
|
SvStatus.sv_list[SvStatus.num_svs].elevation = sv_info_ptr->elevation;
|
|
}
|
|
|
|
if(sv_info_ptr->validMask & QMI_LOC_SV_INFO_MASK_VALID_AZIMUTH_V02)
|
|
{
|
|
SvStatus.sv_list[SvStatus.num_svs].azimuth = sv_info_ptr->azimuth;
|
|
}
|
|
|
|
SvStatus.num_svs++;
|
|
}
|
|
}
|
|
|
|
if (SvStatus.num_svs >= 0)
|
|
{
|
|
LOC_LOGV ("%s:%d]: firing SV callback\n", __func__, __LINE__);
|
|
LocApiBase::reportSv(SvStatus,
|
|
locationExtended,
|
|
(void*)gnss_report_ptr);
|
|
}
|
|
}
|
|
|
|
/* convert engine state report to loc eng format and send the converted
|
|
report to loc eng */
|
|
void LocApiV02 :: reportEngineState (
|
|
const qmiLocEventEngineStateIndMsgT_v02 *engine_state_ptr)
|
|
{
|
|
|
|
LOC_LOGV("%s:%d]: state = %d\n", __func__, __LINE__,
|
|
engine_state_ptr->engineState);
|
|
|
|
if (engine_state_ptr->engineState == eQMI_LOC_ENGINE_STATE_ON_V02)
|
|
{
|
|
reportStatus(GPS_STATUS_ENGINE_ON);
|
|
reportStatus(GPS_STATUS_SESSION_BEGIN);
|
|
}
|
|
else if (engine_state_ptr->engineState == eQMI_LOC_ENGINE_STATE_OFF_V02)
|
|
{
|
|
reportStatus(GPS_STATUS_SESSION_END);
|
|
reportStatus(GPS_STATUS_ENGINE_OFF);
|
|
}
|
|
else
|
|
{
|
|
reportStatus(GPS_STATUS_NONE);
|
|
}
|
|
|
|
}
|
|
|
|
/* convert fix session state report to loc eng format and send the converted
|
|
report to loc eng */
|
|
void LocApiV02 :: reportFixSessionState (
|
|
const qmiLocEventFixSessionStateIndMsgT_v02 *fix_session_state_ptr)
|
|
{
|
|
GpsStatusValue status;
|
|
LOC_LOGD("%s:%d]: state = %d\n", __func__, __LINE__,
|
|
fix_session_state_ptr->sessionState);
|
|
|
|
status = GPS_STATUS_NONE;
|
|
if (fix_session_state_ptr->sessionState == eQMI_LOC_FIX_SESSION_STARTED_V02)
|
|
{
|
|
status = GPS_STATUS_SESSION_BEGIN;
|
|
}
|
|
else if (fix_session_state_ptr->sessionState
|
|
== eQMI_LOC_FIX_SESSION_FINISHED_V02)
|
|
{
|
|
status = GPS_STATUS_SESSION_END;
|
|
}
|
|
reportStatus(status);
|
|
}
|
|
|
|
/* convert NMEA report to loc eng format and send the converted
|
|
report to loc eng */
|
|
void LocApiV02 :: reportNmea (
|
|
const qmiLocEventNmeaIndMsgT_v02 *nmea_report_ptr)
|
|
{
|
|
|
|
LocApiBase::reportNmea(nmea_report_ptr->nmea,
|
|
strlen(nmea_report_ptr->nmea));
|
|
|
|
LOC_LOGD("%s:%d]: $%c%c%c\n", __func__, __LINE__,
|
|
nmea_report_ptr->nmea[3], nmea_report_ptr->nmea[4],
|
|
nmea_report_ptr->nmea[5]);
|
|
}
|
|
|
|
/* convert and report an ATL request to loc engine */
|
|
void LocApiV02 :: reportAtlRequest(
|
|
const qmiLocEventLocationServerConnectionReqIndMsgT_v02 * server_request_ptr)
|
|
{
|
|
uint32_t connHandle = server_request_ptr->connHandle;
|
|
// service ATL open request; copy the WWAN type
|
|
if(server_request_ptr->requestType == eQMI_LOC_SERVER_REQUEST_OPEN_V02 )
|
|
{
|
|
AGpsType agpsType;
|
|
switch(server_request_ptr->wwanType)
|
|
{
|
|
case eQMI_LOC_WWAN_TYPE_INTERNET_V02:
|
|
agpsType = AGPS_TYPE_WWAN_ANY;
|
|
requestATL(connHandle, agpsType);
|
|
break;
|
|
case eQMI_LOC_WWAN_TYPE_AGNSS_V02:
|
|
agpsType = AGPS_TYPE_SUPL;
|
|
requestATL(connHandle, agpsType);
|
|
break;
|
|
case eQMI_LOC_WWAN_TYPE_AGNSS_EMERGENCY_V02:
|
|
requestSuplES(connHandle);
|
|
break;
|
|
default:
|
|
agpsType = AGPS_TYPE_WWAN_ANY;
|
|
requestATL(connHandle, agpsType);
|
|
break;
|
|
}
|
|
}
|
|
// service the ATL close request
|
|
else if (server_request_ptr->requestType == eQMI_LOC_SERVER_REQUEST_CLOSE_V02)
|
|
{
|
|
releaseATL(connHandle);
|
|
}
|
|
}
|
|
|
|
/* conver the NI report to loc eng format and send t loc engine */
|
|
void LocApiV02 :: reportNiRequest(
|
|
const qmiLocEventNiNotifyVerifyReqIndMsgT_v02 *ni_req_ptr)
|
|
{
|
|
GpsNiNotification notif;
|
|
|
|
/* initialize the notification*/
|
|
memset(notif.extras, 0, sizeof notif.extras);
|
|
memset(notif.text, 0, sizeof notif.text);
|
|
memset(notif.requestor_id, 0, sizeof notif.requestor_id);
|
|
|
|
/* NI timeout gets overwritten in LocApiEngAdapter,
|
|
initializing to 0 here */
|
|
notif.timeout = 0;
|
|
|
|
notif.text_encoding = GPS_ENC_NONE ;
|
|
|
|
notif.requestor_id_encoding = GPS_ENC_UNKNOWN;
|
|
|
|
notif.notify_flags = 0;
|
|
|
|
notif.default_response = GPS_NI_RESPONSE_NORESP;
|
|
|
|
/*Handle Vx request */
|
|
if(ni_req_ptr->NiVxInd_valid == 1)
|
|
{
|
|
const qmiLocNiVxNotifyVerifyStructT_v02 *vx_req = &(ni_req_ptr->NiVxInd);
|
|
|
|
notif.ni_type = GPS_NI_TYPE_VOICE;
|
|
|
|
// Requestor ID, the requestor id recieved is NULL terminated
|
|
hexcode(notif.requestor_id, sizeof notif.requestor_id,
|
|
(char *)vx_req->requestorId, vx_req->requestorId_len );
|
|
}
|
|
|
|
/* Handle UMTS CP request*/
|
|
else if(ni_req_ptr->NiUmtsCpInd_valid == 1)
|
|
{
|
|
const qmiLocNiUmtsCpNotifyVerifyStructT_v02 *umts_cp_req =
|
|
&ni_req_ptr->NiUmtsCpInd;
|
|
|
|
notif.ni_type = GPS_NI_TYPE_UMTS_CTRL_PLANE;
|
|
|
|
/* notificationText should always be a NULL terminated string */
|
|
hexcode(notif.text, sizeof notif.text,
|
|
(char *)umts_cp_req->notificationText,
|
|
umts_cp_req->notificationText_len);
|
|
|
|
/* Store requestor ID */
|
|
hexcode(notif.requestor_id, sizeof(notif.requestor_id),
|
|
(char *)umts_cp_req->requestorId.codedString,
|
|
umts_cp_req->requestorId.codedString_len);
|
|
|
|
/* convert encodings */
|
|
notif.text_encoding = convertNiEncoding(umts_cp_req->dataCodingScheme);
|
|
|
|
notif.requestor_id_encoding =
|
|
convertNiEncoding(umts_cp_req->requestorId.dataCodingScheme);
|
|
|
|
/* LCS address (using extras field) */
|
|
if ( umts_cp_req->clientAddress_len != 0)
|
|
{
|
|
char lcs_addr[32]; // Decoded LCS address for UMTS CP NI
|
|
|
|
// Copy LCS Address into notif.extras in the format: Address = 012345
|
|
strlcat(notif.extras, LOC_NI_NOTIF_KEY_ADDRESS, sizeof (notif.extras));
|
|
strlcat(notif.extras, " = ", sizeof notif.extras);
|
|
int addr_len = 0;
|
|
const char *address_source = NULL;
|
|
address_source = (char *)umts_cp_req->clientAddress;
|
|
// client Address is always NULL terminated
|
|
addr_len = decodeAddress(lcs_addr, sizeof(lcs_addr), address_source,
|
|
umts_cp_req->clientAddress_len);
|
|
|
|
// The address is ASCII string
|
|
if (addr_len)
|
|
{
|
|
strlcat(notif.extras, lcs_addr, sizeof notif.extras);
|
|
}
|
|
}
|
|
|
|
}
|
|
else if(ni_req_ptr->NiSuplInd_valid == 1)
|
|
{
|
|
const qmiLocNiSuplNotifyVerifyStructT_v02 *supl_req =
|
|
&ni_req_ptr->NiSuplInd;
|
|
|
|
notif.ni_type = GPS_NI_TYPE_UMTS_SUPL;
|
|
|
|
// Client name
|
|
if (supl_req->valid_flags & QMI_LOC_SUPL_CLIENT_NAME_MASK_V02)
|
|
{
|
|
hexcode(notif.text, sizeof(notif.text),
|
|
(char *)supl_req->clientName.formattedString,
|
|
supl_req->clientName.formattedString_len);
|
|
LOC_LOGV("%s:%d]: SUPL NI: client_name: %s \n", __func__, __LINE__,
|
|
notif.text);
|
|
}
|
|
else
|
|
{
|
|
LOC_LOGV("%s:%d]: SUPL NI: client_name not present.",
|
|
__func__, __LINE__);
|
|
}
|
|
|
|
// Requestor ID
|
|
if (supl_req->valid_flags & QMI_LOC_SUPL_REQUESTOR_ID_MASK_V02)
|
|
{
|
|
hexcode(notif.requestor_id, sizeof notif.requestor_id,
|
|
(char*)supl_req->requestorId.formattedString,
|
|
supl_req->requestorId.formattedString_len );
|
|
|
|
LOC_LOGV("%s:%d]: SUPL NI: requestor_id: %s \n", __func__, __LINE__,
|
|
notif.requestor_id);
|
|
}
|
|
else
|
|
{
|
|
LOC_LOGV("%s:%d]: SUPL NI: requestor_id not present.",
|
|
__func__, __LINE__);
|
|
}
|
|
|
|
// Encoding type
|
|
if (supl_req->valid_flags & QMI_LOC_SUPL_DATA_CODING_SCHEME_MASK_V02)
|
|
{
|
|
notif.text_encoding = convertNiEncoding(supl_req->dataCodingScheme);
|
|
|
|
notif.requestor_id_encoding = convertNiEncoding(supl_req->dataCodingScheme);
|
|
}
|
|
else
|
|
{
|
|
notif.text_encoding = notif.requestor_id_encoding = GPS_ENC_UNKNOWN;
|
|
}
|
|
|
|
} //ni_req_ptr->NiSuplInd_valid == 1
|
|
|
|
else
|
|
{
|
|
LOC_LOGE("%s:%d]: unknown request event \n",__func__, __LINE__);
|
|
return;
|
|
}
|
|
|
|
// Set default_response & notify_flags
|
|
convertNiNotifyVerifyType(¬if, ni_req_ptr->notificationType);
|
|
|
|
qmiLocEventNiNotifyVerifyReqIndMsgT_v02 *ni_req_copy_ptr =
|
|
(qmiLocEventNiNotifyVerifyReqIndMsgT_v02 *)malloc(sizeof(*ni_req_copy_ptr));
|
|
|
|
if( NULL != ni_req_copy_ptr)
|
|
{
|
|
memcpy(ni_req_copy_ptr, ni_req_ptr, sizeof(*ni_req_copy_ptr));
|
|
|
|
requestNiNotify(notif, (const void*)ni_req_copy_ptr);
|
|
}
|
|
else
|
|
{
|
|
LOC_LOGE("%s:%d]: Error copying NI request\n", __func__, __LINE__);
|
|
}
|
|
|
|
}
|
|
|
|
/* Report the Xtra Server Url from the modem to HAL*/
|
|
void LocApiV02 :: reportXtraServerUrl(
|
|
const qmiLocEventInjectPredictedOrbitsReqIndMsgT_v02*
|
|
server_request_ptr)
|
|
{
|
|
|
|
if (server_request_ptr->serverList.serverList_len == 1)
|
|
{
|
|
reportXtraServer(server_request_ptr->serverList.serverList[0].serverUrl,
|
|
"",
|
|
"",
|
|
QMI_LOC_MAX_SERVER_ADDR_LENGTH_V02);
|
|
}
|
|
else if (server_request_ptr->serverList.serverList_len == 2)
|
|
{
|
|
reportXtraServer(server_request_ptr->serverList.serverList[0].serverUrl,
|
|
server_request_ptr->serverList.serverList[1].serverUrl,
|
|
"",
|
|
QMI_LOC_MAX_SERVER_ADDR_LENGTH_V02);
|
|
}
|
|
else
|
|
{
|
|
reportXtraServer(server_request_ptr->serverList.serverList[0].serverUrl,
|
|
server_request_ptr->serverList.serverList[1].serverUrl,
|
|
server_request_ptr->serverList.serverList[2].serverUrl,
|
|
QMI_LOC_MAX_SERVER_ADDR_LENGTH_V02);
|
|
}
|
|
|
|
}
|
|
|
|
/* convert Ni Encoding type from QMI_LOC to loc eng format */
|
|
GpsNiEncodingType LocApiV02 ::convertNiEncoding(
|
|
qmiLocNiDataCodingSchemeEnumT_v02 loc_encoding)
|
|
{
|
|
GpsNiEncodingType enc = GPS_ENC_UNKNOWN;
|
|
|
|
switch (loc_encoding)
|
|
{
|
|
case eQMI_LOC_NI_SUPL_UTF8_V02:
|
|
enc = GPS_ENC_SUPL_UTF8;
|
|
break;
|
|
case eQMI_LOC_NI_SUPL_UCS2_V02:
|
|
enc = GPS_ENC_SUPL_UCS2;
|
|
break;
|
|
case eQMI_LOC_NI_SUPL_GSM_DEFAULT_V02:
|
|
enc = GPS_ENC_SUPL_GSM_DEFAULT;
|
|
break;
|
|
case eQMI_LOC_NI_SS_LANGUAGE_UNSPEC_V02:
|
|
enc = GPS_ENC_SUPL_GSM_DEFAULT; // SS_LANGUAGE_UNSPEC = GSM
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return enc;
|
|
}
|
|
|
|
/*convert NI notify verify type from QMI LOC to loc eng format*/
|
|
bool LocApiV02 :: convertNiNotifyVerifyType (
|
|
GpsNiNotification *notif,
|
|
qmiLocNiNotifyVerifyEnumT_v02 notif_priv)
|
|
{
|
|
switch (notif_priv)
|
|
{
|
|
case eQMI_LOC_NI_USER_NO_NOTIFY_NO_VERIFY_V02:
|
|
notif->notify_flags = 0;
|
|
break;
|
|
|
|
case eQMI_LOC_NI_USER_NOTIFY_ONLY_V02:
|
|
notif->notify_flags = GPS_NI_NEED_NOTIFY;
|
|
break;
|
|
|
|
case eQMI_LOC_NI_USER_NOTIFY_VERIFY_ALLOW_NO_RESP_V02:
|
|
notif->notify_flags = GPS_NI_NEED_NOTIFY | GPS_NI_NEED_VERIFY;
|
|
notif->default_response = GPS_NI_RESPONSE_ACCEPT;
|
|
break;
|
|
|
|
case eQMI_LOC_NI_USER_NOTIFY_VERIFY_NOT_ALLOW_NO_RESP_V02:
|
|
notif->notify_flags = GPS_NI_NEED_NOTIFY | GPS_NI_NEED_VERIFY;
|
|
notif->default_response = GPS_NI_RESPONSE_DENY;
|
|
break;
|
|
|
|
case eQMI_LOC_NI_USER_NOTIFY_VERIFY_PRIVACY_OVERRIDE_V02:
|
|
notif->notify_flags = GPS_NI_PRIVACY_OVERRIDE;
|
|
break;
|
|
|
|
default:
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/* event callback registered with the loc_api v02 interface */
|
|
void LocApiV02 :: eventCb(locClientHandleType clientHandle,
|
|
uint32_t eventId, locClientEventIndUnionType eventPayload)
|
|
{
|
|
LOC_LOGD("%s:%d]: event id = %d\n", __func__, __LINE__,
|
|
eventId);
|
|
|
|
switch(eventId)
|
|
{
|
|
//Position Report
|
|
case QMI_LOC_EVENT_POSITION_REPORT_IND_V02:
|
|
reportPosition(eventPayload.pPositionReportEvent);
|
|
break;
|
|
|
|
// Satellite report
|
|
case QMI_LOC_EVENT_GNSS_SV_INFO_IND_V02:
|
|
reportSv(eventPayload.pGnssSvInfoReportEvent);
|
|
break;
|
|
|
|
// Status report
|
|
case QMI_LOC_EVENT_ENGINE_STATE_IND_V02:
|
|
reportEngineState(eventPayload.pEngineState);
|
|
break;
|
|
|
|
case QMI_LOC_EVENT_FIX_SESSION_STATE_IND_V02:
|
|
reportFixSessionState(eventPayload.pFixSessionState);
|
|
break;
|
|
|
|
// NMEA
|
|
case QMI_LOC_EVENT_NMEA_IND_V02:
|
|
reportNmea(eventPayload.pNmeaReportEvent);
|
|
break;
|
|
|
|
// XTRA request
|
|
case QMI_LOC_EVENT_INJECT_PREDICTED_ORBITS_REQ_IND_V02:
|
|
LOC_LOGD("%s:%d]: XTRA download request\n", __func__,
|
|
__LINE__);
|
|
reportXtraServerUrl(eventPayload.pInjectPredictedOrbitsReqEvent);
|
|
requestXtraData();
|
|
break;
|
|
|
|
// time request
|
|
case QMI_LOC_EVENT_INJECT_TIME_REQ_IND_V02:
|
|
LOC_LOGD("%s:%d]: Time request\n", __func__,
|
|
__LINE__);
|
|
requestTime();
|
|
break;
|
|
|
|
//position request
|
|
case QMI_LOC_EVENT_INJECT_POSITION_REQ_IND_V02:
|
|
LOC_LOGD("%s:%d]: Position request\n", __func__,
|
|
__LINE__);
|
|
requestLocation();
|
|
break;
|
|
|
|
// NI request
|
|
case QMI_LOC_EVENT_NI_NOTIFY_VERIFY_REQ_IND_V02:
|
|
reportNiRequest(eventPayload.pNiNotifyVerifyReqEvent);
|
|
break;
|
|
|
|
// AGPS connection request
|
|
case QMI_LOC_EVENT_LOCATION_SERVER_CONNECTION_REQ_IND_V02:
|
|
reportAtlRequest(eventPayload.pLocationServerConnReqEvent);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* Call the service LocAdapterBase down event*/
|
|
void LocApiV02 :: errorCb(locClientHandleType handle,
|
|
locClientErrorEnumType errorId)
|
|
{
|
|
if(errorId == eLOC_CLIENT_ERROR_SERVICE_UNAVAILABLE)
|
|
{
|
|
LOC_LOGE("%s:%d]: Service unavailable error\n",
|
|
__func__, __LINE__);
|
|
|
|
handleEngineDownEvent();
|
|
|
|
/* immediately send the engine up event so that
|
|
the loc engine re-initializes the adapter and the
|
|
loc-api_v02 interface */
|
|
|
|
handleEngineUpEvent();
|
|
}
|
|
}
|
|
|
|
static void ds_client_global_event_cb(ds_client_status_enum_type result,
|
|
void *loc_adapter_cookie)
|
|
{
|
|
LocApiV02 *locApiV02Instance =
|
|
(LocApiV02 *)loc_adapter_cookie;
|
|
locApiV02Instance->ds_client_event_cb(result);
|
|
return;
|
|
}
|
|
|
|
void LocApiV02::ds_client_event_cb(ds_client_status_enum_type result)
|
|
{
|
|
if(result == E_DS_CLIENT_DATA_CALL_CONNECTED) {
|
|
LOC_LOGD("%s:%d]: Emergency call is up", __func__, __LINE__);
|
|
reportDataCallOpened();
|
|
}
|
|
else if(result == E_DS_CLIENT_DATA_CALL_DISCONNECTED) {
|
|
LOC_LOGE("%s:%d]: Emergency call is stopped", __func__, __LINE__);
|
|
reportDataCallClosed();
|
|
}
|
|
return;
|
|
}
|
|
|
|
ds_client_cb_data ds_client_cb{
|
|
ds_client_global_event_cb
|
|
};
|
|
|
|
int LocApiV02 :: initDataServiceClient()
|
|
{
|
|
int ret=0;
|
|
ret = ds_client_init();
|
|
LOC_LOGD("%s:%d]: ret = %d\n", __func__, __LINE__,ret);
|
|
return ret;
|
|
}
|
|
|
|
int LocApiV02 :: openAndStartDataCall()
|
|
{
|
|
enum loc_api_adapter_err ret;
|
|
int profile_index;
|
|
int pdp_type;
|
|
ds_client_status_enum_type result = ds_client_open_call(&dsClientHandle,
|
|
&ds_client_cb,
|
|
(void *)this,
|
|
&profile_index,
|
|
&pdp_type);
|
|
if(result == E_DS_CLIENT_SUCCESS) {
|
|
result = ds_client_start_call(dsClientHandle, profile_index, pdp_type);
|
|
|
|
if(result == E_DS_CLIENT_SUCCESS) {
|
|
LOC_LOGD("%s:%d]: Request to start Emergency call sent\n",
|
|
__func__, __LINE__);
|
|
ret = LOC_API_ADAPTER_ERR_SUCCESS;
|
|
}
|
|
else {
|
|
LOC_LOGE("%s:%d]: Unable to bring up emergency call using DS. result = %d",
|
|
__func__, __LINE__, (int)result);
|
|
ret = LOC_API_ADAPTER_ERR_UNSUPPORTED;
|
|
}
|
|
}
|
|
else if(result == E_DS_CLIENT_RETRY_LATER) {
|
|
LOC_LOGE("%s:%d]: Could not start emergency call. Retry after delay\n",
|
|
__func__, __LINE__);
|
|
ret = LOC_API_ADAPTER_ERR_ENGINE_BUSY;
|
|
}
|
|
else {
|
|
LOC_LOGE("%s:%d]: Unable to bring up emergency call using DS. ret = %d",
|
|
__func__, __LINE__, (int)ret);
|
|
ret = LOC_API_ADAPTER_ERR_UNSUPPORTED;
|
|
}
|
|
|
|
return (int)ret;
|
|
}
|
|
|
|
void LocApiV02 :: stopDataCall()
|
|
{
|
|
ds_client_status_enum_type ret =
|
|
ds_client_stop_call(dsClientHandle);
|
|
if (ret == E_DS_CLIENT_SUCCESS) {
|
|
LOC_LOGD("%s:%d]: Request to Close SUPL ES call sent\n", __func__, __LINE__);
|
|
}
|
|
else {
|
|
if (ret == E_DS_CLIENT_FAILURE_INVALID_HANDLE) {
|
|
LOC_LOGE("%s:%d]: Conn handle not found for SUPL ES",
|
|
__func__, __LINE__);
|
|
}
|
|
LOC_LOGE("%s:%d]: Could not close SUPL ES call. Ret: %d\n"
|
|
,__func__, __LINE__, ret);
|
|
}
|
|
return;
|
|
}
|
|
|
|
void LocApiV02 :: closeDataCall()
|
|
{
|
|
ds_client_close_call(&dsClientHandle);
|
|
LOC_LOGD("%s:%d]: Release data client handle\n", __func__, __LINE__);
|
|
return;
|
|
}
|
|
|
|
|
|
enum loc_api_adapter_err LocApiV02 ::
|
|
getZppFix(GpsLocation & zppLoc)
|
|
{
|
|
LocPosTechMask tech_mask;
|
|
return getZppFix(zppLoc, tech_mask);
|
|
}
|
|
|
|
enum loc_api_adapter_err LocApiV02 ::
|
|
getZppFix(GpsLocation &zppLoc, LocPosTechMask &tech_mask)
|
|
{
|
|
locClientReqUnionType req_union;
|
|
qmiLocGetBestAvailablePositionIndMsgT_v02 zpp_ind;
|
|
qmiLocGetBestAvailablePositionReqMsgT_v02 zpp_req;
|
|
|
|
memset(&zpp_ind, 0, sizeof(zpp_ind));
|
|
memset(&zpp_req, 0, sizeof(zpp_req));
|
|
memset(&zppLoc, 0, sizeof(zppLoc));
|
|
|
|
req_union.pGetBestAvailablePositionReq = &zpp_req;
|
|
|
|
LOC_LOGD("%s:%d]: Get ZPP Fix\n", __func__, __LINE__);
|
|
|
|
locClientStatusEnumType status = loc_sync_send_req(clientHandle,
|
|
QMI_LOC_GET_BEST_AVAILABLE_POSITION_REQ_V02,
|
|
req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
|
|
QMI_LOC_GET_BEST_AVAILABLE_POSITION_IND_V02,
|
|
&zpp_ind);
|
|
|
|
if (status != eLOC_CLIENT_SUCCESS ||
|
|
eQMI_LOC_SUCCESS_V02 != zpp_ind.status) {
|
|
LOC_LOGE ("%s:%d]: error! status = %s, zpp_ind.status = %s\n",
|
|
__func__, __LINE__,
|
|
loc_get_v02_client_status_name(status),
|
|
loc_get_v02_qmi_status_name(zpp_ind.status));
|
|
|
|
return LOC_API_ADAPTER_ERR_GENERAL_FAILURE;
|
|
}
|
|
|
|
LOC_LOGD("Got Zpp fix location validity (lat:%d, lon:%d, timestamp:%d accuracy:%d)",
|
|
zpp_ind.latitude_valid,
|
|
zpp_ind.longitude_valid,
|
|
zpp_ind.timestampUtc_valid,
|
|
zpp_ind.horUncCircular_valid);
|
|
|
|
LOC_LOGD("(%.7f, %.7f), timestamp %llu, accuracy %f",
|
|
zpp_ind.latitude,
|
|
zpp_ind.longitude,
|
|
zpp_ind.timestampUtc,
|
|
zpp_ind.horUncCircular);
|
|
|
|
zppLoc.size = sizeof(GpsLocation);
|
|
if (zpp_ind.timestampUtc_valid) {
|
|
zppLoc.timestamp = zpp_ind.timestampUtc;
|
|
}
|
|
else {
|
|
// no valid flag in GpsLocation structure to indicate if timestamp field is valid
|
|
zppLoc.timestamp = -1;
|
|
}
|
|
|
|
if ((zpp_ind.latitude_valid == false) ||
|
|
(zpp_ind.longitude_valid == false) ||
|
|
(zpp_ind.horUncCircular_valid == false)) {
|
|
return LOC_API_ADAPTER_ERR_GENERAL_FAILURE;
|
|
}
|
|
|
|
zppLoc.flags = GPS_LOCATION_HAS_LAT_LONG | GPS_LOCATION_HAS_ACCURACY;
|
|
zppLoc.latitude = zpp_ind.latitude;
|
|
zppLoc.longitude = zpp_ind.longitude;
|
|
zppLoc.accuracy = zpp_ind.horUncCircular;
|
|
|
|
if (zpp_ind.altitudeWrtEllipsoid_valid) {
|
|
zppLoc.flags |= GPS_LOCATION_HAS_ALTITUDE;
|
|
zppLoc.altitude = zpp_ind.altitudeWrtEllipsoid;
|
|
}
|
|
|
|
if (zpp_ind.horSpeed_valid) {
|
|
zppLoc.flags |= GPS_LOCATION_HAS_SPEED;
|
|
zppLoc.speed = zpp_ind.horSpeed;
|
|
}
|
|
|
|
if (zpp_ind.heading_valid) {
|
|
zppLoc.flags |= GPS_LOCATION_HAS_BEARING;
|
|
zppLoc.bearing = zpp_ind.heading;
|
|
}
|
|
|
|
if (zpp_ind.technologyMask_valid) {
|
|
tech_mask = zpp_ind.technologyMask;
|
|
}
|
|
|
|
return LOC_API_ADAPTER_ERR_SUCCESS;
|
|
}
|
|
|
|
/*Values for lock
|
|
1 = Do not lock any position sessions
|
|
2 = Lock MI position sessions
|
|
3 = Lock MT position sessions
|
|
4 = Lock all position sessions
|
|
|
|
Returns values:
|
|
zero on success; non-zero on failure
|
|
*/
|
|
int LocApiV02 :: setGpsLock(unsigned int lock)
|
|
{
|
|
qmiLocSetEngineLockReqMsgT_v02 setEngineLockReq;
|
|
qmiLocSetEngineLockIndMsgT_v02 setEngineLockInd;
|
|
locClientStatusEnumType status;
|
|
locClientReqUnionType req_union;
|
|
int ret=0;
|
|
|
|
LOC_LOGD("%s:%d]: Set Gps Lock. Lock: %d\n", __func__, __LINE__, lock);
|
|
setEngineLockReq.lockType = (qmiLocLockEnumT_v02)lock;
|
|
req_union.pSetEngineLockReq = &setEngineLockReq;
|
|
memset(&setEngineLockInd, 0, sizeof(setEngineLockInd));
|
|
status = loc_sync_send_req(clientHandle,
|
|
QMI_LOC_SET_ENGINE_LOCK_REQ_V02,
|
|
req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
|
|
QMI_LOC_SET_ENGINE_LOCK_IND_V02,
|
|
&setEngineLockInd);
|
|
|
|
if(status != eLOC_CLIENT_SUCCESS || setEngineLockInd.status != eQMI_LOC_SUCCESS_V02) {
|
|
LOC_LOGE("%s:%d]: Set engine lock failed. status: %s, ind status:%s\n",
|
|
__func__, __LINE__,
|
|
loc_get_v02_client_status_name(status),
|
|
loc_get_v02_qmi_status_name(setEngineLockInd.status));
|
|
ret = -1;
|
|
}
|
|
LOC_LOGD("%s:%d]: exit\n", __func__, __LINE__);
|
|
return ret;
|
|
}
|
|
/*
|
|
Returns
|
|
Current value of GPS Lock on success
|
|
-1 on failure
|
|
*/
|
|
int LocApiV02 :: getGpsLock()
|
|
{
|
|
qmiLocGetEngineLockReqMsgT_v02 getEngineLockReq;
|
|
qmiLocGetEngineLockIndMsgT_v02 getEngineLockInd;
|
|
locClientStatusEnumType status;
|
|
locClientReqUnionType req_union;
|
|
int ret=0;
|
|
LOC_LOGD("%s:%d]: Enter\n", __func__, __LINE__);
|
|
memset(&getEngineLockInd, 0, sizeof(getEngineLockInd));
|
|
|
|
//Passing req_union as a parameter even though this request has no payload
|
|
//since NULL or 0 gives an error during compilation
|
|
status = loc_sync_send_req(clientHandle,
|
|
QMI_LOC_GET_ENGINE_LOCK_REQ_V02,
|
|
req_union, LOC_ENGINE_SYNC_REQUEST_TIMEOUT,
|
|
QMI_LOC_GET_ENGINE_LOCK_IND_V02,
|
|
&getEngineLockInd);
|
|
if(status != eLOC_CLIENT_SUCCESS || getEngineLockInd.status != eQMI_LOC_SUCCESS_V02) {
|
|
LOC_LOGE("%s:%d]: Set engine lock failed. status: %s, ind status:%s\n",
|
|
__func__, __LINE__,
|
|
loc_get_v02_client_status_name(status),
|
|
loc_get_v02_qmi_status_name(getEngineLockInd.status));
|
|
ret = -1;
|
|
}
|
|
else {
|
|
if(getEngineLockInd.lockType_valid) {
|
|
ret = (int)getEngineLockInd.lockType;
|
|
LOC_LOGD("%s:%d]: Lock Type: %d\n", __func__, __LINE__, ret);
|
|
}
|
|
else {
|
|
LOC_LOGE("%s:%d]: Lock Type not valid\n", __func__, __LINE__);
|
|
ret = -1;
|
|
}
|
|
}
|
|
LOC_LOGD("%s:%d]: Exit\n", __func__, __LINE__);
|
|
return ret;
|
|
}
|