You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
471 lines
18 KiB
471 lines
18 KiB
/* 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 LOCATION_API_CLINET_BASE_H |
|
#define LOCATION_API_CLINET_BASE_H |
|
|
|
#include <stdint.h> |
|
#include <stdlib.h> |
|
#include <pthread.h> |
|
#include <queue> |
|
#include <map> |
|
|
|
#include "LocationAPI.h" |
|
|
|
enum SESSION_MODE { |
|
SESSION_MODE_NONE = 0, |
|
SESSION_MODE_ON_FULL, |
|
SESSION_MODE_ON_FIX, |
|
}; |
|
|
|
enum REQUEST_TYPE { |
|
REQUEST_TRACKING = 0, |
|
REQUEST_BATCHING, |
|
REQUEST_GEOFENCE, |
|
REQUEST_NIRESPONSE, |
|
REQUEST_DELETEAIDINGDATA, |
|
REQUEST_CONTROL, |
|
REQUEST_CONFIG, |
|
REQUEST_MAX, |
|
}; |
|
|
|
class LocationAPIClientBase |
|
{ |
|
public: |
|
LocationAPIClientBase(); |
|
virtual ~LocationAPIClientBase(); |
|
LocationAPIClientBase(const LocationAPIClientBase&) = delete; |
|
LocationAPIClientBase& operator=(const LocationAPIClientBase&) = delete; |
|
|
|
void locAPISetCallbacks(LocationCallbacks& locationCallbacks); |
|
|
|
// LocationAPI |
|
uint32_t locAPIStartTracking(LocationOptions& options); |
|
void locAPIStopTracking(); |
|
void locAPIUpdateTrackingOptions(LocationOptions& options); |
|
|
|
int32_t locAPIGetBatchSize(); |
|
uint32_t locAPIStartSession(uint32_t id, uint32_t sessionMode, |
|
LocationOptions& options); |
|
uint32_t locAPIStopSession(uint32_t id); |
|
uint32_t locAPIUpdateSessionOptions(uint32_t id, uint32_t sessionMode, |
|
LocationOptions& options); |
|
void locAPIGetBatchedLocations(size_t count); |
|
|
|
uint32_t locAPIAddGeofences(size_t count, uint32_t* ids, |
|
GeofenceOption* options, GeofenceInfo* data); |
|
void locAPIRemoveGeofences(size_t count, uint32_t* ids); |
|
void locAPIModifyGeofences(size_t count, uint32_t* ids, GeofenceOption* options); |
|
void locAPIPauseGeofences(size_t count, uint32_t* ids); |
|
void locAPIResumeGeofences(size_t count, uint32_t* ids, GeofenceBreachTypeMask* mask); |
|
void locAPIRemoveAllGeofences(); |
|
|
|
void locAPIGnssNiResponse(uint32_t id, GnssNiResponse response); |
|
uint32_t locAPIGnssDeleteAidingData(GnssAidingData& data); |
|
|
|
uint32_t locAPIEnable(LocationTechnologyType techType); |
|
void locAPIDisable(); |
|
uint32_t locAPIGnssUpdateConfig(GnssConfig config); |
|
|
|
// callbacks |
|
void onResponseCb(LocationError error, uint32_t id); |
|
void onCollectiveResponseCb(size_t count, LocationError* errors, uint32_t* ids); |
|
|
|
void onCtrlResponseCb(LocationError error, uint32_t id); |
|
void onCtrlCollectiveResponseCb(size_t count, LocationError* errors, uint32_t* ids); |
|
|
|
void beforeGeofenceBreachCb(GeofenceBreachNotification geofenceBreachNotification); |
|
|
|
inline virtual void onCapabilitiesCb(LocationCapabilitiesMask /*capabilitiesMask*/) {} |
|
inline virtual void onGnssNmeaCb(GnssNmeaNotification /*gnssNmeaNotification*/) {} |
|
inline virtual void onGnssMeasurementsCb( |
|
GnssMeasurementsNotification /*gnssMeasurementsNotification*/) {} |
|
|
|
inline virtual void onTrackingCb(Location /*location*/) {} |
|
inline virtual void onGnssSvCb(GnssSvNotification /*gnssSvNotification*/) {} |
|
inline virtual void onStartTrackingCb(LocationError /*error*/) {} |
|
inline virtual void onStopTrackingCb(LocationError /*error*/) {} |
|
inline virtual void onUpdateTrackingOptionsCb(LocationError /*error*/) {} |
|
|
|
inline virtual void onGnssLocationInfoCb( |
|
GnssLocationInfoNotification /*gnssLocationInfoNotification*/) {} |
|
|
|
inline virtual void onBatchingCb(size_t /*count*/, Location* /*location*/) {} |
|
inline virtual void onStartBatchingCb(LocationError /*error*/) {} |
|
inline virtual void onStopBatchingCb(LocationError /*error*/) {} |
|
inline virtual void onUpdateBatchingOptionsCb(LocationError /*error*/) {} |
|
inline virtual void onGetBatchedLocationsCb(LocationError /*error*/) {} |
|
|
|
inline virtual void onGeofenceBreachCb( |
|
GeofenceBreachNotification /*geofenceBreachNotification*/) {} |
|
inline virtual void onGeofenceStatusCb( |
|
GeofenceStatusNotification /*geofenceStatusNotification*/) {} |
|
inline virtual void onAddGeofencesCb( |
|
size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {} |
|
inline virtual void onRemoveGeofencesCb( |
|
size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {} |
|
inline virtual void onModifyGeofencesCb( |
|
size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {} |
|
inline virtual void onPauseGeofencesCb( |
|
size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {} |
|
inline virtual void onResumeGeofencesCb( |
|
size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {} |
|
|
|
inline virtual void onGnssNiCb(uint32_t /*id*/, GnssNiNotification /*gnssNiNotification*/) {} |
|
inline virtual void onGnssNiResponseCb(LocationError /*error*/) {} |
|
inline virtual void onGnssDeleteAidingDataCb(LocationError /*error*/) {} |
|
|
|
inline virtual void onEnableCb(LocationError /*error*/) {} |
|
inline virtual void onDisableCb(LocationError /*error*/) {} |
|
inline virtual void onGnssUpdateConfigCb( |
|
size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {} |
|
|
|
private: |
|
// private inner classes |
|
typedef struct { |
|
uint32_t id; |
|
uint32_t trackingSession; |
|
uint32_t batchingSession; |
|
uint32_t sessionMode; |
|
} SessionEntity; |
|
|
|
class BiDict { |
|
public: |
|
BiDict() { |
|
pthread_mutex_init(&mBiDictMutex, nullptr); |
|
} |
|
~BiDict() { |
|
pthread_mutex_destroy(&mBiDictMutex); |
|
} |
|
bool hasId(uint32_t id) { |
|
pthread_mutex_lock(&mBiDictMutex); |
|
bool ret = (mForwardMap.find(id) != mForwardMap.end()); |
|
pthread_mutex_unlock(&mBiDictMutex); |
|
return ret; |
|
} |
|
void set(uint32_t id, uint32_t session, uint32_t type) { |
|
pthread_mutex_lock(&mBiDictMutex); |
|
mForwardMap[id] = session; |
|
mBackwardMap[session] = id; |
|
mTypeMap[session] = type; |
|
pthread_mutex_unlock(&mBiDictMutex); |
|
} |
|
void clear() { |
|
pthread_mutex_lock(&mBiDictMutex); |
|
mForwardMap.clear(); |
|
mBackwardMap.clear(); |
|
mTypeMap.clear(); |
|
pthread_mutex_unlock(&mBiDictMutex); |
|
} |
|
void rmById(uint32_t id) { |
|
pthread_mutex_lock(&mBiDictMutex); |
|
mBackwardMap.erase(mForwardMap[id]); |
|
mTypeMap.erase(mForwardMap[id]); |
|
mForwardMap.erase(id); |
|
pthread_mutex_unlock(&mBiDictMutex); |
|
} |
|
void rmBySession(uint32_t session) { |
|
pthread_mutex_lock(&mBiDictMutex); |
|
mForwardMap.erase(mBackwardMap[session]); |
|
mBackwardMap.erase(session); |
|
mTypeMap.erase(session); |
|
pthread_mutex_unlock(&mBiDictMutex); |
|
} |
|
uint32_t getId(uint32_t session) { |
|
pthread_mutex_lock(&mBiDictMutex); |
|
uint32_t ret = 0; |
|
auto it = mBackwardMap.find(session); |
|
if (it != mBackwardMap.end()) { |
|
ret = it->second; |
|
} |
|
pthread_mutex_unlock(&mBiDictMutex); |
|
return ret; |
|
} |
|
uint32_t getSession(uint32_t id) { |
|
pthread_mutex_lock(&mBiDictMutex); |
|
uint32_t ret = 0; |
|
auto it = mForwardMap.find(id); |
|
if (it != mForwardMap.end()) { |
|
ret = it->second; |
|
} |
|
pthread_mutex_unlock(&mBiDictMutex); |
|
return ret; |
|
} |
|
uint32_t getType(uint32_t session) { |
|
pthread_mutex_lock(&mBiDictMutex); |
|
uint32_t ret = 0; |
|
auto it = mTypeMap.find(session); |
|
if (it != mTypeMap.end()) { |
|
ret = it->second; |
|
} |
|
pthread_mutex_unlock(&mBiDictMutex); |
|
return ret; |
|
} |
|
std::vector<uint32_t> getAllSessions() { |
|
std::vector<uint32_t> ret; |
|
pthread_mutex_lock(&mBiDictMutex); |
|
for (auto it = mBackwardMap.begin(); it != mBackwardMap.end(); it++) { |
|
ret.push_back(it->first); |
|
} |
|
pthread_mutex_unlock(&mBiDictMutex); |
|
return ret; |
|
} |
|
private: |
|
pthread_mutex_t mBiDictMutex; |
|
// mForwarMap mapping id->session |
|
std::map<uint32_t, uint32_t> mForwardMap; |
|
// mBackwardMap mapping session->id |
|
std::map<uint32_t, uint32_t> mBackwardMap; |
|
// mTypeMap mapping session->type |
|
std::map<uint32_t, uint32_t> mTypeMap; |
|
}; |
|
|
|
class LocationAPIRequest { |
|
public: |
|
LocationAPIRequest(LocationAPIClientBase& API) : mAPI(API) {} |
|
virtual ~LocationAPIRequest() {} |
|
virtual void onResponse(LocationError /*error*/) {}; |
|
virtual void onCollectiveResponse( |
|
size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}; |
|
LocationAPIClientBase& mAPI; |
|
}; |
|
|
|
class StartTrackingRequest : public LocationAPIRequest { |
|
public: |
|
StartTrackingRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} |
|
inline void onResponse(LocationError error) { |
|
mAPI.onStartTrackingCb(error); |
|
} |
|
}; |
|
|
|
class StopTrackingRequest : public LocationAPIRequest { |
|
public: |
|
StopTrackingRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} |
|
inline void onResponse(LocationError error) { |
|
mAPI.onStopTrackingCb(error); |
|
} |
|
}; |
|
|
|
class UpdateTrackingOptionsRequest : public LocationAPIRequest { |
|
public: |
|
UpdateTrackingOptionsRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} |
|
inline void onResponse(LocationError error) { |
|
mAPI.onUpdateTrackingOptionsCb(error); |
|
} |
|
}; |
|
|
|
class StartBatchingRequest : public LocationAPIRequest { |
|
public: |
|
StartBatchingRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} |
|
inline void onResponse(LocationError error) { |
|
mAPI.onStartBatchingCb(error); |
|
} |
|
}; |
|
|
|
class StopBatchingRequest : public LocationAPIRequest { |
|
public: |
|
StopBatchingRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} |
|
inline void onResponse(LocationError error) { |
|
mAPI.onStopBatchingCb(error); |
|
} |
|
}; |
|
|
|
class UpdateBatchingOptionsRequest : public LocationAPIRequest { |
|
public: |
|
UpdateBatchingOptionsRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} |
|
inline void onResponse(LocationError error) { |
|
mAPI.onUpdateBatchingOptionsCb(error); |
|
} |
|
}; |
|
|
|
class GetBatchedLocationsRequest : public LocationAPIRequest { |
|
public: |
|
GetBatchedLocationsRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} |
|
inline void onResponse(LocationError error) { |
|
mAPI.onGetBatchedLocationsCb(error); |
|
} |
|
}; |
|
|
|
class AddGeofencesRequest : public LocationAPIRequest { |
|
public: |
|
AddGeofencesRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} |
|
inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) { |
|
uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count); |
|
for (size_t i = 0; i < count; i++) { |
|
ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]); |
|
} |
|
mAPI.onAddGeofencesCb(count, errors, ids); |
|
free(ids); |
|
} |
|
}; |
|
|
|
class RemoveGeofencesRequest : public LocationAPIRequest { |
|
public: |
|
RemoveGeofencesRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} |
|
inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) { |
|
uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count); |
|
for (size_t i = 0; i < count; i++) { |
|
ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]); |
|
mAPI.mGeofenceBiDict.rmBySession(sessions[i]); |
|
} |
|
mAPI.onRemoveGeofencesCb(count, errors, ids); |
|
free(ids); |
|
} |
|
}; |
|
|
|
class ModifyGeofencesRequest : public LocationAPIRequest { |
|
public: |
|
ModifyGeofencesRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} |
|
inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) { |
|
uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count); |
|
for (size_t i = 0; i < count; i++) { |
|
ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]); |
|
} |
|
mAPI.onModifyGeofencesCb(count, errors, ids); |
|
free(ids); |
|
} |
|
}; |
|
|
|
class PauseGeofencesRequest : public LocationAPIRequest { |
|
public: |
|
PauseGeofencesRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} |
|
inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) { |
|
uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count); |
|
for (size_t i = 0; i < count; i++) { |
|
ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]); |
|
} |
|
mAPI.onPauseGeofencesCb(count, errors, ids); |
|
free(ids); |
|
} |
|
}; |
|
|
|
class ResumeGeofencesRequest : public LocationAPIRequest { |
|
public: |
|
ResumeGeofencesRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} |
|
inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) { |
|
uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count); |
|
for (size_t i = 0; i < count; i++) { |
|
ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]); |
|
} |
|
mAPI.onResumeGeofencesCb(count, errors, ids); |
|
free(ids); |
|
} |
|
}; |
|
|
|
class GnssNiResponseRequest : public LocationAPIRequest { |
|
public: |
|
GnssNiResponseRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} |
|
inline void onResponse(LocationError error) { |
|
mAPI.onGnssNiResponseCb(error); |
|
} |
|
}; |
|
|
|
class GnssDeleteAidingDataRequest : public LocationAPIRequest { |
|
public: |
|
GnssDeleteAidingDataRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} |
|
inline void onResponse(LocationError error) { |
|
mAPI.onGnssDeleteAidingDataCb(error); |
|
} |
|
}; |
|
|
|
class EnableRequest : public LocationAPIRequest { |
|
public: |
|
EnableRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} |
|
inline void onResponse(LocationError error) { |
|
mAPI.onEnableCb(error); |
|
} |
|
}; |
|
|
|
class DisableRequest : public LocationAPIRequest { |
|
public: |
|
DisableRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} |
|
inline void onResponse(LocationError error) { |
|
mAPI.onDisableCb(error); |
|
} |
|
}; |
|
|
|
class GnssUpdateConfigRequest : public LocationAPIRequest { |
|
public: |
|
GnssUpdateConfigRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} |
|
inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* ids) { |
|
mAPI.onGnssUpdateConfigCb(count, errors, ids); |
|
} |
|
}; |
|
|
|
class RequestQueue { |
|
public: |
|
RequestQueue(uint32_t session): mSession(session) { |
|
} |
|
~RequestQueue() { |
|
LocationAPIRequest* request = nullptr; |
|
while (!mQueue.empty()) { |
|
request = mQueue.front(); |
|
mQueue.pop(); |
|
delete request; |
|
} |
|
} |
|
void push(LocationAPIRequest* request) { |
|
mQueue.push(request); |
|
} |
|
LocationAPIRequest* pop() { |
|
LocationAPIRequest* request = nullptr; |
|
if (!mQueue.empty()) { |
|
request = mQueue.front(); |
|
mQueue.pop(); |
|
} |
|
return request; |
|
} |
|
uint32_t getSession() { return mSession; } |
|
private: |
|
uint32_t mSession; |
|
std::queue<LocationAPIRequest*> mQueue; |
|
}; |
|
|
|
LocationAPIRequest* getRequestBySession(uint32_t session); |
|
|
|
private: |
|
pthread_mutex_t mMutex; |
|
|
|
trackingCallback mTrackingCallback; |
|
batchingCallback mBatchingCallback; |
|
geofenceBreachCallback mGeofenceBreachCallback; |
|
|
|
LocationAPI* mLocationAPI; |
|
LocationControlAPI* mLocationControlAPI; |
|
|
|
BiDict mGeofenceBiDict; |
|
RequestQueue* mRequestQueues[REQUEST_MAX]; |
|
std::map<uint32_t, SessionEntity> mSessionMap; |
|
int32_t mBatchSize; |
|
bool mEnabled; |
|
bool mTracking; |
|
|
|
GnssConfig mConfig; |
|
}; |
|
|
|
#endif /* LOCATION_API_CLINET_BASE_H */
|
|
|