2732 lines
121 KiB
C++
2732 lines
121 KiB
C++
/* Copyright (c) 2018-2020, 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 Foundation 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_TAG "LocSvc_LocationClientApi"
|
|
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
#include <loc_cfg.h>
|
|
#include <LocationClientApiImpl.h>
|
|
#include <log_util.h>
|
|
#include <gps_extended_c.h>
|
|
#include <unistd.h>
|
|
#include <sstream>
|
|
#include <dlfcn.h>
|
|
#include <loc_misc_utils.h>
|
|
|
|
static uint32_t gDebug = 0;
|
|
|
|
static const loc_param_s_type gConfigTable[] =
|
|
{
|
|
{"DEBUG_LEVEL", &gDebug, NULL, 'n'}
|
|
};
|
|
|
|
|
|
namespace location_client {
|
|
|
|
static uint32_t gfIdGenerator = LOCATION_CLIENT_SESSION_ID_INVALID;
|
|
mutex GeofenceImpl::mGfMutex;
|
|
uint32_t GeofenceImpl::nextId() {
|
|
lock_guard<mutex> lock(mGfMutex);
|
|
uint32_t id = ++gfIdGenerator;
|
|
if (0xFFFFFFFF == id) {
|
|
id = 0;
|
|
gfIdGenerator = 0;
|
|
}
|
|
return id;
|
|
}
|
|
|
|
/******************************************************************************
|
|
Utilities
|
|
******************************************************************************/
|
|
static GnssMeasurementsDataFlagsMask parseMeasurementsDataMask(
|
|
::GnssMeasurementsDataFlagsMask in) {
|
|
uint32_t out = 0;
|
|
LOC_LOGd("Hal GnssMeasurementsDataFlagsMask =0x%x ", in);
|
|
|
|
if (::GNSS_MEASUREMENTS_DATA_SV_ID_BIT & in) {
|
|
out |= GNSS_MEASUREMENTS_DATA_SV_ID_BIT;
|
|
}
|
|
if (::GNSS_MEASUREMENTS_DATA_SV_TYPE_BIT & in) {
|
|
out |= GNSS_MEASUREMENTS_DATA_SV_TYPE_BIT;
|
|
}
|
|
if (::GNSS_MEASUREMENTS_DATA_STATE_BIT & in) {
|
|
out |= GNSS_MEASUREMENTS_DATA_STATE_BIT;
|
|
}
|
|
if (::GNSS_MEASUREMENTS_DATA_RECEIVED_SV_TIME_BIT & in) {
|
|
out |= GNSS_MEASUREMENTS_DATA_RECEIVED_SV_TIME_BIT;
|
|
}
|
|
if (::GNSS_MEASUREMENTS_DATA_RECEIVED_SV_TIME_UNCERTAINTY_BIT & in) {
|
|
out |= GNSS_MEASUREMENTS_DATA_RECEIVED_SV_TIME_UNCERTAINTY_BIT;
|
|
}
|
|
if (::GNSS_MEASUREMENTS_DATA_CARRIER_TO_NOISE_BIT & in) {
|
|
out |= GNSS_MEASUREMENTS_DATA_CARRIER_TO_NOISE_BIT;
|
|
}
|
|
if (::GNSS_MEASUREMENTS_DATA_PSEUDORANGE_RATE_BIT & in) {
|
|
out |= GNSS_MEASUREMENTS_DATA_PSEUDORANGE_RATE_BIT;
|
|
}
|
|
if (::GNSS_MEASUREMENTS_DATA_PSEUDORANGE_RATE_UNCERTAINTY_BIT & in) {
|
|
out |= GNSS_MEASUREMENTS_DATA_PSEUDORANGE_RATE_UNCERTAINTY_BIT;
|
|
}
|
|
if (::GNSS_MEASUREMENTS_DATA_ADR_STATE_BIT & in) {
|
|
out |= GNSS_MEASUREMENTS_DATA_ADR_STATE_BIT;
|
|
}
|
|
if (::GNSS_MEASUREMENTS_DATA_ADR_BIT & in) {
|
|
out |= GNSS_MEASUREMENTS_DATA_ADR_BIT;
|
|
}
|
|
if (::GNSS_MEASUREMENTS_DATA_ADR_UNCERTAINTY_BIT & in) {
|
|
out |= GNSS_MEASUREMENTS_DATA_ADR_UNCERTAINTY_BIT;
|
|
}
|
|
if (::GNSS_MEASUREMENTS_DATA_CARRIER_FREQUENCY_BIT & in) {
|
|
out |= GNSS_MEASUREMENTS_DATA_CARRIER_FREQUENCY_BIT;
|
|
}
|
|
if (::GNSS_MEASUREMENTS_DATA_CARRIER_CYCLES_BIT & in) {
|
|
out |= GNSS_MEASUREMENTS_DATA_CARRIER_CYCLES_BIT;
|
|
}
|
|
if (::GNSS_MEASUREMENTS_DATA_CARRIER_PHASE_BIT & in) {
|
|
out |= GNSS_MEASUREMENTS_DATA_CARRIER_PHASE_BIT;
|
|
}
|
|
if (::GNSS_MEASUREMENTS_DATA_CARRIER_PHASE_UNCERTAINTY_BIT & in) {
|
|
out |= GNSS_MEASUREMENTS_DATA_CARRIER_PHASE_UNCERTAINTY_BIT;
|
|
}
|
|
if (::GNSS_MEASUREMENTS_DATA_MULTIPATH_INDICATOR_BIT & in) {
|
|
out |= GNSS_MEASUREMENTS_DATA_MULTIPATH_INDICATOR_BIT;
|
|
}
|
|
if (::GNSS_MEASUREMENTS_DATA_SIGNAL_TO_NOISE_RATIO_BIT & in) {
|
|
out |= GNSS_MEASUREMENTS_DATA_SIGNAL_TO_NOISE_RATIO_BIT;
|
|
}
|
|
if (::GNSS_MEASUREMENTS_DATA_AUTOMATIC_GAIN_CONTROL_BIT & in) {
|
|
out |= GNSS_MEASUREMENTS_DATA_AUTOMATIC_GAIN_CONTROL_BIT;
|
|
}
|
|
if (::GNSS_MEASUREMENTS_DATA_FULL_ISB_BIT & in) {
|
|
out |= GNSS_MEASUREMENTS_DATA_FULL_ISB_BIT;
|
|
}
|
|
if (::GNSS_MEASUREMENTS_DATA_FULL_ISB_UNCERTAINTY_BIT & in) {
|
|
out |= GNSS_MEASUREMENTS_DATA_FULL_ISB_UNCERTAINTY_BIT;
|
|
}
|
|
if (::GNSS_MEASUREMENTS_DATA_CYCLE_SLIP_COUNT_BIT & in) {
|
|
out |= GNSS_MEASUREMENTS_DATA_CYCLE_SLIP_COUNT_BIT;
|
|
}
|
|
LOC_LOGd("LCA GnssMeasurementsDataFlagsMask =0x%x ", out);
|
|
return static_cast<GnssMeasurementsDataFlagsMask>(out);
|
|
}
|
|
|
|
static LocationCapabilitiesMask parseCapabilitiesMask(::LocationCapabilitiesMask mask) {
|
|
LocationCapabilitiesMask capsMask = 0;
|
|
if (::LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT & mask) {
|
|
capsMask |= LOCATION_CAPS_TIME_BASED_TRACKING_BIT;
|
|
}
|
|
if (::LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT & mask) {
|
|
capsMask |= LOCATION_CAPS_TIME_BASED_BATCHING_BIT;
|
|
}
|
|
if (::LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT & mask) {
|
|
capsMask |= LOCATION_CAPS_DISTANCE_BASED_TRACKING_BIT;
|
|
}
|
|
if (::LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT & mask) {
|
|
capsMask |= LOCATION_CAPS_DISTANCE_BASED_BATCHING_BIT;
|
|
}
|
|
if (::LOCATION_CAPABILITIES_GEOFENCE_BIT & mask) {
|
|
capsMask |= LOCATION_CAPS_GEOFENCE_BIT;
|
|
}
|
|
if (::LOCATION_CAPABILITIES_OUTDOOR_TRIP_BATCHING_BIT & mask) {
|
|
capsMask |= LOCATION_CAPS_OUTDOOR_TRIP_BATCHING_BIT;
|
|
}
|
|
if (::LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT & mask) {
|
|
capsMask |= LOCATION_CAPS_GNSS_MEASUREMENTS_BIT;
|
|
}
|
|
if (::LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT & mask) {
|
|
capsMask |= LOCATION_CAPS_CONSTELLATION_ENABLEMENT_BIT;
|
|
}
|
|
if (::LOCATION_CAPABILITIES_QWES_CARRIER_PHASE_BIT & mask) {
|
|
capsMask |= LOCATION_CAPS_CARRIER_PHASE_BIT;
|
|
}
|
|
if (::LOCATION_CAPABILITIES_QWES_SV_POLYNOMIAL_BIT & mask) {
|
|
capsMask |= LOCATION_CAPS_SV_POLYNOMIAL_BIT;
|
|
}
|
|
if (::LOCATION_CAPABILITIES_QWES_GNSS_SINGLE_FREQUENCY & mask) {
|
|
capsMask |= LOCATION_CAPS_QWES_GNSS_SINGLE_FREQUENCY;
|
|
}
|
|
if (::LOCATION_CAPABILITIES_QWES_GNSS_MULTI_FREQUENCY & mask) {
|
|
capsMask |= LOCATION_CAPS_QWES_GNSS_MULTI_FREQUENCY;
|
|
}
|
|
if (::LOCATION_CAPABILITIES_QWES_VPE & mask) {
|
|
capsMask |= LOCATION_CAPS_QWES_VPE;
|
|
}
|
|
if (::LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_BASIC & mask) {
|
|
capsMask |= LOCATION_CAPS_QWES_CV2X_LOCATION_BASIC;
|
|
}
|
|
if (::LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_PREMIUM & mask) {
|
|
capsMask |= LOCATION_CAPS_QWES_CV2X_LOCATION_PREMIUM;
|
|
}
|
|
if (::LOCATION_CAPABILITIES_QWES_PPE & mask) {
|
|
capsMask |= LOCATION_CAPS_QWES_PPE;
|
|
}
|
|
if (::LOCATION_CAPABILITIES_QWES_QDR2 & mask) {
|
|
capsMask |= LOCATION_CAPS_QWES_QDR2;
|
|
}
|
|
if (::LOCATION_CAPABILITIES_QWES_QDR3 & mask) {
|
|
capsMask |= LOCATION_CAPS_QWES_QDR3;
|
|
}
|
|
LOC_LOGd ("parseCapabilitiesMask LocCapabMask =0x%" PRIx64 " LCA mask 0x%" PRIx64,
|
|
mask, capsMask);
|
|
return capsMask;
|
|
}
|
|
|
|
static uint16_t parseYearOfHw(::LocationCapabilitiesMask mask) {
|
|
uint16_t yearOfHw = 2015;
|
|
if (::LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT & mask) {
|
|
yearOfHw++; // 2016
|
|
if (::LOCATION_CAPABILITIES_DEBUG_NMEA_BIT & mask) {
|
|
yearOfHw++; // 2017
|
|
if (::LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT & mask ||
|
|
::LOCATION_CAPABILITIES_AGPM_BIT & mask) {
|
|
yearOfHw++; // 2018
|
|
if (::LOCATION_CAPABILITIES_PRIVACY_BIT & mask) {
|
|
yearOfHw++; // 2019
|
|
if (::LOCATION_CAPABILITIES_MEASUREMENTS_CORRECTION_BIT & mask) {
|
|
yearOfHw++; // 2020
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return yearOfHw;
|
|
}
|
|
|
|
static void parseLocation(const ::Location &halLocation, Location& location) {
|
|
uint32_t flags = 0;
|
|
|
|
location.timestamp = halLocation.timestamp;
|
|
location.latitude = halLocation.latitude;
|
|
location.longitude = halLocation.longitude;
|
|
location.altitude = halLocation.altitude;
|
|
location.speed = halLocation.speed;
|
|
location.bearing = halLocation.bearing;
|
|
location.horizontalAccuracy = halLocation.accuracy;
|
|
location.verticalAccuracy = halLocation.verticalAccuracy;
|
|
location.speedAccuracy = halLocation.speedAccuracy;
|
|
location.bearingAccuracy = halLocation.bearingAccuracy;
|
|
|
|
if (0 != halLocation.timestamp) {
|
|
flags |= LOCATION_HAS_TIMESTAMP_BIT;
|
|
}
|
|
if (::LOCATION_HAS_LAT_LONG_BIT & halLocation.flags) {
|
|
flags |= LOCATION_HAS_LAT_LONG_BIT;
|
|
}
|
|
if (::LOCATION_HAS_ALTITUDE_BIT & halLocation.flags) {
|
|
flags |= LOCATION_HAS_ALTITUDE_BIT;
|
|
}
|
|
if (::LOCATION_HAS_SPEED_BIT & halLocation.flags) {
|
|
flags |= LOCATION_HAS_SPEED_BIT;
|
|
}
|
|
if (::LOCATION_HAS_BEARING_BIT & halLocation.flags) {
|
|
flags |= LOCATION_HAS_BEARING_BIT;
|
|
}
|
|
if (::LOCATION_HAS_ACCURACY_BIT & halLocation.flags) {
|
|
flags |= LOCATION_HAS_ACCURACY_BIT;
|
|
}
|
|
if (::LOCATION_HAS_VERTICAL_ACCURACY_BIT & halLocation.flags) {
|
|
flags |= LOCATION_HAS_VERTICAL_ACCURACY_BIT;
|
|
}
|
|
if (::LOCATION_HAS_SPEED_ACCURACY_BIT & halLocation.flags) {
|
|
flags |= LOCATION_HAS_SPEED_ACCURACY_BIT;
|
|
}
|
|
if (::LOCATION_HAS_BEARING_ACCURACY_BIT & halLocation.flags) {
|
|
flags |= LOCATION_HAS_BEARING_ACCURACY_BIT;
|
|
}
|
|
location.flags = (LocationFlagsMask)flags;
|
|
|
|
flags = 0;
|
|
if (::LOCATION_TECHNOLOGY_GNSS_BIT & halLocation.techMask) {
|
|
flags |= LOCATION_TECHNOLOGY_GNSS_BIT;
|
|
}
|
|
if (::LOCATION_TECHNOLOGY_CELL_BIT & halLocation.techMask) {
|
|
flags |= LOCATION_TECHNOLOGY_CELL_BIT;
|
|
}
|
|
if (::LOCATION_TECHNOLOGY_WIFI_BIT & halLocation.techMask) {
|
|
flags |= LOCATION_TECHNOLOGY_WIFI_BIT;
|
|
}
|
|
if (::LOCATION_TECHNOLOGY_SENSORS_BIT & halLocation.techMask) {
|
|
flags |= LOCATION_TECHNOLOGY_SENSORS_BIT;
|
|
}
|
|
if (::LOCATION_TECHNOLOGY_REFERENCE_LOCATION_BIT & halLocation.techMask) {
|
|
flags |= LOCATION_TECHNOLOGY_REFERENCE_LOCATION_BIT;
|
|
}
|
|
if (::LOCATION_TECHNOLOGY_INJECTED_COARSE_POSITION_BIT & halLocation.techMask) {
|
|
flags |= LOCATION_TECHNOLOGY_INJECTED_COARSE_POSITION_BIT;
|
|
}
|
|
if (::LOCATION_TECHNOLOGY_AFLT_BIT & halLocation.techMask) {
|
|
flags |= LOCATION_TECHNOLOGY_AFLT_BIT;
|
|
}
|
|
if (::LOCATION_TECHNOLOGY_HYBRID_BIT & halLocation.techMask) {
|
|
flags |= LOCATION_TECHNOLOGY_HYBRID_BIT;
|
|
}
|
|
if (::LOCATION_TECHNOLOGY_PPE_BIT & halLocation.techMask) {
|
|
flags |= LOCATION_TECHNOLOGY_PPE_BIT;
|
|
}
|
|
if (::LOCATION_TECHNOLOGY_VEH_BIT & halLocation.techMask) {
|
|
flags |= LOCATION_TECHNOLOGY_VEH_BIT;
|
|
}
|
|
if (::LOCATION_TECHNOLOGY_VIS_BIT & halLocation.techMask) {
|
|
flags |= LOCATION_TECHNOLOGY_VIS_BIT;
|
|
}
|
|
location.techMask = (LocationTechnologyMask)flags;
|
|
}
|
|
|
|
static Location parseLocation(const ::Location &halLocation) {
|
|
Location location;
|
|
parseLocation(halLocation, location);
|
|
return location;
|
|
}
|
|
|
|
static GnssLocationSvUsedInPosition parseLocationSvUsedInPosition(
|
|
const ::GnssLocationSvUsedInPosition &halSv) {
|
|
|
|
GnssLocationSvUsedInPosition clientSv;
|
|
clientSv.gpsSvUsedIdsMask = halSv.gpsSvUsedIdsMask;
|
|
clientSv.gloSvUsedIdsMask = halSv.gloSvUsedIdsMask;
|
|
clientSv.galSvUsedIdsMask = halSv.galSvUsedIdsMask;
|
|
clientSv.bdsSvUsedIdsMask = halSv.bdsSvUsedIdsMask;
|
|
clientSv.qzssSvUsedIdsMask = halSv.qzssSvUsedIdsMask;
|
|
clientSv.navicSvUsedIdsMask = halSv.navicSvUsedIdsMask;
|
|
return clientSv;
|
|
}
|
|
|
|
static GnssSignalTypeMask parseGnssSignalType(const ::GnssSignalTypeMask &halGnssSignalTypeMask) {
|
|
uint32_t gnssSignalTypeMask = 0;
|
|
if (halGnssSignalTypeMask & ::GNSS_SIGNAL_GPS_L1CA) {
|
|
gnssSignalTypeMask |= GNSS_SIGNAL_GPS_L1CA_BIT;
|
|
}
|
|
if (halGnssSignalTypeMask & ::GNSS_SIGNAL_GPS_L1C) {
|
|
gnssSignalTypeMask |= GNSS_SIGNAL_GPS_L1C_BIT;
|
|
}
|
|
if (halGnssSignalTypeMask & ::GNSS_SIGNAL_GPS_L2) {
|
|
gnssSignalTypeMask |= GNSS_SIGNAL_GPS_L2_BIT;
|
|
}
|
|
if (halGnssSignalTypeMask & ::GNSS_SIGNAL_GPS_L5) {
|
|
gnssSignalTypeMask |= GNSS_SIGNAL_GPS_L5_BIT;
|
|
}
|
|
if (halGnssSignalTypeMask & ::GNSS_SIGNAL_GLONASS_G1) {
|
|
gnssSignalTypeMask |= GNSS_SIGNAL_GLONASS_G1_BIT;
|
|
}
|
|
if (halGnssSignalTypeMask & ::GNSS_SIGNAL_GLONASS_G2) {
|
|
gnssSignalTypeMask |= GNSS_SIGNAL_GLONASS_G2_BIT;
|
|
}
|
|
if (halGnssSignalTypeMask & ::GNSS_SIGNAL_GALILEO_E1) {
|
|
gnssSignalTypeMask |= GNSS_SIGNAL_GALILEO_E1_BIT;
|
|
}
|
|
if (halGnssSignalTypeMask & ::GNSS_SIGNAL_GALILEO_E5A) {
|
|
gnssSignalTypeMask |= GNSS_SIGNAL_GALILEO_E5A_BIT;
|
|
}
|
|
if (halGnssSignalTypeMask & ::GNSS_SIGNAL_GALILEO_E5B) {
|
|
gnssSignalTypeMask |= GNSS_SIGNAL_GALILEO_E5B_BIT;
|
|
}
|
|
if (halGnssSignalTypeMask & ::GNSS_SIGNAL_BEIDOU_B1I) {
|
|
gnssSignalTypeMask |= GNSS_SIGNAL_BEIDOU_B1I_BIT;
|
|
}
|
|
if (halGnssSignalTypeMask & ::GNSS_SIGNAL_BEIDOU_B1C) {
|
|
gnssSignalTypeMask |= GNSS_SIGNAL_BEIDOU_B1C_BIT;
|
|
}
|
|
if (halGnssSignalTypeMask & ::GNSS_SIGNAL_BEIDOU_B2I) {
|
|
gnssSignalTypeMask |= GNSS_SIGNAL_BEIDOU_B2I_BIT;
|
|
}
|
|
if (halGnssSignalTypeMask & ::GNSS_SIGNAL_BEIDOU_B2AI) {
|
|
gnssSignalTypeMask |= GNSS_SIGNAL_BEIDOU_B2AI_BIT;
|
|
}
|
|
if (halGnssSignalTypeMask & ::GNSS_SIGNAL_QZSS_L1CA) {
|
|
gnssSignalTypeMask |= GNSS_SIGNAL_QZSS_L1CA_BIT;
|
|
}
|
|
if (halGnssSignalTypeMask & ::GNSS_SIGNAL_QZSS_L1S) {
|
|
gnssSignalTypeMask |= GNSS_SIGNAL_QZSS_L1S_BIT;
|
|
}
|
|
if (halGnssSignalTypeMask & ::GNSS_SIGNAL_QZSS_L2) {
|
|
gnssSignalTypeMask |= GNSS_SIGNAL_QZSS_L2_BIT;
|
|
}
|
|
if (halGnssSignalTypeMask & ::GNSS_SIGNAL_QZSS_L5) {
|
|
gnssSignalTypeMask |= GNSS_SIGNAL_QZSS_L5_BIT;
|
|
}
|
|
if (halGnssSignalTypeMask & ::GNSS_SIGNAL_SBAS_L1) {
|
|
gnssSignalTypeMask |= GNSS_SIGNAL_SBAS_L1_BIT;
|
|
}
|
|
if (halGnssSignalTypeMask & ::GNSS_SIGNAL_NAVIC_L5) {
|
|
gnssSignalTypeMask |= GNSS_SIGNAL_NAVIC_L5_BIT;
|
|
}
|
|
if (halGnssSignalTypeMask & ::GNSS_SIGNAL_BEIDOU_B2AQ) {
|
|
gnssSignalTypeMask |= GNSS_SIGNAL_BEIDOU_B2AQ_BIT;
|
|
}
|
|
if (halGnssSignalTypeMask & ::GNSS_SIGNAL_BEIDOU_B1) {
|
|
gnssSignalTypeMask |= GNSS_SIGNAL_BEIDOU_B1;
|
|
}
|
|
if (halGnssSignalTypeMask & ::GNSS_SIGNAL_BEIDOU_B2) {
|
|
gnssSignalTypeMask |= GNSS_SIGNAL_BEIDOU_B2;
|
|
}
|
|
return (GnssSignalTypeMask)gnssSignalTypeMask;
|
|
}
|
|
|
|
static void parseGnssMeasUsageInfo(const ::GnssLocationInfoNotification &halLocationInfo,
|
|
std::vector<GnssMeasUsageInfo>& clientMeasUsageInfo) {
|
|
|
|
if (halLocationInfo.numOfMeasReceived) {
|
|
|
|
for (int idx = 0; idx < halLocationInfo.numOfMeasReceived; idx++) {
|
|
GnssMeasUsageInfo measUsageInfo;
|
|
|
|
measUsageInfo.gnssSignalType = parseGnssSignalType(
|
|
halLocationInfo.measUsageInfo[idx].gnssSignalType);
|
|
measUsageInfo.gnssConstellation = (Gnss_LocSvSystemEnumType)
|
|
halLocationInfo.measUsageInfo[idx].gnssConstellation;
|
|
measUsageInfo.gnssSvId = halLocationInfo.measUsageInfo[idx].gnssSvId;
|
|
clientMeasUsageInfo.push_back(measUsageInfo);
|
|
}
|
|
}
|
|
}
|
|
|
|
static GnssLocationPositionDynamics parseLocationPositionDynamics(
|
|
const ::GnssLocationPositionDynamics &halPositionDynamics,
|
|
const ::GnssLocationPositionDynamicsExt &halPositionDynamicsExt) {
|
|
GnssLocationPositionDynamics positionDynamics = {};
|
|
uint32_t bodyFrameDataMask = 0;
|
|
|
|
if (::LOCATION_NAV_DATA_HAS_LONG_ACCEL_BIT & halPositionDynamics.bodyFrameDataMask) {
|
|
bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_LONG_ACCEL_BIT;
|
|
positionDynamics.longAccel = halPositionDynamics.longAccel;
|
|
}
|
|
if (::LOCATION_NAV_DATA_HAS_LAT_ACCEL_BIT & halPositionDynamics.bodyFrameDataMask) {
|
|
bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_LAT_ACCEL_BIT;
|
|
positionDynamics.latAccel = halPositionDynamics.latAccel;
|
|
}
|
|
if (::LOCATION_NAV_DATA_HAS_VERT_ACCEL_BIT & halPositionDynamics.bodyFrameDataMask) {
|
|
bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_VERT_ACCEL_BIT;
|
|
positionDynamics.vertAccel = halPositionDynamics.vertAccel;
|
|
}
|
|
if (::LOCATION_NAV_DATA_HAS_LONG_ACCEL_UNC_BIT & halPositionDynamics.bodyFrameDataMask) {
|
|
bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_LONG_ACCEL_UNC_BIT;
|
|
positionDynamics.longAccelUnc = halPositionDynamics.longAccelUnc;
|
|
}
|
|
if (::LOCATION_NAV_DATA_HAS_LAT_ACCEL_UNC_BIT & halPositionDynamics.bodyFrameDataMask) {
|
|
bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_LAT_ACCEL_UNC_BIT;
|
|
positionDynamics.latAccelUnc = halPositionDynamics.latAccelUnc;
|
|
}
|
|
if (::LOCATION_NAV_DATA_HAS_VERT_ACCEL_UNC_BIT & halPositionDynamics.bodyFrameDataMask) {
|
|
bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_VERT_ACCEL_UNC_BIT;
|
|
positionDynamics.vertAccelUnc = halPositionDynamics.vertAccelUnc;
|
|
}
|
|
|
|
if (::LOCATION_NAV_DATA_HAS_ROLL_BIT & halPositionDynamicsExt.bodyFrameDataMask) {
|
|
bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_ROLL_BIT;
|
|
positionDynamics.roll = halPositionDynamicsExt.roll;
|
|
}
|
|
if (::LOCATION_NAV_DATA_HAS_ROLL_UNC_BIT & halPositionDynamicsExt.bodyFrameDataMask) {
|
|
bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_ROLL_UNC_BIT;
|
|
positionDynamics.rollUnc = halPositionDynamicsExt.rollUnc;
|
|
}
|
|
if (::LOCATION_NAV_DATA_HAS_ROLL_RATE_BIT & halPositionDynamicsExt.bodyFrameDataMask) {
|
|
bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_ROLL_RATE_BIT;
|
|
positionDynamics.rollRate = halPositionDynamicsExt.rollRate;
|
|
}
|
|
if (::LOCATION_NAV_DATA_HAS_ROLL_RATE_UNC_BIT & halPositionDynamicsExt.bodyFrameDataMask) {
|
|
bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_ROLL_RATE_UNC_BIT;
|
|
positionDynamics.rollRateUnc = halPositionDynamicsExt.rollRateUnc;
|
|
}
|
|
|
|
if (::LOCATION_NAV_DATA_HAS_PITCH_BIT & halPositionDynamics.bodyFrameDataMask) {
|
|
bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_PITCH_BIT;
|
|
positionDynamics.pitch = halPositionDynamics.pitch;
|
|
}
|
|
if (::LOCATION_NAV_DATA_HAS_PITCH_UNC_BIT & halPositionDynamics.bodyFrameDataMask) {
|
|
bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_PITCH_UNC_BIT;
|
|
positionDynamics.pitchUnc = halPositionDynamics.pitchUnc;
|
|
}
|
|
if (::LOCATION_NAV_DATA_HAS_PITCH_RATE_BIT & halPositionDynamicsExt.bodyFrameDataMask) {
|
|
bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_PITCH_RATE_BIT;
|
|
positionDynamics.pitchRate = halPositionDynamicsExt.pitchRate;
|
|
}
|
|
if (::LOCATION_NAV_DATA_HAS_PITCH_RATE_UNC_BIT & halPositionDynamicsExt.bodyFrameDataMask) {
|
|
bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_PITCH_RATE_UNC_BIT;
|
|
positionDynamics.pitchRateUnc = halPositionDynamicsExt.pitchRateUnc;
|
|
}
|
|
|
|
if (::LOCATION_NAV_DATA_HAS_YAW_BIT & halPositionDynamicsExt.bodyFrameDataMask) {
|
|
bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_YAW_BIT;
|
|
positionDynamics.yaw = halPositionDynamicsExt.yaw;
|
|
}
|
|
if (::LOCATION_NAV_DATA_HAS_YAW_UNC_BIT & halPositionDynamicsExt.bodyFrameDataMask) {
|
|
bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_YAW_UNC_BIT;
|
|
positionDynamics.yawUnc = halPositionDynamicsExt.yawUnc;
|
|
}
|
|
if (::LOCATION_NAV_DATA_HAS_YAW_RATE_BIT & halPositionDynamics.bodyFrameDataMask) {
|
|
bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_YAW_RATE_BIT;
|
|
positionDynamics.yawRate = halPositionDynamics.yawRate;
|
|
}
|
|
if (::LOCATION_NAV_DATA_HAS_YAW_RATE_UNC_BIT & halPositionDynamics.bodyFrameDataMask) {
|
|
bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_YAW_RATE_UNC_BIT;
|
|
positionDynamics.yawRateUnc = halPositionDynamics.yawRateUnc;
|
|
}
|
|
positionDynamics.bodyFrameDataMask = (GnssLocationPosDataMask)bodyFrameDataMask;
|
|
|
|
return positionDynamics;
|
|
}
|
|
|
|
static LocationReliability parseLocationReliability(const ::LocationReliability &halReliability) {
|
|
|
|
LocationReliability reliability;
|
|
switch (halReliability) {
|
|
case ::LOCATION_RELIABILITY_VERY_LOW:
|
|
reliability = LOCATION_RELIABILITY_VERY_LOW;
|
|
break;
|
|
|
|
case ::LOCATION_RELIABILITY_LOW:
|
|
reliability = LOCATION_RELIABILITY_LOW;
|
|
break;
|
|
|
|
case ::LOCATION_RELIABILITY_MEDIUM:
|
|
reliability = LOCATION_RELIABILITY_MEDIUM;
|
|
break;
|
|
|
|
case ::LOCATION_RELIABILITY_HIGH:
|
|
reliability = LOCATION_RELIABILITY_HIGH;
|
|
break;
|
|
|
|
default:
|
|
reliability = LOCATION_RELIABILITY_NOT_SET;
|
|
break;
|
|
}
|
|
|
|
return reliability;
|
|
}
|
|
|
|
static GnssSystemTimeStructType parseGnssTime(const ::GnssSystemTimeStructType &halGnssTime) {
|
|
|
|
GnssSystemTimeStructType gnssTime;
|
|
memset(&gnssTime, 0, sizeof(gnssTime));
|
|
uint32_t gnssTimeFlags = 0;
|
|
|
|
if (::GNSS_SYSTEM_TIME_WEEK_VALID & halGnssTime.validityMask) {
|
|
gnssTimeFlags |= GNSS_SYSTEM_TIME_WEEK_VALID;
|
|
gnssTime.systemWeek = halGnssTime.systemWeek;
|
|
}
|
|
if (::GNSS_SYSTEM_TIME_WEEK_MS_VALID & halGnssTime.validityMask) {
|
|
gnssTimeFlags |= GNSS_SYSTEM_TIME_WEEK_MS_VALID;
|
|
gnssTime.systemMsec = halGnssTime.systemMsec;
|
|
}
|
|
if (::GNSS_SYSTEM_CLK_TIME_BIAS_VALID & halGnssTime.validityMask) {
|
|
gnssTimeFlags |= GNSS_SYSTEM_CLK_TIME_BIAS_VALID;
|
|
gnssTime.systemClkTimeBias = halGnssTime.systemClkTimeBias;
|
|
}
|
|
if (::GNSS_SYSTEM_CLK_TIME_BIAS_UNC_VALID & halGnssTime.validityMask) {
|
|
gnssTimeFlags |= GNSS_SYSTEM_CLK_TIME_BIAS_UNC_VALID;
|
|
gnssTime.systemClkTimeUncMs = halGnssTime.systemClkTimeUncMs;
|
|
}
|
|
if (::GNSS_SYSTEM_REF_FCOUNT_VALID & halGnssTime.validityMask) {
|
|
gnssTimeFlags |= GNSS_SYSTEM_REF_FCOUNT_VALID;
|
|
gnssTime.refFCount = halGnssTime.refFCount;
|
|
}
|
|
if (::GNSS_SYSTEM_NUM_CLOCK_RESETS_VALID & halGnssTime.validityMask) {
|
|
gnssTimeFlags |= GNSS_SYSTEM_NUM_CLOCK_RESETS_VALID;
|
|
gnssTime.numClockResets = halGnssTime.numClockResets;
|
|
}
|
|
|
|
gnssTime.validityMask = (GnssSystemTimeStructTypeFlags)gnssTimeFlags;
|
|
|
|
return gnssTime;
|
|
}
|
|
|
|
static GnssGloTimeStructType parseGloTime(const ::GnssGloTimeStructType &halGloTime) {
|
|
|
|
GnssGloTimeStructType gloTime;
|
|
memset(&gloTime, 0, sizeof(gloTime));
|
|
uint32_t gloTimeFlags = 0;
|
|
|
|
if (::GNSS_CLO_DAYS_VALID & halGloTime.validityMask) {
|
|
gloTimeFlags |= GNSS_CLO_DAYS_VALID;
|
|
gloTime.gloDays = halGloTime.gloDays;
|
|
}
|
|
if (::GNSS_GLO_MSEC_VALID & halGloTime.validityMask) {
|
|
gloTimeFlags |= GNSS_GLO_MSEC_VALID ;
|
|
gloTime.gloMsec = halGloTime.gloMsec;
|
|
}
|
|
if (::GNSS_GLO_CLK_TIME_BIAS_VALID & halGloTime.validityMask) {
|
|
gloTimeFlags |= GNSS_GLO_CLK_TIME_BIAS_VALID;
|
|
gloTime.gloClkTimeBias = halGloTime.gloClkTimeBias;
|
|
}
|
|
if (::GNSS_GLO_CLK_TIME_BIAS_UNC_VALID & halGloTime.validityMask) {
|
|
gloTimeFlags |= GNSS_GLO_CLK_TIME_BIAS_UNC_VALID;
|
|
gloTime.gloClkTimeUncMs = halGloTime.gloClkTimeUncMs;
|
|
}
|
|
if (::GNSS_GLO_REF_FCOUNT_VALID & halGloTime.validityMask) {
|
|
gloTimeFlags |= GNSS_GLO_REF_FCOUNT_VALID;
|
|
gloTime.refFCount = halGloTime.refFCount;
|
|
}
|
|
if (::GNSS_GLO_NUM_CLOCK_RESETS_VALID & halGloTime.validityMask) {
|
|
gloTimeFlags |= GNSS_GLO_NUM_CLOCK_RESETS_VALID;
|
|
gloTime.numClockResets = halGloTime.numClockResets;
|
|
}
|
|
if (::GNSS_GLO_FOUR_YEAR_VALID & halGloTime.validityMask) {
|
|
gloTimeFlags |= GNSS_GLO_FOUR_YEAR_VALID;
|
|
gloTime.gloFourYear = halGloTime.gloFourYear;
|
|
}
|
|
|
|
gloTime.validityMask = (GnssGloTimeStructTypeFlags)gloTimeFlags;
|
|
|
|
return gloTime;
|
|
}
|
|
|
|
static GnssSystemTime parseSystemTime(const ::GnssSystemTime &halSystemTime) {
|
|
|
|
GnssSystemTime systemTime;
|
|
memset(&systemTime, 0x0, sizeof(GnssSystemTime));
|
|
|
|
switch (halSystemTime.gnssSystemTimeSrc) {
|
|
case ::GNSS_LOC_SV_SYSTEM_GPS:
|
|
systemTime.gnssSystemTimeSrc = GNSS_LOC_SV_SYSTEM_GPS;
|
|
systemTime.u.gpsSystemTime = parseGnssTime(halSystemTime.u.gpsSystemTime);
|
|
break;
|
|
case ::GNSS_LOC_SV_SYSTEM_GALILEO:
|
|
systemTime.gnssSystemTimeSrc = GNSS_LOC_SV_SYSTEM_GALILEO;
|
|
systemTime.u.galSystemTime = parseGnssTime(halSystemTime.u.galSystemTime);
|
|
break;
|
|
case ::GNSS_LOC_SV_SYSTEM_SBAS:
|
|
systemTime.gnssSystemTimeSrc = GNSS_LOC_SV_SYSTEM_SBAS;
|
|
break;
|
|
case ::GNSS_LOC_SV_SYSTEM_GLONASS:
|
|
systemTime.gnssSystemTimeSrc = GNSS_LOC_SV_SYSTEM_GLONASS;
|
|
systemTime.u.gloSystemTime = parseGloTime(halSystemTime.u.gloSystemTime);
|
|
break;
|
|
case ::GNSS_LOC_SV_SYSTEM_BDS:
|
|
systemTime.gnssSystemTimeSrc = GNSS_LOC_SV_SYSTEM_BDS;
|
|
systemTime.u.bdsSystemTime = parseGnssTime(halSystemTime.u.bdsSystemTime);
|
|
break;
|
|
case ::GNSS_LOC_SV_SYSTEM_QZSS:
|
|
systemTime.gnssSystemTimeSrc = GNSS_LOC_SV_SYSTEM_QZSS;
|
|
systemTime.u.qzssSystemTime = parseGnssTime(halSystemTime.u.qzssSystemTime);
|
|
break;
|
|
case GNSS_LOC_SV_SYSTEM_NAVIC:
|
|
systemTime.gnssSystemTimeSrc = GNSS_LOC_SV_SYSTEM_NAVIC;
|
|
systemTime.u.navicSystemTime = parseGnssTime(halSystemTime.u.navicSystemTime);
|
|
break;
|
|
}
|
|
|
|
return systemTime;
|
|
}
|
|
|
|
static GnssLocation parseLocationInfo(const ::GnssLocationInfoNotification &halLocationInfo) {
|
|
|
|
GnssLocation locationInfo;
|
|
parseLocation(halLocationInfo.location, locationInfo);
|
|
uint64_t flags = 0;
|
|
|
|
if (::GNSS_LOCATION_INFO_ALTITUDE_MEAN_SEA_LEVEL_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_ALTITUDE_MEAN_SEA_LEVEL_BIT;
|
|
}
|
|
if (::GNSS_LOCATION_INFO_DOP_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_DOP_BIT;
|
|
}
|
|
if (::GNSS_LOCATION_INFO_MAGNETIC_DEVIATION_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_MAGNETIC_DEVIATION_BIT;
|
|
}
|
|
if (::GNSS_LOCATION_INFO_HOR_RELIABILITY_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_HOR_RELIABILITY_BIT;
|
|
}
|
|
if (::GNSS_LOCATION_INFO_VER_RELIABILITY_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_VER_RELIABILITY_BIT;
|
|
}
|
|
if (::GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_SEMI_MAJOR_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_SEMI_MAJOR_BIT;
|
|
}
|
|
if (::GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_SEMI_MINOR_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_SEMI_MINOR_BIT;
|
|
}
|
|
if (::GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_AZIMUTH_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_AZIMUTH_BIT;
|
|
}
|
|
if (::GNSS_LOCATION_INFO_GNSS_SV_USED_DATA_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_GNSS_SV_USED_DATA_BIT;
|
|
}
|
|
if (::GNSS_LOCATION_INFO_NAV_SOLUTION_MASK_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_NAV_SOLUTION_MASK_BIT;
|
|
}
|
|
flags |= GNSS_LOCATION_INFO_POS_TECH_MASK_BIT;
|
|
if (::GNSS_LOCATION_INFO_SV_SOURCE_INFO_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_SV_SOURCE_INFO_BIT;
|
|
}
|
|
if (::GNSS_LOCATION_INFO_POS_DYNAMICS_DATA_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_POS_DYNAMICS_DATA_BIT;
|
|
}
|
|
if (::GNSS_LOCATION_INFO_EXT_DOP_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_EXT_DOP_BIT;
|
|
}
|
|
if (::GNSS_LOCATION_INFO_ALTITUDE_MEAN_SEA_LEVEL_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_ALTITUDE_MEAN_SEA_LEVEL_BIT;
|
|
}
|
|
if (::GNSS_LOCATION_INFO_NORTH_STD_DEV_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_NORTH_STD_DEV_BIT;
|
|
}
|
|
if (::GNSS_LOCATION_INFO_EAST_STD_DEV_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_EAST_STD_DEV_BIT;
|
|
}
|
|
if (::GNSS_LOCATION_INFO_NORTH_VEL_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_NORTH_VEL_BIT;
|
|
}
|
|
if (::GNSS_LOCATION_INFO_NORTH_VEL_UNC_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_NORTH_VEL_UNC_BIT;
|
|
}
|
|
if (::GNSS_LOCATION_INFO_EAST_VEL_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_EAST_VEL_BIT;
|
|
}
|
|
if (::GNSS_LOCATION_INFO_EAST_VEL_UNC_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_EAST_VEL_UNC_BIT;
|
|
}
|
|
if (::GNSS_LOCATION_INFO_UP_VEL_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_UP_VEL_BIT;
|
|
}
|
|
if (::GNSS_LOCATION_INFO_UP_VEL_UNC_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_UP_VEL_UNC_BIT;
|
|
}
|
|
if (::GNSS_LOCATION_INFO_LEAP_SECONDS_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_LEAP_SECONDS_BIT;
|
|
}
|
|
if (::GNSS_LOCATION_INFO_TIME_UNC_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_TIME_UNC_BIT;
|
|
}
|
|
if (::GNSS_LOCATION_INFO_NUM_SV_USED_IN_POSITION_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_NUM_SV_USED_IN_POSITION_BIT;
|
|
}
|
|
if (::GNSS_LOCATION_INFO_CALIBRATION_CONFIDENCE_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_CALIBRATION_CONFIDENCE_PERCENT_BIT;
|
|
locationInfo.calibrationConfidencePercent = halLocationInfo.calibrationConfidence;
|
|
}
|
|
if (::GNSS_LOCATION_INFO_CALIBRATION_STATUS_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_CALIBRATION_STATUS_BIT;
|
|
locationInfo.calibrationStatus =
|
|
(DrCalibrationStatusMask)halLocationInfo.calibrationStatus;
|
|
}
|
|
if (::GNSS_LOCATION_INFO_OUTPUT_ENG_TYPE_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_OUTPUT_ENG_TYPE_BIT;
|
|
}
|
|
if (::GNSS_LOCATION_INFO_OUTPUT_ENG_MASK_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_OUTPUT_ENG_MASK_BIT;
|
|
}
|
|
|
|
if (::GNSS_LOCATION_INFO_CONFORMITY_INDEX_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_CONFORMITY_INDEX_BIT;
|
|
}
|
|
|
|
if (::GNSS_LOCATION_INFO_LLA_VRP_BASED_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_LLA_VRP_BASED_BIT;
|
|
}
|
|
|
|
if (::GNSS_LOCATION_INFO_ENU_VELOCITY_VRP_BASED_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_ENU_VELOCITY_VRP_BASED_BIT;
|
|
}
|
|
|
|
if (::GNSS_LOCATION_INFO_DR_SOLUTION_STATUS_MASK_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_DR_SOLUTION_STATUS_MASK_BIT;
|
|
}
|
|
|
|
if (::GNSS_LOCATION_INFO_ALTITUDE_ASSUMED_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_ALTITUDE_ASSUMED_BIT;
|
|
}
|
|
|
|
if (::GNSS_LOCATION_INFO_SESSION_STATUS_BIT & halLocationInfo.flags) {
|
|
flags |= GNSS_LOCATION_INFO_SESSION_STATUS_BIT;
|
|
}
|
|
|
|
locationInfo.gnssInfoFlags = (GnssLocationInfoFlagMask)flags;
|
|
locationInfo.altitudeMeanSeaLevel = halLocationInfo.altitudeMeanSeaLevel;
|
|
locationInfo.pdop = halLocationInfo.pdop;
|
|
locationInfo.hdop = halLocationInfo.hdop;
|
|
locationInfo.vdop = halLocationInfo.vdop;
|
|
locationInfo.gdop = halLocationInfo.gdop;
|
|
locationInfo.tdop = halLocationInfo.tdop;
|
|
locationInfo.magneticDeviation = halLocationInfo.magneticDeviation;
|
|
locationInfo.horReliability = parseLocationReliability(halLocationInfo.horReliability);
|
|
locationInfo.verReliability = parseLocationReliability(halLocationInfo.verReliability);
|
|
locationInfo.horUncEllipseSemiMajor = halLocationInfo.horUncEllipseSemiMajor;
|
|
locationInfo.horUncEllipseSemiMinor = halLocationInfo.horUncEllipseSemiMinor;
|
|
locationInfo.horUncEllipseOrientAzimuth = halLocationInfo.horUncEllipseOrientAzimuth;
|
|
locationInfo.northStdDeviation = halLocationInfo.northStdDeviation;
|
|
locationInfo.eastStdDeviation = halLocationInfo.eastStdDeviation;
|
|
locationInfo.northVelocity = halLocationInfo.northVelocity;
|
|
locationInfo.eastVelocity = halLocationInfo.eastVelocity;
|
|
locationInfo.upVelocity = halLocationInfo.upVelocity;
|
|
locationInfo.northVelocityStdDeviation = halLocationInfo.northVelocityStdDeviation;
|
|
locationInfo.eastVelocityStdDeviation = halLocationInfo.eastVelocityStdDeviation;
|
|
locationInfo.upVelocityStdDeviation = halLocationInfo.upVelocityStdDeviation;
|
|
locationInfo.numSvUsedInPosition = halLocationInfo.numSvUsedInPosition;
|
|
locationInfo.svUsedInPosition =
|
|
parseLocationSvUsedInPosition(halLocationInfo.svUsedInPosition);
|
|
locationInfo.locOutputEngType =
|
|
(LocOutputEngineType)halLocationInfo.locOutputEngType;
|
|
locationInfo.locOutputEngMask =
|
|
(PositioningEngineMask)halLocationInfo.locOutputEngMask;
|
|
locationInfo.conformityIndex = halLocationInfo.conformityIndex;
|
|
locationInfo.llaVRPBased.latitude = halLocationInfo.llaVRPBased.latitude;
|
|
locationInfo.llaVRPBased.longitude = halLocationInfo.llaVRPBased.longitude;
|
|
locationInfo.llaVRPBased.altitude = halLocationInfo.llaVRPBased.altitude;
|
|
// copy VRP-based north, east, up velocity
|
|
locationInfo.enuVelocityVRPBased[0] = halLocationInfo.enuVelocityVRPBased[0];
|
|
locationInfo.enuVelocityVRPBased[1] = halLocationInfo.enuVelocityVRPBased[1];
|
|
locationInfo.enuVelocityVRPBased[2] = halLocationInfo.enuVelocityVRPBased[2];
|
|
parseGnssMeasUsageInfo(halLocationInfo, locationInfo.measUsageInfo);
|
|
locationInfo.drSolutionStatusMask = (DrSolutionStatusMask) halLocationInfo.drSolutionStatusMask;
|
|
locationInfo.altitudeAssumed = halLocationInfo.altitudeAssumed;
|
|
locationInfo.sessionStatus = (LocSessionStatus) halLocationInfo.sessionStatus;
|
|
|
|
flags = 0;
|
|
if (::LOCATION_SBAS_CORRECTION_IONO_BIT & halLocationInfo.navSolutionMask) {
|
|
flags |= LOCATION_SBAS_CORRECTION_IONO_BIT;
|
|
}
|
|
if (::LOCATION_SBAS_CORRECTION_FAST_BIT & halLocationInfo.navSolutionMask) {
|
|
flags |= LOCATION_SBAS_CORRECTION_FAST_BIT;
|
|
}
|
|
if (::LOCATION_SBAS_CORRECTION_LONG_BIT & halLocationInfo.navSolutionMask) {
|
|
flags |= LOCATION_SBAS_CORRECTION_LONG_BIT;
|
|
}
|
|
if (::LOCATION_SBAS_INTEGRITY_BIT & halLocationInfo.navSolutionMask) {
|
|
flags |= LOCATION_SBAS_INTEGRITY_BIT;
|
|
}
|
|
if (::LOCATION_NAV_CORRECTION_DGNSS_BIT & halLocationInfo.navSolutionMask) {
|
|
flags |= LOCATION_NAV_CORRECTION_DGNSS_BIT;
|
|
}
|
|
if (::LOCATION_NAV_CORRECTION_RTK_BIT & halLocationInfo.navSolutionMask) {
|
|
flags |= LOCATION_NAV_CORRECTION_RTK_BIT;
|
|
}
|
|
if (::LOCATION_NAV_CORRECTION_RTK_FIXED_BIT & halLocationInfo.navSolutionMask) {
|
|
flags |= LOCATION_NAV_CORRECTION_RTK_FIXED_BIT;
|
|
}
|
|
if (::LOCATION_NAV_CORRECTION_PPP_BIT & halLocationInfo.navSolutionMask) {
|
|
flags |= LOCATION_NAV_CORRECTION_PPP_BIT;
|
|
}
|
|
if (::LOCATION_NAV_CORRECTION_ONLY_SBAS_CORRECTED_SV_USED_BIT &
|
|
halLocationInfo.navSolutionMask) {
|
|
flags |= LOCATION_NAV_CORRECTION_ONLY_SBAS_CORRECTED_SV_USED_BIT;
|
|
}
|
|
locationInfo.navSolutionMask = (GnssLocationNavSolutionMask)flags;
|
|
|
|
locationInfo.posTechMask = locationInfo.techMask;
|
|
locationInfo.bodyFrameData = parseLocationPositionDynamics(
|
|
halLocationInfo.bodyFrameData, halLocationInfo.bodyFrameDataExt);
|
|
locationInfo.gnssSystemTime = parseSystemTime(halLocationInfo.gnssSystemTime);
|
|
locationInfo.leapSeconds = halLocationInfo.leapSeconds;
|
|
locationInfo.timeUncMs = halLocationInfo.timeUncMs;
|
|
|
|
return locationInfo;
|
|
}
|
|
|
|
static GnssSv parseGnssSv(const ::GnssSv &halGnssSv) {
|
|
GnssSv gnssSv;
|
|
|
|
gnssSv.svId = halGnssSv.svId;
|
|
switch (halGnssSv.type) {
|
|
case ::GNSS_SV_TYPE_GPS:
|
|
gnssSv.type = GNSS_SV_TYPE_GPS;
|
|
break;
|
|
|
|
case ::GNSS_SV_TYPE_SBAS:
|
|
gnssSv.type = GNSS_SV_TYPE_SBAS;
|
|
break;
|
|
|
|
case ::GNSS_SV_TYPE_GLONASS:
|
|
gnssSv.type = GNSS_SV_TYPE_GLONASS;
|
|
if (isGloSlotUnknown(halGnssSv.svId)) { // OSN is not known, report FCN
|
|
gnssSv.svId = halGnssSv.gloFrequency + 96;
|
|
}
|
|
break;
|
|
|
|
case ::GNSS_SV_TYPE_QZSS:
|
|
gnssSv.type = GNSS_SV_TYPE_QZSS;
|
|
break;
|
|
|
|
case ::GNSS_SV_TYPE_BEIDOU:
|
|
gnssSv.type = GNSS_SV_TYPE_BEIDOU;
|
|
break;
|
|
|
|
case ::GNSS_SV_TYPE_GALILEO:
|
|
gnssSv.type = GNSS_SV_TYPE_GALILEO;
|
|
break;
|
|
|
|
case ::GNSS_SV_TYPE_NAVIC:
|
|
gnssSv.type = GNSS_SV_TYPE_NAVIC;
|
|
break;
|
|
|
|
default:
|
|
gnssSv.type = GNSS_SV_TYPE_UNKNOWN;
|
|
break;
|
|
}
|
|
gnssSv.cN0Dbhz = halGnssSv.cN0Dbhz;
|
|
gnssSv.elevation = halGnssSv.elevation;
|
|
gnssSv.azimuth = halGnssSv.azimuth;
|
|
gnssSv.basebandCarrierToNoiseDbHz = halGnssSv.basebandCarrierToNoiseDbHz;
|
|
|
|
uint32_t gnssSvOptionsMask = 0;
|
|
if (::GNSS_SV_OPTIONS_HAS_EPHEMER_BIT & halGnssSv.gnssSvOptionsMask) {
|
|
gnssSvOptionsMask |= GNSS_SV_OPTIONS_HAS_EPHEMER_BIT;
|
|
}
|
|
if (::GNSS_SV_OPTIONS_HAS_ALMANAC_BIT & halGnssSv.gnssSvOptionsMask) {
|
|
gnssSvOptionsMask |= GNSS_SV_OPTIONS_HAS_ALMANAC_BIT;
|
|
}
|
|
if (::GNSS_SV_OPTIONS_USED_IN_FIX_BIT & halGnssSv.gnssSvOptionsMask) {
|
|
gnssSvOptionsMask |= GNSS_SV_OPTIONS_USED_IN_FIX_BIT;
|
|
}
|
|
if (::GNSS_SV_OPTIONS_HAS_CARRIER_FREQUENCY_BIT & halGnssSv.gnssSvOptionsMask) {
|
|
gnssSvOptionsMask |= GNSS_SV_OPTIONS_HAS_CARRIER_FREQUENCY_BIT;
|
|
}
|
|
if (::GNSS_SV_OPTIONS_HAS_GNSS_SIGNAL_TYPE_BIT & halGnssSv.gnssSvOptionsMask) {
|
|
gnssSvOptionsMask |= GNSS_SV_OPTIONS_HAS_GNSS_SIGNAL_TYPE_BIT;
|
|
}
|
|
gnssSv.gnssSvOptionsMask = (GnssSvOptionsMask)gnssSvOptionsMask;
|
|
|
|
gnssSv.carrierFrequencyHz = halGnssSv.carrierFrequencyHz;
|
|
gnssSv.gnssSignalTypeMask = parseGnssSignalType(halGnssSv.gnssSignalTypeMask);
|
|
return gnssSv;
|
|
}
|
|
|
|
static GnssData parseGnssData(const ::GnssDataNotification &halGnssData) {
|
|
|
|
GnssData gnssData;
|
|
|
|
for (int sig = GNSS_LOC_SIGNAL_TYPE_GPS_L1CA;
|
|
sig < GNSS_LOC_MAX_NUMBER_OF_SIGNAL_TYPES; sig++) {
|
|
gnssData.gnssDataMask[sig] =
|
|
(location_client::GnssDataMask) halGnssData.gnssDataMask[sig];
|
|
gnssData.jammerInd[sig] = halGnssData.jammerInd[sig];
|
|
gnssData.agc[sig] = halGnssData.agc[sig];
|
|
if (0 != gnssData.gnssDataMask[sig]) {
|
|
LOC_LOGv("gnssDataMask[%d]=0x%X", sig, gnssData.gnssDataMask[sig]);
|
|
LOC_LOGv("jammerInd[%d]=%f", sig, gnssData.jammerInd[sig]);
|
|
LOC_LOGv("agc[%d]=%f", sig, gnssData.agc[sig]);
|
|
}
|
|
}
|
|
return gnssData;
|
|
}
|
|
|
|
static GnssMeasurements parseGnssMeasurements(const ::GnssMeasurementsNotification
|
|
&halGnssMeasurements) {
|
|
GnssMeasurements gnssMeasurements = {};
|
|
|
|
for (int meas = 0; meas < halGnssMeasurements.count; meas++) {
|
|
GnssMeasurementsData measurement;
|
|
|
|
measurement.flags =
|
|
parseMeasurementsDataMask(halGnssMeasurements.measurements[meas].flags);
|
|
measurement.svId = halGnssMeasurements.measurements[meas].svId;
|
|
measurement.svType =
|
|
(location_client::GnssSvType)halGnssMeasurements.measurements[meas].svType;
|
|
measurement.timeOffsetNs = halGnssMeasurements.measurements[meas].timeOffsetNs;
|
|
measurement.stateMask = (GnssMeasurementsStateMask)
|
|
halGnssMeasurements.measurements[meas].stateMask;
|
|
measurement.receivedSvTimeNs = halGnssMeasurements.measurements[meas].receivedSvTimeNs;
|
|
measurement.receivedSvTimeUncertaintyNs =
|
|
halGnssMeasurements.measurements[meas].receivedSvTimeUncertaintyNs;
|
|
measurement.carrierToNoiseDbHz =
|
|
halGnssMeasurements.measurements[meas].carrierToNoiseDbHz;
|
|
measurement.pseudorangeRateMps =
|
|
halGnssMeasurements.measurements[meas].pseudorangeRateMps;
|
|
measurement.pseudorangeRateUncertaintyMps =
|
|
halGnssMeasurements.measurements[meas].pseudorangeRateUncertaintyMps;
|
|
measurement.adrStateMask = (GnssMeasurementsAdrStateMask)
|
|
halGnssMeasurements.measurements[meas].adrStateMask;
|
|
measurement.adrMeters = halGnssMeasurements.measurements[meas].adrMeters;
|
|
measurement.adrUncertaintyMeters =
|
|
halGnssMeasurements.measurements[meas].adrUncertaintyMeters;
|
|
measurement.carrierFrequencyHz =
|
|
halGnssMeasurements.measurements[meas].carrierFrequencyHz;
|
|
measurement.carrierCycles = halGnssMeasurements.measurements[meas].carrierCycles;
|
|
measurement.carrierPhase = halGnssMeasurements.measurements[meas].carrierPhase;
|
|
measurement.carrierPhaseUncertainty =
|
|
halGnssMeasurements.measurements[meas].carrierPhaseUncertainty;
|
|
measurement.multipathIndicator = (location_client::GnssMeasurementsMultipathIndicator)
|
|
halGnssMeasurements.measurements[meas].multipathIndicator;
|
|
measurement.signalToNoiseRatioDb =
|
|
halGnssMeasurements.measurements[meas].signalToNoiseRatioDb;
|
|
measurement.agcLevelDb = halGnssMeasurements.measurements[meas].agcLevelDb;
|
|
measurement.basebandCarrierToNoiseDbHz =
|
|
halGnssMeasurements.measurements[meas].basebandCarrierToNoiseDbHz;
|
|
measurement.gnssSignalType =
|
|
parseGnssSignalType(halGnssMeasurements.measurements[meas].gnssSignalType);
|
|
measurement.interSignalBiasNs =
|
|
halGnssMeasurements.measurements[meas].fullInterSignalBiasNs;
|
|
measurement.interSignalBiasUncertaintyNs =
|
|
halGnssMeasurements.measurements[meas].fullInterSignalBiasUncertaintyNs;
|
|
measurement.cycleSlipCount = halGnssMeasurements.measurements[meas].cycleSlipCount;
|
|
|
|
gnssMeasurements.measurements.push_back(measurement);
|
|
}
|
|
gnssMeasurements.clock.flags =
|
|
(GnssMeasurementsClockFlagsMask) halGnssMeasurements.clock.flags;
|
|
gnssMeasurements.clock.leapSecond = halGnssMeasurements.clock.leapSecond;
|
|
gnssMeasurements.clock.timeNs = halGnssMeasurements.clock.timeNs;
|
|
gnssMeasurements.clock.timeUncertaintyNs = halGnssMeasurements.clock.timeUncertaintyNs;
|
|
gnssMeasurements.clock.fullBiasNs = halGnssMeasurements.clock.fullBiasNs;
|
|
gnssMeasurements.clock.biasNs = halGnssMeasurements.clock.biasNs;
|
|
gnssMeasurements.clock.biasUncertaintyNs = halGnssMeasurements.clock.biasUncertaintyNs;
|
|
gnssMeasurements.clock.driftNsps = halGnssMeasurements.clock.driftNsps;
|
|
gnssMeasurements.clock.driftUncertaintyNsps = halGnssMeasurements.clock.driftUncertaintyNsps;
|
|
gnssMeasurements.clock.hwClockDiscontinuityCount =
|
|
halGnssMeasurements.clock.hwClockDiscontinuityCount;
|
|
|
|
return gnssMeasurements;
|
|
}
|
|
|
|
static LocationResponse parseLocationError(::LocationError error) {
|
|
LocationResponse response;
|
|
|
|
switch (error) {
|
|
case ::LOCATION_ERROR_SUCCESS:
|
|
response = LOCATION_RESPONSE_SUCCESS;
|
|
break;
|
|
case ::LOCATION_ERROR_NOT_SUPPORTED:
|
|
response = LOCATION_RESPONSE_NOT_SUPPORTED;
|
|
break;
|
|
case ::LOCATION_ERROR_TIMEOUT:
|
|
response = LOCATION_RESPONSE_TIMEOUT;
|
|
break;
|
|
default:
|
|
response = LOCATION_RESPONSE_UNKOWN_FAILURE;
|
|
break;
|
|
}
|
|
|
|
return response;
|
|
}
|
|
|
|
static LocationSystemInfo parseLocationSystemInfo(
|
|
const::LocationSystemInfo &halSystemInfo) {
|
|
LocationSystemInfo systemInfo = {};
|
|
|
|
systemInfo.systemInfoMask = (location_client::LocationSystemInfoMask)
|
|
halSystemInfo.systemInfoMask;
|
|
if (halSystemInfo.systemInfoMask & ::LOCATION_SYS_INFO_LEAP_SECOND) {
|
|
systemInfo.leapSecondSysInfo.leapSecondInfoMask = (location_client::LeapSecondSysInfoMask)
|
|
halSystemInfo.leapSecondSysInfo.leapSecondInfoMask;
|
|
|
|
if (halSystemInfo.leapSecondSysInfo.leapSecondInfoMask &
|
|
::LEAP_SECOND_SYS_INFO_LEAP_SECOND_CHANGE_BIT) {
|
|
LeapSecondChangeInfo &clientInfo =
|
|
systemInfo.leapSecondSysInfo.leapSecondChangeInfo;
|
|
const::LeapSecondChangeInfo &halInfo =
|
|
halSystemInfo.leapSecondSysInfo.leapSecondChangeInfo;
|
|
|
|
clientInfo.gpsTimestampLsChange = parseGnssTime(halInfo.gpsTimestampLsChange);
|
|
clientInfo.leapSecondsBeforeChange = halInfo.leapSecondsBeforeChange;
|
|
clientInfo.leapSecondsAfterChange = halInfo.leapSecondsAfterChange;
|
|
}
|
|
|
|
if (halSystemInfo.leapSecondSysInfo.leapSecondInfoMask &
|
|
::LEAP_SECOND_SYS_INFO_CURRENT_LEAP_SECONDS_BIT) {
|
|
systemInfo.leapSecondSysInfo.leapSecondCurrent =
|
|
halSystemInfo.leapSecondSysInfo.leapSecondCurrent;
|
|
}
|
|
}
|
|
|
|
return systemInfo;
|
|
}
|
|
|
|
/******************************************************************************
|
|
ILocIpcListener override
|
|
******************************************************************************/
|
|
class IpcListener : public ILocIpcListener {
|
|
MsgTask& mMsgTask;
|
|
LocationClientApiImpl& mApiImpl;
|
|
const SockNode::Type mSockTpye;
|
|
public:
|
|
inline IpcListener(LocationClientApiImpl& apiImpl, MsgTask& msgTask,
|
|
const SockNode::Type sockType) :
|
|
mMsgTask(msgTask), mApiImpl(apiImpl), mSockTpye(sockType) {}
|
|
virtual void onListenerReady() override;
|
|
virtual void onReceive(const char* data, uint32_t length,
|
|
const LocIpcRecver* recver) override;
|
|
};
|
|
|
|
/******************************************************************************
|
|
LocIpcQrtrWatcher override
|
|
******************************************************************************/
|
|
class IpcQrtrWatcher : public LocIpcQrtrWatcher {
|
|
const weak_ptr<IpcListener> mIpcListener;
|
|
const weak_ptr<LocIpcSender> mIpcSender;
|
|
LocIpcQrtrWatcher::ServiceStatus mKnownStatus;
|
|
LocationApiPbMsgConv mPbufMsgConv;
|
|
public:
|
|
inline IpcQrtrWatcher(shared_ptr<IpcListener>& listener, shared_ptr<LocIpcSender>& sender,
|
|
LocationApiPbMsgConv& pbMsgConv) :
|
|
LocIpcQrtrWatcher({LOCATION_CLIENT_API_QSOCKET_HALDAEMON_SERVICE_ID}),
|
|
mIpcListener(listener), mIpcSender(sender), mPbufMsgConv(pbMsgConv),
|
|
mKnownStatus(LocIpcQrtrWatcher::ServiceStatus::DOWN) {
|
|
}
|
|
inline virtual void onServiceStatusChange(int serviceId, int instanceId,
|
|
LocIpcQrtrWatcher::ServiceStatus status, const LocIpcSender& refSender) {
|
|
if (LOCATION_CLIENT_API_QSOCKET_HALDAEMON_SERVICE_ID == serviceId &&
|
|
LOCATION_CLIENT_API_QSOCKET_HALDAEMON_INSTANCE_ID == instanceId) {
|
|
if (mKnownStatus != status) {
|
|
mKnownStatus = status;
|
|
if (LocIpcQrtrWatcher::ServiceStatus::UP == status) {
|
|
LOC_LOGv("case LocIpcQrtrWatcher::ServiceStatus::UP");
|
|
auto sender = mIpcSender.lock();
|
|
if (nullptr != sender) {
|
|
sender->copyDestAddrFrom(refSender);
|
|
}
|
|
auto listener = mIpcListener.lock();
|
|
if (nullptr != listener) {
|
|
LocAPIHalReadyIndMsg msg(SERVICE_NAME, &mPbufMsgConv);
|
|
string pbStr;
|
|
if (msg.serializeToProtobuf(pbStr)) {
|
|
listener->onReceive(pbStr.c_str(), pbStr.size(), nullptr);
|
|
} else {
|
|
LOC_LOGe("LocAPIHalReadyIndMsg serializeToProtobuf failed");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
/******************************************************************************
|
|
LocationClientApiImpl
|
|
******************************************************************************/
|
|
|
|
uint32_t LocationClientApiImpl::mClientIdGenerator = LOCATION_CLIENT_SESSION_ID_INVALID;
|
|
|
|
mutex LocationClientApiImpl::mMutex;
|
|
|
|
/******************************************************************************
|
|
LocationClientApiImpl - constructors
|
|
******************************************************************************/
|
|
LocationClientApiImpl::LocationClientApiImpl(CapabilitiesCb capabitiescb) :
|
|
mSessionId(LOCATION_CLIENT_SESSION_ID_INVALID),
|
|
mBatchingId(LOCATION_CLIENT_SESSION_ID_INVALID),
|
|
mHalRegistered(false),
|
|
mCallbacksMask(0),
|
|
mCapsMask((LocationCapabilitiesMask)0),
|
|
mYearOfHw(0),
|
|
mLastAddedClientIds({}),
|
|
mCapabilitiesCb(capabitiescb),
|
|
mResponseCb(nullptr),
|
|
mPositionSessionResponseCbPending(false),
|
|
mLocationCb(nullptr),
|
|
mGnssLocationCb(nullptr),
|
|
mEngLocationsCb(nullptr),
|
|
mGnssSvCb(nullptr),
|
|
mGnssNmeaCb(nullptr),
|
|
mGnssDataCb(nullptr),
|
|
mGnssMeasurementsCb(nullptr),
|
|
mGnssEnergyConsumedInfoCb(nullptr),
|
|
mGnssEnergyConsumedResponseCb(nullptr),
|
|
mLocationSysInfoCb(nullptr),
|
|
mLocationSysInfoResponseCb(nullptr),
|
|
mSingleTerrestrialPosCb(nullptr),
|
|
mSingleTerrestrialPosRespCb(nullptr),
|
|
mPingTestCb(nullptr),
|
|
mMsgTask("ClientApiImpl"),
|
|
mLogger()
|
|
{
|
|
// read configuration file
|
|
UTIL_READ_CONF(LOC_PATH_GPS_CONF, gConfigTable);
|
|
LOC_LOGd("gDebug=%u", gDebug);
|
|
|
|
// get pid to generate sokect name
|
|
uint32_t pid = (uint32_t)getpid();
|
|
|
|
#ifdef FEATURE_EXTERNAL_AP
|
|
// The instance id is composed from pid and client id.
|
|
// We support up to 32 unique client api within one process.
|
|
// Each client id is tracked via a bit in mClientIdGenerator,
|
|
// which is 4 bytes now.
|
|
lock_guard<mutex> lock(mMutex);
|
|
unsigned int clientIdMask = 1;
|
|
// find a bit in the mClientIdGenerator that is not yet used
|
|
// and use that as client id
|
|
// client id will be from 1 to 32, as client id will be used to
|
|
// set session id and 0 is reserved for LOCATION_CLIENT_SESSION_ID_INVALID
|
|
for (mClientId = 1; mClientId <= sizeof(mClientIdGenerator) * 8; mClientId++) {
|
|
if ((mClientIdGenerator & (1UL << (mClientId-1))) == 0) {
|
|
mClientIdGenerator |= (1UL << (mClientId-1));
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (mClientId > sizeof(mClientIdGenerator) * 8) {
|
|
LOC_LOGe("create Qsocket failed, already use up maximum of %d clients",
|
|
sizeof(mClientIdGenerator)*8);
|
|
return;
|
|
}
|
|
|
|
SockNodeEap sock(LOCATION_CLIENT_API_QSOCKET_CLIENT_SERVICE_ID,
|
|
pid * 100 + mClientId);
|
|
size_t pathNameLength = strlcpy(mSocketName, sock.getNodePathname().c_str(),
|
|
sizeof(mSocketName));
|
|
if (pathNameLength >= sizeof(mSocketName)) {
|
|
LOC_LOGe("socket name length exceeds limit of %d bytes", sizeof(mSocketName));
|
|
return;
|
|
}
|
|
|
|
// establish an ipc sender to the hal daemon
|
|
mIpcSender = LocIpc::getLocIpcQrtrSender(LOCATION_CLIENT_API_QSOCKET_HALDAEMON_SERVICE_ID,
|
|
LOCATION_CLIENT_API_QSOCKET_HALDAEMON_INSTANCE_ID);
|
|
if (mIpcSender == nullptr) {
|
|
LOC_LOGe("create sender socket failed for service id: %d instance id: %d",
|
|
LOCATION_CLIENT_API_QSOCKET_HALDAEMON_SERVICE_ID,
|
|
LOCATION_CLIENT_API_QSOCKET_HALDAEMON_INSTANCE_ID);
|
|
return;
|
|
}
|
|
shared_ptr<IpcListener> listener(make_shared<IpcListener>(*this, mMsgTask, SockNode::Eap));
|
|
unique_ptr<LocIpcRecver> recver = LocIpc::getLocIpcQrtrRecver(listener,
|
|
sock.getId1(), sock.getId2(),
|
|
make_shared<IpcQrtrWatcher>(listener, mIpcSender, mPbufMsgConv));
|
|
#else
|
|
// get clientId
|
|
lock_guard<mutex> lock(mMutex);
|
|
mClientId = ++mClientIdGenerator;
|
|
// make sure client ID is not equal to LOCATION_CLIENT_SESSION_ID_INVALID,
|
|
// as session id will be assigned to client ID
|
|
if (mClientId == LOCATION_CLIENT_SESSION_ID_INVALID) {
|
|
mClientId = ++mClientIdGenerator;
|
|
}
|
|
|
|
SockNodeLocal sock(LOCATION_CLIENT_API, pid, mClientId);
|
|
size_t pathNameLength = strlcpy(mSocketName, sock.getNodePathname().c_str(),
|
|
sizeof(mSocketName));
|
|
if (pathNameLength >= sizeof(mSocketName)) {
|
|
LOC_LOGe("socket name length exceeds limit of %d bytes", sizeof(mSocketName));
|
|
return;
|
|
}
|
|
|
|
// establish an ipc sender to the hal daemon
|
|
mIpcSender = LocIpc::getLocIpcLocalSender(SOCKET_TO_LOCATION_HAL_DAEMON);
|
|
if (mIpcSender == nullptr) {
|
|
LOC_LOGe("create sender socket failed %s", SOCKET_TO_LOCATION_HAL_DAEMON);
|
|
return;
|
|
}
|
|
unique_ptr<LocIpcRecver> recver = LocIpc::getLocIpcLocalRecver(
|
|
make_shared<IpcListener>(*this, mMsgTask, SockNode::Local), mSocketName);
|
|
#endif
|
|
|
|
LOC_LOGd("listen on socket: %s", mSocketName);
|
|
mIpc.startNonBlockingListening(recver);
|
|
}
|
|
|
|
LocationClientApiImpl::~LocationClientApiImpl() {
|
|
}
|
|
|
|
void LocationClientApiImpl::destroy() {
|
|
|
|
struct DestroyReq : public LocMsg {
|
|
DestroyReq(LocationClientApiImpl* apiImpl) :
|
|
mApiImpl(apiImpl) {}
|
|
virtual ~DestroyReq() {}
|
|
void proc() const {
|
|
// deregister
|
|
if (mApiImpl->mHalRegistered && (nullptr != mApiImpl->mIpcSender)) {
|
|
string pbStr;
|
|
LocAPIClientDeregisterReqMsg msg(mApiImpl->mSocketName, &mApiImpl->mPbufMsgConv);
|
|
if (msg.serializeToProtobuf(pbStr)) {
|
|
bool rc = mApiImpl->sendMessage(
|
|
reinterpret_cast<uint8_t *>((uint8_t *)pbStr.c_str()), pbStr.size());
|
|
LOC_LOGd(">>> DeregisterReq rc=%d", rc);
|
|
mApiImpl->mIpcSender = nullptr;
|
|
} else {
|
|
LOC_LOGe("LocAPIClientDeregisterReqMsg serializeToProtobuf failed");
|
|
}
|
|
}
|
|
|
|
#ifdef FEATURE_EXTERNAL_AP
|
|
{
|
|
// get clientId
|
|
lock_guard<mutex> lock(mMutex);
|
|
mApiImpl->mClientIdGenerator &= ~(1UL << mApiImpl->mClientId);
|
|
LOC_LOGd("client id generarator 0x%x, id %d",
|
|
mApiImpl->mClientIdGenerator, mApiImpl->mClientId);
|
|
}
|
|
#endif //FEATURE_EXTERNAL_AP
|
|
delete mApiImpl;
|
|
}
|
|
LocationClientApiImpl* mApiImpl;
|
|
};
|
|
|
|
mMsgTask.sendMsg(new (nothrow) DestroyReq(this));
|
|
}
|
|
|
|
/******************************************************************************
|
|
LocationClientApiImpl - implementation
|
|
******************************************************************************/
|
|
void LocationClientApiImpl::updateCallbackFunctions(const ClientCallbacks& cbs,
|
|
ReportCbEnumType reportCbType) {
|
|
|
|
struct UpdateCallbackFunctionsReq : public LocMsg {
|
|
UpdateCallbackFunctionsReq(LocationClientApiImpl* apiImpl, const ClientCallbacks& cbs,
|
|
ReportCbEnumType reportCbType) :
|
|
mApiImpl(apiImpl), mCbs(cbs), mReportCbType(reportCbType) {}
|
|
virtual ~UpdateCallbackFunctionsReq() {}
|
|
void proc() const {
|
|
// update callback functions
|
|
mApiImpl->mResponseCb = mCbs.responsecb;
|
|
mApiImpl->mCollectiveResCb = mCbs.collectivecb;
|
|
mApiImpl->mLocationCb = mCbs.locationcb;
|
|
mApiImpl->mBatchingCb = mCbs.batchingcb;
|
|
mApiImpl->mGfBreachCb = mCbs.gfbreachcb;
|
|
|
|
if (REPORT_CB_GNSS_INFO == mReportCbType) {
|
|
mApiImpl->mGnssLocationCb = mCbs.gnssreportcbs.gnssLocationCallback;
|
|
mApiImpl->mGnssSvCb = mCbs.gnssreportcbs.gnssSvCallback;
|
|
mApiImpl->mGnssNmeaCb = mCbs.gnssreportcbs.gnssNmeaCallback;
|
|
mApiImpl->mGnssDataCb = mCbs.gnssreportcbs.gnssDataCallback;
|
|
mApiImpl->mGnssMeasurementsCb = mCbs.gnssreportcbs.gnssMeasurementsCallback;
|
|
} else if (REPORT_CB_ENGINE_INFO == mReportCbType) {
|
|
mApiImpl->mEngLocationsCb = mCbs.engreportcbs.engLocationsCallback;
|
|
mApiImpl->mGnssSvCb = mCbs.engreportcbs.gnssSvCallback;
|
|
mApiImpl->mGnssNmeaCb = mCbs.engreportcbs.gnssNmeaCallback;
|
|
mApiImpl->mGnssDataCb = mCbs.engreportcbs.gnssDataCallback;
|
|
mApiImpl->mGnssMeasurementsCb = mCbs.engreportcbs.gnssMeasurementsCallback;
|
|
}
|
|
}
|
|
LocationClientApiImpl* mApiImpl;
|
|
const ClientCallbacks mCbs;
|
|
ReportCbEnumType mReportCbType;
|
|
};
|
|
mMsgTask.sendMsg(new (nothrow) UpdateCallbackFunctionsReq(this, cbs, reportCbType));
|
|
}
|
|
|
|
void LocationClientApiImpl::updateCallbacks(LocationCallbacks& callbacks) {
|
|
|
|
struct UpdateCallbacksReq : public LocMsg {
|
|
UpdateCallbacksReq(LocationClientApiImpl* apiImpl, const LocationCallbacks& callbacks) :
|
|
mApiImpl(apiImpl), mCallBacks(callbacks) {}
|
|
virtual ~UpdateCallbacksReq() {}
|
|
void proc() const {
|
|
// set up the flag to indicate that responseCb is pending
|
|
mApiImpl->mPositionSessionResponseCbPending = true;
|
|
|
|
//convert callbacks to callBacksMask
|
|
LocationCallbacksMask callBacksMask = 0;
|
|
if (mCallBacks.trackingCb) {
|
|
callBacksMask |= E_LOC_CB_DISTANCE_BASED_TRACKING_BIT;
|
|
}
|
|
if (mCallBacks.gnssLocationInfoCb) {
|
|
if (mApiImpl->mLocationCb) {
|
|
callBacksMask |= E_LOC_CB_SIMPLE_LOCATION_INFO_BIT;
|
|
} else {
|
|
callBacksMask |= E_LOC_CB_GNSS_LOCATION_INFO_BIT;
|
|
}
|
|
}
|
|
if (mCallBacks.engineLocationsInfoCb) {
|
|
callBacksMask |= E_LOC_CB_ENGINE_LOCATIONS_INFO_BIT;
|
|
}
|
|
if (mCallBacks.gnssSvCb) {
|
|
callBacksMask |= E_LOC_CB_GNSS_SV_BIT;
|
|
}
|
|
if (mCallBacks.gnssNmeaCb) {
|
|
callBacksMask |= E_LOC_CB_GNSS_NMEA_BIT;
|
|
}
|
|
if (mCallBacks.gnssDataCb) {
|
|
callBacksMask |= E_LOC_CB_GNSS_DATA_BIT;
|
|
}
|
|
if (mCallBacks.gnssMeasurementsCb) {
|
|
callBacksMask |= E_LOC_CB_GNSS_MEAS_BIT;
|
|
}
|
|
// handle callbacks that are not related to a fix session
|
|
if (mApiImpl->mLocationSysInfoCb) {
|
|
callBacksMask |= E_LOC_CB_SYSTEM_INFO_BIT;
|
|
}
|
|
if (mCallBacks.batchingCb) {
|
|
callBacksMask |= E_LOC_CB_BATCHING_BIT;
|
|
}
|
|
if (mCallBacks.batchingStatusCb) {
|
|
callBacksMask |= E_LOC_CB_BATCHING_STATUS_BIT;
|
|
}
|
|
if (mCallBacks.geofenceBreachCb) {
|
|
callBacksMask |= E_LOC_CB_GEOFENCE_BREACH_BIT;
|
|
}
|
|
|
|
// update callback only when changed
|
|
if (mApiImpl->mCallbacksMask != callBacksMask) {
|
|
mApiImpl->mCallbacksMask = callBacksMask;
|
|
if (mApiImpl->mHalRegistered) {
|
|
string pbStr;
|
|
LocAPIUpdateCallbacksReqMsg msg(mApiImpl->mSocketName,
|
|
mApiImpl->mCallbacksMask,
|
|
&mApiImpl->mPbufMsgConv);
|
|
if (msg.serializeToProtobuf(pbStr)) {
|
|
bool rc = mApiImpl->sendMessage(
|
|
reinterpret_cast<uint8_t *>((uint8_t *)pbStr.c_str()),
|
|
pbStr.size());
|
|
LOC_LOGd(">>> UpdateCallbacksReq callBacksMask=0x%x rc=%d",
|
|
mApiImpl->mCallbacksMask, rc);
|
|
} else {
|
|
LOC_LOGe("LocAPIUpdateCallbacksReqMsg serializeToProtobuf failed");
|
|
}
|
|
}
|
|
} else {
|
|
LOC_LOGd("No updateCallbacks because same callBacksMask 0x%x", callBacksMask);
|
|
}
|
|
}
|
|
LocationClientApiImpl* mApiImpl;
|
|
const LocationCallbacks mCallBacks;
|
|
};
|
|
mMsgTask.sendMsg(new (nothrow) UpdateCallbacksReq(this, callbacks));
|
|
}
|
|
|
|
uint32_t LocationClientApiImpl::startTracking(TrackingOptions& option) {
|
|
|
|
struct StartTrackingReq : public LocMsg {
|
|
StartTrackingReq(LocationClientApiImpl* apiImpl, TrackingOptions& option) :
|
|
mApiImpl(apiImpl), mOption(option) {}
|
|
virtual ~StartTrackingReq() {}
|
|
void proc() const {
|
|
// check if option is updated
|
|
bool isOptionUpdated = false;
|
|
|
|
if ((mApiImpl->mLocationOptions.minInterval != mOption.minInterval) ||
|
|
(mApiImpl->mLocationOptions.minDistance != mOption.minDistance) ||
|
|
(mApiImpl->mLocationOptions.locReqEngTypeMask != mOption.locReqEngTypeMask)) {
|
|
isOptionUpdated = true;
|
|
}
|
|
|
|
if (!mApiImpl->mHalRegistered) {
|
|
mApiImpl->mLocationOptions = mOption;
|
|
// need to set session id so when hal is ready, the session can be resumed
|
|
mApiImpl->mSessionId = mApiImpl->mClientId;
|
|
LOC_LOGe(">>> startTracking - Not registered yet");
|
|
return;
|
|
}
|
|
|
|
if (LOCATION_CLIENT_SESSION_ID_INVALID == mApiImpl->mSessionId) {
|
|
mApiImpl->mLocationOptions = mOption;
|
|
//start a new tracking session
|
|
mApiImpl->mSessionId = mApiImpl->mClientId;
|
|
|
|
if ((0 != mApiImpl->mLocationOptions.minInterval) ||
|
|
(0 != mApiImpl->mLocationOptions.minDistance)) {
|
|
string pbStr;
|
|
LocAPIStartTrackingReqMsg msg(mApiImpl->mSocketName,
|
|
mApiImpl->mLocationOptions,
|
|
&mApiImpl->mPbufMsgConv);
|
|
if (msg.serializeToProtobuf(pbStr)) {
|
|
bool rc = mApiImpl->sendMessage(
|
|
reinterpret_cast<uint8_t *>((uint8_t *)pbStr.c_str()), pbStr.size());
|
|
LOC_LOGd(">>> StartTrackingReq Interval=%d Distance=%d,"
|
|
" locReqEngTypeMask=0x%x",
|
|
mApiImpl->mLocationOptions.minInterval,
|
|
mApiImpl->mLocationOptions.minDistance,
|
|
mApiImpl->mLocationOptions.locReqEngTypeMask);
|
|
} else {
|
|
LOC_LOGe("LocAPIStartTrackingReqMsg serializeToProtobuf failed");
|
|
}
|
|
}
|
|
} else if (isOptionUpdated) {
|
|
//update a tracking session, mApiImpl->mLocationOptions
|
|
//will be updated in updateTrackingOptionsSync
|
|
mApiImpl->updateTrackingOptionsSync(
|
|
mApiImpl, const_cast<TrackingOptions&>(mOption));
|
|
} else {
|
|
LOC_LOGd(">>> StartTrackingReq - no change in option");
|
|
mApiImpl->invokePositionSessionResponseCb(LOCATION_RESPONSE_SUCCESS);
|
|
}
|
|
}
|
|
LocationClientApiImpl* mApiImpl;
|
|
TrackingOptions mOption;
|
|
};
|
|
mMsgTask.sendMsg(new (nothrow) StartTrackingReq(this, option));
|
|
return 0;
|
|
}
|
|
|
|
void LocationClientApiImpl::stopTracking(uint32_t) {
|
|
|
|
struct StopTrackingReq : public LocMsg {
|
|
StopTrackingReq(LocationClientApiImpl* apiImpl) : mApiImpl(apiImpl) {}
|
|
virtual ~StopTrackingReq() {}
|
|
void proc() const {
|
|
if (mApiImpl->mSessionId == mApiImpl->mClientId) {
|
|
if (mApiImpl->mHalRegistered &&
|
|
((mApiImpl->mLocationOptions.minInterval != 0) ||
|
|
(mApiImpl->mLocationOptions.minDistance != 0))) {
|
|
string pbStr;
|
|
LocAPIStopTrackingReqMsg msg(mApiImpl->mSocketName, &mApiImpl->mPbufMsgConv);
|
|
if (msg.serializeToProtobuf(pbStr)) {
|
|
bool rc = mApiImpl->sendMessage(
|
|
reinterpret_cast<uint8_t *>((uint8_t *)pbStr.c_str()),
|
|
pbStr.size());
|
|
LOC_LOGd(">>> StopTrackingReq rc=%d\n", rc);
|
|
} else {
|
|
LOC_LOGe("LocAPIStopTrackingReqMsg serializeToProtobuf failed");
|
|
}
|
|
}
|
|
|
|
mApiImpl->mLocationOptions.minInterval = 0;
|
|
mApiImpl->mLocationOptions.minDistance = 0;
|
|
mApiImpl->mCallbacksMask = 0;
|
|
// handle callback that are not tied with fix session
|
|
if (mApiImpl->mLocationSysInfoCb) {
|
|
mApiImpl->mCallbacksMask |= E_LOC_CB_SYSTEM_INFO_BIT;
|
|
}
|
|
}
|
|
mApiImpl->mSessionId = LOCATION_CLIENT_SESSION_ID_INVALID;
|
|
}
|
|
LocationClientApiImpl* mApiImpl;
|
|
};
|
|
mMsgTask.sendMsg(new (nothrow) StopTrackingReq(this));
|
|
}
|
|
|
|
void LocationClientApiImpl::updateTrackingOptionsSync(
|
|
LocationClientApiImpl* pImpl, TrackingOptions& option) {
|
|
|
|
LOC_LOGd(">>> updateTrackingOptionsSync,sessionId=%d, "
|
|
"new Interval=%d Distance=%d, current Interval=%d Distance=%d",
|
|
pImpl->mSessionId, option.minInterval,
|
|
option.minDistance, pImpl->mLocationOptions.minInterval,
|
|
pImpl->mLocationOptions.minDistance);
|
|
|
|
bool rc = true;
|
|
string pbStr;
|
|
// update option to passive listening where previous option
|
|
// is not passive listening, in this case, we need to stop the session
|
|
if (((option.minInterval == 0) && (option.minDistance == 0)) &&
|
|
((pImpl->mLocationOptions.minInterval != 0) ||
|
|
(pImpl->mLocationOptions.minDistance != 0))) {
|
|
LocAPIStopTrackingReqMsg msg(pImpl->mSocketName, &pImpl->mPbufMsgConv);
|
|
if (msg.serializeToProtobuf(pbStr)) {
|
|
rc = pImpl->sendMessage(reinterpret_cast<uint8_t *>((uint8_t *)pbStr.c_str()),
|
|
pbStr.size());
|
|
} else {
|
|
LOC_LOGe("LocAPIStopTrackingReqMsg serializeToProtobuf failed");
|
|
}
|
|
} else if (((option.minInterval != 0) || (option.minDistance != 0)) &&
|
|
((pImpl->mLocationOptions.minInterval == 0) &&
|
|
(pImpl->mLocationOptions.minDistance == 0))) {
|
|
// update option from passive listening to none passive listening,
|
|
// we need to start the session
|
|
LocAPIStartTrackingReqMsg msg(pImpl->mSocketName, option, &pImpl->mPbufMsgConv);
|
|
if (msg.serializeToProtobuf(pbStr)) {
|
|
rc = pImpl->sendMessage(reinterpret_cast<uint8_t *>((uint8_t *)pbStr.c_str()),
|
|
pbStr.size());
|
|
LOC_LOGd(">>> start tracking Interval=%d Distance=%d",
|
|
option.minInterval, option.minDistance);
|
|
} else {
|
|
LOC_LOGe("LocAPIStartTrackingReqMsg serializeToProtobuf failed");
|
|
}
|
|
} else {
|
|
LocAPIUpdateTrackingOptionsReqMsg msg(pImpl->mSocketName, option, &pImpl->mPbufMsgConv);
|
|
if (msg.serializeToProtobuf(pbStr)) {
|
|
bool rc = pImpl->sendMessage(reinterpret_cast<uint8_t *>((uint8_t *)pbStr.c_str()),
|
|
pbStr.size());
|
|
LOC_LOGd(">>> updateTrackingOptionsSync Interval=%d Distance=%d, reqTypeMask=0x%x",
|
|
option.minInterval, option.minDistance, option.locReqEngTypeMask);
|
|
} else {
|
|
LOC_LOGe("LocAPIUpdateTrackingOptionsReqMsg serializeToProtobuf failed");
|
|
}
|
|
}
|
|
|
|
pImpl->mLocationOptions = option;
|
|
}
|
|
|
|
|
|
//Batching
|
|
uint32_t LocationClientApiImpl::startBatching(BatchingOptions& batchOptions) {
|
|
struct StartBatchingReq : public LocMsg {
|
|
StartBatchingReq(LocationClientApiImpl *apiImpl, BatchingOptions& batchOptions) :
|
|
mApiImpl(apiImpl), mBatchOptions(batchOptions) {}
|
|
virtual ~StartBatchingReq() {}
|
|
void proc() const {
|
|
mApiImpl->mBatchingOptions = mBatchOptions;
|
|
if (!mApiImpl->mHalRegistered) {
|
|
LOC_LOGe(">>> startBatching - Not registered yet");
|
|
return;
|
|
}
|
|
if (LOCATION_CLIENT_SESSION_ID_INVALID == mApiImpl->mSessionId) {
|
|
//start a new batching session
|
|
string pbStr;
|
|
mApiImpl->mBatchingId = mApiImpl->mClientId;
|
|
LocAPIStartBatchingReqMsg msg(mApiImpl->mSocketName,
|
|
mApiImpl->mBatchingOptions.minInterval,
|
|
mApiImpl->mBatchingOptions.minDistance,
|
|
mApiImpl->mBatchingOptions.batchingMode,
|
|
&mApiImpl->mPbufMsgConv);
|
|
if (msg.serializeToProtobuf(pbStr)) {
|
|
bool rc = mApiImpl->sendMessage(
|
|
reinterpret_cast<uint8_t *>((uint8_t *)pbStr.c_str()), pbStr.size());
|
|
LOC_LOGd(">>> StartBatchingReq Interval=%d Distance=%d BatchingMode=%d",
|
|
mApiImpl->mBatchingOptions.minInterval,
|
|
mApiImpl->mBatchingOptions.minDistance,
|
|
mApiImpl->mBatchingOptions.batchingMode);
|
|
} else {
|
|
LOC_LOGe("LocAPIStartBatchingReqMsg serializeToProtobuf failed");
|
|
}
|
|
} else {
|
|
mApiImpl->updateBatchingOptions(mApiImpl->mBatchingId,
|
|
const_cast<BatchingOptions&>(mBatchOptions));
|
|
}
|
|
}
|
|
LocationClientApiImpl *mApiImpl;
|
|
BatchingOptions mBatchOptions;
|
|
};
|
|
mMsgTask.sendMsg(new (nothrow) StartBatchingReq(this, batchOptions));
|
|
return 0;
|
|
}
|
|
|
|
void LocationClientApiImpl::stopBatching(uint32_t id) {
|
|
struct StopBatchingReq : public LocMsg {
|
|
StopBatchingReq(LocationClientApiImpl *apiImpl) :
|
|
mApiImpl(apiImpl) {}
|
|
virtual ~StopBatchingReq() {}
|
|
void proc() const {
|
|
if (mApiImpl->mBatchingId == mApiImpl->mClientId) {
|
|
string pbStr;
|
|
mApiImpl->mBatchingOptions = {};
|
|
LocAPIStopBatchingReqMsg msg(mApiImpl->mSocketName, &mApiImpl->mPbufMsgConv);
|
|
if (msg.serializeToProtobuf(pbStr)) {
|
|
bool rc = mApiImpl->sendMessage(
|
|
reinterpret_cast<uint8_t *>((uint8_t *)pbStr.c_str()), pbStr.size());
|
|
LOC_LOGd(">>> StopBatchingReq rc=%d", rc);
|
|
} else {
|
|
LOC_LOGe("LocAPIStopBatchingReqMsg serializeToProtobuf failed");
|
|
}
|
|
}
|
|
mApiImpl->mBatchingId = LOCATION_CLIENT_SESSION_ID_INVALID;
|
|
}
|
|
LocationClientApiImpl *mApiImpl;
|
|
};
|
|
mMsgTask.sendMsg(new (nothrow) StopBatchingReq(this));
|
|
}
|
|
|
|
void LocationClientApiImpl::updateBatchingOptions(uint32_t id, BatchingOptions& batchOptions) {
|
|
struct UpdateBatchingOptionsReq : public LocMsg {
|
|
UpdateBatchingOptionsReq(LocationClientApiImpl* apiImpl, BatchingOptions& batchOptions) :
|
|
mApiImpl(apiImpl), mBatchOptions(batchOptions) {}
|
|
virtual ~UpdateBatchingOptionsReq() {}
|
|
void proc() const {
|
|
string pbStr;
|
|
mApiImpl->mBatchingOptions = mBatchOptions;
|
|
LocAPIUpdateBatchingOptionsReqMsg msg(mApiImpl->mSocketName,
|
|
mApiImpl->mBatchingOptions.minInterval,
|
|
mApiImpl->mBatchingOptions.minDistance,
|
|
mApiImpl->mBatchingOptions.batchingMode,
|
|
&mApiImpl->mPbufMsgConv);
|
|
if (msg.serializeToProtobuf(pbStr)) {
|
|
bool rc = mApiImpl->sendMessage(
|
|
reinterpret_cast<uint8_t *>((uint8_t *)pbStr.c_str()), pbStr.size());
|
|
LOC_LOGd(">>> StartBatchingReq Interval=%d Distance=%d BatchingMode=%d",
|
|
mApiImpl->mBatchingOptions.minInterval,
|
|
mApiImpl->mBatchingOptions.minDistance,
|
|
mApiImpl->mBatchingOptions.batchingMode);
|
|
} else {
|
|
LOC_LOGe("LocAPIUpdateBatchingOptionsReqMsg serializeToProtobuf failed");
|
|
}
|
|
}
|
|
LocationClientApiImpl *mApiImpl;
|
|
BatchingOptions mBatchOptions;
|
|
};
|
|
|
|
if ((mBatchingOptions.minInterval != batchOptions.minInterval) ||
|
|
(mBatchingOptions.minDistance != batchOptions.minDistance) ||
|
|
mBatchingOptions.batchingMode != batchOptions.batchingMode) {
|
|
mMsgTask.sendMsg(new (nothrow) UpdateBatchingOptionsReq(this, batchOptions));
|
|
} else {
|
|
LOC_LOGd("No UpdateBatchingOptions because same Interval=%d Distance=%d, BatchingMode=%d",
|
|
batchOptions.minInterval, batchOptions.minDistance, batchOptions.batchingMode);
|
|
}
|
|
}
|
|
|
|
void LocationClientApiImpl::getBatchedLocations(uint32_t id, size_t count) {}
|
|
|
|
bool LocationClientApiImpl::checkGeofenceMap(size_t count, uint32_t* ids) {
|
|
for (int i=0; i<count; ++i) {
|
|
auto got = mGeofenceMap.find(ids[i]);
|
|
if (got == mGeofenceMap.end()) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
void LocationClientApiImpl::addGeofenceMap(uint32_t id, Geofence& geofence) {
|
|
lock_guard<mutex> lock(mMutex);
|
|
mGeofenceMap.insert(make_pair(id, geofence));
|
|
}
|
|
void LocationClientApiImpl::eraseGeofenceMap(size_t count, uint32_t* ids) {
|
|
lock_guard<mutex> lock(mMutex);
|
|
for (int i=0; i<count; ++i) {
|
|
mGeofenceMap.erase(ids[i]);
|
|
}
|
|
}
|
|
|
|
uint32_t* LocationClientApiImpl::addGeofences(size_t count, GeofenceOption* options,
|
|
GeofenceInfo* infos) {
|
|
struct AddGeofencesReq : public LocMsg {
|
|
AddGeofencesReq(LocationClientApiImpl* apiImpl, uint32_t count, GeofenceOption* gfOptions,
|
|
GeofenceInfo* gfInfos, std::vector<uint32_t> clientIds) :
|
|
mApiImpl(apiImpl), mGfCount(count), mGfOptions(gfOptions), mGfInfos(gfInfos),
|
|
mClientIds(clientIds) {}
|
|
virtual ~AddGeofencesReq() {}
|
|
void proc() const {
|
|
if (!mApiImpl->mHalRegistered) {
|
|
LOC_LOGe(">>> addGeofences - Not registered yet");
|
|
return;
|
|
}
|
|
|
|
if (mGfCount > 0) {
|
|
uint32_t gfCountUsed = std::min((uint32_t)MAX_GEOFENCE_ENTRY, mGfCount);
|
|
//Add geofences, serialize geofence msg payload into ipc message payload
|
|
GeofencesAddedReqPayload gfAddReqPayLoad;
|
|
gfAddReqPayLoad.count = gfCountUsed;
|
|
for (int i=0; i < gfCountUsed; ++i) {
|
|
gfAddReqPayLoad.gfPayload[i].gfClientId = mClientIds[i];
|
|
gfAddReqPayLoad.gfPayload[i].gfOption = mGfOptions[i];
|
|
gfAddReqPayLoad.gfPayload[i].gfInfo = mGfInfos[i];
|
|
}
|
|
|
|
string pbStr;
|
|
LocAPIAddGeofencesReqMsg msg(mApiImpl->mSocketName, gfAddReqPayLoad,
|
|
&mApiImpl->mPbufMsgConv);
|
|
if (msg.serializeToProtobuf(pbStr)) {
|
|
bool rc = mApiImpl->sendMessage(
|
|
reinterpret_cast<uint8_t *>((uint8_t *)pbStr.c_str()), pbStr.size());
|
|
LOC_LOGd(">>> AddGeofencesReq count=%zu", gfCountUsed);
|
|
} else {
|
|
LOC_LOGe("LocAPIAddGeofencesReqMsg serializeToProtobuf failed");
|
|
}
|
|
free(mGfOptions);
|
|
free(mGfInfos);
|
|
} else {
|
|
LOC_LOGe("Invalid number of Gf count");
|
|
}
|
|
}
|
|
LocationClientApiImpl *mApiImpl;
|
|
uint32_t mGfCount;
|
|
GeofenceOption* mGfOptions;
|
|
GeofenceInfo* mGfInfos;
|
|
std::vector<uint32_t> mClientIds;
|
|
};
|
|
mMsgTask.sendMsg(new (nothrow) AddGeofencesReq(this, count, options, infos,
|
|
mLastAddedClientIds));
|
|
return nullptr;
|
|
}
|
|
|
|
void LocationClientApiImpl::removeGeofences(size_t count, uint32_t* ids) {
|
|
struct RemoveGeofencesReq : public LocMsg {
|
|
RemoveGeofencesReq(LocationClientApiImpl* apiImpl, uint32_t count, uint32_t* gfIds) :
|
|
mApiImpl(apiImpl), mGfCount(count), mGfIds(gfIds) {}
|
|
virtual ~RemoveGeofencesReq() {}
|
|
void proc() const {
|
|
if (!mApiImpl->mHalRegistered) {
|
|
LOC_LOGe(">>> removeGeofences - Not registered yet");
|
|
return;
|
|
}
|
|
if (mGfCount > 0) {
|
|
uint32_t gfCountUsed = std::min((uint32_t)MAX_GEOFENCE_ENTRY, mGfCount);
|
|
//Remove geofences
|
|
GeofencesReqClientIdPayload gfRemReqPayLoad;
|
|
gfRemReqPayLoad.count = gfCountUsed;
|
|
memcpy(gfRemReqPayLoad.gfIds, mGfIds, sizeof(uint32_t) * gfCountUsed);
|
|
|
|
string pbStr;
|
|
LocAPIRemoveGeofencesReqMsg msg(mApiImpl->mSocketName, gfRemReqPayLoad,
|
|
&mApiImpl->mPbufMsgConv);
|
|
if (msg.serializeToProtobuf(pbStr)) {
|
|
bool rc = mApiImpl->sendMessage(
|
|
reinterpret_cast<uint8_t *>((uint8_t *)pbStr.c_str()), pbStr.size());
|
|
LOC_LOGd(">>> RemoveGeofencesReq count=%zu", gfCountUsed);
|
|
} else {
|
|
LOC_LOGe("LocAPIRemoveGeofencesReqMsg serializeToProtobuf failed");
|
|
}
|
|
free(mGfIds);
|
|
} else {
|
|
LOC_LOGe("Invalid number of Gf count");
|
|
}
|
|
}
|
|
LocationClientApiImpl *mApiImpl;
|
|
uint32_t mGfCount;
|
|
uint32_t* mGfIds;
|
|
};
|
|
mMsgTask.sendMsg(new (nothrow) RemoveGeofencesReq(this, count, ids));
|
|
}
|
|
|
|
void LocationClientApiImpl::modifyGeofences(
|
|
size_t count, uint32_t* ids, GeofenceOption* options) {
|
|
struct ModifyGeofencesReq : public LocMsg {
|
|
ModifyGeofencesReq(LocationClientApiImpl* apiImpl, uint32_t count, uint32_t* gfIds,
|
|
GeofenceOption* gfOptions) :
|
|
mApiImpl(apiImpl), mGfCount(count), mGfIds(gfIds), mGfOptions(gfOptions) {}
|
|
virtual ~ModifyGeofencesReq() {}
|
|
void proc() const {
|
|
if (!mApiImpl->mHalRegistered) {
|
|
LOC_LOGe(">>> modifyGeofences - Not registered yet");
|
|
return;
|
|
}
|
|
if (mGfCount > 0) {
|
|
uint32_t gfCountUsed = std::min((uint32_t)MAX_GEOFENCE_ENTRY, mGfCount);
|
|
//Modify geofences
|
|
GeofencesAddedReqPayload gfModReqPayLoad;
|
|
gfModReqPayLoad.count = gfCountUsed;
|
|
for (int i=0; i < gfCountUsed; ++i) {
|
|
gfModReqPayLoad.gfPayload[i].gfClientId = mGfIds[i];
|
|
gfModReqPayLoad.gfPayload[i].gfOption = mGfOptions[i];
|
|
}
|
|
|
|
string pbStr;
|
|
LocAPIModifyGeofencesReqMsg msg(mApiImpl->mSocketName, gfModReqPayLoad,
|
|
&mApiImpl->mPbufMsgConv);
|
|
if (msg.serializeToProtobuf(pbStr)) {
|
|
bool rc = mApiImpl->sendMessage(
|
|
reinterpret_cast<uint8_t *>((uint8_t *)pbStr.c_str()), pbStr.size());
|
|
LOC_LOGd(">>> ModifyGeofencesReq count=%zu", gfCountUsed);
|
|
} else {
|
|
LOC_LOGe("LocAPIModifyGeofencesReqMsg serializeToProtobuf failed");
|
|
}
|
|
free(mGfIds);
|
|
free(mGfOptions);
|
|
} else {
|
|
LOC_LOGe("Invalid number of Gf count");
|
|
}
|
|
}
|
|
LocationClientApiImpl *mApiImpl;
|
|
uint32_t mGfCount;
|
|
uint32_t* mGfIds;
|
|
GeofenceOption* mGfOptions;
|
|
};
|
|
mMsgTask.sendMsg(new (nothrow) ModifyGeofencesReq(this, count, ids, options));
|
|
}
|
|
|
|
void LocationClientApiImpl::pauseGeofences(size_t count, uint32_t* ids) {
|
|
struct PauseGeofencesReq : public LocMsg {
|
|
PauseGeofencesReq(LocationClientApiImpl* apiImpl, uint32_t count, uint32_t* gfIds) :
|
|
mApiImpl(apiImpl), mGfCount(count), mGfIds(gfIds) {}
|
|
virtual ~PauseGeofencesReq() {}
|
|
void proc() const {
|
|
if (!mApiImpl->mHalRegistered) {
|
|
LOC_LOGe(">>> pauseGeofences - Not registered yet");
|
|
return;
|
|
}
|
|
if (mGfCount > 0) {
|
|
uint32_t gfCountUsed = std::min((uint32_t)MAX_GEOFENCE_ENTRY, mGfCount);
|
|
//Pause geofences
|
|
GeofencesReqClientIdPayload gfPauseReqPayLoad;
|
|
gfPauseReqPayLoad.count = gfCountUsed;
|
|
memcpy(gfPauseReqPayLoad.gfIds, mGfIds, sizeof(uint32_t) * gfCountUsed);
|
|
|
|
string pbStr;
|
|
LocAPIPauseGeofencesReqMsg msg(mApiImpl->mSocketName, gfPauseReqPayLoad,
|
|
&mApiImpl->mPbufMsgConv);
|
|
if (msg.serializeToProtobuf(pbStr)) {
|
|
bool rc = mApiImpl->sendMessage(
|
|
reinterpret_cast<uint8_t *>((uint8_t *)pbStr.c_str()), pbStr.size());
|
|
LOC_LOGd(">>> PauseGeofencesReq count=%zu", gfCountUsed);
|
|
} else {
|
|
LOC_LOGe("LocAPIPauseGeofencesReqMsg serializeToProtobuf failed");
|
|
}
|
|
free(mGfIds);
|
|
} else {
|
|
LOC_LOGe("Invalid number of Gf count");
|
|
}
|
|
}
|
|
LocationClientApiImpl *mApiImpl;
|
|
uint32_t mGfCount;
|
|
uint32_t* mGfIds;
|
|
};
|
|
mMsgTask.sendMsg(new (nothrow) PauseGeofencesReq(this, count, ids));
|
|
}
|
|
|
|
void LocationClientApiImpl::resumeGeofences(size_t count, uint32_t* ids) {
|
|
struct ResumeGeofencesReq : public LocMsg {
|
|
ResumeGeofencesReq(LocationClientApiImpl* apiImpl, uint32_t count, uint32_t* gfIds) :
|
|
mApiImpl(apiImpl), mGfCount(count), mGfIds(gfIds) {}
|
|
virtual ~ResumeGeofencesReq() {}
|
|
void proc() const {
|
|
if (!mApiImpl->mHalRegistered) {
|
|
LOC_LOGe(">>> resumeGeofences - Not registered yet");
|
|
return;
|
|
}
|
|
if (mGfCount > 0) {
|
|
uint32_t gfCountUsed = std::min((uint32_t)MAX_GEOFENCE_ENTRY, mGfCount);
|
|
//Resume geofences
|
|
GeofencesReqClientIdPayload gfResumeReqPayLoad;
|
|
gfResumeReqPayLoad.count = gfCountUsed;
|
|
memcpy(gfResumeReqPayLoad.gfIds, mGfIds, sizeof(uint32_t) * gfCountUsed);
|
|
|
|
string pbStr;
|
|
LocAPIResumeGeofencesReqMsg msg(mApiImpl->mSocketName, gfResumeReqPayLoad,
|
|
&mApiImpl->mPbufMsgConv);
|
|
if (msg.serializeToProtobuf(pbStr)) {
|
|
bool rc = mApiImpl->sendMessage(
|
|
reinterpret_cast<uint8_t *>((uint8_t *)pbStr.c_str()), pbStr.size());
|
|
LOC_LOGd(">>> ResumeGeofencesReq count=%zu", gfCountUsed);
|
|
} else {
|
|
LOC_LOGe("LocAPIResumeGeofencesReqMsg serializeToProtobuf failed");
|
|
}
|
|
free(mGfIds);
|
|
} else {
|
|
LOC_LOGe("Invalid number of Gf count");
|
|
}
|
|
}
|
|
LocationClientApiImpl *mApiImpl;
|
|
uint32_t mGfCount;
|
|
uint32_t* mGfIds;
|
|
};
|
|
mMsgTask.sendMsg(new (nothrow) ResumeGeofencesReq(this, count, ids));
|
|
}
|
|
|
|
void LocationClientApiImpl::updateNetworkAvailability(bool available) {
|
|
|
|
struct UpdateNetworkAvailabilityReq : public LocMsg {
|
|
UpdateNetworkAvailabilityReq(LocationClientApiImpl* apiImpl, bool available) :
|
|
mApiImpl(apiImpl), mAvailable(available) {}
|
|
virtual ~UpdateNetworkAvailabilityReq() {}
|
|
void proc() const {
|
|
string pbStr;
|
|
LocAPIUpdateNetworkAvailabilityReqMsg msg(mApiImpl->mSocketName,
|
|
mAvailable,
|
|
&mApiImpl->mPbufMsgConv);
|
|
if (msg.serializeToProtobuf(pbStr)) {
|
|
bool rc = mApiImpl->sendMessage(
|
|
reinterpret_cast<uint8_t *>((uint8_t *)pbStr.c_str()), pbStr.size());
|
|
LOC_LOGd(">>> UpdateNetworkAvailabilityReq available=%d ", mAvailable);
|
|
} else {
|
|
LOC_LOGe("LocAPIUpdateNetworkAvailabilityReqMsg serializeToProtobuf failed");
|
|
}
|
|
}
|
|
LocationClientApiImpl* mApiImpl;
|
|
const bool mAvailable;
|
|
};
|
|
mMsgTask.sendMsg(new (nothrow) UpdateNetworkAvailabilityReq(this, available));
|
|
}
|
|
|
|
void LocationClientApiImpl::getGnssEnergyConsumed(
|
|
GnssEnergyConsumedCb gnssEnergyConsumedCallback,
|
|
ResponseCb responseCallback) {
|
|
|
|
struct GetGnssEnergyConsumedReq : public LocMsg {
|
|
GetGnssEnergyConsumedReq(LocationClientApiImpl *apiImpl,
|
|
GnssEnergyConsumedCb gnssEnergyConsumedCb,
|
|
ResponseCb responseCb) :
|
|
mApiImpl(apiImpl),
|
|
mGnssEnergyConsumedCb(gnssEnergyConsumedCb),
|
|
mResponseCb(responseCb) {}
|
|
|
|
virtual ~GetGnssEnergyConsumedReq() {}
|
|
void proc() const {
|
|
mApiImpl->mGnssEnergyConsumedInfoCb = mGnssEnergyConsumedCb;
|
|
mApiImpl->mGnssEnergyConsumedResponseCb = mResponseCb;
|
|
|
|
// send msg to the hal daemon
|
|
if (nullptr != mApiImpl->mGnssEnergyConsumedInfoCb) {
|
|
string pbStr;
|
|
LocAPIGetGnssEnergyConsumedReqMsg msg(mApiImpl->mSocketName,
|
|
&mApiImpl->mPbufMsgConv);
|
|
if (msg.serializeToProtobuf(pbStr)) {
|
|
bool rc = mApiImpl->sendMessage(
|
|
reinterpret_cast<uint8_t *>((uint8_t *)pbStr.c_str()), pbStr.size());
|
|
if (mResponseCb) {
|
|
if (true == rc) {
|
|
mResponseCb(LOCATION_RESPONSE_SUCCESS);
|
|
} else {
|
|
mResponseCb(LOCATION_RESPONSE_UNKOWN_FAILURE);
|
|
}
|
|
}
|
|
} else {
|
|
LOC_LOGe("LocAPIGetGnssEnergyConsumedReqMsg serializeToProtobuf failed");
|
|
}
|
|
}
|
|
}
|
|
|
|
LocationClientApiImpl *mApiImpl;
|
|
GnssEnergyConsumedCb mGnssEnergyConsumedCb;
|
|
ResponseCb mResponseCb;
|
|
};
|
|
|
|
LOC_LOGd(">>> getGnssEnergyConsumed ");
|
|
mMsgTask.sendMsg(new (nothrow)GetGnssEnergyConsumedReq(
|
|
this, gnssEnergyConsumedCallback, responseCallback));
|
|
}
|
|
|
|
void LocationClientApiImpl::updateLocationSystemInfoListener(
|
|
LocationSystemInfoCb locSystemInfoCallback,
|
|
ResponseCb responseCallback) {
|
|
|
|
struct UpdateLocationSystemInfoListenerReq : public LocMsg {
|
|
UpdateLocationSystemInfoListenerReq(LocationClientApiImpl *apiImpl,
|
|
LocationSystemInfoCb sysInfoCb,
|
|
ResponseCb responseCb) :
|
|
mApiImpl(apiImpl),
|
|
mLocSysInfoCb(sysInfoCb),
|
|
mResponseCb(responseCb) {}
|
|
|
|
virtual ~UpdateLocationSystemInfoListenerReq() {}
|
|
void proc() const {
|
|
bool needIpc = false;
|
|
LocationCallbacksMask callbackMaskCopy = mApiImpl->mCallbacksMask;
|
|
// send msg to the hal daemon if the registration changes
|
|
if ((nullptr != mLocSysInfoCb) &&
|
|
(nullptr == mApiImpl->mLocationSysInfoCb)) {
|
|
// client registers for system info, set up the bit
|
|
mApiImpl->mCallbacksMask |= E_LOC_CB_SYSTEM_INFO_BIT;
|
|
needIpc = true;
|
|
} else if ((nullptr == mLocSysInfoCb) &&
|
|
(nullptr != mApiImpl->mLocationSysInfoCb)) {
|
|
// system info is no longer needed, clear the bit
|
|
mApiImpl->mCallbacksMask &= ~E_LOC_CB_SYSTEM_INFO_BIT;
|
|
needIpc = true;
|
|
}
|
|
|
|
// save the new callback
|
|
mApiImpl->mLocationSysInfoCb = mLocSysInfoCb;
|
|
mApiImpl->mLocationSysInfoResponseCb = mResponseCb;
|
|
|
|
// inform hal daemon of updated callback only when changed
|
|
if (needIpc == true) {
|
|
if (mApiImpl->mHalRegistered) {
|
|
string pbStr;
|
|
LocAPIUpdateCallbacksReqMsg msg(mApiImpl->mSocketName,
|
|
mApiImpl->mCallbacksMask,
|
|
&mApiImpl->mPbufMsgConv);
|
|
if (msg.serializeToProtobuf(pbStr)) {
|
|
bool rc = mApiImpl->sendMessage(
|
|
reinterpret_cast<uint8_t *>((uint8_t *)pbStr.c_str()),
|
|
pbStr.size());
|
|
LOC_LOGd(">>> UpdateCallbacksReq new callBacksMask=0x%x, "
|
|
"old mask =0x%x, rc=%d",
|
|
mApiImpl->mCallbacksMask, callbackMaskCopy, rc);
|
|
if (mResponseCb) {
|
|
if (true == rc) {
|
|
mResponseCb(LOCATION_RESPONSE_SUCCESS);
|
|
} else {
|
|
mResponseCb(LOCATION_RESPONSE_UNKOWN_FAILURE);
|
|
}
|
|
}
|
|
} else {
|
|
LOC_LOGe("LocAPIUpdateCallbacksReqMsg serializeToProtobuf failed");
|
|
}
|
|
}
|
|
} else {
|
|
if (mResponseCb) {
|
|
mResponseCb(LOCATION_RESPONSE_SUCCESS);
|
|
}
|
|
LOC_LOGd("No updateCallbacks because same callback");
|
|
}
|
|
}
|
|
|
|
LocationClientApiImpl *mApiImpl;
|
|
LocationSystemInfoCb mLocSysInfoCb;
|
|
ResponseCb mResponseCb;
|
|
};
|
|
|
|
LOC_LOGd(">>> updateLocationSystemInfoListener ");
|
|
mMsgTask.sendMsg(new (nothrow)UpdateLocationSystemInfoListenerReq(
|
|
this, locSystemInfoCallback, responseCallback));
|
|
}
|
|
|
|
void LocationClientApiImpl::getSingleTerrestrialPos(
|
|
uint32_t timeoutMsec, TerrestrialTechMask techMask, float horQoS,
|
|
LocationCb terrestrialPositionCallback, ResponseCb responseCallback) {
|
|
|
|
struct GetSingleTerrestrialPosReq : public LocMsg {
|
|
GetSingleTerrestrialPosReq(LocationClientApiImpl *apiImpl,
|
|
uint32_t timeoutMsec,
|
|
TerrestrialTechMask techMask,
|
|
float horQoS,
|
|
LocationCb terrestrialPositionCallback,
|
|
ResponseCb responseCallback) :
|
|
mApiImpl(apiImpl), mTimeoutMsec(timeoutMsec), mTechMask(techMask),
|
|
mHorQoS(horQoS), mSingleTerrestrialPosCb(terrestrialPositionCallback),
|
|
mResponseCb(responseCallback) {}
|
|
|
|
virtual ~GetSingleTerrestrialPosReq() {}
|
|
void proc() const {
|
|
do {
|
|
if ((mApiImpl->mSingleTerrestrialPosCb == nullptr) &&
|
|
(mSingleTerrestrialPosCb == nullptr)) {
|
|
// pos cb can not be null if there is no pending request
|
|
if (mResponseCb) {
|
|
mResponseCb(LOCATION_RESPONSE_PARAM_INVALID);
|
|
}
|
|
break;
|
|
}
|
|
|
|
if ((mApiImpl->mSingleTerrestrialPosCb != nullptr) &&
|
|
(mSingleTerrestrialPosCb != nullptr)) {
|
|
// do not allow concurent single terrestrial position requests
|
|
if (mResponseCb) {
|
|
mResponseCb(LOCATION_RESPONSE_REQUEST_ALREADY_IN_PROGRESS);
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (!mApiImpl->mHalRegistered) {
|
|
if (mResponseCb) {
|
|
mResponseCb(LOCATION_RESPONSE_SYSTEM_NOT_READY);
|
|
}
|
|
break;
|
|
}
|
|
|
|
// save the new callback
|
|
mApiImpl->mSingleTerrestrialPosCb = mSingleTerrestrialPosCb;
|
|
mApiImpl->mSingleTerrestrialPosRespCb = mResponseCb;
|
|
|
|
// If client has cancelled the callback, we are done with processing
|
|
if (mApiImpl->mSingleTerrestrialPosCb == nullptr) {
|
|
if (mResponseCb) {
|
|
mResponseCb(LOCATION_RESPONSE_SUCCESS);
|
|
}
|
|
break;
|
|
}
|
|
|
|
string pbStr;
|
|
LocAPIGetSingleTerrestrialPosReqMsg msg(
|
|
mApiImpl->mSocketName, mTimeoutMsec, mTechMask, mHorQoS,
|
|
&mApiImpl->mPbufMsgConv);
|
|
|
|
if (msg.serializeToProtobuf(pbStr)) {
|
|
bool rc = mApiImpl->sendMessage(
|
|
reinterpret_cast<uint8_t *>((uint8_t *)pbStr.c_str()),
|
|
pbStr.size());
|
|
if (!rc && mResponseCb) {
|
|
mResponseCb(LOCATION_RESPONSE_UNKOWN_FAILURE);
|
|
}
|
|
}
|
|
} while (0);
|
|
}
|
|
|
|
LocationClientApiImpl *mApiImpl;
|
|
uint32_t mTimeoutMsec;
|
|
TerrestrialTechMask mTechMask;
|
|
float mHorQoS;
|
|
LocationCb mSingleTerrestrialPosCb;
|
|
ResponseCb mResponseCb;
|
|
};
|
|
|
|
mMsgTask.sendMsg(new (nothrow)GetSingleTerrestrialPosReq(
|
|
this, timeoutMsec, techMask, horQoS,
|
|
terrestrialPositionCallback, responseCallback));
|
|
}
|
|
|
|
/******************************************************************************
|
|
LocationClientApiImpl - LocIpc onReceive handler
|
|
******************************************************************************/
|
|
void LocationClientApiImpl::capabilitesCallback(ELocMsgID msgId, const void* msgData) {
|
|
|
|
mHalRegistered = true;
|
|
const LocAPICapabilitiesIndMsg* pCapabilitiesIndMsg =
|
|
(LocAPICapabilitiesIndMsg*)(msgData);
|
|
mCapsMask = parseCapabilitiesMask(pCapabilitiesIndMsg->capabilitiesMask);
|
|
|
|
if (mCapabilitiesCb) {
|
|
mCapabilitiesCb(mCapsMask);
|
|
}
|
|
|
|
mYearOfHw = parseYearOfHw(pCapabilitiesIndMsg->capabilitiesMask);
|
|
|
|
// send updatecallback request
|
|
if (0 != mCallbacksMask) {
|
|
string pbStr;
|
|
LocAPIUpdateCallbacksReqMsg msg(mSocketName, mCallbacksMask, &mPbufMsgConv);
|
|
if (msg.serializeToProtobuf(pbStr)) {
|
|
bool rc = sendMessage(reinterpret_cast<uint8_t *>((uint8_t *)pbStr.c_str()),
|
|
pbStr.size());
|
|
LOC_LOGd(">>> UpdateCallbacksReq callBacksMask=0x%x rc=%d", mCallbacksMask, rc);
|
|
} else {
|
|
LOC_LOGe("LocAPIUpdateCallbacksReqMsg serializeToProtobuf failed");
|
|
}
|
|
}
|
|
|
|
LOC_LOGe(">>> session id %d, cap mask 0x%" PRIx64, mSessionId, mCapsMask);
|
|
if (mSessionId != LOCATION_CLIENT_SESSION_ID_INVALID) {
|
|
// force mSessionId to invalid so startTracking will start the sesssion
|
|
// if hal deamon crashes and restarts in the middle of a session
|
|
mSessionId = LOCATION_CLIENT_SESSION_ID_INVALID;
|
|
TrackingOptions trackOption;
|
|
trackOption.setLocationOptions(mLocationOptions);
|
|
(void)startTracking(trackOption);
|
|
}
|
|
}
|
|
|
|
void LocationClientApiImpl::pingTest(PingTestCb pingTestCallback) {
|
|
|
|
mPingTestCb = pingTestCallback;
|
|
|
|
struct PingTestReq : public LocMsg {
|
|
PingTestReq(LocationClientApiImpl *apiImpl) : mApiImpl(apiImpl){}
|
|
virtual ~PingTestReq() {}
|
|
void proc() const {
|
|
string pbStr;
|
|
LocAPIPingTestReqMsg msg(mApiImpl->mSocketName, &mApiImpl->mPbufMsgConv);
|
|
if (msg.serializeToProtobuf(pbStr)) {
|
|
mApiImpl->sendMessage(
|
|
reinterpret_cast<uint8_t *>((uint8_t *)pbStr.c_str()), pbStr.size());
|
|
} else {
|
|
LOC_LOGe("LocAPIPingTestReqMsg serializeToProtobuf failed");
|
|
}
|
|
}
|
|
LocationClientApiImpl *mApiImpl;
|
|
};
|
|
mMsgTask.sendMsg(new (nothrow) PingTestReq(this));
|
|
return;
|
|
}
|
|
|
|
void LocationClientApiImpl::invokePositionSessionResponseCb(LocationResponse responseCode) {
|
|
if (mPositionSessionResponseCbPending) {
|
|
if (nullptr != mResponseCb) {
|
|
mResponseCb(responseCode);
|
|
}
|
|
mPositionSessionResponseCbPending = false;
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
LocationClientApiImpl -ILocIpcListener
|
|
******************************************************************************/
|
|
void IpcListener::onListenerReady() {
|
|
struct ClientRegisterReq : public LocMsg {
|
|
ClientRegisterReq(LocationClientApiImpl& apiImpl) : mApiImpl(apiImpl) {}
|
|
void proc() const {
|
|
string pbStr;
|
|
LocAPIClientRegisterReqMsg msg(mApiImpl.mSocketName, LOCATION_CLIENT_API,
|
|
&mApiImpl.mPbufMsgConv);
|
|
if (msg.serializeToProtobuf(pbStr)) {
|
|
mApiImpl.sendMessage(
|
|
reinterpret_cast<uint8_t *>((uint8_t *)pbStr.c_str()), pbStr.size());
|
|
} else {
|
|
LOC_LOGe("LocAPIClientRegisterReqMsg serializeToProtobuf failed");
|
|
}
|
|
}
|
|
LocationClientApiImpl& mApiImpl;
|
|
};
|
|
if (SockNode::Local == mSockTpye) {
|
|
if (0 != chown(mApiImpl.mSocketName, getuid(), GID_LOCCLIENT)) {
|
|
LOC_LOGe("chown to group locclient failed %s", strerror(errno));
|
|
}
|
|
}
|
|
mMsgTask.sendMsg(new (nothrow) ClientRegisterReq(mApiImpl));
|
|
}
|
|
|
|
void IpcListener::onReceive(const char* data, uint32_t length,
|
|
const LocIpcRecver* recver) {
|
|
struct OnReceiveHandler : public LocMsg {
|
|
OnReceiveHandler(LocationClientApiImpl& apiImpl, IpcListener& listener,
|
|
const char* data, uint32_t length) :
|
|
mApiImpl(apiImpl), mListener(listener), mMsgData(data, length) {}
|
|
|
|
virtual ~OnReceiveHandler() {}
|
|
void proc() const {
|
|
// Protobuff Encoding enabled, so we need to convert the message from proto
|
|
// encoded format to local structure
|
|
PBLocAPIMsgHeader pbLocApiMsg;
|
|
if (0 == pbLocApiMsg.ParseFromString(mMsgData)) {
|
|
LOC_LOGe("Failed to parse pbLocApiMsg from input stream!! length: %u",
|
|
mMsgData.length());
|
|
return;
|
|
}
|
|
|
|
ELocMsgID eLocMsgid = mApiImpl.mPbufMsgConv.getEnumForPBELocMsgID(pbLocApiMsg.msgid());
|
|
string sockName = pbLocApiMsg.msocketname();
|
|
uint32_t msgVer = pbLocApiMsg.msgversion();
|
|
uint32_t payloadSize = pbLocApiMsg.payloadsize();
|
|
// pbLocApiMsg.payload() contains the payload data.
|
|
|
|
LOC_LOGi(">-- onReceive Rcvd msg id: %d, sockname: %s, payload size: %d", eLocMsgid,
|
|
sockName.c_str(), payloadSize);
|
|
LocAPIMsgHeader locApiMsg(sockName.c_str(), eLocMsgid);
|
|
|
|
// throw away message that does not come from location hal daemon
|
|
if (false == locApiMsg.isValidServerMsg(payloadSize)) {
|
|
return;
|
|
}
|
|
|
|
switch (locApiMsg.msgId) {
|
|
case E_LOCAPI_CAPABILILTIES_MSG_ID:
|
|
{
|
|
LOC_LOGd("<<< capabilities indication");
|
|
PBLocAPICapabilitiesIndMsg pbLocApiCapIndMsg;
|
|
if (0 == pbLocApiCapIndMsg.ParseFromString(pbLocApiMsg.payload())) {
|
|
LOC_LOGe("Failed to parse pbLocApiCapIndMsg from payload!!");
|
|
return;
|
|
}
|
|
LocAPICapabilitiesIndMsg msg(sockName.c_str(), pbLocApiCapIndMsg,
|
|
&mApiImpl.mPbufMsgConv);
|
|
mApiImpl.capabilitesCallback(locApiMsg.msgId, (void*)&msg);
|
|
break;
|
|
}
|
|
|
|
case E_LOCAPI_HAL_READY_MSG_ID:
|
|
{
|
|
LOC_LOGd("<<< HAL ready");
|
|
|
|
// location hal deamon has restarted, need to set this
|
|
// flag to false to prevent messages to be sent to hal
|
|
// before registeration completes
|
|
mApiImpl.mHalRegistered = false;
|
|
mListener.onListenerReady();
|
|
break;
|
|
}
|
|
|
|
case E_LOCAPI_START_TRACKING_MSG_ID:
|
|
case E_LOCAPI_UPDATE_TRACKING_OPTIONS_MSG_ID:
|
|
case E_LOCAPI_STOP_TRACKING_MSG_ID:
|
|
case E_LOCAPI_START_BATCHING_MSG_ID:
|
|
case E_LOCAPI_STOP_BATCHING_MSG_ID:
|
|
case E_LOCAPI_UPDATE_BATCHING_OPTIONS_MSG_ID:
|
|
{
|
|
LOC_LOGd("<<< response message %d\n", locApiMsg.msgId);
|
|
PBLocAPIGenericRespMsg pbLocApiGenericRsp;
|
|
if (0 == pbLocApiGenericRsp.ParseFromString(pbLocApiMsg.payload())) {
|
|
LOC_LOGe("Failed to parse pbLocApiGenericRsp from payload!!");
|
|
return;
|
|
}
|
|
if (locApiMsg.msgId != E_LOCAPI_STOP_TRACKING_MSG_ID) {
|
|
LocAPIGenericRespMsg respMsg(sockName.c_str(), eLocMsgid, pbLocApiGenericRsp,
|
|
&mApiImpl.mPbufMsgConv);
|
|
LocationResponse response = parseLocationError(respMsg.err);
|
|
mApiImpl.invokePositionSessionResponseCb(response);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case E_LOCAPI_ADD_GEOFENCES_MSG_ID:
|
|
case E_LOCAPI_REMOVE_GEOFENCES_MSG_ID:
|
|
case E_LOCAPI_MODIFY_GEOFENCES_MSG_ID:
|
|
case E_LOCAPI_PAUSE_GEOFENCES_MSG_ID:
|
|
case E_LOCAPI_RESUME_GEOFENCES_MSG_ID:
|
|
{
|
|
LOC_LOGd("<<< collective response message, msgId = %d", locApiMsg.msgId);
|
|
PBLocAPICollectiveRespMsg pbLocApiCollctvRespMsg;
|
|
if (0 == pbLocApiCollctvRespMsg.ParseFromString(pbLocApiMsg.payload())) {
|
|
LOC_LOGe("Failed to parse pbLocApiCollctvRespMsg from payload!!");
|
|
return;
|
|
}
|
|
LocAPICollectiveRespMsg msg(sockName.c_str(), eLocMsgid, pbLocApiCollctvRespMsg,
|
|
&mApiImpl.mPbufMsgConv);
|
|
const LocAPICollectiveRespMsg* pRespMsg = (LocAPICollectiveRespMsg*)(&msg);
|
|
std::vector<pair<Geofence, LocationResponse>> responses{};
|
|
for (int i=0; i<pRespMsg->collectiveRes.count; ++i) {
|
|
responses.push_back(make_pair(
|
|
mApiImpl.mGeofenceMap.at(
|
|
(*(pRespMsg->collectiveRes.resp + i)).clientId),
|
|
parseLocationError(
|
|
(*(pRespMsg->collectiveRes.resp + i)).error)));
|
|
if (LOCATION_ERROR_SUCCESS !=
|
|
(*(pRespMsg->collectiveRes.resp + i)).error ||
|
|
E_LOCAPI_REMOVE_GEOFENCES_MSG_ID == locApiMsg.msgId) {
|
|
mApiImpl.eraseGeofenceMap(1, const_cast<uint32_t*>(
|
|
&((*(pRespMsg->collectiveRes.resp + i)).clientId)));
|
|
}
|
|
}
|
|
if (mApiImpl.mCollectiveResCb) {
|
|
mApiImpl.mCollectiveResCb(responses);
|
|
}
|
|
break;
|
|
}
|
|
|
|
// async indication messages
|
|
case E_LOCAPI_LOCATION_MSG_ID:
|
|
{
|
|
LOC_LOGd("<<< message = location");
|
|
PBLocAPILocationIndMsg pbLocApiLocIndMsg;
|
|
if (0 == pbLocApiLocIndMsg.ParseFromString(pbLocApiMsg.payload())) {
|
|
LOC_LOGe("Failed to parse pbLocApiLocIndMsg from payload!!");
|
|
return;
|
|
}
|
|
LocAPILocationIndMsg msg(sockName.c_str(), pbLocApiLocIndMsg,
|
|
&mApiImpl.mPbufMsgConv);
|
|
LocationCallbacksMask tempMask =
|
|
(E_LOC_CB_DISTANCE_BASED_TRACKING_BIT | E_LOC_CB_SIMPLE_LOCATION_INFO_BIT);
|
|
if ((mApiImpl.mSessionId != LOCATION_CLIENT_SESSION_ID_INVALID) &&
|
|
(mApiImpl.mCallbacksMask & tempMask)) {
|
|
const LocAPILocationIndMsg* pLocationIndMsg = (LocAPILocationIndMsg*)(&msg);
|
|
Location location = parseLocation(pLocationIndMsg->locationNotification);
|
|
if (mApiImpl.mLocationCb) {
|
|
mApiImpl.mLocationCb(location);
|
|
}
|
|
// copy location info over to gnsslocaiton so we can use existing routine
|
|
// to log the packet
|
|
GnssLocation gnssLocation = {};
|
|
gnssLocation.flags = location.flags;
|
|
gnssLocation.timestamp = location.timestamp;
|
|
gnssLocation.latitude = location.latitude;
|
|
gnssLocation.longitude = location.longitude;
|
|
gnssLocation.altitude = location.altitude;
|
|
gnssLocation.speed = location.speed;
|
|
gnssLocation.bearing = location.bearing;
|
|
gnssLocation.horizontalAccuracy = location.horizontalAccuracy;
|
|
gnssLocation.verticalAccuracy = location.verticalAccuracy;
|
|
gnssLocation.speedAccuracy = location.speedAccuracy;
|
|
gnssLocation.bearingAccuracy = location.bearingAccuracy;
|
|
gnssLocation.techMask = location.techMask;
|
|
|
|
mApiImpl.mLogger.log(gnssLocation, mApiImpl.mCapsMask);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case E_LOCAPI_BATCHING_MSG_ID:
|
|
{
|
|
LOC_LOGd("<<< message = batching");
|
|
if (mApiImpl.mCallbacksMask & E_LOC_CB_BATCHING_BIT) {
|
|
PBLocAPIBatchingIndMsg pbLocApiBatchIndMsg;
|
|
if (0 == pbLocApiBatchIndMsg.ParseFromString(pbLocApiMsg.payload())) {
|
|
LOC_LOGe("Failed to parse pbLocApiBatchIndMsg from payload!!");
|
|
return;
|
|
}
|
|
LocAPIBatchingIndMsg msg(sockName.c_str(), pbLocApiBatchIndMsg,
|
|
&mApiImpl.mPbufMsgConv);
|
|
const LocAPIBatchingIndMsg* pBatchingIndMsg =
|
|
(LocAPIBatchingIndMsg*)(&msg);
|
|
std::vector<Location> locationVector;
|
|
BatchingStatus status = BATCHING_STATUS_INACTIVE;
|
|
if (BATCHING_STATUS_POSITION_AVAILABE ==
|
|
pBatchingIndMsg->batchNotification.status) {
|
|
for (int i=0; i<pBatchingIndMsg->batchNotification.count; ++i) {
|
|
locationVector.push_back(parseLocation(
|
|
*(pBatchingIndMsg->batchNotification.location +
|
|
i)));
|
|
}
|
|
status = BATCHING_STATUS_ACTIVE;
|
|
} else if (BATCHING_STATUS_TRIP_COMPLETED ==
|
|
pBatchingIndMsg->batchNotification.status) {
|
|
mApiImpl.stopBatching(0);
|
|
status = BATCHING_STATUS_DONE;
|
|
} else {
|
|
LOC_LOGe("invalid Batching Status!");
|
|
break;
|
|
}
|
|
if (mApiImpl.mBatchingCb) {
|
|
mApiImpl.mBatchingCb(locationVector, status);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case E_LOCAPI_GEOFENCE_BREACH_MSG_ID:
|
|
{
|
|
LOC_LOGd("<<< message = geofence breach");
|
|
if (mApiImpl.mCallbacksMask & E_LOC_CB_GEOFENCE_BREACH_BIT) {
|
|
PBLocAPIGeofenceBreachIndMsg pbLocApiGfBreachIndMsg;
|
|
if (0 == pbLocApiGfBreachIndMsg.ParseFromString(pbLocApiMsg.payload())) {
|
|
LOC_LOGe("Failed to parse pbLocApiGfBreachIndMsg from payload!!");
|
|
return;
|
|
}
|
|
LocAPIGeofenceBreachIndMsg msg(sockName.c_str(), pbLocApiGfBreachIndMsg,
|
|
&mApiImpl.mPbufMsgConv);
|
|
const LocAPIGeofenceBreachIndMsg* pGfBreachIndMsg =
|
|
(LocAPIGeofenceBreachIndMsg*)(&msg);
|
|
std::vector<Geofence> geofences;
|
|
for (int i=0; i<pGfBreachIndMsg->gfBreachNotification.count;
|
|
++i) {
|
|
geofences.push_back(mApiImpl.mGeofenceMap.at(
|
|
*(pGfBreachIndMsg->gfBreachNotification.id + i)));
|
|
}
|
|
if (mApiImpl.mGfBreachCb) {
|
|
mApiImpl.mGfBreachCb(geofences,
|
|
parseLocation(
|
|
pGfBreachIndMsg->gfBreachNotification.location),
|
|
GeofenceBreachTypeMask(
|
|
pGfBreachIndMsg->gfBreachNotification.type),
|
|
pGfBreachIndMsg->gfBreachNotification.timestamp);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case E_LOCAPI_LOCATION_INFO_MSG_ID:
|
|
{
|
|
LOC_LOGd("<<< message = location info");
|
|
if ((mApiImpl.mSessionId != LOCATION_CLIENT_SESSION_ID_INVALID) &&
|
|
(mApiImpl.mCallbacksMask & E_LOC_CB_GNSS_LOCATION_INFO_BIT)) {
|
|
PBLocAPILocationInfoIndMsg pbLocApiLocInfoIndMsg;
|
|
if (0 == pbLocApiLocInfoIndMsg.ParseFromString(pbLocApiMsg.payload())) {
|
|
LOC_LOGe("Failed to parse pbLocApiLocInfoIndMsg from payload!!");
|
|
return;
|
|
}
|
|
LocAPILocationInfoIndMsg msg(sockName.c_str(), pbLocApiLocInfoIndMsg,
|
|
&mApiImpl.mPbufMsgConv);
|
|
const LocAPILocationInfoIndMsg* pLocationInfoIndMsg =
|
|
(LocAPILocationInfoIndMsg*)(&msg);
|
|
GnssLocation gnssLocation =
|
|
parseLocationInfo(pLocationInfoIndMsg->gnssLocationInfoNotification);
|
|
|
|
if (mApiImpl.mGnssLocationCb) {
|
|
mApiImpl.mGnssLocationCb(gnssLocation);
|
|
}
|
|
mApiImpl.mLogger.log(gnssLocation, mApiImpl.mCapsMask);
|
|
}
|
|
break;
|
|
}
|
|
case E_LOCAPI_ENGINE_LOCATIONS_INFO_MSG_ID:
|
|
{
|
|
LOC_LOGd("<<< message = engine location info\n");
|
|
|
|
if ((mApiImpl.mSessionId != LOCATION_CLIENT_SESSION_ID_INVALID) &&
|
|
(mApiImpl.mCallbacksMask & E_LOC_CB_ENGINE_LOCATIONS_INFO_BIT)) {
|
|
PBLocAPIEngineLocationsInfoIndMsg pbLocApiEngLocInfoIndMsg;
|
|
if (0 == pbLocApiEngLocInfoIndMsg.ParseFromString(pbLocApiMsg.payload())) {
|
|
LOC_LOGe("Failed to parse pbLocApiEngLocInfoIndMsg from payload!!");
|
|
return;
|
|
}
|
|
LocAPIEngineLocationsInfoIndMsg msg(sockName.c_str(),
|
|
pbLocApiEngLocInfoIndMsg,
|
|
&mApiImpl.mPbufMsgConv);
|
|
const LocAPIEngineLocationsInfoIndMsg* pEngLocationsInfoIndMsg =
|
|
(LocAPIEngineLocationsInfoIndMsg*)(&msg);
|
|
|
|
if (pEngLocationsInfoIndMsg->getMsgSize() != payloadSize) {
|
|
LOC_LOGw("payload size does not match for message with id: %d",
|
|
locApiMsg.msgId);
|
|
}
|
|
|
|
std::vector<GnssLocation> engLocationsVector;
|
|
for (int i=0; i< pEngLocationsInfoIndMsg->count; i++) {
|
|
GnssLocation gnssLocation =
|
|
parseLocationInfo(pEngLocationsInfoIndMsg->engineLocationsInfo[i]);
|
|
engLocationsVector.push_back(gnssLocation);
|
|
mApiImpl.mLogger.log(gnssLocation, mApiImpl.mCapsMask);
|
|
}
|
|
|
|
if (mApiImpl.mEngLocationsCb) {
|
|
mApiImpl.mEngLocationsCb(engLocationsVector);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case E_LOCAPI_SATELLITE_VEHICLE_MSG_ID:
|
|
{
|
|
LOC_LOGd("<<< message = sv");
|
|
if (mApiImpl.mCallbacksMask & E_LOC_CB_GNSS_SV_BIT) {
|
|
PBLocAPISatelliteVehicleIndMsg pbLocApiSatVehIndMsg;
|
|
if (0 == pbLocApiSatVehIndMsg.ParseFromString(pbLocApiMsg.payload())) {
|
|
LOC_LOGe("Failed to parse pbLocApiSatVehIndMsg from payload!!");
|
|
return;
|
|
}
|
|
LocAPISatelliteVehicleIndMsg msg(sockName.c_str(), pbLocApiSatVehIndMsg,
|
|
&mApiImpl.mPbufMsgConv);
|
|
const LocAPISatelliteVehicleIndMsg* pSvIndMsg =
|
|
(LocAPISatelliteVehicleIndMsg*)(&msg);
|
|
std::vector<GnssSv> gnssSvsVector;
|
|
for (int i=0; i< pSvIndMsg->gnssSvNotification.count; i++) {
|
|
GnssSv gnssSv;
|
|
gnssSv = parseGnssSv(pSvIndMsg->gnssSvNotification.gnssSvs[i]);
|
|
gnssSvsVector.push_back(gnssSv);
|
|
}
|
|
if (mApiImpl.mGnssSvCb) {
|
|
mApiImpl.mGnssSvCb(gnssSvsVector);
|
|
}
|
|
mApiImpl.mLogger.log(gnssSvsVector);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case E_LOCAPI_NMEA_MSG_ID:
|
|
{
|
|
if ((mApiImpl.mSessionId != LOCATION_CLIENT_SESSION_ID_INVALID) &&
|
|
(mApiImpl.mCallbacksMask & E_LOC_CB_GNSS_NMEA_BIT) &&
|
|
mApiImpl.mGnssNmeaCb) {
|
|
|
|
PBLocAPINmeaIndMsg pbLocApiNmeaIndMsg;
|
|
if (0 == pbLocApiNmeaIndMsg.ParseFromString(pbLocApiMsg.payload())) {
|
|
LOC_LOGe("Failed to parse pbLocApiNmeaIndMsg from payload!!");
|
|
return;
|
|
}
|
|
LocAPINmeaIndMsg msg(sockName.c_str(), pbLocApiNmeaIndMsg,
|
|
&mApiImpl.mPbufMsgConv);
|
|
// nmea is variable length, can not be checked
|
|
const LocAPINmeaIndMsg* pNmeaIndMsg = (LocAPINmeaIndMsg*)(&msg);
|
|
uint64_t timestamp = pNmeaIndMsg->gnssNmeaNotification.timestamp;
|
|
std::string nmea(pNmeaIndMsg->gnssNmeaNotification.nmea);
|
|
LOC_LOGd("<<< message = nmea[%s]", nmea.c_str());
|
|
std::stringstream ss(nmea);
|
|
std::string each;
|
|
while(std::getline(ss, each, '\n')) {
|
|
each += '\n';
|
|
mApiImpl.mGnssNmeaCb(timestamp, each);
|
|
}
|
|
mApiImpl.mLogger.log(timestamp, nmea.size(), nmea.c_str());
|
|
}
|
|
break;
|
|
}
|
|
|
|
case E_LOCAPI_DATA_MSG_ID:
|
|
{
|
|
LOC_LOGd("<<< message = data");
|
|
if ((mApiImpl.mSessionId != LOCATION_CLIENT_SESSION_ID_INVALID) &&
|
|
(mApiImpl.mCallbacksMask & E_LOC_CB_GNSS_DATA_BIT)) {
|
|
PBLocAPIDataIndMsg pbLocApiDataIndMsg;
|
|
if (0 == pbLocApiDataIndMsg.ParseFromString(pbLocApiMsg.payload())) {
|
|
LOC_LOGe("Failed to parse pbLocApiDataIndMsg from payload!!");
|
|
return;
|
|
}
|
|
LocAPIDataIndMsg msg(sockName.c_str(), pbLocApiDataIndMsg,
|
|
&mApiImpl.mPbufMsgConv);
|
|
const LocAPIDataIndMsg* pDataIndMsg = (LocAPIDataIndMsg*)(&msg);
|
|
GnssData gnssData =
|
|
parseGnssData(pDataIndMsg->gnssDataNotification);
|
|
if (mApiImpl.mGnssDataCb) {
|
|
mApiImpl.mGnssDataCb(gnssData);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case E_LOCAPI_MEAS_MSG_ID:
|
|
{
|
|
LOC_LOGd("<<< message = measurements");
|
|
if ((mApiImpl.mSessionId != LOCATION_CLIENT_SESSION_ID_INVALID) &&
|
|
(mApiImpl.mCallbacksMask & E_LOC_CB_GNSS_MEAS_BIT)) {
|
|
|
|
PBLocAPIMeasIndMsg pbLocApiMeasIndMsg;
|
|
if (0 == pbLocApiMeasIndMsg.ParseFromString(pbLocApiMsg.payload())) {
|
|
LOC_LOGe("Failed to parse pbLocApiMeasIndMsg from payload!!");
|
|
return;
|
|
}
|
|
LocAPIMeasIndMsg msg(sockName.c_str(), pbLocApiMeasIndMsg,
|
|
&mApiImpl.mPbufMsgConv);
|
|
const LocAPIMeasIndMsg* pMeasIndMsg = (LocAPIMeasIndMsg*)(&msg);
|
|
GnssMeasurements gnssMeasurements =
|
|
parseGnssMeasurements(pMeasIndMsg->gnssMeasurementsNotification);
|
|
if (mApiImpl.mGnssMeasurementsCb) {
|
|
mApiImpl.mGnssMeasurementsCb(gnssMeasurements);
|
|
}
|
|
mApiImpl.mLogger.log(gnssMeasurements);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case E_LOCAPI_GET_GNSS_ENGERY_CONSUMED_MSG_ID:
|
|
{
|
|
LOC_LOGd("<<< message = GNSS power consumption\n");
|
|
PBLocAPIGnssEnergyConsumedIndMsg pbLocApiGnssEnergyConsmdIndMsg;
|
|
if (0 == pbLocApiGnssEnergyConsmdIndMsg.ParseFromString(pbLocApiMsg.payload())) {
|
|
LOC_LOGe("Failed to parse pbLocApiGnssEnergyConsmdIndMsg from payload!!");
|
|
return;
|
|
}
|
|
LocAPIGnssEnergyConsumedIndMsg msg(sockName.c_str(),
|
|
pbLocApiGnssEnergyConsmdIndMsg,
|
|
&mApiImpl.mPbufMsgConv);
|
|
LocAPIGnssEnergyConsumedIndMsg* pEnergyMsg =
|
|
(LocAPIGnssEnergyConsumedIndMsg*) &msg;
|
|
uint64_t energyNumber = pEnergyMsg->totalGnssEnergyConsumedSinceFirstBoot;
|
|
uint32_t flags = 0;
|
|
if (energyNumber != 0xffffffffffffffff) {
|
|
flags = ENERGY_CONSUMED_SINCE_FIRST_BOOT_BIT;
|
|
}
|
|
GnssEnergyConsumedInfo energyConsumedInfo = {};
|
|
energyConsumedInfo.flags =
|
|
(location_client::GnssEnergyConsumedInfoMask) flags;
|
|
energyConsumedInfo.totalEnergyConsumedSinceFirstBoot = energyNumber;
|
|
if (flags == 0 && mApiImpl.mGnssEnergyConsumedResponseCb) {
|
|
mApiImpl.mGnssEnergyConsumedResponseCb(
|
|
LOCATION_RESPONSE_UNKOWN_FAILURE);
|
|
} else if (mApiImpl.mGnssEnergyConsumedInfoCb){
|
|
mApiImpl.mGnssEnergyConsumedInfoCb(energyConsumedInfo);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case E_LOCAPI_LOCATION_SYSTEM_INFO_MSG_ID:
|
|
{
|
|
LOC_LOGd("<<< message = location system info");
|
|
if (mApiImpl.mCallbacksMask & E_LOC_CB_SYSTEM_INFO_BIT) {
|
|
PBLocAPILocationSystemInfoIndMsg pbLocApiLocSysInfoIndMsg;
|
|
if (0 == pbLocApiLocSysInfoIndMsg.ParseFromString(pbLocApiMsg.payload())) {
|
|
LOC_LOGe("Failed to parse pbLocApiLocSysInfoIndMsg from payload!!");
|
|
return;
|
|
}
|
|
LocAPILocationSystemInfoIndMsg msg(sockName.c_str(), pbLocApiLocSysInfoIndMsg,
|
|
&mApiImpl.mPbufMsgConv);
|
|
const LocAPILocationSystemInfoIndMsg * pDataIndMsg =
|
|
(LocAPILocationSystemInfoIndMsg*)(&msg);
|
|
LocationSystemInfo locationSystemInfo =
|
|
parseLocationSystemInfo(pDataIndMsg->locationSystemInfo);
|
|
if (mApiImpl.mLocationSysInfoCb) {
|
|
mApiImpl.mLocationSysInfoCb(locationSystemInfo);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case E_LOCAPI_GET_SINGLE_TERRESTRIAL_POS_RESP_MSG_ID:
|
|
{
|
|
LOC_LOGd("<<< message = terrestrial pos info");
|
|
if (mApiImpl.mSingleTerrestrialPosCb) {
|
|
PBLocAPIGetSingleTerrestrialPosRespMsg pbMsg;
|
|
if (0 == pbMsg.ParseFromString(pbLocApiMsg.payload())) {
|
|
LOC_LOGe("Failed to parse PBLocAPIGetSingleTerrestrialPosRespMsg!!");
|
|
return;
|
|
}
|
|
|
|
LocAPIGetSingleTerrestrialPosRespMsg msg(sockName.c_str(), pbMsg,
|
|
&mApiImpl.mPbufMsgConv);
|
|
if (mApiImpl.mSingleTerrestrialPosRespCb) {
|
|
mApiImpl.mSingleTerrestrialPosRespCb(parseLocationError(msg.mErrorCode));
|
|
}
|
|
if (msg.mErrorCode == ::LOCATION_ERROR_SUCCESS) {
|
|
Location terrestialPos = parseLocation(msg.mLocation);
|
|
mApiImpl.mSingleTerrestrialPosCb(terrestialPos);
|
|
}
|
|
// clean up variable to indicate that no request is pending
|
|
mApiImpl.mSingleTerrestrialPosRespCb = nullptr;
|
|
mApiImpl.mSingleTerrestrialPosCb = nullptr;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case E_LOCAPI_PINGTEST_MSG_ID:
|
|
{
|
|
LOC_LOGd("<<< ping message %d", locApiMsg.msgId);
|
|
PBLocAPIPingTestIndMsg pbLocApiPingTestIndMsg;
|
|
if (0 == pbLocApiPingTestIndMsg.ParseFromString(pbLocApiMsg.payload())) {
|
|
LOC_LOGe("Failed to parse pbLocApiPingTestIndMsg from payload!!");
|
|
return;
|
|
}
|
|
LocAPIPingTestIndMsg msg(sockName.c_str(), pbLocApiPingTestIndMsg,
|
|
&mApiImpl.mPbufMsgConv);
|
|
const LocAPIPingTestIndMsg* pIndMsg = (LocAPIPingTestIndMsg*)(&msg);
|
|
if (mApiImpl.mPingTestCb) {
|
|
uint32_t response = pIndMsg->data[0];
|
|
mApiImpl.mPingTestCb(response);
|
|
}
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
LOC_LOGe("<<< unknown message %d\n", locApiMsg.msgId);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
LocationClientApiImpl& mApiImpl;
|
|
IpcListener& mListener;
|
|
const string mMsgData;
|
|
};
|
|
mMsgTask.sendMsg(new (nothrow) OnReceiveHandler(mApiImpl, *this, data, length));
|
|
}
|
|
|
|
/******************************************************************************
|
|
LocationClientApiImpl - Not implemented overrides
|
|
******************************************************************************/
|
|
|
|
void LocationClientApiImpl::gnssNiResponse(uint32_t id, GnssNiResponse response) {
|
|
}
|
|
|
|
void LocationClientApiImpl::updateTrackingOptions(uint32_t id, TrackingOptions& options) {
|
|
}
|
|
} // namespace location_client
|