1 /* Copyright (c) 2011-2017, 2020, The Linux Foundation. All rights reserved. 2 * 3 * Redistribution and use in source and binary forms, with or without 4 * modification, are permitted provided that the following conditions are 5 * met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above 9 * copyright notice, this list of conditions and the following 10 * disclaimer in the documentation and/or other materials provided 11 * with the distribution. 12 * * Neither the name of The Linux Foundation, nor the names of its 13 * contributors may be used to endorse or promote products derived 14 * from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 */ 29 #ifndef __LOC_CONTEXT_BASE__ 30 #define __LOC_CONTEXT_BASE__ 31 32 #include <stdbool.h> 33 #include <ctype.h> 34 #include <MsgTask.h> 35 #include <LocApiBase.h> 36 #include <LBSProxyBase.h> 37 #include <loc_cfg.h> 38 #ifdef NO_UNORDERED_SET_OR_MAP 39 #include <map> 40 #else 41 #include <unordered_map> 42 #endif 43 44 /* GPS.conf support */ 45 /* NOTE: the implementaiton of the parser casts number 46 fields to 32 bit. To ensure all 'n' fields working, 47 they must all be 32 bit fields. */ 48 typedef struct loc_gps_cfg_s 49 { 50 uint32_t INTERMEDIATE_POS; 51 uint32_t ACCURACY_THRES; 52 uint32_t SUPL_VER; 53 uint32_t SUPL_MODE; 54 uint32_t SUPL_ES; 55 uint32_t CAPABILITIES; 56 uint32_t LPP_PROFILE; 57 char XTRA_SERVER_1[LOC_MAX_PARAM_STRING]; 58 char XTRA_SERVER_2[LOC_MAX_PARAM_STRING]; 59 char XTRA_SERVER_3[LOC_MAX_PARAM_STRING]; 60 uint32_t USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL; 61 uint32_t NMEA_PROVIDER; 62 char NMEA_REPORT_RATE[LOC_MAX_PARAM_NAME]; 63 GnssConfigGpsLock GPS_LOCK; 64 uint32_t A_GLONASS_POS_PROTOCOL_SELECT; 65 uint32_t AGPS_CERT_WRITABLE_MASK; 66 uint32_t AGPS_CONFIG_INJECT; 67 uint32_t LPPE_CP_TECHNOLOGY; 68 uint32_t LPPE_UP_TECHNOLOGY; 69 uint32_t EXTERNAL_DR_ENABLED; 70 char SUPL_HOST[LOC_MAX_PARAM_STRING]; 71 uint32_t SUPL_PORT; 72 uint32_t MODEM_TYPE; 73 char MO_SUPL_HOST[LOC_MAX_PARAM_STRING]; 74 uint32_t MO_SUPL_PORT; 75 uint32_t CONSTRAINED_TIME_UNCERTAINTY_ENABLED; 76 double CONSTRAINED_TIME_UNCERTAINTY_THRESHOLD; 77 uint32_t CONSTRAINED_TIME_UNCERTAINTY_ENERGY_BUDGET; 78 uint32_t POSITION_ASSISTED_CLOCK_ESTIMATOR_ENABLED; 79 char PROXY_APP_PACKAGE_NAME[LOC_MAX_PARAM_STRING]; 80 uint32_t CP_MTLR_ES; 81 uint32_t GNSS_DEPLOYMENT; 82 uint32_t CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED; 83 uint32_t NI_SUPL_DENY_ON_NFW_LOCKED; 84 uint32_t ENABLE_NMEA_PRINT; 85 uint32_t NMEA_TAG_BLOCK_GROUPING_ENABLED; 86 } loc_gps_cfg_s_type; 87 88 /* NOTE: the implementation of the parser casts number 89 fields to 32 bit. To ensure all 'n' fields working, 90 they must all be 32 bit fields. */ 91 /* Meanwhile, *_valid fields are 8 bit fields, and 'f' 92 fields are double. Rigid as they are, it is the 93 the status quo, until the parsing mechanism is 94 changed, that is. */ 95 typedef struct 96 { 97 uint8_t GYRO_BIAS_RANDOM_WALK_VALID; 98 double GYRO_BIAS_RANDOM_WALK; 99 uint32_t SENSOR_ACCEL_BATCHES_PER_SEC; 100 uint32_t SENSOR_ACCEL_SAMPLES_PER_BATCH; 101 uint32_t SENSOR_GYRO_BATCHES_PER_SEC; 102 uint32_t SENSOR_GYRO_SAMPLES_PER_BATCH; 103 uint32_t SENSOR_ACCEL_BATCHES_PER_SEC_HIGH; 104 uint32_t SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH; 105 uint32_t SENSOR_GYRO_BATCHES_PER_SEC_HIGH; 106 uint32_t SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH; 107 uint32_t SENSOR_CONTROL_MODE; 108 uint32_t SENSOR_ALGORITHM_CONFIG_MASK; 109 uint8_t ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID; 110 double ACCEL_RANDOM_WALK_SPECTRAL_DENSITY; 111 uint8_t ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID; 112 double ANGLE_RANDOM_WALK_SPECTRAL_DENSITY; 113 uint8_t RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID; 114 double RATE_RANDOM_WALK_SPECTRAL_DENSITY; 115 uint8_t VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID; 116 double VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY; 117 } loc_sap_cfg_s_type; 118 119 using namespace loc_util; 120 121 namespace loc_core { 122 123 class LocAdapterBase; 124 125 class ContextBase { 126 static LBSProxyBase* getLBSProxy(const char* libName); 127 LocApiBase* createLocApi(LOC_API_ADAPTER_EVENT_MASK_T excludedMask); 128 static const loc_param_s_type mGps_conf_table[]; 129 static const loc_param_s_type mSap_conf_table[]; 130 protected: 131 const LBSProxyBase* mLBSProxy; 132 const MsgTask* mMsgTask; 133 LocApiBase* mLocApi; 134 LocApiProxyBase *mLocApiProxy; 135 136 public: 137 ContextBase(const MsgTask* msgTask, 138 LOC_API_ADAPTER_EVENT_MASK_T exMask, 139 const char* libName); ~ContextBase()140 inline virtual ~ContextBase() { 141 if (nullptr != mLocApi) { 142 mLocApi->destroy(); 143 mLocApi = nullptr; 144 } 145 if (nullptr != mLBSProxy) { 146 delete mLBSProxy; 147 mLBSProxy = nullptr; 148 } 149 } 150 getMsgTask()151 inline const MsgTask* getMsgTask() { return mMsgTask; } getLocApi()152 inline LocApiBase* getLocApi() { return mLocApi; } getLocApiProxy()153 inline LocApiProxyBase* getLocApiProxy() { return mLocApiProxy; } hasAgpsExtendedCapabilities()154 inline bool hasAgpsExtendedCapabilities() { return mLBSProxy->hasAgpsExtendedCapabilities(); } hasNativeXtraClient()155 inline bool hasNativeXtraClient() { return mLBSProxy->hasNativeXtraClient(); } modemPowerVote(bool power)156 inline void modemPowerVote(bool power) const { return mLBSProxy->modemPowerVote(power); } getIzatDevId()157 inline IzatDevId_t getIzatDevId() const { 158 return mLBSProxy->getIzatDevId(); 159 } sendMsg(const LocMsg * msg)160 inline void sendMsg(const LocMsg *msg) { getMsgTask()->sendMsg(msg); } 161 162 static loc_gps_cfg_s_type mGps_conf; 163 static loc_sap_cfg_s_type mSap_conf; 164 static bool sIsEngineCapabilitiesKnown; 165 static uint64_t sSupportedMsgMask; 166 static uint8_t sFeaturesSupported[MAX_FEATURE_LENGTH]; 167 static bool sGnssMeasurementSupported; 168 static GnssNMEARptRate sNmeaReportRate; 169 static LocationCapabilitiesMask sQwesFeatureMask; 170 171 void readConfig(); 172 static uint32_t getCarrierCapabilities(); 173 void setEngineCapabilities(uint64_t supportedMsgMask, 174 uint8_t *featureList, bool gnssMeasurementSupported); 175 isEngineCapabilitiesKnown()176 static inline bool isEngineCapabilitiesKnown() { 177 return sIsEngineCapabilitiesKnown; 178 } 179 isMessageSupported(LocCheckingMessagesID msgID)180 static inline bool isMessageSupported(LocCheckingMessagesID msgID) { 181 182 // confirm if msgID is not larger than the number of bits in 183 // mSupportedMsg 184 if ((uint64_t)msgID > (sizeof(sSupportedMsgMask) << 3)) { 185 return false; 186 } else { 187 uint32_t messageChecker = 1 << msgID; 188 return (messageChecker & sSupportedMsgMask) == messageChecker; 189 } 190 } 191 192 /* 193 Check if a feature is supported 194 */ 195 static bool isFeatureSupported(uint8_t featureVal); 196 197 /* 198 Check if gnss measurement is supported 199 */ 200 static bool gnssConstellationConfig(); 201 202 /* 203 set QWES feature status info 204 */ setQwesFeatureStatus(const std::unordered_map<LocationQwesFeatureType,bool> & featureMap)205 static inline void setQwesFeatureStatus( 206 const std::unordered_map<LocationQwesFeatureType, bool> &featureMap) { 207 std::unordered_map<LocationQwesFeatureType, bool>::const_iterator itr; 208 static LocationQwesFeatureType locQwesFeatType[LOCATION_QWES_FEATURE_TYPE_MAX]; 209 for (itr = featureMap.begin(); itr != featureMap.end(); ++itr) { 210 LOC_LOGi("Feature : %d isValid: %d", itr->first, itr->second); 211 locQwesFeatType[itr->first] = itr->second; 212 switch (itr->first) { 213 case LOCATION_QWES_FEATURE_TYPE_CARRIER_PHASE: 214 if (itr->second) { 215 sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_CARRIER_PHASE_BIT; 216 } else { 217 sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_CARRIER_PHASE_BIT; 218 } 219 break; 220 case LOCATION_QWES_FEATURE_TYPE_SV_POLYNOMIAL: 221 if (itr->second) { 222 sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_SV_POLYNOMIAL_BIT; 223 } else { 224 sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_SV_POLYNOMIAL_BIT; 225 } 226 break; 227 case LOCATION_QWES_FEATURE_TYPE_GNSS_SINGLE_FREQUENCY: 228 if (itr->second) { 229 sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_GNSS_SINGLE_FREQUENCY; 230 } else { 231 sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_GNSS_SINGLE_FREQUENCY; 232 } 233 break; 234 case LOCATION_QWES_FEATURE_TYPE_SV_EPH: 235 if (itr->second) { 236 sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_SV_EPHEMERIS_BIT; 237 } else { 238 sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_SV_EPHEMERIS_BIT; 239 } 240 break; 241 case LOCATION_QWES_FEATURE_TYPE_GNSS_MULTI_FREQUENCY: 242 if (itr->second) { 243 sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_GNSS_MULTI_FREQUENCY; 244 } else { 245 sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_GNSS_MULTI_FREQUENCY; 246 } 247 break; 248 case LOCATION_QWES_FEATURE_TYPE_PPE: 249 if (itr->second) { 250 sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_PPE; 251 } else { 252 sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_PPE; 253 } 254 break; 255 case LOCATION_QWES_FEATURE_TYPE_QDR2: 256 if (itr->second) { 257 sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_QDR2; 258 } else { 259 sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_QDR2; 260 } 261 break; 262 case LOCATION_QWES_FEATURE_TYPE_QDR3: 263 if (itr->second) { 264 sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_QDR3; 265 } else { 266 sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_QDR3; 267 } 268 break; 269 case LOCATION_QWES_FEATURE_TYPE_VPE: 270 if (itr->second) { 271 sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_VPE; 272 } else { 273 sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_VPE; 274 } 275 break; 276 } 277 } 278 279 // Set CV2X basic when time freq and tunc is set 280 // CV2X_BASIC = LOCATION_QWES_FEATURE_TYPE_TIME_FREQUENCY & 281 // LOCATION_QWES_FEATURE_TYPE_TIME_UNCERTAINTY 282 283 // Set CV2X premium when time freq and tunc is set 284 // CV2X_PREMIUM = CV2X_BASIC & LOCATION_QWES_FEATURE_TYPE_QDR3 & 285 // LOCATION_QWES_FEATURE_TYPE_CLOCK_ESTIMATE 286 287 bool cv2xBasicEnabled = (1 == locQwesFeatType[LOCATION_QWES_FEATURE_TYPE_TIME_FREQUENCY]) && 288 (1 == locQwesFeatType[LOCATION_QWES_FEATURE_TYPE_TIME_UNCERTAINTY]); 289 bool cv2xPremiumEnabled = cv2xBasicEnabled && 290 (1 == locQwesFeatType[LOCATION_QWES_FEATURE_TYPE_QDR3]) && 291 (1 == locQwesFeatType[LOCATION_QWES_FEATURE_TYPE_CLOCK_ESTIMATE]); 292 293 LOC_LOGd("CV2X_BASIC:%d, CV2X_PREMIUM:%d", cv2xBasicEnabled, cv2xPremiumEnabled); 294 if (cv2xBasicEnabled) { 295 sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_BASIC; 296 } else { 297 sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_BASIC; 298 } 299 if (cv2xPremiumEnabled) { 300 sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_PREMIUM; 301 } else { 302 sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_PREMIUM; 303 } 304 } 305 306 /* 307 get QWES feature status info 308 */ getQwesFeatureStatus()309 static inline LocationCapabilitiesMask getQwesFeatureStatus() { 310 return (ContextBase::sQwesFeatureMask); 311 } 312 313 314 }; 315 316 struct LocApiResponse: LocMsg { 317 private: 318 ContextBase& mContext; 319 std::function<void (LocationError err)> mProcImpl; procLocApiResponse320 inline virtual void proc() const { 321 mProcImpl(mLocationError); 322 } 323 protected: 324 LocationError mLocationError; 325 public: LocApiResponseLocApiResponse326 inline LocApiResponse(ContextBase& context, 327 std::function<void (LocationError err)> procImpl ) : 328 mContext(context), mProcImpl(procImpl) {} 329 returnToSenderLocApiResponse330 void returnToSender(const LocationError err) { 331 mLocationError = err; 332 mContext.sendMsg(this); 333 } 334 }; 335 336 struct LocApiCollectiveResponse: LocMsg { 337 private: 338 ContextBase& mContext; 339 std::function<void (std::vector<LocationError> errs)> mProcImpl; procLocApiCollectiveResponse340 inline virtual void proc() const { 341 mProcImpl(mLocationErrors); 342 } 343 protected: 344 std::vector<LocationError> mLocationErrors; 345 public: LocApiCollectiveResponseLocApiCollectiveResponse346 inline LocApiCollectiveResponse(ContextBase& context, 347 std::function<void (std::vector<LocationError> errs)> procImpl ) : 348 mContext(context), mProcImpl(procImpl) {} ~LocApiCollectiveResponseLocApiCollectiveResponse349 inline virtual ~LocApiCollectiveResponse() { 350 } 351 returnToSenderLocApiCollectiveResponse352 void returnToSender(std::vector<LocationError>& errs) { 353 mLocationErrors = errs; 354 mContext.sendMsg(this); 355 } 356 }; 357 358 359 template <typename DATA> 360 struct LocApiResponseData: LocMsg { 361 private: 362 ContextBase& mContext; 363 std::function<void (LocationError err, DATA data)> mProcImpl; procLocApiResponseData364 inline virtual void proc() const { 365 mProcImpl(mLocationError, mData); 366 } 367 protected: 368 LocationError mLocationError; 369 DATA mData; 370 public: LocApiResponseDataLocApiResponseData371 inline LocApiResponseData(ContextBase& context, 372 std::function<void (LocationError err, DATA data)> procImpl ) : 373 mContext(context), mProcImpl(procImpl) {} 374 returnToSenderLocApiResponseData375 void returnToSender(const LocationError err, const DATA data) { 376 mLocationError = err; 377 mData = data; 378 mContext.sendMsg(this); 379 } 380 }; 381 382 383 } // namespace loc_core 384 385 #endif //__LOC_CONTEXT_BASE__ 386