gps: AP NMEA generation

Generate NMEA sentences on the AP

Change-Id: Ifc9e9263868ab4dec450bef35c53c441c881a072
This commit is contained in:
Dante Russo 2012-08-07 10:29:30 -07:00
parent d3b220c611
commit a3409617b6
10 changed files with 896 additions and 17 deletions

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2011, Code Aurora Forum. All rights reserved. /* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are * modification, are permitted provided that the following conditions are
@ -625,8 +625,10 @@ LocApiRpcAdapter::deleteAidingData(GpsAidingData bits)
void LocApiRpcAdapter::reportPosition(const rpc_loc_parsed_position_s_type *location_report_ptr) void LocApiRpcAdapter::reportPosition(const rpc_loc_parsed_position_s_type *location_report_ptr)
{ {
GpsLocation location = {0}; GpsLocation location = {0};
GpsLocationExtended locationExtended = {0};
location.size = sizeof(location); location.size = sizeof(location);
locationExtended.size = sizeof(locationExtended);
if (location_report_ptr->valid_mask & RPC_LOC_POS_VALID_SESSION_STATUS) if (location_report_ptr->valid_mask & RPC_LOC_POS_VALID_SESSION_STATUS)
{ {
// Process the position from final and intermediate reports // Process the position from final and intermediate reports
@ -681,8 +683,22 @@ void LocApiRpcAdapter::reportPosition(const rpc_loc_parsed_position_s_type *loca
//Mark the location source as from GNSS //Mark the location source as from GNSS
location.flags |= LOCATION_HAS_SOURCE_INFO; location.flags |= LOCATION_HAS_SOURCE_INFO;
location.position_source = ULP_LOCATION_IS_FROM_GNSS; location.position_source = ULP_LOCATION_IS_FROM_GNSS;
if (location_report_ptr->valid_mask & RPC_LOC_POS_VALID_ALTITUDE_WRT_MEAN_SEA_LEVEL)
{
locationExtended.flags |= GPS_LOCATION_EXTENDED_HAS_MAG_DEV;
locationExtended.magneticDeviation = location_report_ptr->altitude_wrt_mean_sea_level;
}
if (location_report_ptr->valid_mask & RPC_LOC_POS_VALID_MAGNETIC_VARIATION )
{
locationExtended.flags |= GPS_LOCATION_EXTENDED_HAS_MAG_DEV;
locationExtended.magneticDeviation = location_report_ptr->magnetic_deviation;
}
LOC_LOGV("reportPosition: fire callback\n"); LOC_LOGV("reportPosition: fire callback\n");
LocApiAdapter::reportPosition(location, LocApiAdapter::reportPosition(location,
locationExtended,
locEngHandle.extPosInfo((void*)location_report_ptr), locEngHandle.extPosInfo((void*)location_report_ptr),
(location_report_ptr->session_status == RPC_LOC_SESS_STATUS_IN_PROGESS ? (location_report_ptr->session_status == RPC_LOC_SESS_STATUS_IN_PROGESS ?
LOC_SESS_INTERMEDIATE : LOC_SESS_SUCCESS)); LOC_SESS_INTERMEDIATE : LOC_SESS_SUCCESS));
@ -691,6 +707,7 @@ void LocApiRpcAdapter::reportPosition(const rpc_loc_parsed_position_s_type *loca
else else
{ {
LocApiAdapter::reportPosition(location, LocApiAdapter::reportPosition(location,
locationExtended,
NULL, NULL,
LOC_SESS_FAILURE); LOC_SESS_FAILURE);
LOC_LOGV("loc_eng_report_position: ignore position report when session status = %d\n", location_report_ptr->session_status); LOC_LOGV("loc_eng_report_position: ignore position report when session status = %d\n", location_report_ptr->session_status);
@ -705,6 +722,8 @@ void LocApiRpcAdapter::reportPosition(const rpc_loc_parsed_position_s_type *loca
void LocApiRpcAdapter::reportSv(const rpc_loc_gnss_info_s_type *gnss_report_ptr) void LocApiRpcAdapter::reportSv(const rpc_loc_gnss_info_s_type *gnss_report_ptr)
{ {
GpsSvStatus SvStatus = {0}; GpsSvStatus SvStatus = {0};
GpsLocationExtended locationExtended = {0};
locationExtended.size = sizeof(locationExtended);
int num_svs_max = 0; int num_svs_max = 0;
const rpc_loc_sv_info_s_type *sv_info_ptr; const rpc_loc_sv_info_s_type *sv_info_ptr;
@ -788,9 +807,20 @@ void LocApiRpcAdapter::reportSv(const rpc_loc_gnss_info_s_type *gnss_report_ptr)
} }
} }
if ((gnss_report_ptr->valid_mask & RPC_LOC_GNSS_INFO_VALID_POS_DOP) &&
(gnss_report_ptr->valid_mask & RPC_LOC_GNSS_INFO_VALID_HOR_DOP) &&
(gnss_report_ptr->valid_mask & RPC_LOC_GNSS_INFO_VALID_VERT_DOP))
{
locationExtended.flags |= GPS_LOCATION_EXTENDED_HAS_DOP;
locationExtended.pdop = gnss_report_ptr->position_dop;
locationExtended.hdop = gnss_report_ptr->horizontal_dop;
locationExtended.vdop = gnss_report_ptr->vertical_dop;
}
if (SvStatus.num_svs >= 0) if (SvStatus.num_svs >= 0)
{ {
LocApiAdapter::reportSv(SvStatus, LocApiAdapter::reportSv(SvStatus,
locationExtended,
locEngHandle.extSvInfo((void*)gnss_report_ptr)); locEngHandle.extSvInfo((void*)gnss_report_ptr));
} }
} }

View file

@ -65,7 +65,8 @@ LOCAL_SRC_FILES += \
loc_eng_agps.cpp \ loc_eng_agps.cpp \
loc_eng_xtra.cpp \ loc_eng_xtra.cpp \
loc_eng_ni.cpp \ loc_eng_ni.cpp \
loc_eng_log.cpp loc_eng_log.cpp \
loc_eng_nmea.cpp
ifeq ($(FEATURE_GNSS_BIT_API), true) ifeq ($(FEATURE_GNSS_BIT_API), true)
LOCAL_CFLAGS += -DFEATURE_GNSS_BIT_API LOCAL_CFLAGS += -DFEATURE_GNSS_BIT_API

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2011, Code Aurora Forum. All rights reserved. /* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are * modification, are permitted provided that the following conditions are
@ -113,12 +113,14 @@ int LocApiAdapter::decodeAddress(char *addr_string, int string_size,
} }
void LocApiAdapter::reportPosition(GpsLocation &location, void LocApiAdapter::reportPosition(GpsLocation &location,
GpsLocationExtended &locationExtended,
void* locationExt, void* locationExt,
enum loc_sess_status status, enum loc_sess_status status,
LocPosTechMask loc_technology_mask ) LocPosTechMask loc_technology_mask )
{ {
loc_eng_msg_report_position *msg(new loc_eng_msg_report_position(locEngHandle.owner, loc_eng_msg_report_position *msg(new loc_eng_msg_report_position(locEngHandle.owner,
location, location,
locationExtended,
locationExt, locationExt,
status, status,
loc_technology_mask)); loc_technology_mask));
@ -129,9 +131,9 @@ void LocApiAdapter::reportPosition(GpsLocation &location,
} }
} }
void LocApiAdapter::reportSv(GpsSvStatus &svStatus, void* svExt) void LocApiAdapter::reportSv(GpsSvStatus &svStatus, GpsLocationExtended &locationExtended, void* svExt)
{ {
loc_eng_msg_report_sv *msg(new loc_eng_msg_report_sv(locEngHandle.owner, svStatus, svExt)); loc_eng_msg_report_sv *msg(new loc_eng_msg_report_sv(locEngHandle.owner, svStatus, locationExtended, svExt));
//We want to send SV info to ULP to help it in determining GNSS signal strength //We want to send SV info to ULP to help it in determining GNSS signal strength
//ULP will forward the SV reports to HAL without any modifications //ULP will forward the SV reports to HAL without any modifications

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2011, Code Aurora Forum. All rights reserved. /* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are * modification, are permitted provided that the following conditions are
@ -121,10 +121,13 @@ public:
const char *data, int data_size); const char *data, int data_size);
void reportPosition(GpsLocation &location, void reportPosition(GpsLocation &location,
GpsLocationExtended &locationExtended,
void* locationExt, void* locationExt,
enum loc_sess_status status, enum loc_sess_status status,
LocPosTechMask loc_technology_mask = LOC_POS_TECH_MASK_DEFAULT); LocPosTechMask loc_technology_mask = LOC_POS_TECH_MASK_DEFAULT);
void reportSv(GpsSvStatus &svStatus, void* svExt); void reportSv(GpsSvStatus &svStatus,
GpsLocationExtended &locationExtended,
void* svExt);
void reportStatus(GpsStatusValue status); void reportStatus(GpsStatusValue status);
void reportNmea(const char* nmea, int length); void reportNmea(const char* nmea, int length);
void reportAgpsStatus(AGpsStatus &agpsStatus); void reportAgpsStatus(AGpsStatus &agpsStatus);

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2012 Code Aurora Forum. All rights reserved. /* Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are * modification, are permitted provided that the following conditions are
@ -57,6 +57,7 @@
#include <loc_eng_dmn_conn_handler.h> #include <loc_eng_dmn_conn_handler.h>
#include <loc_eng_msg.h> #include <loc_eng_msg.h>
#include <loc_eng_msg_id.h> #include <loc_eng_msg_id.h>
#include <loc_eng_nmea.h>
#include <msg_q.h> #include <msg_q.h>
#include <loc.h> #include <loc.h>
@ -83,6 +84,7 @@ static loc_param_s_type loc_parameter_table[] =
{"INTERMEDIATE_POS", &gps_conf.INTERMEDIATE_POS, NULL, 'n'}, {"INTERMEDIATE_POS", &gps_conf.INTERMEDIATE_POS, NULL, 'n'},
{"ACCURACY_THRES", &gps_conf.ACCURACY_THRES, NULL, 'n'}, {"ACCURACY_THRES", &gps_conf.ACCURACY_THRES, NULL, 'n'},
{"ENABLE_WIPER", &gps_conf.ENABLE_WIPER, NULL, 'n'}, {"ENABLE_WIPER", &gps_conf.ENABLE_WIPER, NULL, 'n'},
{"NMEA_PROVIDER", &gps_conf.NMEA_PROVIDER, NULL, 'n'},
{"SUPL_VER", &gps_conf.SUPL_VER, NULL, 'n'}, {"SUPL_VER", &gps_conf.SUPL_VER, NULL, 'n'},
{"CAPABILITIES", &gps_conf.CAPABILITIES, NULL, 'n'}, {"CAPABILITIES", &gps_conf.CAPABILITIES, NULL, 'n'},
{"GYRO_BIAS_RANDOM_WALK", &gps_conf.GYRO_BIAS_RANDOM_WALK, &gps_conf.GYRO_BIAS_RANDOM_WALK_VALID, 'f'}, {"GYRO_BIAS_RANDOM_WALK", &gps_conf.GYRO_BIAS_RANDOM_WALK, &gps_conf.GYRO_BIAS_RANDOM_WALK_VALID, 'f'},
@ -111,6 +113,7 @@ static void loc_default_parameters(void)
gps_conf.INTERMEDIATE_POS = 0; gps_conf.INTERMEDIATE_POS = 0;
gps_conf.ACCURACY_THRES = 0; gps_conf.ACCURACY_THRES = 0;
gps_conf.ENABLE_WIPER = 0; gps_conf.ENABLE_WIPER = 0;
gps_conf.NMEA_PROVIDER = 0;
gps_conf.SUPL_VER = 0x10000; gps_conf.SUPL_VER = 0x10000;
gps_conf.CAPABILITIES = 0x7; gps_conf.CAPABILITIES = 0x7;
@ -303,6 +306,16 @@ int loc_eng_init(loc_eng_data_s_type &loc_eng_data, LocCallbacks* callbacks,
// loc_eng_data.fix_session_status -- GPS_STATUS_NONE; // loc_eng_data.fix_session_status -- GPS_STATUS_NONE;
// loc_eng_data.mute_session_state -- LOC_MUTE_SESS_NONE; // loc_eng_data.mute_session_state -- LOC_MUTE_SESS_NONE;
if ((event & LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT) && (gps_conf.NMEA_PROVIDER == NMEA_PROVIDER_AP))
{
event = event ^ LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT; // unregister for modem NMEA report
loc_eng_data.generateNmea = true;
}
else
{
loc_eng_data.generateNmea = false;
}
LocEng locEngHandle(&loc_eng_data, event, loc_eng_data.acquire_wakelock_cb, LocEng locEngHandle(&loc_eng_data, event, loc_eng_data.acquire_wakelock_cb,
loc_eng_data.release_wakelock_cb, loc_eng_msg_sender, loc_external_msg_sender, loc_eng_data.release_wakelock_cb, loc_eng_msg_sender, loc_external_msg_sender,
callbacks->location_ext_parser, callbacks->sv_ext_parser); callbacks->location_ext_parser, callbacks->sv_ext_parser);
@ -1523,6 +1536,11 @@ static void loc_eng_deferred_action_thread(void* arg)
loc_eng_data_p->client_handle->setInSession(false); loc_eng_data_p->client_handle->setInSession(false);
} }
if (loc_eng_data_p->generateNmea && rpMsg->location.position_source == ULP_LOCATION_IS_FROM_GNSS)
{
loc_eng_nmea_generate_pos(loc_eng_data_p, rpMsg->location, rpMsg->locationExtended);
}
// Free the allocated memory for rawData // Free the allocated memory for rawData
GpsLocation* gp = (GpsLocation*)&(rpMsg->location); GpsLocation* gp = (GpsLocation*)&(rpMsg->location);
if (gp != NULL && gp->rawData != NULL) if (gp != NULL && gp->rawData != NULL)
@ -1543,6 +1561,12 @@ static void loc_eng_deferred_action_thread(void* arg)
loc_eng_data_p->sv_status_cb((GpsSvStatus*)&(rsMsg->svStatus), loc_eng_data_p->sv_status_cb((GpsSvStatus*)&(rsMsg->svStatus),
(void*)rsMsg->svExt); (void*)rsMsg->svExt);
} }
if (loc_eng_data_p->generateNmea)
{
loc_eng_nmea_generate_sv(loc_eng_data_p, rsMsg->svStatus, rsMsg->locationExtended);
}
} }
break; break;

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2012 Code Aurora Forum. All rights reserved. /* Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are * modification, are permitted provided that the following conditions are
@ -68,6 +68,11 @@ typedef unsigned char boolean;
#define FAILURE FALSE #define FAILURE FALSE
#define INVALID_ATL_CONNECTION_HANDLE -1 #define INVALID_ATL_CONNECTION_HANDLE -1
enum loc_nmea_provider_e_type {
NMEA_PROVIDER_AP = 0, // Application Processor Provider of NMEA
NMEA_PROVIDER_MP // Modem Processor Provider of NMEA
};
enum loc_mute_session_e_type { enum loc_mute_session_e_type {
LOC_MUTE_SESS_NONE = 0, LOC_MUTE_SESS_NONE = 0,
LOC_MUTE_SESS_WAIT, LOC_MUTE_SESS_WAIT,
@ -128,6 +133,13 @@ typedef struct
// For muting session broadcast // For muting session broadcast
loc_mute_session_e_type mute_session_state; loc_mute_session_e_type mute_session_state;
// For nmea generation
boolean generateNmea;
uint32_t sv_used_mask;
float hdop;
float pdop;
float vdop;
// Address buffers, for addressing setting before init // Address buffers, for addressing setting before init
int supl_host_set; int supl_host_set;
char supl_host_buf[101]; char supl_host_buf[101];
@ -149,6 +161,7 @@ typedef struct loc_gps_cfg_s
unsigned long INTERMEDIATE_POS; unsigned long INTERMEDIATE_POS;
unsigned long ACCURACY_THRES; unsigned long ACCURACY_THRES;
unsigned long ENABLE_WIPER; unsigned long ENABLE_WIPER;
uint8_t NMEA_PROVIDER;
unsigned long SUPL_VER; unsigned long SUPL_VER;
unsigned long CAPABILITIES; unsigned long CAPABILITIES;
uint8_t GYRO_BIAS_RANDOM_WALK_VALID; uint8_t GYRO_BIAS_RANDOM_WALK_VALID;

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2011,2012 Code Aurora Forum. All rights reserved. /* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are * modification, are permitted provided that the following conditions are
@ -98,6 +98,35 @@ struct LocPosMode
} }
}; };
/** Flags to indicate which values are valid in a GpsLocationExtended. */
typedef uint16_t GpsLocationExtendedFlags;
/** GpsLocationExtended has valid pdop, hdop, vdop. */
#define GPS_LOCATION_EXTENDED_HAS_DOP 0x0001
/** GpsLocationExtended has valid altitude mean sea level. */
#define GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL 0x0002
/** GpsLocation has valid magnetic deviation. */
#define GPS_LOCATION_EXTENDED_HAS_MAG_DEV 0x0004
/** GpsLocation has valid mode indicator. */
#define GPS_LOCATION_EXTENDED_HAS_MODE_IND 0x0008
/** Represents gps location extended. */
typedef struct {
/** set to sizeof(GpsLocationExtended) */
size_t size;
/** Contains GpsLocationExtendedFlags bits. */
uint16_t flags;
/** Contains the Altitude wrt mean sea level */
float altitudeMeanSeaLevel;
/** Contains Position Dilusion of Precision. */
float pdop;
/** Contains Horizontal Dilusion of Precision. */
float hdop;
/** Contains Vertical Dilusion of Precision. */
float vdop;
/** Contains Magnetic Deviation. */
float magneticDeviation;
} GpsLocationExtended;
typedef enum { typedef enum {
LOC_ENG_IF_REQUEST_TYPE_SUPL = 0, LOC_ENG_IF_REQUEST_TYPE_SUPL = 0,
LOC_ENG_IF_REQUEST_TYPE_WIFI, LOC_ENG_IF_REQUEST_TYPE_WIFI,
@ -317,23 +346,24 @@ struct loc_eng_msg_delete_aiding_data : public loc_eng_msg {
struct loc_eng_msg_report_position : public loc_eng_msg { struct loc_eng_msg_report_position : public loc_eng_msg {
const GpsLocation location; const GpsLocation location;
const GpsLocationExtended locationExtended;
const void* locationExt; const void* locationExt;
const enum loc_sess_status status; const enum loc_sess_status status;
const LocPosTechMask technology_mask; const LocPosTechMask technology_mask;
inline loc_eng_msg_report_position(void* instance, GpsLocation &loc, void* locExt, inline loc_eng_msg_report_position(void* instance, GpsLocation &loc, GpsLocationExtended &locExtended, void* locExt,
enum loc_sess_status st) : enum loc_sess_status st) :
loc_eng_msg(instance, LOC_ENG_MSG_REPORT_POSITION), loc_eng_msg(instance, LOC_ENG_MSG_REPORT_POSITION),
location(loc), locationExt(locExt), status(st), technology_mask(LOC_POS_TECH_MASK_DEFAULT) location(loc), locationExtended(locExtended), locationExt(locExt), status(st), technology_mask(LOC_POS_TECH_MASK_DEFAULT)
{ {
LOC_LOGV("flags: %d\n source: %d\n latitude: %f\n longitude: %f\n altitude: %f\n speed: %f\n bearing: %f\n accuracy: %f\n timestamp: %lld\n rawDataSize: %d\n rawData: %p\n Session status: %d\n Technology mask: %u", LOC_LOGV("flags: %d\n source: %d\n latitude: %f\n longitude: %f\n altitude: %f\n speed: %f\n bearing: %f\n accuracy: %f\n timestamp: %lld\n rawDataSize: %d\n rawData: %p\n Session status: %d\n Technology mask: %u",
location.flags, location.position_source, location.latitude, location.longitude, location.flags, location.position_source, location.latitude, location.longitude,
location.altitude, location.speed, location.bearing, location.accuracy, location.altitude, location.speed, location.bearing, location.accuracy,
location.timestamp, location.rawDataSize, location.rawData,status,technology_mask); location.timestamp, location.rawDataSize, location.rawData,status,technology_mask);
} }
inline loc_eng_msg_report_position(void* instance, GpsLocation &loc, void* locExt, inline loc_eng_msg_report_position(void* instance, GpsLocation &loc, GpsLocationExtended &locExtended, void* locExt,
enum loc_sess_status st, LocPosTechMask technology) : enum loc_sess_status st, LocPosTechMask technology) :
loc_eng_msg(instance, LOC_ENG_MSG_REPORT_POSITION), loc_eng_msg(instance, LOC_ENG_MSG_REPORT_POSITION),
location(loc), locationExt(locExt), status(st), technology_mask(technology) location(loc), locationExtended(locExtended), locationExt(locExt), status(st), technology_mask(technology)
{ {
LOC_LOGV("flags: %d\n source: %d\n latitude: %f\n longitude: %f\n altitude: %f\n speed: %f\n bearing: %f\n accuracy: %f\n timestamp: %lld\n rawDataSize: %d\n rawData: %p\n Session status: %d\n Technology mask: %u", LOC_LOGV("flags: %d\n source: %d\n latitude: %f\n longitude: %f\n altitude: %f\n speed: %f\n bearing: %f\n accuracy: %f\n timestamp: %lld\n rawDataSize: %d\n rawData: %p\n Session status: %d\n Technology mask: %u",
location.flags, location.position_source, location.latitude, location.longitude, location.flags, location.position_source, location.latitude, location.longitude,
@ -344,9 +374,10 @@ struct loc_eng_msg_report_position : public loc_eng_msg {
struct loc_eng_msg_report_sv : public loc_eng_msg { struct loc_eng_msg_report_sv : public loc_eng_msg {
const GpsSvStatus svStatus; const GpsSvStatus svStatus;
const GpsLocationExtended locationExtended;
const void* svExt; const void* svExt;
inline loc_eng_msg_report_sv(void* instance, GpsSvStatus &sv, void* ext) : inline loc_eng_msg_report_sv(void* instance, GpsSvStatus &sv, GpsLocationExtended &locExtended, void* ext) :
loc_eng_msg(instance, LOC_ENG_MSG_REPORT_SV), svStatus(sv), svExt(ext) loc_eng_msg(instance, LOC_ENG_MSG_REPORT_SV), svStatus(sv), locationExtended(locExtended), svExt(ext)
{ {
LOC_LOGV("num sv: %d\n ephemeris mask: %dxn almanac mask: %x\n used in fix mask: %x\n sv: prn snr elevation azimuth", LOC_LOGV("num sv: %d\n ephemeris mask: %dxn almanac mask: %x\n used in fix mask: %x\n sv: prn snr elevation azimuth",
svStatus.num_svs, svStatus.ephemeris_mask, svStatus.almanac_mask, svStatus.used_in_fix_mask); svStatus.num_svs, svStatus.ephemeris_mask, svStatus.almanac_mask, svStatus.used_in_fix_mask);

View file

@ -0,0 +1,703 @@
/* Copyright (c) 2012, 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 Code Aurora Forum, Inc. 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_NDDEBUG 0
#define LOG_TAG "LocSvc_eng_nmea"
#include <loc_eng.h>
#include <loc_eng_nmea.h>
#include <math.h>
#include "log_util.h"
/*===========================================================================
FUNCTION loc_eng_nmea_send
DESCRIPTION
send out NMEA sentence
DEPENDENCIES
NONE
RETURN VALUE
Total length of the nmea sentence
SIDE EFFECTS
N/A
===========================================================================*/
void loc_eng_nmea_send(char *pNmea, int length, loc_eng_data_s_type *loc_eng_data_p)
{
struct timeval tv;
gettimeofday(&tv, (struct timezone *) NULL);
int64_t now = tv.tv_sec * 1000LL + tv.tv_usec / 1000;
CALLBACK_LOG_CALLFLOW("nmea_cb", %p, pNmea);
loc_eng_data_p->nmea_cb(now, pNmea, length);
LOC_LOGD("NMEA <%s", pNmea);
}
/*===========================================================================
FUNCTION loc_eng_nmea_put_checksum
DESCRIPTION
Generate NMEA sentences generated based on position report
DEPENDENCIES
NONE
RETURN VALUE
Total length of the nmea sentence
SIDE EFFECTS
N/A
===========================================================================*/
int loc_eng_nmea_put_checksum(char *pNmea, int maxSize)
{
uint8_t checksum = 0;
int length = 0;
pNmea++; //skip the $
while (*pNmea != '\0')
{
checksum ^= *pNmea++;
length++;
}
int checksumLength = snprintf(pNmea, maxSize,"*%02X\r\n", checksum);
return (length + checksumLength);
}
/*===========================================================================
FUNCTION loc_eng_nmea_generate_pos
DESCRIPTION
Generate NMEA sentences generated based on position report
DEPENDENCIES
NONE
RETURN VALUE
0
SIDE EFFECTS
N/A
===========================================================================*/
void loc_eng_nmea_generate_pos(loc_eng_data_s_type *loc_eng_data_p,
const GpsLocation &location, const GpsLocationExtended &locationExtended)
{
ENTRY_LOG();
char sentence[NMEA_SENTENCE_MAX_LENGTH] = {0};
char* pMarker = sentence;
int lengthRemaining = sizeof(sentence);
int length = 0;
time_t utcTime(location.timestamp/1000);
tm * pTm = gmtime(&utcTime);
int utcYear = pTm->tm_year % 100; // 2 digit year
int utcMonth = pTm->tm_mon + 1; // tm_mon starts at zero
int utcDay = pTm->tm_mday;
int utcHours = pTm->tm_hour;
int utcMinutes = pTm->tm_min;
int utcSeconds = pTm->tm_sec;
// ------------------
// ------$GPGSA------
// ------------------
uint32_t svUsedCount = 0;
uint32_t svUsedList[32] = {0};
uint32_t mask = loc_eng_data_p->sv_used_mask;
for (uint8_t i = 1; mask > 0 && svUsedCount < 32; i++)
{
if (mask & 1)
svUsedList[svUsedCount++] = i;
mask = mask >> 1;
}
// clear the cache so they can't be used again
loc_eng_data_p->sv_used_mask = 0;
char fixType;
if (svUsedCount == 0)
fixType = '1'; // no fix
else if (svUsedCount <= 3)
fixType = '2'; // 2D fix
else
fixType = '3'; // 3D fix
length = snprintf(pMarker, lengthRemaining, "$GPGSA,A,%c,", fixType);
if (length < 0 || length >= lengthRemaining)
{
LOC_LOGE("NMEA Error in string formatting");
return;
}
pMarker += length;
lengthRemaining -= length;
for (uint8_t i = 0; i < 12; i++) // only the first 12 sv go in sentence
{
if (i < svUsedCount)
length = snprintf(pMarker, lengthRemaining, "%02d,", svUsedList[i]);
else
length = snprintf(pMarker, lengthRemaining, ",");
if (length < 0 || length >= lengthRemaining)
{
LOC_LOGE("NMEA Error in string formatting");
return;
}
pMarker += length;
lengthRemaining -= length;
}
if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_DOP)
{ // dop is in locationExtended, (QMI)
length = snprintf(pMarker, lengthRemaining, "%.1f,%.1f,%.1f",
locationExtended.pdop,
locationExtended.hdop,
locationExtended.vdop);
}
else if (loc_eng_data_p->pdop > 0 && loc_eng_data_p->hdop > 0 && loc_eng_data_p->vdop > 0)
{ // dop was cached from sv report (RPC)
length = snprintf(pMarker, lengthRemaining, "%.1f,%.1f,%.1f",
loc_eng_data_p->pdop,
loc_eng_data_p->hdop,
loc_eng_data_p->vdop);
}
else
{ // no dop
length = snprintf(pMarker, lengthRemaining, ",,");
}
length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
loc_eng_nmea_send(sentence, length, loc_eng_data_p);
// ------------------
// ------$GPVTG------
// ------------------
pMarker = sentence;
lengthRemaining = sizeof(sentence);
if (location.flags & GPS_LOCATION_HAS_BEARING)
{
float magTrack = location.bearing;
if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_MAG_DEV)
{
float magTrack = location.bearing - locationExtended.magneticDeviation;
if (magTrack < 0.0)
magTrack += 360.0;
else if (magTrack > 360.0)
magTrack -= 360.0;
}
length = snprintf(pMarker, lengthRemaining, "$GPVTG,%.1lf,T,%.1lf,M,", location.bearing, magTrack);
}
else
{
length = snprintf(pMarker, lengthRemaining, "$GPVTG,,T,,M,");
}
if (length < 0 || length >= lengthRemaining)
{
LOC_LOGE("NMEA Error in string formatting");
return;
}
pMarker += length;
lengthRemaining -= length;
if (location.flags & GPS_LOCATION_HAS_SPEED)
{
float speedKnots = location.speed * (3600.0/1852.0);
float speedKmPerHour = location.speed * 3.6;
length = snprintf(pMarker, lengthRemaining, "%.1lf,N,%.1lf,K,", speedKnots, speedKmPerHour);
}
else
{
length = snprintf(pMarker, lengthRemaining, ",N,,K,");
}
if (length < 0 || length >= lengthRemaining)
{
LOC_LOGE("NMEA Error in string formatting");
return;
}
pMarker += length;
lengthRemaining -= length;
if (!(location.flags & GPS_LOCATION_HAS_LAT_LONG))
length = snprintf(pMarker, lengthRemaining, "%c", 'N'); // N means no fix
else if (LOC_POSITION_MODE_STANDALONE == loc_eng_data_p->client_handle->getPositionMode().mode)
length = snprintf(pMarker, lengthRemaining, "%c", 'A'); // A means autonomous
else
length = snprintf(pMarker, lengthRemaining, "%c", 'D'); // D means differential
length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
loc_eng_nmea_send(sentence, length, loc_eng_data_p);
// ------------------
// ------$GPRMC------
// ------------------
pMarker = sentence;
lengthRemaining = sizeof(sentence);
length = snprintf(pMarker, lengthRemaining, "$GPRMC,%02d%02d%02d,A," ,
utcHours, utcMinutes, utcSeconds);
if (length < 0 || length >= lengthRemaining)
{
LOC_LOGE("NMEA Error in string formatting");
return;
}
pMarker += length;
lengthRemaining -= length;
if (location.flags & GPS_LOCATION_HAS_LAT_LONG)
{
double latitude = location.latitude;
double longitude = location.longitude;
char latHemisphere;
char lonHemisphere;
double latMinutes;
double lonMinutes;
if (latitude > 0)
{
latHemisphere = 'N';
}
else
{
latHemisphere = 'S';
latitude *= -1.0;
}
if (longitude < 0)
{
lonHemisphere = 'W';
longitude *= -1.0;
}
else
{
lonHemisphere = 'E';
}
latMinutes = fmod(latitude * 60.0 , 60.0);
lonMinutes = fmod(longitude * 60.0 , 60.0);
length = snprintf(pMarker, lengthRemaining, "%02d%09.6lf,%c,%03d%09.6lf,%c,",
(uint8_t)floor(latitude), latMinutes, latHemisphere,
(uint8_t)floor(longitude),lonMinutes, lonHemisphere);
}
else
{
length = snprintf(pMarker, lengthRemaining,",,,,");
}
if (length < 0 || length >= lengthRemaining)
{
LOC_LOGE("NMEA Error in string formatting");
return;
}
pMarker += length;
lengthRemaining -= length;
if (location.flags & GPS_LOCATION_HAS_SPEED)
{
float speedKnots = location.speed * (3600.0/1852.0);
length = snprintf(pMarker, lengthRemaining, "%.1lf,", speedKnots);
}
else
{
length = snprintf(pMarker, lengthRemaining, ",");
}
if (length < 0 || length >= lengthRemaining)
{
LOC_LOGE("NMEA Error in string formatting");
return;
}
pMarker += length;
lengthRemaining -= length;
if (location.flags & GPS_LOCATION_HAS_BEARING)
{
length = snprintf(pMarker, lengthRemaining, "%.1lf,", location.bearing);
}
else
{
length = snprintf(pMarker, lengthRemaining, ",");
}
if (length < 0 || length >= lengthRemaining)
{
LOC_LOGE("NMEA Error in string formatting");
return;
}
pMarker += length;
lengthRemaining -= length;
length = snprintf(pMarker, lengthRemaining, "%2.2d%2.2d%2.2d,",
utcDay, utcMonth, utcYear);
if (length < 0 || length >= lengthRemaining)
{
LOC_LOGE("NMEA Error in string formatting");
return;
}
pMarker += length;
lengthRemaining -= length;
if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_MAG_DEV)
{
float magneticVariation = locationExtended.magneticDeviation;
char direction;
if (magneticVariation < 0.0)
{
direction = 'W';
magneticVariation *= -1.0;
}
else
{
direction = 'E';
}
length = snprintf(pMarker, lengthRemaining, "%.1lf,%c,",
magneticVariation, direction);
}
else
{
length = snprintf(pMarker, lengthRemaining, ",,");
}
if (length < 0 || length >= lengthRemaining)
{
LOC_LOGE("NMEA Error in string formatting");
return;
}
pMarker += length;
lengthRemaining -= length;
if (!(location.flags & GPS_LOCATION_HAS_LAT_LONG))
length = snprintf(pMarker, lengthRemaining, "%c", 'N'); // N means no fix
else if (LOC_POSITION_MODE_STANDALONE == loc_eng_data_p->client_handle->getPositionMode().mode)
length = snprintf(pMarker, lengthRemaining, "%c", 'A'); // A means autonomous
else
length = snprintf(pMarker, lengthRemaining, "%c", 'D'); // D means differential
length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
loc_eng_nmea_send(sentence, length, loc_eng_data_p);
// ------------------
// ------$GPGGA------
// ------------------
pMarker = sentence;
lengthRemaining = sizeof(sentence);
length = snprintf(pMarker, lengthRemaining, "$GPGGA,%02d%02d%02d," ,
utcHours, utcMinutes, utcSeconds);
if (length < 0 || length >= lengthRemaining)
{
LOC_LOGE("NMEA Error in string formatting");
return;
}
pMarker += length;
lengthRemaining -= length;
if (location.flags & GPS_LOCATION_HAS_LAT_LONG)
{
double latitude = location.latitude;
double longitude = location.longitude;
char latHemisphere;
char lonHemisphere;
double latMinutes;
double lonMinutes;
if (latitude > 0)
{
latHemisphere = 'N';
}
else
{
latHemisphere = 'S';
latitude *= -1.0;
}
if (longitude < 0)
{
lonHemisphere = 'W';
longitude *= -1.0;
}
else
{
lonHemisphere = 'E';
}
latMinutes = fmod(latitude * 60.0 , 60.0);
lonMinutes = fmod(longitude * 60.0 , 60.0);
length = snprintf(pMarker, lengthRemaining, "%02d%09.6lf,%c,%03d%09.6lf,%c,",
(uint8_t)floor(latitude), latMinutes, latHemisphere,
(uint8_t)floor(longitude),lonMinutes, lonHemisphere);
}
else
{
length = snprintf(pMarker, lengthRemaining,",,,,");
}
if (length < 0 || length >= lengthRemaining)
{
LOC_LOGE("NMEA Error in string formatting");
return;
}
pMarker += length;
lengthRemaining -= length;
char gpsQuality;
if (!(location.flags & GPS_LOCATION_HAS_LAT_LONG))
gpsQuality = '0'; // 0 means no fix
else if (LOC_POSITION_MODE_STANDALONE == loc_eng_data_p->client_handle->getPositionMode().mode)
gpsQuality = '1'; // 1 means GPS fix
else
gpsQuality = '2'; // 2 means DGPS fix
if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_DOP)
{ // dop is in locationExtended, (QMI)
length = snprintf(pMarker, lengthRemaining, "%c,%02d,%.1f,",
gpsQuality, svUsedCount, locationExtended.hdop);
}
else if (loc_eng_data_p->pdop > 0 && loc_eng_data_p->hdop > 0 && loc_eng_data_p->vdop > 0)
{ // dop was cached from sv report (RPC)
length = snprintf(pMarker, lengthRemaining, "%c,%02d,%.1f,",
gpsQuality, svUsedCount, loc_eng_data_p->hdop);
}
else
{ // no hdop
length = snprintf(pMarker, lengthRemaining, "%c,%02d,,",
gpsQuality, svUsedCount);
}
if (length < 0 || length >= lengthRemaining)
{
LOC_LOGE("NMEA Error in string formatting");
return;
}
pMarker += length;
lengthRemaining -= length;
if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL)
{
length = snprintf(pMarker, lengthRemaining, "%.1lf,M,",
locationExtended.altitudeMeanSeaLevel);
}
else
{
length = snprintf(pMarker, lengthRemaining,",,");
}
if (length < 0 || length >= lengthRemaining)
{
LOC_LOGE("NMEA Error in string formatting");
return;
}
pMarker += length;
lengthRemaining -= length;
if ((location.flags & GPS_LOCATION_HAS_ALTITUDE) &&
(locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL))
{
length = snprintf(pMarker, lengthRemaining, "%.1lf,M,,",
location.altitude - locationExtended.altitudeMeanSeaLevel);
}
else
{
length = snprintf(pMarker, lengthRemaining,",,,");
}
length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
loc_eng_nmea_send(sentence, length, loc_eng_data_p);
// clear the dop cache so they can't be used again
loc_eng_data_p->pdop = 0;
loc_eng_data_p->hdop = 0;
loc_eng_data_p->vdop = 0;
EXIT_LOG(%d, 0);
}
/*===========================================================================
FUNCTION loc_eng_nmea_generate_sv
DESCRIPTION
Generate NMEA sentences generated based on sv report
DEPENDENCIES
NONE
RETURN VALUE
0
SIDE EFFECTS
N/A
===========================================================================*/
void loc_eng_nmea_generate_sv(loc_eng_data_s_type *loc_eng_data_p,
const GpsSvStatus &svStatus, const GpsLocationExtended &locationExtended)
{
ENTRY_LOG();
char sentence[NMEA_SENTENCE_MAX_LENGTH] = {0};
char* pMarker = sentence;
int lengthRemaining = sizeof(sentence);
int length = 0;
// ------------------
// ------$GPGSV------
// ------------------
if (svStatus.num_svs <= 0)
{
// no svs in view, so just send a blank $GPGSV sentence
strlcpy(sentence, "$GPGSV,1,1,0,", sizeof(sentence));
length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
loc_eng_nmea_send(sentence, length, loc_eng_data_p);
}
else
{
int svCount = svStatus.num_svs;
int sentenceCount = svCount / 4;
if (svStatus.num_svs % 4)
sentenceCount++;
int sentenceNumber = 1;
int svNumber = 1;
while (sentenceNumber <= sentenceCount)
{
pMarker = sentence;
lengthRemaining = sizeof(sentence);
length = snprintf(pMarker, lengthRemaining, "$GPGSV,%d,%d,%02d",
sentenceCount, sentenceNumber, svCount);
if (length < 0 || length >= lengthRemaining)
{
LOC_LOGE("NMEA Error in string formatting");
return;
}
pMarker += length;
lengthRemaining -= length;
for (int i=0; (svNumber <= svCount) && (i < 4); i++, svNumber++)
{
length = snprintf(pMarker, lengthRemaining,",%02d,%02d,%03d,",
svStatus.sv_list[svNumber-1].prn,
(int)(0.5 + svStatus.sv_list[svNumber-1].elevation), //float to int
(int)(0.5 + svStatus.sv_list[svNumber-1].azimuth)); //float to int
if (length < 0 || length >= lengthRemaining)
{
LOC_LOGE("NMEA Error in string formatting");
return;
}
pMarker += length;
lengthRemaining -= length;
if (svStatus.sv_list[svNumber-1].snr > 0)
{
length = snprintf(pMarker, lengthRemaining,"%02d",
(int)(0.5 + svStatus.sv_list[svNumber-1].snr)); //float to int
if (length < 0 || length >= lengthRemaining)
{
LOC_LOGE("NMEA Error in string formatting");
return;
}
pMarker += length;
lengthRemaining -= length;
}
}
length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
loc_eng_nmea_send(sentence, length, loc_eng_data_p);
sentenceNumber++;
}
}
if (svStatus.used_in_fix_mask == 0)
{ // No sv used, so there will be no position report, so send
// blank NMEA sentences
strlcpy(sentence, "$GPGSA,A,1,,,,,,,,,,,,,,,", sizeof(sentence));
length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
loc_eng_nmea_send(sentence, length, loc_eng_data_p);
strlcpy(sentence, "$GPVTG,,T,,M,,N,,K,N", sizeof(sentence));
length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
loc_eng_nmea_send(sentence, length, loc_eng_data_p);
strlcpy(sentence, "$GPRMC,,V,,,,,,,,,,N", sizeof(sentence));
length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
loc_eng_nmea_send(sentence, length, loc_eng_data_p);
strlcpy(sentence, "$GPGGA,,,,,,0,,,,,,,,", sizeof(sentence));
length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
loc_eng_nmea_send(sentence, length, loc_eng_data_p);
}
else
{ // cache the used in fix mask, as it will be needed to send $GPGSA
// during the position report
loc_eng_data_p->sv_used_mask = svStatus.used_in_fix_mask;
// For RPC, the DOP are sent during sv report, so cache them
// now to be sent during position report.
// For QMI, the DOP will be in position report.
if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_DOP)
{
loc_eng_data_p->pdop = locationExtended.pdop;
loc_eng_data_p->hdop = locationExtended.hdop;
loc_eng_data_p->vdop = locationExtended.vdop;
}
else
{
loc_eng_data_p->pdop = 0;
loc_eng_data_p->hdop = 0;
loc_eng_data_p->vdop = 0;
}
}
EXIT_LOG(%d, 0);
}

View file

@ -0,0 +1,42 @@
/* Copyright (c) 2012, 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 Code Aurora Forum, Inc. 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.
*
*/
#ifndef LOC_ENG_NMEA_H
#define LOC_ENG_NMEA_H
#include <hardware/gps.h>
#define NMEA_SENTENCE_MAX_LENGTH 200
void loc_eng_nmea_send(char *pNmea, int length, loc_eng_data_s_type *loc_eng_data_p);
int loc_eng_nmea_put_checksum(char *pNmea, int maxSize);
void loc_eng_nmea_generate_sv(loc_eng_data_s_type *loc_eng_data_p, const GpsSvStatus &svStatus, const GpsLocationExtended &locationExtended);
void loc_eng_nmea_generate_pos(loc_eng_data_s_type *loc_eng_data_p, const GpsLocation &location, const GpsLocationExtended &locationExtended);
#endif // LOC_ENG_NMEA_H

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2011, Code Aurora Forum. All rights reserved. /* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are * modification, are permitted provided that the following conditions are
@ -1554,6 +1554,9 @@ void LocApiV02Adapter :: reportPosition (
LOC_LOGD("Reporting postion from V2 Adapter\n"); LOC_LOGD("Reporting postion from V2 Adapter\n");
memset(&location, 0, sizeof (GpsLocation)); memset(&location, 0, sizeof (GpsLocation));
location.size = sizeof(location); location.size = sizeof(location);
GpsLocationExtended locationExtended;
memset(&locationExtended, 0, sizeof (GpsLocationExtended));
locationExtended.size = sizeof(locationExtended);
// Process the position from final and intermediate reports // Process the position from final and intermediate reports
if( (location_report_ptr->sessionStatus == eQMI_LOC_SESS_STATUS_SUCCESS_V02) || if( (location_report_ptr->sessionStatus == eQMI_LOC_SESS_STATUS_SUCCESS_V02) ||
@ -1615,7 +1618,29 @@ void LocApiV02Adapter :: reportPosition (
//Mark the location source as from GNSS //Mark the location source as from GNSS
location.flags |= LOCATION_HAS_SOURCE_INFO; location.flags |= LOCATION_HAS_SOURCE_INFO;
location.position_source = ULP_LOCATION_IS_FROM_GNSS; 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;
}
LocApiAdapter::reportPosition( location, LocApiAdapter::reportPosition( location,
locationExtended,
locEngHandle.extPosInfo((void*)location_report_ptr), locEngHandle.extPosInfo((void*)location_report_ptr),
(location_report_ptr->sessionStatus (location_report_ptr->sessionStatus
== eQMI_LOC_SESS_STATUS_IN_PROGRESS_V02 ? == eQMI_LOC_SESS_STATUS_IN_PROGRESS_V02 ?
@ -1626,6 +1651,7 @@ void LocApiV02Adapter :: reportPosition (
else else
{ {
LocApiAdapter::reportPosition(location, LocApiAdapter::reportPosition(location,
locationExtended,
NULL, NULL,
LOC_SESS_FAILURE); LOC_SESS_FAILURE);
@ -1642,6 +1668,7 @@ void LocApiV02Adapter :: reportSv (
const qmiLocEventGnssSvInfoIndMsgT_v02 *gnss_report_ptr) const qmiLocEventGnssSvInfoIndMsgT_v02 *gnss_report_ptr)
{ {
GpsSvStatus SvStatus; GpsSvStatus SvStatus;
GpsLocationExtended locationExtended;
int num_svs_max, i; int num_svs_max, i;
const qmiLocSvInfoStructT_v02 *sv_info_ptr; const qmiLocSvInfoStructT_v02 *sv_info_ptr;
@ -1650,6 +1677,8 @@ void LocApiV02Adapter :: reportSv (
num_svs_max = 0; num_svs_max = 0;
memset (&SvStatus, 0, sizeof (GpsSvStatus)); memset (&SvStatus, 0, sizeof (GpsSvStatus));
memset(&locationExtended, 0, sizeof (GpsLocationExtended));
locationExtended.size = sizeof(locationExtended);
if(gnss_report_ptr->svList_valid == 1) if(gnss_report_ptr->svList_valid == 1)
{ {
num_svs_max = gnss_report_ptr->svList_len; num_svs_max = gnss_report_ptr->svList_len;
@ -1740,6 +1769,7 @@ void LocApiV02Adapter :: reportSv (
{ {
LOC_LOGV ("%s:%d]: firing SV callback\n", __func__, __LINE__); LOC_LOGV ("%s:%d]: firing SV callback\n", __func__, __LINE__);
LocApiAdapter::reportSv(SvStatus, LocApiAdapter::reportSv(SvStatus,
locationExtended,
locEngHandle.extSvInfo((void*)gnss_report_ptr)); locEngHandle.extSvInfo((void*)gnss_report_ptr));
} }
} }