1 /* Copyright (c) 2017 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 LOCATION_API_CLINET_BASE_H 30 #define LOCATION_API_CLINET_BASE_H 31 32 #include <stdint.h> 33 #include <stdlib.h> 34 #include <pthread.h> 35 #include <queue> 36 #include <map> 37 38 #include "LocationAPI.h" 39 40 enum SESSION_MODE { 41 SESSION_MODE_NONE = 0, 42 SESSION_MODE_ON_FULL, 43 SESSION_MODE_ON_FIX, 44 }; 45 46 enum REQUEST_TYPE { 47 REQUEST_TRACKING = 0, 48 REQUEST_BATCHING, 49 REQUEST_GEOFENCE, 50 REQUEST_NIRESPONSE, 51 REQUEST_DELETEAIDINGDATA, 52 REQUEST_CONTROL, 53 REQUEST_CONFIG, 54 REQUEST_MAX, 55 }; 56 57 class LocationAPIClientBase 58 { 59 public: 60 LocationAPIClientBase(); 61 virtual ~LocationAPIClientBase(); 62 LocationAPIClientBase(const LocationAPIClientBase&) = delete; 63 LocationAPIClientBase& operator=(const LocationAPIClientBase&) = delete; 64 65 void locAPISetCallbacks(LocationCallbacks& locationCallbacks); 66 67 // LocationAPI 68 uint32_t locAPIStartTracking(LocationOptions& options); 69 void locAPIStopTracking(); 70 void locAPIUpdateTrackingOptions(LocationOptions& options); 71 72 int32_t locAPIGetBatchSize(); 73 uint32_t locAPIStartSession(uint32_t id, uint32_t sessionMode, 74 LocationOptions& options); 75 uint32_t locAPIStopSession(uint32_t id); 76 uint32_t locAPIUpdateSessionOptions(uint32_t id, uint32_t sessionMode, 77 LocationOptions& options); 78 void locAPIGetBatchedLocations(size_t count); 79 80 uint32_t locAPIAddGeofences(size_t count, uint32_t* ids, 81 GeofenceOption* options, GeofenceInfo* data); 82 void locAPIRemoveGeofences(size_t count, uint32_t* ids); 83 void locAPIModifyGeofences(size_t count, uint32_t* ids, GeofenceOption* options); 84 void locAPIPauseGeofences(size_t count, uint32_t* ids); 85 void locAPIResumeGeofences(size_t count, uint32_t* ids, GeofenceBreachTypeMask* mask); 86 void locAPIRemoveAllGeofences(); 87 88 void locAPIGnssNiResponse(uint32_t id, GnssNiResponse response); 89 uint32_t locAPIGnssDeleteAidingData(GnssAidingData& data); 90 91 uint32_t locAPIEnable(LocationTechnologyType techType); 92 void locAPIDisable(); 93 uint32_t locAPIGnssUpdateConfig(GnssConfig config); 94 95 // callbacks 96 void onResponseCb(LocationError error, uint32_t id); 97 void onCollectiveResponseCb(size_t count, LocationError* errors, uint32_t* ids); 98 99 void onCtrlResponseCb(LocationError error, uint32_t id); 100 void onCtrlCollectiveResponseCb(size_t count, LocationError* errors, uint32_t* ids); 101 102 void beforeGeofenceBreachCb(GeofenceBreachNotification geofenceBreachNotification); 103 onCapabilitiesCb(LocationCapabilitiesMask)104 inline virtual void onCapabilitiesCb(LocationCapabilitiesMask /*capabilitiesMask*/) {} onGnssNmeaCb(GnssNmeaNotification)105 inline virtual void onGnssNmeaCb(GnssNmeaNotification /*gnssNmeaNotification*/) {} onGnssMeasurementsCb(GnssMeasurementsNotification)106 inline virtual void onGnssMeasurementsCb( 107 GnssMeasurementsNotification /*gnssMeasurementsNotification*/) {} 108 onTrackingCb(Location)109 inline virtual void onTrackingCb(Location /*location*/) {} onGnssSvCb(GnssSvNotification)110 inline virtual void onGnssSvCb(GnssSvNotification /*gnssSvNotification*/) {} onStartTrackingCb(LocationError)111 inline virtual void onStartTrackingCb(LocationError /*error*/) {} onStopTrackingCb(LocationError)112 inline virtual void onStopTrackingCb(LocationError /*error*/) {} onUpdateTrackingOptionsCb(LocationError)113 inline virtual void onUpdateTrackingOptionsCb(LocationError /*error*/) {} 114 onGnssLocationInfoCb(GnssLocationInfoNotification)115 inline virtual void onGnssLocationInfoCb( 116 GnssLocationInfoNotification /*gnssLocationInfoNotification*/) {} 117 onBatchingCb(size_t,Location *)118 inline virtual void onBatchingCb(size_t /*count*/, Location* /*location*/) {} onStartBatchingCb(LocationError)119 inline virtual void onStartBatchingCb(LocationError /*error*/) {} onStopBatchingCb(LocationError)120 inline virtual void onStopBatchingCb(LocationError /*error*/) {} onUpdateBatchingOptionsCb(LocationError)121 inline virtual void onUpdateBatchingOptionsCb(LocationError /*error*/) {} onGetBatchedLocationsCb(LocationError)122 inline virtual void onGetBatchedLocationsCb(LocationError /*error*/) {} 123 onGeofenceBreachCb(GeofenceBreachNotification)124 inline virtual void onGeofenceBreachCb( 125 GeofenceBreachNotification /*geofenceBreachNotification*/) {} onGeofenceStatusCb(GeofenceStatusNotification)126 inline virtual void onGeofenceStatusCb( 127 GeofenceStatusNotification /*geofenceStatusNotification*/) {} onAddGeofencesCb(size_t,LocationError *,uint32_t *)128 inline virtual void onAddGeofencesCb( 129 size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {} onRemoveGeofencesCb(size_t,LocationError *,uint32_t *)130 inline virtual void onRemoveGeofencesCb( 131 size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {} onModifyGeofencesCb(size_t,LocationError *,uint32_t *)132 inline virtual void onModifyGeofencesCb( 133 size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {} onPauseGeofencesCb(size_t,LocationError *,uint32_t *)134 inline virtual void onPauseGeofencesCb( 135 size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {} onResumeGeofencesCb(size_t,LocationError *,uint32_t *)136 inline virtual void onResumeGeofencesCb( 137 size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {} 138 onGnssNiCb(uint32_t,GnssNiNotification)139 inline virtual void onGnssNiCb(uint32_t /*id*/, GnssNiNotification /*gnssNiNotification*/) {} onGnssNiResponseCb(LocationError)140 inline virtual void onGnssNiResponseCb(LocationError /*error*/) {} onGnssDeleteAidingDataCb(LocationError)141 inline virtual void onGnssDeleteAidingDataCb(LocationError /*error*/) {} 142 onEnableCb(LocationError)143 inline virtual void onEnableCb(LocationError /*error*/) {} onDisableCb(LocationError)144 inline virtual void onDisableCb(LocationError /*error*/) {} onGnssUpdateConfigCb(size_t,LocationError *,uint32_t *)145 inline virtual void onGnssUpdateConfigCb( 146 size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {} 147 148 private: 149 // private inner classes 150 typedef struct { 151 uint32_t id; 152 uint32_t trackingSession; 153 uint32_t batchingSession; 154 uint32_t sessionMode; 155 } SessionEntity; 156 157 class BiDict { 158 public: BiDict()159 BiDict() { 160 pthread_mutex_init(&mBiDictMutex, nullptr); 161 } ~BiDict()162 ~BiDict() { 163 pthread_mutex_destroy(&mBiDictMutex); 164 } hasId(uint32_t id)165 bool hasId(uint32_t id) { 166 pthread_mutex_lock(&mBiDictMutex); 167 bool ret = (mForwardMap.find(id) != mForwardMap.end()); 168 pthread_mutex_unlock(&mBiDictMutex); 169 return ret; 170 } set(uint32_t id,uint32_t session,uint32_t type)171 void set(uint32_t id, uint32_t session, uint32_t type) { 172 pthread_mutex_lock(&mBiDictMutex); 173 mForwardMap[id] = session; 174 mBackwardMap[session] = id; 175 mTypeMap[session] = type; 176 pthread_mutex_unlock(&mBiDictMutex); 177 } clear()178 void clear() { 179 pthread_mutex_lock(&mBiDictMutex); 180 mForwardMap.clear(); 181 mBackwardMap.clear(); 182 mTypeMap.clear(); 183 pthread_mutex_unlock(&mBiDictMutex); 184 } rmById(uint32_t id)185 void rmById(uint32_t id) { 186 pthread_mutex_lock(&mBiDictMutex); 187 mBackwardMap.erase(mForwardMap[id]); 188 mTypeMap.erase(mForwardMap[id]); 189 mForwardMap.erase(id); 190 pthread_mutex_unlock(&mBiDictMutex); 191 } rmBySession(uint32_t session)192 void rmBySession(uint32_t session) { 193 pthread_mutex_lock(&mBiDictMutex); 194 mForwardMap.erase(mBackwardMap[session]); 195 mBackwardMap.erase(session); 196 mTypeMap.erase(session); 197 pthread_mutex_unlock(&mBiDictMutex); 198 } getId(uint32_t session)199 uint32_t getId(uint32_t session) { 200 pthread_mutex_lock(&mBiDictMutex); 201 uint32_t ret = 0; 202 auto it = mBackwardMap.find(session); 203 if (it != mBackwardMap.end()) { 204 ret = it->second; 205 } 206 pthread_mutex_unlock(&mBiDictMutex); 207 return ret; 208 } getSession(uint32_t id)209 uint32_t getSession(uint32_t id) { 210 pthread_mutex_lock(&mBiDictMutex); 211 uint32_t ret = 0; 212 auto it = mForwardMap.find(id); 213 if (it != mForwardMap.end()) { 214 ret = it->second; 215 } 216 pthread_mutex_unlock(&mBiDictMutex); 217 return ret; 218 } getType(uint32_t session)219 uint32_t getType(uint32_t session) { 220 pthread_mutex_lock(&mBiDictMutex); 221 uint32_t ret = 0; 222 auto it = mTypeMap.find(session); 223 if (it != mTypeMap.end()) { 224 ret = it->second; 225 } 226 pthread_mutex_unlock(&mBiDictMutex); 227 return ret; 228 } getAllSessions()229 std::vector<uint32_t> getAllSessions() { 230 std::vector<uint32_t> ret; 231 pthread_mutex_lock(&mBiDictMutex); 232 for (auto it = mBackwardMap.begin(); it != mBackwardMap.end(); it++) { 233 ret.push_back(it->first); 234 } 235 pthread_mutex_unlock(&mBiDictMutex); 236 return ret; 237 } 238 private: 239 pthread_mutex_t mBiDictMutex; 240 // mForwarMap mapping id->session 241 std::map<uint32_t, uint32_t> mForwardMap; 242 // mBackwardMap mapping session->id 243 std::map<uint32_t, uint32_t> mBackwardMap; 244 // mTypeMap mapping session->type 245 std::map<uint32_t, uint32_t> mTypeMap; 246 }; 247 248 class LocationAPIRequest { 249 public: LocationAPIRequest(LocationAPIClientBase & API)250 LocationAPIRequest(LocationAPIClientBase& API) : mAPI(API) {} ~LocationAPIRequest()251 virtual ~LocationAPIRequest() {} onResponse(LocationError)252 virtual void onResponse(LocationError /*error*/) {}; onCollectiveResponse(size_t,LocationError *,uint32_t *)253 virtual void onCollectiveResponse( 254 size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}; 255 LocationAPIClientBase& mAPI; 256 }; 257 258 class StartTrackingRequest : public LocationAPIRequest { 259 public: StartTrackingRequest(LocationAPIClientBase & API)260 StartTrackingRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} onResponse(LocationError error)261 inline void onResponse(LocationError error) { 262 mAPI.onStartTrackingCb(error); 263 } 264 }; 265 266 class StopTrackingRequest : public LocationAPIRequest { 267 public: StopTrackingRequest(LocationAPIClientBase & API)268 StopTrackingRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} onResponse(LocationError error)269 inline void onResponse(LocationError error) { 270 mAPI.onStopTrackingCb(error); 271 } 272 }; 273 274 class UpdateTrackingOptionsRequest : public LocationAPIRequest { 275 public: UpdateTrackingOptionsRequest(LocationAPIClientBase & API)276 UpdateTrackingOptionsRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} onResponse(LocationError error)277 inline void onResponse(LocationError error) { 278 mAPI.onUpdateTrackingOptionsCb(error); 279 } 280 }; 281 282 class StartBatchingRequest : public LocationAPIRequest { 283 public: StartBatchingRequest(LocationAPIClientBase & API)284 StartBatchingRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} onResponse(LocationError error)285 inline void onResponse(LocationError error) { 286 mAPI.onStartBatchingCb(error); 287 } 288 }; 289 290 class StopBatchingRequest : public LocationAPIRequest { 291 public: StopBatchingRequest(LocationAPIClientBase & API)292 StopBatchingRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} onResponse(LocationError error)293 inline void onResponse(LocationError error) { 294 mAPI.onStopBatchingCb(error); 295 } 296 }; 297 298 class UpdateBatchingOptionsRequest : public LocationAPIRequest { 299 public: UpdateBatchingOptionsRequest(LocationAPIClientBase & API)300 UpdateBatchingOptionsRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} onResponse(LocationError error)301 inline void onResponse(LocationError error) { 302 mAPI.onUpdateBatchingOptionsCb(error); 303 } 304 }; 305 306 class GetBatchedLocationsRequest : public LocationAPIRequest { 307 public: GetBatchedLocationsRequest(LocationAPIClientBase & API)308 GetBatchedLocationsRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} onResponse(LocationError error)309 inline void onResponse(LocationError error) { 310 mAPI.onGetBatchedLocationsCb(error); 311 } 312 }; 313 314 class AddGeofencesRequest : public LocationAPIRequest { 315 public: AddGeofencesRequest(LocationAPIClientBase & API)316 AddGeofencesRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} onCollectiveResponse(size_t count,LocationError * errors,uint32_t * sessions)317 inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) { 318 uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count); 319 for (size_t i = 0; i < count; i++) { 320 ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]); 321 } 322 mAPI.onAddGeofencesCb(count, errors, ids); 323 free(ids); 324 } 325 }; 326 327 class RemoveGeofencesRequest : public LocationAPIRequest { 328 public: RemoveGeofencesRequest(LocationAPIClientBase & API)329 RemoveGeofencesRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} onCollectiveResponse(size_t count,LocationError * errors,uint32_t * sessions)330 inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) { 331 uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count); 332 for (size_t i = 0; i < count; i++) { 333 ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]); 334 mAPI.mGeofenceBiDict.rmBySession(sessions[i]); 335 } 336 mAPI.onRemoveGeofencesCb(count, errors, ids); 337 free(ids); 338 } 339 }; 340 341 class ModifyGeofencesRequest : public LocationAPIRequest { 342 public: ModifyGeofencesRequest(LocationAPIClientBase & API)343 ModifyGeofencesRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} onCollectiveResponse(size_t count,LocationError * errors,uint32_t * sessions)344 inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) { 345 uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count); 346 for (size_t i = 0; i < count; i++) { 347 ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]); 348 } 349 mAPI.onModifyGeofencesCb(count, errors, ids); 350 free(ids); 351 } 352 }; 353 354 class PauseGeofencesRequest : public LocationAPIRequest { 355 public: PauseGeofencesRequest(LocationAPIClientBase & API)356 PauseGeofencesRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} onCollectiveResponse(size_t count,LocationError * errors,uint32_t * sessions)357 inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) { 358 uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count); 359 for (size_t i = 0; i < count; i++) { 360 ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]); 361 } 362 mAPI.onPauseGeofencesCb(count, errors, ids); 363 free(ids); 364 } 365 }; 366 367 class ResumeGeofencesRequest : public LocationAPIRequest { 368 public: ResumeGeofencesRequest(LocationAPIClientBase & API)369 ResumeGeofencesRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} onCollectiveResponse(size_t count,LocationError * errors,uint32_t * sessions)370 inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) { 371 uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count); 372 for (size_t i = 0; i < count; i++) { 373 ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]); 374 } 375 mAPI.onResumeGeofencesCb(count, errors, ids); 376 free(ids); 377 } 378 }; 379 380 class GnssNiResponseRequest : public LocationAPIRequest { 381 public: GnssNiResponseRequest(LocationAPIClientBase & API)382 GnssNiResponseRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} onResponse(LocationError error)383 inline void onResponse(LocationError error) { 384 mAPI.onGnssNiResponseCb(error); 385 } 386 }; 387 388 class GnssDeleteAidingDataRequest : public LocationAPIRequest { 389 public: GnssDeleteAidingDataRequest(LocationAPIClientBase & API)390 GnssDeleteAidingDataRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} onResponse(LocationError error)391 inline void onResponse(LocationError error) { 392 mAPI.onGnssDeleteAidingDataCb(error); 393 } 394 }; 395 396 class EnableRequest : public LocationAPIRequest { 397 public: EnableRequest(LocationAPIClientBase & API)398 EnableRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} onResponse(LocationError error)399 inline void onResponse(LocationError error) { 400 mAPI.onEnableCb(error); 401 } 402 }; 403 404 class DisableRequest : public LocationAPIRequest { 405 public: DisableRequest(LocationAPIClientBase & API)406 DisableRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} onResponse(LocationError error)407 inline void onResponse(LocationError error) { 408 mAPI.onDisableCb(error); 409 } 410 }; 411 412 class GnssUpdateConfigRequest : public LocationAPIRequest { 413 public: GnssUpdateConfigRequest(LocationAPIClientBase & API)414 GnssUpdateConfigRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} onCollectiveResponse(size_t count,LocationError * errors,uint32_t * ids)415 inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* ids) { 416 mAPI.onGnssUpdateConfigCb(count, errors, ids); 417 } 418 }; 419 420 class RequestQueue { 421 public: RequestQueue(uint32_t session)422 RequestQueue(uint32_t session): mSession(session) { 423 } ~RequestQueue()424 ~RequestQueue() { 425 LocationAPIRequest* request = nullptr; 426 while (!mQueue.empty()) { 427 request = mQueue.front(); 428 mQueue.pop(); 429 delete request; 430 } 431 } push(LocationAPIRequest * request)432 void push(LocationAPIRequest* request) { 433 mQueue.push(request); 434 } pop()435 LocationAPIRequest* pop() { 436 LocationAPIRequest* request = nullptr; 437 if (!mQueue.empty()) { 438 request = mQueue.front(); 439 mQueue.pop(); 440 } 441 return request; 442 } getSession()443 uint32_t getSession() { return mSession; } 444 private: 445 uint32_t mSession; 446 std::queue<LocationAPIRequest*> mQueue; 447 }; 448 449 LocationAPIRequest* getRequestBySession(uint32_t session); 450 451 private: 452 pthread_mutex_t mMutex; 453 454 trackingCallback mTrackingCallback; 455 batchingCallback mBatchingCallback; 456 geofenceBreachCallback mGeofenceBreachCallback; 457 458 LocationAPI* mLocationAPI; 459 LocationControlAPI* mLocationControlAPI; 460 461 BiDict mGeofenceBiDict; 462 RequestQueue* mRequestQueues[REQUEST_MAX]; 463 std::map<uint32_t, SessionEntity> mSessionMap; 464 int32_t mBatchSize; 465 bool mEnabled; 466 bool mTracking; 467 468 GnssConfig mConfig; 469 }; 470 471 #endif /* LOCATION_API_CLINET_BASE_H */ 472