diff options
Diffstat (limited to 'gps/core')
30 files changed, 8598 insertions, 0 deletions
diff --git a/gps/core/Android.bp b/gps/core/Android.bp new file mode 100644 index 0000000..ee8e807 --- /dev/null +++ b/gps/core/Android.bp @@ -0,0 +1,56 @@ + +cc_library_shared { + + name: "libloc_core", + vendor: true, + + sanitize: GNSS_SANITIZE, + + shared_libs: [ + "liblog", + "libutils", + "libcutils", + "libgps.utils", + "libdl", + "liblog", + ], + + srcs: [ + "LocApiBase.cpp", + "LocAdapterBase.cpp", + "ContextBase.cpp", + "LocContext.cpp", + "loc_core_log.cpp", + "data-items/DataItemsFactoryProxy.cpp", + "SystemStatusOsObserver.cpp", + "SystemStatus.cpp", + ], + + cflags: [ + "-fno-short-enums", + "-D_ANDROID_", + ] + GNSS_CFLAGS, + + local_include_dirs: [ + "data-items", + "observer", + ], + + header_libs: [ + "libutils_headers", + "libgps.utils_headers", + "libloc_pla_headers", + "liblocation_api_headers", + ], + +} + +cc_library_headers { + + name: "libloc_core_headers", + vendor: true, + export_include_dirs: ["."] + [ + "data-items", + "observer", + ], +} diff --git a/gps/core/ContextBase.cpp b/gps/core/ContextBase.cpp new file mode 100644 index 0000000..87e98dc --- /dev/null +++ b/gps/core/ContextBase.cpp @@ -0,0 +1,384 @@ +/* Copyright (c) 2011-2014,2016-2017,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_NDEBUG 0 +#define LOG_TAG "LocSvc_CtxBase" + +#include <dlfcn.h> +#include <unistd.h> +#include <ContextBase.h> +#include <msg_q.h> +#include <loc_target.h> +#include <loc_pla.h> +#include <loc_log.h> + +namespace loc_core { + +#define SLL_LOC_API_LIB_NAME "libsynergy_loc_api.so" +#define LOC_APIV2_0_LIB_NAME "libloc_api_v02.so" +#define IS_SS5_HW_ENABLED 1 + +loc_gps_cfg_s_type ContextBase::mGps_conf {}; +loc_sap_cfg_s_type ContextBase::mSap_conf {}; +bool ContextBase::sIsEngineCapabilitiesKnown = false; +uint64_t ContextBase::sSupportedMsgMask = 0; +bool ContextBase::sGnssMeasurementSupported = false; +uint8_t ContextBase::sFeaturesSupported[MAX_FEATURE_LENGTH]; +GnssNMEARptRate ContextBase::sNmeaReportRate = GNSS_NMEA_REPORT_RATE_NHZ; +LocationCapabilitiesMask ContextBase::sQwesFeatureMask = 0; + +const loc_param_s_type ContextBase::mGps_conf_table[] = +{ + {"GPS_LOCK", &mGps_conf.GPS_LOCK, NULL, 'n'}, + {"SUPL_VER", &mGps_conf.SUPL_VER, NULL, 'n'}, + {"LPP_PROFILE", &mGps_conf.LPP_PROFILE, NULL, 'n'}, + {"A_GLONASS_POS_PROTOCOL_SELECT", &mGps_conf.A_GLONASS_POS_PROTOCOL_SELECT, NULL, 'n'}, + {"LPPE_CP_TECHNOLOGY", &mGps_conf.LPPE_CP_TECHNOLOGY, NULL, 'n'}, + {"LPPE_UP_TECHNOLOGY", &mGps_conf.LPPE_UP_TECHNOLOGY, NULL, 'n'}, + {"AGPS_CERT_WRITABLE_MASK", &mGps_conf.AGPS_CERT_WRITABLE_MASK, NULL, 'n'}, + {"SUPL_MODE", &mGps_conf.SUPL_MODE, NULL, 'n'}, + {"SUPL_ES", &mGps_conf.SUPL_ES, NULL, 'n'}, + {"INTERMEDIATE_POS", &mGps_conf.INTERMEDIATE_POS, NULL, 'n'}, + {"ACCURACY_THRES", &mGps_conf.ACCURACY_THRES, NULL, 'n'}, + {"NMEA_PROVIDER", &mGps_conf.NMEA_PROVIDER, NULL, 'n'}, + {"NMEA_REPORT_RATE", &mGps_conf.NMEA_REPORT_RATE, NULL, 's'}, + {"CAPABILITIES", &mGps_conf.CAPABILITIES, NULL, 'n'}, + {"XTRA_SERVER_1", &mGps_conf.XTRA_SERVER_1, NULL, 's'}, + {"XTRA_SERVER_2", &mGps_conf.XTRA_SERVER_2, NULL, 's'}, + {"XTRA_SERVER_3", &mGps_conf.XTRA_SERVER_3, NULL, 's'}, + {"USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL", + &mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL, NULL, 'n'}, + {"AGPS_CONFIG_INJECT", &mGps_conf.AGPS_CONFIG_INJECT, NULL, 'n'}, + {"EXTERNAL_DR_ENABLED", &mGps_conf.EXTERNAL_DR_ENABLED, NULL, 'n'}, + {"SUPL_HOST", &mGps_conf.SUPL_HOST, NULL, 's'}, + {"SUPL_PORT", &mGps_conf.SUPL_PORT, NULL, 'n'}, + {"MODEM_TYPE", &mGps_conf.MODEM_TYPE, NULL, 'n' }, + {"MO_SUPL_HOST", &mGps_conf.MO_SUPL_HOST, NULL, 's' }, + {"MO_SUPL_PORT", &mGps_conf.MO_SUPL_PORT, NULL, 'n' }, + {"CONSTRAINED_TIME_UNCERTAINTY_ENABLED", + &mGps_conf.CONSTRAINED_TIME_UNCERTAINTY_ENABLED, NULL, 'n'}, + {"CONSTRAINED_TIME_UNCERTAINTY_THRESHOLD", + &mGps_conf.CONSTRAINED_TIME_UNCERTAINTY_THRESHOLD, NULL, 'f'}, + {"CONSTRAINED_TIME_UNCERTAINTY_ENERGY_BUDGET", + &mGps_conf.CONSTRAINED_TIME_UNCERTAINTY_ENERGY_BUDGET, NULL, 'n'}, + {"POSITION_ASSISTED_CLOCK_ESTIMATOR_ENABLED", + &mGps_conf.POSITION_ASSISTED_CLOCK_ESTIMATOR_ENABLED, NULL, 'n'}, + {"PROXY_APP_PACKAGE_NAME", &mGps_conf.PROXY_APP_PACKAGE_NAME, NULL, 's' }, + {"CP_MTLR_ES", &mGps_conf.CP_MTLR_ES, NULL, 'n' }, + {"GNSS_DEPLOYMENT", &mGps_conf.GNSS_DEPLOYMENT, NULL, 'n'}, + {"CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED", + &mGps_conf.CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED, NULL, 'n'}, + {"NMEA_TAG_BLOCK_GROUPING_ENABLED", &mGps_conf.NMEA_TAG_BLOCK_GROUPING_ENABLED, NULL, 'n'}, + {"NI_SUPL_DENY_ON_NFW_LOCKED", &mGps_conf.NI_SUPL_DENY_ON_NFW_LOCKED, NULL, 'n'}, + {"ENABLE_NMEA_PRINT", &mGps_conf.ENABLE_NMEA_PRINT, NULL, 'n'} +}; + +const loc_param_s_type ContextBase::mSap_conf_table[] = +{ + {"GYRO_BIAS_RANDOM_WALK", &mSap_conf.GYRO_BIAS_RANDOM_WALK, &mSap_conf.GYRO_BIAS_RANDOM_WALK_VALID, 'f'}, + {"ACCEL_RANDOM_WALK_SPECTRAL_DENSITY", &mSap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY, &mSap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'}, + {"ANGLE_RANDOM_WALK_SPECTRAL_DENSITY", &mSap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY, &mSap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'}, + {"RATE_RANDOM_WALK_SPECTRAL_DENSITY", &mSap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY, &mSap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'}, + {"VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY", &mSap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY, &mSap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'}, + {"SENSOR_ACCEL_BATCHES_PER_SEC", &mSap_conf.SENSOR_ACCEL_BATCHES_PER_SEC, NULL, 'n'}, + {"SENSOR_ACCEL_SAMPLES_PER_BATCH", &mSap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH, NULL, 'n'}, + {"SENSOR_GYRO_BATCHES_PER_SEC", &mSap_conf.SENSOR_GYRO_BATCHES_PER_SEC, NULL, 'n'}, + {"SENSOR_GYRO_SAMPLES_PER_BATCH", &mSap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH, NULL, 'n'}, + {"SENSOR_ACCEL_BATCHES_PER_SEC_HIGH", &mSap_conf.SENSOR_ACCEL_BATCHES_PER_SEC_HIGH, NULL, 'n'}, + {"SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH", &mSap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH, NULL, 'n'}, + {"SENSOR_GYRO_BATCHES_PER_SEC_HIGH", &mSap_conf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH, NULL, 'n'}, + {"SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH", &mSap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH, NULL, 'n'}, + {"SENSOR_CONTROL_MODE", &mSap_conf.SENSOR_CONTROL_MODE, NULL, 'n'}, + {"SENSOR_ALGORITHM_CONFIG_MASK", &mSap_conf.SENSOR_ALGORITHM_CONFIG_MASK, NULL, 'n'} +}; + +void ContextBase::readConfig() +{ + static bool confReadDone = false; + if (!confReadDone) { + confReadDone = true; + /*Defaults for gps.conf*/ + mGps_conf.INTERMEDIATE_POS = 0; + mGps_conf.ACCURACY_THRES = 0; + mGps_conf.NMEA_PROVIDER = 0; + mGps_conf.GPS_LOCK = GNSS_CONFIG_GPS_LOCK_MO_AND_NI; + mGps_conf.SUPL_VER = 0x10000; + mGps_conf.SUPL_MODE = 0x1; + mGps_conf.SUPL_ES = 0; + mGps_conf.CP_MTLR_ES = 0; + mGps_conf.SUPL_HOST[0] = 0; + mGps_conf.SUPL_PORT = 0; + mGps_conf.CAPABILITIES = 0x7; + /* LTE Positioning Profile configuration is disable by default*/ + mGps_conf.LPP_PROFILE = 0; + /*By default no positioning protocol is selected on A-GLONASS system*/ + mGps_conf.A_GLONASS_POS_PROTOCOL_SELECT = 0; + /*Use emergency PDN by default*/ + mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL = 1; + /* By default no LPPe CP technology is enabled*/ + mGps_conf.LPPE_CP_TECHNOLOGY = 0; + /* By default no LPPe UP technology is enabled*/ + mGps_conf.LPPE_UP_TECHNOLOGY = 0; + /* By default we use unknown modem type*/ + mGps_conf.MODEM_TYPE = 2; + + /*Defaults for sap.conf*/ + mSap_conf.GYRO_BIAS_RANDOM_WALK = 0; + mSap_conf.SENSOR_ACCEL_BATCHES_PER_SEC = 2; + mSap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH = 5; + mSap_conf.SENSOR_GYRO_BATCHES_PER_SEC = 2; + mSap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH = 5; + mSap_conf.SENSOR_ACCEL_BATCHES_PER_SEC_HIGH = 4; + mSap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH = 25; + mSap_conf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH = 4; + mSap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH = 25; + mSap_conf.SENSOR_CONTROL_MODE = 0; /* AUTO */ + mSap_conf.SENSOR_ALGORITHM_CONFIG_MASK = 0; /* INS Disabled = FALSE*/ + /* Values MUST be set by OEMs in configuration for sensor-assisted + navigation to work. There are NO default values */ + mSap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY = 0; + mSap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY = 0; + mSap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY = 0; + mSap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY = 0; + mSap_conf.GYRO_BIAS_RANDOM_WALK_VALID = 0; + mSap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0; + mSap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0; + mSap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0; + mSap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0; + + /* None of the 10 slots for agps certificates are writable by default */ + mGps_conf.AGPS_CERT_WRITABLE_MASK = 0; + + /* inject supl config to modem with config values from config.xml or gps.conf, default 1 */ + mGps_conf.AGPS_CONFIG_INJECT = 1; + + /* default configuration value of constrained time uncertainty mode: + feature disabled, time uncertainty threshold defined by modem, + and unlimited power budget */ +#ifdef FEATURE_AUTOMOTIVE + mGps_conf.CONSTRAINED_TIME_UNCERTAINTY_ENABLED = 1; +#else + mGps_conf.CONSTRAINED_TIME_UNCERTAINTY_ENABLED = 0; +#endif + mGps_conf.CONSTRAINED_TIME_UNCERTAINTY_THRESHOLD = 0.0; + mGps_conf.CONSTRAINED_TIME_UNCERTAINTY_ENERGY_BUDGET = 0; + + /* default configuration value of position assisted clock estimator mode */ + mGps_conf.POSITION_ASSISTED_CLOCK_ESTIMATOR_ENABLED = 0; + /* default configuration QTI GNSS H/W */ + mGps_conf.GNSS_DEPLOYMENT = 0; + mGps_conf.CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED = 0; + /* default NMEA Tag Block Grouping is disabled */ + mGps_conf.NMEA_TAG_BLOCK_GROUPING_ENABLED = 0; + /* default configuration for NI_SUPL_DENY_ON_NFW_LOCKED */ + mGps_conf.NI_SUPL_DENY_ON_NFW_LOCKED = 1; + /* By default NMEA Printing is disabled */ + mGps_conf.ENABLE_NMEA_PRINT = 0; + + UTIL_READ_CONF(LOC_PATH_GPS_CONF, mGps_conf_table); + UTIL_READ_CONF(LOC_PATH_SAP_CONF, mSap_conf_table); + + if (strncmp(mGps_conf.NMEA_REPORT_RATE, "1HZ", sizeof(mGps_conf.NMEA_REPORT_RATE)) == 0) { + /* NMEA reporting is configured at 1Hz*/ + sNmeaReportRate = GNSS_NMEA_REPORT_RATE_1HZ; + } else { + sNmeaReportRate = GNSS_NMEA_REPORT_RATE_NHZ; + } + LOC_LOGI("%s] GNSS Deployment: %s", __FUNCTION__, + ((mGps_conf.GNSS_DEPLOYMENT == 1) ? "SS5" : + ((mGps_conf.GNSS_DEPLOYMENT == 2) ? "QFUSION" : "QGNSS"))); + + switch (getTargetGnssType(loc_get_target())) { + case GNSS_GSS: + case GNSS_AUTO: + // For APQ targets, MSA/MSB capabilities should be reset + mGps_conf.CAPABILITIES &= ~(LOC_GPS_CAPABILITY_MSA | LOC_GPS_CAPABILITY_MSB); + break; + default: + break; + } + } +} + +uint32_t ContextBase::getCarrierCapabilities() { + #define carrierMSA (uint32_t)0x2 + #define carrierMSB (uint32_t)0x1 + #define gpsConfMSA (uint32_t)0x4 + #define gpsConfMSB (uint32_t)0x2 + uint32_t capabilities = mGps_conf.CAPABILITIES; + if ((mGps_conf.SUPL_MODE & carrierMSA) != carrierMSA) { + capabilities &= ~gpsConfMSA; + } + if ((mGps_conf.SUPL_MODE & carrierMSB) != carrierMSB) { + capabilities &= ~gpsConfMSB; + } + + LOC_LOGV("getCarrierCapabilities: CAPABILITIES %x, SUPL_MODE %x, carrier capabilities %x", + mGps_conf.CAPABILITIES, mGps_conf.SUPL_MODE, capabilities); + return capabilities; +} + +LBSProxyBase* ContextBase::getLBSProxy(const char* libName) +{ + LBSProxyBase* proxy = NULL; + LOC_LOGD("%s:%d]: getLBSProxy libname: %s\n", __func__, __LINE__, libName); + void* lib = dlopen(libName, RTLD_NOW); + + if ((void*)NULL != lib) { + getLBSProxy_t* getter = (getLBSProxy_t*)dlsym(lib, "getLBSProxy"); + if (NULL != getter) { + proxy = (*getter)(); + } + } + else + { + LOC_LOGW("%s:%d]: FAILED TO LOAD libname: %s\n", __func__, __LINE__, libName); + } + if (NULL == proxy) { + proxy = new LBSProxyBase(); + } + LOC_LOGD("%s:%d]: Exiting\n", __func__, __LINE__); + return proxy; +} + +LocApiBase* ContextBase::createLocApi(LOC_API_ADAPTER_EVENT_MASK_T exMask) +{ + LocApiBase* locApi = NULL; + const char* libname = LOC_APIV2_0_LIB_NAME; + + // Check the target + if (TARGET_NO_GNSS != loc_get_target()){ + + if (NULL == (locApi = mLBSProxy->getLocApi(exMask, this))) { + void *handle = NULL; + + if (IS_SS5_HW_ENABLED == mGps_conf.GNSS_DEPLOYMENT) { + libname = SLL_LOC_API_LIB_NAME; + } + + if ((handle = dlopen(libname, RTLD_NOW)) != NULL) { + LOC_LOGD("%s:%d]: %s is present", __func__, __LINE__, libname); + getLocApi_t* getter = (getLocApi_t*) dlsym(handle, "getLocApi"); + if (getter != NULL) { + LOC_LOGD("%s:%d]: getter is not NULL of %s", __func__, + __LINE__, libname); + locApi = (*getter)(exMask, this); + } + } + // only RPC is the option now + else { + LOC_LOGD("%s:%d]: libloc_api_v02.so is NOT present. Trying RPC", + __func__, __LINE__); + handle = dlopen("libloc_api-rpc-qc.so", RTLD_NOW); + if (NULL != handle) { + getLocApi_t* getter = (getLocApi_t*) dlsym(handle, "getLocApi"); + if (NULL != getter) { + LOC_LOGD("%s:%d]: getter is not NULL in RPC", __func__, + __LINE__); + locApi = (*getter)(exMask, this); + } + } + } + } + } + + // locApi could still be NULL at this time + // we would then create a dummy one + if (NULL == locApi) { + locApi = new LocApiBase(exMask, this); + } + + return locApi; +} + +ContextBase::ContextBase(const MsgTask* msgTask, + LOC_API_ADAPTER_EVENT_MASK_T exMask, + const char* libName) : + mLBSProxy(getLBSProxy(libName)), + mMsgTask(msgTask), + mLocApi(createLocApi(exMask)), + mLocApiProxy(mLocApi->getLocApiProxy()) +{ +} + +void ContextBase::setEngineCapabilities(uint64_t supportedMsgMask, + uint8_t *featureList, bool gnssMeasurementSupported) { + + if (ContextBase::sIsEngineCapabilitiesKnown == false) { + ContextBase::sSupportedMsgMask = supportedMsgMask; + ContextBase::sGnssMeasurementSupported = gnssMeasurementSupported; + if (featureList != NULL) { + memcpy((void *)ContextBase::sFeaturesSupported, + (void *)featureList, sizeof(ContextBase::sFeaturesSupported)); + } + + /* */ + if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_MEASUREMENTS_CORRECTION)) { + static uint8_t isSapModeKnown = 0; + + if (!isSapModeKnown) { + /* Check if SAP is PREMIUM_ENV_AIDING in izat.conf */ + char conf_feature_sap[LOC_MAX_PARAM_STRING]; + loc_param_s_type izat_conf_feature_table[] = + { + { "SAP", &conf_feature_sap, &isSapModeKnown, 's' } + }; + UTIL_READ_CONF(LOC_PATH_IZAT_CONF, izat_conf_feature_table); + + /* Disable this feature if SAP is not PREMIUM_ENV_AIDING in izat.conf */ + if (strcmp(conf_feature_sap, "PREMIUM_ENV_AIDING") != 0) { + uint8_t arrayIndex = LOC_SUPPORTED_FEATURE_MEASUREMENTS_CORRECTION >> 3; + uint8_t bitPos = LOC_SUPPORTED_FEATURE_MEASUREMENTS_CORRECTION & 7; + + if (arrayIndex < MAX_FEATURE_LENGTH) { + /* To disable the feature we need to reset the bit on the "bitPos" + position, so shift a "1" to the left by "bitPos" */ + ContextBase::sFeaturesSupported[arrayIndex] &= ~(1 << bitPos); + } + } + } + } + ContextBase::sIsEngineCapabilitiesKnown = true; + } +} + + +bool ContextBase::isFeatureSupported(uint8_t featureVal) +{ + uint8_t arrayIndex = featureVal >> 3; + uint8_t bitPos = featureVal & 7; + + if (arrayIndex >= MAX_FEATURE_LENGTH) return false; + return ((ContextBase::sFeaturesSupported[arrayIndex] >> bitPos ) & 0x1); +} + +bool ContextBase::gnssConstellationConfig() { + return sGnssMeasurementSupported; +} + +} diff --git a/gps/core/ContextBase.h b/gps/core/ContextBase.h new file mode 100644 index 0000000..34cad60 --- /dev/null +++ b/gps/core/ContextBase.h @@ -0,0 +1,385 @@ +/* Copyright (c) 2011-2017, 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. + * + */ +#ifndef __LOC_CONTEXT_BASE__ +#define __LOC_CONTEXT_BASE__ + +#include <stdbool.h> +#include <ctype.h> +#include <MsgTask.h> +#include <LocApiBase.h> +#include <LBSProxyBase.h> +#include <loc_cfg.h> +#ifdef NO_UNORDERED_SET_OR_MAP + #include <map> +#else + #include <unordered_map> +#endif + +/* GPS.conf support */ +/* NOTE: the implementaiton of the parser casts number + fields to 32 bit. To ensure all 'n' fields working, + they must all be 32 bit fields. */ +typedef struct loc_gps_cfg_s +{ + uint32_t INTERMEDIATE_POS; + uint32_t ACCURACY_THRES; + uint32_t SUPL_VER; + uint32_t SUPL_MODE; + uint32_t SUPL_ES; + uint32_t CAPABILITIES; + uint32_t LPP_PROFILE; + char XTRA_SERVER_1[LOC_MAX_PARAM_STRING]; + char XTRA_SERVER_2[LOC_MAX_PARAM_STRING]; + char XTRA_SERVER_3[LOC_MAX_PARAM_STRING]; + uint32_t USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL; + uint32_t NMEA_PROVIDER; + char NMEA_REPORT_RATE[LOC_MAX_PARAM_NAME]; + GnssConfigGpsLock GPS_LOCK; + uint32_t A_GLONASS_POS_PROTOCOL_SELECT; + uint32_t AGPS_CERT_WRITABLE_MASK; + uint32_t AGPS_CONFIG_INJECT; + uint32_t LPPE_CP_TECHNOLOGY; + uint32_t LPPE_UP_TECHNOLOGY; + uint32_t EXTERNAL_DR_ENABLED; + char SUPL_HOST[LOC_MAX_PARAM_STRING]; + uint32_t SUPL_PORT; + uint32_t MODEM_TYPE; + char MO_SUPL_HOST[LOC_MAX_PARAM_STRING]; + uint32_t MO_SUPL_PORT; + uint32_t CONSTRAINED_TIME_UNCERTAINTY_ENABLED; + double CONSTRAINED_TIME_UNCERTAINTY_THRESHOLD; + uint32_t CONSTRAINED_TIME_UNCERTAINTY_ENERGY_BUDGET; + uint32_t POSITION_ASSISTED_CLOCK_ESTIMATOR_ENABLED; + char PROXY_APP_PACKAGE_NAME[LOC_MAX_PARAM_STRING]; + uint32_t CP_MTLR_ES; + uint32_t GNSS_DEPLOYMENT; + uint32_t CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED; + uint32_t NI_SUPL_DENY_ON_NFW_LOCKED; + uint32_t ENABLE_NMEA_PRINT; + uint32_t NMEA_TAG_BLOCK_GROUPING_ENABLED; +} loc_gps_cfg_s_type; + +/* NOTE: the implementation of the parser casts number + fields to 32 bit. To ensure all 'n' fields working, + they must all be 32 bit fields. */ +/* Meanwhile, *_valid fields are 8 bit fields, and 'f' + fields are double. Rigid as they are, it is the + the status quo, until the parsing mechanism is + changed, that is. */ +typedef struct +{ + uint8_t GYRO_BIAS_RANDOM_WALK_VALID; + double GYRO_BIAS_RANDOM_WALK; + uint32_t SENSOR_ACCEL_BATCHES_PER_SEC; + uint32_t SENSOR_ACCEL_SAMPLES_PER_BATCH; + uint32_t SENSOR_GYRO_BATCHES_PER_SEC; + uint32_t SENSOR_GYRO_SAMPLES_PER_BATCH; + uint32_t SENSOR_ACCEL_BATCHES_PER_SEC_HIGH; + uint32_t SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH; + uint32_t SENSOR_GYRO_BATCHES_PER_SEC_HIGH; + uint32_t SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH; + uint32_t SENSOR_CONTROL_MODE; + uint32_t SENSOR_ALGORITHM_CONFIG_MASK; + uint8_t ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID; + double ACCEL_RANDOM_WALK_SPECTRAL_DENSITY; + uint8_t ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID; + double ANGLE_RANDOM_WALK_SPECTRAL_DENSITY; + uint8_t RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID; + double RATE_RANDOM_WALK_SPECTRAL_DENSITY; + uint8_t VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID; + double VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY; +} loc_sap_cfg_s_type; + +using namespace loc_util; + +namespace loc_core { + +class LocAdapterBase; + +class ContextBase { + static LBSProxyBase* getLBSProxy(const char* libName); + LocApiBase* createLocApi(LOC_API_ADAPTER_EVENT_MASK_T excludedMask); + static const loc_param_s_type mGps_conf_table[]; + static const loc_param_s_type mSap_conf_table[]; +protected: + const LBSProxyBase* mLBSProxy; + const MsgTask* mMsgTask; + LocApiBase* mLocApi; + LocApiProxyBase *mLocApiProxy; + +public: + ContextBase(const MsgTask* msgTask, + LOC_API_ADAPTER_EVENT_MASK_T exMask, + const char* libName); + inline virtual ~ContextBase() { + if (nullptr != mLocApi) { + mLocApi->destroy(); + mLocApi = nullptr; + } + if (nullptr != mLBSProxy) { + delete mLBSProxy; + mLBSProxy = nullptr; + } + } + + inline const MsgTask* getMsgTask() { return mMsgTask; } + inline LocApiBase* getLocApi() { return mLocApi; } + inline LocApiProxyBase* getLocApiProxy() { return mLocApiProxy; } + inline bool hasAgpsExtendedCapabilities() { return mLBSProxy->hasAgpsExtendedCapabilities(); } + inline bool hasNativeXtraClient() { return mLBSProxy->hasNativeXtraClient(); } + inline void modemPowerVote(bool power) const { return mLBSProxy->modemPowerVote(power); } + inline IzatDevId_t getIzatDevId() const { + return mLBSProxy->getIzatDevId(); + } + inline void sendMsg(const LocMsg *msg) { getMsgTask()->sendMsg(msg); } + + static loc_gps_cfg_s_type mGps_conf; + static loc_sap_cfg_s_type mSap_conf; + static bool sIsEngineCapabilitiesKnown; + static uint64_t sSupportedMsgMask; + static uint8_t sFeaturesSupported[MAX_FEATURE_LENGTH]; + static bool sGnssMeasurementSupported; + static GnssNMEARptRate sNmeaReportRate; + static LocationCapabilitiesMask sQwesFeatureMask; + + void readConfig(); + static uint32_t getCarrierCapabilities(); + void setEngineCapabilities(uint64_t supportedMsgMask, + uint8_t *featureList, bool gnssMeasurementSupported); + + static inline bool isEngineCapabilitiesKnown() { + return sIsEngineCapabilitiesKnown; + } + + static inline bool isMessageSupported(LocCheckingMessagesID msgID) { + + // confirm if msgID is not larger than the number of bits in + // mSupportedMsg + if ((uint64_t)msgID > (sizeof(sSupportedMsgMask) << 3)) { + return false; + } else { + uint32_t messageChecker = 1 << msgID; + return (messageChecker & sSupportedMsgMask) == messageChecker; + } + } + + /* + Check if a feature is supported + */ + static bool isFeatureSupported(uint8_t featureVal); + + /* + Check if gnss measurement is supported + */ + static bool gnssConstellationConfig(); + + /* + set QWES feature status info + */ + static inline void setQwesFeatureStatus( + const std::unordered_map<LocationQwesFeatureType, bool> &featureMap) { + std::unordered_map<LocationQwesFeatureType, bool>::const_iterator itr; + static LocationQwesFeatureType locQwesFeatType[LOCATION_QWES_FEATURE_TYPE_MAX]; + for (itr = featureMap.begin(); itr != featureMap.end(); ++itr) { + LOC_LOGi("Feature : %d isValid: %d", itr->first, itr->second); + locQwesFeatType[itr->first] = itr->second; + switch (itr->first) { + case LOCATION_QWES_FEATURE_TYPE_CARRIER_PHASE: + if (itr->second) { + sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_CARRIER_PHASE_BIT; + } else { + sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_CARRIER_PHASE_BIT; + } + break; + case LOCATION_QWES_FEATURE_TYPE_SV_POLYNOMIAL: + if (itr->second) { + sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_SV_POLYNOMIAL_BIT; + } else { + sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_SV_POLYNOMIAL_BIT; + } + break; + case LOCATION_QWES_FEATURE_TYPE_GNSS_SINGLE_FREQUENCY: + if (itr->second) { + sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_GNSS_SINGLE_FREQUENCY; + } else { + sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_GNSS_SINGLE_FREQUENCY; + } + break; + case LOCATION_QWES_FEATURE_TYPE_SV_EPH: + if (itr->second) { + sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_SV_EPHEMERIS_BIT; + } else { + sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_SV_EPHEMERIS_BIT; + } + break; + case LOCATION_QWES_FEATURE_TYPE_GNSS_MULTI_FREQUENCY: + if (itr->second) { + sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_GNSS_MULTI_FREQUENCY; + } else { + sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_GNSS_MULTI_FREQUENCY; + } + break; + case LOCATION_QWES_FEATURE_TYPE_PPE: + if (itr->second) { + sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_PPE; + } else { + sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_PPE; + } + break; + case LOCATION_QWES_FEATURE_TYPE_QDR2: + if (itr->second) { + sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_QDR2; + } else { + sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_QDR2; + } + break; + case LOCATION_QWES_FEATURE_TYPE_QDR3: + if (itr->second) { + sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_QDR3; + } else { + sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_QDR3; + } + break; + case LOCATION_QWES_FEATURE_TYPE_VPE: + if (itr->second) { + sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_VPE; + } else { + sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_VPE; + } + break; + } + } + + // Set CV2X basic when time freq and tunc is set + // CV2X_BASIC = LOCATION_QWES_FEATURE_TYPE_TIME_FREQUENCY & + // LOCATION_QWES_FEATURE_TYPE_TIME_UNCERTAINTY + + // Set CV2X premium when time freq and tunc is set + // CV2X_PREMIUM = CV2X_BASIC & LOCATION_QWES_FEATURE_TYPE_QDR3 & + // LOCATION_QWES_FEATURE_TYPE_CLOCK_ESTIMATE + + bool cv2xBasicEnabled = (1 == locQwesFeatType[LOCATION_QWES_FEATURE_TYPE_TIME_FREQUENCY]) && + (1 == locQwesFeatType[LOCATION_QWES_FEATURE_TYPE_TIME_UNCERTAINTY]); + bool cv2xPremiumEnabled = cv2xBasicEnabled && + (1 == locQwesFeatType[LOCATION_QWES_FEATURE_TYPE_QDR3]) && + (1 == locQwesFeatType[LOCATION_QWES_FEATURE_TYPE_CLOCK_ESTIMATE]); + + LOC_LOGd("CV2X_BASIC:%d, CV2X_PREMIUM:%d", cv2xBasicEnabled, cv2xPremiumEnabled); + if (cv2xBasicEnabled) { + sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_BASIC; + } else { + sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_BASIC; + } + if (cv2xPremiumEnabled) { + sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_PREMIUM; + } else { + sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_PREMIUM; + } + } + + /* + get QWES feature status info + */ + static inline LocationCapabilitiesMask getQwesFeatureStatus() { + return (ContextBase::sQwesFeatureMask); + } + + +}; + +struct LocApiResponse: LocMsg { + private: + ContextBase& mContext; + std::function<void (LocationError err)> mProcImpl; + inline virtual void proc() const { + mProcImpl(mLocationError); + } + protected: + LocationError mLocationError; + public: + inline LocApiResponse(ContextBase& context, + std::function<void (LocationError err)> procImpl ) : + mContext(context), mProcImpl(procImpl) {} + + void returnToSender(const LocationError err) { + mLocationError = err; + mContext.sendMsg(this); + } +}; + +struct LocApiCollectiveResponse: LocMsg { + private: + ContextBase& mContext; + std::function<void (std::vector<LocationError> errs)> mProcImpl; + inline virtual void proc() const { + mProcImpl(mLocationErrors); + } + protected: + std::vector<LocationError> mLocationErrors; + public: + inline LocApiCollectiveResponse(ContextBase& context, + std::function<void (std::vector<LocationError> errs)> procImpl ) : + mContext(context), mProcImpl(procImpl) {} + inline virtual ~LocApiCollectiveResponse() { + } + + void returnToSender(std::vector<LocationError>& errs) { + mLocationErrors = errs; + mContext.sendMsg(this); + } +}; + + +template <typename DATA> +struct LocApiResponseData: LocMsg { + private: + ContextBase& mContext; + std::function<void (LocationError err, DATA data)> mProcImpl; + inline virtual void proc() const { + mProcImpl(mLocationError, mData); + } + protected: + LocationError mLocationError; + DATA mData; + public: + inline LocApiResponseData(ContextBase& context, + std::function<void (LocationError err, DATA data)> procImpl ) : + mContext(context), mProcImpl(procImpl) {} + + void returnToSender(const LocationError err, const DATA data) { + mLocationError = err; + mData = data; + mContext.sendMsg(this); + } +}; + + +} // namespace loc_core + +#endif //__LOC_CONTEXT_BASE__ diff --git a/gps/core/EngineHubProxyBase.h b/gps/core/EngineHubProxyBase.h new file mode 100644 index 0000000..468a8f0 --- /dev/null +++ b/gps/core/EngineHubProxyBase.h @@ -0,0 +1,160 @@ +/* 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. + * + */ +#ifndef ENGINE_HUB_PROXY_BASE_H +#define ENGINE_HUB_PROXY_BASE_H +#ifdef NO_UNORDERED_SET_OR_MAP + #include <map> +#else + #include <unordered_map> +#endif + +namespace loc_core { + +using namespace loc_util; + +class EngineHubProxyBase { +public: + inline EngineHubProxyBase() { + } + inline virtual ~EngineHubProxyBase() {} + + // gnss session related functions + inline virtual bool gnssStartFix() { + return false; + } + + inline virtual bool gnssStopFix() { + return false; + } + + inline virtual bool gnssSetFixMode(const LocPosMode ¶ms) { + (void) params; + return false; + } + + inline virtual bool gnssDeleteAidingData(const GnssAidingData &aidingData) { + (void) aidingData; + return false; + } + + // GNSS reports + inline virtual bool gnssReportPosition(const UlpLocation &location, + const GpsLocationExtended &locationExtended, + enum loc_sess_status status) { + (void) location; + (void) locationExtended; + (void) status; + return false; + } + + inline virtual bool gnssReportSv(const GnssSvNotification& svNotify) { + (void) svNotify; + return false; + } + + inline virtual bool gnssReportSvMeasurement(const GnssSvMeasurementSet& svMeasurementSet) { + (void) svMeasurementSet; + return false; + } + + inline virtual bool gnssReportSvPolynomial(const GnssSvPolynomial& svPolynomial) { + (void) svPolynomial; + return false; + } + + inline virtual bool gnssReportSvEphemeris(const GnssSvEphemerisReport& svEphemeris) { + (void) svEphemeris; + return false; + } + + inline virtual bool gnssReportSystemInfo(const LocationSystemInfo& systemInfo) { + (void) systemInfo; + return false; + } + + inline virtual bool gnssReportKlobucharIonoModel(const GnssKlobucharIonoModel& ionoModel) { + (void) ionoModel; + return false; + } + + inline virtual bool gnssReportAdditionalSystemInfo( + const GnssAdditionalSystemInfo& additionalSystemInfo) { + (void) additionalSystemInfo; + return false; + } + + inline virtual bool configLeverArm(const LeverArmConfigInfo& configInfo) { + (void) configInfo; + return false; + } + + inline virtual bool configDeadReckoningEngineParams( + const DeadReckoningEngineConfig& dreConfig) { + (void) dreConfig; + return false; + } + + inline virtual bool configEngineRunState( + PositioningEngineMask engType, LocEngineRunState engState) { + (void) engType; + (void) engState; + return false; + } +}; + +typedef std::function<void(int count, EngineLocationInfo* locationArr)> + GnssAdapterReportEnginePositionsEventCb; + +typedef std::function<void(const GnssSvNotification& svNotify, + bool fromEngineHub)> + GnssAdapterReportSvEventCb; + +typedef std::function<void(const GnssAidingDataSvMask& svDataMask)> + GnssAdapterReqAidingDataCb; + +typedef std::function<void(bool nHzNeeded, bool nHzMeasNeeded)> + GnssAdapterUpdateNHzRequirementCb; + +typedef std::function<void(const std::unordered_map<LocationQwesFeatureType, bool> &featureMap)> + GnssAdapterUpdateQwesFeatureStatusCb; + +// potential parameters: message queue: MsgTask * msgTask; +// callback function to report back dr and ppe position and sv report +typedef EngineHubProxyBase* (getEngHubProxyFn)( + const MsgTask * msgTask, + IOsObserver* osObserver, + GnssAdapterReportEnginePositionsEventCb positionEventCb, + GnssAdapterReportSvEventCb svEventCb, + GnssAdapterReqAidingDataCb reqAidingDataCb, + GnssAdapterUpdateNHzRequirementCb updateNHzRequirementCb, + GnssAdapterUpdateQwesFeatureStatusCb updateQwesFeatureStatusCb); + +} // namespace loc_core + +#endif // ENGINE_HUB_PROXY_BASE_H diff --git a/gps/core/LBSProxyBase.h b/gps/core/LBSProxyBase.h new file mode 100644 index 0000000..564c60b --- /dev/null +++ b/gps/core/LBSProxyBase.h @@ -0,0 +1,70 @@ +/* Copyright (c) 2013-2015, 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. + * + */ +#ifndef IZAT_PROXY_BASE_H +#define IZAT_PROXY_BASE_H +#include <gps_extended.h> + +namespace loc_core { + +class LocApiBase; +class LocAdapterBase; +class ContextBase; + +class LBSProxyBase { + friend class ContextBase; + inline virtual LocApiBase* + getLocApi(LOC_API_ADAPTER_EVENT_MASK_T exMask, + ContextBase* context) const { + + (void)exMask; + (void)context; + return NULL; + } +protected: + inline LBSProxyBase() {} +public: + inline virtual ~LBSProxyBase() {} + inline virtual bool hasAgpsExtendedCapabilities() const { return false; } + inline virtual void modemPowerVote(bool power) const { + + (void)power; + } + virtual void injectFeatureConfig(ContextBase* context) const { + + (void)context; + } + inline virtual bool hasNativeXtraClient() const { return false; } + inline virtual IzatDevId_t getIzatDevId() const { return 0; } +}; + +typedef LBSProxyBase* (getLBSProxy_t)(); + +} // namespace loc_core + +#endif // IZAT_PROXY_BASE_H diff --git a/gps/core/LocAdapterBase.cpp b/gps/core/LocAdapterBase.cpp new file mode 100644 index 0000000..95f2728 --- /dev/null +++ b/gps/core/LocAdapterBase.cpp @@ -0,0 +1,439 @@ +/* Copyright (c) 2011-2014, 2016-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_NDEBUG 0 +#define LOG_TAG "LocSvc_LocAdapterBase" + +#include <dlfcn.h> +#include <LocAdapterBase.h> +#include <loc_target.h> +#include <log_util.h> +#include <LocAdapterProxyBase.h> + +namespace loc_core { + +// This is the top level class, so the constructor will +// always gets called. Here we prepare for the default. +// But if getLocApi(targetEnumType target) is overriden, +// the right locApi should get created. +LocAdapterBase::LocAdapterBase(const LOC_API_ADAPTER_EVENT_MASK_T mask, + ContextBase* context, bool isMaster, + LocAdapterProxyBase *adapterProxyBase, + bool waitForDoneInit) : + mIsMaster(isMaster), mEvtMask(mask), mContext(context), + mLocApi(context->getLocApi()), mLocAdapterProxyBase(adapterProxyBase), + mMsgTask(context->getMsgTask()), + mIsEngineCapabilitiesKnown(ContextBase::sIsEngineCapabilitiesKnown) +{ + LOC_LOGd("waitForDoneInit: %d", waitForDoneInit); + if (!waitForDoneInit) { + mLocApi->addAdapter(this); + mAdapterAdded = true; + } else { + mAdapterAdded = false; + } +} + +uint32_t LocAdapterBase::mSessionIdCounter(1); + +uint32_t LocAdapterBase::generateSessionId() +{ + if (++mSessionIdCounter == 0xFFFFFFFF) + mSessionIdCounter = 1; + + return mSessionIdCounter; +} + +void LocAdapterBase::handleEngineUpEvent() +{ + if (mLocAdapterProxyBase) { + mLocAdapterProxyBase->handleEngineUpEvent(); + } +} + +void LocAdapterBase::handleEngineDownEvent() +{ + if (mLocAdapterProxyBase) { + mLocAdapterProxyBase->handleEngineDownEvent(); + } +} + +void LocAdapterBase:: + reportPositionEvent(const UlpLocation& location, + const GpsLocationExtended& locationExtended, + enum loc_sess_status status, + LocPosTechMask loc_technology_mask, + GnssDataNotification* pDataNotify, + int msInWeek) +{ + if (mLocAdapterProxyBase != NULL) { + mLocAdapterProxyBase->reportPositionEvent((UlpLocation&)location, + (GpsLocationExtended&)locationExtended, + status, + loc_technology_mask); + } else { + DEFAULT_IMPL() + } +} + +void LocAdapterBase:: + reportSvEvent(const GnssSvNotification& /*svNotify*/, + bool /*fromEngineHub*/) +DEFAULT_IMPL() + +void LocAdapterBase:: + reportSvPolynomialEvent(GnssSvPolynomial &/*svPolynomial*/) +DEFAULT_IMPL() + +void LocAdapterBase:: + reportSvEphemerisEvent(GnssSvEphemerisReport &/*svEphemeris*/) +DEFAULT_IMPL() + + +void LocAdapterBase:: + reportStatus(LocGpsStatusValue /*status*/) +DEFAULT_IMPL() + + +void LocAdapterBase:: + reportNmeaEvent(const char* /*nmea*/, size_t /*length*/) +DEFAULT_IMPL() + +void LocAdapterBase:: + reportDataEvent(const GnssDataNotification& /*dataNotify*/, + int /*msInWeek*/) +DEFAULT_IMPL() + +bool LocAdapterBase:: + reportXtraServer(const char* /*url1*/, const char* /*url2*/, + const char* /*url3*/, const int /*maxlength*/) +DEFAULT_IMPL(false) + +void LocAdapterBase:: + reportLocationSystemInfoEvent(const LocationSystemInfo& /*locationSystemInfo*/) +DEFAULT_IMPL() + +bool LocAdapterBase:: + requestXtraData() +DEFAULT_IMPL(false) + +bool LocAdapterBase:: + requestTime() +DEFAULT_IMPL(false) + +bool LocAdapterBase:: + requestLocation() +DEFAULT_IMPL(false) + +bool LocAdapterBase:: + requestATL(int /*connHandle*/, LocAGpsType /*agps_type*/, + LocApnTypeMask /*apn_type_mask*/) +DEFAULT_IMPL(false) + +bool LocAdapterBase:: + releaseATL(int /*connHandle*/) +DEFAULT_IMPL(false) + +bool LocAdapterBase:: + requestNiNotifyEvent(const GnssNiNotification &/*notify*/, + const void* /*data*/, + const LocInEmergency emergencyState) +DEFAULT_IMPL(false) + +void LocAdapterBase:: +reportGnssMeasurementsEvent(const GnssMeasurements& /*gnssMeasurements*/, + int /*msInWeek*/) +DEFAULT_IMPL() + +bool LocAdapterBase:: + reportWwanZppFix(LocGpsLocation &/*zppLoc*/) +DEFAULT_IMPL(false) + +bool LocAdapterBase:: + reportZppBestAvailableFix(LocGpsLocation& /*zppLoc*/, + GpsLocationExtended& /*location_extended*/, LocPosTechMask /*tech_mask*/) +DEFAULT_IMPL(false) + +void LocAdapterBase::reportGnssSvIdConfigEvent(const GnssSvIdConfig& /*config*/) +DEFAULT_IMPL() + +void LocAdapterBase::reportGnssSvTypeConfigEvent(const GnssSvTypeConfig& /*config*/) +DEFAULT_IMPL() + +void LocAdapterBase::reportGnssConfigEvent(uint32_t, /* session id*/ + const GnssConfig& /*gnssConfig*/) +DEFAULT_IMPL() + +bool LocAdapterBase:: + requestOdcpiEvent(OdcpiRequestInfo& /*request*/) +DEFAULT_IMPL(false) + +bool LocAdapterBase:: + reportGnssEngEnergyConsumedEvent(uint64_t /*energyConsumedSinceFirstBoot*/) +DEFAULT_IMPL(false) + +bool LocAdapterBase:: + reportDeleteAidingDataEvent(GnssAidingData & /*aidingData*/) +DEFAULT_IMPL(false) + +bool LocAdapterBase:: + reportKlobucharIonoModelEvent(GnssKlobucharIonoModel& /*ionoModel*/) +DEFAULT_IMPL(false) + +bool LocAdapterBase:: + reportGnssAdditionalSystemInfoEvent(GnssAdditionalSystemInfo& /*additionalSystemInfo*/) +DEFAULT_IMPL(false) + +void LocAdapterBase:: + reportNfwNotificationEvent(GnssNfwNotification& /*notification*/) +DEFAULT_IMPL() + +void +LocAdapterBase::geofenceBreachEvent(size_t /*count*/, uint32_t* /*hwIds*/, Location& /*location*/, + GeofenceBreachType /*breachType*/, uint64_t /*timestamp*/) +DEFAULT_IMPL() + +void +LocAdapterBase::geofenceStatusEvent(GeofenceStatusAvailable /*available*/) +DEFAULT_IMPL() + +void +LocAdapterBase::reportLocationsEvent(const Location* /*locations*/, size_t /*count*/, + BatchingMode /*batchingMode*/) +DEFAULT_IMPL() + +void +LocAdapterBase::reportCompletedTripsEvent(uint32_t /*accumulated_distance*/) +DEFAULT_IMPL() + +void +LocAdapterBase::reportBatchStatusChangeEvent(BatchingStatus /*batchStatus*/) +DEFAULT_IMPL() + +void +LocAdapterBase::reportPositionEvent(UlpLocation& /*location*/, + GpsLocationExtended& /*locationExtended*/, + enum loc_sess_status /*status*/, + LocPosTechMask /*loc_technology_mask*/) +DEFAULT_IMPL() + +void +LocAdapterBase::saveClient(LocationAPI* client, const LocationCallbacks& callbacks) +{ + mClientData[client] = callbacks; + updateClientsEventMask(); +} + +void +LocAdapterBase::eraseClient(LocationAPI* client) +{ + auto it = mClientData.find(client); + if (it != mClientData.end()) { + mClientData.erase(it); + } + updateClientsEventMask(); +} + +LocationCallbacks +LocAdapterBase::getClientCallbacks(LocationAPI* client) +{ + LocationCallbacks callbacks = {}; + auto it = mClientData.find(client); + if (it != mClientData.end()) { + callbacks = it->second; + } + return callbacks; +} + +LocationCapabilitiesMask +LocAdapterBase::getCapabilities() +{ + LocationCapabilitiesMask mask = 0; + + if (isEngineCapabilitiesKnown()) { + // time based tracking always supported + mask |= LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT; + if (ContextBase::isMessageSupported( + LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_LOCATION_BATCHING)){ + mask |= LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT | + LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT; + } + if (ContextBase::isMessageSupported(LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_TRACKING)) { + mask |= LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT; + } + if (ContextBase::isMessageSupported(LOC_API_ADAPTER_MESSAGE_OUTDOOR_TRIP_BATCHING)) { + mask |= LOCATION_CAPABILITIES_OUTDOOR_TRIP_BATCHING_BIT; + } + // geofence always supported + mask |= LOCATION_CAPABILITIES_GEOFENCE_BIT; + if (ContextBase::gnssConstellationConfig()) { + mask |= LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT; + } + uint32_t carrierCapabilities = ContextBase::getCarrierCapabilities(); + if (carrierCapabilities & LOC_GPS_CAPABILITY_MSB) { + mask |= LOCATION_CAPABILITIES_GNSS_MSB_BIT; + } + if (LOC_GPS_CAPABILITY_MSA & carrierCapabilities) { + mask |= LOCATION_CAPABILITIES_GNSS_MSA_BIT; + } + if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_DEBUG_NMEA_V02)) { + mask |= LOCATION_CAPABILITIES_DEBUG_NMEA_BIT; + } + if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) { + mask |= LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT; + } + if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_AGPM_V02)) { + mask |= LOCATION_CAPABILITIES_AGPM_BIT; + } + if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_LOCATION_PRIVACY)) { + mask |= LOCATION_CAPABILITIES_PRIVACY_BIT; + } + if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_MEASUREMENTS_CORRECTION)) { + mask |= LOCATION_CAPABILITIES_MEASUREMENTS_CORRECTION_BIT; + } + if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_ROBUST_LOCATION)) { + mask |= LOCATION_CAPABILITIES_CONFORMITY_INDEX_BIT; + } + if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_EDGNSS)) { + mask |= LOCATION_CAPABILITIES_EDGNSS_BIT; + } + } else { + LOC_LOGE("%s]: attempt to get capabilities before they are known.", __func__); + } + + return mask; +} + +void +LocAdapterBase::broadcastCapabilities(LocationCapabilitiesMask mask) +{ + for (auto clientData : mClientData) { + if (nullptr != clientData.second.capabilitiesCb) { + clientData.second.capabilitiesCb(mask); + } + } +} + +void +LocAdapterBase::updateClientsEventMask() +DEFAULT_IMPL() + +void +LocAdapterBase::stopClientSessions(LocationAPI* client) +DEFAULT_IMPL() + +void +LocAdapterBase::addClientCommand(LocationAPI* client, const LocationCallbacks& callbacks) +{ + LOC_LOGD("%s]: client %p", __func__, client); + + struct MsgAddClient : public LocMsg { + LocAdapterBase& mAdapter; + LocationAPI* mClient; + const LocationCallbacks mCallbacks; + inline MsgAddClient(LocAdapterBase& adapter, + LocationAPI* client, + const LocationCallbacks& callbacks) : + LocMsg(), + mAdapter(adapter), + mClient(client), + mCallbacks(callbacks) {} + inline virtual void proc() const { + mAdapter.saveClient(mClient, mCallbacks); + } + }; + + sendMsg(new MsgAddClient(*this, client, callbacks)); +} + +void +LocAdapterBase::removeClientCommand(LocationAPI* client, + removeClientCompleteCallback rmClientCb) +{ + LOC_LOGD("%s]: client %p", __func__, client); + + struct MsgRemoveClient : public LocMsg { + LocAdapterBase& mAdapter; + LocationAPI* mClient; + removeClientCompleteCallback mRmClientCb; + inline MsgRemoveClient(LocAdapterBase& adapter, + LocationAPI* client, + removeClientCompleteCallback rmCb) : + LocMsg(), + mAdapter(adapter), + mClient(client), + mRmClientCb(rmCb){} + inline virtual void proc() const { + mAdapter.stopClientSessions(mClient); + mAdapter.eraseClient(mClient); + if (nullptr != mRmClientCb) { + (mRmClientCb)(mClient); + } + } + }; + + sendMsg(new MsgRemoveClient(*this, client, rmClientCb)); +} + +void +LocAdapterBase::requestCapabilitiesCommand(LocationAPI* client) +{ + LOC_LOGD("%s]: ", __func__); + + struct MsgRequestCapabilities : public LocMsg { + LocAdapterBase& mAdapter; + LocationAPI* mClient; + inline MsgRequestCapabilities(LocAdapterBase& adapter, + LocationAPI* client) : + LocMsg(), + mAdapter(adapter), + mClient(client) {} + inline virtual void proc() const { + if (!mAdapter.isEngineCapabilitiesKnown()) { + mAdapter.mPendingMsgs.push_back(new MsgRequestCapabilities(*this)); + return; + } + LocationCallbacks callbacks = mAdapter.getClientCallbacks(mClient); + if (callbacks.capabilitiesCb != nullptr) { + callbacks.capabilitiesCb(mAdapter.getCapabilities()); + } + } + }; + + sendMsg(new MsgRequestCapabilities(*this, client)); +} + +void +LocAdapterBase::reportLatencyInfoEvent(const GnssLatencyInfo& /*gnssLatencyInfo*/) +DEFAULT_IMPL() + +bool LocAdapterBase:: + reportQwesCapabilities(const std::unordered_map<LocationQwesFeatureType, bool> &featureMap) +DEFAULT_IMPL(false) + +} // namespace loc_core diff --git a/gps/core/LocAdapterBase.h b/gps/core/LocAdapterBase.h new file mode 100644 index 0000000..51b2306 --- /dev/null +++ b/gps/core/LocAdapterBase.h @@ -0,0 +1,246 @@ +/* Copyright (c) 2011-2014, 2016-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. + * + */ +#ifndef LOC_API_ADAPTER_BASE_H +#define LOC_API_ADAPTER_BASE_H + +#include <gps_extended.h> +#include <ContextBase.h> +#include <LocationAPI.h> +#include <map> + +#define MIN_TRACKING_INTERVAL (100) // 100 msec + +typedef struct LocationSessionKey { + LocationAPI* client; + uint32_t id; + inline LocationSessionKey(LocationAPI* _client, uint32_t _id) : + client(_client), id(_id) {} +} LocationSessionKey; +inline bool operator <(LocationSessionKey const& left, LocationSessionKey const& right) { + return left.id < right.id || (left.id == right.id && left.client < right.client); +} +inline bool operator ==(LocationSessionKey const& left, LocationSessionKey const& right) { + return left.id == right.id && left.client == right.client; +} +inline bool operator !=(LocationSessionKey const& left, LocationSessionKey const& right) { + return left.id != right.id || left.client != right.client; +} + +typedef void (*removeClientCompleteCallback)(LocationAPI* client); + +namespace loc_core { + +class LocAdapterProxyBase; + +class LocAdapterBase { +private: + static uint32_t mSessionIdCounter; + const bool mIsMaster; + bool mIsEngineCapabilitiesKnown = false; + +protected: + LOC_API_ADAPTER_EVENT_MASK_T mEvtMask; + ContextBase* mContext; + LocApiBase* mLocApi; + LocAdapterProxyBase* mLocAdapterProxyBase; + const MsgTask* mMsgTask; + bool mAdapterAdded; + + inline LocAdapterBase(const MsgTask* msgTask) : + mIsMaster(false), mEvtMask(0), mContext(NULL), mLocApi(NULL), + mLocAdapterProxyBase(NULL), mMsgTask(msgTask), mAdapterAdded(false) {} + + /* ==== CLIENT ========================================================================= */ + typedef std::map<LocationAPI*, LocationCallbacks> ClientDataMap; + ClientDataMap mClientData; + std::vector<LocMsg*> mPendingMsgs; // For temporal storage of msgs before Open is completed + /* ======== UTILITIES ================================================================== */ + void saveClient(LocationAPI* client, const LocationCallbacks& callbacks); + void eraseClient(LocationAPI* client); + LocationCallbacks getClientCallbacks(LocationAPI* client); + LocationCapabilitiesMask getCapabilities(); + void broadcastCapabilities(LocationCapabilitiesMask mask); + virtual void updateClientsEventMask(); + virtual void stopClientSessions(LocationAPI* client); + +public: + inline virtual ~LocAdapterBase() { mLocApi->removeAdapter(this); } + // When waitForDoneInit is not specified or specified as false, + // handleEngineUpEvent may be called on the child adapter object from + // a different thread before the constructor of the child + // object finishes. + // + // If the handleEngineUpEvent relies on member variables of the constructor + // of the child adapter to be initialized first, we need to specify the + // waitForDoneInit to *TRUE* to delay handleEngineUpEvent to get called + // until when the child adapter finishes its initialization and notify + // LocAdapterBase via doneInit method. + LocAdapterBase(const LOC_API_ADAPTER_EVENT_MASK_T mask, + ContextBase* context, bool isMaster = false, + LocAdapterProxyBase *adapterProxyBase = NULL, + bool waitForDoneInit = false); + + inline void doneInit() { + if (!mAdapterAdded) { + mLocApi->addAdapter(this); + mAdapterAdded = true; + } + } + + inline LOC_API_ADAPTER_EVENT_MASK_T + checkMask(LOC_API_ADAPTER_EVENT_MASK_T mask) const { + return mEvtMask & mask; + } + + inline LOC_API_ADAPTER_EVENT_MASK_T getEvtMask() const { + return mEvtMask; + } + + inline void sendMsg(const LocMsg* msg) const { + mMsgTask->sendMsg(msg); + } + + inline void sendMsg(const LocMsg* msg) { + mMsgTask->sendMsg(msg); + } + + inline void updateEvtMask(LOC_API_ADAPTER_EVENT_MASK_T event, + loc_registration_mask_status status) + { + switch(status) { + case (LOC_REGISTRATION_MASK_ENABLED): + mEvtMask = mEvtMask | event; + break; + case (LOC_REGISTRATION_MASK_DISABLED): + mEvtMask = mEvtMask &~ event; + break; + case (LOC_REGISTRATION_MASK_SET): + mEvtMask = event; + break; + } + mLocApi->updateEvtMask(); + } + + inline void updateNmeaMask(uint32_t mask) + { + mLocApi->updateNmeaMask(mask); + } + + inline bool isFeatureSupported(uint8_t featureVal) { + return ContextBase::isFeatureSupported(featureVal); + } + + static uint32_t generateSessionId(); + + inline bool isAdapterMaster() { + return mIsMaster; + } + + inline bool isEngineCapabilitiesKnown() { return mIsEngineCapabilitiesKnown;} + inline void setEngineCapabilitiesKnown(bool value) { mIsEngineCapabilitiesKnown = value;} + + virtual void handleEngineUpEvent(); + virtual void handleEngineDownEvent(); + virtual void reportPositionEvent(const UlpLocation& location, + const GpsLocationExtended& locationExtended, + enum loc_sess_status status, + LocPosTechMask loc_technology_mask, + GnssDataNotification* pDataNotify = nullptr, + int msInWeek = -1); + virtual void reportEnginePositionsEvent(unsigned int count, + EngineLocationInfo* locationArr) { + (void)count; + (void)locationArr; + } + virtual void reportSvEvent(const GnssSvNotification& svNotify, + bool fromEngineHub=false); + virtual void reportDataEvent(const GnssDataNotification& dataNotify, int msInWeek); + virtual void reportNmeaEvent(const char* nmea, size_t length); + virtual void reportSvPolynomialEvent(GnssSvPolynomial &svPolynomial); + virtual void reportSvEphemerisEvent(GnssSvEphemerisReport &svEphemeris); + virtual void reportStatus(LocGpsStatusValue status); + virtual bool reportXtraServer(const char* url1, const char* url2, + const char* url3, const int maxlength); + virtual void reportLocationSystemInfoEvent(const LocationSystemInfo& locationSystemInfo); + + virtual bool requestXtraData(); + virtual bool requestTime(); + virtual bool requestLocation(); + virtual bool requestATL(int connHandle, LocAGpsType agps_type, + LocApnTypeMask apn_type_mask); + virtual bool releaseATL(int connHandle); + virtual bool requestNiNotifyEvent(const GnssNiNotification ¬ify, const void* data, + const LocInEmergency emergencyState); + inline virtual bool isInSession() { return false; } + ContextBase* getContext() const { return mContext; } + virtual void reportGnssMeasurementsEvent(const GnssMeasurements& gnssMeasurements, + int msInWeek); + virtual bool reportWwanZppFix(LocGpsLocation &zppLoc); + virtual bool reportZppBestAvailableFix(LocGpsLocation &zppLoc, + GpsLocationExtended &location_extended, LocPosTechMask tech_mask); + virtual void reportGnssSvIdConfigEvent(const GnssSvIdConfig& config); + virtual void reportGnssSvTypeConfigEvent(const GnssSvTypeConfig& config); + virtual void reportGnssConfigEvent(uint32_t sessionId, const GnssConfig& gnssConfig); + virtual bool requestOdcpiEvent(OdcpiRequestInfo& request); + virtual bool reportGnssEngEnergyConsumedEvent(uint64_t energyConsumedSinceFirstBoot); + virtual bool reportDeleteAidingDataEvent(GnssAidingData &aidingData); + virtual bool reportKlobucharIonoModelEvent(GnssKlobucharIonoModel& ionoModel); + virtual bool reportGnssAdditionalSystemInfoEvent( + GnssAdditionalSystemInfo& additionalSystemInfo); + virtual void reportNfwNotificationEvent(GnssNfwNotification& notification); + + virtual void geofenceBreachEvent(size_t count, uint32_t* hwIds, Location& location, + GeofenceBreachType breachType, uint64_t timestamp); + virtual void geofenceStatusEvent(GeofenceStatusAvailable available); + + virtual void reportPositionEvent(UlpLocation &location, + GpsLocationExtended &locationExtended, + enum loc_sess_status status, + LocPosTechMask loc_technology_mask); + + virtual void reportLocationsEvent(const Location* locations, size_t count, + BatchingMode batchingMode); + virtual void reportCompletedTripsEvent(uint32_t accumulated_distance); + virtual void reportBatchStatusChangeEvent(BatchingStatus batchStatus); + + /* ==== CLIENT ========================================================================= */ + /* ======== COMMANDS ====(Called from Client Thread)==================================== */ + void addClientCommand(LocationAPI* client, const LocationCallbacks& callbacks); + void removeClientCommand(LocationAPI* client, + removeClientCompleteCallback rmClientCb); + void requestCapabilitiesCommand(LocationAPI* client); + + virtual void reportLatencyInfoEvent(const GnssLatencyInfo& gnssLatencyInfo); + virtual bool reportQwesCapabilities( + const std::unordered_map<LocationQwesFeatureType, bool> &featureMap); +}; + +} // namespace loc_core + +#endif //LOC_API_ADAPTER_BASE_H diff --git a/gps/core/LocAdapterProxyBase.h b/gps/core/LocAdapterProxyBase.h new file mode 100644 index 0000000..727d424 --- /dev/null +++ b/gps/core/LocAdapterProxyBase.h @@ -0,0 +1,77 @@ +/* Copyright (c) 2014, 2016-2017 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. + * + */ + +#ifndef LOC_ADAPTER_PROXY_BASE_H +#define LOC_ADAPTER_PROXY_BASE_H + +#include <ContextBase.h> +#include <gps_extended.h> + +namespace loc_core { + +class LocAdapterProxyBase { +private: + LocAdapterBase *mLocAdapterBase; +protected: + inline LocAdapterProxyBase(const LOC_API_ADAPTER_EVENT_MASK_T mask, + ContextBase* context, bool isMaster = false): + mLocAdapterBase(new LocAdapterBase(mask, context, isMaster, this)) { + } + inline virtual ~LocAdapterProxyBase() { + delete mLocAdapterBase; + } + inline void updateEvtMask(LOC_API_ADAPTER_EVENT_MASK_T event, + loc_registration_mask_status isEnabled) { + mLocAdapterBase->updateEvtMask(event,isEnabled); + } + + inline uint32_t generateSessionId() { + return mLocAdapterBase->generateSessionId(); + } +public: + inline ContextBase* getContext() const { + return mLocAdapterBase->getContext(); + } + + inline virtual void handleEngineUpEvent() {}; + inline virtual void handleEngineDownEvent() {}; + inline virtual void reportPositionEvent(UlpLocation &location, + GpsLocationExtended &locationExtended, + enum loc_sess_status status, + LocPosTechMask loc_technology_mask) { + (void)location; + (void)locationExtended; + (void)status; + (void)loc_technology_mask; + } +}; + +} // namespace loc_core + +#endif //LOC_ADAPTER_PROXY_BASE_H diff --git a/gps/core/LocApiBase.cpp b/gps/core/LocApiBase.cpp new file mode 100644 index 0000000..6a0ff84 --- /dev/null +++ b/gps/core/LocApiBase.cpp @@ -0,0 +1,1069 @@ +/* Copyright (c) 2011-2014, 2016-2021 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_NDEBUG 0 //Define to enable LOGV +#define LOG_TAG "LocSvc_LocApiBase" + +#include <dlfcn.h> +#include <inttypes.h> +#include <gps_extended_c.h> +#include <LocApiBase.h> +#include <LocAdapterBase.h> +#include <log_util.h> +#include <LocContext.h> +#include <loc_misc_utils.h> + +namespace loc_core { + +#define TO_ALL_LOCADAPTERS(call) TO_ALL_ADAPTERS(mLocAdapters, (call)) +#define TO_1ST_HANDLING_LOCADAPTERS(call) TO_1ST_HANDLING_ADAPTER(mLocAdapters, (call)) + +int hexcode(char *hexstring, int string_size, + const char *data, int data_size) +{ + int i; + for (i = 0; i < data_size; i++) + { + char ch = data[i]; + if (i*2 + 3 <= string_size) + { + snprintf(&hexstring[i*2], 3, "%02X", ch); + } + else { + break; + } + } + return i; +} + +int decodeAddress(char *addr_string, int string_size, + const char *data, int data_size) +{ + const char addr_prefix = 0x91; + int i, idxOutput = 0; + + if (!data || !addr_string) { return 0; } + + if (data[0] != addr_prefix) + { + LOC_LOGW("decodeAddress: address prefix is not 0x%x but 0x%x", addr_prefix, data[0]); + addr_string[0] = '\0'; + return 0; // prefix not correct + } + + for (i = 1; i < data_size; i++) + { + unsigned char ch = data[i], low = ch & 0x0F, hi = ch >> 4; + if (low <= 9 && idxOutput < string_size - 1) { addr_string[idxOutput++] = low + '0'; } + if (hi <= 9 && idxOutput < string_size - 1) { addr_string[idxOutput++] = hi + '0'; } + } + + addr_string[idxOutput] = '\0'; // Terminates the string + + return idxOutput; +} + +struct LocSsrMsg : public LocMsg { + LocApiBase* mLocApi; + inline LocSsrMsg(LocApiBase* locApi) : + LocMsg(), mLocApi(locApi) + { + locallog(); + } + inline virtual void proc() const { + mLocApi->close(); + if (LOC_API_ADAPTER_ERR_SUCCESS == mLocApi->open(mLocApi->getEvtMask())) { + // Notify adapters that engine up after SSR + mLocApi->handleEngineUpEvent(); + } + } + inline void locallog() const { + LOC_LOGV("LocSsrMsg"); + } + inline virtual void log() const { + locallog(); + } +}; + +struct LocOpenMsg : public LocMsg { + LocApiBase* mLocApi; + LocAdapterBase* mAdapter; + inline LocOpenMsg(LocApiBase* locApi, LocAdapterBase* adapter = nullptr) : + LocMsg(), mLocApi(locApi), mAdapter(adapter) + { + locallog(); + } + inline virtual void proc() const { + if (LOC_API_ADAPTER_ERR_SUCCESS == mLocApi->open(mLocApi->getEvtMask()) && + nullptr != mAdapter) { + mAdapter->handleEngineUpEvent(); + } + } + inline void locallog() const { + LOC_LOGv("LocOpen Mask: %" PRIx64 "\n", mLocApi->getEvtMask()); + } + inline virtual void log() const { + locallog(); + } +}; + +struct LocCloseMsg : public LocMsg { + LocApiBase* mLocApi; + inline LocCloseMsg(LocApiBase* locApi) : + LocMsg(), mLocApi(locApi) + { + locallog(); + } + inline virtual void proc() const { + mLocApi->close(); + } + inline void locallog() const { + } + inline virtual void log() const { + locallog(); + } +}; + +MsgTask* LocApiBase::mMsgTask = nullptr; +volatile int32_t LocApiBase::mMsgTaskRefCount = 0; + +LocApiBase::LocApiBase(LOC_API_ADAPTER_EVENT_MASK_T excludedMask, + ContextBase* context) : + mContext(context), + mMask(0), mExcludedMask(excludedMask) +{ + memset(mLocAdapters, 0, sizeof(mLocAdapters)); + + android_atomic_inc(&mMsgTaskRefCount); + if (nullptr == mMsgTask) { + mMsgTask = new MsgTask("LocApiMsgTask"); + } +} + +LOC_API_ADAPTER_EVENT_MASK_T LocApiBase::getEvtMask() +{ + LOC_API_ADAPTER_EVENT_MASK_T mask = 0; + + TO_ALL_LOCADAPTERS(mask |= mLocAdapters[i]->getEvtMask()); + + return mask & ~mExcludedMask; +} + +bool LocApiBase::isMaster() +{ + bool isMaster = false; + + for (int i = 0; + !isMaster && i < MAX_ADAPTERS && NULL != mLocAdapters[i]; + i++) { + isMaster |= mLocAdapters[i]->isAdapterMaster(); + } + return isMaster; +} + +bool LocApiBase::isInSession() +{ + bool inSession = false; + + for (int i = 0; + !inSession && i < MAX_ADAPTERS && NULL != mLocAdapters[i]; + i++) { + inSession = mLocAdapters[i]->isInSession(); + } + + return inSession; +} + +bool LocApiBase::needReport(const UlpLocation& ulpLocation, + enum loc_sess_status status, + LocPosTechMask techMask) +{ + bool reported = false; + + if (LOC_SESS_SUCCESS == status) { + // this is a final fix + LocPosTechMask mask = + LOC_POS_TECH_MASK_SATELLITE | LOC_POS_TECH_MASK_SENSORS | LOC_POS_TECH_MASK_HYBRID; + // it is a Satellite fix or a sensor fix + reported = (mask & techMask); + } + else if (LOC_SESS_INTERMEDIATE == status && + LOC_SESS_INTERMEDIATE == ContextBase::mGps_conf.INTERMEDIATE_POS) { + // this is a intermediate fix and we accept intermediate + + // it is NOT the case that + // there is inaccuracy; and + // we care about inaccuracy; and + // the inaccuracy exceeds our tolerance + reported = !((ulpLocation.gpsLocation.flags & LOC_GPS_LOCATION_HAS_ACCURACY) && + (ContextBase::mGps_conf.ACCURACY_THRES != 0) && + (ulpLocation.gpsLocation.accuracy > ContextBase::mGps_conf.ACCURACY_THRES)); + } + + return reported; +} + +void LocApiBase::addAdapter(LocAdapterBase* adapter) +{ + for (int i = 0; i < MAX_ADAPTERS && mLocAdapters[i] != adapter; i++) { + if (mLocAdapters[i] == NULL) { + mLocAdapters[i] = adapter; + sendMsg(new LocOpenMsg(this, adapter)); + break; + } + } +} + +void LocApiBase::removeAdapter(LocAdapterBase* adapter) +{ + for (int i = 0; + i < MAX_ADAPTERS && NULL != mLocAdapters[i]; + i++) { + if (mLocAdapters[i] == adapter) { + mLocAdapters[i] = NULL; + + // shift the rest of the adapters up so that the pointers + // in the array do not have holes. This should be more + // performant, because the array maintenance is much much + // less frequent than event handlings, which need to linear + // search all the adapters + int j = i; + while (++i < MAX_ADAPTERS && mLocAdapters[i] != NULL); + + // i would be MAX_ADAPTERS or point to a NULL + i--; + // i now should point to a none NULL adapter within valid + // range although i could be equal to j, but it won't hurt. + // No need to check it, as it gains nothing. + mLocAdapters[j] = mLocAdapters[i]; + // this makes sure that we exit the for loop + mLocAdapters[i] = NULL; + + // if we have an empty list of adapters + if (0 == i) { + sendMsg(new LocCloseMsg(this)); + } else { + // else we need to remove the bit + sendMsg(new LocOpenMsg(this)); + } + } + } +} + +void LocApiBase::updateEvtMask() +{ + sendMsg(new LocOpenMsg(this)); +} + +void LocApiBase::updateNmeaMask(uint32_t mask) +{ + struct LocSetNmeaMsg : public LocMsg { + LocApiBase* mLocApi; + uint32_t mMask; + inline LocSetNmeaMsg(LocApiBase* locApi, uint32_t mask) : + LocMsg(), mLocApi(locApi), mMask(mask) + { + locallog(); + } + inline virtual void proc() const { + mLocApi->setNMEATypesSync(mMask); + } + inline void locallog() const { + LOC_LOGv("LocSyncNmea NmeaMask: %" PRIx32 "\n", mMask); + } + inline virtual void log() const { + locallog(); + } + }; + + sendMsg(new LocSetNmeaMsg(this, mask)); +} + +void LocApiBase::handleEngineUpEvent() +{ + // loop through adapters, and deliver to all adapters. + TO_ALL_LOCADAPTERS(mLocAdapters[i]->handleEngineUpEvent()); +} + +void LocApiBase::handleEngineDownEvent() +{ // This will take care of renegotiating the loc handle + sendMsg(new LocSsrMsg(this)); + + // loop through adapters, and deliver to all adapters. + TO_ALL_LOCADAPTERS(mLocAdapters[i]->handleEngineDownEvent()); +} + +void LocApiBase::reportPosition(UlpLocation& location, + GpsLocationExtended& locationExtended, + enum loc_sess_status status, + LocPosTechMask loc_technology_mask, + GnssDataNotification* pDataNotify, + int msInWeek) +{ + // print the location info before delivering + LOC_LOGD("flags: %d\n source: %d\n latitude: %f\n longitude: %f\n " + "altitude: %f\n speed: %f\n bearing: %f\n accuracy: %f\n " + "timestamp: %" PRId64 "\n" + "Session status: %d\n Technology mask: %u\n " + "SV used in fix (gps/glo/bds/gal/qzss) : \ + (0x%" PRIx64 "/0x%" PRIx64 "/0x%" PRIx64 "/0x%" PRIx64 "/0x%" PRIx64 "/0x%" PRIx64 ")", + location.gpsLocation.flags, location.position_source, + location.gpsLocation.latitude, location.gpsLocation.longitude, + location.gpsLocation.altitude, location.gpsLocation.speed, + location.gpsLocation.bearing, location.gpsLocation.accuracy, + location.gpsLocation.timestamp, status, loc_technology_mask, + locationExtended.gnss_sv_used_ids.gps_sv_used_ids_mask, + locationExtended.gnss_sv_used_ids.glo_sv_used_ids_mask, + locationExtended.gnss_sv_used_ids.bds_sv_used_ids_mask, + locationExtended.gnss_sv_used_ids.gal_sv_used_ids_mask, + locationExtended.gnss_sv_used_ids.qzss_sv_used_ids_mask, + locationExtended.gnss_sv_used_ids.navic_sv_used_ids_mask); + // loop through adapters, and deliver to all adapters. + TO_ALL_LOCADAPTERS( + mLocAdapters[i]->reportPositionEvent(location, locationExtended, + status, loc_technology_mask, + pDataNotify, msInWeek) + ); +} + +void LocApiBase::reportWwanZppFix(LocGpsLocation &zppLoc) +{ + // loop through adapters, and deliver to the first handling adapter. + TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->reportWwanZppFix(zppLoc)); +} + +void LocApiBase::reportZppBestAvailableFix(LocGpsLocation &zppLoc, + GpsLocationExtended &location_extended, LocPosTechMask tech_mask) +{ + // loop through adapters, and deliver to the first handling adapter. + TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->reportZppBestAvailableFix(zppLoc, + location_extended, tech_mask)); +} + +void LocApiBase::requestOdcpi(OdcpiRequestInfo& request) +{ + // loop through adapters, and deliver to the first handling adapter. + TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->requestOdcpiEvent(request)); +} + +void LocApiBase::reportGnssEngEnergyConsumedEvent(uint64_t energyConsumedSinceFirstBoot) +{ + // loop through adapters, and deliver to the first handling adapter. + TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportGnssEngEnergyConsumedEvent( + energyConsumedSinceFirstBoot)); +} + +void LocApiBase::reportDeleteAidingDataEvent(GnssAidingData& aidingData) { + // loop through adapters, and deliver to the first handling adapter. + TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->reportDeleteAidingDataEvent(aidingData)); +} + +void LocApiBase::reportKlobucharIonoModel(GnssKlobucharIonoModel & ionoModel) { + // loop through adapters, and deliver to the first handling adapter. + TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->reportKlobucharIonoModelEvent(ionoModel)); +} + +void LocApiBase::reportGnssAdditionalSystemInfo(GnssAdditionalSystemInfo& additionalSystemInfo) { + // loop through adapters, and deliver to the first handling adapter. + TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->reportGnssAdditionalSystemInfoEvent( + additionalSystemInfo)); +} + +void LocApiBase::sendNfwNotification(GnssNfwNotification& notification) +{ + // loop through adapters, and deliver to the first handling adapter. + TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportNfwNotificationEvent(notification)); + +} + +void LocApiBase::reportSv(GnssSvNotification& svNotify) +{ + const char* constellationString[] = { "Unknown", "GPS", "SBAS", "GLONASS", + "QZSS", "BEIDOU", "GALILEO", "NAVIC" }; + + // print the SV info before delivering + LOC_LOGV("num sv: %u\n" + " sv: constellation svid cN0 basebandCN0" + " elevation azimuth flags", + svNotify.count); + for (size_t i = 0; i < svNotify.count && i < GNSS_SV_MAX; i++) { + if (svNotify.gnssSvs[i].type > + sizeof(constellationString) / sizeof(constellationString[0]) - 1) { + svNotify.gnssSvs[i].type = GNSS_SV_TYPE_UNKNOWN; + } + // Display what we report to clients + LOC_LOGV(" %03zu: %*s %02d %f %f %f %f %f 0x%02X 0x%2X", + i, + 13, + constellationString[svNotify.gnssSvs[i].type], + svNotify.gnssSvs[i].svId, + svNotify.gnssSvs[i].cN0Dbhz, + svNotify.gnssSvs[i].basebandCarrierToNoiseDbHz, + svNotify.gnssSvs[i].elevation, + svNotify.gnssSvs[i].azimuth, + svNotify.gnssSvs[i].carrierFrequencyHz, + svNotify.gnssSvs[i].gnssSvOptionsMask, + svNotify.gnssSvs[i].gnssSignalTypeMask); + } + // loop through adapters, and deliver to all adapters. + TO_ALL_LOCADAPTERS( + mLocAdapters[i]->reportSvEvent(svNotify) + ); +} + +void LocApiBase::reportSvPolynomial(GnssSvPolynomial &svPolynomial) +{ + // loop through adapters, and deliver to all adapters. + TO_ALL_LOCADAPTERS( + mLocAdapters[i]->reportSvPolynomialEvent(svPolynomial) + ); +} + +void LocApiBase::reportSvEphemeris(GnssSvEphemerisReport & svEphemeris) +{ + // loop through adapters, and deliver to all adapters. + TO_ALL_LOCADAPTERS( + mLocAdapters[i]->reportSvEphemerisEvent(svEphemeris) + ); +} + +void LocApiBase::reportStatus(LocGpsStatusValue status) +{ + // loop through adapters, and deliver to all adapters. + TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportStatus(status)); +} + +void LocApiBase::reportData(GnssDataNotification& dataNotify, int msInWeek) +{ + // loop through adapters, and deliver to all adapters. + TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportDataEvent(dataNotify, msInWeek)); +} + +void LocApiBase::reportNmea(const char* nmea, int length) +{ + // loop through adapters, and deliver to all adapters. + TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportNmeaEvent(nmea, length)); +} + +void LocApiBase::reportXtraServer(const char* url1, const char* url2, + const char* url3, const int maxlength) +{ + // loop through adapters, and deliver to the first handling adapter. + TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->reportXtraServer(url1, url2, url3, maxlength)); + +} + +void LocApiBase::reportLocationSystemInfo(const LocationSystemInfo& locationSystemInfo) +{ + // loop through adapters, and deliver to all adapters. + TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportLocationSystemInfoEvent(locationSystemInfo)); +} + +void LocApiBase::reportQwesCapabilities +( + const std::unordered_map<LocationQwesFeatureType, bool> &featureMap +) +{ + // loop through adapters, and deliver to all adapters. + TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportQwesCapabilities(featureMap)); +} +void LocApiBase::requestXtraData() +{ + // loop through adapters, and deliver to the first handling adapter. + TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->requestXtraData()); +} + +void LocApiBase::requestTime() +{ + // loop through adapters, and deliver to the first handling adapter. + TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->requestTime()); +} + +void LocApiBase::requestLocation() +{ + // loop through adapters, and deliver to the first handling adapter. + TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->requestLocation()); +} + +void LocApiBase::requestATL(int connHandle, LocAGpsType agps_type, + LocApnTypeMask apn_type_mask) +{ + // loop through adapters, and deliver to the first handling adapter. + TO_1ST_HANDLING_LOCADAPTERS( + mLocAdapters[i]->requestATL(connHandle, agps_type, apn_type_mask)); +} + +void LocApiBase::releaseATL(int connHandle) +{ + // loop through adapters, and deliver to the first handling adapter. + TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->releaseATL(connHandle)); +} + +void LocApiBase::requestNiNotify(GnssNiNotification ¬ify, const void* data, + const LocInEmergency emergencyState) +{ + // loop through adapters, and deliver to the first handling adapter. + TO_1ST_HANDLING_LOCADAPTERS( + mLocAdapters[i]->requestNiNotifyEvent(notify, + data, + emergencyState)); +} + +void* LocApiBase :: getSibling() + DEFAULT_IMPL(NULL) + +LocApiProxyBase* LocApiBase :: getLocApiProxy() + DEFAULT_IMPL(NULL) + +void LocApiBase::reportGnssMeasurements(GnssMeasurements& gnssMeasurements, int msInWeek) +{ + // loop through adapters, and deliver to all adapters. + TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportGnssMeasurementsEvent(gnssMeasurements, msInWeek)); +} + +void LocApiBase::reportGnssSvIdConfig(const GnssSvIdConfig& config) +{ + // Print the config + LOC_LOGv("gloBlacklistSvMask: %" PRIu64 ", bdsBlacklistSvMask: %" PRIu64 ",\n" + "qzssBlacklistSvMask: %" PRIu64 ", galBlacklistSvMask: %" PRIu64 ",\n" + "navicBlacklistSvMask: %" PRIu64, + config.gloBlacklistSvMask, config.bdsBlacklistSvMask, + config.qzssBlacklistSvMask, config.galBlacklistSvMask, config.navicBlacklistSvMask); + + // Loop through adapters, and deliver to all adapters. + TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportGnssSvIdConfigEvent(config)); +} + +void LocApiBase::reportGnssSvTypeConfig(const GnssSvTypeConfig& config) +{ + // Print the config + LOC_LOGv("blacklistedMask: %" PRIu64 ", enabledMask: %" PRIu64, + config.blacklistedSvTypesMask, config.enabledSvTypesMask); + + // Loop through adapters, and deliver to all adapters. + TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportGnssSvTypeConfigEvent(config)); +} + +void LocApiBase::geofenceBreach(size_t count, uint32_t* hwIds, Location& location, + GeofenceBreachType breachType, uint64_t timestamp) +{ + TO_ALL_LOCADAPTERS(mLocAdapters[i]->geofenceBreachEvent(count, hwIds, location, breachType, + timestamp)); +} + +void LocApiBase::geofenceStatus(GeofenceStatusAvailable available) +{ + TO_ALL_LOCADAPTERS(mLocAdapters[i]->geofenceStatusEvent(available)); +} + +void LocApiBase::reportDBTPosition(UlpLocation &location, GpsLocationExtended &locationExtended, + enum loc_sess_status status, LocPosTechMask loc_technology_mask) +{ + TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportPositionEvent(location, locationExtended, status, + loc_technology_mask)); +} + +void LocApiBase::reportLocations(Location* locations, size_t count, BatchingMode batchingMode) +{ + TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportLocationsEvent(locations, count, batchingMode)); +} + +void LocApiBase::reportCompletedTrips(uint32_t accumulated_distance) +{ + TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportCompletedTripsEvent(accumulated_distance)); +} + +void LocApiBase::handleBatchStatusEvent(BatchingStatus batchStatus) +{ + TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportBatchStatusChangeEvent(batchStatus)); +} + +void LocApiBase::reportGnssConfig(uint32_t sessionId, const GnssConfig& gnssConfig) +{ + // loop through adapters, and deliver to the first handling adapter. + TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportGnssConfigEvent(sessionId, gnssConfig)); +} + +void LocApiBase::reportLatencyInfo(GnssLatencyInfo& gnssLatencyInfo) +{ + // loop through adapters, and deliver to the first handling adapter. + TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportLatencyInfoEvent(gnssLatencyInfo)); +} + +enum loc_api_adapter_err LocApiBase:: + open(LOC_API_ADAPTER_EVENT_MASK_T /*mask*/) +DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) + +enum loc_api_adapter_err LocApiBase:: + close() +DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) + +void LocApiBase::startFix(const LocPosMode& /*posMode*/, LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +void LocApiBase::stopFix(LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +void LocApiBase:: + deleteAidingData(const GnssAidingData& /*data*/, LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +void LocApiBase:: + injectPosition(double /*latitude*/, double /*longitude*/, float /*accuracy*/, + bool /*onDemandCpi*/) +DEFAULT_IMPL() + +void LocApiBase:: + injectPosition(const Location& /*location*/, bool /*onDemandCpi*/) +DEFAULT_IMPL() + +void LocApiBase:: + injectPosition(const GnssLocationInfoNotification & /*locationInfo*/, bool /*onDemandCpi*/) +DEFAULT_IMPL() + +void LocApiBase:: + setTime(LocGpsUtcTime /*time*/, int64_t /*timeReference*/, int /*uncertainty*/) +DEFAULT_IMPL() + +void LocApiBase:: + atlOpenStatus(int /*handle*/, int /*is_succ*/, char* /*apn*/, uint32_t /*apnLen*/, + AGpsBearerType /*bear*/, LocAGpsType /*agpsType*/, + LocApnTypeMask /*mask*/) +DEFAULT_IMPL() + +void LocApiBase:: + atlCloseStatus(int /*handle*/, int /*is_succ*/) +DEFAULT_IMPL() + +LocationError LocApiBase:: + setServerSync(const char* /*url*/, int /*len*/, LocServerType /*type*/) +DEFAULT_IMPL(LOCATION_ERROR_SUCCESS) + +LocationError LocApiBase:: + setServerSync(unsigned int /*ip*/, int /*port*/, LocServerType /*type*/) +DEFAULT_IMPL(LOCATION_ERROR_SUCCESS) + +void LocApiBase:: + informNiResponse(GnssNiResponse /*userResponse*/, const void* /*passThroughData*/) +DEFAULT_IMPL() + +LocationError LocApiBase:: + setSUPLVersionSync(GnssConfigSuplVersion /*version*/) +DEFAULT_IMPL(LOCATION_ERROR_SUCCESS) + +enum loc_api_adapter_err LocApiBase:: + setNMEATypesSync (uint32_t /*typesMask*/) +DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) + +LocationError LocApiBase:: + setLPPConfigSync(GnssConfigLppProfileMask /*profileMask*/) +DEFAULT_IMPL(LOCATION_ERROR_SUCCESS) + + +enum loc_api_adapter_err LocApiBase:: + setSensorPropertiesSync(bool /*gyroBiasVarianceRandomWalk_valid*/, + float /*gyroBiasVarianceRandomWalk*/, + bool /*accelBiasVarianceRandomWalk_valid*/, + float /*accelBiasVarianceRandomWalk*/, + bool /*angleBiasVarianceRandomWalk_valid*/, + float /*angleBiasVarianceRandomWalk*/, + bool /*rateBiasVarianceRandomWalk_valid*/, + float /*rateBiasVarianceRandomWalk*/, + bool /*velocityBiasVarianceRandomWalk_valid*/, + float /*velocityBiasVarianceRandomWalk*/) +DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) + +enum loc_api_adapter_err LocApiBase:: + setSensorPerfControlConfigSync(int /*controlMode*/, + int /*accelSamplesPerBatch*/, + int /*accelBatchesPerSec*/, + int /*gyroSamplesPerBatch*/, + int /*gyroBatchesPerSec*/, + int /*accelSamplesPerBatchHigh*/, + int /*accelBatchesPerSecHigh*/, + int /*gyroSamplesPerBatchHigh*/, + int /*gyroBatchesPerSecHigh*/, + int /*algorithmConfig*/) +DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) + +LocationError LocApiBase:: + setAGLONASSProtocolSync(GnssConfigAGlonassPositionProtocolMask /*aGlonassProtocol*/) +DEFAULT_IMPL(LOCATION_ERROR_SUCCESS) + +LocationError LocApiBase:: + setLPPeProtocolCpSync(GnssConfigLppeControlPlaneMask /*lppeCP*/) +DEFAULT_IMPL(LOCATION_ERROR_SUCCESS) + +LocationError LocApiBase:: + setLPPeProtocolUpSync(GnssConfigLppeUserPlaneMask /*lppeUP*/) +DEFAULT_IMPL(LOCATION_ERROR_SUCCESS) + +GnssConfigSuplVersion LocApiBase::convertSuplVersion(const uint32_t /*suplVersion*/) +DEFAULT_IMPL(GNSS_CONFIG_SUPL_VERSION_1_0_0) + +GnssConfigLppeControlPlaneMask LocApiBase::convertLppeCp(const uint32_t /*lppeControlPlaneMask*/) +DEFAULT_IMPL(0) + +GnssConfigLppeUserPlaneMask LocApiBase::convertLppeUp(const uint32_t /*lppeUserPlaneMask*/) +DEFAULT_IMPL(0) + +LocationError LocApiBase::setEmergencyExtensionWindowSync( + const uint32_t /*emergencyExtensionSeconds*/) +DEFAULT_IMPL(LOCATION_ERROR_SUCCESS) + +void LocApiBase::setMeasurementCorrections( + const GnssMeasurementCorrections& /*gnssMeasurementCorrections*/) +DEFAULT_IMPL() + +void LocApiBase:: + getWwanZppFix() +DEFAULT_IMPL() + +void LocApiBase:: + getBestAvailableZppFix() +DEFAULT_IMPL() + +LocationError LocApiBase:: + setGpsLockSync(GnssConfigGpsLock /*lock*/) +DEFAULT_IMPL(LOCATION_ERROR_SUCCESS) + +void LocApiBase:: + requestForAidingData(GnssAidingDataSvMask /*svDataMask*/) +DEFAULT_IMPL() + +LocationError LocApiBase:: + setXtraVersionCheckSync(uint32_t /*check*/) +DEFAULT_IMPL(LOCATION_ERROR_SUCCESS) + +LocationError LocApiBase::setBlacklistSvSync(const GnssSvIdConfig& /*config*/) +DEFAULT_IMPL(LOCATION_ERROR_SUCCESS) + +void LocApiBase::setBlacklistSv(const GnssSvIdConfig& /*config*/, + LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +void LocApiBase::getBlacklistSv() +DEFAULT_IMPL() + +void LocApiBase::setConstellationControl(const GnssSvTypeConfig& /*config*/, + LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +void LocApiBase::getConstellationControl() +DEFAULT_IMPL() + +void LocApiBase::resetConstellationControl(LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +void LocApiBase:: + setConstrainedTuncMode(bool /*enabled*/, + float /*tuncConstraint*/, + uint32_t /*energyBudget*/, + LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +void LocApiBase:: + setPositionAssistedClockEstimatorMode(bool /*enabled*/, + LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +void LocApiBase::getGnssEnergyConsumed() +DEFAULT_IMPL() + + +void LocApiBase::addGeofence(uint32_t /*clientId*/, const GeofenceOption& /*options*/, + const GeofenceInfo& /*info*/, + LocApiResponseData<LocApiGeofenceData>* /*adapterResponseData*/) +DEFAULT_IMPL() + +void LocApiBase::removeGeofence(uint32_t /*hwId*/, uint32_t /*clientId*/, + LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +void LocApiBase::pauseGeofence(uint32_t /*hwId*/, uint32_t /*clientId*/, + LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +void LocApiBase::resumeGeofence(uint32_t /*hwId*/, uint32_t /*clientId*/, + LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +void LocApiBase::modifyGeofence(uint32_t /*hwId*/, uint32_t /*clientId*/, + const GeofenceOption& /*options*/, LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +void LocApiBase::startTimeBasedTracking(const TrackingOptions& /*options*/, + LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +void LocApiBase::stopTimeBasedTracking(LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +void LocApiBase::startDistanceBasedTracking(uint32_t /*sessionId*/, + const LocationOptions& /*options*/, LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +void LocApiBase::stopDistanceBasedTracking(uint32_t /*sessionId*/, + LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +void LocApiBase::startBatching(uint32_t /*sessionId*/, const LocationOptions& /*options*/, + uint32_t /*accuracy*/, uint32_t /*timeout*/, LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +void LocApiBase::stopBatching(uint32_t /*sessionId*/, LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +LocationError LocApiBase::startOutdoorTripBatchingSync(uint32_t /*tripDistance*/, + uint32_t /*tripTbf*/, uint32_t /*timeout*/) +DEFAULT_IMPL(LOCATION_ERROR_SUCCESS) + +void LocApiBase::startOutdoorTripBatching(uint32_t /*tripDistance*/, uint32_t /*tripTbf*/, + uint32_t /*timeout*/, LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +void LocApiBase::reStartOutdoorTripBatching(uint32_t /*ongoingTripDistance*/, + uint32_t /*ongoingTripInterval*/, uint32_t /*batchingTimeout,*/, + LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +LocationError LocApiBase::stopOutdoorTripBatchingSync(bool /*deallocBatchBuffer*/) +DEFAULT_IMPL(LOCATION_ERROR_SUCCESS) + +void LocApiBase::stopOutdoorTripBatching(bool /*deallocBatchBuffer*/, + LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +LocationError LocApiBase::getBatchedLocationsSync(size_t /*count*/) +DEFAULT_IMPL(LOCATION_ERROR_SUCCESS) + +void LocApiBase::getBatchedLocations(size_t /*count*/, LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +LocationError LocApiBase::getBatchedTripLocationsSync(size_t /*count*/, + uint32_t /*accumulatedDistance*/) +DEFAULT_IMPL(LOCATION_ERROR_SUCCESS) + +void LocApiBase::getBatchedTripLocations(size_t /*count*/, uint32_t /*accumulatedDistance*/, + LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +LocationError LocApiBase::queryAccumulatedTripDistanceSync(uint32_t& /*accumulated_trip_distance*/, + uint32_t& /*numOfBatchedPositions*/) +DEFAULT_IMPL(LOCATION_ERROR_SUCCESS) + +void LocApiBase::queryAccumulatedTripDistance( + LocApiResponseData<LocApiBatchData>* /*adapterResponseData*/) +DEFAULT_IMPL() + +void LocApiBase::setBatchSize(size_t /*size*/) +DEFAULT_IMPL() + +void LocApiBase::setTripBatchSize(size_t /*size*/) +DEFAULT_IMPL() + +void LocApiBase::addToCallQueue(LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +void LocApiBase::updateSystemPowerState(PowerStateType /*powerState*/) +DEFAULT_IMPL() + +void LocApiBase:: + configRobustLocation(bool /*enabled*/, + bool /*enableForE911*/, + LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +void LocApiBase:: + getRobustLocationConfig(uint32_t sessionId, LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +void LocApiBase:: + configMinGpsWeek(uint16_t minGpsWeek, + LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +void LocApiBase:: + getMinGpsWeek(uint32_t sessionId, LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +LocationError LocApiBase:: + setParameterSync(const GnssConfig& gnssConfig) +DEFAULT_IMPL(LOCATION_ERROR_SUCCESS) + +void LocApiBase:: + getParameter(uint32_t sessionId, GnssConfigFlagsMask flags, LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +void LocApiBase:: + configConstellationMultiBand(const GnssSvTypeConfig& secondaryBandConfig, + LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +void LocApiBase:: + getConstellationMultiBandConfig(uint32_t sessionId, LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +int64_t ElapsedRealtimeEstimator::getElapsedRealtimeEstimateNanos(int64_t curDataTimeNanos, + bool isCurDataTimeTrustable, int64_t tbf) { + //The algorithm works follow below steps: + //When isCurDataTimeTrustable is meet (means Modem timestamp is already stable), + //1, Wait for mFixTimeStablizationThreshold fixes; While waiting for modem time + // stable, we set the traveltime to a default value; + //2, When the mFixTimeStablizationThreshold fix comes, we think now the mode time + // is already stable, calculate the initial AP-Modem clock diff(mCurrentClockDiff) + // using formula: + // mCurrentClockDiff = currentTimeNanos - locationTimeNanos - currentTravelTimeNanos + //3, since then, when the nth fix comes, + // 3.1 First update mCurrentClockDiff using below formula: + // mCurrentClockDiff = mCurrentClockDiff + (currentTimeNanos - sinceBootTimeNanos) + // - (mPrevUtcTimeNanos - mPrevBootTimeNanos) + // 3.2 Calculate currentTravelTimeNanos: + // currentTravelTimeNanos = currentTimeNanos - locationTimeNanos - mCurrentClockDiff + //4, It is possible that locationTimeNanos will jump, + // reset mFixTimeStablizationThreshold to default value, jump to step 2 to continue. + + int64_t currentTravelTimeNanos = mInitialTravelTime; + struct timespec currentTime; + int64_t sinceBootTimeNanos; + if (getCurrentTime(currentTime, sinceBootTimeNanos)) { + if (isCurDataTimeTrustable) { + if (tbf > 0 && tbf != curDataTimeNanos - mPrevDataTimeNanos) { + mFixTimeStablizationThreshold = 5; + } + int64_t currentTimeNanos = (int64_t)currentTime.tv_sec*1000000000 + currentTime.tv_nsec; + LOC_LOGd("sinceBootTimeNanos:%" PRIi64 " currentTimeNanos:%" PRIi64 "" + " locationTimeNanos:%" PRIi64 "", + sinceBootTimeNanos, currentTimeNanos, curDataTimeNanos); + if (mFixTimeStablizationThreshold == 0) { + currentTravelTimeNanos = mInitialTravelTime; + mCurrentClockDiff = currentTimeNanos - curDataTimeNanos - currentTravelTimeNanos; + } else if (mFixTimeStablizationThreshold < 0) { + mCurrentClockDiff = mCurrentClockDiff + (currentTimeNanos - sinceBootTimeNanos) + - (mPrevUtcTimeNanos - mPrevBootTimeNanos); + currentTravelTimeNanos = currentTimeNanos - curDataTimeNanos - mCurrentClockDiff; + } + + mPrevUtcTimeNanos = currentTimeNanos; + mPrevBootTimeNanos = sinceBootTimeNanos; + mPrevDataTimeNanos = curDataTimeNanos; + mFixTimeStablizationThreshold--; + } + } else { + return -1; + } + LOC_LOGd("Estimated travel time: %" PRIi64 "", currentTravelTimeNanos); + return (sinceBootTimeNanos - currentTravelTimeNanos); +} + +void ElapsedRealtimeEstimator::reset() { + mCurrentClockDiff = 0; + mPrevDataTimeNanos = 0; + mPrevUtcTimeNanos = 0; + mPrevBootTimeNanos = 0; + mFixTimeStablizationThreshold = 5; +} + +int64_t ElapsedRealtimeEstimator::getElapsedRealtimeQtimer(int64_t qtimerTicksAtOrigin) { + struct timespec currentTime; + int64_t sinceBootTimeNanos; + int64_t elapsedRealTimeNanos; + + if (getCurrentTime(currentTime, sinceBootTimeNanos)) { + uint64_t qtimerDiff = 0; + uint64_t qTimerTickCount = getQTimerTickCount(); + if (qTimerTickCount >= qtimerTicksAtOrigin) { + qtimerDiff = qTimerTickCount - qtimerTicksAtOrigin; + } + LOC_LOGd("sinceBootTimeNanos:%" PRIi64 " qtimerTicksAtOrigin=%" PRIi64 "" + " qTimerTickCount=%" PRIi64 " qtimerDiff=%" PRIi64 "", + sinceBootTimeNanos, qtimerTicksAtOrigin, qTimerTickCount, qtimerDiff); + uint64_t qTimerDiffNanos = qTimerTicksToNanos(double(qtimerDiff)); + + /* If the time difference between Qtimer on modem side and Qtimer on AP side + is greater than one second we assume this is a dual-SoC device such as + Kona and will try to get Qtimer on modem side and on AP side and + will adjust our difference accordingly */ + if (qTimerDiffNanos > 1000000000) { + uint64_t qtimerDelta = getQTimerDeltaNanos(); + if (qTimerDiffNanos >= qtimerDelta) { + qTimerDiffNanos -= qtimerDelta; + } + } + + LOC_LOGd("Qtimer travel time: %" PRIi64 "", qTimerDiffNanos); + if (sinceBootTimeNanos >= qTimerDiffNanos) { + elapsedRealTimeNanos = sinceBootTimeNanos - qTimerDiffNanos; + } else { + elapsedRealTimeNanos = -1; + } + } else { + elapsedRealTimeNanos = -1; + } + return elapsedRealTimeNanos; +} + +bool ElapsedRealtimeEstimator::getCurrentTime( + struct timespec& currentTime, int64_t& sinceBootTimeNanos) +{ + struct timespec sinceBootTime; + struct timespec sinceBootTimeTest; + bool clockGetTimeSuccess = false; + const uint32_t MAX_TIME_DELTA_VALUE_NANOS = 10000; + const uint32_t MAX_GET_TIME_COUNT = 20; + /* Attempt to get CLOCK_REALTIME and CLOCK_BOOTIME in succession without an interruption + or context switch (for up to MAX_GET_TIME_COUNT times) to avoid errors in the calculation */ + for (uint32_t i = 0; i < MAX_GET_TIME_COUNT; i++) { + if (clock_gettime(CLOCK_BOOTTIME, &sinceBootTime) != 0) { + break; + }; + if (clock_gettime(CLOCK_REALTIME, ¤tTime) != 0) { + break; + } + if (clock_gettime(CLOCK_BOOTTIME, &sinceBootTimeTest) != 0) { + break; + }; + sinceBootTimeNanos = (int64_t)sinceBootTime.tv_sec * 1000000000 + sinceBootTime.tv_nsec; + int64_t sinceBootTimeTestNanos = + (int64_t)sinceBootTimeTest.tv_sec * 1000000000 + sinceBootTimeTest.tv_nsec; + int64_t sinceBootTimeDeltaNanos = sinceBootTimeTestNanos - sinceBootTimeNanos; + + /* sinceBootTime and sinceBootTimeTest should have a close value if there was no + interruption or context switch between clock_gettime for CLOCK_BOOTIME and + clock_gettime for CLOCK_REALTIME */ + if (sinceBootTimeDeltaNanos < MAX_TIME_DELTA_VALUE_NANOS) { + clockGetTimeSuccess = true; + break; + } else { + LOC_LOGd("Delta:%" PRIi64 "ns time too large, retry number #%u...", + sinceBootTimeDeltaNanos, i + 1); + } + } + return clockGetTimeSuccess; +} +} // namespace loc_core diff --git a/gps/core/LocApiBase.h b/gps/core/LocApiBase.h new file mode 100644 index 0000000..121f795 --- /dev/null +++ b/gps/core/LocApiBase.h @@ -0,0 +1,375 @@ +/* Copyright (c) 2011-2014, 2016-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. + * + */ +#ifndef LOC_API_BASE_H +#define LOC_API_BASE_H + +#include <stddef.h> +#include <ctype.h> +#include <gps_extended.h> +#include <LocationAPI.h> +#include <MsgTask.h> +#include <LocSharedLock.h> +#include <log_util.h> +#ifdef NO_UNORDERED_SET_OR_MAP + #include <map> +#else + #include <unordered_map> +#endif +#include <inttypes.h> +#include <functional> + +using namespace loc_util; + +namespace loc_core { + +class ContextBase; +struct LocApiResponse; +template <typename> struct LocApiResponseData; + +int hexcode(char *hexstring, int string_size, + const char *data, int data_size); +int decodeAddress(char *addr_string, int string_size, + const char *data, int data_size); + +#define MAX_ADAPTERS 10 +#define MAX_FEATURE_LENGTH 100 + +#define TO_ALL_ADAPTERS(adapters, call) \ + for (int i = 0; i < MAX_ADAPTERS && NULL != (adapters)[i]; i++) { \ + call; \ + } + +#define TO_1ST_HANDLING_ADAPTER(adapters, call) \ + for (int i = 0; i <MAX_ADAPTERS && NULL != (adapters)[i] && !(call); i++); + +class LocAdapterBase; +struct LocSsrMsg; +struct LocOpenMsg; + +typedef struct +{ + uint32_t accumulatedDistance; + uint32_t numOfBatchedPositions; +} LocApiBatchData; + +typedef struct +{ + uint32_t hwId; +} LocApiGeofenceData; + +struct LocApiMsg: LocMsg { + private: + std::function<void ()> mProcImpl; + inline virtual void proc() const { + mProcImpl(); + } + public: + inline LocApiMsg(std::function<void ()> procImpl ) : + mProcImpl(procImpl) {} +}; + +class LocApiProxyBase { +public: + inline LocApiProxyBase() {} + inline virtual ~LocApiProxyBase() {} + inline virtual void* getSibling2() { return NULL; } + inline virtual double getGloRfLoss(uint32_t left, + uint32_t center, uint32_t right, uint8_t gloFrequency) { return 0.0; } +}; + +class LocApiBase { + friend struct LocSsrMsg; + //LocOpenMsg calls open() which makes it necessary to declare + //it as a friend + friend struct LocOpenMsg; + friend struct LocCloseMsg; + friend struct LocKillMsg; + friend class ContextBase; + static MsgTask* mMsgTask; + static volatile int32_t mMsgTaskRefCount; + LocAdapterBase* mLocAdapters[MAX_ADAPTERS]; + +protected: + ContextBase *mContext; + virtual enum loc_api_adapter_err + open(LOC_API_ADAPTER_EVENT_MASK_T mask); + virtual enum loc_api_adapter_err + close(); + LOC_API_ADAPTER_EVENT_MASK_T getEvtMask(); + LOC_API_ADAPTER_EVENT_MASK_T mMask; + uint32_t mNmeaMask; + LocApiBase(LOC_API_ADAPTER_EVENT_MASK_T excludedMask, + ContextBase* context = NULL); + inline virtual ~LocApiBase() { + android_atomic_dec(&mMsgTaskRefCount); + if (nullptr != mMsgTask && 0 == mMsgTaskRefCount) { + delete mMsgTask; + mMsgTask = nullptr; + } + } + bool isInSession(); + const LOC_API_ADAPTER_EVENT_MASK_T mExcludedMask; + bool isMaster(); + +public: + inline void sendMsg(const LocMsg* msg) const { + if (nullptr != mMsgTask) { + mMsgTask->sendMsg(msg); + } + } + inline void destroy() { + close(); + struct LocKillMsg : public LocMsg { + LocApiBase* mLocApi; + inline LocKillMsg(LocApiBase* locApi) : LocMsg(), mLocApi(locApi) {} + inline virtual void proc() const { + delete mLocApi; + } + }; + sendMsg(new LocKillMsg(this)); + } + + static bool needReport(const UlpLocation& ulpLocation, + enum loc_sess_status status, + LocPosTechMask techMask); + + void addAdapter(LocAdapterBase* adapter); + void removeAdapter(LocAdapterBase* adapter); + + // upward calls + void handleEngineUpEvent(); + void handleEngineDownEvent(); + void reportPosition(UlpLocation& location, + GpsLocationExtended& locationExtended, + enum loc_sess_status status, + LocPosTechMask loc_technology_mask = + LOC_POS_TECH_MASK_DEFAULT, + GnssDataNotification* pDataNotify = nullptr, + int msInWeek = -1); + void reportSv(GnssSvNotification& svNotify); + void reportSvPolynomial(GnssSvPolynomial &svPolynomial); + void reportSvEphemeris(GnssSvEphemerisReport &svEphemeris); + void reportStatus(LocGpsStatusValue status); + void reportNmea(const char* nmea, int length); + void reportData(GnssDataNotification& dataNotify, int msInWeek); + void reportXtraServer(const char* url1, const char* url2, + const char* url3, const int maxlength); + void reportLocationSystemInfo(const LocationSystemInfo& locationSystemInfo); + void requestXtraData(); + void requestTime(); + void requestLocation(); + void requestATL(int connHandle, LocAGpsType agps_type, LocApnTypeMask apn_type_mask); + void releaseATL(int connHandle); + void requestNiNotify(GnssNiNotification ¬ify, const void* data, + const LocInEmergency emergencyState); + void reportGnssMeasurements(GnssMeasurements& gnssMeasurements, int msInWeek); + void reportWwanZppFix(LocGpsLocation &zppLoc); + void reportZppBestAvailableFix(LocGpsLocation &zppLoc, GpsLocationExtended &location_extended, + LocPosTechMask tech_mask); + void reportGnssSvIdConfig(const GnssSvIdConfig& config); + void reportGnssSvTypeConfig(const GnssSvTypeConfig& config); + void requestOdcpi(OdcpiRequestInfo& request); + void reportGnssEngEnergyConsumedEvent(uint64_t energyConsumedSinceFirstBoot); + void reportDeleteAidingDataEvent(GnssAidingData& aidingData); + void reportKlobucharIonoModel(GnssKlobucharIonoModel& ionoModel); + void reportGnssAdditionalSystemInfo(GnssAdditionalSystemInfo& additionalSystemInfo); + void sendNfwNotification(GnssNfwNotification& notification); + void reportGnssConfig(uint32_t sessionId, const GnssConfig& gnssConfig); + void reportLatencyInfo(GnssLatencyInfo& gnssLatencyInfo); + void reportQwesCapabilities + ( + const std::unordered_map<LocationQwesFeatureType, bool> &featureMap + ); + + void geofenceBreach(size_t count, uint32_t* hwIds, Location& location, + GeofenceBreachType breachType, uint64_t timestamp); + void geofenceStatus(GeofenceStatusAvailable available); + void reportDBTPosition(UlpLocation &location, + GpsLocationExtended &locationExtended, + enum loc_sess_status status, + LocPosTechMask loc_technology_mask); + void reportLocations(Location* locations, size_t count, BatchingMode batchingMode); + void reportCompletedTrips(uint32_t accumulated_distance); + void handleBatchStatusEvent(BatchingStatus batchStatus); + + // downward calls + virtual void* getSibling(); + virtual LocApiProxyBase* getLocApiProxy(); + virtual void startFix(const LocPosMode& fixCriteria, LocApiResponse* adapterResponse); + virtual void stopFix(LocApiResponse* adapterResponse); + virtual void deleteAidingData(const GnssAidingData& data, LocApiResponse* adapterResponse); + virtual void injectPosition(double latitude, double longitude, float accuracy, + bool onDemandCpi); + virtual void injectPosition(const GnssLocationInfoNotification &locationInfo, + bool onDemandCpi=false); + virtual void injectPosition(const Location& location, bool onDemandCpi); + virtual void setTime(LocGpsUtcTime time, int64_t timeReference, int uncertainty); + virtual void atlOpenStatus(int handle, int is_succ, char* apn, uint32_t apnLen, + AGpsBearerType bear, LocAGpsType agpsType, LocApnTypeMask mask); + virtual void atlCloseStatus(int handle, int is_succ); + virtual LocationError setServerSync(const char* url, int len, LocServerType type); + virtual LocationError setServerSync(unsigned int ip, int port, LocServerType type); + virtual void informNiResponse(GnssNiResponse userResponse, const void* passThroughData); + virtual LocationError setSUPLVersionSync(GnssConfigSuplVersion version); + virtual enum loc_api_adapter_err setNMEATypesSync(uint32_t typesMask); + virtual LocationError setLPPConfigSync(GnssConfigLppProfileMask profileMask); + virtual enum loc_api_adapter_err setSensorPropertiesSync( + bool gyroBiasVarianceRandomWalk_valid, float gyroBiasVarianceRandomWalk, + bool accelBiasVarianceRandomWalk_valid, float accelBiasVarianceRandomWalk, + bool angleBiasVarianceRandomWalk_valid, float angleBiasVarianceRandomWalk, + bool rateBiasVarianceRandomWalk_valid, float rateBiasVarianceRandomWalk, + bool velocityBiasVarianceRandomWalk_valid, float velocityBiasVarianceRandomWalk); + virtual enum loc_api_adapter_err setSensorPerfControlConfigSync(int controlMode, + int accelSamplesPerBatch, int accelBatchesPerSec, int gyroSamplesPerBatch, + int gyroBatchesPerSec, int accelSamplesPerBatchHigh, int accelBatchesPerSecHigh, + int gyroSamplesPerBatchHigh, int gyroBatchesPerSecHigh, int algorithmConfig); + virtual LocationError + setAGLONASSProtocolSync(GnssConfigAGlonassPositionProtocolMask aGlonassProtocol); + virtual LocationError setLPPeProtocolCpSync(GnssConfigLppeControlPlaneMask lppeCP); + virtual LocationError setLPPeProtocolUpSync(GnssConfigLppeUserPlaneMask lppeUP); + virtual GnssConfigSuplVersion convertSuplVersion(const uint32_t suplVersion); + virtual GnssConfigLppeControlPlaneMask convertLppeCp(const uint32_t lppeControlPlaneMask); + virtual GnssConfigLppeUserPlaneMask convertLppeUp(const uint32_t lppeUserPlaneMask); + virtual LocationError setEmergencyExtensionWindowSync(const uint32_t emergencyExtensionSeconds); + virtual void setMeasurementCorrections( + const GnssMeasurementCorrections& gnssMeasurementCorrections); + + virtual void getWwanZppFix(); + virtual void getBestAvailableZppFix(); + virtual LocationError setGpsLockSync(GnssConfigGpsLock lock); + virtual void requestForAidingData(GnssAidingDataSvMask svDataMask); + virtual LocationError setXtraVersionCheckSync(uint32_t check); + /* Requests for SV/Constellation Control */ + virtual LocationError setBlacklistSvSync(const GnssSvIdConfig& config); + virtual void setBlacklistSv(const GnssSvIdConfig& config, + LocApiResponse *adapterResponse=nullptr); + virtual void getBlacklistSv(); + virtual void setConstellationControl(const GnssSvTypeConfig& config, + LocApiResponse *adapterResponse=nullptr); + virtual void getConstellationControl(); + virtual void resetConstellationControl(LocApiResponse *adapterResponse=nullptr); + + virtual void setConstrainedTuncMode(bool enabled, + float tuncConstraint, + uint32_t energyBudget, + LocApiResponse* adapterResponse=nullptr); + virtual void setPositionAssistedClockEstimatorMode(bool enabled, + LocApiResponse* adapterResponse=nullptr); + virtual void getGnssEnergyConsumed(); + + virtual void addGeofence(uint32_t clientId, const GeofenceOption& options, + const GeofenceInfo& info, LocApiResponseData<LocApiGeofenceData>* adapterResponseData); + virtual void removeGeofence(uint32_t hwId, uint32_t clientId, LocApiResponse* adapterResponse); + virtual void pauseGeofence(uint32_t hwId, uint32_t clientId, LocApiResponse* adapterResponse); + virtual void resumeGeofence(uint32_t hwId, uint32_t clientId, LocApiResponse* adapterResponse); + virtual void modifyGeofence(uint32_t hwId, uint32_t clientId, const GeofenceOption& options, + LocApiResponse* adapterResponse); + + virtual void startTimeBasedTracking(const TrackingOptions& options, + LocApiResponse* adapterResponse); + virtual void stopTimeBasedTracking(LocApiResponse* adapterResponse); + virtual void startDistanceBasedTracking(uint32_t sessionId, const LocationOptions& options, + LocApiResponse* adapterResponse); + virtual void stopDistanceBasedTracking(uint32_t sessionId, + LocApiResponse* adapterResponse = nullptr); + virtual void startBatching(uint32_t sessionId, const LocationOptions& options, + uint32_t accuracy, uint32_t timeout, LocApiResponse* adapterResponse); + virtual void stopBatching(uint32_t sessionId, LocApiResponse* adapterResponse); + virtual LocationError startOutdoorTripBatchingSync(uint32_t tripDistance, + uint32_t tripTbf, uint32_t timeout); + virtual void startOutdoorTripBatching(uint32_t tripDistance, + uint32_t tripTbf, uint32_t timeout, LocApiResponse* adapterResponse); + virtual void reStartOutdoorTripBatching(uint32_t ongoingTripDistance, + uint32_t ongoingTripInterval, uint32_t batchingTimeout, + LocApiResponse* adapterResponse); + virtual LocationError stopOutdoorTripBatchingSync(bool deallocBatchBuffer = true); + virtual void stopOutdoorTripBatching(bool deallocBatchBuffer = true, + LocApiResponse* adapterResponse = nullptr); + virtual LocationError getBatchedLocationsSync(size_t count); + virtual void getBatchedLocations(size_t count, LocApiResponse* adapterResponse); + virtual LocationError getBatchedTripLocationsSync(size_t count, uint32_t accumulatedDistance); + virtual void getBatchedTripLocations(size_t count, uint32_t accumulatedDistance, + LocApiResponse* adapterResponse); + virtual LocationError queryAccumulatedTripDistanceSync(uint32_t &accumulated_trip_distance, + uint32_t &numOfBatchedPositions); + virtual void queryAccumulatedTripDistance( + LocApiResponseData<LocApiBatchData>* adapterResponseData); + virtual void setBatchSize(size_t size); + virtual void setTripBatchSize(size_t size); + virtual void addToCallQueue(LocApiResponse* adapterResponse); + + void updateEvtMask(); + void updateNmeaMask(uint32_t mask); + + virtual void updateSystemPowerState(PowerStateType systemPowerState); + + virtual void configRobustLocation(bool enable, bool enableForE911, + LocApiResponse* adapterResponse=nullptr); + virtual void getRobustLocationConfig(uint32_t sessionId, LocApiResponse* adapterResponse); + virtual void configMinGpsWeek(uint16_t minGpsWeek, + LocApiResponse* adapterResponse=nullptr); + virtual void getMinGpsWeek(uint32_t sessionId, LocApiResponse* adapterResponse); + + virtual LocationError setParameterSync(const GnssConfig & gnssConfig); + virtual void getParameter(uint32_t sessionId, GnssConfigFlagsMask flags, + LocApiResponse* adapterResponse=nullptr); + + virtual void configConstellationMultiBand(const GnssSvTypeConfig& secondaryBandConfig, + LocApiResponse* adapterResponse=nullptr); + virtual void getConstellationMultiBandConfig(uint32_t sessionId, + LocApiResponse* adapterResponse=nullptr); +}; + +class ElapsedRealtimeEstimator { +private: + int64_t mCurrentClockDiff; + int64_t mPrevUtcTimeNanos; + int64_t mPrevBootTimeNanos; + int64_t mFixTimeStablizationThreshold; + int64_t mInitialTravelTime; + int64_t mPrevDataTimeNanos; +public: + + ElapsedRealtimeEstimator(int64_t travelTimeNanosEstimate): + mInitialTravelTime(travelTimeNanosEstimate) {reset();} + int64_t getElapsedRealtimeEstimateNanos(int64_t curDataTimeNanos, + bool isCurDataTimeTrustable, int64_t tbf); + inline int64_t getElapsedRealtimeUncNanos() { return 5000000;} + void reset(); + + static int64_t getElapsedRealtimeQtimer(int64_t qtimerTicksAtOrigin); + static bool getCurrentTime(struct timespec& currentTime, int64_t& sinceBootTimeNanos); +}; + +typedef LocApiBase* (getLocApi_t)(LOC_API_ADAPTER_EVENT_MASK_T exMask, + ContextBase *context); + +} // namespace loc_core + +#endif //LOC_API_BASE_H diff --git a/gps/core/LocContext.cpp b/gps/core/LocContext.cpp new file mode 100644 index 0000000..272c08c --- /dev/null +++ b/gps/core/LocContext.cpp @@ -0,0 +1,87 @@ +/* Copyright (c) 2011-2014, 2016-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_NDEBUG 0 +#define LOG_TAG "LocSvc_Ctx" + +#include <cutils/sched_policy.h> +#include <unistd.h> +#include <LocContext.h> +#include <msg_q.h> +#include <log_util.h> +#include <loc_log.h> + +namespace loc_core { + +const MsgTask* LocContext::mMsgTask = NULL; +ContextBase* LocContext::mContext = NULL; +// the name must be shorter than 15 chars +const char* LocContext::mLocationHalName = "Loc_hal_worker"; +#ifndef USE_GLIB +const char* LocContext::mLBSLibName = "liblbs_core.so"; +#else +const char* LocContext::mLBSLibName = "liblbs_core.so.1"; +#endif + +pthread_mutex_t LocContext::mGetLocContextMutex = PTHREAD_MUTEX_INITIALIZER; + +const MsgTask* LocContext::getMsgTask(const char* name) +{ + if (NULL == mMsgTask) { + mMsgTask = new MsgTask(name); + } + return mMsgTask; +} + +ContextBase* LocContext::getLocContext(const char* name) +{ + pthread_mutex_lock(&LocContext::mGetLocContextMutex); + LOC_LOGD("%s:%d]: querying ContextBase with tCreator", __func__, __LINE__); + if (NULL == mContext) { + LOC_LOGD("%s:%d]: creating msgTask with tCreator", __func__, __LINE__); + const MsgTask* msgTask = getMsgTask(name); + mContext = new LocContext(msgTask); + } + pthread_mutex_unlock(&LocContext::mGetLocContextMutex); + + return mContext; +} + +void LocContext :: injectFeatureConfig(ContextBase *curContext) +{ + LOC_LOGD("%s:%d]: Calling LBSProxy (%p) to inject feature config", + __func__, __LINE__, ((LocContext *)curContext)->mLBSProxy); + ((LocContext *)curContext)->mLBSProxy->injectFeatureConfig(curContext); +} + +LocContext::LocContext(const MsgTask* msgTask) : + ContextBase(msgTask, 0, mLBSLibName) +{ +} + +} diff --git a/gps/core/LocContext.h b/gps/core/LocContext.h new file mode 100644 index 0000000..628ed93 --- /dev/null +++ b/gps/core/LocContext.h @@ -0,0 +1,60 @@ +/* Copyright (c) 2011-2014, 2017-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. + * + */ +#ifndef __LOC_CONTEXT__ +#define __LOC_CONTEXT__ + +#include <stdbool.h> +#include <ctype.h> +#include <dlfcn.h> +#include <ContextBase.h> + +namespace loc_core { + +class LocContext : public ContextBase { + static const MsgTask* mMsgTask; + static ContextBase* mContext; + static const MsgTask* getMsgTask(const char* name); + static pthread_mutex_t mGetLocContextMutex; + +protected: + LocContext(const MsgTask* msgTask); + inline virtual ~LocContext() {} + +public: + static const char* mLBSLibName; + static const char* mLocationHalName; + + static ContextBase* getLocContext(const char* name); + + static void injectFeatureConfig(ContextBase *context); +}; + +} + +#endif //__LOC_CONTEXT__ diff --git a/gps/core/Makefile.am b/gps/core/Makefile.am new file mode 100644 index 0000000..291dbb5 --- /dev/null +++ b/gps/core/Makefile.am @@ -0,0 +1,74 @@ +ACLOCAL_AMFLAGS = -I m4 + +AM_CFLAGS = -I./ \ + $(LOCPLA_CFLAGS) \ + $(GPSUTILS_CFLAGS) \ + -I./data-items/ \ + -I./data-items/common \ + -I./observer \ + -I$(WORKSPACE)/gps-noship/flp \ + -D__func__=__PRETTY_FUNCTION__ \ + -fno-short-enums \ + -std=c++11 + +libloc_core_la_h_sources = \ + LocApiBase.h \ + LocAdapterBase.h \ + ContextBase.h \ + LocContext.h \ + LBSProxyBase.h \ + loc_core_log.h \ + LocAdapterProxyBase.h \ + EngineHubProxyBase.h \ + data-items/DataItemId.h \ + data-items/IDataItemCore.h \ + data-items/DataItemConcreteTypesBase.h \ + observer/IDataItemObserver.h \ + observer/IDataItemSubscription.h \ + observer/IFrameworkActionReq.h \ + observer/IOsObserver.h \ + SystemStatusOsObserver.h \ + SystemStatus.h + +libloc_core_la_c_sources = \ + LocApiBase.cpp \ + LocAdapterBase.cpp \ + ContextBase.cpp \ + LocContext.cpp \ + loc_core_log.cpp \ + data-items/DataItemsFactoryProxy.cpp \ + SystemStatusOsObserver.cpp \ + SystemStatus.cpp + +if USE_EXTERNAL_AP +AM_CFLAGS += -DFEATURE_EXTERNAL_AP +endif + +library_includedir = $(pkgincludedir) + +library_include_HEADERS = $(libloc_core_la_h_sources) + +libloc_core_la_SOURCES = $(libloc_core_la_c_sources) + +if USE_GLIB +libloc_core_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@ +libloc_core_la_LDFLAGS = -lstdc++ -Wl,-z,defs -lpthread @GLIB_LIBS@ -shared -version-info 1:0:0 +libloc_core_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@ +else +libloc_core_la_CFLAGS = $(AM_CFLAGS) +libloc_core_la_LDFLAGS = -Wl,-z,defs -lpthread -shared -version-info 1:0:0 +libloc_core_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS) +endif + +if USE_FEATURE_AUTOMOTIVE +AM_CFLAGS += -DFEATURE_AUTOMOTIVE +endif + +libloc_core_la_LIBADD = -ldl $(GPSUTILS_LIBS) + +#Create and Install libraries +lib_LTLIBRARIES = libloc_core.la + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = loc-core.pc +EXTRA_DIST = $(pkgconfig_DATA) diff --git a/gps/core/SystemStatus.cpp b/gps/core/SystemStatus.cpp new file mode 100644 index 0000000..d792577 --- /dev/null +++ b/gps/core/SystemStatus.cpp @@ -0,0 +1,1760 @@ +/* Copyright (c) 2017-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_SystemStatus" + +#include <inttypes.h> +#include <string> +#include <stdlib.h> +#include <string.h> +#include <sys/time.h> +#include <pthread.h> +#include <loc_pla.h> +#include <log_util.h> +#include <loc_nmea.h> +#include <DataItemsFactoryProxy.h> +#include <SystemStatus.h> +#include <SystemStatusOsObserver.h> +#include <DataItemConcreteTypesBase.h> + +namespace loc_core +{ + +/****************************************************************************** + SystemStatusNmeaBase - base class for all NMEA parsers +******************************************************************************/ +class SystemStatusNmeaBase +{ +protected: + std::vector<std::string> mField; + + SystemStatusNmeaBase(const char *str_in, uint32_t len_in) + { + // check size and talker + if (!loc_nmea_is_debug(str_in, len_in)) { + return; + } + + std::string parser(str_in); + std::string::size_type index = 0; + + // verify checksum field + index = parser.find("*"); + if (index == std::string::npos) { + return; + } + parser[index] = ','; + + // tokenize parser + while (1) { + std::string str; + index = parser.find(","); + if (index == std::string::npos) { + break; + } + str = parser.substr(0, index); + parser = parser.substr(index + 1); + mField.push_back(str); + } + } + + virtual ~SystemStatusNmeaBase() { } + +public: + static const uint32_t NMEA_MINSIZE = DEBUG_NMEA_MINSIZE; + static const uint32_t NMEA_MAXSIZE = DEBUG_NMEA_MAXSIZE; +}; + +/****************************************************************************** + SystemStatusPQWM1 +******************************************************************************/ +class SystemStatusPQWM1 +{ +public: + uint16_t mGpsWeek; // x1 + uint32_t mGpsTowMs; // x2 + uint8_t mTimeValid; // x3 + uint8_t mTimeSource; // x4 + int32_t mTimeUnc; // x5 + int32_t mClockFreqBias; // x6 + int32_t mClockFreqBiasUnc; // x7 + uint8_t mXoState; // x8 + int32_t mPgaGain; // x9 + uint32_t mGpsBpAmpI; // xA + uint32_t mGpsBpAmpQ; // xB + uint32_t mAdcI; // xC + uint32_t mAdcQ; // xD + uint32_t mJammerGps; // xE + uint32_t mJammerGlo; // xF + uint32_t mJammerBds; // x10 + uint32_t mJammerGal; // x11 + uint32_t mRecErrorRecovery; // x12 + double mAgcGps; // x13 + double mAgcGlo; // x14 + double mAgcBds; // x15 + double mAgcGal; // x16 + int32_t mLeapSeconds;// x17 + int32_t mLeapSecUnc; // x18 + uint32_t mGloBpAmpI; // x19 + uint32_t mGloBpAmpQ; // x1A + uint32_t mBdsBpAmpI; // x1B + uint32_t mBdsBpAmpQ; // x1C + uint32_t mGalBpAmpI; // x1D + uint32_t mGalBpAmpQ; // x1E + uint64_t mTimeUncNs; // x1F +}; + +// parser +class SystemStatusPQWM1parser : public SystemStatusNmeaBase +{ +private: + enum + { + eTalker = 0, + eGpsWeek = 1, + eGpsTowMs = 2, + eTimeValid = 3, + eTimeSource = 4, + eTimeUnc = 5, + eClockFreqBias = 6, + eClockFreqBiasUnc = 7, + eXoState = 8, + ePgaGain = 9, + eGpsBpAmpI = 10, + eGpsBpAmpQ = 11, + eAdcI = 12, + eAdcQ = 13, + eJammerGps = 14, + eJammerGlo = 15, + eJammerBds = 16, + eJammerGal = 17, + eRecErrorRecovery = 18, + eAgcGps = 19, + eAgcGlo = 20, + eAgcBds = 21, + eAgcGal = 22, + eMax0 = eAgcGal, + eLeapSeconds = 23, + eLeapSecUnc = 24, + eGloBpAmpI = 25, + eGloBpAmpQ = 26, + eBdsBpAmpI = 27, + eBdsBpAmpQ = 28, + eGalBpAmpI = 29, + eGalBpAmpQ = 30, + eTimeUncNs = 31, + eMax + }; + SystemStatusPQWM1 mM1; + +public: + inline uint16_t getGpsWeek() { return mM1.mGpsWeek; } + inline uint32_t getGpsTowMs() { return mM1.mGpsTowMs; } + inline uint8_t getTimeValid() { return mM1.mTimeValid; } + inline uint8_t getTimeSource() { return mM1.mTimeSource; } + inline int32_t getTimeUnc() { return mM1.mTimeUnc; } + inline int32_t getClockFreqBias() { return mM1.mClockFreqBias; } + inline int32_t getClockFreqBiasUnc() { return mM1.mClockFreqBiasUnc; } + inline uint8_t getXoState() { return mM1.mXoState;} + inline int32_t getPgaGain() { return mM1.mPgaGain; } + inline uint32_t getGpsBpAmpI() { return mM1.mGpsBpAmpI; } + inline uint32_t getGpsBpAmpQ() { return mM1.mGpsBpAmpQ; } + inline uint32_t getAdcI() { return mM1.mAdcI; } + inline uint32_t getAdcQ() { return mM1.mAdcQ; } + inline uint32_t getJammerGps() { return mM1.mJammerGps; } + inline uint32_t getJammerGlo() { return mM1.mJammerGlo; } + inline uint32_t getJammerBds() { return mM1.mJammerBds; } + inline uint32_t getJammerGal() { return mM1.mJammerGal; } + inline uint32_t getAgcGps() { return mM1.mAgcGps; } + inline uint32_t getAgcGlo() { return mM1.mAgcGlo; } + inline uint32_t getAgcBds() { return mM1.mAgcBds; } + inline uint32_t getAgcGal() { return mM1.mAgcGal; } + inline uint32_t getRecErrorRecovery() { return mM1.mRecErrorRecovery; } + inline int32_t getLeapSeconds(){ return mM1.mLeapSeconds; } + inline int32_t getLeapSecUnc() { return mM1.mLeapSecUnc; } + inline uint32_t getGloBpAmpI() { return mM1.mGloBpAmpI; } + inline uint32_t getGloBpAmpQ() { return mM1.mGloBpAmpQ; } + inline uint32_t getBdsBpAmpI() { return mM1.mBdsBpAmpI; } + inline uint32_t getBdsBpAmpQ() { return mM1.mBdsBpAmpQ; } + inline uint32_t getGalBpAmpI() { return mM1.mGalBpAmpI; } + inline uint32_t getGalBpAmpQ() { return mM1.mGalBpAmpQ; } + inline uint64_t getTimeUncNs() { return mM1.mTimeUncNs; } + + SystemStatusPQWM1parser(const char *str_in, uint32_t len_in) + : SystemStatusNmeaBase(str_in, len_in) + { + memset(&mM1, 0, sizeof(mM1)); + if (mField.size() <= eMax0) { + LOC_LOGE("PQWM1parser - invalid size=%zu", mField.size()); + mM1.mTimeValid = 0; + return; + } + mM1.mGpsWeek = atoi(mField[eGpsWeek].c_str()); + mM1.mGpsTowMs = atoi(mField[eGpsTowMs].c_str()); + mM1.mTimeValid = atoi(mField[eTimeValid].c_str()); + mM1.mTimeSource = atoi(mField[eTimeSource].c_str()); + mM1.mTimeUnc = atoi(mField[eTimeUnc].c_str()); + mM1.mClockFreqBias = atoi(mField[eClockFreqBias].c_str()); + mM1.mClockFreqBiasUnc = atoi(mField[eClockFreqBiasUnc].c_str()); + mM1.mXoState = atoi(mField[eXoState].c_str()); + mM1.mPgaGain = atoi(mField[ePgaGain].c_str()); + mM1.mGpsBpAmpI = atoi(mField[eGpsBpAmpI].c_str()); + mM1.mGpsBpAmpQ = atoi(mField[eGpsBpAmpQ].c_str()); + mM1.mAdcI = atoi(mField[eAdcI].c_str()); + mM1.mAdcQ = atoi(mField[eAdcQ].c_str()); + mM1.mJammerGps = atoi(mField[eJammerGps].c_str()); + mM1.mJammerGlo = atoi(mField[eJammerGlo].c_str()); + mM1.mJammerBds = atoi(mField[eJammerBds].c_str()); + mM1.mJammerGal = atoi(mField[eJammerGal].c_str()); + mM1.mRecErrorRecovery = atoi(mField[eRecErrorRecovery].c_str()); + mM1.mAgcGps = atof(mField[eAgcGps].c_str()); + mM1.mAgcGlo = atof(mField[eAgcGlo].c_str()); + mM1.mAgcBds = atof(mField[eAgcBds].c_str()); + mM1.mAgcGal = atof(mField[eAgcGal].c_str()); + if (mField.size() > eLeapSecUnc) { + mM1.mLeapSeconds = atoi(mField[eLeapSeconds].c_str()); + mM1.mLeapSecUnc = atoi(mField[eLeapSecUnc].c_str()); + } + if (mField.size() > eGalBpAmpQ) { + mM1.mGloBpAmpI = atoi(mField[eGloBpAmpI].c_str()); + mM1.mGloBpAmpQ = atoi(mField[eGloBpAmpQ].c_str()); + mM1.mBdsBpAmpI = atoi(mField[eBdsBpAmpI].c_str()); + mM1.mBdsBpAmpQ = atoi(mField[eBdsBpAmpQ].c_str()); + mM1.mGalBpAmpI = atoi(mField[eGalBpAmpI].c_str()); + mM1.mGalBpAmpQ = atoi(mField[eGalBpAmpQ].c_str()); + } + if (mField.size() > eTimeUncNs) { + mM1.mTimeUncNs = strtoull(mField[eTimeUncNs].c_str(), nullptr, 10); + } + } + + inline SystemStatusPQWM1& get() { return mM1;} //getparser +}; + +/****************************************************************************** + SystemStatusPQWP1 +******************************************************************************/ +class SystemStatusPQWP1 +{ +public: + uint8_t mEpiValidity; // x4 + float mEpiLat; // x5 + float mEpiLon; // x6 + float mEpiAlt; // x7 + float mEpiHepe; // x8 + float mEpiAltUnc; // x9 + uint8_t mEpiSrc; // x10 +}; + +class SystemStatusPQWP1parser : public SystemStatusNmeaBase +{ +private: + enum + { + eTalker = 0, + eUtcTime = 1, + eEpiValidity = 2, + eEpiLat = 3, + eEpiLon = 4, + eEpiAlt = 5, + eEpiHepe = 6, + eEpiAltUnc = 7, + eEpiSrc = 8, + eMax + }; + SystemStatusPQWP1 mP1; + +public: + inline uint8_t getEpiValidity() { return mP1.mEpiValidity; } + inline float getEpiLat() { return mP1.mEpiLat; } + inline float getEpiLon() { return mP1.mEpiLon; } + inline float getEpiAlt() { return mP1.mEpiAlt; } + inline float getEpiHepe() { return mP1.mEpiHepe; } + inline float getEpiAltUnc() { return mP1.mEpiAltUnc; } + inline uint8_t getEpiSrc() { return mP1.mEpiSrc; } + + SystemStatusPQWP1parser(const char *str_in, uint32_t len_in) + : SystemStatusNmeaBase(str_in, len_in) + { + if (mField.size() < eMax) { + return; + } + memset(&mP1, 0, sizeof(mP1)); + mP1.mEpiValidity = strtol(mField[eEpiValidity].c_str(), NULL, 16); + mP1.mEpiLat = atof(mField[eEpiLat].c_str()); + mP1.mEpiLon = atof(mField[eEpiLon].c_str()); + mP1.mEpiAlt = atof(mField[eEpiAlt].c_str()); + mP1.mEpiHepe = atoi(mField[eEpiHepe].c_str()); + mP1.mEpiAltUnc = atof(mField[eEpiAltUnc].c_str()); + mP1.mEpiSrc = atoi(mField[eEpiSrc].c_str()); + } + + inline SystemStatusPQWP1& get() { return mP1;} +}; + +/****************************************************************************** + SystemStatusPQWP2 +******************************************************************************/ +class SystemStatusPQWP2 +{ +public: + float mBestLat; // x4 + float mBestLon; // x5 + float mBestAlt; // x6 + float mBestHepe; // x7 + float mBestAltUnc; // x8 +}; + +class SystemStatusPQWP2parser : public SystemStatusNmeaBase +{ +private: + enum + { + eTalker = 0, + eUtcTime = 1, + eBestLat = 2, + eBestLon = 3, + eBestAlt = 4, + eBestHepe = 5, + eBestAltUnc = 6, + eMax + }; + SystemStatusPQWP2 mP2; + +public: + inline float getBestLat() { return mP2.mBestLat; } + inline float getBestLon() { return mP2.mBestLon; } + inline float getBestAlt() { return mP2.mBestAlt; } + inline float getBestHepe() { return mP2.mBestHepe; } + inline float getBestAltUnc() { return mP2.mBestAltUnc; } + + SystemStatusPQWP2parser(const char *str_in, uint32_t len_in) + : SystemStatusNmeaBase(str_in, len_in) + { + if (mField.size() < eMax) { + return; + } + memset(&mP2, 0, sizeof(mP2)); + mP2.mBestLat = atof(mField[eBestLat].c_str()); + mP2.mBestLon = atof(mField[eBestLon].c_str()); + mP2.mBestAlt = atof(mField[eBestAlt].c_str()); + mP2.mBestHepe = atof(mField[eBestHepe].c_str()); + mP2.mBestAltUnc = atof(mField[eBestAltUnc].c_str()); + } + + inline SystemStatusPQWP2& get() { return mP2;} +}; + +/****************************************************************************** + SystemStatusPQWP3 +******************************************************************************/ +class SystemStatusPQWP3 +{ +public: + uint8_t mXtraValidMask; + uint32_t mGpsXtraAge; + uint32_t mGloXtraAge; + uint32_t mBdsXtraAge; + uint32_t mGalXtraAge; + uint32_t mQzssXtraAge; + uint32_t mNavicXtraAge; + uint32_t mGpsXtraValid; + uint32_t mGloXtraValid; + uint64_t mBdsXtraValid; + uint64_t mGalXtraValid; + uint8_t mQzssXtraValid; + uint32_t mNavicXtraValid; +}; + +class SystemStatusPQWP3parser : public SystemStatusNmeaBase +{ +private: + // todo: update for navic once available + enum + { + eTalker = 0, + eUtcTime = 1, + eXtraValidMask = 2, + eGpsXtraAge = 3, + eGloXtraAge = 4, + eBdsXtraAge = 5, + eGalXtraAge = 6, + eQzssXtraAge = 7, + eGpsXtraValid = 8, + eGloXtraValid = 9, + eBdsXtraValid = 10, + eGalXtraValid = 11, + eQzssXtraValid = 12, + eMax + }; + SystemStatusPQWP3 mP3; + +public: + inline uint8_t getXtraValid() { return mP3.mXtraValidMask; } + inline uint32_t getGpsXtraAge() { return mP3.mGpsXtraAge; } + inline uint32_t getGloXtraAge() { return mP3.mGloXtraAge; } + inline uint32_t getBdsXtraAge() { return mP3.mBdsXtraAge; } + inline uint32_t getGalXtraAge() { return mP3.mGalXtraAge; } + inline uint32_t getQzssXtraAge() { return mP3.mQzssXtraAge; } + inline uint32_t getNavicXtraAge() { return mP3.mNavicXtraAge; } + inline uint32_t getGpsXtraValid() { return mP3.mGpsXtraValid; } + inline uint32_t getGloXtraValid() { return mP3.mGloXtraValid; } + inline uint64_t getBdsXtraValid() { return mP3.mBdsXtraValid; } + inline uint64_t getGalXtraValid() { return mP3.mGalXtraValid; } + inline uint8_t getQzssXtraValid() { return mP3.mQzssXtraValid; } + inline uint32_t getNavicXtraValid() { return mP3.mNavicXtraValid; } + + SystemStatusPQWP3parser(const char *str_in, uint32_t len_in) + : SystemStatusNmeaBase(str_in, len_in) + { + if (mField.size() < eMax) { + return; + } + memset(&mP3, 0, sizeof(mP3)); + // todo: update for navic once available + mP3.mXtraValidMask = strtol(mField[eXtraValidMask].c_str(), NULL, 16); + mP3.mGpsXtraAge = atoi(mField[eGpsXtraAge].c_str()); + mP3.mGloXtraAge = atoi(mField[eGloXtraAge].c_str()); + mP3.mBdsXtraAge = atoi(mField[eBdsXtraAge].c_str()); + mP3.mGalXtraAge = atoi(mField[eGalXtraAge].c_str()); + mP3.mQzssXtraAge = atoi(mField[eQzssXtraAge].c_str()); + mP3.mGpsXtraValid = strtol(mField[eGpsXtraValid].c_str(), NULL, 16); + mP3.mGloXtraValid = strtol(mField[eGloXtraValid].c_str(), NULL, 16); + mP3.mBdsXtraValid = strtol(mField[eBdsXtraValid].c_str(), NULL, 16); + mP3.mGalXtraValid = strtol(mField[eGalXtraValid].c_str(), NULL, 16); + mP3.mQzssXtraValid = strtol(mField[eQzssXtraValid].c_str(), NULL, 16); + } + + inline SystemStatusPQWP3& get() { return mP3;} +}; + +/****************************************************************************** + SystemStatusPQWP4 +******************************************************************************/ +class SystemStatusPQWP4 +{ +public: + uint32_t mGpsEpheValid; + uint32_t mGloEpheValid; + uint64_t mBdsEpheValid; + uint64_t mGalEpheValid; + uint8_t mQzssEpheValid; +}; + +class SystemStatusPQWP4parser : public SystemStatusNmeaBase +{ +private: + enum + { + eTalker = 0, + eUtcTime = 1, + eGpsEpheValid = 2, + eGloEpheValid = 3, + eBdsEpheValid = 4, + eGalEpheValid = 5, + eQzssEpheValid = 6, + eMax + }; + SystemStatusPQWP4 mP4; + +public: + inline uint32_t getGpsEpheValid() { return mP4.mGpsEpheValid; } + inline uint32_t getGloEpheValid() { return mP4.mGloEpheValid; } + inline uint64_t getBdsEpheValid() { return mP4.mBdsEpheValid; } + inline uint64_t getGalEpheValid() { return mP4.mGalEpheValid; } + inline uint8_t getQzssEpheValid() { return mP4.mQzssEpheValid; } + + SystemStatusPQWP4parser(const char *str_in, uint32_t len_in) + : SystemStatusNmeaBase(str_in, len_in) + { + if (mField.size() < eMax) { + return; + } + memset(&mP4, 0, sizeof(mP4)); + mP4.mGpsEpheValid = strtol(mField[eGpsEpheValid].c_str(), NULL, 16); + mP4.mGloEpheValid = strtol(mField[eGloEpheValid].c_str(), NULL, 16); + mP4.mBdsEpheValid = strtol(mField[eBdsEpheValid].c_str(), NULL, 16); + mP4.mGalEpheValid = strtol(mField[eGalEpheValid].c_str(), NULL, 16); + mP4.mQzssEpheValid = strtol(mField[eQzssEpheValid].c_str(), NULL, 16); + } + + inline SystemStatusPQWP4& get() { return mP4;} +}; + +/****************************************************************************** + SystemStatusPQWP5 +******************************************************************************/ +class SystemStatusPQWP5 +{ +public: + uint32_t mGpsUnknownMask; + uint32_t mGloUnknownMask; + uint64_t mBdsUnknownMask; + uint64_t mGalUnknownMask; + uint8_t mQzssUnknownMask; + uint32_t mNavicUnknownMask; + uint32_t mGpsGoodMask; + uint32_t mGloGoodMask; + uint64_t mBdsGoodMask; + uint64_t mGalGoodMask; + uint8_t mQzssGoodMask; + uint32_t mNavicGoodMask; + uint32_t mGpsBadMask; + uint32_t mGloBadMask; + uint64_t mBdsBadMask; + uint64_t mGalBadMask; + uint8_t mQzssBadMask; + uint32_t mNavicBadMask; +}; + +class SystemStatusPQWP5parser : public SystemStatusNmeaBase +{ +private: + // todo: update for navic once available + enum + { + eTalker = 0, + eUtcTime = 1, + eGpsUnknownMask = 2, + eGloUnknownMask = 3, + eBdsUnknownMask = 4, + eGalUnknownMask = 5, + eQzssUnknownMask = 6, + eGpsGoodMask = 7, + eGloGoodMask = 8, + eBdsGoodMask = 9, + eGalGoodMask = 10, + eQzssGoodMask = 11, + eGpsBadMask = 12, + eGloBadMask = 13, + eBdsBadMask = 14, + eGalBadMask = 15, + eQzssBadMask = 16, + eMax + }; + SystemStatusPQWP5 mP5; + +public: + inline uint32_t getGpsUnknownMask() { return mP5.mGpsUnknownMask; } + inline uint32_t getGloUnknownMask() { return mP5.mGloUnknownMask; } + inline uint64_t getBdsUnknownMask() { return mP5.mBdsUnknownMask; } + inline uint64_t getGalUnknownMask() { return mP5.mGalUnknownMask; } + inline uint8_t getQzssUnknownMask() { return mP5.mQzssUnknownMask; } + inline uint32_t getNavicUnknownMask() { return mP5.mNavicUnknownMask; } + inline uint32_t getGpsGoodMask() { return mP5.mGpsGoodMask; } + inline uint32_t getGloGoodMask() { return mP5.mGloGoodMask; } + inline uint64_t getBdsGoodMask() { return mP5.mBdsGoodMask; } + inline uint64_t getGalGoodMask() { return mP5.mGalGoodMask; } + inline uint8_t getQzssGoodMask() { return mP5.mQzssGoodMask; } + inline uint32_t getNavicGoodMask() { return mP5.mNavicGoodMask; } + inline uint32_t getGpsBadMask() { return mP5.mGpsBadMask; } + inline uint32_t getGloBadMask() { return mP5.mGloBadMask; } + inline uint64_t getBdsBadMask() { return mP5.mBdsBadMask; } + inline uint64_t getGalBadMask() { return mP5.mGalBadMask; } + inline uint8_t getQzssBadMask() { return mP5.mQzssBadMask; } + inline uint32_t getNavicBadMask() { return mP5.mNavicBadMask; } + + SystemStatusPQWP5parser(const char *str_in, uint32_t len_in) + : SystemStatusNmeaBase(str_in, len_in) + { + if (mField.size() < eMax) { + return; + } + memset(&mP5, 0, sizeof(mP5)); + // todo: update for navic once available + mP5.mGpsUnknownMask = strtol(mField[eGpsUnknownMask].c_str(), NULL, 16); + mP5.mGloUnknownMask = strtol(mField[eGloUnknownMask].c_str(), NULL, 16); + mP5.mBdsUnknownMask = strtol(mField[eBdsUnknownMask].c_str(), NULL, 16); + mP5.mGalUnknownMask = strtol(mField[eGalUnknownMask].c_str(), NULL, 16); + mP5.mQzssUnknownMask = strtol(mField[eQzssUnknownMask].c_str(), NULL, 16); + mP5.mGpsGoodMask = strtol(mField[eGpsGoodMask].c_str(), NULL, 16); + mP5.mGloGoodMask = strtol(mField[eGloGoodMask].c_str(), NULL, 16); + mP5.mBdsGoodMask = strtol(mField[eBdsGoodMask].c_str(), NULL, 16); + mP5.mGalGoodMask = strtol(mField[eGalGoodMask].c_str(), NULL, 16); + mP5.mQzssGoodMask = strtol(mField[eQzssGoodMask].c_str(), NULL, 16); + mP5.mGpsBadMask = strtol(mField[eGpsBadMask].c_str(), NULL, 16); + mP5.mGloBadMask = strtol(mField[eGloBadMask].c_str(), NULL, 16); + mP5.mBdsBadMask = strtol(mField[eBdsBadMask].c_str(), NULL, 16); + mP5.mGalBadMask = strtol(mField[eGalBadMask].c_str(), NULL, 16); + mP5.mQzssBadMask = strtol(mField[eQzssBadMask].c_str(), NULL, 16); + } + + inline SystemStatusPQWP5& get() { return mP5;} +}; + +/****************************************************************************** + SystemStatusPQWP6parser +******************************************************************************/ +class SystemStatusPQWP6 +{ +public: + uint32_t mFixInfoMask; +}; + +class SystemStatusPQWP6parser : public SystemStatusNmeaBase +{ +private: + enum + { + eTalker = 0, + eUtcTime = 1, + eFixInfoMask = 2, + eMax + }; + SystemStatusPQWP6 mP6; + +public: + inline uint32_t getFixInfoMask() { return mP6.mFixInfoMask; } + + SystemStatusPQWP6parser(const char *str_in, uint32_t len_in) + : SystemStatusNmeaBase(str_in, len_in) + { + if (mField.size() < eMax) { + return; + } + memset(&mP6, 0, sizeof(mP6)); + mP6.mFixInfoMask = strtol(mField[eFixInfoMask].c_str(), NULL, 16); + } + + inline SystemStatusPQWP6& get() { return mP6;} +}; + +/****************************************************************************** + SystemStatusPQWP7parser +******************************************************************************/ +class SystemStatusPQWP7 +{ +public: + SystemStatusNav mNav[SV_ALL_NUM]; +}; + +class SystemStatusPQWP7parser : public SystemStatusNmeaBase +{ +private: + enum + { + eTalker = 0, + eUtcTime = 1, + eMin = 2 + SV_ALL_NUM_MIN*3, + eMax = 2 + SV_ALL_NUM*3 + }; + SystemStatusPQWP7 mP7; + +public: + SystemStatusPQWP7parser(const char *str_in, uint32_t len_in) + : SystemStatusNmeaBase(str_in, len_in) + { + uint32_t svLimit = SV_ALL_NUM; + if (mField.size() < eMin) { + LOC_LOGE("PQWP7parser - invalid size=%zu", mField.size()); + return; + } + if (mField.size() < eMax) { + // Try reducing limit, accounting for possibly missing NAVIC support + svLimit = SV_ALL_NUM_MIN; + } + + memset(mP7.mNav, 0, sizeof(mP7.mNav)); + for (uint32_t i=0; i<svLimit; i++) { + mP7.mNav[i].mType = GnssEphemerisType(atoi(mField[i*3+2].c_str())); + mP7.mNav[i].mSource = GnssEphemerisSource(atoi(mField[i*3+3].c_str())); + mP7.mNav[i].mAgeSec = atoi(mField[i*3+4].c_str()); + } + } + + inline SystemStatusPQWP7& get() { return mP7;} +}; + +/****************************************************************************** + SystemStatusPQWS1parser +******************************************************************************/ +class SystemStatusPQWS1 +{ +public: + uint32_t mFixInfoMask; + uint32_t mHepeLimit; +}; + +class SystemStatusPQWS1parser : public SystemStatusNmeaBase +{ +private: + enum + { + eTalker = 0, + eUtcTime = 1, + eFixInfoMask = 2, + eHepeLimit = 3, + eMax + }; + SystemStatusPQWS1 mS1; + +public: + inline uint16_t getFixInfoMask() { return mS1.mFixInfoMask; } + inline uint32_t getHepeLimit() { return mS1.mHepeLimit; } + + SystemStatusPQWS1parser(const char *str_in, uint32_t len_in) + : SystemStatusNmeaBase(str_in, len_in) + { + if (mField.size() < eMax) { + return; + } + memset(&mS1, 0, sizeof(mS1)); + mS1.mFixInfoMask = atoi(mField[eFixInfoMask].c_str()); + mS1.mHepeLimit = atoi(mField[eHepeLimit].c_str()); + } + + inline SystemStatusPQWS1& get() { return mS1;} +}; + +/****************************************************************************** + SystemStatusTimeAndClock +******************************************************************************/ +SystemStatusTimeAndClock::SystemStatusTimeAndClock(const SystemStatusPQWM1& nmea) : + mGpsWeek(nmea.mGpsWeek), + mGpsTowMs(nmea.mGpsTowMs), + mTimeValid(nmea.mTimeValid), + mTimeSource(nmea.mTimeSource), + mTimeUnc(nmea.mTimeUnc), + mClockFreqBias(nmea.mClockFreqBias), + mClockFreqBiasUnc(nmea.mClockFreqBiasUnc), + mLeapSeconds(nmea.mLeapSeconds), + mLeapSecUnc(nmea.mLeapSecUnc), + mTimeUncNs(nmea.mTimeUncNs) +{ +} + +bool SystemStatusTimeAndClock::equals(const SystemStatusTimeAndClock& peer) +{ + if ((mGpsWeek != peer.mGpsWeek) || + (mGpsTowMs != peer.mGpsTowMs) || + (mTimeValid != peer.mTimeValid) || + (mTimeSource != peer.mTimeSource) || + (mTimeUnc != peer.mTimeUnc) || + (mClockFreqBias != peer.mClockFreqBias) || + (mClockFreqBiasUnc != peer.mClockFreqBiasUnc) || + (mLeapSeconds != peer.mLeapSeconds) || + (mLeapSecUnc != peer.mLeapSecUnc) || + (mTimeUncNs != peer.mTimeUncNs)) { + return false; + } + return true; +} + +void SystemStatusTimeAndClock::dump() +{ + LOC_LOGV("TimeAndClock: u=%ld:%ld g=%d:%d v=%d ts=%d tu=%d b=%d bu=%d ls=%d lu=%d un=%" PRIu64, + mUtcTime.tv_sec, mUtcTime.tv_nsec, + mGpsWeek, + mGpsTowMs, + mTimeValid, + mTimeSource, + mTimeUnc, + mClockFreqBias, + mClockFreqBiasUnc, + mLeapSeconds, + mLeapSecUnc, + mTimeUncNs); + return; +} + +/****************************************************************************** + SystemStatusXoState +******************************************************************************/ +SystemStatusXoState::SystemStatusXoState(const SystemStatusPQWM1& nmea) : + mXoState(nmea.mXoState) +{ +} + +bool SystemStatusXoState::equals(const SystemStatusXoState& peer) +{ + if (mXoState != peer.mXoState) { + return false; + } + return true; +} + +void SystemStatusXoState::dump() +{ + LOC_LOGV("XoState: u=%ld:%ld x=%d", + mUtcTime.tv_sec, mUtcTime.tv_nsec, + mXoState); + return; +} + +/****************************************************************************** + SystemStatusRfAndParams +******************************************************************************/ +SystemStatusRfAndParams::SystemStatusRfAndParams(const SystemStatusPQWM1& nmea) : + mPgaGain(nmea.mPgaGain), + mGpsBpAmpI(nmea.mGpsBpAmpI), + mGpsBpAmpQ(nmea.mGpsBpAmpQ), + mAdcI(nmea.mAdcI), + mAdcQ(nmea.mAdcQ), + mJammerGps(nmea.mJammerGps), + mJammerGlo(nmea.mJammerGlo), + mJammerBds(nmea.mJammerBds), + mJammerGal(nmea.mJammerGal), + mAgcGps(nmea.mAgcGps), + mAgcGlo(nmea.mAgcGlo), + mAgcBds(nmea.mAgcBds), + mAgcGal(nmea.mAgcGal), + mGloBpAmpI(nmea.mGloBpAmpI), + mGloBpAmpQ(nmea.mGloBpAmpQ), + mBdsBpAmpI(nmea.mBdsBpAmpI), + mBdsBpAmpQ(nmea.mBdsBpAmpQ), + mGalBpAmpI(nmea.mGalBpAmpI), + mGalBpAmpQ(nmea.mGalBpAmpQ) +{ +} + +bool SystemStatusRfAndParams::equals(const SystemStatusRfAndParams& peer) +{ + if ((mPgaGain != peer.mPgaGain) || + (mGpsBpAmpI != peer.mGpsBpAmpI) || + (mGpsBpAmpQ != peer.mGpsBpAmpQ) || + (mAdcI != peer.mAdcI) || + (mAdcQ != peer.mAdcQ) || + (mJammerGps != peer.mJammerGps) || + (mJammerGlo != peer.mJammerGlo) || + (mJammerBds != peer.mJammerBds) || + (mJammerGal != peer.mJammerGal) || + (mAgcGps != peer.mAgcGps) || + (mAgcGlo != peer.mAgcGlo) || + (mAgcBds != peer.mAgcBds) || + (mAgcGal != peer.mAgcGal) || + (mGloBpAmpI != peer.mGloBpAmpI) || + (mGloBpAmpQ != peer.mGloBpAmpQ) || + (mBdsBpAmpI != peer.mBdsBpAmpI) || + (mBdsBpAmpQ != peer.mBdsBpAmpQ) || + (mGalBpAmpI != peer.mGalBpAmpI) || + (mGalBpAmpQ != peer.mGalBpAmpQ)) { + return false; + } + return true; +} + +void SystemStatusRfAndParams::dump() +{ + LOC_LOGV("RfAndParams: u=%ld:%ld p=%d bi=%d bq=%d ai=%d aq=%d " + "jgp=%d jgl=%d jbd=%d jga=%d " + "agp=%lf agl=%lf abd=%lf aga=%lf", + mUtcTime.tv_sec, mUtcTime.tv_nsec, + mPgaGain, + mGpsBpAmpI, + mGpsBpAmpQ, + mAdcI, + mAdcQ, + mJammerGps, + mJammerGlo, + mJammerBds, + mJammerGal, + mAgcGps, + mAgcGlo, + mAgcBds, + mAgcGal); + return; +} + +/****************************************************************************** + SystemStatusErrRecovery +******************************************************************************/ +SystemStatusErrRecovery::SystemStatusErrRecovery(const SystemStatusPQWM1& nmea) : + mRecErrorRecovery(nmea.mRecErrorRecovery) +{ +} + +bool SystemStatusErrRecovery::equals(const SystemStatusErrRecovery& peer) +{ + if (mRecErrorRecovery != peer.mRecErrorRecovery) { + return false; + } + return true; +} + +void SystemStatusErrRecovery::dump() +{ + LOC_LOGV("ErrRecovery: u=%ld:%ld e=%d", + mUtcTime.tv_sec, mUtcTime.tv_nsec, + mRecErrorRecovery); + return; +} + +/****************************************************************************** + SystemStatusInjectedPosition +******************************************************************************/ +SystemStatusInjectedPosition::SystemStatusInjectedPosition(const SystemStatusPQWP1& nmea) : + mEpiValidity(nmea.mEpiValidity), + mEpiLat(nmea.mEpiLat), + mEpiLon(nmea.mEpiLon), + mEpiAlt(nmea.mEpiAlt), + mEpiHepe(nmea.mEpiHepe), + mEpiAltUnc(nmea.mEpiAltUnc), + mEpiSrc(nmea.mEpiSrc) +{ +} + +bool SystemStatusInjectedPosition::equals(const SystemStatusInjectedPosition& peer) +{ + if ((mEpiValidity != peer.mEpiValidity) || + (mEpiLat != peer.mEpiLat) || + (mEpiLon != peer.mEpiLon) || + (mEpiAlt != peer.mEpiAlt) || + (mEpiHepe != peer.mEpiHepe) || + (mEpiAltUnc != peer.mEpiAltUnc) || + (mEpiSrc != peer.mEpiSrc)) { + return false; + } + return true; +} + +void SystemStatusInjectedPosition::dump() +{ + LOC_LOGV("InjectedPosition: u=%ld:%ld v=%x la=%f lo=%f al=%f he=%f au=%f es=%d", + mUtcTime.tv_sec, mUtcTime.tv_nsec, + mEpiValidity, + mEpiLat, + mEpiLon, + mEpiAlt, + mEpiHepe, + mEpiAltUnc, + mEpiSrc); + return; +} + +/****************************************************************************** + SystemStatusBestPosition +******************************************************************************/ +SystemStatusBestPosition::SystemStatusBestPosition(const SystemStatusPQWP2& nmea) : + mValid(true), + mBestLat(nmea.mBestLat), + mBestLon(nmea.mBestLon), + mBestAlt(nmea.mBestAlt), + mBestHepe(nmea.mBestHepe), + mBestAltUnc(nmea.mBestAltUnc) +{ +} + +bool SystemStatusBestPosition::equals(const SystemStatusBestPosition& peer) +{ + if ((mBestLat != peer.mBestLat) || + (mBestLon != peer.mBestLon) || + (mBestAlt != peer.mBestAlt) || + (mBestHepe != peer.mBestHepe) || + (mBestAltUnc != peer.mBestAltUnc)) { + return false; + } + return true; +} + +void SystemStatusBestPosition::dump() +{ + LOC_LOGV("BestPosition: u=%ld:%ld la=%f lo=%f al=%f he=%f au=%f", + mUtcTime.tv_sec, mUtcTime.tv_nsec, + mBestLat, + mBestLon, + mBestAlt, + mBestHepe, + mBestAltUnc); + return; +} + +/****************************************************************************** + SystemStatusXtra +******************************************************************************/ +SystemStatusXtra::SystemStatusXtra(const SystemStatusPQWP3& nmea) : + mXtraValidMask(nmea.mXtraValidMask), + mGpsXtraAge(nmea.mGpsXtraAge), + mGloXtraAge(nmea.mGloXtraAge), + mBdsXtraAge(nmea.mBdsXtraAge), + mGalXtraAge(nmea.mGalXtraAge), + mQzssXtraAge(nmea.mQzssXtraAge), + mNavicXtraAge(nmea.mNavicXtraAge), + mGpsXtraValid(nmea.mGpsXtraValid), + mGloXtraValid(nmea.mGloXtraValid), + mBdsXtraValid(nmea.mBdsXtraValid), + mGalXtraValid(nmea.mGalXtraValid), + mQzssXtraValid(nmea.mQzssXtraValid), + mNavicXtraValid(nmea.mNavicXtraValid) +{ +} + +bool SystemStatusXtra::equals(const SystemStatusXtra& peer) +{ + if ((mXtraValidMask != peer.mXtraValidMask) || + (mGpsXtraAge != peer.mGpsXtraAge) || + (mGloXtraAge != peer.mGloXtraAge) || + (mBdsXtraAge != peer.mBdsXtraAge) || + (mGalXtraAge != peer.mGalXtraAge) || + (mQzssXtraAge != peer.mQzssXtraAge) || + (mNavicXtraAge != peer.mNavicXtraAge) || + (mGpsXtraValid != peer.mGpsXtraValid) || + (mGloXtraValid != peer.mGloXtraValid) || + (mBdsXtraValid != peer.mBdsXtraValid) || + (mGalXtraValid != peer.mGalXtraValid) || + (mQzssXtraValid != peer.mQzssXtraValid) || + (mNavicXtraValid != peer.mNavicXtraValid)) { + return false; + } + return true; +} + +void SystemStatusXtra::dump() +{ + LOC_LOGV("SystemStatusXtra: u=%ld:%ld m=%x a=%d:%d:%d:%d:%d v=%x:%x:%" PRIx64 ":%" PRIx64":%x", + mUtcTime.tv_sec, mUtcTime.tv_nsec, + mXtraValidMask, + mGpsXtraAge, + mGloXtraAge, + mBdsXtraAge, + mGalXtraAge, + mQzssXtraAge, + mGpsXtraValid, + mGloXtraValid, + mBdsXtraValid, + mGalXtraValid, + mQzssXtraValid); + return; +} + +/****************************************************************************** + SystemStatusEphemeris +******************************************************************************/ +SystemStatusEphemeris::SystemStatusEphemeris(const SystemStatusPQWP4& nmea) : + mGpsEpheValid(nmea.mGpsEpheValid), + mGloEpheValid(nmea.mGloEpheValid), + mBdsEpheValid(nmea.mBdsEpheValid), + mGalEpheValid(nmea.mGalEpheValid), + mQzssEpheValid(nmea.mQzssEpheValid) +{ +} + +bool SystemStatusEphemeris::equals(const SystemStatusEphemeris& peer) +{ + if ((mGpsEpheValid != peer.mGpsEpheValid) || + (mGloEpheValid != peer.mGloEpheValid) || + (mBdsEpheValid != peer.mBdsEpheValid) || + (mGalEpheValid != peer.mGalEpheValid) || + (mQzssEpheValid != peer.mQzssEpheValid)) { + return false; + } + return true; +} + +void SystemStatusEphemeris::dump() +{ + LOC_LOGV("Ephemeris: u=%ld:%ld ev=%x:%x:%" PRIx64 ":%" PRIx64 ":%x", + mUtcTime.tv_sec, mUtcTime.tv_nsec, + mGpsEpheValid, + mGloEpheValid, + mBdsEpheValid, + mGalEpheValid, + mQzssEpheValid); + return; +} + +/****************************************************************************** + SystemStatusSvHealth +******************************************************************************/ +SystemStatusSvHealth::SystemStatusSvHealth(const SystemStatusPQWP5& nmea) : + mGpsUnknownMask(nmea.mGpsUnknownMask), + mGloUnknownMask(nmea.mGloUnknownMask), + mBdsUnknownMask(nmea.mBdsUnknownMask), + mGalUnknownMask(nmea.mGalUnknownMask), + mQzssUnknownMask(nmea.mQzssUnknownMask), + mNavicUnknownMask(nmea.mNavicUnknownMask), + mGpsGoodMask(nmea.mGpsGoodMask), + mGloGoodMask(nmea.mGloGoodMask), + mBdsGoodMask(nmea.mBdsGoodMask), + mGalGoodMask(nmea.mGalGoodMask), + mQzssGoodMask(nmea.mQzssGoodMask), + mNavicGoodMask(nmea.mNavicGoodMask), + mGpsBadMask(nmea.mGpsBadMask), + mGloBadMask(nmea.mGloBadMask), + mBdsBadMask(nmea.mBdsBadMask), + mGalBadMask(nmea.mGalBadMask), + mQzssBadMask(nmea.mQzssBadMask), + mNavicBadMask(nmea.mNavicBadMask) +{ +} + +bool SystemStatusSvHealth::equals(const SystemStatusSvHealth& peer) +{ + if ((mGpsUnknownMask != peer.mGpsUnknownMask) || + (mGloUnknownMask != peer.mGloUnknownMask) || + (mBdsUnknownMask != peer.mBdsUnknownMask) || + (mGalUnknownMask != peer.mGalUnknownMask) || + (mQzssUnknownMask != peer.mQzssUnknownMask) || + (mGpsGoodMask != peer.mGpsGoodMask) || + (mGloGoodMask != peer.mGloGoodMask) || + (mBdsGoodMask != peer.mBdsGoodMask) || + (mGalGoodMask != peer.mGalGoodMask) || + (mQzssGoodMask != peer.mQzssGoodMask) || + (mGpsBadMask != peer.mGpsBadMask) || + (mGloBadMask != peer.mGloBadMask) || + (mBdsBadMask != peer.mBdsBadMask) || + (mGalBadMask != peer.mGalBadMask) || + (mQzssBadMask != peer.mQzssBadMask)) { + return false; + } + return true; +} + +void SystemStatusSvHealth::dump() +{ + LOC_LOGV("SvHealth: u=%ld:%ld \ + u=%x:%x:%" PRIx64 ":%" PRIx64 ":%x \ + g=%x:%x:%" PRIx64 ":%" PRIx64 ":%x \ + b=%x:%x:%" PRIx64 ":%" PRIx64 ":%x", + mUtcTime.tv_sec, mUtcTime.tv_nsec, + mGpsUnknownMask, + mGloUnknownMask, + mBdsUnknownMask, + mGalUnknownMask, + mQzssUnknownMask, + mGpsGoodMask, + mGloGoodMask, + mBdsGoodMask, + mGalGoodMask, + mQzssGoodMask, + mGpsBadMask, + mGloBadMask, + mBdsBadMask, + mGalBadMask, + mQzssBadMask); + return; +} + +/****************************************************************************** + SystemStatusPdr +******************************************************************************/ +SystemStatusPdr::SystemStatusPdr(const SystemStatusPQWP6& nmea) : + mFixInfoMask(nmea.mFixInfoMask) +{ +} + +bool SystemStatusPdr::equals(const SystemStatusPdr& peer) +{ + if (mFixInfoMask != peer.mFixInfoMask) { + return false; + } + return true; +} + +void SystemStatusPdr::dump() +{ + LOC_LOGV("Pdr: u=%ld:%ld m=%x", + mUtcTime.tv_sec, mUtcTime.tv_nsec, + mFixInfoMask); + return; +} + +/****************************************************************************** + SystemStatusNavData +******************************************************************************/ +SystemStatusNavData::SystemStatusNavData(const SystemStatusPQWP7& nmea) +{ + for (uint32_t i=0; i<SV_ALL_NUM; i++) { + mNav[i] = nmea.mNav[i]; + } +} + +bool SystemStatusNavData::equals(const SystemStatusNavData& peer) +{ + for (uint32_t i=0; i<SV_ALL_NUM; i++) { + if ((mNav[i].mType != peer.mNav[i].mType) || + (mNav[i].mSource != peer.mNav[i].mSource) || + (mNav[i].mAgeSec != peer.mNav[i].mAgeSec)) { + return false; + } + } + return true; +} + +void SystemStatusNavData::dump() +{ + LOC_LOGV("NavData: u=%ld:%ld", + mUtcTime.tv_sec, mUtcTime.tv_nsec); + for (uint32_t i=0; i<SV_ALL_NUM; i++) { + LOC_LOGV("i=%d type=%d src=%d age=%d", + i, mNav[i].mType, mNav[i].mSource, mNav[i].mAgeSec); + } + return; +} + +/****************************************************************************** + SystemStatusPositionFailure +******************************************************************************/ +SystemStatusPositionFailure::SystemStatusPositionFailure(const SystemStatusPQWS1& nmea) : + mFixInfoMask(nmea.mFixInfoMask), + mHepeLimit(nmea.mHepeLimit) +{ +} + +bool SystemStatusPositionFailure::equals(const SystemStatusPositionFailure& peer) +{ + if ((mFixInfoMask != peer.mFixInfoMask) || + (mHepeLimit != peer.mHepeLimit)) { + return false; + } + return true; +} + +void SystemStatusPositionFailure::dump() +{ + LOC_LOGV("PositionFailure: u=%ld:%ld m=%d h=%d", + mUtcTime.tv_sec, mUtcTime.tv_nsec, + mFixInfoMask, + mHepeLimit); + return; +} + +/****************************************************************************** + SystemStatusLocation +******************************************************************************/ +bool SystemStatusLocation::equals(const SystemStatusLocation& peer) +{ + if ((mLocation.gpsLocation.latitude != peer.mLocation.gpsLocation.latitude) || + (mLocation.gpsLocation.longitude != peer.mLocation.gpsLocation.longitude) || + (mLocation.gpsLocation.altitude != peer.mLocation.gpsLocation.altitude)) { + return false; + } + return true; +} + +void SystemStatusLocation::dump() +{ + LOC_LOGV("Location: lat=%f lon=%f alt=%f spd=%f", + mLocation.gpsLocation.latitude, + mLocation.gpsLocation.longitude, + mLocation.gpsLocation.altitude, + mLocation.gpsLocation.speed); + return; +} + +/****************************************************************************** + SystemStatus +******************************************************************************/ +pthread_mutex_t SystemStatus::mMutexSystemStatus = PTHREAD_MUTEX_INITIALIZER; +SystemStatus* SystemStatus::mInstance = NULL; + +SystemStatus* SystemStatus::getInstance(const MsgTask* msgTask) +{ + pthread_mutex_lock(&mMutexSystemStatus); + + if (!mInstance) { + // Instantiating for the first time. msgTask should not be NULL + if (msgTask == NULL) { + LOC_LOGE("SystemStatus: msgTask is NULL!!"); + pthread_mutex_unlock(&mMutexSystemStatus); + return NULL; + } + mInstance = new (nothrow) SystemStatus(msgTask); + LOC_LOGD("SystemStatus::getInstance:%p. Msgtask:%p", mInstance, msgTask); + } + + pthread_mutex_unlock(&mMutexSystemStatus); + return mInstance; +} + +void SystemStatus::destroyInstance() +{ + delete mInstance; + mInstance = NULL; +} + +void SystemStatus::resetNetworkInfo() { + for (int i=0; i<mCache.mNetworkInfo.size(); ++i) { + // Reset all the cached NetworkInfo Items as disconnected + eventConnectionStatus(false, mCache.mNetworkInfo[i].mType, mCache.mNetworkInfo[i].mRoaming, + mCache.mNetworkInfo[i].mNetworkHandle, mCache.mNetworkInfo[i].mApn); + } +} + +IOsObserver* SystemStatus::getOsObserver() +{ + return &mSysStatusObsvr; +} + +SystemStatus::SystemStatus(const MsgTask* msgTask) : + mSysStatusObsvr(this, msgTask) +{ + int result = 0; + ENTRY_LOG (); + mCache.mLocation.clear(); + + mCache.mTimeAndClock.clear(); + mCache.mXoState.clear(); + mCache.mRfAndParams.clear(); + mCache.mErrRecovery.clear(); + + mCache.mInjectedPosition.clear(); + mCache.mBestPosition.clear(); + mCache.mXtra.clear(); + mCache.mEphemeris.clear(); + mCache.mSvHealth.clear(); + mCache.mPdr.clear(); + mCache.mNavData.clear(); + + mCache.mPositionFailure.clear(); + + mCache.mAirplaneMode.clear(); + mCache.mENH.clear(); + mCache.mGPSState.clear(); + mCache.mNLPStatus.clear(); + mCache.mWifiHardwareState.clear(); + mCache.mNetworkInfo.clear(); + mCache.mRilServiceInfo.clear(); + mCache.mRilCellInfo.clear(); + mCache.mServiceStatus.clear(); + mCache.mModel.clear(); + mCache.mManufacturer.clear(); + mCache.mAssistedGps.clear(); + mCache.mScreenState.clear(); + mCache.mPowerConnectState.clear(); + mCache.mTimeZoneChange.clear(); + mCache.mTimeChange.clear(); + mCache.mWifiSupplicantStatus.clear(); + mCache.mShutdownState.clear(); + mCache.mTac.clear(); + mCache.mMccMnc.clear(); + mCache.mBtDeviceScanDetail.clear(); + mCache.mBtLeDeviceScanDetail.clear(); + + EXIT_LOG_WITH_ERROR ("%d",result); +} + +/****************************************************************************** + SystemStatus - storing dataitems +******************************************************************************/ +template <typename TYPE_REPORT, typename TYPE_ITEM> +bool SystemStatus::setIteminReport(TYPE_REPORT& report, TYPE_ITEM&& s) +{ + if (s.ignore()) { + return false; + } + if (!report.empty() && report.back().equals(static_cast<TYPE_ITEM&>(s.collate(report.back())))) { + // there is no change - just update reported timestamp + report.back().mUtcReported = s.mUtcReported; + return false; + } + + // first event or updated + report.push_back(s); + if (report.size() > s.maxItem) { + report.erase(report.begin()); + } + return true; +} + +template <typename TYPE_REPORT, typename TYPE_ITEM> +void SystemStatus::setDefaultIteminReport(TYPE_REPORT& report, const TYPE_ITEM& s) +{ + report.push_back(s); + if (report.size() > s.maxItem) { + report.erase(report.begin()); + } +} + +template <typename TYPE_REPORT, typename TYPE_ITEM> +void SystemStatus::getIteminReport(TYPE_REPORT& reportout, const TYPE_ITEM& c) const +{ + reportout.clear(); + if (c.size() >= 1) { + reportout.push_back(c.back()); + reportout.back().dump(); + } +} + +/****************************************************************************** +@brief API to set report data into internal buffer + +@param[In] data pointer to the NMEA string +@param[In] len length of the NMEA string + +@return true when the NMEA is consumed by the method. +******************************************************************************/ +bool SystemStatus::setNmeaString(const char *data, uint32_t len) +{ + if (!loc_nmea_is_debug(data, len)) { + return false; + } + + char buf[SystemStatusNmeaBase::NMEA_MAXSIZE + 1] = { 0 }; + strlcpy(buf, data, sizeof(buf)); + + pthread_mutex_lock(&mMutexSystemStatus); + + // parse the received nmea strings here + if (0 == strncmp(data, "$PQWM1", SystemStatusNmeaBase::NMEA_MINSIZE)) { + SystemStatusPQWM1 s = SystemStatusPQWM1parser(buf, len).get(); + setIteminReport(mCache.mTimeAndClock, SystemStatusTimeAndClock(s)); + setIteminReport(mCache.mXoState, SystemStatusXoState(s)); + setIteminReport(mCache.mRfAndParams, SystemStatusRfAndParams(s)); + setIteminReport(mCache.mErrRecovery, SystemStatusErrRecovery(s)); + } + else if (0 == strncmp(data, "$PQWP1", SystemStatusNmeaBase::NMEA_MINSIZE)) { + setIteminReport(mCache.mInjectedPosition, + SystemStatusInjectedPosition(SystemStatusPQWP1parser(buf, len).get())); + } + else if (0 == strncmp(data, "$PQWP2", SystemStatusNmeaBase::NMEA_MINSIZE)) { + setIteminReport(mCache.mBestPosition, + SystemStatusBestPosition(SystemStatusPQWP2parser(buf, len).get())); + } + else if (0 == strncmp(data, "$PQWP3", SystemStatusNmeaBase::NMEA_MINSIZE)) { + setIteminReport(mCache.mXtra, + SystemStatusXtra(SystemStatusPQWP3parser(buf, len).get())); + } + else if (0 == strncmp(data, "$PQWP4", SystemStatusNmeaBase::NMEA_MINSIZE)) { + setIteminReport(mCache.mEphemeris, + SystemStatusEphemeris(SystemStatusPQWP4parser(buf, len).get())); + } + else if (0 == strncmp(data, "$PQWP5", SystemStatusNmeaBase::NMEA_MINSIZE)) { + setIteminReport(mCache.mSvHealth, + SystemStatusSvHealth(SystemStatusPQWP5parser(buf, len).get())); + } + else if (0 == strncmp(data, "$PQWP6", SystemStatusNmeaBase::NMEA_MINSIZE)) { + setIteminReport(mCache.mPdr, + SystemStatusPdr(SystemStatusPQWP6parser(buf, len).get())); + } + else if (0 == strncmp(data, "$PQWP7", SystemStatusNmeaBase::NMEA_MINSIZE)) { + setIteminReport(mCache.mNavData, + SystemStatusNavData(SystemStatusPQWP7parser(buf, len).get())); + } + else if (0 == strncmp(data, "$PQWS1", SystemStatusNmeaBase::NMEA_MINSIZE)) { + setIteminReport(mCache.mPositionFailure, + SystemStatusPositionFailure(SystemStatusPQWS1parser(buf, len).get())); + } + else { + // do nothing + } + + pthread_mutex_unlock(&mMutexSystemStatus); + return true; +} + +/****************************************************************************** +@brief API to set report position data into internal buffer + +@param[In] UlpLocation + +@return true when successfully done +******************************************************************************/ +bool SystemStatus::eventPosition(const UlpLocation& location, + const GpsLocationExtended& locationEx) +{ + bool ret = false; + pthread_mutex_lock(&mMutexSystemStatus); + + ret = setIteminReport(mCache.mLocation, SystemStatusLocation(location, locationEx)); + LOC_LOGV("eventPosition - lat=%f lon=%f alt=%f speed=%f", + location.gpsLocation.latitude, + location.gpsLocation.longitude, + location.gpsLocation.altitude, + location.gpsLocation.speed); + + pthread_mutex_unlock(&mMutexSystemStatus); + return ret; +} + +/****************************************************************************** +@brief API to set report DataItem event into internal buffer + +@param[In] DataItem + +@return true when info is updatated +******************************************************************************/ +bool SystemStatus::eventDataItemNotify(IDataItemCore* dataitem) +{ + bool ret = false; + pthread_mutex_lock(&mMutexSystemStatus); + switch(dataitem->getId()) + { + case AIRPLANEMODE_DATA_ITEM_ID: + ret = setIteminReport(mCache.mAirplaneMode, + SystemStatusAirplaneMode(*(static_cast<AirplaneModeDataItemBase*>(dataitem)))); + break; + case ENH_DATA_ITEM_ID: + ret = setIteminReport(mCache.mENH, + SystemStatusENH(*(static_cast<ENHDataItemBase*>(dataitem)))); + break; + case GPSSTATE_DATA_ITEM_ID: + ret = setIteminReport(mCache.mGPSState, + SystemStatusGpsState(*(static_cast<GPSStateDataItemBase*>(dataitem)))); + break; + case NLPSTATUS_DATA_ITEM_ID: + ret = setIteminReport(mCache.mNLPStatus, + SystemStatusNLPStatus(*(static_cast<NLPStatusDataItemBase*>(dataitem)))); + break; + case WIFIHARDWARESTATE_DATA_ITEM_ID: + ret = setIteminReport(mCache.mWifiHardwareState, + SystemStatusWifiHardwareState(*(static_cast<WifiHardwareStateDataItemBase*>(dataitem)))); + break; + case NETWORKINFO_DATA_ITEM_ID: + ret = setIteminReport(mCache.mNetworkInfo, + SystemStatusNetworkInfo(*(static_cast<NetworkInfoDataItemBase*>(dataitem)))); + break; + case RILSERVICEINFO_DATA_ITEM_ID: + ret = setIteminReport(mCache.mRilServiceInfo, + SystemStatusServiceInfo(*(static_cast<RilServiceInfoDataItemBase*>(dataitem)))); + break; + case RILCELLINFO_DATA_ITEM_ID: + ret = setIteminReport(mCache.mRilCellInfo, + SystemStatusRilCellInfo(*(static_cast<RilCellInfoDataItemBase*>(dataitem)))); + break; + case SERVICESTATUS_DATA_ITEM_ID: + ret = setIteminReport(mCache.mServiceStatus, + SystemStatusServiceStatus(*(static_cast<ServiceStatusDataItemBase*>(dataitem)))); + break; + case MODEL_DATA_ITEM_ID: + ret = setIteminReport(mCache.mModel, + SystemStatusModel(*(static_cast<ModelDataItemBase*>(dataitem)))); + break; + case MANUFACTURER_DATA_ITEM_ID: + ret = setIteminReport(mCache.mManufacturer, + SystemStatusManufacturer(*(static_cast<ManufacturerDataItemBase*>(dataitem)))); + break; + case ASSISTED_GPS_DATA_ITEM_ID: + ret = setIteminReport(mCache.mAssistedGps, + SystemStatusAssistedGps(*(static_cast<AssistedGpsDataItemBase*>(dataitem)))); + break; + case SCREEN_STATE_DATA_ITEM_ID: + ret = setIteminReport(mCache.mScreenState, + SystemStatusScreenState(*(static_cast<ScreenStateDataItemBase*>(dataitem)))); + break; + case POWER_CONNECTED_STATE_DATA_ITEM_ID: + ret = setIteminReport(mCache.mPowerConnectState, + SystemStatusPowerConnectState(*(static_cast<PowerConnectStateDataItemBase*>(dataitem)))); + break; + case TIMEZONE_CHANGE_DATA_ITEM_ID: + ret = setIteminReport(mCache.mTimeZoneChange, + SystemStatusTimeZoneChange(*(static_cast<TimeZoneChangeDataItemBase*>(dataitem)))); + break; + case TIME_CHANGE_DATA_ITEM_ID: + ret = setIteminReport(mCache.mTimeChange, + SystemStatusTimeChange(*(static_cast<TimeChangeDataItemBase*>(dataitem)))); + break; + case WIFI_SUPPLICANT_STATUS_DATA_ITEM_ID: + ret = setIteminReport(mCache.mWifiSupplicantStatus, + SystemStatusWifiSupplicantStatus(*(static_cast<WifiSupplicantStatusDataItemBase*>(dataitem)))); + break; + case SHUTDOWN_STATE_DATA_ITEM_ID: + ret = setIteminReport(mCache.mShutdownState, + SystemStatusShutdownState(*(static_cast<ShutdownStateDataItemBase*>(dataitem)))); + break; + case TAC_DATA_ITEM_ID: + ret = setIteminReport(mCache.mTac, + SystemStatusTac(*(static_cast<TacDataItemBase*>(dataitem)))); + break; + case MCCMNC_DATA_ITEM_ID: + ret = setIteminReport(mCache.mMccMnc, + SystemStatusMccMnc(*(static_cast<MccmncDataItemBase*>(dataitem)))); + break; + case BTLE_SCAN_DATA_ITEM_ID: + ret = setIteminReport(mCache.mBtDeviceScanDetail, + SystemStatusBtDeviceScanDetail(*(static_cast<BtDeviceScanDetailsDataItemBase*>(dataitem)))); + break; + case BT_SCAN_DATA_ITEM_ID: + ret = setIteminReport(mCache.mBtLeDeviceScanDetail, + SystemStatusBtleDeviceScanDetail(*(static_cast<BtLeDeviceScanDetailsDataItemBase*>(dataitem)))); + break; + default: + break; + } + pthread_mutex_unlock(&mMutexSystemStatus); + return ret; +} + +/****************************************************************************** +@brief API to get report data into a given buffer + +@param[In] reference to report buffer +@param[In] bool flag to identify latest only or entire buffer + +@return true when successfully done +******************************************************************************/ +bool SystemStatus::getReport(SystemStatusReports& report, bool isLatestOnly) const +{ + pthread_mutex_lock(&mMutexSystemStatus); + + if (isLatestOnly) { + // push back only the latest report and return it + getIteminReport(report.mLocation, mCache.mLocation); + + getIteminReport(report.mTimeAndClock, mCache.mTimeAndClock); + getIteminReport(report.mXoState, mCache.mXoState); + getIteminReport(report.mRfAndParams, mCache.mRfAndParams); + getIteminReport(report.mErrRecovery, mCache.mErrRecovery); + + getIteminReport(report.mInjectedPosition, mCache.mInjectedPosition); + getIteminReport(report.mBestPosition, mCache.mBestPosition); + getIteminReport(report.mXtra, mCache.mXtra); + getIteminReport(report.mEphemeris, mCache.mEphemeris); + getIteminReport(report.mSvHealth, mCache.mSvHealth); + getIteminReport(report.mPdr, mCache.mPdr); + getIteminReport(report.mNavData, mCache.mNavData); + + getIteminReport(report.mPositionFailure, mCache.mPositionFailure); + + getIteminReport(report.mAirplaneMode, mCache.mAirplaneMode); + getIteminReport(report.mENH, mCache.mENH); + getIteminReport(report.mGPSState, mCache.mGPSState); + getIteminReport(report.mNLPStatus, mCache.mNLPStatus); + getIteminReport(report.mWifiHardwareState, mCache.mWifiHardwareState); + getIteminReport(report.mNetworkInfo, mCache.mNetworkInfo); + getIteminReport(report.mRilServiceInfo, mCache.mRilServiceInfo); + getIteminReport(report.mRilCellInfo, mCache.mRilCellInfo); + getIteminReport(report.mServiceStatus, mCache.mServiceStatus); + getIteminReport(report.mModel, mCache.mModel); + getIteminReport(report.mManufacturer, mCache.mManufacturer); + getIteminReport(report.mAssistedGps, mCache.mAssistedGps); + getIteminReport(report.mScreenState, mCache.mScreenState); + getIteminReport(report.mPowerConnectState, mCache.mPowerConnectState); + getIteminReport(report.mTimeZoneChange, mCache.mTimeZoneChange); + getIteminReport(report.mTimeChange, mCache.mTimeChange); + getIteminReport(report.mWifiSupplicantStatus, mCache.mWifiSupplicantStatus); + getIteminReport(report.mShutdownState, mCache.mShutdownState); + getIteminReport(report.mTac, mCache.mTac); + getIteminReport(report.mMccMnc, mCache.mMccMnc); + getIteminReport(report.mBtDeviceScanDetail, mCache.mBtDeviceScanDetail); + getIteminReport(report.mBtLeDeviceScanDetail, mCache.mBtLeDeviceScanDetail); + } + else { + // copy entire reports and return them + report.mLocation.clear(); + + report.mTimeAndClock.clear(); + report.mXoState.clear(); + report.mRfAndParams.clear(); + report.mErrRecovery.clear(); + + report.mInjectedPosition.clear(); + report.mBestPosition.clear(); + report.mXtra.clear(); + report.mEphemeris.clear(); + report.mSvHealth.clear(); + report.mPdr.clear(); + report.mNavData.clear(); + + report.mPositionFailure.clear(); + + report.mAirplaneMode.clear(); + report.mENH.clear(); + report.mGPSState.clear(); + report.mNLPStatus.clear(); + report.mWifiHardwareState.clear(); + report.mNetworkInfo.clear(); + report.mRilServiceInfo.clear(); + report.mRilCellInfo.clear(); + report.mServiceStatus.clear(); + report.mModel.clear(); + report.mManufacturer.clear(); + report.mAssistedGps.clear(); + report.mScreenState.clear(); + report.mPowerConnectState.clear(); + report.mTimeZoneChange.clear(); + report.mTimeChange.clear(); + report.mWifiSupplicantStatus.clear(); + report.mShutdownState.clear(); + report.mTac.clear(); + report.mMccMnc.clear(); + report.mBtDeviceScanDetail.clear(); + report.mBtLeDeviceScanDetail.clear(); + + report = mCache; + } + + pthread_mutex_unlock(&mMutexSystemStatus); + return true; +} + +/****************************************************************************** +@brief API to set default report data + +@param[In] none + +@return true when successfully done +******************************************************************************/ +bool SystemStatus::setDefaultGnssEngineStates(void) +{ + pthread_mutex_lock(&mMutexSystemStatus); + + setDefaultIteminReport(mCache.mLocation, SystemStatusLocation()); + + setDefaultIteminReport(mCache.mTimeAndClock, SystemStatusTimeAndClock()); + setDefaultIteminReport(mCache.mXoState, SystemStatusXoState()); + setDefaultIteminReport(mCache.mRfAndParams, SystemStatusRfAndParams()); + setDefaultIteminReport(mCache.mErrRecovery, SystemStatusErrRecovery()); + + setDefaultIteminReport(mCache.mInjectedPosition, SystemStatusInjectedPosition()); + setDefaultIteminReport(mCache.mBestPosition, SystemStatusBestPosition()); + setDefaultIteminReport(mCache.mXtra, SystemStatusXtra()); + setDefaultIteminReport(mCache.mEphemeris, SystemStatusEphemeris()); + setDefaultIteminReport(mCache.mSvHealth, SystemStatusSvHealth()); + setDefaultIteminReport(mCache.mPdr, SystemStatusPdr()); + setDefaultIteminReport(mCache.mNavData, SystemStatusNavData()); + + setDefaultIteminReport(mCache.mPositionFailure, SystemStatusPositionFailure()); + + pthread_mutex_unlock(&mMutexSystemStatus); + return true; +} + +/****************************************************************************** +@brief API to handle connection status update event from GnssRil + +@param[In] Connection status + +@return true when successfully done +******************************************************************************/ +bool SystemStatus::eventConnectionStatus(bool connected, int8_t type, + bool roaming, NetworkHandle networkHandle, + string& apn) +{ + // send networkinof dataitem to systemstatus observer clients + SystemStatusNetworkInfo s(type, "", "", connected, roaming, + (uint64_t) networkHandle, apn); + mSysStatusObsvr.notify({&s}); + + return true; +} + +/****************************************************************************** +@brief API to update power connect state + +@param[In] power connect status + +@return true when successfully done +******************************************************************************/ +bool SystemStatus::updatePowerConnectState(bool charging) +{ + SystemStatusPowerConnectState s(charging); + mSysStatusObsvr.notify({&s}); + return true; +} +} // namespace loc_core + diff --git a/gps/core/SystemStatus.h b/gps/core/SystemStatus.h new file mode 100644 index 0000000..097e7cc --- /dev/null +++ b/gps/core/SystemStatus.h @@ -0,0 +1,924 @@ +/* Copyright (c) 2017-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. + * + */ +#ifndef __SYSTEM_STATUS__ +#define __SYSTEM_STATUS__ + +#include <stdint.h> +#include <sys/time.h> +#include <vector> +#include <algorithm> +#include <iterator> +#include <loc_pla.h> +#include <log_util.h> +#include <MsgTask.h> +#include <IDataItemCore.h> +#include <IOsObserver.h> +#include <DataItemConcreteTypesBase.h> +#include <SystemStatusOsObserver.h> + +#include <gps_extended_c.h> + +#define GPS_MIN (1) //1-32 +#define SBAS_MIN (33) +#define GLO_MIN (65) //65-88 +#define QZSS_MIN (193) //193-197 +#define BDS_MIN (201) //201-237 +#define GAL_MIN (301) //301-336 +#define NAVIC_MIN (401) //401-414 + +#define GPS_NUM (32) +#define SBAS_NUM (32) +#define GLO_NUM (24) +#define QZSS_NUM (5) +#define BDS_NUM (37) +#define GAL_NUM (36) +#define NAVIC_NUM (14) +#define SV_ALL_NUM_MIN (GPS_NUM + GLO_NUM + QZSS_NUM + BDS_NUM + GAL_NUM) //=134 +#define SV_ALL_NUM (SV_ALL_NUM_MIN + NAVIC_NUM) //=148 + +namespace loc_core +{ + +/****************************************************************************** + SystemStatus report data structure +******************************************************************************/ +class SystemStatusItemBase +{ +public: + timespec mUtcTime; + timespec mUtcReported; + static const uint32_t maxItem = 5; + + SystemStatusItemBase() { + timeval tv; + gettimeofday(&tv, NULL); + mUtcTime.tv_sec = tv.tv_sec; + mUtcTime.tv_nsec = tv.tv_usec*1000ULL; + mUtcReported = mUtcTime; + }; + virtual ~SystemStatusItemBase() {}; + inline virtual SystemStatusItemBase& collate(SystemStatusItemBase&) { + return *this; + } + virtual void dump(void) {}; + inline virtual bool ignore() { return false; }; +}; + +class SystemStatusLocation : public SystemStatusItemBase +{ +public: + bool mValid; + UlpLocation mLocation; + GpsLocationExtended mLocationEx; + inline SystemStatusLocation() : + mValid(false) {} + inline SystemStatusLocation(const UlpLocation& location, + const GpsLocationExtended& locationEx) : + mValid(true), + mLocation(location), + mLocationEx(locationEx) {} + bool equals(const SystemStatusLocation& peer); + void dump(void) override; +}; + +class SystemStatusPQWM1; +class SystemStatusTimeAndClock : public SystemStatusItemBase +{ +public: + uint16_t mGpsWeek; + uint32_t mGpsTowMs; + uint8_t mTimeValid; + uint8_t mTimeSource; + int32_t mTimeUnc; + int32_t mClockFreqBias; + int32_t mClockFreqBiasUnc; + int32_t mLeapSeconds; + int32_t mLeapSecUnc; + uint64_t mTimeUncNs; + inline SystemStatusTimeAndClock() : + mGpsWeek(0), + mGpsTowMs(0), + mTimeValid(0), + mTimeSource(0), + mTimeUnc(0), + mClockFreqBias(0), + mClockFreqBiasUnc(0), + mLeapSeconds(0), + mLeapSecUnc(0), + mTimeUncNs(0ULL) {} + inline SystemStatusTimeAndClock(const SystemStatusPQWM1& nmea); + bool equals(const SystemStatusTimeAndClock& peer); + void dump(void) override; +}; + +class SystemStatusXoState : public SystemStatusItemBase +{ +public: + uint8_t mXoState; + inline SystemStatusXoState() : + mXoState(0) {} + inline SystemStatusXoState(const SystemStatusPQWM1& nmea); + bool equals(const SystemStatusXoState& peer); + void dump(void) override; +}; + +class SystemStatusRfAndParams : public SystemStatusItemBase +{ +public: + int32_t mPgaGain; + uint32_t mGpsBpAmpI; + uint32_t mGpsBpAmpQ; + uint32_t mAdcI; + uint32_t mAdcQ; + uint32_t mJammerGps; + uint32_t mJammerGlo; + uint32_t mJammerBds; + uint32_t mJammerGal; + double mAgcGps; + double mAgcGlo; + double mAgcBds; + double mAgcGal; + uint32_t mGloBpAmpI; + uint32_t mGloBpAmpQ; + uint32_t mBdsBpAmpI; + uint32_t mBdsBpAmpQ; + uint32_t mGalBpAmpI; + uint32_t mGalBpAmpQ; + inline SystemStatusRfAndParams() : + mPgaGain(0), + mGpsBpAmpI(0), + mGpsBpAmpQ(0), + mAdcI(0), + mAdcQ(0), + mJammerGps(0), + mJammerGlo(0), + mJammerBds(0), + mJammerGal(0), + mAgcGps(0), + mAgcGlo(0), + mAgcBds(0), + mAgcGal(0), + mGloBpAmpI(0), + mGloBpAmpQ(0), + mBdsBpAmpI(0), + mBdsBpAmpQ(0), + mGalBpAmpI(0), + mGalBpAmpQ(0) {} + inline SystemStatusRfAndParams(const SystemStatusPQWM1& nmea); + bool equals(const SystemStatusRfAndParams& peer); + void dump(void) override; +}; + +class SystemStatusErrRecovery : public SystemStatusItemBase +{ +public: + uint32_t mRecErrorRecovery; + inline SystemStatusErrRecovery() : + mRecErrorRecovery(0) {}; + inline SystemStatusErrRecovery(const SystemStatusPQWM1& nmea); + bool equals(const SystemStatusErrRecovery& peer); + inline bool ignore() override { return 0 == mRecErrorRecovery; }; + void dump(void) override; +}; + +class SystemStatusPQWP1; +class SystemStatusInjectedPosition : public SystemStatusItemBase +{ +public: + uint8_t mEpiValidity; + float mEpiLat; + float mEpiLon; + float mEpiAlt; + float mEpiHepe; + float mEpiAltUnc; + uint8_t mEpiSrc; + inline SystemStatusInjectedPosition() : + mEpiValidity(0), + mEpiLat(0), + mEpiLon(0), + mEpiAlt(0), + mEpiHepe(0), + mEpiAltUnc(0), + mEpiSrc(0) {} + inline SystemStatusInjectedPosition(const SystemStatusPQWP1& nmea); + bool equals(const SystemStatusInjectedPosition& peer); + void dump(void) override; +}; + +class SystemStatusPQWP2; +class SystemStatusBestPosition : public SystemStatusItemBase +{ +public: + bool mValid; + float mBestLat; + float mBestLon; + float mBestAlt; + float mBestHepe; + float mBestAltUnc; + inline SystemStatusBestPosition() : + mValid(false), + mBestLat(0), + mBestLon(0), + mBestAlt(0), + mBestHepe(0), + mBestAltUnc(0) {} + inline SystemStatusBestPosition(const SystemStatusPQWP2& nmea); + bool equals(const SystemStatusBestPosition& peer); + void dump(void) override; +}; + +class SystemStatusPQWP3; +class SystemStatusXtra : public SystemStatusItemBase +{ +public: + uint8_t mXtraValidMask; + uint32_t mGpsXtraAge; + uint32_t mGloXtraAge; + uint32_t mBdsXtraAge; + uint32_t mGalXtraAge; + uint32_t mQzssXtraAge; + uint32_t mNavicXtraAge; + uint32_t mGpsXtraValid; + uint32_t mGloXtraValid; + uint64_t mBdsXtraValid; + uint64_t mGalXtraValid; + uint8_t mQzssXtraValid; + uint32_t mNavicXtraValid; + inline SystemStatusXtra() : + mXtraValidMask(0), + mGpsXtraAge(0), + mGloXtraAge(0), + mBdsXtraAge(0), + mGalXtraAge(0), + mQzssXtraAge(0), + mNavicXtraAge(0), + mGpsXtraValid(0), + mGloXtraValid(0), + mBdsXtraValid(0ULL), + mGalXtraValid(0ULL), + mQzssXtraValid(0), + mNavicXtraValid(0) {} + inline SystemStatusXtra(const SystemStatusPQWP3& nmea); + bool equals(const SystemStatusXtra& peer); + void dump(void) override; +}; + +class SystemStatusPQWP4; +class SystemStatusEphemeris : public SystemStatusItemBase +{ +public: + uint32_t mGpsEpheValid; + uint32_t mGloEpheValid; + uint64_t mBdsEpheValid; + uint64_t mGalEpheValid; + uint8_t mQzssEpheValid; + inline SystemStatusEphemeris() : + mGpsEpheValid(0), + mGloEpheValid(0), + mBdsEpheValid(0ULL), + mGalEpheValid(0ULL), + mQzssEpheValid(0) {} + inline SystemStatusEphemeris(const SystemStatusPQWP4& nmea); + bool equals(const SystemStatusEphemeris& peer); + void dump(void) override; +}; + +class SystemStatusPQWP5; +class SystemStatusSvHealth : public SystemStatusItemBase +{ +public: + uint32_t mGpsUnknownMask; + uint32_t mGloUnknownMask; + uint64_t mBdsUnknownMask; + uint64_t mGalUnknownMask; + uint8_t mQzssUnknownMask; + uint32_t mNavicUnknownMask; + uint32_t mGpsGoodMask; + uint32_t mGloGoodMask; + uint64_t mBdsGoodMask; + uint64_t mGalGoodMask; + uint8_t mQzssGoodMask; + uint32_t mNavicGoodMask; + uint32_t mGpsBadMask; + uint32_t mGloBadMask; + uint64_t mBdsBadMask; + uint64_t mGalBadMask; + uint8_t mQzssBadMask; + uint32_t mNavicBadMask; + inline SystemStatusSvHealth() : + mGpsUnknownMask(0), + mGloUnknownMask(0), + mBdsUnknownMask(0ULL), + mGalUnknownMask(0ULL), + mQzssUnknownMask(0), + mNavicUnknownMask(0), + mGpsGoodMask(0), + mGloGoodMask(0), + mBdsGoodMask(0ULL), + mGalGoodMask(0ULL), + mQzssGoodMask(0), + mNavicGoodMask(0), + mGpsBadMask(0), + mGloBadMask(0), + mBdsBadMask(0ULL), + mGalBadMask(0ULL), + mQzssBadMask(0), + mNavicBadMask(0) {} + inline SystemStatusSvHealth(const SystemStatusPQWP5& nmea); + bool equals(const SystemStatusSvHealth& peer); + void dump(void) override; +}; + +class SystemStatusPQWP6; +class SystemStatusPdr : public SystemStatusItemBase +{ +public: + uint32_t mFixInfoMask; + inline SystemStatusPdr() : + mFixInfoMask(0) {} + inline SystemStatusPdr(const SystemStatusPQWP6& nmea); + bool equals(const SystemStatusPdr& peer); + void dump(void) override; +}; + +class SystemStatusPQWP7; +struct SystemStatusNav +{ + GnssEphemerisType mType; + GnssEphemerisSource mSource; + int32_t mAgeSec; +}; + +class SystemStatusNavData : public SystemStatusItemBase +{ +public: + SystemStatusNav mNav[SV_ALL_NUM]; + inline SystemStatusNavData() { + for (uint32_t i=0; i<SV_ALL_NUM; i++) { + mNav[i].mType = GNSS_EPH_TYPE_UNKNOWN; + mNav[i].mSource = GNSS_EPH_SOURCE_UNKNOWN; + mNav[i].mAgeSec = 0; + } + } + inline SystemStatusNavData(const SystemStatusPQWP7& nmea); + bool equals(const SystemStatusNavData& peer); + void dump(void) override; +}; + +class SystemStatusPQWS1; +class SystemStatusPositionFailure : public SystemStatusItemBase +{ +public: + uint32_t mFixInfoMask; + uint32_t mHepeLimit; + inline SystemStatusPositionFailure() : + mFixInfoMask(0), + mHepeLimit(0) {} + inline SystemStatusPositionFailure(const SystemStatusPQWS1& nmea); + bool equals(const SystemStatusPositionFailure& peer); + void dump(void) override; +}; + +/****************************************************************************** + SystemStatus report data structure - from DataItem observer +******************************************************************************/ +class SystemStatusAirplaneMode : public SystemStatusItemBase, + public AirplaneModeDataItemBase +{ +public: + inline SystemStatusAirplaneMode(bool mode=false) : + AirplaneModeDataItemBase(mode) {} + inline SystemStatusAirplaneMode(const AirplaneModeDataItemBase& itemBase) : + AirplaneModeDataItemBase(itemBase) {} + inline bool equals(const SystemStatusAirplaneMode& peer) { + return (mMode == peer.mMode); + } +}; + +class SystemStatusENH : public SystemStatusItemBase, + public ENHDataItemBase +{ +public: + inline SystemStatusENH(bool enabled=false) : + ENHDataItemBase(enabled) {} + inline SystemStatusENH(const ENHDataItemBase& itemBase) : + ENHDataItemBase(itemBase) {} + inline bool equals(const SystemStatusENH& peer) { + return (mEnabled == peer.mEnabled); + } +}; + +class SystemStatusGpsState : public SystemStatusItemBase, + public GPSStateDataItemBase +{ +public: + inline SystemStatusGpsState(bool enabled=false) : + GPSStateDataItemBase(enabled) {} + inline SystemStatusGpsState(const GPSStateDataItemBase& itemBase) : + GPSStateDataItemBase(itemBase) {} + inline bool equals(const SystemStatusGpsState& peer) { + return (mEnabled == peer.mEnabled); + } + inline void dump(void) override { + LOC_LOGD("GpsState: state=%u", mEnabled); + } +}; + +class SystemStatusNLPStatus : public SystemStatusItemBase, + public NLPStatusDataItemBase +{ +public: + inline SystemStatusNLPStatus(bool enabled=false) : + NLPStatusDataItemBase(enabled) {} + inline SystemStatusNLPStatus(const NLPStatusDataItemBase& itemBase) : + NLPStatusDataItemBase(itemBase) {} + inline bool equals(const SystemStatusNLPStatus& peer) { + return (mEnabled == peer.mEnabled); + } +}; + +class SystemStatusWifiHardwareState : public SystemStatusItemBase, + public WifiHardwareStateDataItemBase +{ +public: + inline SystemStatusWifiHardwareState(bool enabled=false) : + WifiHardwareStateDataItemBase(enabled) {} + inline SystemStatusWifiHardwareState(const WifiHardwareStateDataItemBase& itemBase) : + WifiHardwareStateDataItemBase(itemBase) {} + inline bool equals(const SystemStatusWifiHardwareState& peer) { + return (mEnabled == peer.mEnabled); + } +}; + +class SystemStatusNetworkInfo : public SystemStatusItemBase, + public NetworkInfoDataItemBase +{ + NetworkInfoDataItemBase* mSrcObjPtr; +public: + inline SystemStatusNetworkInfo( + int32_t type = 0, + std::string typeName = "", + string subTypeName = "", + bool connected = false, + bool roaming = false, + uint64_t networkHandle = NETWORK_HANDLE_UNKNOWN, + string apn = "") : + NetworkInfoDataItemBase( + (NetworkType)type, + type, + typeName, + subTypeName, + connected && (!roaming), + connected, + roaming, + networkHandle, apn), + mSrcObjPtr(nullptr) {} + inline SystemStatusNetworkInfo(const NetworkInfoDataItemBase& itemBase) : + NetworkInfoDataItemBase(itemBase), + mSrcObjPtr((NetworkInfoDataItemBase*)&itemBase) { + mType = (int32_t)itemBase.getType(); + } + inline bool equals(const SystemStatusNetworkInfo& peer) { + bool rtv = (peer.mConnected == mConnected); + for (uint8_t i = 0; rtv && i < MAX_NETWORK_HANDLES; ++i) { + rtv &= (mAllNetworkHandles[i] == peer.mAllNetworkHandles[i]); + } + return peer.mApn.compare(mApn); + } + inline virtual SystemStatusItemBase& collate(SystemStatusItemBase& curInfo) { + uint64_t allTypes = (static_cast<SystemStatusNetworkInfo&>(curInfo)).mAllTypes; + string& apn = (static_cast<SystemStatusNetworkInfo&>(curInfo)).mApn; + // Replace current with cached table for now and then update + memcpy(mAllNetworkHandles, + (static_cast<SystemStatusNetworkInfo&>(curInfo)).getNetworkHandle(), + sizeof(mAllNetworkHandles)); + // Update the apn for non-mobile type connections. + if (TYPE_MOBILE != mType && apn.compare("") != 0) { + mApn = apn; + } + if (mConnected) { + mAllTypes |= allTypes; + for (uint8_t i = 0; i < MAX_NETWORK_HANDLES; ++i) { + if (mNetworkHandle == mAllNetworkHandles[i].networkHandle) { + LOC_LOGD("collate duplicate detected, not updating"); + break; + } + if (NETWORK_HANDLE_UNKNOWN == mAllNetworkHandles[i].networkHandle) { + mAllNetworkHandles[i].networkHandle = mNetworkHandle; + mAllNetworkHandles[i].networkType = (loc_core::NetworkType) mType; + break; + } + } + } else if (0 != mAllTypes) { + uint8_t deletedIndex = MAX_NETWORK_HANDLES; + uint8_t lastValidIndex = 0; + uint8_t typeCount = 0; + for (; lastValidIndex < MAX_NETWORK_HANDLES && + NETWORK_HANDLE_UNKNOWN != mAllNetworkHandles[lastValidIndex].networkHandle; + ++lastValidIndex) { + // Maintain count for number of network handles still + // connected for given type + if (mType == (int32_t)mAllNetworkHandles[lastValidIndex].networkType) { + if (mNetworkHandle == mAllNetworkHandles[lastValidIndex].networkHandle) { + deletedIndex = lastValidIndex; + } else { + typeCount++; + } + } + + } + if (lastValidIndex > 0) { + --lastValidIndex; + } + + if (MAX_NETWORK_HANDLES != deletedIndex) { + LOC_LOGd("deletedIndex:%u, lastValidIndex:%u, typeCount:%u", + deletedIndex, lastValidIndex, typeCount); + mAllNetworkHandles[deletedIndex] = mAllNetworkHandles[lastValidIndex]; + mAllNetworkHandles[lastValidIndex].networkHandle = NETWORK_HANDLE_UNKNOWN; + mAllNetworkHandles[lastValidIndex].networkType = TYPE_UNKNOWN; + } + + // If no more handles of given type, set bitmask + if (0 == typeCount) { + mAllTypes = (allTypes & (~mAllTypes)); + LOC_LOGD("mAllTypes:%" PRIx64, mAllTypes); + } + } // else (mConnected == false && mAllTypes == 0) + // we keep mAllTypes as 0, which means no more connections. + + if (nullptr != mSrcObjPtr) { + // this is critical, changing mAllTypes of the original obj + mSrcObjPtr->mAllTypes = mAllTypes; + memcpy(mSrcObjPtr->mAllNetworkHandles, + mAllNetworkHandles, + sizeof(mSrcObjPtr->mAllNetworkHandles)); + } + return *this; + } + inline void dump(void) override { + LOC_LOGD("NetworkInfo: mAllTypes=%" PRIx64 " connected=%u mType=%x mApn=%s", + mAllTypes, mConnected, mType, mApn.c_str()); + } +}; + +class SystemStatusServiceInfo : public SystemStatusItemBase, + public RilServiceInfoDataItemBase +{ +public: + inline SystemStatusServiceInfo() : + RilServiceInfoDataItemBase() {} + inline SystemStatusServiceInfo(const RilServiceInfoDataItemBase& itemBase) : + RilServiceInfoDataItemBase(itemBase) {} + inline bool equals(const SystemStatusServiceInfo& peer) { + return static_cast<const RilServiceInfoDataItemBase&>(peer) == + static_cast<const RilServiceInfoDataItemBase&>(*this); + } +}; + +class SystemStatusRilCellInfo : public SystemStatusItemBase, + public RilCellInfoDataItemBase +{ +public: + inline SystemStatusRilCellInfo() : + RilCellInfoDataItemBase() {} + inline SystemStatusRilCellInfo(const RilCellInfoDataItemBase& itemBase) : + RilCellInfoDataItemBase(itemBase) {} + inline bool equals(const SystemStatusRilCellInfo& peer) { + return static_cast<const RilCellInfoDataItemBase&>(peer) == + static_cast<const RilCellInfoDataItemBase&>(*this); + } +}; + +class SystemStatusServiceStatus : public SystemStatusItemBase, + public ServiceStatusDataItemBase +{ +public: + inline SystemStatusServiceStatus(int32_t mServiceState=0) : + ServiceStatusDataItemBase(mServiceState) {} + inline SystemStatusServiceStatus(const ServiceStatusDataItemBase& itemBase) : + ServiceStatusDataItemBase(itemBase) {} + inline bool equals(const SystemStatusServiceStatus& peer) { + return (mServiceState == peer.mServiceState); + } +}; + +class SystemStatusModel : public SystemStatusItemBase, + public ModelDataItemBase +{ +public: + inline SystemStatusModel(string name="") : + ModelDataItemBase(name) {} + inline SystemStatusModel(const ModelDataItemBase& itemBase) : + ModelDataItemBase(itemBase) {} + inline bool equals(const SystemStatusModel& peer) { + return (mModel == peer.mModel); + } +}; + +class SystemStatusManufacturer : public SystemStatusItemBase, + public ManufacturerDataItemBase +{ +public: + inline SystemStatusManufacturer(string name="") : + ManufacturerDataItemBase(name) {} + inline SystemStatusManufacturer(const ManufacturerDataItemBase& itemBase) : + ManufacturerDataItemBase(itemBase) {} + inline bool equals(const SystemStatusManufacturer& peer) { + return (mManufacturer == peer.mManufacturer); + } +}; + +class SystemStatusAssistedGps : public SystemStatusItemBase, + public AssistedGpsDataItemBase +{ +public: + inline SystemStatusAssistedGps(bool enabled=false) : + AssistedGpsDataItemBase(enabled) {} + inline SystemStatusAssistedGps(const AssistedGpsDataItemBase& itemBase) : + AssistedGpsDataItemBase(itemBase) {} + inline bool equals(const SystemStatusAssistedGps& peer) { + return (mEnabled == peer.mEnabled); + } +}; + +class SystemStatusScreenState : public SystemStatusItemBase, + public ScreenStateDataItemBase +{ +public: + inline SystemStatusScreenState(bool state=false) : + ScreenStateDataItemBase(state) {} + inline SystemStatusScreenState(const ScreenStateDataItemBase& itemBase) : + ScreenStateDataItemBase(itemBase) {} + inline bool equals(const SystemStatusScreenState& peer) { + return (mState == peer.mState); + } +}; + +class SystemStatusPowerConnectState : public SystemStatusItemBase, + public PowerConnectStateDataItemBase +{ +public: + inline SystemStatusPowerConnectState(bool state=false) : + PowerConnectStateDataItemBase(state) {} + inline SystemStatusPowerConnectState(const PowerConnectStateDataItemBase& itemBase) : + PowerConnectStateDataItemBase(itemBase) {} + inline bool equals(const SystemStatusPowerConnectState& peer) { + return (mState == peer.mState); + } +}; + +class SystemStatusTimeZoneChange : public SystemStatusItemBase, + public TimeZoneChangeDataItemBase +{ +public: + inline SystemStatusTimeZoneChange( + int64_t currTimeMillis=0ULL, int32_t rawOffset=0, int32_t dstOffset=0) : + TimeZoneChangeDataItemBase(currTimeMillis, rawOffset, dstOffset) {} + inline SystemStatusTimeZoneChange(const TimeZoneChangeDataItemBase& itemBase) : + TimeZoneChangeDataItemBase(itemBase) {} + inline bool equals(const SystemStatusTimeZoneChange& peer) { + return ((mCurrTimeMillis == peer.mCurrTimeMillis) && + (mRawOffsetTZ == peer.mRawOffsetTZ) && + (mDstOffsetTZ == peer.mDstOffsetTZ)); + } +}; + +class SystemStatusTimeChange : public SystemStatusItemBase, + public TimeChangeDataItemBase +{ +public: + inline SystemStatusTimeChange( + int64_t currTimeMillis=0ULL, int32_t rawOffset=0, int32_t dstOffset=0) : + TimeChangeDataItemBase(currTimeMillis, rawOffset, dstOffset) {} + inline SystemStatusTimeChange(const TimeChangeDataItemBase& itemBase) : + TimeChangeDataItemBase(itemBase) {} + inline bool equals(const SystemStatusTimeChange& peer) { + return ((mCurrTimeMillis == peer.mCurrTimeMillis) && + (mRawOffsetTZ == peer.mRawOffsetTZ) && + (mDstOffsetTZ == peer.mDstOffsetTZ)); + } +}; + +class SystemStatusWifiSupplicantStatus : public SystemStatusItemBase, + public WifiSupplicantStatusDataItemBase +{ +public: + inline SystemStatusWifiSupplicantStatus() : + WifiSupplicantStatusDataItemBase() {} + inline SystemStatusWifiSupplicantStatus(const WifiSupplicantStatusDataItemBase& itemBase) : + WifiSupplicantStatusDataItemBase(itemBase) {} + inline bool equals(const SystemStatusWifiSupplicantStatus& peer) { + return ((mState == peer.mState) && + (mApMacAddressValid == peer.mApMacAddressValid) && + (mWifiApSsidValid == peer.mWifiApSsidValid) && + (mWifiApSsid == peer.mWifiApSsid)); + } +}; + +class SystemStatusShutdownState : public SystemStatusItemBase, + public ShutdownStateDataItemBase +{ +public: + inline SystemStatusShutdownState(bool state=false) : + ShutdownStateDataItemBase(state) {} + inline SystemStatusShutdownState(const ShutdownStateDataItemBase& itemBase) : + ShutdownStateDataItemBase(itemBase) {} + inline bool equals(const SystemStatusShutdownState& peer) { + return (mState == peer.mState); + } +}; + +class SystemStatusTac : public SystemStatusItemBase, + public TacDataItemBase +{ +public: + inline SystemStatusTac(std::string value="") : + TacDataItemBase(value) {} + inline SystemStatusTac(const TacDataItemBase& itemBase) : + TacDataItemBase(itemBase) {} + inline bool equals(const SystemStatusTac& peer) { + return (mValue == peer.mValue); + } + inline void dump(void) override { + LOC_LOGD("Tac: value=%s", mValue.c_str()); + } +}; + +class SystemStatusMccMnc : public SystemStatusItemBase, + public MccmncDataItemBase +{ +public: + inline SystemStatusMccMnc(std::string value="") : + MccmncDataItemBase(value) {} + inline SystemStatusMccMnc(const MccmncDataItemBase& itemBase) : + MccmncDataItemBase(itemBase) {} + inline bool equals(const SystemStatusMccMnc& peer) { + return (mValue == peer.mValue); + } + inline void dump(void) override { + LOC_LOGD("TacMccMnc value=%s", mValue.c_str()); + } +}; + +class SystemStatusBtDeviceScanDetail : public SystemStatusItemBase, + public BtDeviceScanDetailsDataItemBase +{ +public: + inline SystemStatusBtDeviceScanDetail() : + BtDeviceScanDetailsDataItemBase() {} + inline SystemStatusBtDeviceScanDetail(const BtDeviceScanDetailsDataItemBase& itemBase) : + BtDeviceScanDetailsDataItemBase(itemBase) {} + inline bool equals(const SystemStatusBtDeviceScanDetail& peer) { + return ((mApSrnRssi == peer.mApSrnRssi) && + (0 == memcmp(mApSrnMacAddress, peer.mApSrnMacAddress, sizeof(mApSrnMacAddress))) && + (mApSrnTimestamp == peer.mApSrnTimestamp) && + (mRequestTimestamp == peer.mRequestTimestamp) && + (mReceiveTimestamp == peer.mReceiveTimestamp)); + } +}; + +class SystemStatusBtleDeviceScanDetail : public SystemStatusItemBase, + public BtLeDeviceScanDetailsDataItemBase +{ +public: + inline SystemStatusBtleDeviceScanDetail() : + BtLeDeviceScanDetailsDataItemBase() {} + inline SystemStatusBtleDeviceScanDetail(const BtLeDeviceScanDetailsDataItemBase& itemBase) : + BtLeDeviceScanDetailsDataItemBase(itemBase) {} + inline bool equals(const SystemStatusBtleDeviceScanDetail& peer) { + return ((mApSrnRssi == peer.mApSrnRssi) && + (0 == memcmp(mApSrnMacAddress, peer.mApSrnMacAddress, sizeof(mApSrnMacAddress))) && + (mApSrnTimestamp == peer.mApSrnTimestamp) && + (mRequestTimestamp == peer.mRequestTimestamp) && + (mReceiveTimestamp == peer.mReceiveTimestamp)); + } +}; + +/****************************************************************************** + SystemStatusReports +******************************************************************************/ +class SystemStatusReports +{ +public: + // from QMI_LOC indication + std::vector<SystemStatusLocation> mLocation; + + // from ME debug NMEA + std::vector<SystemStatusTimeAndClock> mTimeAndClock; + std::vector<SystemStatusXoState> mXoState; + std::vector<SystemStatusRfAndParams> mRfAndParams; + std::vector<SystemStatusErrRecovery> mErrRecovery; + + // from PE debug NMEA + std::vector<SystemStatusInjectedPosition> mInjectedPosition; + std::vector<SystemStatusBestPosition> mBestPosition; + std::vector<SystemStatusXtra> mXtra; + std::vector<SystemStatusEphemeris> mEphemeris; + std::vector<SystemStatusSvHealth> mSvHealth; + std::vector<SystemStatusPdr> mPdr; + std::vector<SystemStatusNavData> mNavData; + + // from SM debug NMEA + std::vector<SystemStatusPositionFailure> mPositionFailure; + + // from dataitems observer + std::vector<SystemStatusAirplaneMode> mAirplaneMode; + std::vector<SystemStatusENH> mENH; + std::vector<SystemStatusGpsState> mGPSState; + std::vector<SystemStatusNLPStatus> mNLPStatus; + std::vector<SystemStatusWifiHardwareState> mWifiHardwareState; + std::vector<SystemStatusNetworkInfo> mNetworkInfo; + std::vector<SystemStatusServiceInfo> mRilServiceInfo; + std::vector<SystemStatusRilCellInfo> mRilCellInfo; + std::vector<SystemStatusServiceStatus> mServiceStatus; + std::vector<SystemStatusModel> mModel; + std::vector<SystemStatusManufacturer> mManufacturer; + std::vector<SystemStatusAssistedGps> mAssistedGps; + std::vector<SystemStatusScreenState> mScreenState; + std::vector<SystemStatusPowerConnectState> mPowerConnectState; + std::vector<SystemStatusTimeZoneChange> mTimeZoneChange; + std::vector<SystemStatusTimeChange> mTimeChange; + std::vector<SystemStatusWifiSupplicantStatus> mWifiSupplicantStatus; + std::vector<SystemStatusShutdownState> mShutdownState; + std::vector<SystemStatusTac> mTac; + std::vector<SystemStatusMccMnc> mMccMnc; + std::vector<SystemStatusBtDeviceScanDetail> mBtDeviceScanDetail; + std::vector<SystemStatusBtleDeviceScanDetail> mBtLeDeviceScanDetail; +}; + +/****************************************************************************** + SystemStatus +******************************************************************************/ +class SystemStatus +{ +private: + static SystemStatus *mInstance; + SystemStatusOsObserver mSysStatusObsvr; + // ctor + SystemStatus(const MsgTask* msgTask); + // dtor + inline ~SystemStatus() {} + + // Data members + static pthread_mutex_t mMutexSystemStatus; + SystemStatusReports mCache; + + template <typename TYPE_REPORT, typename TYPE_ITEM> + bool setIteminReport(TYPE_REPORT& report, TYPE_ITEM&& s); + + // set default dataitem derived item in report cache + template <typename TYPE_REPORT, typename TYPE_ITEM> + void setDefaultIteminReport(TYPE_REPORT& report, const TYPE_ITEM& s); + + template <typename TYPE_REPORT, typename TYPE_ITEM> + void getIteminReport(TYPE_REPORT& reportout, const TYPE_ITEM& c) const; + +public: + // Static methods + static SystemStatus* getInstance(const MsgTask* msgTask); + static void destroyInstance(); + IOsObserver* getOsObserver(); + + // Helpers + bool eventPosition(const UlpLocation& location,const GpsLocationExtended& locationEx); + bool eventDataItemNotify(IDataItemCore* dataitem); + bool setNmeaString(const char *data, uint32_t len); + bool getReport(SystemStatusReports& reports, bool isLatestonly = false) const; + bool setDefaultGnssEngineStates(void); + bool eventConnectionStatus(bool connected, int8_t type, + bool roaming, NetworkHandle networkHandle, string& apn); + bool updatePowerConnectState(bool charging); + void resetNetworkInfo(); +}; + +} // namespace loc_core + +#endif //__SYSTEM_STATUS__ + diff --git a/gps/core/SystemStatusOsObserver.cpp b/gps/core/SystemStatusOsObserver.cpp new file mode 100644 index 0000000..8fd9564 --- /dev/null +++ b/gps/core/SystemStatusOsObserver.cpp @@ -0,0 +1,592 @@ +/* Copyright (c) 2015-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_SystemStatusOsObserver" + +#include <algorithm> +#include <SystemStatus.h> +#include <SystemStatusOsObserver.h> +#include <IDataItemCore.h> +#include <DataItemsFactoryProxy.h> + +namespace loc_core +{ +template <typename CINT, typename COUT> +COUT SystemStatusOsObserver::containerTransfer(CINT& inContainer) { + COUT outContainer = {}; + for (auto item : inContainer) { + outContainer.insert(outContainer.begin(), item); + } + return outContainer; +} + +SystemStatusOsObserver::~SystemStatusOsObserver() { + // Close data-item library handle + DataItemsFactoryProxy::closeDataItemLibraryHandle(); + + // Destroy cache + for (auto each : mDataItemCache) { + if (nullptr != each.second) { + delete each.second; + } + } + + mDataItemCache.clear(); +} + +void SystemStatusOsObserver::setSubscriptionObj(IDataItemSubscription* subscriptionObj) +{ + struct SetSubsObj : public LocMsg { + ObserverContext& mContext; + IDataItemSubscription* mSubsObj; + inline SetSubsObj(ObserverContext& context, IDataItemSubscription* subscriptionObj) : + mContext(context), mSubsObj(subscriptionObj) {} + void proc() const { + LOC_LOGi("SetSubsObj::enter"); + mContext.mSubscriptionObj = mSubsObj; + + if (!mContext.mSSObserver->mDataItemToClients.empty()) { + list<DataItemId> dis( + containerTransfer<unordered_set<DataItemId>, list<DataItemId>>( + mContext.mSSObserver->mDataItemToClients.getKeys())); + mContext.mSubscriptionObj->subscribe(dis, mContext.mSSObserver); + mContext.mSubscriptionObj->requestData(dis, mContext.mSSObserver); + } + LOC_LOGi("SetSubsObj::exit"); + } + }; + + if (nullptr == subscriptionObj) { + LOC_LOGw("subscriptionObj is NULL"); + } else { + mContext.mMsgTask->sendMsg(new SetSubsObj(mContext, subscriptionObj)); + } +} + +/****************************************************************************** + IDataItemSubscription Overrides +******************************************************************************/ +void SystemStatusOsObserver::subscribe(const list<DataItemId>& l, IDataItemObserver* client, + bool toRequestData) +{ + struct HandleSubscribeReq : public LocMsg { + inline HandleSubscribeReq(SystemStatusOsObserver* parent, + list<DataItemId>& l, IDataItemObserver* client, bool requestData) : + mParent(parent), mClient(client), + mDataItemSet(containerTransfer<list<DataItemId>, unordered_set<DataItemId>>(l)), + diItemlist(l), + mToRequestData(requestData) {} + + void proc() const { + unordered_set<DataItemId> dataItemsToSubscribe = {}; + mParent->mDataItemToClients.add(mDataItemSet, {mClient}, &dataItemsToSubscribe); + mParent->mClientToDataItems.add(mClient, mDataItemSet); + + mParent->sendCachedDataItems(mDataItemSet, mClient); + + // Send subscription set to framework + if (nullptr != mParent->mContext.mSubscriptionObj) { + if (mToRequestData) { + LOC_LOGD("Request Data sent to framework for the following"); + mParent->mContext.mSubscriptionObj->requestData(diItemlist, mParent); + } else if (!dataItemsToSubscribe.empty()) { + LOC_LOGD("Subscribe Request sent to framework for the following"); + mParent->logMe(dataItemsToSubscribe); + mParent->mContext.mSubscriptionObj->subscribe( + containerTransfer<unordered_set<DataItemId>, list<DataItemId>>( + std::move(dataItemsToSubscribe)), + mParent); + } + } + } + mutable SystemStatusOsObserver* mParent; + IDataItemObserver* mClient; + const unordered_set<DataItemId> mDataItemSet; + const list<DataItemId> diItemlist; + bool mToRequestData; + }; + + if (l.empty() || nullptr == client) { + LOC_LOGw("Data item set is empty or client is nullptr"); + } else { + mContext.mMsgTask->sendMsg( + new HandleSubscribeReq(this, (list<DataItemId>&)l, client, toRequestData)); + } +} + +void SystemStatusOsObserver::updateSubscription( + const list<DataItemId>& l, IDataItemObserver* client) +{ + struct HandleUpdateSubscriptionReq : public LocMsg { + HandleUpdateSubscriptionReq(SystemStatusOsObserver* parent, + list<DataItemId>& l, IDataItemObserver* client) : + mParent(parent), mClient(client), + mDataItemSet(containerTransfer<list<DataItemId>, unordered_set<DataItemId>>(l)) {} + + void proc() const { + unordered_set<DataItemId> dataItemsToSubscribe = {}; + unordered_set<DataItemId> dataItemsToUnsubscribe = {}; + unordered_set<IDataItemObserver*> clients({mClient}); + // below removes clients from all entries keyed with the return of the + // mClientToDataItems.update() call. If leaving an empty set of clients as the + // result, the entire entry will be removed. dataItemsToUnsubscribe will be + // populated to keep the keys of the removed entries. + mParent->mDataItemToClients.trimOrRemove( + // this call updates <IDataItemObserver*, DataItemId> map; removes + // the DataItemId's that are not new to the clietn from mDataItemSet; + // and returns a set of mDataItemSet's that are no longer used by client. + // This unused set of mDataItemSet's is passed to trimOrRemove method of + // <DataItemId, IDataItemObserver*> map to remove the client from the + // corresponding entries, and gets a set of the entries that are + // removed from the <DataItemId, IDataItemObserver*> map as a result. + mParent->mClientToDataItems.update(mClient, + (unordered_set<DataItemId>&)mDataItemSet), + clients, &dataItemsToUnsubscribe, nullptr); + // below adds mClient to <DataItemId, IDataItemObserver*> map, and populates + // new keys added to that map, which are DataItemIds to be subscribed. + mParent->mDataItemToClients.add(mDataItemSet, clients, &dataItemsToSubscribe); + + // Send First Response + mParent->sendCachedDataItems(mDataItemSet, mClient); + + if (nullptr != mParent->mContext.mSubscriptionObj) { + // Send subscription set to framework + if (!dataItemsToSubscribe.empty()) { + LOC_LOGD("Subscribe Request sent to framework for the following"); + mParent->logMe(dataItemsToSubscribe); + + mParent->mContext.mSubscriptionObj->subscribe( + containerTransfer<unordered_set<DataItemId>, list<DataItemId>>( + std::move(dataItemsToSubscribe)), + mParent); + } + + // Send unsubscribe to framework + if (!dataItemsToUnsubscribe.empty()) { + LOC_LOGD("Unsubscribe Request sent to framework for the following"); + mParent->logMe(dataItemsToUnsubscribe); + + mParent->mContext.mSubscriptionObj->unsubscribe( + containerTransfer<unordered_set<DataItemId>, list<DataItemId>>( + std::move(dataItemsToUnsubscribe)), + mParent); + } + } + } + SystemStatusOsObserver* mParent; + IDataItemObserver* mClient; + unordered_set<DataItemId> mDataItemSet; + }; + + if (l.empty() || nullptr == client) { + LOC_LOGw("Data item set is empty or client is nullptr"); + } else { + mContext.mMsgTask->sendMsg( + new HandleUpdateSubscriptionReq(this, (list<DataItemId>&)l, client)); + } +} + +void SystemStatusOsObserver::unsubscribe( + const list<DataItemId>& l, IDataItemObserver* client) +{ + struct HandleUnsubscribeReq : public LocMsg { + HandleUnsubscribeReq(SystemStatusOsObserver* parent, + list<DataItemId>& l, IDataItemObserver* client) : + mParent(parent), mClient(client), + mDataItemSet(containerTransfer<list<DataItemId>, unordered_set<DataItemId>>(l)) {} + + void proc() const { + unordered_set<DataItemId> dataItemsUnusedByClient = {}; + unordered_set<IDataItemObserver*> clientToRemove = {}; + unordered_set<DataItemId> dataItemsToUnsubscribe = {}; + mParent->mClientToDataItems.trimOrRemove({mClient}, mDataItemSet, &clientToRemove, + &dataItemsUnusedByClient); + mParent->mDataItemToClients.trimOrRemove(dataItemsUnusedByClient, {mClient}, + &dataItemsToUnsubscribe, nullptr); + + if (nullptr != mParent->mContext.mSubscriptionObj && !dataItemsToUnsubscribe.empty()) { + LOC_LOGD("Unsubscribe Request sent to framework for the following data items"); + mParent->logMe(dataItemsToUnsubscribe); + + // Send unsubscribe to framework + mParent->mContext.mSubscriptionObj->unsubscribe( + containerTransfer<unordered_set<DataItemId>, list<DataItemId>>( + std::move(dataItemsToUnsubscribe)), + mParent); + } + } + SystemStatusOsObserver* mParent; + IDataItemObserver* mClient; + unordered_set<DataItemId> mDataItemSet; + }; + + if (l.empty() || nullptr == client) { + LOC_LOGw("Data item set is empty or client is nullptr"); + } else { + mContext.mMsgTask->sendMsg(new HandleUnsubscribeReq(this, (list<DataItemId>&)l, client)); + } +} + +void SystemStatusOsObserver::unsubscribeAll(IDataItemObserver* client) +{ + struct HandleUnsubscribeAllReq : public LocMsg { + HandleUnsubscribeAllReq(SystemStatusOsObserver* parent, + IDataItemObserver* client) : + mParent(parent), mClient(client) {} + + void proc() const { + unordered_set<DataItemId> diByClient = mParent->mClientToDataItems.getValSet(mClient); + + if (!diByClient.empty()) { + unordered_set<DataItemId> dataItemsToUnsubscribe; + mParent->mClientToDataItems.remove(mClient); + mParent->mDataItemToClients.trimOrRemove(diByClient, {mClient}, + &dataItemsToUnsubscribe, nullptr); + + if (!dataItemsToUnsubscribe.empty() && + nullptr != mParent->mContext.mSubscriptionObj) { + + LOC_LOGD("Unsubscribe Request sent to framework for the following data items"); + mParent->logMe(dataItemsToUnsubscribe); + + // Send unsubscribe to framework + mParent->mContext.mSubscriptionObj->unsubscribe( + containerTransfer<unordered_set<DataItemId>, list<DataItemId>>( + std::move(dataItemsToUnsubscribe)), + mParent); + } + } + } + SystemStatusOsObserver* mParent; + IDataItemObserver* mClient; + }; + + if (nullptr == client) { + LOC_LOGw("Data item set is empty or client is nullptr"); + } else { + mContext.mMsgTask->sendMsg(new HandleUnsubscribeAllReq(this, client)); + } +} + +/****************************************************************************** + IDataItemObserver Overrides +******************************************************************************/ +void SystemStatusOsObserver::notify(const list<IDataItemCore*>& dlist) +{ + struct HandleNotify : public LocMsg { + HandleNotify(SystemStatusOsObserver* parent, vector<IDataItemCore*>& v) : + mParent(parent), mDiVec(std::move(v)) {} + + inline virtual ~HandleNotify() { + for (auto item : mDiVec) { + delete item; + } + } + + void proc() const { + // Update Cache with received data items and prepare + // list of data items to be sent. + unordered_set<DataItemId> dataItemIdsToBeSent = {}; + for (auto item : mDiVec) { + if (mParent->updateCache(item)) { + dataItemIdsToBeSent.insert(item->getId()); + } + } + + // Send data item to all subscribed clients + unordered_set<IDataItemObserver*> clientSet = {}; + for (auto each : dataItemIdsToBeSent) { + auto clients = mParent->mDataItemToClients.getValSetPtr(each); + if (nullptr != clients) { + clientSet.insert(clients->begin(), clients->end()); + } + } + + for (auto client : clientSet) { + unordered_set<DataItemId> dataItemIdsForThisClient( + mParent->mClientToDataItems.getValSet(client)); + for (auto itr = dataItemIdsForThisClient.begin(); + itr != dataItemIdsForThisClient.end(); ) { + if (dataItemIdsToBeSent.find(*itr) == dataItemIdsToBeSent.end()) { + itr = dataItemIdsForThisClient.erase(itr); + } else { + itr++; + } + } + + mParent->sendCachedDataItems(dataItemIdsForThisClient, client); + } + } + SystemStatusOsObserver* mParent; + const vector<IDataItemCore*> mDiVec; + }; + + if (!dlist.empty()) { + vector<IDataItemCore*> dataItemVec(dlist.size()); + + for (auto each : dlist) { + + IDataItemCore* di = DataItemsFactoryProxy::createNewDataItem(each->getId()); + if (nullptr == di) { + LOC_LOGw("Unable to create dataitem:%d", each->getId()); + continue; + } + + // Copy contents into the newly created data item + di->copy(each); + + // add this dataitem if updated from last one + dataItemVec.push_back(di); + IF_LOC_LOGD { + string dv; + di->stringify(dv); + LOC_LOGd("notify: DataItem In Value:%s", dv.c_str()); + } + } + + if (!dataItemVec.empty()) { + mContext.mMsgTask->sendMsg(new HandleNotify(this, dataItemVec)); + } + } +} + +/****************************************************************************** + IFrameworkActionReq Overrides +******************************************************************************/ +void SystemStatusOsObserver::turnOn(DataItemId dit, int timeOut) +{ + if (nullptr == mContext.mFrameworkActionReqObj) { + LOC_LOGE("%s:%d]: Framework action request object is NULL", __func__, __LINE__); + return; + } + + // Check if data item exists in mActiveRequestCount + DataItemIdToInt::iterator citer = mActiveRequestCount.find(dit); + if (citer == mActiveRequestCount.end()) { + // Data item not found in map + // Add reference count as 1 and add dataitem to map + pair<DataItemId, int> cpair(dit, 1); + mActiveRequestCount.insert(cpair); + LOC_LOGD("Sending turnOn request"); + + // Send action turn on to framework + struct HandleTurnOnMsg : public LocMsg { + HandleTurnOnMsg(IFrameworkActionReq* framework, + DataItemId dit, int timeOut) : + mFrameworkActionReqObj(framework), mDataItemId(dit), mTimeOut(timeOut) {} + virtual ~HandleTurnOnMsg() {} + void proc() const { + mFrameworkActionReqObj->turnOn(mDataItemId, mTimeOut); + } + IFrameworkActionReq* mFrameworkActionReqObj; + DataItemId mDataItemId; + int mTimeOut; + }; + mContext.mMsgTask->sendMsg( + new (nothrow) HandleTurnOnMsg(mContext.mFrameworkActionReqObj, dit, timeOut)); + } + else { + // Found in map, update reference count + citer->second++; + LOC_LOGD("turnOn - Data item:%d Num_refs:%d", dit, citer->second); + } +} + +void SystemStatusOsObserver::turnOff(DataItemId dit) +{ + if (nullptr == mContext.mFrameworkActionReqObj) { + LOC_LOGE("%s:%d]: Framework action request object is NULL", __func__, __LINE__); + return; + } + + // Check if data item exists in mActiveRequestCount + DataItemIdToInt::iterator citer = mActiveRequestCount.find(dit); + if (citer != mActiveRequestCount.end()) { + // found + citer->second--; + LOC_LOGD("turnOff - Data item:%d Remaining:%d", dit, citer->second); + if(citer->second == 0) { + // if this was last reference, remove item from map and turn off module + mActiveRequestCount.erase(citer); + + // Send action turn off to framework + struct HandleTurnOffMsg : public LocMsg { + HandleTurnOffMsg(IFrameworkActionReq* framework, DataItemId dit) : + mFrameworkActionReqObj(framework), mDataItemId(dit) {} + virtual ~HandleTurnOffMsg() {} + void proc() const { + mFrameworkActionReqObj->turnOff(mDataItemId); + } + IFrameworkActionReq* mFrameworkActionReqObj; + DataItemId mDataItemId; + }; + mContext.mMsgTask->sendMsg( + new (nothrow) HandleTurnOffMsg(mContext.mFrameworkActionReqObj, dit)); + } + } +} + +#ifdef USE_GLIB +bool SystemStatusOsObserver::connectBackhaul(const string& clientName) +{ + bool result = false; + + if (mContext.mFrameworkActionReqObj != NULL) { + struct HandleConnectBackhaul : public LocMsg { + HandleConnectBackhaul(IFrameworkActionReq* fwkActReq, const string& clientName) : + mClientName(clientName), mFwkActionReqObj(fwkActReq) {} + virtual ~HandleConnectBackhaul() {} + void proc() const { + LOC_LOGi("HandleConnectBackhaul::enter"); + mFwkActionReqObj->connectBackhaul(mClientName); + LOC_LOGi("HandleConnectBackhaul::exit"); + } + IFrameworkActionReq* mFwkActionReqObj; + string mClientName; + }; + mContext.mMsgTask->sendMsg( + new (nothrow) HandleConnectBackhaul(mContext.mFrameworkActionReqObj, clientName)); + result = true; + } + else { + LOC_LOGe("Framework action request object is NULL.Caching connect request: %s", + clientName.c_str()); + ClientBackhaulReqCache::const_iterator iter = mBackHaulConnReqCache.find(clientName); + if (iter == mBackHaulConnReqCache.end()) { + // not found in set. first time receiving from request from client + LOC_LOGe("Adding client to BackHaulConnReqCache list"); + mBackHaulConnReqCache.insert(clientName); + } + result = false; + } + return result; + +} + +bool SystemStatusOsObserver::disconnectBackhaul(const string& clientName) +{ + bool result = false; + + if (mContext.mFrameworkActionReqObj != NULL) { + struct HandleDisconnectBackhaul : public LocMsg { + HandleDisconnectBackhaul(IFrameworkActionReq* fwkActReq, const string& clientName) : + mClientName(clientName), mFwkActionReqObj(fwkActReq) {} + virtual ~HandleDisconnectBackhaul() {} + void proc() const { + LOC_LOGi("HandleDisconnectBackhaul::enter"); + mFwkActionReqObj->disconnectBackhaul(mClientName); + LOC_LOGi("HandleDisconnectBackhaul::exit"); + } + IFrameworkActionReq* mFwkActionReqObj; + string mClientName; + }; + mContext.mMsgTask->sendMsg( + new (nothrow) HandleDisconnectBackhaul(mContext.mFrameworkActionReqObj, + clientName)); + } + else { + LOC_LOGe("Framework action request object is NULL.Caching disconnect request: %s", + clientName.c_str()); + // Check if client has requested for backhaul connection. + ClientBackhaulReqCache::const_iterator iter = mBackHaulConnReqCache.find(clientName); + if (iter != mBackHaulConnReqCache.end()) { + // client found, remove from set. + LOC_LOGd("Removing client from BackHaulConnReqCache list"); + mBackHaulConnReqCache.erase(iter); + } + result = false; + } + return result; +} +#endif +/****************************************************************************** + Helpers +******************************************************************************/ +void SystemStatusOsObserver::sendCachedDataItems( + const unordered_set<DataItemId>& s, IDataItemObserver* to) +{ + if (nullptr == to) { + LOC_LOGv("client pointer is NULL."); + } else { + string clientName; + to->getName(clientName); + list<IDataItemCore*> dataItems = {}; + + for (auto each : s) { + auto citer = mDataItemCache.find(each); + if (citer != mDataItemCache.end()) { + string dv; + citer->second->stringify(dv); + LOC_LOGI("DataItem: %s >> %s", dv.c_str(), clientName.c_str()); + dataItems.push_front(citer->second); + } + } + + if (dataItems.empty()) { + LOC_LOGv("No items to notify."); + } else { + to->notify(dataItems); + } + } +} + +bool SystemStatusOsObserver::updateCache(IDataItemCore* d) +{ + bool dataItemUpdated = false; + + // Request systemstatus to record this dataitem in its cache + // if the return is false, it means that SystemStatus is not + // handling it, so SystemStatusOsObserver also doesn't. + // So it has to be true to proceed. + if (nullptr != d && mSystemStatus->eventDataItemNotify(d)) { + auto citer = mDataItemCache.find(d->getId()); + if (citer == mDataItemCache.end()) { + // New data item; not found in cache + IDataItemCore* dataitem = DataItemsFactoryProxy::createNewDataItem(d->getId()); + if (nullptr != dataitem) { + // Copy the contents of the data item + dataitem->copy(d); + // Insert in mDataItemCache + mDataItemCache.insert(std::make_pair(d->getId(), dataitem)); + dataItemUpdated = true; + } + } else { + // Found in cache; Update cache if necessary + citer->second->copy(d, &dataItemUpdated); + } + + if (dataItemUpdated) { + LOC_LOGV("DataItem:%d updated:%d", d->getId(), dataItemUpdated); + } + } + + return dataItemUpdated; +} + +} // namespace loc_core + diff --git a/gps/core/SystemStatusOsObserver.h b/gps/core/SystemStatusOsObserver.h new file mode 100644 index 0000000..c0f56d8 --- /dev/null +++ b/gps/core/SystemStatusOsObserver.h @@ -0,0 +1,181 @@ +/* Copyright (c) 2015-2017, 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. + * + */ +#ifndef __SYSTEM_STATUS_OSOBSERVER__ +#define __SYSTEM_STATUS_OSOBSERVER__ + +#include <cinttypes> +#include <string> +#include <list> +#include <map> +#include <new> +#include <vector> + +#include <MsgTask.h> +#include <DataItemId.h> +#include <IOsObserver.h> +#include <loc_pla.h> +#include <log_util.h> +#include <LocUnorderedSetMap.h> + +namespace loc_core +{ +/****************************************************************************** + SystemStatusOsObserver +******************************************************************************/ +using namespace std; +using namespace loc_util; + +// Forward Declarations +class IDataItemCore; +class SystemStatus; +class SystemStatusOsObserver; +typedef map<IDataItemObserver*, list<DataItemId>> ObserverReqCache; +typedef LocUnorderedSetMap<IDataItemObserver*, DataItemId> ClientToDataItems; +typedef LocUnorderedSetMap<DataItemId, IDataItemObserver*> DataItemToClients; +typedef unordered_map<DataItemId, IDataItemCore*> DataItemIdToCore; +typedef unordered_map<DataItemId, int> DataItemIdToInt; +#ifdef USE_GLIB +// Cache details of backhaul client requests +typedef unordered_set<string> ClientBackhaulReqCache; +#endif + +struct ObserverContext { + IDataItemSubscription* mSubscriptionObj; + IFrameworkActionReq* mFrameworkActionReqObj; + const MsgTask* mMsgTask; + SystemStatusOsObserver* mSSObserver; + + inline ObserverContext(const MsgTask* msgTask, SystemStatusOsObserver* observer) : + mSubscriptionObj(NULL), mFrameworkActionReqObj(NULL), + mMsgTask(msgTask), mSSObserver(observer) {} +}; + +// Clients wanting to get data from OS/Framework would need to +// subscribe with OSObserver using IDataItemSubscription interface. +// Such clients would need to implement IDataItemObserver interface +// to receive data when it becomes available. +class SystemStatusOsObserver : public IOsObserver { + +public: + // ctor + inline SystemStatusOsObserver(SystemStatus* systemstatus, const MsgTask* msgTask) : + mSystemStatus(systemstatus), mContext(msgTask, this), + mAddress("SystemStatusOsObserver"), + mClientToDataItems(MAX_DATA_ITEM_ID), mDataItemToClients(MAX_DATA_ITEM_ID) {} + + // dtor + ~SystemStatusOsObserver(); + + template <typename CINT, typename COUT> + static COUT containerTransfer(CINT& s); + template <typename CINT, typename COUT> + inline static COUT containerTransfer(CINT&& s) { + return containerTransfer<CINT, COUT>(s); + } + + // To set the subscription object + virtual void setSubscriptionObj(IDataItemSubscription* subscriptionObj); + + // To set the framework action request object + inline void setFrameworkActionReqObj(IFrameworkActionReq* frameworkActionReqObj) { + mContext.mFrameworkActionReqObj = frameworkActionReqObj; +#ifdef USE_GLIB + uint32_t numBackHaulClients = mBackHaulConnReqCache.size(); + if (numBackHaulClients > 0) { + // For each client, invoke connectbackhaul. + for (auto clientName : mBackHaulConnReqCache) { + LOC_LOGd("Invoke connectBackhaul for client: %s", clientName.c_str()); + connectBackhaul(clientName); + } + // Clear the set + mBackHaulConnReqCache.clear(); + } +#endif + } + + // IDataItemSubscription Overrides + inline virtual void subscribe(const list<DataItemId>& l, IDataItemObserver* client) override { + subscribe(l, client, false); + } + virtual void updateSubscription(const list<DataItemId>& l, IDataItemObserver* client) override; + inline virtual void requestData(const list<DataItemId>& l, IDataItemObserver* client) override { + subscribe(l, client, true); + } + virtual void unsubscribe(const list<DataItemId>& l, IDataItemObserver* client) override; + virtual void unsubscribeAll(IDataItemObserver* client) override; + + // IDataItemObserver Overrides + virtual void notify(const list<IDataItemCore*>& dlist) override; + inline virtual void getName(string& name) override { + name = mAddress; + } + + // IFrameworkActionReq Overrides + virtual void turnOn(DataItemId dit, int timeOut = 0) override; + virtual void turnOff(DataItemId dit) override; +#ifdef USE_GLIB + virtual bool connectBackhaul(const string& clientName) override; + virtual bool disconnectBackhaul(const string& clientName) override; +#endif + +private: + SystemStatus* mSystemStatus; + ObserverContext mContext; + const string mAddress; + ClientToDataItems mClientToDataItems; + DataItemToClients mDataItemToClients; + DataItemIdToCore mDataItemCache; + DataItemIdToInt mActiveRequestCount; + + // Cache the subscribe and requestData till subscription obj is obtained + void cacheObserverRequest(ObserverReqCache& reqCache, + const list<DataItemId>& l, IDataItemObserver* client); +#ifdef USE_GLIB + // Cache the framework action request for connect/disconnect + ClientBackhaulReqCache mBackHaulConnReqCache; +#endif + + void subscribe(const list<DataItemId>& l, IDataItemObserver* client, bool toRequestData); + + // Helpers + void sendCachedDataItems(const unordered_set<DataItemId>& s, IDataItemObserver* to); + bool updateCache(IDataItemCore* d); + inline void logMe(const unordered_set<DataItemId>& l) { + IF_LOC_LOGD { + for (auto id : l) { + LOC_LOGD("DataItem %d", id); + } + } + } +}; + +} // namespace loc_core + +#endif //__SYSTEM_STATUS__ + diff --git a/gps/core/configure.ac b/gps/core/configure.ac new file mode 100644 index 0000000..19db9cf --- /dev/null +++ b/gps/core/configure.ac @@ -0,0 +1,107 @@ +# configure.ac -- Autoconf script for gps loc-core +# +# Process this file with autoconf to produce a configure script + +# Requires autoconf tool later than 2.61 +AC_PREREQ(2.61) +# Initialize the gps loc-hal package version 1.0.0 +AC_INIT([loc-core],1.0.0) +# Does not strictly follow GNU Coding standards +AM_INIT_AUTOMAKE([foreign subdir-objects]) +# Disables auto rebuilding of configure, Makefile.ins +AM_MAINTAINER_MODE +# Verifies the --srcdir is correct by checking for the path +AC_CONFIG_SRCDIR([loc-core.pc.in]) +# defines some macros variable to be included by source +AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_MACRO_DIR([m4]) + +# Checks for programs. +AC_PROG_LIBTOOL +AC_PROG_CXX +AC_PROG_CC +AM_PROG_CC_C_O +AC_PROG_AWK +AC_PROG_CPP +AC_PROG_INSTALL +AC_PROG_LN_S +AC_PROG_MAKE_SET +PKG_PROG_PKG_CONFIG + +# Checks for libraries. +PKG_CHECK_MODULES([GPSUTILS], [gps-utils]) +AC_SUBST([GPSUTILS_CFLAGS]) +AC_SUBST([GPSUTILS_LIBS]) + +AC_ARG_WITH([core_includes], + AC_HELP_STRING([--with-core-includes=@<:@dir@:>@], + [Specify the location of the core headers]), + [core_incdir=$withval], + with_core_includes=no) + +if test "x$with_core_includes" != "xno"; then + CPPFLAGS="${CPPFLAGS} -I${core_incdir}" +fi + +AC_ARG_WITH([locpla_includes], + AC_HELP_STRING([--with-locpla-includes=@<:@dir@:>@], + [specify the path to locpla-includes in loc-pla_git.bb]), + [locpla_incdir=$withval], + with_locpla_includes=no) + +if test "x$with_locpla_includes" != "xno"; then + AC_SUBST(LOCPLA_CFLAGS, "-I${locpla_incdir}") +fi + +AC_SUBST([CPPFLAGS]) + +AC_ARG_WITH([glib], + AC_HELP_STRING([--with-glib], + [enable glib, building HLOS systems which use glib])) + +if (test "x${with_glib}" = "xyes"); then + AC_DEFINE(ENABLE_USEGLIB, 1, [Define if HLOS systems uses glib]) + PKG_CHECK_MODULES(GTHREAD, gthread-2.0 >= 2.16, dummy=yes, + AC_MSG_ERROR(GThread >= 2.16 is required)) + PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.16, dummy=yes, + AC_MSG_ERROR(GLib >= 2.16 is required)) + GLIB_CFLAGS="$GLIB_CFLAGS $GTHREAD_CFLAGS" + GLIB_LIBS="$GLIB_LIBS $GTHREAD_LIBS" + + AC_SUBST(GLIB_CFLAGS) + AC_SUBST(GLIB_LIBS) +fi + +AM_CONDITIONAL(USE_GLIB, test "x${with_glib}" = "xyes") + +AC_ARG_WITH([auto_feature], + AC_HELP_STRING([--with-auto_feature=@<:@dir@:>@], + [Using Automotive feature]), + [], + with_auto_feature=no) + +if test "x$with_auto_feature" != "xno"; then + CPPFLAGS="${CPPFLAGS} -DFEATURE_AUTOMOTIVE" +fi + +AM_CONDITIONAL(USE_FEATURE_AUTOMOTIVE, test "x${with_auto_feature}" = "xyes") + +# External AP +AC_ARG_WITH([external_ap], + AC_HELP_STRING([--with-external_ap=@<:@dir@:>@], + [Using External Application Processor]), + [], + with_external_ap=no) + +if test "x$with_external_ap" != "xno"; then + CPPFLAGS="${CPPFLAGS} -DFEATURE_EXTERNAL_AP" +fi + +AM_CONDITIONAL(USE_EXTERNAL_AP, test "x${with_external_ap}" = "xyes") + +AC_CONFIG_FILES([ \ + Makefile \ + loc-core.pc \ + ]) + +AC_OUTPUT diff --git a/gps/core/data-items/DataItemConcreteTypesBase.h b/gps/core/data-items/DataItemConcreteTypesBase.h new file mode 100644 index 0000000..11a3cce --- /dev/null +++ b/gps/core/data-items/DataItemConcreteTypesBase.h @@ -0,0 +1,555 @@ +/* Copyright (c) 2015-2017, 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. + * + */ + +#ifndef __DATAITEMCONCRETEBASETYPES__ +#define __DATAITEMCONCRETEBASETYPES__ + +#include <string> +#include <cstring> +#include <sstream> +#include <DataItemId.h> +#include <IDataItemCore.h> +#include <gps_extended_c.h> +#include <inttypes.h> + +#define MAC_ADDRESS_LENGTH 6 +// MAC address length in bytes +// QMI_LOC_SRN_MAC_ADDR_LENGTH_V02 +#define SRN_MAC_ADDRESS_LENGTH 6 +#define WIFI_SUPPLICANT_DEFAULT_STATE 0 + +static constexpr char sDelimit = ':'; + +namespace loc_core +{ +using namespace std; + +enum NetworkType { + TYPE_MOBILE = 0, + TYPE_WIFI, + TYPE_ETHERNET, + TYPE_BLUETOOTH, + TYPE_MMS, + TYPE_SUPL, + TYPE_DUN, + TYPE_HIPRI, + TYPE_WIMAX, + TYPE_PROXY, + TYPE_UNKNOWN, +}; + +typedef struct NetworkInfoType +{ + // Unique network handle ID + uint64_t networkHandle; + // Type of network for corresponding network handle + NetworkType networkType; + NetworkInfoType() : networkHandle(NETWORK_HANDLE_UNKNOWN), networkType(TYPE_UNKNOWN) {} + NetworkInfoType(string strObj) { + size_t posDelimit = strObj.find(sDelimit); + + if ( posDelimit != string::npos) { + int32_t type = TYPE_UNKNOWN; + string handleStr = strObj.substr(0, posDelimit); + string typeStr = strObj.substr(posDelimit + 1, strObj.length() - posDelimit - 1); + stringstream(handleStr) >> networkHandle; + stringstream(typeStr) >> type; + networkType = (NetworkType) type; + } else { + networkHandle = NETWORK_HANDLE_UNKNOWN; + networkType = TYPE_UNKNOWN; + } + } + bool operator== (const NetworkInfoType& other) { + return ((networkHandle == other.networkHandle) && (networkType == other.networkType)); + } + string toString() { + string valueStr; + valueStr.clear (); + char nethandle [32]; + memset (nethandle, 0, 32); + snprintf(nethandle, sizeof(nethandle), "%" PRIu64, networkHandle); + valueStr += string(nethandle); + valueStr += sDelimit; + char type [12]; + memset (type, 0, 12); + snprintf (type, 12, "%u", networkType); + valueStr += string (type); + return valueStr; + } +} NetworkInfoType; + + +class AirplaneModeDataItemBase : public IDataItemCore { +public: + AirplaneModeDataItemBase(bool mode): + mMode(mode), + mId(AIRPLANEMODE_DATA_ITEM_ID) {} + virtual ~AirplaneModeDataItemBase() {} + inline virtual DataItemId getId() { return mId; } + virtual void stringify(string& /*valueStr*/) {} + virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;} +// Data members + bool mMode; + +protected: + DataItemId mId; +}; + +class ENHDataItemBase : public IDataItemCore { +public: + ENHDataItemBase(bool enabled) : + mEnabled(enabled), + mId(ENH_DATA_ITEM_ID) {} + virtual ~ENHDataItemBase() {} + inline virtual DataItemId getId() { return mId; } + virtual void stringify(string& /*valueStr*/) {} + virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;} +// Data members + bool mEnabled; +protected: + DataItemId mId; +}; + +class GPSStateDataItemBase : public IDataItemCore { +public: + GPSStateDataItemBase(bool enabled) : + mEnabled(enabled), + mId(GPSSTATE_DATA_ITEM_ID) {} + virtual ~GPSStateDataItemBase() {} + inline virtual DataItemId getId() { return mId; } + virtual void stringify(string& /*valueStr*/) {} + virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;} +// Data members + bool mEnabled; +protected: + DataItemId mId; +}; + +class NLPStatusDataItemBase : public IDataItemCore { +public: + NLPStatusDataItemBase(bool enabled) : + mEnabled(enabled), + mId(NLPSTATUS_DATA_ITEM_ID) {} + virtual ~NLPStatusDataItemBase() {} + inline virtual DataItemId getId() { return mId; } + virtual void stringify(string& /*valueStr*/) {} + virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;} +// Data members + bool mEnabled; +protected: + DataItemId mId; +}; + +class WifiHardwareStateDataItemBase : public IDataItemCore { +public: + WifiHardwareStateDataItemBase(bool enabled) : + mEnabled(enabled), + mId(WIFIHARDWARESTATE_DATA_ITEM_ID) {} + virtual ~WifiHardwareStateDataItemBase() {} + inline virtual DataItemId getId() { return mId; } + virtual void stringify(string& /*valueStr*/) {} + virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;} +// Data members + bool mEnabled; +protected: + DataItemId mId; +}; + +class ScreenStateDataItemBase : public IDataItemCore { +public: + ScreenStateDataItemBase(bool state) : + mState(state), + mId(SCREEN_STATE_DATA_ITEM_ID) {} + virtual ~ScreenStateDataItemBase() {} + inline virtual DataItemId getId() { return mId; } + virtual void stringify(string& /*valueStr*/) {} + virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;} +// Data members + bool mState; +protected: + DataItemId mId; +}; + +class PowerConnectStateDataItemBase : public IDataItemCore { +public: + PowerConnectStateDataItemBase(bool state) : + mState(state), + mId(POWER_CONNECTED_STATE_DATA_ITEM_ID) {} + virtual ~PowerConnectStateDataItemBase() {} + inline virtual DataItemId getId() { return mId; } + virtual void stringify(string& /*valueStr*/) {} + virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;} +// Data members + bool mState; +protected: + DataItemId mId; +}; + +class TimeZoneChangeDataItemBase : public IDataItemCore { +public: + TimeZoneChangeDataItemBase(int64_t currTimeMillis, int32_t rawOffset, int32_t dstOffset) : + mCurrTimeMillis (currTimeMillis), + mRawOffsetTZ (rawOffset), + mDstOffsetTZ (dstOffset), + mId(TIMEZONE_CHANGE_DATA_ITEM_ID) {} + virtual ~TimeZoneChangeDataItemBase() {} + inline virtual DataItemId getId() { return mId; } + virtual void stringify(string& /*valueStr*/) {} + virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;} +// Data members + int64_t mCurrTimeMillis; + int32_t mRawOffsetTZ; + int32_t mDstOffsetTZ; +protected: + DataItemId mId; +}; + +class TimeChangeDataItemBase : public IDataItemCore { +public: + TimeChangeDataItemBase(int64_t currTimeMillis, int32_t rawOffset, int32_t dstOffset) : + mCurrTimeMillis (currTimeMillis), + mRawOffsetTZ (rawOffset), + mDstOffsetTZ (dstOffset), + mId(TIME_CHANGE_DATA_ITEM_ID) {} + virtual ~TimeChangeDataItemBase() {} + inline virtual DataItemId getId() { return mId; } + virtual void stringify(string& /*valueStr*/) {} + virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;} +// Data members + int64_t mCurrTimeMillis; + int32_t mRawOffsetTZ; + int32_t mDstOffsetTZ; +protected: + DataItemId mId; +}; + +class ShutdownStateDataItemBase : public IDataItemCore { +public: + ShutdownStateDataItemBase(bool state) : + mState (state), + mId(SHUTDOWN_STATE_DATA_ITEM_ID) {} + virtual ~ShutdownStateDataItemBase() {} + inline virtual DataItemId getId() { return mId; } + virtual void stringify(string& /*valueStr*/) {} + virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;} +// Data members + bool mState; +protected: + DataItemId mId; +}; + +class AssistedGpsDataItemBase : public IDataItemCore { +public: + AssistedGpsDataItemBase(bool enabled) : + mEnabled(enabled), + mId(ASSISTED_GPS_DATA_ITEM_ID) {} + virtual ~AssistedGpsDataItemBase() {} + inline virtual DataItemId getId() { return mId; } + virtual void stringify(string& /*valueStr*/) {} + virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;} +// Data members + bool mEnabled; +protected: + DataItemId mId; +}; + +class NetworkInfoDataItemBase : public IDataItemCore { +public: + NetworkInfoDataItemBase( + NetworkType initialType, int32_t type, string typeName, string subTypeName, + bool available, bool connected, bool roaming, uint64_t networkHandle, string apn): + mAllTypes(typeToAllTypes(initialType)), + mType(type), + mTypeName(typeName), + mSubTypeName(subTypeName), + mAvailable(available), + mConnected(connected), + mRoaming(roaming), + mNetworkHandle(networkHandle), + mId(NETWORKINFO_DATA_ITEM_ID), mApn(apn) { + mAllNetworkHandles[0].networkHandle = networkHandle; + mAllNetworkHandles[0].networkType = initialType; + } + virtual ~NetworkInfoDataItemBase() {} + inline virtual DataItemId getId() { return mId; } + virtual void stringify(string& /*valueStr*/) {} + virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;} + inline virtual NetworkType getType(void) const { + return (NetworkType)mType; + } + inline uint64_t getAllTypes() { return mAllTypes; } + inline NetworkInfoType* getNetworkHandle() { + return &mAllNetworkHandles[0]; + } + // Data members + uint64_t mAllTypes; + int32_t mType; + string mTypeName; + string mSubTypeName; + bool mAvailable; + bool mConnected; + bool mRoaming; + NetworkInfoType mAllNetworkHandles[MAX_NETWORK_HANDLES]; + uint64_t mNetworkHandle; + string mApn; +protected: + DataItemId mId; + inline uint64_t typeToAllTypes(NetworkType type) { + return (type >= TYPE_UNKNOWN || type < TYPE_MOBILE) ? 0 : (1<<type); + } +}; + +class ServiceStatusDataItemBase : public IDataItemCore { +public: + ServiceStatusDataItemBase(int32_t serviceState) : + mServiceState (serviceState), + mId(SERVICESTATUS_DATA_ITEM_ID) {} + virtual ~ServiceStatusDataItemBase() {} + inline virtual DataItemId getId() { return mId; } + virtual void stringify(string& /*valueStr*/) {} + virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;} +// Data members + int32_t mServiceState; +protected: + DataItemId mId; +}; + +class ModelDataItemBase : public IDataItemCore { +public: + ModelDataItemBase(const string & name) : + mModel (name), + mId(MODEL_DATA_ITEM_ID) {} + virtual ~ModelDataItemBase() {} + inline virtual DataItemId getId() { return mId; } + virtual void stringify(string& /*valueStr*/) {} + virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;} +// Data members + string mModel; +protected: + DataItemId mId; +}; + +class ManufacturerDataItemBase : public IDataItemCore { +public: + ManufacturerDataItemBase(const string & name) : + mManufacturer (name), + mId(MANUFACTURER_DATA_ITEM_ID) {} + virtual ~ManufacturerDataItemBase() {} + inline virtual DataItemId getId() { return mId; } + virtual void stringify(string& /*valueStr*/) {} + virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;} +// Data members + string mManufacturer; +protected: + DataItemId mId; +}; + +class RilServiceInfoDataItemBase : public IDataItemCore { +public: + inline RilServiceInfoDataItemBase() : + mData(nullptr), mId(RILSERVICEINFO_DATA_ITEM_ID) {} + inline virtual ~RilServiceInfoDataItemBase() { if (nullptr != mData) free(mData); } + inline virtual DataItemId getId() { return mId; } + virtual void stringify(string& /*valueStr*/) {} + virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;} + inline RilServiceInfoDataItemBase(const RilServiceInfoDataItemBase& peer) : + RilServiceInfoDataItemBase() { + peer.setPeerData(*this); + } + inline virtual bool operator==(const RilServiceInfoDataItemBase& other) const { + return other.mData == mData; + } + inline virtual void setPeerData(RilServiceInfoDataItemBase& /*peer*/) const {} + void* mData; +protected: + DataItemId mId; +}; + +class RilCellInfoDataItemBase : public IDataItemCore { +public: + inline RilCellInfoDataItemBase() : + mData(nullptr), mId(RILCELLINFO_DATA_ITEM_ID) {} + inline virtual ~RilCellInfoDataItemBase() { if (nullptr != mData) free(mData); } + inline virtual DataItemId getId() { return mId; } + virtual void stringify(string& /*valueStr*/) {} + virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;} + inline RilCellInfoDataItemBase(const RilCellInfoDataItemBase& peer) : + RilCellInfoDataItemBase() { + peer.setPeerData(*this); + } + inline virtual bool operator==(const RilCellInfoDataItemBase& other) const { + return other.mData == mData; + } + inline virtual void setPeerData(RilCellInfoDataItemBase& /*peer*/) const {} + void* mData; +protected: + DataItemId mId; +}; + +class WifiSupplicantStatusDataItemBase : public IDataItemCore { +public: + WifiSupplicantStatusDataItemBase() : + mState((WifiSupplicantState)WIFI_SUPPLICANT_DEFAULT_STATE), + mApMacAddressValid(false), + mWifiApSsidValid(false), + mId(WIFI_SUPPLICANT_STATUS_DATA_ITEM_ID) { + memset (&mApMacAddress, 0, sizeof (mApMacAddress)); + mWifiApSsid.clear(); + } + virtual ~WifiSupplicantStatusDataItemBase() {} + inline virtual DataItemId getId() { return mId; } + virtual void stringify(string& /*valueStr*/) {} + virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;} + // Data members + typedef enum WifiSupplicantState { + DISCONNECTED, + INTERFACE_DISABLED, + INACTIVE, + SCANNING, + AUTHENTICATING, + ASSOCIATING, + ASSOCIATED, + FOUR_WAY_HANDSHAKE, + GROUP_HANDSHAKE, + COMPLETED, + DORMANT, + UNINITIALIZED, + INVALID + } WifiSupplicantState; + /* Represents whether access point attach state*/ + WifiSupplicantState mState; + /* Represents info on whether ap mac address is valid */ + bool mApMacAddressValid; + /* Represents mac address of the wifi access point*/ + uint8_t mApMacAddress[MAC_ADDRESS_LENGTH]; + /* Represents info on whether ap SSID is valid */ + bool mWifiApSsidValid; + /* Represents Wifi SSID string*/ + string mWifiApSsid; +protected: + DataItemId mId; +}; + +class TacDataItemBase : public IDataItemCore { +public: + TacDataItemBase(const string & name) : + mValue (name), + mId(TAC_DATA_ITEM_ID) {} + virtual ~TacDataItemBase() {} + inline virtual DataItemId getId() { return mId; } + virtual void stringify(string& /*valueStr*/) {} + virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;} +// Data members + string mValue; +protected: + DataItemId mId; +}; + +class MccmncDataItemBase : public IDataItemCore { +public: + MccmncDataItemBase(const string & name) : + mValue(name), + mId(MCCMNC_DATA_ITEM_ID) {} + virtual ~MccmncDataItemBase() {} + inline virtual DataItemId getId() { return mId; } + virtual void stringify(string& /*valueStr*/) {} + virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;} +// Data members + string mValue; +protected: + DataItemId mId; +}; + +class SrnDeviceScanDetailsDataItemBase : public IDataItemCore { +public: + SrnDeviceScanDetailsDataItemBase(DataItemId Id) : + mValidSrnData(false), + mApSrnRssi(-1), + mApSrnTimestamp(0), + mRequestTimestamp(0), + mReceiveTimestamp(0), + mErrorCause(-1), + mId(Id) {} + virtual ~SrnDeviceScanDetailsDataItemBase() {} + inline virtual DataItemId getId() { return mId; } + // Data members common to all SRN tech types + /* Represents info on whether SRN data is valid (no error)*/ + bool mValidSrnData; + /* SRN device RSSI reported */ + int32_t mApSrnRssi; + /* MAC adress of SRN device */ + uint8_t mApSrnMacAddress[SRN_MAC_ADDRESS_LENGTH]; + /* UTC timestamp at which the scan was requested.for this SRN device*/ + int64_t mApSrnTimestamp; + /* UTC timestamp at which the scan was started. */ + int64_t mRequestTimestamp; + /* UTC timestamp at which the scan was received.*/ + int64_t mReceiveTimestamp; + /* Reason for the error/failure if SRN details are not valid */ + int32_t mErrorCause; +protected: + DataItemId mId; +}; + +class BtDeviceScanDetailsDataItemBase : public SrnDeviceScanDetailsDataItemBase { + +public: + BtDeviceScanDetailsDataItemBase() : + SrnDeviceScanDetailsDataItemBase(BT_SCAN_DATA_ITEM_ID) {} + virtual ~BtDeviceScanDetailsDataItemBase() {} + virtual void stringify(string& /*valueStr*/) {} + virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;} +}; + +class BtLeDeviceScanDetailsDataItemBase : public SrnDeviceScanDetailsDataItemBase { + +public: + BtLeDeviceScanDetailsDataItemBase() : + SrnDeviceScanDetailsDataItemBase(BTLE_SCAN_DATA_ITEM_ID) {} + virtual ~BtLeDeviceScanDetailsDataItemBase() {} + virtual void stringify(string& /*valueStr*/) {} + virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;} +}; + +class BatteryLevelDataItemBase : public IDataItemCore { +public: + inline BatteryLevelDataItemBase(uint8_t batteryPct) : + mBatteryPct(batteryPct), mId(BATTERY_LEVEL_DATA_ITEM_ID) {} + inline ~BatteryLevelDataItemBase() {} + inline virtual DataItemId getId() { return mId; } +// Data members + uint8_t mBatteryPct; +protected: + DataItemId mId; +}; + +} // namespace loc_core + +#endif //__DATAITEMCONCRETEBASETYPES__ diff --git a/gps/core/data-items/DataItemId.h b/gps/core/data-items/DataItemId.h new file mode 100644 index 0000000..1661be6 --- /dev/null +++ b/gps/core/data-items/DataItemId.h @@ -0,0 +1,79 @@ +/* Copyright (c) 2015-2017 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. + * + */ + +#ifndef __DATAITEMID_H__ +#define __DATAITEMID_H__ + +/** + * Enumeration of Data Item types + * When add/remove/update changes are made to Data Items, this file needs to be updated + * accordingly + */ +typedef enum e_DataItemId { + INVALID_DATA_ITEM_ID = -1, + // 0 - 4 + AIRPLANEMODE_DATA_ITEM_ID, + ENH_DATA_ITEM_ID, + GPSSTATE_DATA_ITEM_ID, + NLPSTATUS_DATA_ITEM_ID, + WIFIHARDWARESTATE_DATA_ITEM_ID, + // 5 - 9 + NETWORKINFO_DATA_ITEM_ID, + RILVERSION_DATA_ITEM_ID, + RILSERVICEINFO_DATA_ITEM_ID, + RILCELLINFO_DATA_ITEM_ID, + SERVICESTATUS_DATA_ITEM_ID, + // 10 - 14 + MODEL_DATA_ITEM_ID, + MANUFACTURER_DATA_ITEM_ID, + VOICECALL_DATA_ITEM, + ASSISTED_GPS_DATA_ITEM_ID, + SCREEN_STATE_DATA_ITEM_ID, + // 15 - 19 + POWER_CONNECTED_STATE_DATA_ITEM_ID, + TIMEZONE_CHANGE_DATA_ITEM_ID, + TIME_CHANGE_DATA_ITEM_ID, + WIFI_SUPPLICANT_STATUS_DATA_ITEM_ID, + SHUTDOWN_STATE_DATA_ITEM_ID, + // 20 - 24 + TAC_DATA_ITEM_ID, + MCCMNC_DATA_ITEM_ID, + BTLE_SCAN_DATA_ITEM_ID, + BT_SCAN_DATA_ITEM_ID, + OEM_GTP_UPLOAD_TRIGGER_READY_ITEM_ID, + + MAX_DATA_ITEM_ID, + + // 26 - + BATTERY_LEVEL_DATA_ITEM_ID, + + MAX_DATA_ITEM_ID_1_1, +} DataItemId; + +#endif // #ifndef __DATAITEMID_H__ diff --git a/gps/core/data-items/DataItemsFactoryProxy.cpp b/gps/core/data-items/DataItemsFactoryProxy.cpp new file mode 100644 index 0000000..10f73f4 --- /dev/null +++ b/gps/core/data-items/DataItemsFactoryProxy.cpp @@ -0,0 +1,82 @@ +/* Copyright (c) 2017-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 "DataItemsFactoryProxy" + +#include <dlfcn.h> +#include <DataItemId.h> +#include <IDataItemCore.h> +#include <DataItemsFactoryProxy.h> +#include <loc_pla.h> +#include <log_util.h> +#include "loc_misc_utils.h" + +namespace loc_core +{ +void* DataItemsFactoryProxy::dataItemLibHandle = NULL; +get_concrete_data_item_fn* DataItemsFactoryProxy::getConcreteDIFunc = NULL; + +IDataItemCore* DataItemsFactoryProxy::createNewDataItem(DataItemId id) +{ + IDataItemCore *mydi = nullptr; + + if (NULL != getConcreteDIFunc) { + mydi = (*getConcreteDIFunc)(id); + } + else { + getConcreteDIFunc = (get_concrete_data_item_fn * ) + dlGetSymFromLib(dataItemLibHandle, DATA_ITEMS_LIB_NAME, DATA_ITEMS_GET_CONCRETE_DI); + + if (NULL != getConcreteDIFunc) { + LOC_LOGd("Loaded function %s : %p", DATA_ITEMS_GET_CONCRETE_DI, getConcreteDIFunc); + mydi = (*getConcreteDIFunc)(id); + } + else { + // dlysm failed. + const char * err = dlerror(); + if (NULL == err) + { + err = "Unknown"; + } + LOC_LOGe("failed to find symbol %s; error=%s", DATA_ITEMS_GET_CONCRETE_DI, err); + } + } + return mydi; +} + +void DataItemsFactoryProxy::closeDataItemLibraryHandle() +{ + if (NULL != dataItemLibHandle) { + dlclose(dataItemLibHandle); + dataItemLibHandle = NULL; + } +} + +} // namespace loc_core + + diff --git a/gps/core/data-items/DataItemsFactoryProxy.h b/gps/core/data-items/DataItemsFactoryProxy.h new file mode 100644 index 0000000..cfd447d --- /dev/null +++ b/gps/core/data-items/DataItemsFactoryProxy.h @@ -0,0 +1,55 @@ +/* Copyright (c) 2017, 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. + * + */ + +#ifndef __DATAITEMFACTORYBASE__ +#define __DATAITEMFACTORYBASE__ + +#include <DataItemId.h> +#include <IDataItemCore.h> + +namespace loc_core +{ + +#define DATA_ITEMS_LIB_NAME "libdataitems.so" +#define DATA_ITEMS_GET_CONCRETE_DI "getConcreteDataItem" + +typedef IDataItemCore * (get_concrete_data_item_fn)(DataItemId); + +class DataItemsFactoryProxy { +public: + static IDataItemCore* createNewDataItem(DataItemId id); + static void closeDataItemLibraryHandle(); + static void *dataItemLibHandle; + static get_concrete_data_item_fn *getConcreteDIFunc; +}; + +} // namespace loc_core + +#endif //__DATAITEMFACTORYBASE__ + diff --git a/gps/core/data-items/IDataItemCore.h b/gps/core/data-items/IDataItemCore.h new file mode 100644 index 0000000..6084c92 --- /dev/null +++ b/gps/core/data-items/IDataItemCore.h @@ -0,0 +1,82 @@ +/* Copyright (c) 2015, 2017 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. + * + */ + +#ifndef __IDATAITEMCORE_H__ +#define __IDATAITEMCORE_H__ + +#include <string> +#include <DataItemId.h> + +namespace loc_core { + +using namespace std; + +/** + * @brief IDataItemCore interface. + * @details IDataItemCore interface. + * + */ +class IDataItemCore { +public: + /** + * @brief Gets Data item id. + * @details Gets Data item id. + * @return Data item id. + */ + virtual DataItemId getId () = 0; + + /** + * @brief Stringify. + * @details Stringify. + * + * @param valueStr Reference to string. + */ + virtual void stringify (string & valueStr) = 0; + + /** + * @brief copy. + * @details copy. + * + * @param src Where to copy from. + * @param dataItemCopied Boolean flag indicated whether or not copied. + * + * @return Zero for success or non zero for failure. + */ + virtual int32_t copy (IDataItemCore * src, bool *dataItemCopied = nullptr) = 0; + + /** + * @brief Destructor. + * @details Destructor. + */ + virtual ~IDataItemCore () {} +}; + +} // namespace loc_core + +#endif // __IDATAITEMCORE_H__ diff --git a/gps/core/loc-core.pc.in b/gps/core/loc-core.pc.in new file mode 100644 index 0000000..76b514c --- /dev/null +++ b/gps/core/loc-core.pc.in @@ -0,0 +1,10 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: loc-core +Description: QTI GPS Loc Core +Version: @VERSION@ +Libs: -L${libdir} -lloc_core +Cflags: -I${includedir}/loc-core diff --git a/gps/core/loc_core_log.cpp b/gps/core/loc_core_log.cpp new file mode 100644 index 0000000..904f94b --- /dev/null +++ b/gps/core/loc_core_log.cpp @@ -0,0 +1,215 @@ +/* Copyright (c) 2011-2015, 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_NDEBUG 0 +#define LOG_TAG "LocSvc_core_log" + +#include <log_util.h> +#include <loc_log.h> +#include <loc_core_log.h> +#include <loc_pla.h> + +void LocPosMode::logv() const +{ + LOC_LOGV ("Position mode: %s\n Position recurrence: %s\n " + "min interval: %d\n preferred accuracy: %d\n " + "preferred time: %d\n credentials: %s provider: %s \n " + "power mode: %d\n tbm %d", + loc_get_position_mode_name(mode), + loc_get_position_recurrence_name(recurrence), + min_interval, + preferred_accuracy, + preferred_time, + credentials, + provider, + powerMode, + timeBetweenMeasurements); +} + +/* GPS status names */ +DECLARE_TBL(gps_status_name) = +{ + NAME_VAL( LOC_GPS_STATUS_NONE ), + NAME_VAL( LOC_GPS_STATUS_SESSION_BEGIN ), + NAME_VAL( LOC_GPS_STATUS_SESSION_END ), + NAME_VAL( LOC_GPS_STATUS_ENGINE_ON ), + NAME_VAL( LOC_GPS_STATUS_ENGINE_OFF ), +}; + +/* Find Android GPS status name */ +const char* loc_get_gps_status_name(LocGpsStatusValue gps_status) +{ + return loc_get_name_from_val(gps_status_name_tbl, (int64_t) gps_status); +} + + + +DECLARE_TBL(loc_eng_position_modes) = +{ + NAME_VAL( LOC_POSITION_MODE_STANDALONE ), + NAME_VAL( LOC_POSITION_MODE_MS_BASED ), + NAME_VAL( LOC_POSITION_MODE_MS_ASSISTED ), + NAME_VAL( LOC_POSITION_MODE_RESERVED_1 ), + NAME_VAL( LOC_POSITION_MODE_RESERVED_2 ), + NAME_VAL( LOC_POSITION_MODE_RESERVED_3 ), + NAME_VAL( LOC_POSITION_MODE_RESERVED_4 ), + NAME_VAL( LOC_POSITION_MODE_RESERVED_5 ) +}; + +const char* loc_get_position_mode_name(LocGpsPositionMode mode) +{ + return loc_get_name_from_val(loc_eng_position_modes_tbl, (int64_t) mode); +} + + + +DECLARE_TBL(loc_eng_position_recurrences) = +{ + NAME_VAL( LOC_GPS_POSITION_RECURRENCE_PERIODIC ), + NAME_VAL( LOC_GPS_POSITION_RECURRENCE_SINGLE ) +}; + +const char* loc_get_position_recurrence_name(LocGpsPositionRecurrence recur) +{ + return loc_get_name_from_val(loc_eng_position_recurrences_tbl, (int64_t) recur); +} + +const char* loc_get_aiding_data_mask_names(LocGpsAidingData /*data*/) +{ + return NULL; +} + + +DECLARE_TBL(loc_eng_agps_types) = +{ + NAME_VAL( LOC_AGPS_TYPE_INVALID ), + NAME_VAL( LOC_AGPS_TYPE_ANY ), + NAME_VAL( LOC_AGPS_TYPE_SUPL ), + NAME_VAL( LOC_AGPS_TYPE_C2K ), + NAME_VAL( LOC_AGPS_TYPE_WWAN_ANY ) +}; + +const char* loc_get_agps_type_name(LocAGpsType type) +{ + return loc_get_name_from_val(loc_eng_agps_types_tbl, (int64_t) type); +} + + +DECLARE_TBL(loc_eng_ni_types) = +{ + NAME_VAL( LOC_GPS_NI_TYPE_VOICE ), + NAME_VAL( LOC_GPS_NI_TYPE_UMTS_SUPL ), + NAME_VAL( LOC_GPS_NI_TYPE_UMTS_CTRL_PLANE ), + NAME_VAL( LOC_GPS_NI_TYPE_EMERGENCY_SUPL ) +}; + +const char* loc_get_ni_type_name(LocGpsNiType type) +{ + return loc_get_name_from_val(loc_eng_ni_types_tbl, (int64_t) type); +} + + +DECLARE_TBL(loc_eng_ni_responses) = +{ + NAME_VAL( LOC_GPS_NI_RESPONSE_ACCEPT ), + NAME_VAL( LOC_GPS_NI_RESPONSE_DENY ), + NAME_VAL( LOC_GPS_NI_RESPONSE_DENY ) +}; + +const char* loc_get_ni_response_name(LocGpsUserResponseType response) +{ + return loc_get_name_from_val(loc_eng_ni_responses_tbl, (int64_t) response); +} + + +DECLARE_TBL(loc_eng_ni_encodings) = +{ + NAME_VAL( LOC_GPS_ENC_NONE ), + NAME_VAL( LOC_GPS_ENC_SUPL_GSM_DEFAULT ), + NAME_VAL( LOC_GPS_ENC_SUPL_UTF8 ), + NAME_VAL( LOC_GPS_ENC_SUPL_UCS2 ), + NAME_VAL( LOC_GPS_ENC_UNKNOWN ) +}; + +const char* loc_get_ni_encoding_name(LocGpsNiEncodingType encoding) +{ + return loc_get_name_from_val(loc_eng_ni_encodings_tbl, (int64_t) encoding); +} + +DECLARE_TBL(loc_eng_agps_bears) = +{ + NAME_VAL( AGPS_APN_BEARER_INVALID ), + NAME_VAL( AGPS_APN_BEARER_IPV4 ), + NAME_VAL( AGPS_APN_BEARER_IPV6 ), + NAME_VAL( AGPS_APN_BEARER_IPV4V6 ) +}; + +const char* loc_get_agps_bear_name(AGpsBearerType bearer) +{ + return loc_get_name_from_val(loc_eng_agps_bears_tbl, (int64_t) bearer); +} + +DECLARE_TBL(loc_eng_server_types) = +{ + NAME_VAL( LOC_AGPS_CDMA_PDE_SERVER ), + NAME_VAL( LOC_AGPS_CUSTOM_PDE_SERVER ), + NAME_VAL( LOC_AGPS_MPC_SERVER ), + NAME_VAL( LOC_AGPS_SUPL_SERVER ) +}; + +const char* loc_get_server_type_name(LocServerType type) +{ + return loc_get_name_from_val(loc_eng_server_types_tbl, (int64_t) type); +} + +DECLARE_TBL(loc_eng_position_sess_status_types) = +{ + NAME_VAL( LOC_SESS_SUCCESS ), + NAME_VAL( LOC_SESS_INTERMEDIATE ), + NAME_VAL( LOC_SESS_FAILURE ) +}; + +const char* loc_get_position_sess_status_name(enum loc_sess_status status) +{ + return loc_get_name_from_val(loc_eng_position_sess_status_types_tbl, (int64_t) status); +} + +DECLARE_TBL(loc_eng_agps_status_names) = +{ + NAME_VAL( LOC_GPS_REQUEST_AGPS_DATA_CONN ), + NAME_VAL( LOC_GPS_RELEASE_AGPS_DATA_CONN ), + NAME_VAL( LOC_GPS_AGPS_DATA_CONNECTED ), + NAME_VAL( LOC_GPS_AGPS_DATA_CONN_DONE ), + NAME_VAL( LOC_GPS_AGPS_DATA_CONN_FAILED ) +}; + +const char* loc_get_agps_status_name(LocAGpsStatusValue status) +{ + return loc_get_name_from_val(loc_eng_agps_status_names_tbl, (int64_t) status); +} diff --git a/gps/core/loc_core_log.h b/gps/core/loc_core_log.h new file mode 100644 index 0000000..2beb687 --- /dev/null +++ b/gps/core/loc_core_log.h @@ -0,0 +1,58 @@ +/* Copyright (c) 2011-2013, 2016-2017 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. + * + */ + +#ifndef LOC_CORE_LOG_H +#define LOC_CORE_LOG_H + +#include <ctype.h> +#include <gps_extended.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + +const char* loc_get_gps_status_name(LocGpsStatusValue gps_status); +const char* loc_get_position_mode_name(LocGpsPositionMode mode); +const char* loc_get_position_recurrence_name(LocGpsPositionRecurrence recur); +const char* loc_get_aiding_data_mask_names(LocGpsAidingData data); +const char* loc_get_agps_type_name(LocAGpsType type); +const char* loc_get_ni_type_name(LocGpsNiType type); +const char* loc_get_ni_response_name(LocGpsUserResponseType response); +const char* loc_get_ni_encoding_name(LocGpsNiEncodingType encoding); +const char* loc_get_agps_bear_name(AGpsBearerType bear); +const char* loc_get_server_type_name(LocServerType type); +const char* loc_get_position_sess_status_name(enum loc_sess_status status); +const char* loc_get_agps_status_name(LocAGpsStatusValue status); + +#ifdef __cplusplus +} +#endif + +#endif /* LOC_CORE_LOG_H */ diff --git a/gps/core/observer/IDataItemObserver.h b/gps/core/observer/IDataItemObserver.h new file mode 100644 index 0000000..7954d85 --- /dev/null +++ b/gps/core/observer/IDataItemObserver.h @@ -0,0 +1,76 @@ +/* Copyright (c) 2015, 2017 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. + * + */ + +#ifndef __IDATAITEMOBSERVER_H__ +#define __IDATAITEMOBSERVER_H__ + +#include <list> +#include <string> + +using namespace std; + +namespace loc_core +{ +class IDataItemCore; + +/** + * @brief IDataItemObserver interface + * @details IDataItemObserver interface; + * In OS dependent code this type serves as a handle to an OS independent instance of this interface. + */ +class IDataItemObserver { + +public: + + /** + * @brief Gets name of Data Item Observer + * @details Gets name of Data Item Observer + * + * @param name reference to name of Data Item Observer + */ + virtual void getName (string & name) = 0; + + /** + * @brief Notify updated values of Data Items + * @details Notifys updated values of Data items + * + * @param dlist List of updated data items + */ + virtual void notify (const std :: list <IDataItemCore *> & dlist) = 0; + + /** + * @brief Destructor + * @details Destructor + */ + virtual ~IDataItemObserver () {} +}; + +} // namespace loc_core + +#endif // #ifndef __IDATAITEMOBSERVER_H__ diff --git a/gps/core/observer/IDataItemSubscription.h b/gps/core/observer/IDataItemSubscription.h new file mode 100644 index 0000000..7e8b8c8 --- /dev/null +++ b/gps/core/observer/IDataItemSubscription.h @@ -0,0 +1,129 @@ +/* Copyright (c) 2015, 2017 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. + * + */ + +#ifndef __IDATAITEMSUBSCRIPTION_H__ +#define __IDATAITEMSUBSCRIPTION_H__ + +#include <list> +#include <DataItemId.h> + +namespace loc_core +{ +class IDataItemObserver; + +/** + * @brief IDataItemSubscription interface + * @details IDataItemSubscription interface; + * Defines an interface for operations such as subscribe, + * unsubscribe data items by their IDs. + * Must be implemented by OS dependent code. + */ +class IDataItemSubscription { + +public: + /** + * @brief Subscribe for data items by their IDs + * @details Subscribe for data items by their IDs; + * An IDataItemObserver implementer invokes this method to subscribe + * for a list of DataItems by passing in their Ids. + * A symbolic invocation of this method in the following order + * subscribe ( {1,2,3}, &obj), subscribe ( {2,3,4,5}, &obj) + * where the numbers enclosed in braces indicate a list of data item Ids + * will cause this class implementer to update its subscription list for + * &obj to only contain the following Data Item Ids 1,2,3,4,5. + * + * @param l List of DataItemId + * @param o Pointer to an instance of IDataItemObserver + */ + virtual void subscribe (const std :: list <DataItemId> & l, IDataItemObserver * o = NULL) = 0; + + /** + * @brief Update subscription for Data items + * @details Update subscription for Data items; + * An IDataItemObserver implementer invokes this method to update their + * subscription for a list of DataItems by passing in their Ids + * A symbolic invocation of this method in the following order + * updateSubscription ( {1,2,3}, &obj),updateSubscription ( {2,3,4,5}, &obj) + * where the numbers enclosed in braces indicate a list of data item Ids + * will cause this class implementer to update its subscription list for + * &obj to only contain the following Data Item Ids 2,3,4,5. + * Note that this method may or may not be called. + * + * @param l List of DataItemId + * @param o Pointer to an instance of IDataItemObserver + */ + virtual void updateSubscription (const std :: list <DataItemId> & l, IDataItemObserver * o = NULL) = 0; + + /** + * @brief Request Data + * @details Request Data + * + * @param l List of DataItemId + * @param o Pointer to an instance of IDataItemObserver + */ + virtual void requestData (const std :: list <DataItemId> & l, IDataItemObserver * o = NULL) = 0; + + /** + * @brief Unsubscribe Data items + * @details Unsubscrbe Data items; + * An IDataItemObserver implementer invokes this method to unsubscribe their + * subscription for a list of DataItems by passing in their Ids + * Suppose this class implementor has a currently active subscription list + * containing 1,2,3,4,5,6,7 for &obj then a symbolic invocation of this + * method in the following order + * unsubscribe ( {1,2,3}, &obj), unsubscribe ( {1,2,3,4}, &obj), + * unsubscribe ( {7}, &obj) + * where the numbers enclosed in braces indicate a list of data item Ids + * will cause this class implementer to update its subscription list for + * &obj to only contain the following data item id 5,6. + * + * @param l List of DataItemId + * @param o Pointer to an instance of IDataItemObserver + */ + virtual void unsubscribe (const std :: list <DataItemId> & l, IDataItemObserver * o = NULL) = 0; + + /** + * @brief Unsubscribe all data items + * @details Unsubscribe all data items + * + * @param o Pointer to an instance of IDataItemObserver + */ + virtual void unsubscribeAll (IDataItemObserver * o = NULL) = 0; + + /** + * @brief Destructor + * @details Destructor + */ + virtual ~IDataItemSubscription () {} +}; + +} // namespace loc_core + +#endif // #ifndef __IDATAITEMSUBSCRIPTION_H__ + diff --git a/gps/core/observer/IFrameworkActionReq.h b/gps/core/observer/IFrameworkActionReq.h new file mode 100644 index 0000000..138508c --- /dev/null +++ b/gps/core/observer/IFrameworkActionReq.h @@ -0,0 +1,104 @@ +/* Copyright (c) 2017, 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. + * + */ + +#ifndef __IFRAMEWORKACTIONREQ_H__ +#define __IFRAMEWORKACTIONREQ_H__ + +#include <string> +#include <DataItemId.h> + +using namespace std; + +namespace loc_core +{ + +/** + * @brief IFrameworkActionReq interface + * @details IFrameworkActionReq interface; + * Defines an interface for operations such as turnOn, turnOff a + * framework module described by the data item. Framework module + * could be bluetooth, wifi etc. + * Must be implemented by OS dependent code. + * + */ +class IFrameworkActionReq { + +public: + /** + * @brief Turn on the framework module described by the data item. + * @details Turn on the framework module described by the data item; + * An IFrameworkActionReq implementer invokes this method to + * turn on the framework module described by the data item. + * Framework module could be bluetooth, wifi etc. + * + * @param dit DataItemId + * @param timeout Timeout after which to turn off the framework module. + */ + virtual void turnOn (DataItemId dit, int timeOut = 0) = 0; + + /** + * @brief Turn off the framework module described by the data item. + * @details Turn off the framework module described by the data item; + * An IFrameworkActionReq implementer invokes this method to + * turn off the framework module described by the data item. + * Framework module could be bluetooth, wifi etc. + * + * @param dit DataItemId + */ + virtual void turnOff (DataItemId dit) = 0; + +#ifdef USE_GLIB + /** + * @brief Setup WWAN backhaul + * @details Setup WWAN backhaul + * + * @param None + */ + virtual bool connectBackhaul(const string& clientName) = 0; + + /** + * @brief Disconnects the WWANbackhaul + * @details Disconnects the WWANbackhaul, only if it was setup by us + * + * @param None + */ + virtual bool disconnectBackhaul(const string& clientName) = 0; +#endif + + /** + * @brief Destructor + * @details Destructor + */ + virtual ~IFrameworkActionReq () {} +}; + +} // namespace loc_core + +#endif // #ifndef __IFRAMEWORKACTIONREQ_H__ + diff --git a/gps/core/observer/IOsObserver.h b/gps/core/observer/IOsObserver.h new file mode 100644 index 0000000..a25bb9f --- /dev/null +++ b/gps/core/observer/IOsObserver.h @@ -0,0 +1,107 @@ +/* Copyright (c) 2017, 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. + * + */ + +#ifndef __IOSOBSERVER_H__ +#define __IOSOBSERVER_H__ + +#include <list> +#include <string> +#include <IDataItemObserver.h> +#include <IDataItemSubscription.h> +#include <IFrameworkActionReq.h> + +using namespace std; + +namespace loc_core +{ + +/** + * @brief IOsObserver interface + * @details IOsObserver interface; + * In OS dependent code this type serves as a handle to + * an OS independent instance of this interface. + */ +class IOsObserver : + public IDataItemObserver, + public IDataItemSubscription, + public IFrameworkActionReq { + +public: + + // To set the subscription object + virtual void setSubscriptionObj(IDataItemSubscription *subscriptionObj) = 0; + + // To set the framework action request object + virtual void setFrameworkActionReqObj(IFrameworkActionReq *frameworkActionReqObj) = 0; + + // IDataItemObserver Overrides + inline virtual void getName (string & /*name*/) {} + inline virtual void notify (const std::list <IDataItemCore *> & /*dlist*/) {} + + // IDataItemSubscription Overrides + inline virtual void subscribe + ( + const std :: list <DataItemId> & /*l*/, + IDataItemObserver * /*client*/ + ){} + inline virtual void updateSubscription + ( + const std :: list <DataItemId> & /*l*/, + IDataItemObserver * /*client*/ + ){} + inline virtual void requestData + ( + const std :: list <DataItemId> & /*l*/, + IDataItemObserver * /*client*/ + ){} + inline virtual void unsubscribe + ( + const std :: list <DataItemId> & /*l*/, + IDataItemObserver * /*client*/ + ){} + inline virtual void unsubscribeAll (IDataItemObserver * /*client*/){} + + // IFrameworkActionReq Overrides + inline virtual void turnOn (DataItemId /*dit*/, int /*timeOut*/){} + inline virtual void turnOff (DataItemId /*dit*/) {} +#ifdef USE_GLIB + inline virtual bool connectBackhaul(const string& clientName) { return false; } + inline virtual bool disconnectBackhaul(const string& clientName) { return false; } +#endif + + /** + * @brief Destructor + * @details Destructor + */ + virtual ~IOsObserver () {} +}; + +} // namespace loc_core + +#endif // #ifndef __IOSOBSERVER_H__ |