sm8450-common: Import gps from LA.VENDOR.1.0.r1-12800-WAIPIO.0
Change-Id: Ia76265a8c3326f2b5f9f260ce98807276af80ee3
This commit is contained in:
296
gps/android/2.1/location_api/BatchingAPIClient.cpp
Normal file
296
gps/android/2.1/location_api/BatchingAPIClient.cpp
Normal file
@@ -0,0 +1,296 @@
|
||||
/* Copyright (c) 2017-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 LOG_TAG "LocSvc_BatchingAPIClient"
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <log_util.h>
|
||||
#include <loc_cfg.h>
|
||||
#include <thread>
|
||||
#include "LocationUtil.h"
|
||||
#include "BatchingAPIClient.h"
|
||||
|
||||
#include "limits.h"
|
||||
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace gnss {
|
||||
namespace V2_1 {
|
||||
namespace implementation {
|
||||
|
||||
using ::android::hardware::gnss::V2_0::IGnssBatching;
|
||||
using ::android::hardware::gnss::V2_0::IGnssBatchingCallback;
|
||||
using ::android::hardware::gnss::V2_0::GnssLocation;
|
||||
|
||||
static void convertBatchOption(const IGnssBatching::Options& in, LocationOptions& out,
|
||||
LocationCapabilitiesMask mask);
|
||||
|
||||
BatchingAPIClient::BatchingAPIClient(const sp<V1_0::IGnssBatchingCallback>& callback) :
|
||||
LocationAPIClientBase(),
|
||||
mGnssBatchingCbIface(nullptr),
|
||||
mDefaultId(UINT_MAX),
|
||||
mLocationCapabilitiesMask(0),
|
||||
mGnssBatchingCbIface_2_0(nullptr)
|
||||
{
|
||||
LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
|
||||
|
||||
gnssUpdateCallbacks(callback);
|
||||
}
|
||||
|
||||
BatchingAPIClient::BatchingAPIClient(const sp<V2_0::IGnssBatchingCallback>& callback) :
|
||||
LocationAPIClientBase(),
|
||||
mGnssBatchingCbIface(nullptr),
|
||||
mDefaultId(UINT_MAX),
|
||||
mLocationCapabilitiesMask(0),
|
||||
mGnssBatchingCbIface_2_0(nullptr)
|
||||
{
|
||||
LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
|
||||
|
||||
gnssUpdateCallbacks_2_0(callback);
|
||||
}
|
||||
|
||||
BatchingAPIClient::~BatchingAPIClient()
|
||||
{
|
||||
LOC_LOGD("%s]: ()", __FUNCTION__);
|
||||
}
|
||||
|
||||
int BatchingAPIClient::getBatchSize() {
|
||||
int batchSize = locAPIGetBatchSize();
|
||||
LOC_LOGd("batchSize: %d", batchSize);
|
||||
return batchSize;
|
||||
}
|
||||
|
||||
void BatchingAPIClient::setCallbacks()
|
||||
{
|
||||
LocationCallbacks locationCallbacks;
|
||||
memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
|
||||
locationCallbacks.size = sizeof(LocationCallbacks);
|
||||
|
||||
locationCallbacks.trackingCb = nullptr;
|
||||
locationCallbacks.batchingCb = nullptr;
|
||||
locationCallbacks.batchingCb = [this](size_t count, Location* location,
|
||||
BatchingOptions batchOptions) {
|
||||
onBatchingCb(count, location, batchOptions);
|
||||
};
|
||||
locationCallbacks.geofenceBreachCb = nullptr;
|
||||
locationCallbacks.geofenceStatusCb = nullptr;
|
||||
locationCallbacks.gnssLocationInfoCb = nullptr;
|
||||
locationCallbacks.gnssNiCb = nullptr;
|
||||
locationCallbacks.gnssSvCb = nullptr;
|
||||
locationCallbacks.gnssNmeaCb = nullptr;
|
||||
locationCallbacks.gnssMeasurementsCb = nullptr;
|
||||
|
||||
locAPISetCallbacks(locationCallbacks);
|
||||
}
|
||||
|
||||
void BatchingAPIClient::gnssUpdateCallbacks(const sp<V1_0::IGnssBatchingCallback>& callback)
|
||||
{
|
||||
mMutex.lock();
|
||||
bool cbWasNull = (mGnssBatchingCbIface == nullptr);
|
||||
mGnssBatchingCbIface = callback;
|
||||
mGnssBatchingCbIface_2_0 = nullptr;
|
||||
mMutex.unlock();
|
||||
|
||||
if (cbWasNull) {
|
||||
setCallbacks();
|
||||
}
|
||||
}
|
||||
|
||||
void BatchingAPIClient::gnssUpdateCallbacks_2_0(const sp<V2_0::IGnssBatchingCallback>& callback)
|
||||
{
|
||||
mMutex.lock();
|
||||
bool cbWasNull = (mGnssBatchingCbIface_2_0 == nullptr);
|
||||
mGnssBatchingCbIface = nullptr;
|
||||
mGnssBatchingCbIface_2_0 = callback;
|
||||
mMutex.unlock();
|
||||
|
||||
if (cbWasNull) {
|
||||
setCallbacks();
|
||||
}
|
||||
}
|
||||
|
||||
int BatchingAPIClient::startSession(const IGnssBatching::Options& opts) {
|
||||
mMutex.lock();
|
||||
mState = STARTED;
|
||||
mMutex.unlock();
|
||||
LOC_LOGD("%s]: (%lld %d)", __FUNCTION__,
|
||||
static_cast<long long>(opts.periodNanos), static_cast<uint8_t>(opts.flags));
|
||||
int retVal = -1;
|
||||
LocationOptions options;
|
||||
convertBatchOption(opts, options, mLocationCapabilitiesMask);
|
||||
uint32_t mode = 0;
|
||||
if (opts.flags == static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL)) {
|
||||
mode = SESSION_MODE_ON_FULL;
|
||||
}
|
||||
if (locAPIStartSession(mDefaultId, mode, options) == LOCATION_ERROR_SUCCESS) {
|
||||
retVal = 1;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int BatchingAPIClient::updateSessionOptions(const IGnssBatching::Options& opts)
|
||||
{
|
||||
LOC_LOGD("%s]: (%lld %d)", __FUNCTION__,
|
||||
static_cast<long long>(opts.periodNanos), static_cast<uint8_t>(opts.flags));
|
||||
int retVal = -1;
|
||||
LocationOptions options;
|
||||
convertBatchOption(opts, options, mLocationCapabilitiesMask);
|
||||
|
||||
uint32_t mode = 0;
|
||||
if (opts.flags == static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL)) {
|
||||
mode = SESSION_MODE_ON_FULL;
|
||||
}
|
||||
if (locAPIUpdateSessionOptions(mDefaultId, mode, options) == LOCATION_ERROR_SUCCESS) {
|
||||
retVal = 1;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int BatchingAPIClient::stopSession() {
|
||||
mMutex.lock();
|
||||
mState = STOPPING;
|
||||
mMutex.unlock();
|
||||
LOC_LOGD("%s]: ", __FUNCTION__);
|
||||
int retVal = -1;
|
||||
locAPIGetBatchedLocations(mDefaultId, SIZE_MAX);
|
||||
if (locAPIStopSession(mDefaultId) == LOCATION_ERROR_SUCCESS) {
|
||||
retVal = 1;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void BatchingAPIClient::getBatchedLocation(int last_n_locations)
|
||||
{
|
||||
LOC_LOGD("%s]: (%d)", __FUNCTION__, last_n_locations);
|
||||
locAPIGetBatchedLocations(mDefaultId, last_n_locations);
|
||||
}
|
||||
|
||||
void BatchingAPIClient::flushBatchedLocations() {
|
||||
LOC_LOGD("%s]: ()", __FUNCTION__);
|
||||
uint32_t retVal = locAPIGetBatchedLocations(mDefaultId, SIZE_MAX);
|
||||
// when flush a stopped session or one doesn't exist, just report an empty batch.
|
||||
if (LOCATION_ERROR_ID_UNKNOWN == retVal) {
|
||||
BatchingOptions opt = {};
|
||||
::std::thread thd(&BatchingAPIClient::onBatchingCb, this, 0, nullptr, opt);
|
||||
thd.detach();
|
||||
}
|
||||
}
|
||||
|
||||
void BatchingAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
|
||||
{
|
||||
LOC_LOGD("%s]: (%" PRIu64 ")", __FUNCTION__, capabilitiesMask);
|
||||
mLocationCapabilitiesMask = capabilitiesMask;
|
||||
}
|
||||
|
||||
void BatchingAPIClient::onBatchingCb(size_t count, Location* location,
|
||||
BatchingOptions /*batchOptions*/) {
|
||||
bool processReport = false;
|
||||
LOC_LOGd("(count: %zu)", count);
|
||||
mMutex.lock();
|
||||
// back to back stop() and flush() could bring twice onBatchingCb(). Each one might come first.
|
||||
// Combine them both (the first goes to cache, the second in location*) before report to FW
|
||||
switch (mState) {
|
||||
case STOPPING:
|
||||
mState = STOPPED;
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
mBatchedLocationInCache.push_back(location[i]);
|
||||
}
|
||||
break;
|
||||
case STARTED:
|
||||
case STOPPED: // flush() always trigger report, even on a stopped session
|
||||
processReport = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// report location batch when in STARTED state or flush(), combined with cache in last stop()
|
||||
if (processReport) {
|
||||
auto gnssBatchingCbIface(mGnssBatchingCbIface);
|
||||
auto gnssBatchingCbIface_2_0(mGnssBatchingCbIface_2_0);
|
||||
size_t batchCacheCnt = mBatchedLocationInCache.size();
|
||||
LOC_LOGd("(batchCacheCnt: %zu)", batchCacheCnt);
|
||||
if (gnssBatchingCbIface_2_0 != nullptr) {
|
||||
hidl_vec<V2_0::GnssLocation> locationVec;
|
||||
if (count+batchCacheCnt > 0) {
|
||||
locationVec.resize(count+batchCacheCnt);
|
||||
for (size_t i = 0; i < batchCacheCnt; ++i) {
|
||||
convertGnssLocation(mBatchedLocationInCache[i], locationVec[i]);
|
||||
}
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
convertGnssLocation(location[i], locationVec[i+batchCacheCnt]);
|
||||
}
|
||||
}
|
||||
auto r = gnssBatchingCbIface_2_0->gnssLocationBatchCb(locationVec);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssLocationBatchCb 2_0 description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
} else if (gnssBatchingCbIface != nullptr) {
|
||||
hidl_vec<V1_0::GnssLocation> locationVec;
|
||||
if (count+batchCacheCnt > 0) {
|
||||
locationVec.resize(count+batchCacheCnt);
|
||||
for (size_t i = 0; i < batchCacheCnt; ++i) {
|
||||
convertGnssLocation(mBatchedLocationInCache[i], locationVec[i]);
|
||||
}
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
convertGnssLocation(location[i], locationVec[i+batchCacheCnt]);
|
||||
}
|
||||
}
|
||||
auto r = gnssBatchingCbIface->gnssLocationBatchCb(locationVec);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssLocationBatchCb 1.0 description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
}
|
||||
mBatchedLocationInCache.clear();
|
||||
}
|
||||
mMutex.unlock();
|
||||
}
|
||||
|
||||
static void convertBatchOption(const IGnssBatching::Options& in, LocationOptions& out,
|
||||
LocationCapabilitiesMask mask)
|
||||
{
|
||||
memset(&out, 0, sizeof(LocationOptions));
|
||||
out.size = sizeof(LocationOptions);
|
||||
out.minInterval = (uint32_t)(in.periodNanos / 1000000L);
|
||||
out.minDistance = 0;
|
||||
out.mode = GNSS_SUPL_MODE_STANDALONE;
|
||||
if (mask & LOCATION_CAPABILITIES_GNSS_MSA_BIT)
|
||||
out.mode = GNSS_SUPL_MODE_MSA;
|
||||
if (mask & LOCATION_CAPABILITIES_GNSS_MSB_BIT)
|
||||
out.mode = GNSS_SUPL_MODE_MSB;
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_1
|
||||
} // namespace gnss
|
||||
} // namespace hardware
|
||||
} // namespace android
|
88
gps/android/2.1/location_api/BatchingAPIClient.h
Executable file
88
gps/android/2.1/location_api/BatchingAPIClient.h
Executable file
@@ -0,0 +1,88 @@
|
||||
/* 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 BATCHING_API_CLINET_H
|
||||
#define BATCHING_API_CLINET_H
|
||||
|
||||
#include <mutex>
|
||||
#include <android/hardware/gnss/2.0/IGnssBatching.h>
|
||||
#include <android/hardware/gnss/2.0/IGnssBatchingCallback.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <LocationAPIClientBase.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace gnss {
|
||||
namespace V2_1 {
|
||||
namespace implementation {
|
||||
|
||||
|
||||
enum BATCHING_STATE { STARTED, STOPPING, STOPPED };
|
||||
|
||||
class BatchingAPIClient : public LocationAPIClientBase
|
||||
{
|
||||
public:
|
||||
BatchingAPIClient(const sp<V1_0::IGnssBatchingCallback>& callback);
|
||||
BatchingAPIClient(const sp<V2_0::IGnssBatchingCallback>& callback);
|
||||
void gnssUpdateCallbacks(const sp<V1_0::IGnssBatchingCallback>& callback);
|
||||
void gnssUpdateCallbacks_2_0(const sp<V2_0::IGnssBatchingCallback>& callback);
|
||||
int getBatchSize();
|
||||
int startSession(const V1_0::IGnssBatching::Options& options);
|
||||
int updateSessionOptions(const V1_0::IGnssBatching::Options& options);
|
||||
int stopSession();
|
||||
void getBatchedLocation(int last_n_locations);
|
||||
void flushBatchedLocations();
|
||||
|
||||
inline LocationCapabilitiesMask getCapabilities() { return mLocationCapabilitiesMask; }
|
||||
|
||||
// callbacks
|
||||
void onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) final;
|
||||
void onBatchingCb(size_t count, Location* location, BatchingOptions batchOptions) final;
|
||||
|
||||
private:
|
||||
~BatchingAPIClient();
|
||||
|
||||
void setCallbacks();
|
||||
std::mutex mMutex;
|
||||
sp<V1_0::IGnssBatchingCallback> mGnssBatchingCbIface;
|
||||
uint32_t mDefaultId;
|
||||
LocationCapabilitiesMask mLocationCapabilitiesMask;
|
||||
sp<V2_0::IGnssBatchingCallback> mGnssBatchingCbIface_2_0;
|
||||
volatile BATCHING_STATE mState = STOPPED;
|
||||
|
||||
std::vector<Location> mBatchedLocationInCache;
|
||||
};
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_1
|
||||
} // namespace gnss
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
#endif // BATCHING_API_CLINET_H
|
333
gps/android/2.1/location_api/GeofenceAPIClient.cpp
Executable file
333
gps/android/2.1/location_api/GeofenceAPIClient.cpp
Executable file
@@ -0,0 +1,333 @@
|
||||
/* 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.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
Changes from Qualcomm Innovation Center are provided under the following license:
|
||||
|
||||
Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted (subject to the limitations in the
|
||||
disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
|
||||
GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
|
||||
HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER 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_GeofenceApiClient"
|
||||
|
||||
#include <log_util.h>
|
||||
#include <loc_cfg.h>
|
||||
|
||||
#include "LocationUtil.h"
|
||||
#include "GeofenceAPIClient.h"
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace gnss {
|
||||
namespace V2_1 {
|
||||
namespace implementation {
|
||||
|
||||
using ::android::hardware::gnss::V1_0::IGnssGeofenceCallback;
|
||||
using ::android::hardware::gnss::V1_0::GnssLocation;
|
||||
|
||||
GeofenceAPIClient::GeofenceAPIClient(const sp<IGnssGeofenceCallback>& callback) :
|
||||
LocationAPIClientBase(),
|
||||
mGnssGeofencingCbIface(callback)
|
||||
{
|
||||
LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
|
||||
|
||||
LocationCallbacks locationCallbacks;
|
||||
memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
|
||||
locationCallbacks.size = sizeof(LocationCallbacks);
|
||||
|
||||
locationCallbacks.trackingCb = nullptr;
|
||||
locationCallbacks.batchingCb = nullptr;
|
||||
|
||||
locationCallbacks.geofenceBreachCb = nullptr;
|
||||
locationCallbacks.geofenceBreachCb =
|
||||
[this](GeofenceBreachNotification geofenceBreachNotification) {
|
||||
onGeofenceBreachCb(geofenceBreachNotification);
|
||||
};
|
||||
|
||||
locationCallbacks.geofenceStatusCb =
|
||||
[this](GeofenceStatusNotification geofenceStatusNotification) {
|
||||
onGeofenceStatusCb(geofenceStatusNotification);
|
||||
};
|
||||
|
||||
locationCallbacks.gnssLocationInfoCb = nullptr;
|
||||
locationCallbacks.gnssNiCb = nullptr;
|
||||
locationCallbacks.gnssSvCb = nullptr;
|
||||
locationCallbacks.gnssNmeaCb = nullptr;
|
||||
locationCallbacks.gnssMeasurementsCb = nullptr;
|
||||
|
||||
locAPISetCallbacks(locationCallbacks);
|
||||
}
|
||||
|
||||
void GeofenceAPIClient::upcateCallback(const sp<IGnssGeofenceCallback>& callback) {
|
||||
mMutex.lock();
|
||||
mGnssGeofencingCbIface = callback;
|
||||
mMutex.unlock();
|
||||
}
|
||||
|
||||
void GeofenceAPIClient::geofenceAdd(uint32_t geofence_id, double latitude, double longitude,
|
||||
double radius_meters, int32_t last_transition, int32_t monitor_transitions,
|
||||
uint32_t notification_responsiveness_ms, uint32_t unknown_timer_ms)
|
||||
{
|
||||
LOC_LOGD("%s]: (%d %f %f %f %d %d %d %d)", __FUNCTION__,
|
||||
geofence_id, latitude, longitude, radius_meters,
|
||||
last_transition, monitor_transitions, notification_responsiveness_ms, unknown_timer_ms);
|
||||
|
||||
GeofenceOption options;
|
||||
memset(&options, 0, sizeof(GeofenceOption));
|
||||
options.size = sizeof(GeofenceOption);
|
||||
if (monitor_transitions & IGnssGeofenceCallback::GeofenceTransition::ENTERED)
|
||||
options.breachTypeMask |= GEOFENCE_BREACH_ENTER_BIT;
|
||||
if (monitor_transitions & IGnssGeofenceCallback::GeofenceTransition::EXITED)
|
||||
options.breachTypeMask |= GEOFENCE_BREACH_EXIT_BIT;
|
||||
options.responsiveness = notification_responsiveness_ms;
|
||||
options.confidence = GEOFENCE_CONFIDENCE_HIGH;
|
||||
|
||||
GeofenceInfo data;
|
||||
data.size = sizeof(GeofenceInfo);
|
||||
data.latitude = latitude;
|
||||
data.longitude = longitude;
|
||||
data.radius = radius_meters;
|
||||
|
||||
LocationError err = (LocationError)locAPIAddGeofences(1, &geofence_id, &options, &data);
|
||||
if (LOCATION_ERROR_SUCCESS != err) {
|
||||
onAddGeofencesCb(1, &err, &geofence_id);
|
||||
}
|
||||
}
|
||||
|
||||
void GeofenceAPIClient::geofencePause(uint32_t geofence_id)
|
||||
{
|
||||
LOC_LOGD("%s]: (%d)", __FUNCTION__, geofence_id);
|
||||
locAPIPauseGeofences(1, &geofence_id);
|
||||
}
|
||||
|
||||
void GeofenceAPIClient::geofenceResume(uint32_t geofence_id, int32_t monitor_transitions)
|
||||
{
|
||||
LOC_LOGD("%s]: (%d %d)", __FUNCTION__, geofence_id, monitor_transitions);
|
||||
GeofenceBreachTypeMask mask = 0;
|
||||
if (monitor_transitions & IGnssGeofenceCallback::GeofenceTransition::ENTERED)
|
||||
mask |= GEOFENCE_BREACH_ENTER_BIT;
|
||||
if (monitor_transitions & IGnssGeofenceCallback::GeofenceTransition::EXITED)
|
||||
mask |= GEOFENCE_BREACH_EXIT_BIT;
|
||||
locAPIResumeGeofences(1, &geofence_id, &mask);
|
||||
}
|
||||
|
||||
void GeofenceAPIClient::geofenceRemove(uint32_t geofence_id)
|
||||
{
|
||||
LOC_LOGD("%s]: (%d)", __FUNCTION__, geofence_id);
|
||||
locAPIRemoveGeofences(1, &geofence_id);
|
||||
}
|
||||
|
||||
void GeofenceAPIClient::geofenceRemoveAll()
|
||||
{
|
||||
LOC_LOGD("%s]", __FUNCTION__);
|
||||
locAPIRemoveAllGeofences();
|
||||
}
|
||||
|
||||
// callbacks
|
||||
void GeofenceAPIClient::onGeofenceBreachCb(GeofenceBreachNotification geofenceBreachNotification)
|
||||
{
|
||||
LOC_LOGD("%s]: (%d)", __FUNCTION__, geofenceBreachNotification.count);
|
||||
mMutex.lock();
|
||||
auto cbIface = mGnssGeofencingCbIface;
|
||||
mMutex.unlock();
|
||||
if (cbIface != nullptr) {
|
||||
for (size_t i = 0; i < geofenceBreachNotification.count; i++) {
|
||||
GnssLocation gnssLocation;
|
||||
convertGnssLocation(geofenceBreachNotification.location, gnssLocation);
|
||||
|
||||
IGnssGeofenceCallback::GeofenceTransition transition;
|
||||
if (geofenceBreachNotification.type == GEOFENCE_BREACH_ENTER)
|
||||
transition = IGnssGeofenceCallback::GeofenceTransition::ENTERED;
|
||||
else if (geofenceBreachNotification.type == GEOFENCE_BREACH_EXIT)
|
||||
transition = IGnssGeofenceCallback::GeofenceTransition::EXITED;
|
||||
else {
|
||||
// continue with other breach if transition is
|
||||
// nether GPS_GEOFENCE_ENTERED nor GPS_GEOFENCE_EXITED
|
||||
continue;
|
||||
}
|
||||
|
||||
auto r = cbIface->gnssGeofenceTransitionCb(
|
||||
geofenceBreachNotification.ids[i], gnssLocation, transition,
|
||||
static_cast<V1_0::GnssUtcTime>(geofenceBreachNotification.timestamp));
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssGeofenceTransitionCb description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GeofenceAPIClient::onGeofenceStatusCb(GeofenceStatusNotification geofenceStatusNotification)
|
||||
{
|
||||
LOC_LOGD("%s]: (%d)", __FUNCTION__, geofenceStatusNotification.available);
|
||||
mMutex.lock();
|
||||
auto cbIface = mGnssGeofencingCbIface;
|
||||
mMutex.unlock();
|
||||
if (cbIface != nullptr) {
|
||||
IGnssGeofenceCallback::GeofenceAvailability status =
|
||||
IGnssGeofenceCallback::GeofenceAvailability::UNAVAILABLE;
|
||||
if (geofenceStatusNotification.available == GEOFENCE_STATUS_AVAILABILE_YES) {
|
||||
status = IGnssGeofenceCallback::GeofenceAvailability::AVAILABLE;
|
||||
}
|
||||
GnssLocation gnssLocation;
|
||||
memset(&gnssLocation, 0, sizeof(GnssLocation));
|
||||
auto r = cbIface->gnssGeofenceStatusCb(status, gnssLocation);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssGeofenceStatusCb description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GeofenceAPIClient::onAddGeofencesCb(size_t count, LocationError* errors, uint32_t* ids)
|
||||
{
|
||||
LOC_LOGD("%s]: (%zu)", __FUNCTION__, count);
|
||||
mMutex.lock();
|
||||
auto cbIface = mGnssGeofencingCbIface;
|
||||
mMutex.unlock();
|
||||
if (cbIface != nullptr) {
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
IGnssGeofenceCallback::GeofenceStatus status =
|
||||
IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC;
|
||||
if (errors[i] == LOCATION_ERROR_SUCCESS)
|
||||
status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS;
|
||||
else if (errors[i] == LOCATION_ERROR_ID_EXISTS)
|
||||
status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_EXISTS;
|
||||
auto r = cbIface->gnssGeofenceAddCb(ids[i], status);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssGeofenceAddCb description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GeofenceAPIClient::onRemoveGeofencesCb(size_t count, LocationError* errors, uint32_t* ids)
|
||||
{
|
||||
LOC_LOGD("%s]: (%zu)", __FUNCTION__, count);
|
||||
mMutex.lock();
|
||||
auto cbIface = mGnssGeofencingCbIface;
|
||||
mMutex.unlock();
|
||||
if (cbIface != nullptr) {
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
IGnssGeofenceCallback::GeofenceStatus status =
|
||||
IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC;
|
||||
if (errors[i] == LOCATION_ERROR_SUCCESS)
|
||||
status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS;
|
||||
else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN)
|
||||
status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN;
|
||||
auto r = cbIface->gnssGeofenceRemoveCb(ids[i], status);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssGeofenceRemoveCb description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GeofenceAPIClient::onPauseGeofencesCb(size_t count, LocationError* errors, uint32_t* ids)
|
||||
{
|
||||
LOC_LOGD("%s]: (%zu)", __FUNCTION__, count);
|
||||
mMutex.lock();
|
||||
auto cbIface = mGnssGeofencingCbIface;
|
||||
mMutex.unlock();
|
||||
if (cbIface != nullptr) {
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
IGnssGeofenceCallback::GeofenceStatus status =
|
||||
IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC;
|
||||
if (errors[i] == LOCATION_ERROR_SUCCESS)
|
||||
status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS;
|
||||
else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN)
|
||||
status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN;
|
||||
auto r = cbIface->gnssGeofencePauseCb(ids[i], status);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssGeofencePauseCb description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GeofenceAPIClient::onResumeGeofencesCb(size_t count, LocationError* errors, uint32_t* ids)
|
||||
{
|
||||
LOC_LOGD("%s]: (%zu)", __FUNCTION__, count);
|
||||
mMutex.lock();
|
||||
auto cbIface = mGnssGeofencingCbIface;
|
||||
mMutex.unlock();
|
||||
if (cbIface != nullptr) {
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
IGnssGeofenceCallback::GeofenceStatus status =
|
||||
IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC;
|
||||
if (errors[i] == LOCATION_ERROR_SUCCESS)
|
||||
status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS;
|
||||
else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN)
|
||||
status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN;
|
||||
auto r = cbIface->gnssGeofenceResumeCb(ids[i], status);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssGeofenceResumeCb description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_1
|
||||
} // namespace gnss
|
||||
} // namespace hardware
|
||||
} // namespace android
|
77
gps/android/2.1/location_api/GeofenceAPIClient.h
Executable file
77
gps/android/2.1/location_api/GeofenceAPIClient.h
Executable file
@@ -0,0 +1,77 @@
|
||||
/* 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 GEOFENCE_API_CLINET_H
|
||||
#define GEOFENCE_API_CLINET_H
|
||||
|
||||
#include <mutex>
|
||||
#include <android/hardware/gnss/1.0/IGnssGeofenceCallback.h>
|
||||
#include <LocationAPIClientBase.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace gnss {
|
||||
namespace V2_1 {
|
||||
namespace implementation {
|
||||
|
||||
using ::android::sp;
|
||||
|
||||
class GeofenceAPIClient : public LocationAPIClientBase
|
||||
{
|
||||
public:
|
||||
GeofenceAPIClient(const sp<V1_0::IGnssGeofenceCallback>& callback);
|
||||
void upcateCallback(const sp<V1_0::IGnssGeofenceCallback>& callback);
|
||||
void geofenceAdd(uint32_t geofence_id, double latitude, double longitude,
|
||||
double radius_meters, int32_t last_transition, int32_t monitor_transitions,
|
||||
uint32_t notification_responsiveness_ms, uint32_t unknown_timer_ms);
|
||||
void geofencePause(uint32_t geofence_id);
|
||||
void geofenceResume(uint32_t geofence_id, int32_t monitor_transitions);
|
||||
void geofenceRemove(uint32_t geofence_id);
|
||||
void geofenceRemoveAll();
|
||||
|
||||
// callbacks
|
||||
void onGeofenceBreachCb(GeofenceBreachNotification geofenceBreachNotification) final;
|
||||
void onGeofenceStatusCb(GeofenceStatusNotification geofenceStatusNotification) final;
|
||||
void onAddGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) final;
|
||||
void onRemoveGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) final;
|
||||
void onPauseGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) final;
|
||||
void onResumeGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) final;
|
||||
|
||||
private:
|
||||
virtual ~GeofenceAPIClient() = default;
|
||||
std::mutex mMutex;
|
||||
sp<V1_0::IGnssGeofenceCallback> mGnssGeofencingCbIface;
|
||||
};
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_1
|
||||
} // namespace gnss
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
#endif // GEOFENCE_API_CLINET_H
|
920
gps/android/2.1/location_api/GnssAPIClient.cpp
Normal file
920
gps/android/2.1/location_api/GnssAPIClient.cpp
Normal file
@@ -0,0 +1,920 @@
|
||||
/* 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_NDEBUG 0
|
||||
#define LOG_TAG "LocSvc_GnssAPIClient"
|
||||
#define SINGLE_SHOT_MIN_TRACKING_INTERVAL_MSEC (590 * 60 * 60 * 1000) // 590 hours
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <log_util.h>
|
||||
#include <loc_cfg.h>
|
||||
|
||||
#include "LocationUtil.h"
|
||||
#include "GnssAPIClient.h"
|
||||
#include <LocContext.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace gnss {
|
||||
namespace V2_1 {
|
||||
namespace implementation {
|
||||
|
||||
using ::android::hardware::gnss::V2_1::IGnss;
|
||||
using ::android::hardware::gnss::V2_1::IGnssCallback;
|
||||
using ::android::hardware::gnss::V1_0::IGnssNiCallback;
|
||||
using ::android::hardware::gnss::V2_0::GnssLocation;
|
||||
|
||||
static void convertGnssSvStatus(GnssSvNotification& in, V1_0::IGnssCallback::GnssSvStatus& out);
|
||||
static void convertGnssSvStatus(GnssSvNotification& in,
|
||||
hidl_vec<V2_0::IGnssCallback::GnssSvInfo>& out);
|
||||
static void convertGnssSvStatus(GnssSvNotification& in,
|
||||
hidl_vec<V2_1::IGnssCallback::GnssSvInfo>& out);
|
||||
|
||||
GnssAPIClient::GnssAPIClient(const sp<V1_0::IGnssCallback>& gpsCb,
|
||||
const sp<V1_0::IGnssNiCallback>& niCb) :
|
||||
LocationAPIClientBase(),
|
||||
mGnssCbIface(nullptr),
|
||||
mGnssNiCbIface(nullptr),
|
||||
mControlClient(new LocationAPIControlClient()),
|
||||
mLocationCapabilitiesMask(0),
|
||||
mLocationCapabilitiesCached(false),
|
||||
mTracking(false),
|
||||
mGnssCbIface_2_0(nullptr)
|
||||
{
|
||||
LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb);
|
||||
|
||||
initLocationOptions();
|
||||
gnssUpdateCallbacks(gpsCb, niCb);
|
||||
}
|
||||
|
||||
GnssAPIClient::GnssAPIClient(const sp<V2_0::IGnssCallback>& gpsCb) :
|
||||
LocationAPIClientBase(),
|
||||
mGnssCbIface(nullptr),
|
||||
mGnssNiCbIface(nullptr),
|
||||
mControlClient(new LocationAPIControlClient()),
|
||||
mLocationCapabilitiesMask(0),
|
||||
mLocationCapabilitiesCached(false),
|
||||
mTracking(false),
|
||||
mGnssCbIface_2_0(nullptr)
|
||||
{
|
||||
LOC_LOGD("%s]: (%p)", __FUNCTION__, &gpsCb);
|
||||
|
||||
initLocationOptions();
|
||||
gnssUpdateCallbacks_2_0(gpsCb);
|
||||
}
|
||||
|
||||
GnssAPIClient::GnssAPIClient(const sp<V2_1::IGnssCallback>& gpsCb) :
|
||||
LocationAPIClientBase(),
|
||||
mGnssCbIface(nullptr),
|
||||
mGnssNiCbIface(nullptr),
|
||||
mControlClient(new LocationAPIControlClient()),
|
||||
mLocationCapabilitiesMask(0),
|
||||
mLocationCapabilitiesCached(false),
|
||||
mTracking(false),
|
||||
mGnssCbIface_2_1(nullptr)
|
||||
{
|
||||
LOC_LOGD("%s]: (%p)", __FUNCTION__, &gpsCb);
|
||||
|
||||
initLocationOptions();
|
||||
gnssUpdateCallbacks_2_1(gpsCb);
|
||||
}
|
||||
|
||||
GnssAPIClient::~GnssAPIClient()
|
||||
{
|
||||
LOC_LOGD("%s]: ()", __FUNCTION__);
|
||||
if (mControlClient) {
|
||||
delete mControlClient;
|
||||
mControlClient = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void GnssAPIClient::initLocationOptions()
|
||||
{
|
||||
// set default LocationOptions.
|
||||
memset(&mTrackingOptions, 0, sizeof(TrackingOptions));
|
||||
mTrackingOptions.size = sizeof(TrackingOptions);
|
||||
mTrackingOptions.minInterval = 1000;
|
||||
mTrackingOptions.minDistance = 0;
|
||||
mTrackingOptions.mode = GNSS_SUPL_MODE_STANDALONE;
|
||||
}
|
||||
|
||||
void GnssAPIClient::setCallbacks()
|
||||
{
|
||||
LocationCallbacks locationCallbacks;
|
||||
memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
|
||||
locationCallbacks.size = sizeof(LocationCallbacks);
|
||||
|
||||
static bool readConfig = false;
|
||||
// if ANDROID_REPORT_SPE_ONLY is not set in the izat.conf,
|
||||
// the default behavior is "report SPE PVT to Android GNSS API"
|
||||
static uint32_t reportSpeOnly = 1;
|
||||
static loc_param_s_type izatConfParamTable[] = {
|
||||
{"ANDROID_REPORT_SPE_ONLY", &reportSpeOnly, nullptr, 'n'},
|
||||
};
|
||||
|
||||
if (false == readConfig) {
|
||||
UTIL_READ_CONF(LOC_PATH_IZAT_CONF, izatConfParamTable);
|
||||
readConfig = true;
|
||||
}
|
||||
|
||||
/*-------------------|------------- PVT received --------------------|
|
||||
| Technology used | By trackingCb | By engineLocationInfoCallback|
|
||||
|-------------------|-------------------|------------------------------|
|
||||
|Modem PE only | SPE | SPE |
|
||||
|-------------------|-------------------|---------------------------- |
|
||||
|Modem + HLOS Boeing| Aggregated | SPE and Aggregated |
|
||||
|----------------------------------------------------------------------|
|
||||
* By default always register with engineLocationsInfoCb, drop
|
||||
* aggreated PVTs(if received), so this call back only report SPE no
|
||||
* matter what the techonolgy is used;
|
||||
* When config is set to 0, register with trackingCb, this is the call back
|
||||
* which will report aggregated PVT to Android GNSS API*/
|
||||
if (0 == reportSpeOnly) {
|
||||
locationCallbacks.trackingCb = nullptr;
|
||||
locationCallbacks.trackingCb = [this](Location location) {
|
||||
onTrackingCb(location);
|
||||
};
|
||||
} else {
|
||||
locationCallbacks.engineLocationsInfoCb = nullptr;
|
||||
locationCallbacks.engineLocationsInfoCb = [this](uint32_t count,
|
||||
GnssLocationInfoNotification* engineLocationInfoNotification) {
|
||||
onEngineLocationsInfoCb(count, engineLocationInfoNotification);
|
||||
};
|
||||
}
|
||||
|
||||
locationCallbacks.batchingCb = nullptr;
|
||||
locationCallbacks.geofenceBreachCb = nullptr;
|
||||
locationCallbacks.geofenceStatusCb = nullptr;
|
||||
locationCallbacks.gnssLocationInfoCb = nullptr;
|
||||
locationCallbacks.gnssNiCb = nullptr;
|
||||
if (mGnssNiCbIface != nullptr) {
|
||||
loc_core::ContextBase* context =
|
||||
loc_core::LocContext::getLocContext(loc_core::LocContext::mLocationHalName);
|
||||
if (!context->hasAgpsExtendedCapabilities()) {
|
||||
LOC_LOGD("Registering NI CB");
|
||||
locationCallbacks.gnssNiCb = [this](uint32_t id, GnssNiNotification gnssNiNotify) {
|
||||
onGnssNiCb(id, gnssNiNotify);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
locationCallbacks.gnssSvCb = nullptr;
|
||||
locationCallbacks.gnssSvCb = [this](GnssSvNotification gnssSvNotification) {
|
||||
onGnssSvCb(gnssSvNotification);
|
||||
};
|
||||
|
||||
locationCallbacks.gnssNmeaCb = nullptr;
|
||||
locationCallbacks.gnssNmeaCb = [this](GnssNmeaNotification gnssNmeaNotification) {
|
||||
onGnssNmeaCb(gnssNmeaNotification);
|
||||
};
|
||||
|
||||
locationCallbacks.gnssMeasurementsCb = nullptr;
|
||||
|
||||
locAPISetCallbacks(locationCallbacks);
|
||||
}
|
||||
|
||||
// for GpsInterface
|
||||
void GnssAPIClient::gnssUpdateCallbacks(const sp<V1_0::IGnssCallback>& gpsCb,
|
||||
const sp<IGnssNiCallback>& niCb)
|
||||
{
|
||||
LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb);
|
||||
|
||||
mMutex.lock();
|
||||
mGnssCbIface = gpsCb;
|
||||
mGnssNiCbIface = niCb;
|
||||
mMutex.unlock();
|
||||
|
||||
if (mGnssCbIface != nullptr || mGnssNiCbIface != nullptr) {
|
||||
setCallbacks();
|
||||
}
|
||||
}
|
||||
|
||||
void GnssAPIClient::gnssUpdateCallbacks_2_0(const sp<V2_0::IGnssCallback>& gpsCb)
|
||||
{
|
||||
LOC_LOGD("%s]: (%p)", __FUNCTION__, &gpsCb);
|
||||
|
||||
mMutex.lock();
|
||||
mGnssCbIface_2_0 = gpsCb;
|
||||
mMutex.unlock();
|
||||
|
||||
if (mGnssCbIface_2_0 != nullptr) {
|
||||
setCallbacks();
|
||||
}
|
||||
}
|
||||
|
||||
void GnssAPIClient::gnssUpdateCallbacks_2_1(const sp<V2_1::IGnssCallback>& gpsCb)
|
||||
{
|
||||
LOC_LOGD("%s]: (%p)", __FUNCTION__, &gpsCb);
|
||||
|
||||
mMutex.lock();
|
||||
mGnssCbIface_2_1 = gpsCb;
|
||||
mMutex.unlock();
|
||||
|
||||
if (mGnssCbIface_2_1 != nullptr) {
|
||||
setCallbacks();
|
||||
}
|
||||
}
|
||||
|
||||
bool GnssAPIClient::gnssStart()
|
||||
{
|
||||
LOC_LOGD("%s]: ()", __FUNCTION__);
|
||||
|
||||
mMutex.lock();
|
||||
mTracking = true;
|
||||
mMutex.unlock();
|
||||
|
||||
bool retVal = true;
|
||||
locAPIStartTracking(mTrackingOptions);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
bool GnssAPIClient::gnssStop()
|
||||
{
|
||||
LOC_LOGD("%s]: ()", __FUNCTION__);
|
||||
|
||||
mMutex.lock();
|
||||
mTracking = false;
|
||||
mMutex.unlock();
|
||||
|
||||
bool retVal = true;
|
||||
locAPIStopTracking();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
bool GnssAPIClient::gnssSetPositionMode(IGnss::GnssPositionMode mode,
|
||||
IGnss::GnssPositionRecurrence recurrence, uint32_t minIntervalMs,
|
||||
uint32_t preferredAccuracyMeters, uint32_t preferredTimeMs,
|
||||
GnssPowerMode powerMode, uint32_t timeBetweenMeasurement)
|
||||
{
|
||||
LOC_LOGD("%s]: (%d %d %d %d %d %d %d)", __FUNCTION__,
|
||||
(int)mode, recurrence, minIntervalMs, preferredAccuracyMeters,
|
||||
preferredTimeMs, (int)powerMode, timeBetweenMeasurement);
|
||||
bool retVal = true;
|
||||
memset(&mTrackingOptions, 0, sizeof(TrackingOptions));
|
||||
mTrackingOptions.size = sizeof(TrackingOptions);
|
||||
mTrackingOptions.minInterval = minIntervalMs;
|
||||
if (IGnss::GnssPositionMode::MS_ASSISTED == mode ||
|
||||
IGnss::GnssPositionRecurrence::RECURRENCE_SINGLE == recurrence) {
|
||||
// We set a very large interval to simulate SINGLE mode. Once we report a fix,
|
||||
// the caller should take the responsibility to stop the session.
|
||||
// For MSA, we always treat it as SINGLE mode.
|
||||
mTrackingOptions.minInterval = SINGLE_SHOT_MIN_TRACKING_INTERVAL_MSEC;
|
||||
}
|
||||
if (mode == IGnss::GnssPositionMode::STANDALONE)
|
||||
mTrackingOptions.mode = GNSS_SUPL_MODE_STANDALONE;
|
||||
else if (mode == IGnss::GnssPositionMode::MS_BASED)
|
||||
mTrackingOptions.mode = GNSS_SUPL_MODE_MSB;
|
||||
else if (mode == IGnss::GnssPositionMode::MS_ASSISTED)
|
||||
mTrackingOptions.mode = GNSS_SUPL_MODE_MSA;
|
||||
else {
|
||||
LOC_LOGD("%s]: invalid GnssPositionMode: %d", __FUNCTION__, (int)mode);
|
||||
retVal = false;
|
||||
}
|
||||
if (GNSS_POWER_MODE_INVALID != powerMode) {
|
||||
mTrackingOptions.powerMode = powerMode;
|
||||
mTrackingOptions.tbm = timeBetweenMeasurement;
|
||||
}
|
||||
locAPIUpdateTrackingOptions(mTrackingOptions);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
// for GpsNiInterface
|
||||
void GnssAPIClient::gnssNiRespond(int32_t notifId,
|
||||
IGnssNiCallback::GnssUserResponseType userResponse)
|
||||
{
|
||||
LOC_LOGD("%s]: (%d %d)", __FUNCTION__, notifId, static_cast<int>(userResponse));
|
||||
GnssNiResponse data;
|
||||
switch (userResponse) {
|
||||
case IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT:
|
||||
data = GNSS_NI_RESPONSE_ACCEPT;
|
||||
break;
|
||||
case IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY:
|
||||
data = GNSS_NI_RESPONSE_DENY;
|
||||
break;
|
||||
case IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP:
|
||||
data = GNSS_NI_RESPONSE_NO_RESPONSE;
|
||||
break;
|
||||
default:
|
||||
data = GNSS_NI_RESPONSE_IGNORE;
|
||||
break;
|
||||
}
|
||||
|
||||
locAPIGnssNiResponse(notifId, data);
|
||||
}
|
||||
|
||||
// these apis using LocationAPIControlClient
|
||||
void GnssAPIClient::gnssDeleteAidingData(IGnss::GnssAidingData aidingDataFlags)
|
||||
{
|
||||
LOC_LOGD("%s]: (%02hx)", __FUNCTION__, aidingDataFlags);
|
||||
if (mControlClient == nullptr) {
|
||||
return;
|
||||
}
|
||||
GnssAidingData data;
|
||||
memset(&data, 0, sizeof (GnssAidingData));
|
||||
data.sv.svTypeMask = GNSS_AIDING_DATA_SV_TYPE_GPS_BIT |
|
||||
GNSS_AIDING_DATA_SV_TYPE_GLONASS_BIT |
|
||||
GNSS_AIDING_DATA_SV_TYPE_QZSS_BIT |
|
||||
GNSS_AIDING_DATA_SV_TYPE_BEIDOU_BIT |
|
||||
GNSS_AIDING_DATA_SV_TYPE_GALILEO_BIT |
|
||||
GNSS_AIDING_DATA_SV_TYPE_NAVIC_BIT;
|
||||
data.posEngineMask = STANDARD_POSITIONING_ENGINE;
|
||||
|
||||
if (aidingDataFlags == IGnss::GnssAidingData::DELETE_ALL)
|
||||
data.deleteAll = true;
|
||||
else {
|
||||
if (aidingDataFlags & IGnss::GnssAidingData::DELETE_EPHEMERIS)
|
||||
data.sv.svMask |= GNSS_AIDING_DATA_SV_EPHEMERIS_BIT;
|
||||
if (aidingDataFlags & IGnss::GnssAidingData::DELETE_ALMANAC)
|
||||
data.sv.svMask |= GNSS_AIDING_DATA_SV_ALMANAC_BIT;
|
||||
if (aidingDataFlags & IGnss::GnssAidingData::DELETE_POSITION)
|
||||
data.common.mask |= GNSS_AIDING_DATA_COMMON_POSITION_BIT;
|
||||
if (aidingDataFlags & IGnss::GnssAidingData::DELETE_TIME)
|
||||
data.common.mask |= GNSS_AIDING_DATA_COMMON_TIME_BIT;
|
||||
if (aidingDataFlags & IGnss::GnssAidingData::DELETE_IONO)
|
||||
data.sv.svMask |= GNSS_AIDING_DATA_SV_IONOSPHERE_BIT;
|
||||
if (aidingDataFlags & IGnss::GnssAidingData::DELETE_UTC)
|
||||
data.common.mask |= GNSS_AIDING_DATA_COMMON_UTC_BIT;
|
||||
if (aidingDataFlags & IGnss::GnssAidingData::DELETE_HEALTH)
|
||||
data.sv.svMask |= GNSS_AIDING_DATA_SV_HEALTH_BIT;
|
||||
if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SVDIR)
|
||||
data.sv.svMask |= GNSS_AIDING_DATA_SV_DIRECTION_BIT;
|
||||
if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SVSTEER)
|
||||
data.sv.svMask |= GNSS_AIDING_DATA_SV_STEER_BIT;
|
||||
if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SADATA)
|
||||
data.sv.svMask |= GNSS_AIDING_DATA_SV_SA_DATA_BIT;
|
||||
if (aidingDataFlags & IGnss::GnssAidingData::DELETE_RTI)
|
||||
data.common.mask |= GNSS_AIDING_DATA_COMMON_RTI_BIT;
|
||||
if (aidingDataFlags & IGnss::GnssAidingData::DELETE_CELLDB_INFO)
|
||||
data.common.mask |= GNSS_AIDING_DATA_COMMON_CELLDB_BIT;
|
||||
}
|
||||
mControlClient->locAPIGnssDeleteAidingData(data);
|
||||
}
|
||||
|
||||
void GnssAPIClient::gnssEnable(LocationTechnologyType techType)
|
||||
{
|
||||
LOC_LOGD("%s]: (%0d)", __FUNCTION__, techType);
|
||||
if (mControlClient == nullptr) {
|
||||
return;
|
||||
}
|
||||
mControlClient->locAPIEnable(techType);
|
||||
}
|
||||
|
||||
void GnssAPIClient::gnssDisable()
|
||||
{
|
||||
LOC_LOGD("%s]: ()", __FUNCTION__);
|
||||
if (mControlClient == nullptr) {
|
||||
return;
|
||||
}
|
||||
mControlClient->locAPIDisable();
|
||||
}
|
||||
|
||||
void GnssAPIClient::gnssConfigurationUpdate(const GnssConfig& gnssConfig)
|
||||
{
|
||||
LOC_LOGD("%s]: (%02x)", __FUNCTION__, gnssConfig.flags);
|
||||
if (mControlClient == nullptr) {
|
||||
return;
|
||||
}
|
||||
mControlClient->locAPIGnssUpdateConfig(gnssConfig);
|
||||
}
|
||||
|
||||
void GnssAPIClient::requestCapabilities() {
|
||||
// only send capablities if it's already cached, otherwise the first time LocationAPI
|
||||
// is initialized, capabilities will be sent by LocationAPI
|
||||
if (mLocationCapabilitiesCached) {
|
||||
onCapabilitiesCb(mLocationCapabilitiesMask);
|
||||
}
|
||||
}
|
||||
|
||||
// callbacks
|
||||
void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
|
||||
{
|
||||
LOC_LOGD("%s]: (%" PRIu64 ")", __FUNCTION__, capabilitiesMask);
|
||||
mLocationCapabilitiesMask = capabilitiesMask;
|
||||
mLocationCapabilitiesCached = true;
|
||||
|
||||
mMutex.lock();
|
||||
auto gnssCbIface(mGnssCbIface);
|
||||
auto gnssCbIface_2_0(mGnssCbIface_2_0);
|
||||
auto gnssCbIface_2_1(mGnssCbIface_2_1);
|
||||
mMutex.unlock();
|
||||
|
||||
if (gnssCbIface_2_1 != nullptr ||gnssCbIface_2_0 != nullptr || gnssCbIface != nullptr) {
|
||||
|
||||
uint32_t antennaInfoVectorSize = 0;
|
||||
uint32_t data = 0;
|
||||
loc_param_s_type ant_info_vector_table[] =
|
||||
{
|
||||
{ "ANTENNA_INFO_VECTOR_SIZE", &antennaInfoVectorSize, NULL, 'n' }
|
||||
};
|
||||
UTIL_READ_CONF(LOC_PATH_ANT_CORR, ant_info_vector_table);
|
||||
|
||||
if (0 != antennaInfoVectorSize) {
|
||||
data |= V2_1::IGnssCallback::Capabilities::ANTENNA_INFO;
|
||||
}
|
||||
|
||||
if ((capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT) ||
|
||||
(capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT) ||
|
||||
(capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT) ||
|
||||
(capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT))
|
||||
data |= IGnssCallback::Capabilities::SCHEDULING;
|
||||
if (capabilitiesMask & LOCATION_CAPABILITIES_GEOFENCE_BIT)
|
||||
data |= V1_0::IGnssCallback::Capabilities::GEOFENCING;
|
||||
if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT)
|
||||
data |= V1_0::IGnssCallback::Capabilities::MEASUREMENTS;
|
||||
if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSB_BIT)
|
||||
data |= IGnssCallback::Capabilities::MSB;
|
||||
if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSA_BIT)
|
||||
data |= IGnssCallback::Capabilities::MSA;
|
||||
if (capabilitiesMask & LOCATION_CAPABILITIES_AGPM_BIT)
|
||||
data |= IGnssCallback::Capabilities::LOW_POWER_MODE;
|
||||
if (capabilitiesMask & LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT)
|
||||
data |= IGnssCallback::Capabilities::SATELLITE_BLACKLIST;
|
||||
if (capabilitiesMask & LOCATION_CAPABILITIES_MEASUREMENTS_CORRECTION_BIT)
|
||||
data |= V2_0::IGnssCallback::Capabilities::MEASUREMENT_CORRECTIONS;
|
||||
|
||||
IGnssCallback::GnssSystemInfo gnssInfo = { .yearOfHw = 2015 };
|
||||
|
||||
if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT) {
|
||||
gnssInfo.yearOfHw++; // 2016
|
||||
if (capabilitiesMask & LOCATION_CAPABILITIES_DEBUG_NMEA_BIT) {
|
||||
gnssInfo.yearOfHw++; // 2017
|
||||
if (capabilitiesMask & LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT ||
|
||||
capabilitiesMask & LOCATION_CAPABILITIES_AGPM_BIT) {
|
||||
gnssInfo.yearOfHw++; // 2018
|
||||
if (capabilitiesMask & LOCATION_CAPABILITIES_PRIVACY_BIT) {
|
||||
gnssInfo.yearOfHw++; // 2019
|
||||
if (capabilitiesMask & LOCATION_CAPABILITIES_MEASUREMENTS_CORRECTION_BIT) {
|
||||
gnssInfo.yearOfHw++; // 2020
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
LOC_LOGV("%s:%d] set_system_info_cb (%d)", __FUNCTION__, __LINE__, gnssInfo.yearOfHw);
|
||||
|
||||
if (gnssCbIface_2_1 != nullptr) {
|
||||
auto r = gnssCbIface_2_1->gnssSetCapabilitiesCb_2_1(data);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssSetCapabilitiesCb_2_1 description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
r = gnssCbIface_2_1->gnssSetSystemInfoCb(gnssInfo);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssSetSystemInfoCb description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
} else if (gnssCbIface_2_0 != nullptr) {
|
||||
auto r = gnssCbIface_2_0->gnssSetCapabilitiesCb_2_0(data);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssSetCapabilitiesCb_2_0 description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
r = gnssCbIface_2_0->gnssSetSystemInfoCb(gnssInfo);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssSetSystemInfoCb description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
} else if (gnssCbIface != nullptr) {
|
||||
auto r = gnssCbIface->gnssSetCapabilitesCb(data);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssSetCapabilitesCb description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
r = gnssCbIface->gnssSetSystemInfoCb(gnssInfo);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssSetSystemInfoCb description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void GnssAPIClient::onTrackingCb(Location location)
|
||||
{
|
||||
mMutex.lock();
|
||||
auto gnssCbIface(mGnssCbIface);
|
||||
auto gnssCbIface_2_0(mGnssCbIface_2_0);
|
||||
auto gnssCbIface_2_1(mGnssCbIface_2_1);
|
||||
bool isTracking = mTracking;
|
||||
mMutex.unlock();
|
||||
|
||||
LOC_LOGD("%s]: (flags: %02x isTracking: %d)", __FUNCTION__, location.flags, isTracking);
|
||||
|
||||
if (!isTracking) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (gnssCbIface_2_1 != nullptr) {
|
||||
V2_0::GnssLocation gnssLocation;
|
||||
convertGnssLocation(location, gnssLocation);
|
||||
auto r = gnssCbIface_2_1->gnssLocationCb_2_0(gnssLocation);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssLocationCb_2_0 description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
} else if (gnssCbIface_2_0 != nullptr) {
|
||||
V2_0::GnssLocation gnssLocation;
|
||||
convertGnssLocation(location, gnssLocation);
|
||||
auto r = gnssCbIface_2_0->gnssLocationCb_2_0(gnssLocation);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssLocationCb_2_0 description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
} else if (gnssCbIface != nullptr) {
|
||||
V1_0::GnssLocation gnssLocation;
|
||||
convertGnssLocation(location, gnssLocation);
|
||||
auto r = gnssCbIface->gnssLocationCb(gnssLocation);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssLocationCb description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
} else {
|
||||
LOC_LOGW("%s] No GNSS Interface ready for gnssLocationCb ", __FUNCTION__);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void GnssAPIClient::onGnssNiCb(uint32_t id, GnssNiNotification gnssNiNotification)
|
||||
{
|
||||
LOC_LOGD("%s]: (id: %d)", __FUNCTION__, id);
|
||||
mMutex.lock();
|
||||
auto gnssNiCbIface(mGnssNiCbIface);
|
||||
mMutex.unlock();
|
||||
|
||||
if (gnssNiCbIface == nullptr) {
|
||||
LOC_LOGE("%s]: mGnssNiCbIface is nullptr", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
IGnssNiCallback::GnssNiNotification notificationGnss = {};
|
||||
|
||||
notificationGnss.notificationId = id;
|
||||
|
||||
if (gnssNiNotification.type == GNSS_NI_TYPE_VOICE)
|
||||
notificationGnss.niType = IGnssNiCallback::GnssNiType::VOICE;
|
||||
else if (gnssNiNotification.type == GNSS_NI_TYPE_SUPL)
|
||||
notificationGnss.niType = IGnssNiCallback::GnssNiType::UMTS_SUPL;
|
||||
else if (gnssNiNotification.type == GNSS_NI_TYPE_CONTROL_PLANE)
|
||||
notificationGnss.niType = IGnssNiCallback::GnssNiType::UMTS_CTRL_PLANE;
|
||||
else if (gnssNiNotification.type == GNSS_NI_TYPE_EMERGENCY_SUPL)
|
||||
notificationGnss.niType = IGnssNiCallback::GnssNiType::EMERGENCY_SUPL;
|
||||
|
||||
if (gnssNiNotification.options & GNSS_NI_OPTIONS_NOTIFICATION_BIT)
|
||||
notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::NEED_NOTIFY;
|
||||
if (gnssNiNotification.options & GNSS_NI_OPTIONS_VERIFICATION_BIT)
|
||||
notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::NEED_VERIFY;
|
||||
if (gnssNiNotification.options & GNSS_NI_OPTIONS_PRIVACY_OVERRIDE_BIT)
|
||||
notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::PRIVACY_OVERRIDE;
|
||||
|
||||
notificationGnss.timeoutSec = gnssNiNotification.timeout;
|
||||
|
||||
if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_ACCEPT)
|
||||
notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT;
|
||||
else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_DENY)
|
||||
notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY;
|
||||
else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_NO_RESPONSE ||
|
||||
gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_IGNORE)
|
||||
notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP;
|
||||
|
||||
notificationGnss.requestorId = gnssNiNotification.requestor;
|
||||
|
||||
notificationGnss.notificationMessage = gnssNiNotification.message;
|
||||
|
||||
if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_NONE)
|
||||
notificationGnss.requestorIdEncoding =
|
||||
IGnssNiCallback::GnssNiEncodingType::ENC_NONE;
|
||||
else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT)
|
||||
notificationGnss.requestorIdEncoding =
|
||||
IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_GSM_DEFAULT;
|
||||
else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UTF8)
|
||||
notificationGnss.requestorIdEncoding =
|
||||
IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UTF8;
|
||||
else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UCS2)
|
||||
notificationGnss.requestorIdEncoding =
|
||||
IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2;
|
||||
|
||||
if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_NONE)
|
||||
notificationGnss.notificationIdEncoding =
|
||||
IGnssNiCallback::GnssNiEncodingType::ENC_NONE;
|
||||
else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT)
|
||||
notificationGnss.notificationIdEncoding =
|
||||
IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_GSM_DEFAULT;
|
||||
else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UTF8)
|
||||
notificationGnss.notificationIdEncoding =
|
||||
IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UTF8;
|
||||
else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UCS2)
|
||||
notificationGnss.notificationIdEncoding =
|
||||
IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2;
|
||||
|
||||
gnssNiCbIface->niNotifyCb(notificationGnss);
|
||||
}
|
||||
|
||||
void GnssAPIClient::onGnssSvCb(GnssSvNotification gnssSvNotification)
|
||||
{
|
||||
LOC_LOGD("%s]: (count: %u)", __FUNCTION__, gnssSvNotification.count);
|
||||
mMutex.lock();
|
||||
auto gnssCbIface(mGnssCbIface);
|
||||
auto gnssCbIface_2_0(mGnssCbIface_2_0);
|
||||
auto gnssCbIface_2_1(mGnssCbIface_2_1);
|
||||
mMutex.unlock();
|
||||
|
||||
if (gnssCbIface_2_1 != nullptr) {
|
||||
hidl_vec<V2_1::IGnssCallback::GnssSvInfo> svInfoList;
|
||||
convertGnssSvStatus(gnssSvNotification, svInfoList);
|
||||
auto r = gnssCbIface_2_1->gnssSvStatusCb_2_1(svInfoList);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssSvStatusCb_2_1 description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
} else if (gnssCbIface_2_0 != nullptr) {
|
||||
hidl_vec<V2_0::IGnssCallback::GnssSvInfo> svInfoList;
|
||||
convertGnssSvStatus(gnssSvNotification, svInfoList);
|
||||
auto r = gnssCbIface_2_0->gnssSvStatusCb_2_0(svInfoList);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssSvStatusCb_2_0 description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
} else if (gnssCbIface != nullptr) {
|
||||
V1_0::IGnssCallback::GnssSvStatus svStatus;
|
||||
convertGnssSvStatus(gnssSvNotification, svStatus);
|
||||
auto r = gnssCbIface->gnssSvStatusCb(svStatus);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssSvStatusCb description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GnssAPIClient::onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification)
|
||||
{
|
||||
mMutex.lock();
|
||||
auto gnssCbIface(mGnssCbIface);
|
||||
auto gnssCbIface_2_0(mGnssCbIface_2_0);
|
||||
auto gnssCbIface_2_1(mGnssCbIface_2_1);
|
||||
mMutex.unlock();
|
||||
|
||||
if (gnssCbIface != nullptr || gnssCbIface_2_0 != nullptr| gnssCbIface_2_1 != nullptr) {
|
||||
const std::string s(gnssNmeaNotification.nmea);
|
||||
std::stringstream ss(s);
|
||||
std::string each;
|
||||
while(std::getline(ss, each, '\n')) {
|
||||
each += '\n';
|
||||
android::hardware::hidl_string nmeaString;
|
||||
nmeaString.setToExternal(each.c_str(), each.length());
|
||||
if (gnssCbIface_2_1 != nullptr) {
|
||||
auto r = gnssCbIface_2_1->gnssNmeaCb(
|
||||
static_cast<V1_0::GnssUtcTime>(gnssNmeaNotification.timestamp), nmeaString);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssCbIface_2_1 nmea=%s length=%u description=%s",
|
||||
__func__, gnssNmeaNotification.nmea, gnssNmeaNotification.length,
|
||||
r.description().c_str());
|
||||
}
|
||||
} else if (gnssCbIface_2_0 != nullptr) {
|
||||
auto r = gnssCbIface_2_0->gnssNmeaCb(
|
||||
static_cast<V1_0::GnssUtcTime>(gnssNmeaNotification.timestamp), nmeaString);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssCbIface_2_0 nmea=%s length=%u description=%s",
|
||||
__func__, gnssNmeaNotification.nmea, gnssNmeaNotification.length,
|
||||
r.description().c_str());
|
||||
}
|
||||
} else if (gnssCbIface != nullptr) {
|
||||
auto r = gnssCbIface->gnssNmeaCb(
|
||||
static_cast<V1_0::GnssUtcTime>(gnssNmeaNotification.timestamp), nmeaString);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssNmeaCb nmea=%s length=%u description=%s",
|
||||
__func__, gnssNmeaNotification.nmea, gnssNmeaNotification.length,
|
||||
r.description().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GnssAPIClient::onEngineLocationsInfoCb(uint32_t count,
|
||||
GnssLocationInfoNotification* engineLocationInfoNotification) {
|
||||
if (nullptr == engineLocationInfoNotification) {
|
||||
LOC_LOGe("engineLocationInfoNotification is nullptr");
|
||||
return;
|
||||
}
|
||||
GnssLocationInfoNotification* locPtr = nullptr;
|
||||
bool foundSPE = false;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
locPtr = engineLocationInfoNotification + i;
|
||||
if (nullptr == locPtr) return;
|
||||
LOC_LOGv("count %d, type %d", i, locPtr->locOutputEngType);
|
||||
if (LOC_OUTPUT_ENGINE_SPE == locPtr->locOutputEngType) {
|
||||
foundSPE = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (foundSPE) {
|
||||
onTrackingCb(locPtr->location);
|
||||
}
|
||||
}
|
||||
|
||||
void GnssAPIClient::onStartTrackingCb(LocationError error)
|
||||
{
|
||||
LOC_LOGD("%s]: (%d)", __FUNCTION__, error);
|
||||
mMutex.lock();
|
||||
auto gnssCbIface(mGnssCbIface);
|
||||
auto gnssCbIface_2_0(mGnssCbIface_2_0);
|
||||
auto gnssCbIface_2_1(mGnssCbIface_2_1);
|
||||
mMutex.unlock();
|
||||
|
||||
if (error == LOCATION_ERROR_SUCCESS) {
|
||||
if (gnssCbIface_2_1 != nullptr) {
|
||||
auto r = gnssCbIface_2_1->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssStatusCb 2_0 ENGINE_ON description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
r = gnssCbIface_2_1->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssStatusCb 2_0 SESSION_BEGIN description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
} else if (gnssCbIface_2_0 != nullptr) {
|
||||
auto r = gnssCbIface_2_0->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssStatusCb 2_0 ENGINE_ON description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
r = gnssCbIface_2_0->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssStatusCb 2_0 SESSION_BEGIN description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
} else if (gnssCbIface != nullptr) {
|
||||
auto r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssStatusCb ENGINE_ON description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssStatusCb SESSION_BEGIN description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GnssAPIClient::onStopTrackingCb(LocationError error)
|
||||
{
|
||||
LOC_LOGD("%s]: (%d)", __FUNCTION__, error);
|
||||
mMutex.lock();
|
||||
auto gnssCbIface(mGnssCbIface);
|
||||
auto gnssCbIface_2_0(mGnssCbIface_2_0);
|
||||
auto gnssCbIface_2_1(mGnssCbIface_2_1);
|
||||
mMutex.unlock();
|
||||
|
||||
if (error == LOCATION_ERROR_SUCCESS) {
|
||||
if (gnssCbIface_2_1 != nullptr) {
|
||||
auto r = gnssCbIface_2_1->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssStatusCb 2_0 SESSION_END description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
r = gnssCbIface_2_1->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_OFF);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssStatusCb 2_0 ENGINE_OFF description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
} else if (gnssCbIface_2_0 != nullptr) {
|
||||
auto r = gnssCbIface_2_0->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssStatusCb 2_0 SESSION_END description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
r = gnssCbIface_2_0->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_OFF);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssStatusCb 2_0 ENGINE_OFF description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
|
||||
} else if (gnssCbIface != nullptr) {
|
||||
auto r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssStatusCb SESSION_END description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_OFF);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssStatusCb ENGINE_OFF description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void convertGnssSvStatus(GnssSvNotification& in, V1_0::IGnssCallback::GnssSvStatus& out)
|
||||
{
|
||||
memset(&out, 0, sizeof(IGnssCallback::GnssSvStatus));
|
||||
out.numSvs = in.count;
|
||||
if (out.numSvs > static_cast<uint32_t>(V1_0::GnssMax::SVS_COUNT)) {
|
||||
LOC_LOGW("%s]: Too many satellites %u. Clamps to %d.",
|
||||
__FUNCTION__, out.numSvs, V1_0::GnssMax::SVS_COUNT);
|
||||
out.numSvs = static_cast<uint32_t>(V1_0::GnssMax::SVS_COUNT);
|
||||
}
|
||||
for (size_t i = 0; i < out.numSvs; i++) {
|
||||
convertGnssSvid(in.gnssSvs[i], out.gnssSvList[i].svid);
|
||||
convertGnssConstellationType(in.gnssSvs[i].type, out.gnssSvList[i].constellation);
|
||||
out.gnssSvList[i].cN0Dbhz = in.gnssSvs[i].cN0Dbhz;
|
||||
out.gnssSvList[i].elevationDegrees = in.gnssSvs[i].elevation;
|
||||
out.gnssSvList[i].azimuthDegrees = in.gnssSvs[i].azimuth;
|
||||
out.gnssSvList[i].carrierFrequencyHz = in.gnssSvs[i].carrierFrequencyHz;
|
||||
out.gnssSvList[i].svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE);
|
||||
if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT)
|
||||
out.gnssSvList[i].svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
|
||||
if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT)
|
||||
out.gnssSvList[i].svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA;
|
||||
if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT)
|
||||
out.gnssSvList[i].svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX;
|
||||
if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_CARRIER_FREQUENCY_BIT)
|
||||
out.gnssSvList[i].svFlag |= IGnssCallback::GnssSvFlags::HAS_CARRIER_FREQUENCY;
|
||||
}
|
||||
}
|
||||
|
||||
static void convertGnssSvStatus(GnssSvNotification& in,
|
||||
hidl_vec<V2_0::IGnssCallback::GnssSvInfo>& out)
|
||||
{
|
||||
out.resize(in.count);
|
||||
for (size_t i = 0; i < in.count; i++) {
|
||||
convertGnssSvid(in.gnssSvs[i], out[i].v1_0.svid);
|
||||
out[i].v1_0.cN0Dbhz = in.gnssSvs[i].cN0Dbhz;
|
||||
out[i].v1_0.elevationDegrees = in.gnssSvs[i].elevation;
|
||||
out[i].v1_0.azimuthDegrees = in.gnssSvs[i].azimuth;
|
||||
out[i].v1_0.carrierFrequencyHz = in.gnssSvs[i].carrierFrequencyHz;
|
||||
out[i].v1_0.svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE);
|
||||
if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT)
|
||||
out[i].v1_0.svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
|
||||
if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT)
|
||||
out[i].v1_0.svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA;
|
||||
if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT)
|
||||
out[i].v1_0.svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX;
|
||||
if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_CARRIER_FREQUENCY_BIT)
|
||||
out[i].v1_0.svFlag |= IGnssCallback::GnssSvFlags::HAS_CARRIER_FREQUENCY;
|
||||
|
||||
convertGnssConstellationType(in.gnssSvs[i].type, out[i].constellation);
|
||||
}
|
||||
}
|
||||
|
||||
static void convertGnssSvStatus(GnssSvNotification& in,
|
||||
hidl_vec<V2_1::IGnssCallback::GnssSvInfo>& out)
|
||||
{
|
||||
out.resize(in.count);
|
||||
for (size_t i = 0; i < in.count; i++) {
|
||||
convertGnssSvid(in.gnssSvs[i], out[i].v2_0.v1_0.svid);
|
||||
out[i].v2_0.v1_0.cN0Dbhz = in.gnssSvs[i].cN0Dbhz;
|
||||
out[i].v2_0.v1_0.elevationDegrees = in.gnssSvs[i].elevation;
|
||||
out[i].v2_0.v1_0.azimuthDegrees = in.gnssSvs[i].azimuth;
|
||||
out[i].v2_0.v1_0.carrierFrequencyHz = in.gnssSvs[i].carrierFrequencyHz;
|
||||
out[i].v2_0.v1_0.svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE);
|
||||
if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT)
|
||||
out[i].v2_0.v1_0.svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
|
||||
if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT)
|
||||
out[i].v2_0.v1_0.svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA;
|
||||
if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT)
|
||||
out[i].v2_0.v1_0.svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX;
|
||||
if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_CARRIER_FREQUENCY_BIT)
|
||||
out[i].v2_0.v1_0.svFlag |= IGnssCallback::GnssSvFlags::HAS_CARRIER_FREQUENCY;
|
||||
|
||||
convertGnssConstellationType(in.gnssSvs[i].type, out[i].v2_0.constellation);
|
||||
out[i].basebandCN0DbHz = in.gnssSvs[i].basebandCarrierToNoiseDbHz;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_1
|
||||
} // namespace gnss
|
||||
} // namespace hardware
|
||||
} // namespace android
|
121
gps/android/2.1/location_api/GnssAPIClient.h
Normal file
121
gps/android/2.1/location_api/GnssAPIClient.h
Normal file
@@ -0,0 +1,121 @@
|
||||
/* 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 GNSS_API_CLINET_H
|
||||
#define GNSS_API_CLINET_H
|
||||
|
||||
|
||||
#include <mutex>
|
||||
#include <android/hardware/gnss/2.1/IGnss.h>
|
||||
#include <android/hardware/gnss/2.1/IGnssCallback.h>
|
||||
#include <LocationAPIClientBase.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace gnss {
|
||||
namespace V2_1 {
|
||||
namespace implementation {
|
||||
|
||||
using ::android::sp;
|
||||
|
||||
class GnssAPIClient : public LocationAPIClientBase
|
||||
{
|
||||
public:
|
||||
GnssAPIClient(const sp<V1_0::IGnssCallback>& gpsCb,
|
||||
const sp<V1_0::IGnssNiCallback>& niCb);
|
||||
GnssAPIClient(const sp<V2_0::IGnssCallback>& gpsCb);
|
||||
GnssAPIClient(const sp<V2_1::IGnssCallback>& gpsCb);
|
||||
GnssAPIClient(const GnssAPIClient&) = delete;
|
||||
GnssAPIClient& operator=(const GnssAPIClient&) = delete;
|
||||
|
||||
// for GpsInterface
|
||||
void gnssUpdateCallbacks(const sp<V1_0::IGnssCallback>& gpsCb,
|
||||
const sp<V1_0::IGnssNiCallback>& niCb);
|
||||
void gnssUpdateCallbacks_2_0(const sp<V2_0::IGnssCallback>& gpsCb);
|
||||
void gnssUpdateCallbacks_2_1(const sp<V2_1::IGnssCallback>& gpsCb);
|
||||
bool gnssStart();
|
||||
bool gnssStop();
|
||||
bool gnssSetPositionMode(V1_0::IGnss::GnssPositionMode mode,
|
||||
V1_0::IGnss::GnssPositionRecurrence recurrence,
|
||||
uint32_t minIntervalMs,
|
||||
uint32_t preferredAccuracyMeters,
|
||||
uint32_t preferredTimeMs,
|
||||
GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID,
|
||||
uint32_t timeBetweenMeasurement = 0);
|
||||
|
||||
// for GpsNiInterface
|
||||
void gnssNiRespond(int32_t notifId, V1_0::IGnssNiCallback::GnssUserResponseType userResponse);
|
||||
|
||||
// these apis using LocationAPIControlClient
|
||||
void gnssDeleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags);
|
||||
void gnssEnable(LocationTechnologyType techType);
|
||||
void gnssDisable();
|
||||
void gnssConfigurationUpdate(const GnssConfig& gnssConfig);
|
||||
|
||||
inline LocationCapabilitiesMask gnssGetCapabilities() const {
|
||||
return mLocationCapabilitiesMask;
|
||||
}
|
||||
void requestCapabilities();
|
||||
|
||||
// callbacks we are interested in
|
||||
void onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) final;
|
||||
void onTrackingCb(Location location) final;
|
||||
void onGnssNiCb(uint32_t id, GnssNiNotification gnssNiNotification) final;
|
||||
void onGnssSvCb(GnssSvNotification gnssSvNotification) final;
|
||||
void onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification) final;
|
||||
void onEngineLocationsInfoCb(uint32_t count,
|
||||
GnssLocationInfoNotification* engineLocationInfoNotification);
|
||||
|
||||
|
||||
void onStartTrackingCb(LocationError error) final;
|
||||
void onStopTrackingCb(LocationError error) final;
|
||||
|
||||
private:
|
||||
virtual ~GnssAPIClient();
|
||||
void setCallbacks();
|
||||
void initLocationOptions();
|
||||
|
||||
sp<V1_0::IGnssCallback> mGnssCbIface;
|
||||
sp<V1_0::IGnssNiCallback> mGnssNiCbIface;
|
||||
std::mutex mMutex;
|
||||
LocationAPIControlClient* mControlClient;
|
||||
LocationCapabilitiesMask mLocationCapabilitiesMask;
|
||||
bool mLocationCapabilitiesCached;
|
||||
TrackingOptions mTrackingOptions;
|
||||
bool mTracking;
|
||||
sp<V2_0::IGnssCallback> mGnssCbIface_2_0;
|
||||
sp<V2_1::IGnssCallback> mGnssCbIface_2_1;
|
||||
};
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_1
|
||||
} // namespace gnss
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
#endif // GNSS_API_CLINET_H
|
405
gps/android/2.1/location_api/LocationUtil.cpp
Normal file
405
gps/android/2.1/location_api/LocationUtil.cpp
Normal file
@@ -0,0 +1,405 @@
|
||||
/* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <LocationUtil.h>
|
||||
#include <log_util.h>
|
||||
#include <inttypes.h>
|
||||
#include <loc_misc_utils.h>
|
||||
#include <gps_extended_c.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace gnss {
|
||||
namespace V2_1 {
|
||||
namespace implementation {
|
||||
|
||||
using ::android::hardware::gnss::V2_0::GnssLocation;
|
||||
using ::android::hardware::gnss::V2_0::ElapsedRealtimeFlags;
|
||||
using ::android::hardware::gnss::V2_0::GnssConstellationType;
|
||||
using ::android::hardware::gnss::V1_0::GnssLocationFlags;
|
||||
using ::android::hardware::gnss::measurement_corrections::V1_0::GnssSingleSatCorrectionFlags;
|
||||
|
||||
void convertGnssLocation(Location& in, V1_0::GnssLocation& out)
|
||||
{
|
||||
memset(&out, 0, sizeof(V1_0::GnssLocation));
|
||||
if (in.flags & LOCATION_HAS_LAT_LONG_BIT) {
|
||||
out.gnssLocationFlags |= GnssLocationFlags::HAS_LAT_LONG;
|
||||
out.latitudeDegrees = in.latitude;
|
||||
out.longitudeDegrees = in.longitude;
|
||||
}
|
||||
if (in.flags & LOCATION_HAS_ALTITUDE_BIT) {
|
||||
out.gnssLocationFlags |= GnssLocationFlags::HAS_ALTITUDE;
|
||||
out.altitudeMeters = in.altitude;
|
||||
}
|
||||
if (in.flags & LOCATION_HAS_SPEED_BIT) {
|
||||
out.gnssLocationFlags |= GnssLocationFlags::HAS_SPEED;
|
||||
out.speedMetersPerSec = in.speed;
|
||||
}
|
||||
if (in.flags & LOCATION_HAS_BEARING_BIT) {
|
||||
out.gnssLocationFlags |= GnssLocationFlags::HAS_BEARING;
|
||||
out.bearingDegrees = in.bearing;
|
||||
}
|
||||
if (in.flags & LOCATION_HAS_ACCURACY_BIT) {
|
||||
out.gnssLocationFlags |= GnssLocationFlags::HAS_HORIZONTAL_ACCURACY;
|
||||
out.horizontalAccuracyMeters = in.accuracy;
|
||||
}
|
||||
if (in.flags & LOCATION_HAS_VERTICAL_ACCURACY_BIT) {
|
||||
out.gnssLocationFlags |= GnssLocationFlags::HAS_VERTICAL_ACCURACY;
|
||||
out.verticalAccuracyMeters = in.verticalAccuracy;
|
||||
}
|
||||
if (in.flags & LOCATION_HAS_SPEED_ACCURACY_BIT) {
|
||||
out.gnssLocationFlags |= GnssLocationFlags::HAS_SPEED_ACCURACY;
|
||||
out.speedAccuracyMetersPerSecond = in.speedAccuracy;
|
||||
}
|
||||
if (in.flags & LOCATION_HAS_BEARING_ACCURACY_BIT) {
|
||||
out.gnssLocationFlags |= GnssLocationFlags::HAS_BEARING_ACCURACY;
|
||||
out.bearingAccuracyDegrees = in.bearingAccuracy;
|
||||
}
|
||||
|
||||
out.timestamp = static_cast<V1_0::GnssUtcTime>(in.timestamp);
|
||||
}
|
||||
|
||||
void convertGnssLocation(Location& in, V2_0::GnssLocation& out)
|
||||
{
|
||||
memset(&out, 0, sizeof(V2_0::GnssLocation));
|
||||
convertGnssLocation(in, out.v1_0);
|
||||
|
||||
if (in.flags & LOCATION_HAS_ELAPSED_REAL_TIME_BIT) {
|
||||
out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIMESTAMP_NS;
|
||||
out.elapsedRealtime.timestampNs = in.elapsedRealTime;
|
||||
out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS;
|
||||
out.elapsedRealtime.timeUncertaintyNs = in.elapsedRealTimeUnc;
|
||||
LOC_LOGd("out.elapsedRealtime.timestampNs=%" PRIi64 ""
|
||||
" out.elapsedRealtime.timeUncertaintyNs=%" PRIi64 ""
|
||||
" out.elapsedRealtime.flags=0x%X",
|
||||
out.elapsedRealtime.timestampNs,
|
||||
out.elapsedRealtime.timeUncertaintyNs, out.elapsedRealtime.flags);
|
||||
}
|
||||
}
|
||||
|
||||
void convertGnssLocation(const V1_0::GnssLocation& in, Location& out)
|
||||
{
|
||||
memset(&out, 0, sizeof(out));
|
||||
if (in.gnssLocationFlags & GnssLocationFlags::HAS_LAT_LONG) {
|
||||
out.flags |= LOCATION_HAS_LAT_LONG_BIT;
|
||||
out.latitude = in.latitudeDegrees;
|
||||
out.longitude = in.longitudeDegrees;
|
||||
}
|
||||
if (in.gnssLocationFlags & GnssLocationFlags::HAS_ALTITUDE) {
|
||||
out.flags |= LOCATION_HAS_ALTITUDE_BIT;
|
||||
out.altitude = in.altitudeMeters;
|
||||
}
|
||||
if (in.gnssLocationFlags & GnssLocationFlags::HAS_SPEED) {
|
||||
out.flags |= LOCATION_HAS_SPEED_BIT;
|
||||
out.speed = in.speedMetersPerSec;
|
||||
}
|
||||
if (in.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) {
|
||||
out.flags |= LOCATION_HAS_BEARING_BIT;
|
||||
out.bearing = in.bearingDegrees;
|
||||
}
|
||||
if (in.gnssLocationFlags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY) {
|
||||
out.flags |= LOCATION_HAS_ACCURACY_BIT;
|
||||
out.accuracy = in.horizontalAccuracyMeters;
|
||||
}
|
||||
if (in.gnssLocationFlags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
|
||||
out.flags |= LOCATION_HAS_VERTICAL_ACCURACY_BIT;
|
||||
out.verticalAccuracy = in.verticalAccuracyMeters;
|
||||
}
|
||||
if (in.gnssLocationFlags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
|
||||
out.flags |= LOCATION_HAS_SPEED_ACCURACY_BIT;
|
||||
out.speedAccuracy = in.speedAccuracyMetersPerSecond;
|
||||
}
|
||||
if (in.gnssLocationFlags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
|
||||
out.flags |= LOCATION_HAS_BEARING_ACCURACY_BIT;
|
||||
out.bearingAccuracy = in.bearingAccuracyDegrees;
|
||||
}
|
||||
|
||||
out.timestamp = static_cast<uint64_t>(in.timestamp);
|
||||
}
|
||||
|
||||
void convertGnssLocation(const V2_0::GnssLocation& in, Location& out)
|
||||
{
|
||||
memset(&out, 0, sizeof(out));
|
||||
convertGnssLocation(in.v1_0, out);
|
||||
}
|
||||
|
||||
void convertGnssConstellationType(GnssSvType& in, V1_0::GnssConstellationType& out)
|
||||
{
|
||||
switch(in) {
|
||||
case GNSS_SV_TYPE_GPS:
|
||||
out = V1_0::GnssConstellationType::GPS;
|
||||
break;
|
||||
case GNSS_SV_TYPE_SBAS:
|
||||
out = V1_0::GnssConstellationType::SBAS;
|
||||
break;
|
||||
case GNSS_SV_TYPE_GLONASS:
|
||||
out = V1_0::GnssConstellationType::GLONASS;
|
||||
break;
|
||||
case GNSS_SV_TYPE_QZSS:
|
||||
out = V1_0::GnssConstellationType::QZSS;
|
||||
break;
|
||||
case GNSS_SV_TYPE_BEIDOU:
|
||||
out = V1_0::GnssConstellationType::BEIDOU;
|
||||
break;
|
||||
case GNSS_SV_TYPE_GALILEO:
|
||||
out = V1_0::GnssConstellationType::GALILEO;
|
||||
break;
|
||||
case GNSS_SV_TYPE_UNKNOWN:
|
||||
default:
|
||||
out = V1_0::GnssConstellationType::UNKNOWN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void convertGnssConstellationType(GnssSvType& in, V2_0::GnssConstellationType& out)
|
||||
{
|
||||
switch(in) {
|
||||
case GNSS_SV_TYPE_GPS:
|
||||
out = V2_0::GnssConstellationType::GPS;
|
||||
break;
|
||||
case GNSS_SV_TYPE_SBAS:
|
||||
out = V2_0::GnssConstellationType::SBAS;
|
||||
break;
|
||||
case GNSS_SV_TYPE_GLONASS:
|
||||
out = V2_0::GnssConstellationType::GLONASS;
|
||||
break;
|
||||
case GNSS_SV_TYPE_QZSS:
|
||||
out = V2_0::GnssConstellationType::QZSS;
|
||||
break;
|
||||
case GNSS_SV_TYPE_BEIDOU:
|
||||
out = V2_0::GnssConstellationType::BEIDOU;
|
||||
break;
|
||||
case GNSS_SV_TYPE_GALILEO:
|
||||
out = V2_0::GnssConstellationType::GALILEO;
|
||||
break;
|
||||
case GNSS_SV_TYPE_NAVIC:
|
||||
out = V2_0::GnssConstellationType::IRNSS;
|
||||
break;
|
||||
case GNSS_SV_TYPE_UNKNOWN:
|
||||
default:
|
||||
out = V2_0::GnssConstellationType::UNKNOWN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void convertGnssSvid(GnssSv& in, int16_t& out)
|
||||
{
|
||||
switch (in.type) {
|
||||
case GNSS_SV_TYPE_GPS:
|
||||
out = in.svId;
|
||||
break;
|
||||
case GNSS_SV_TYPE_SBAS:
|
||||
out = in.svId;
|
||||
break;
|
||||
case GNSS_SV_TYPE_GLONASS:
|
||||
if (!isGloSlotUnknown(in.svId)) { // OSN is known
|
||||
out = in.svId - GLO_SV_PRN_MIN + 1;
|
||||
} else { // OSN is not known, report FCN
|
||||
out = in.gloFrequency + 92;
|
||||
}
|
||||
break;
|
||||
case GNSS_SV_TYPE_QZSS:
|
||||
out = in.svId;
|
||||
break;
|
||||
case GNSS_SV_TYPE_BEIDOU:
|
||||
out = in.svId - BDS_SV_PRN_MIN + 1;
|
||||
break;
|
||||
case GNSS_SV_TYPE_GALILEO:
|
||||
out = in.svId - GAL_SV_PRN_MIN + 1;
|
||||
break;
|
||||
case GNSS_SV_TYPE_NAVIC:
|
||||
out = in.svId - NAVIC_SV_PRN_MIN + 1;
|
||||
break;
|
||||
default:
|
||||
out = in.svId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void convertGnssSvid(GnssMeasurementsData& in, int16_t& out)
|
||||
{
|
||||
switch (in.svType) {
|
||||
case GNSS_SV_TYPE_GPS:
|
||||
out = in.svId;
|
||||
break;
|
||||
case GNSS_SV_TYPE_SBAS:
|
||||
out = in.svId;
|
||||
break;
|
||||
case GNSS_SV_TYPE_GLONASS:
|
||||
if (!isGloSlotUnknown(in.svId)) { // OSN is known
|
||||
out = in.svId - GLO_SV_PRN_MIN + 1;
|
||||
} else { // OSN is not known, report FCN
|
||||
out = in.gloFrequency + 92;
|
||||
}
|
||||
break;
|
||||
case GNSS_SV_TYPE_QZSS:
|
||||
out = in.svId;
|
||||
break;
|
||||
case GNSS_SV_TYPE_BEIDOU:
|
||||
out = in.svId - BDS_SV_PRN_MIN + 1;
|
||||
break;
|
||||
case GNSS_SV_TYPE_GALILEO:
|
||||
out = in.svId - GAL_SV_PRN_MIN + 1;
|
||||
break;
|
||||
case GNSS_SV_TYPE_NAVIC:
|
||||
out = in.svId - NAVIC_SV_PRN_MIN + 1;
|
||||
break;
|
||||
default:
|
||||
out = in.svId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void convertGnssEphemerisType(GnssEphemerisType& in, GnssDebug::SatelliteEphemerisType& out)
|
||||
{
|
||||
switch(in) {
|
||||
case GNSS_EPH_TYPE_EPHEMERIS:
|
||||
out = GnssDebug::SatelliteEphemerisType::EPHEMERIS;
|
||||
break;
|
||||
case GNSS_EPH_TYPE_ALMANAC:
|
||||
out = GnssDebug::SatelliteEphemerisType::ALMANAC_ONLY;
|
||||
break;
|
||||
case GNSS_EPH_TYPE_UNKNOWN:
|
||||
default:
|
||||
out = GnssDebug::SatelliteEphemerisType::NOT_AVAILABLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void convertGnssEphemerisSource(GnssEphemerisSource& in, GnssDebug::SatelliteEphemerisSource& out)
|
||||
{
|
||||
switch(in) {
|
||||
case GNSS_EPH_SOURCE_DEMODULATED:
|
||||
out = GnssDebug::SatelliteEphemerisSource::DEMODULATED;
|
||||
break;
|
||||
case GNSS_EPH_SOURCE_SUPL_PROVIDED:
|
||||
out = GnssDebug::SatelliteEphemerisSource::SUPL_PROVIDED;
|
||||
break;
|
||||
case GNSS_EPH_SOURCE_OTHER_SERVER_PROVIDED:
|
||||
out = GnssDebug::SatelliteEphemerisSource::OTHER_SERVER_PROVIDED;
|
||||
break;
|
||||
case GNSS_EPH_SOURCE_LOCAL:
|
||||
case GNSS_EPH_SOURCE_UNKNOWN:
|
||||
default:
|
||||
out = GnssDebug::SatelliteEphemerisSource::OTHER;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void convertGnssEphemerisHealth(GnssEphemerisHealth& in, GnssDebug::SatelliteEphemerisHealth& out)
|
||||
{
|
||||
switch(in) {
|
||||
case GNSS_EPH_HEALTH_GOOD:
|
||||
out = GnssDebug::SatelliteEphemerisHealth::GOOD;
|
||||
break;
|
||||
case GNSS_EPH_HEALTH_BAD:
|
||||
out = GnssDebug::SatelliteEphemerisHealth::BAD;
|
||||
break;
|
||||
case GNSS_EPH_HEALTH_UNKNOWN:
|
||||
default:
|
||||
out = GnssDebug::SatelliteEphemerisHealth::UNKNOWN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void convertSingleSatCorrections(const SingleSatCorrection& in, GnssSingleSatCorrection& out)
|
||||
{
|
||||
out.flags = GNSS_MEAS_CORR_UNKNOWN_BIT;
|
||||
if (in.singleSatCorrectionFlags & (GnssSingleSatCorrectionFlags::HAS_SAT_IS_LOS_PROBABILITY)) {
|
||||
out.flags |= GNSS_MEAS_CORR_HAS_SAT_IS_LOS_PROBABILITY_BIT;
|
||||
}
|
||||
if (in.singleSatCorrectionFlags & (GnssSingleSatCorrectionFlags::HAS_EXCESS_PATH_LENGTH)) {
|
||||
out.flags |= GNSS_MEAS_CORR_HAS_EXCESS_PATH_LENGTH_BIT;
|
||||
}
|
||||
if (in.singleSatCorrectionFlags & (GnssSingleSatCorrectionFlags::HAS_EXCESS_PATH_LENGTH_UNC)) {
|
||||
out.flags |= GNSS_MEAS_CORR_HAS_EXCESS_PATH_LENGTH_UNC_BIT;
|
||||
}
|
||||
if (in.singleSatCorrectionFlags & (GnssSingleSatCorrectionFlags::HAS_REFLECTING_PLANE)) {
|
||||
out.flags |= GNSS_MEAS_CORR_HAS_REFLECTING_PLANE_BIT;
|
||||
}
|
||||
switch (in.constellation) {
|
||||
case (::android::hardware::gnss::V1_0::GnssConstellationType::GPS):
|
||||
out.svType = GNSS_SV_TYPE_GPS;
|
||||
break;
|
||||
case (::android::hardware::gnss::V1_0::GnssConstellationType::SBAS):
|
||||
out.svType = GNSS_SV_TYPE_SBAS;
|
||||
break;
|
||||
case (::android::hardware::gnss::V1_0::GnssConstellationType::GLONASS):
|
||||
out.svType = GNSS_SV_TYPE_GLONASS;
|
||||
break;
|
||||
case (::android::hardware::gnss::V1_0::GnssConstellationType::QZSS):
|
||||
out.svType = GNSS_SV_TYPE_QZSS;
|
||||
break;
|
||||
case (::android::hardware::gnss::V1_0::GnssConstellationType::BEIDOU):
|
||||
out.svType = GNSS_SV_TYPE_BEIDOU;
|
||||
break;
|
||||
case (::android::hardware::gnss::V1_0::GnssConstellationType::GALILEO):
|
||||
out.svType = GNSS_SV_TYPE_GALILEO;
|
||||
break;
|
||||
case (::android::hardware::gnss::V1_0::GnssConstellationType::UNKNOWN):
|
||||
default:
|
||||
out.svType = GNSS_SV_TYPE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
out.svId = in.svid;
|
||||
out.carrierFrequencyHz = in.carrierFrequencyHz;
|
||||
out.probSatIsLos = in.probSatIsLos;
|
||||
out.excessPathLengthMeters = in.excessPathLengthMeters;
|
||||
out.excessPathLengthUncertaintyMeters = in.excessPathLengthUncertaintyMeters;
|
||||
|
||||
out.reflectingPlane.latitudeDegrees = in.reflectingPlane.latitudeDegrees;
|
||||
out.reflectingPlane.longitudeDegrees = in.reflectingPlane.longitudeDegrees;
|
||||
out.reflectingPlane.altitudeMeters = in.reflectingPlane.altitudeMeters;
|
||||
out.reflectingPlane.azimuthDegrees = in.reflectingPlane.azimuthDegrees;
|
||||
}
|
||||
|
||||
void convertMeasurementCorrections(const MeasurementCorrectionsV1_0& in,
|
||||
GnssMeasurementCorrections& out)
|
||||
{
|
||||
memset(&out, 0, sizeof(GnssMeasurementCorrections));
|
||||
out.latitudeDegrees = in.latitudeDegrees;
|
||||
out.longitudeDegrees = in.longitudeDegrees;
|
||||
out.altitudeMeters = in.altitudeMeters;
|
||||
out.horizontalPositionUncertaintyMeters = in.horizontalPositionUncertaintyMeters;
|
||||
out.verticalPositionUncertaintyMeters = in.verticalPositionUncertaintyMeters;
|
||||
out.toaGpsNanosecondsOfWeek = in.toaGpsNanosecondsOfWeek;
|
||||
|
||||
for (int i = 0; i < in.satCorrections.size(); i++) {
|
||||
GnssSingleSatCorrection gnssSingleSatCorrection = {};
|
||||
|
||||
convertSingleSatCorrections(in.satCorrections[i], gnssSingleSatCorrection);
|
||||
out.satCorrections.push_back(gnssSingleSatCorrection);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_1
|
||||
} // namespace gnss
|
||||
} // namespace hardware
|
||||
} // namespace android
|
68
gps/android/2.1/location_api/LocationUtil.h
Normal file
68
gps/android/2.1/location_api/LocationUtil.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/* 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 LOCATION_UTIL_H
|
||||
#define LOCATION_UTIL_H
|
||||
|
||||
#include <android/hardware/gnss/2.0/types.h>
|
||||
#include <android/hardware/gnss/measurement_corrections/1.0/IMeasurementCorrections.h>
|
||||
#include <LocationAPI.h>
|
||||
#include <GnssDebug.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace gnss {
|
||||
namespace V2_1 {
|
||||
namespace implementation {
|
||||
|
||||
using MeasurementCorrectionsV1_0 =
|
||||
::android::hardware::gnss::measurement_corrections::V1_0::MeasurementCorrections;
|
||||
using ::android::hardware::gnss::measurement_corrections::V1_0::SingleSatCorrection;
|
||||
|
||||
void convertGnssLocation(Location& in, V1_0::GnssLocation& out);
|
||||
void convertGnssLocation(Location& in, V2_0::GnssLocation& out);
|
||||
void convertGnssLocation(const V1_0::GnssLocation& in, Location& out);
|
||||
void convertGnssLocation(const V2_0::GnssLocation& in, Location& out);
|
||||
void convertGnssConstellationType(GnssSvType& in, V1_0::GnssConstellationType& out);
|
||||
void convertGnssConstellationType(GnssSvType& in, V2_0::GnssConstellationType& out);
|
||||
void convertGnssSvid(GnssSv& in, int16_t& out);
|
||||
void convertGnssSvid(GnssMeasurementsData& in, int16_t& out);
|
||||
void convertGnssEphemerisType(GnssEphemerisType& in, GnssDebug::SatelliteEphemerisType& out);
|
||||
void convertGnssEphemerisSource(GnssEphemerisSource& in, GnssDebug::SatelliteEphemerisSource& out);
|
||||
void convertGnssEphemerisHealth(GnssEphemerisHealth& in, GnssDebug::SatelliteEphemerisHealth& out);
|
||||
void convertSingleSatCorrections(const SingleSatCorrection& in, GnssSingleSatCorrection& out);
|
||||
void convertMeasurementCorrections(const MeasurementCorrectionsV1_0& in,
|
||||
GnssMeasurementCorrections& out);
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_1
|
||||
} // namespace gnss
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
#endif // LOCATION_UTIL_H
|
641
gps/android/2.1/location_api/MeasurementAPIClient.cpp
Normal file
641
gps/android/2.1/location_api/MeasurementAPIClient.cpp
Normal file
@@ -0,0 +1,641 @@
|
||||
/* 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_NDEBUG 0
|
||||
#define LOG_TAG "LocSvc_MeasurementAPIClient"
|
||||
|
||||
#include <log_util.h>
|
||||
#include <loc_cfg.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "LocationUtil.h"
|
||||
#include "MeasurementAPIClient.h"
|
||||
#include <loc_misc_utils.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace gnss {
|
||||
namespace V2_1 {
|
||||
namespace implementation {
|
||||
|
||||
using ::android::hardware::gnss::V1_0::IGnssMeasurement;
|
||||
using ::android::hardware::gnss::V2_0::IGnssMeasurementCallback;
|
||||
|
||||
static void convertGnssData(GnssMeasurementsNotification& in,
|
||||
V1_0::IGnssMeasurementCallback::GnssData& out);
|
||||
static void convertGnssData_1_1(GnssMeasurementsNotification& in,
|
||||
V1_1::IGnssMeasurementCallback::GnssData& out);
|
||||
static void convertGnssData_2_0(GnssMeasurementsNotification& in,
|
||||
V2_0::IGnssMeasurementCallback::GnssData& out);
|
||||
static void convertGnssData_2_1(GnssMeasurementsNotification& in,
|
||||
V2_1::IGnssMeasurementCallback::GnssData& out);
|
||||
static void convertGnssMeasurement(GnssMeasurementsData& in,
|
||||
V1_0::IGnssMeasurementCallback::GnssMeasurement& out);
|
||||
static void convertGnssClock(GnssMeasurementsClock& in, IGnssMeasurementCallback::GnssClock& out);
|
||||
static void convertGnssClock_2_1(GnssMeasurementsClock& in,
|
||||
V2_1::IGnssMeasurementCallback::GnssClock& out);
|
||||
static void convertGnssMeasurementsCodeType(GnssMeasurementsCodeType& inCodeType,
|
||||
char* inOtherCodeTypeName,
|
||||
::android::hardware::hidl_string& out);
|
||||
static void convertGnssMeasurementsAccumulatedDeltaRangeState(GnssMeasurementsAdrStateMask& in,
|
||||
::android::hardware::hidl_bitfield
|
||||
<V1_1::IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState>& out);
|
||||
static void convertGnssMeasurementsState(GnssMeasurementsStateMask& in,
|
||||
::android::hardware::hidl_bitfield
|
||||
<V2_0::IGnssMeasurementCallback::GnssMeasurementState>& out);
|
||||
static void convertElapsedRealtimeNanos(GnssMeasurementsNotification& in,
|
||||
::android::hardware::gnss::V2_0::ElapsedRealtime& elapsedRealtimeNanos);
|
||||
|
||||
MeasurementAPIClient::MeasurementAPIClient() :
|
||||
mGnssMeasurementCbIface(nullptr),
|
||||
mGnssMeasurementCbIface_1_1(nullptr),
|
||||
mGnssMeasurementCbIface_2_0(nullptr),
|
||||
mGnssMeasurementCbIface_2_1(nullptr),
|
||||
mTracking(false)
|
||||
{
|
||||
LOC_LOGD("%s]: ()", __FUNCTION__);
|
||||
}
|
||||
|
||||
MeasurementAPIClient::~MeasurementAPIClient()
|
||||
{
|
||||
LOC_LOGD("%s]: ()", __FUNCTION__);
|
||||
}
|
||||
|
||||
void MeasurementAPIClient::clearInterfaces()
|
||||
{
|
||||
mGnssMeasurementCbIface = nullptr;
|
||||
mGnssMeasurementCbIface_1_1 = nullptr;
|
||||
mGnssMeasurementCbIface_2_0 = nullptr;
|
||||
mGnssMeasurementCbIface_2_1 = nullptr;
|
||||
}
|
||||
|
||||
// for GpsInterface
|
||||
Return<IGnssMeasurement::GnssMeasurementStatus>
|
||||
MeasurementAPIClient::measurementSetCallback(const sp<V1_0::IGnssMeasurementCallback>& callback)
|
||||
{
|
||||
LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
|
||||
|
||||
mMutex.lock();
|
||||
clearInterfaces();
|
||||
mGnssMeasurementCbIface = callback;
|
||||
mMutex.unlock();
|
||||
|
||||
return startTracking();
|
||||
}
|
||||
|
||||
Return<IGnssMeasurement::GnssMeasurementStatus>
|
||||
MeasurementAPIClient::measurementSetCallback_1_1(
|
||||
const sp<V1_1::IGnssMeasurementCallback>& callback,
|
||||
GnssPowerMode powerMode, uint32_t timeBetweenMeasurement)
|
||||
{
|
||||
LOC_LOGD("%s]: (%p) (powermode: %d) (tbm: %d)",
|
||||
__FUNCTION__, &callback, (int)powerMode, timeBetweenMeasurement);
|
||||
|
||||
mMutex.lock();
|
||||
clearInterfaces();
|
||||
mGnssMeasurementCbIface_1_1 = callback;
|
||||
mMutex.unlock();
|
||||
|
||||
return startTracking(powerMode, timeBetweenMeasurement);
|
||||
}
|
||||
|
||||
Return<IGnssMeasurement::GnssMeasurementStatus>
|
||||
MeasurementAPIClient::measurementSetCallback_2_0(
|
||||
const sp<V2_0::IGnssMeasurementCallback>& callback,
|
||||
GnssPowerMode powerMode, uint32_t timeBetweenMeasurement)
|
||||
{
|
||||
LOC_LOGD("%s]: (%p) (powermode: %d) (tbm: %d)",
|
||||
__FUNCTION__, &callback, (int)powerMode, timeBetweenMeasurement);
|
||||
|
||||
mMutex.lock();
|
||||
clearInterfaces();
|
||||
mGnssMeasurementCbIface_2_0 = callback;
|
||||
mMutex.unlock();
|
||||
|
||||
return startTracking(powerMode, timeBetweenMeasurement);
|
||||
}
|
||||
|
||||
Return<IGnssMeasurement::GnssMeasurementStatus> MeasurementAPIClient::measurementSetCallback_2_1(
|
||||
const sp<V2_1::IGnssMeasurementCallback>& callback,
|
||||
GnssPowerMode powerMode, uint32_t timeBetweenMeasurement) {
|
||||
LOC_LOGD("%s]: (%p) (powermode: %d) (tbm: %d)",
|
||||
__FUNCTION__, &callback, (int)powerMode, timeBetweenMeasurement);
|
||||
|
||||
mMutex.lock();
|
||||
clearInterfaces();
|
||||
mGnssMeasurementCbIface_2_1 = callback;
|
||||
mMutex.unlock();
|
||||
|
||||
return startTracking(powerMode, timeBetweenMeasurement);
|
||||
}
|
||||
Return<IGnssMeasurement::GnssMeasurementStatus>
|
||||
MeasurementAPIClient::startTracking(
|
||||
GnssPowerMode powerMode, uint32_t timeBetweenMeasurement)
|
||||
{
|
||||
LocationCallbacks locationCallbacks;
|
||||
memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
|
||||
locationCallbacks.size = sizeof(LocationCallbacks);
|
||||
|
||||
locationCallbacks.trackingCb = nullptr;
|
||||
locationCallbacks.batchingCb = nullptr;
|
||||
locationCallbacks.geofenceBreachCb = nullptr;
|
||||
locationCallbacks.geofenceStatusCb = nullptr;
|
||||
locationCallbacks.gnssLocationInfoCb = nullptr;
|
||||
locationCallbacks.gnssNiCb = nullptr;
|
||||
locationCallbacks.gnssSvCb = nullptr;
|
||||
locationCallbacks.gnssNmeaCb = nullptr;
|
||||
|
||||
locationCallbacks.gnssMeasurementsCb = nullptr;
|
||||
if (mGnssMeasurementCbIface_2_1 != nullptr ||
|
||||
mGnssMeasurementCbIface_2_0 != nullptr ||
|
||||
mGnssMeasurementCbIface_1_1 != nullptr ||
|
||||
mGnssMeasurementCbIface != nullptr) {
|
||||
locationCallbacks.gnssMeasurementsCb =
|
||||
[this](GnssMeasurementsNotification gnssMeasurementsNotification) {
|
||||
onGnssMeasurementsCb(gnssMeasurementsNotification);
|
||||
};
|
||||
}
|
||||
|
||||
locAPISetCallbacks(locationCallbacks);
|
||||
|
||||
TrackingOptions options = {};
|
||||
memset(&options, 0, sizeof(TrackingOptions));
|
||||
options.size = sizeof(TrackingOptions);
|
||||
options.minInterval = 1000;
|
||||
options.mode = GNSS_SUPL_MODE_STANDALONE;
|
||||
if (GNSS_POWER_MODE_INVALID != powerMode) {
|
||||
options.powerMode = powerMode;
|
||||
options.tbm = timeBetweenMeasurement;
|
||||
}
|
||||
|
||||
mTracking = true;
|
||||
LOC_LOGD("%s]: start tracking session", __FUNCTION__);
|
||||
locAPIStartTracking(options);
|
||||
return IGnssMeasurement::GnssMeasurementStatus::SUCCESS;
|
||||
}
|
||||
|
||||
// for GpsMeasurementInterface
|
||||
void MeasurementAPIClient::measurementClose() {
|
||||
LOC_LOGD("%s]: ()", __FUNCTION__);
|
||||
mTracking = false;
|
||||
locAPIStopTracking();
|
||||
}
|
||||
|
||||
// callbacks
|
||||
void MeasurementAPIClient::onGnssMeasurementsCb(
|
||||
GnssMeasurementsNotification gnssMeasurementsNotification)
|
||||
{
|
||||
LOC_LOGD("%s]: (count: %u active: %d)",
|
||||
__FUNCTION__, gnssMeasurementsNotification.count, mTracking);
|
||||
if (mTracking) {
|
||||
mMutex.lock();
|
||||
sp<V1_0::IGnssMeasurementCallback> gnssMeasurementCbIface = nullptr;
|
||||
sp<V1_1::IGnssMeasurementCallback> gnssMeasurementCbIface_1_1 = nullptr;
|
||||
sp<V2_0::IGnssMeasurementCallback> gnssMeasurementCbIface_2_0 = nullptr;
|
||||
sp<V2_1::IGnssMeasurementCallback> gnssMeasurementCbIface_2_1 = nullptr;
|
||||
if (mGnssMeasurementCbIface_2_1 != nullptr) {
|
||||
gnssMeasurementCbIface_2_1 = mGnssMeasurementCbIface_2_1;
|
||||
} else if (mGnssMeasurementCbIface_2_0 != nullptr) {
|
||||
gnssMeasurementCbIface_2_0 = mGnssMeasurementCbIface_2_0;
|
||||
} else if (mGnssMeasurementCbIface_1_1 != nullptr) {
|
||||
gnssMeasurementCbIface_1_1 = mGnssMeasurementCbIface_1_1;
|
||||
} else if (mGnssMeasurementCbIface != nullptr) {
|
||||
gnssMeasurementCbIface = mGnssMeasurementCbIface;
|
||||
}
|
||||
mMutex.unlock();
|
||||
|
||||
if (gnssMeasurementCbIface_2_1 != nullptr) {
|
||||
V2_1::IGnssMeasurementCallback::GnssData gnssData;
|
||||
convertGnssData_2_1(gnssMeasurementsNotification, gnssData);
|
||||
auto r = gnssMeasurementCbIface_2_1->gnssMeasurementCb_2_1(gnssData);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssMeasurementCb description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
} else if (gnssMeasurementCbIface_2_0 != nullptr) {
|
||||
V2_0::IGnssMeasurementCallback::GnssData gnssData;
|
||||
convertGnssData_2_0(gnssMeasurementsNotification, gnssData);
|
||||
auto r = gnssMeasurementCbIface_2_0->gnssMeasurementCb_2_0(gnssData);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssMeasurementCb description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
} else if (gnssMeasurementCbIface_1_1 != nullptr) {
|
||||
V1_1::IGnssMeasurementCallback::GnssData gnssData;
|
||||
convertGnssData_1_1(gnssMeasurementsNotification, gnssData);
|
||||
auto r = gnssMeasurementCbIface_1_1->gnssMeasurementCb(gnssData);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from gnssMeasurementCb description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
} else if (gnssMeasurementCbIface != nullptr) {
|
||||
V1_0::IGnssMeasurementCallback::GnssData gnssData;
|
||||
convertGnssData(gnssMeasurementsNotification, gnssData);
|
||||
auto r = gnssMeasurementCbIface->GnssMeasurementCb(gnssData);
|
||||
if (!r.isOk()) {
|
||||
LOC_LOGE("%s] Error from GnssMeasurementCb description=%s",
|
||||
__func__, r.description().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void convertGnssMeasurement(GnssMeasurementsData& in,
|
||||
V1_0::IGnssMeasurementCallback::GnssMeasurement& out)
|
||||
{
|
||||
memset(&out, 0, sizeof(out));
|
||||
if (in.flags & GNSS_MEASUREMENTS_DATA_SIGNAL_TO_NOISE_RATIO_BIT)
|
||||
out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_SNR;
|
||||
if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_FREQUENCY_BIT)
|
||||
out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_FREQUENCY;
|
||||
if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_CYCLES_BIT)
|
||||
out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_CYCLES;
|
||||
if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_PHASE_BIT)
|
||||
out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_PHASE;
|
||||
if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_PHASE_UNCERTAINTY_BIT)
|
||||
out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_PHASE_UNCERTAINTY;
|
||||
if (in.flags & GNSS_MEASUREMENTS_DATA_AUTOMATIC_GAIN_CONTROL_BIT)
|
||||
out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL;
|
||||
convertGnssSvid(in, out.svid);
|
||||
convertGnssConstellationType(in.svType, out.constellation);
|
||||
out.timeOffsetNs = in.timeOffsetNs;
|
||||
if (in.stateMask & GNSS_MEASUREMENTS_STATE_CODE_LOCK_BIT)
|
||||
out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_CODE_LOCK;
|
||||
if (in.stateMask & GNSS_MEASUREMENTS_STATE_BIT_SYNC_BIT)
|
||||
out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_BIT_SYNC;
|
||||
if (in.stateMask & GNSS_MEASUREMENTS_STATE_SUBFRAME_SYNC_BIT)
|
||||
out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_SUBFRAME_SYNC;
|
||||
if (in.stateMask & GNSS_MEASUREMENTS_STATE_TOW_DECODED_BIT)
|
||||
out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_TOW_DECODED;
|
||||
if (in.stateMask & GNSS_MEASUREMENTS_STATE_MSEC_AMBIGUOUS_BIT)
|
||||
out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_MSEC_AMBIGUOUS;
|
||||
if (in.stateMask & GNSS_MEASUREMENTS_STATE_SYMBOL_SYNC_BIT)
|
||||
out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_SYMBOL_SYNC;
|
||||
if (in.stateMask & GNSS_MEASUREMENTS_STATE_GLO_STRING_SYNC_BIT)
|
||||
out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GLO_STRING_SYNC;
|
||||
if (in.stateMask & GNSS_MEASUREMENTS_STATE_GLO_TOD_DECODED_BIT)
|
||||
out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GLO_TOD_DECODED;
|
||||
if (in.stateMask & GNSS_MEASUREMENTS_STATE_BDS_D2_BIT_SYNC_BIT)
|
||||
out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_BDS_D2_BIT_SYNC;
|
||||
if (in.stateMask & GNSS_MEASUREMENTS_STATE_BDS_D2_SUBFRAME_SYNC_BIT)
|
||||
out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_BDS_D2_SUBFRAME_SYNC;
|
||||
if (in.stateMask & GNSS_MEASUREMENTS_STATE_GAL_E1BC_CODE_LOCK_BIT)
|
||||
out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GAL_E1BC_CODE_LOCK;
|
||||
if (in.stateMask & GNSS_MEASUREMENTS_STATE_GAL_E1C_2ND_CODE_LOCK_BIT)
|
||||
out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GAL_E1C_2ND_CODE_LOCK;
|
||||
if (in.stateMask & GNSS_MEASUREMENTS_STATE_GAL_E1B_PAGE_SYNC_BIT)
|
||||
out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GAL_E1B_PAGE_SYNC;
|
||||
if (in.stateMask & GNSS_MEASUREMENTS_STATE_SBAS_SYNC_BIT)
|
||||
out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_SBAS_SYNC;
|
||||
out.receivedSvTimeInNs = in.receivedSvTimeNs;
|
||||
out.receivedSvTimeUncertaintyInNs = in.receivedSvTimeUncertaintyNs;
|
||||
out.cN0DbHz = in.carrierToNoiseDbHz;
|
||||
out.pseudorangeRateMps = in.pseudorangeRateMps;
|
||||
out.pseudorangeRateUncertaintyMps = in.pseudorangeRateUncertaintyMps;
|
||||
if (in.adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_VALID_BIT)
|
||||
out.accumulatedDeltaRangeState |=
|
||||
IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_VALID;
|
||||
if (in.adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_RESET_BIT)
|
||||
out.accumulatedDeltaRangeState |=
|
||||
IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_RESET;
|
||||
if (in.adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_CYCLE_SLIP_BIT)
|
||||
out.accumulatedDeltaRangeState |=
|
||||
IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_CYCLE_SLIP;
|
||||
out.accumulatedDeltaRangeM = in.adrMeters;
|
||||
out.accumulatedDeltaRangeUncertaintyM = in.adrUncertaintyMeters;
|
||||
out.carrierFrequencyHz = in.carrierFrequencyHz;
|
||||
out.carrierCycles = in.carrierCycles;
|
||||
out.carrierPhase = in.carrierPhase;
|
||||
out.carrierPhaseUncertainty = in.carrierPhaseUncertainty;
|
||||
uint8_t indicator =
|
||||
static_cast<uint8_t>(IGnssMeasurementCallback::GnssMultipathIndicator::INDICATOR_UNKNOWN);
|
||||
if (in.multipathIndicator & GNSS_MEASUREMENTS_MULTIPATH_INDICATOR_PRESENT)
|
||||
indicator |= IGnssMeasurementCallback::GnssMultipathIndicator::INDICATOR_PRESENT;
|
||||
if (in.multipathIndicator & GNSS_MEASUREMENTS_MULTIPATH_INDICATOR_NOT_PRESENT)
|
||||
indicator |= IGnssMeasurementCallback::GnssMultipathIndicator::INDICATIOR_NOT_PRESENT;
|
||||
out.multipathIndicator =
|
||||
static_cast<IGnssMeasurementCallback::GnssMultipathIndicator>(indicator);
|
||||
out.snrDb = in.signalToNoiseRatioDb;
|
||||
out.agcLevelDb = in.agcLevelDb;
|
||||
}
|
||||
|
||||
static void convertGnssClock(GnssMeasurementsClock& in, IGnssMeasurementCallback::GnssClock& out)
|
||||
{
|
||||
memset(&out, 0, sizeof(out));
|
||||
if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_LEAP_SECOND_BIT)
|
||||
out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_LEAP_SECOND;
|
||||
if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_TIME_UNCERTAINTY_BIT)
|
||||
out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_TIME_UNCERTAINTY;
|
||||
if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_FULL_BIAS_BIT)
|
||||
out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_FULL_BIAS;
|
||||
if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_BIAS_BIT)
|
||||
out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_BIAS;
|
||||
if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_BIAS_UNCERTAINTY_BIT)
|
||||
out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_BIAS_UNCERTAINTY;
|
||||
if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_DRIFT_BIT)
|
||||
out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_DRIFT;
|
||||
if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_DRIFT_UNCERTAINTY_BIT)
|
||||
out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_DRIFT_UNCERTAINTY;
|
||||
out.leapSecond = in.leapSecond;
|
||||
out.timeNs = in.timeNs;
|
||||
out.timeUncertaintyNs = in.timeUncertaintyNs;
|
||||
out.fullBiasNs = in.fullBiasNs;
|
||||
out.biasNs = in.biasNs;
|
||||
out.biasUncertaintyNs = in.biasUncertaintyNs;
|
||||
out.driftNsps = in.driftNsps;
|
||||
out.driftUncertaintyNsps = in.driftUncertaintyNsps;
|
||||
out.hwClockDiscontinuityCount = in.hwClockDiscontinuityCount;
|
||||
}
|
||||
|
||||
static void convertGnssClock_2_1(GnssMeasurementsClock& in,
|
||||
V2_1::IGnssMeasurementCallback::GnssClock& out)
|
||||
{
|
||||
memset(&out, 0, sizeof(out));
|
||||
convertGnssClock(in, out.v1_0);
|
||||
convertGnssConstellationType(in.referenceSignalTypeForIsb.svType,
|
||||
out.referenceSignalTypeForIsb.constellation);
|
||||
out.referenceSignalTypeForIsb.carrierFrequencyHz =
|
||||
in.referenceSignalTypeForIsb.carrierFrequencyHz;
|
||||
convertGnssMeasurementsCodeType(in.referenceSignalTypeForIsb.codeType,
|
||||
in.referenceSignalTypeForIsb.otherCodeTypeName,
|
||||
out.referenceSignalTypeForIsb.codeType);
|
||||
}
|
||||
|
||||
static void convertGnssData(GnssMeasurementsNotification& in,
|
||||
V1_0::IGnssMeasurementCallback::GnssData& out)
|
||||
{
|
||||
memset(&out, 0, sizeof(out));
|
||||
out.measurementCount = in.count;
|
||||
if (out.measurementCount > static_cast<uint32_t>(V1_0::GnssMax::SVS_COUNT)) {
|
||||
LOC_LOGW("%s]: Too many measurement %u. Clamps to %d.",
|
||||
__FUNCTION__, out.measurementCount, V1_0::GnssMax::SVS_COUNT);
|
||||
out.measurementCount = static_cast<uint32_t>(V1_0::GnssMax::SVS_COUNT);
|
||||
}
|
||||
for (size_t i = 0; i < out.measurementCount; i++) {
|
||||
convertGnssMeasurement(in.measurements[i], out.measurements[i]);
|
||||
}
|
||||
convertGnssClock(in.clock, out.clock);
|
||||
}
|
||||
|
||||
static void convertGnssData_1_1(GnssMeasurementsNotification& in,
|
||||
V1_1::IGnssMeasurementCallback::GnssData& out)
|
||||
{
|
||||
memset(&out, 0, sizeof(out));
|
||||
out.measurements.resize(in.count);
|
||||
for (size_t i = 0; i < in.count; i++) {
|
||||
convertGnssMeasurement(in.measurements[i], out.measurements[i].v1_0);
|
||||
convertGnssMeasurementsAccumulatedDeltaRangeState(in.measurements[i].adrStateMask,
|
||||
out.measurements[i].accumulatedDeltaRangeState);
|
||||
}
|
||||
convertGnssClock(in.clock, out.clock);
|
||||
}
|
||||
|
||||
static void convertGnssData_2_0(GnssMeasurementsNotification& in,
|
||||
V2_0::IGnssMeasurementCallback::GnssData& out)
|
||||
{
|
||||
memset(&out, 0, sizeof(out));
|
||||
out.measurements.resize(in.count);
|
||||
for (size_t i = 0; i < in.count; i++) {
|
||||
convertGnssMeasurement(in.measurements[i], out.measurements[i].v1_1.v1_0);
|
||||
convertGnssConstellationType(in.measurements[i].svType, out.measurements[i].constellation);
|
||||
convertGnssMeasurementsCodeType(in.measurements[i].codeType,
|
||||
in.measurements[i].otherCodeTypeName,
|
||||
out.measurements[i].codeType);
|
||||
convertGnssMeasurementsAccumulatedDeltaRangeState(in.measurements[i].adrStateMask,
|
||||
out.measurements[i].v1_1.accumulatedDeltaRangeState);
|
||||
convertGnssMeasurementsState(in.measurements[i].stateMask, out.measurements[i].state);
|
||||
}
|
||||
convertGnssClock(in.clock, out.clock);
|
||||
convertElapsedRealtimeNanos(in, out.elapsedRealtime);
|
||||
}
|
||||
|
||||
static void convertGnssMeasurementsCodeType(GnssMeasurementsCodeType& inCodeType,
|
||||
char* inOtherCodeTypeName, ::android::hardware::hidl_string& out)
|
||||
{
|
||||
switch(inCodeType) {
|
||||
case GNSS_MEASUREMENTS_CODE_TYPE_A:
|
||||
out = "A";
|
||||
break;
|
||||
case GNSS_MEASUREMENTS_CODE_TYPE_B:
|
||||
out = "B";
|
||||
break;
|
||||
case GNSS_MEASUREMENTS_CODE_TYPE_C:
|
||||
out = "C";
|
||||
break;
|
||||
case GNSS_MEASUREMENTS_CODE_TYPE_I:
|
||||
out = "I";
|
||||
break;
|
||||
case GNSS_MEASUREMENTS_CODE_TYPE_L:
|
||||
out = "L";
|
||||
break;
|
||||
case GNSS_MEASUREMENTS_CODE_TYPE_M:
|
||||
out = "M";
|
||||
break;
|
||||
case GNSS_MEASUREMENTS_CODE_TYPE_P:
|
||||
out = "P";
|
||||
break;
|
||||
case GNSS_MEASUREMENTS_CODE_TYPE_Q:
|
||||
out = "Q";
|
||||
break;
|
||||
case GNSS_MEASUREMENTS_CODE_TYPE_S:
|
||||
out = "S";
|
||||
break;
|
||||
case GNSS_MEASUREMENTS_CODE_TYPE_W:
|
||||
out = "W";
|
||||
break;
|
||||
case GNSS_MEASUREMENTS_CODE_TYPE_X:
|
||||
out = "X";
|
||||
break;
|
||||
case GNSS_MEASUREMENTS_CODE_TYPE_Y:
|
||||
out = "Y";
|
||||
break;
|
||||
case GNSS_MEASUREMENTS_CODE_TYPE_Z:
|
||||
out = "Z";
|
||||
break;
|
||||
case GNSS_MEASUREMENTS_CODE_TYPE_N:
|
||||
out = "N";
|
||||
break;
|
||||
case GNSS_MEASUREMENTS_CODE_TYPE_OTHER:
|
||||
default:
|
||||
out = inOtherCodeTypeName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void convertGnssMeasurementsAccumulatedDeltaRangeState(GnssMeasurementsAdrStateMask& in,
|
||||
::android::hardware::hidl_bitfield
|
||||
<V1_1::IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState>& out)
|
||||
{
|
||||
memset(&out, 0, sizeof(out));
|
||||
if (in & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_VALID_BIT)
|
||||
out |= IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_VALID;
|
||||
if (in & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_RESET_BIT)
|
||||
out |= IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_RESET;
|
||||
if (in & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_CYCLE_SLIP_BIT)
|
||||
out |= IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_CYCLE_SLIP;
|
||||
if (in & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_HALF_CYCLE_RESOLVED_BIT)
|
||||
out |= IGnssMeasurementCallback::
|
||||
GnssAccumulatedDeltaRangeState::ADR_STATE_HALF_CYCLE_RESOLVED;
|
||||
}
|
||||
|
||||
static void convertGnssMeasurementsState(GnssMeasurementsStateMask& in,
|
||||
::android::hardware::hidl_bitfield
|
||||
<V2_0::IGnssMeasurementCallback::GnssMeasurementState>& out)
|
||||
{
|
||||
memset(&out, 0, sizeof(out));
|
||||
if (in & GNSS_MEASUREMENTS_STATE_CODE_LOCK_BIT)
|
||||
out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_CODE_LOCK;
|
||||
if (in & GNSS_MEASUREMENTS_STATE_BIT_SYNC_BIT)
|
||||
out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_BIT_SYNC;
|
||||
if (in & GNSS_MEASUREMENTS_STATE_SUBFRAME_SYNC_BIT)
|
||||
out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_SUBFRAME_SYNC;
|
||||
if (in & GNSS_MEASUREMENTS_STATE_TOW_DECODED_BIT)
|
||||
out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_TOW_DECODED;
|
||||
if (in & GNSS_MEASUREMENTS_STATE_MSEC_AMBIGUOUS_BIT)
|
||||
out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_MSEC_AMBIGUOUS;
|
||||
if (in & GNSS_MEASUREMENTS_STATE_SYMBOL_SYNC_BIT)
|
||||
out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_SYMBOL_SYNC;
|
||||
if (in & GNSS_MEASUREMENTS_STATE_GLO_STRING_SYNC_BIT)
|
||||
out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GLO_STRING_SYNC;
|
||||
if (in & GNSS_MEASUREMENTS_STATE_GLO_TOD_DECODED_BIT)
|
||||
out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GLO_TOD_DECODED;
|
||||
if (in & GNSS_MEASUREMENTS_STATE_BDS_D2_BIT_SYNC_BIT)
|
||||
out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_BDS_D2_BIT_SYNC;
|
||||
if (in & GNSS_MEASUREMENTS_STATE_BDS_D2_SUBFRAME_SYNC_BIT)
|
||||
out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_BDS_D2_SUBFRAME_SYNC;
|
||||
if (in & GNSS_MEASUREMENTS_STATE_GAL_E1BC_CODE_LOCK_BIT)
|
||||
out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GAL_E1BC_CODE_LOCK;
|
||||
if (in & GNSS_MEASUREMENTS_STATE_GAL_E1C_2ND_CODE_LOCK_BIT)
|
||||
out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GAL_E1C_2ND_CODE_LOCK;
|
||||
if (in & GNSS_MEASUREMENTS_STATE_GAL_E1B_PAGE_SYNC_BIT)
|
||||
out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GAL_E1B_PAGE_SYNC;
|
||||
if (in & GNSS_MEASUREMENTS_STATE_SBAS_SYNC_BIT)
|
||||
out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_SBAS_SYNC;
|
||||
if (in & GNSS_MEASUREMENTS_STATE_TOW_KNOWN_BIT)
|
||||
out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_TOW_KNOWN;
|
||||
if (in & GNSS_MEASUREMENTS_STATE_GLO_TOD_KNOWN_BIT)
|
||||
out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GLO_TOD_KNOWN;
|
||||
if (in & GNSS_MEASUREMENTS_STATE_2ND_CODE_LOCK_BIT)
|
||||
out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_2ND_CODE_LOCK;
|
||||
}
|
||||
|
||||
static void convertGnssData_2_1(GnssMeasurementsNotification& in,
|
||||
V2_1::IGnssMeasurementCallback::GnssData& out)
|
||||
{
|
||||
memset(&out, 0, sizeof(out));
|
||||
out.measurements.resize(in.count);
|
||||
for (size_t i = 0; i < in.count; i++) {
|
||||
out.measurements[i].flags = 0;
|
||||
convertGnssMeasurement(in.measurements[i], out.measurements[i].v2_0.v1_1.v1_0);
|
||||
convertGnssConstellationType(in.measurements[i].svType,
|
||||
out.measurements[i].v2_0.constellation);
|
||||
convertGnssMeasurementsCodeType(in.measurements[i].codeType,
|
||||
in.measurements[i].otherCodeTypeName,
|
||||
out.measurements[i].v2_0.codeType);
|
||||
convertGnssMeasurementsAccumulatedDeltaRangeState(in.measurements[i].adrStateMask,
|
||||
out.measurements[i].v2_0.v1_1.accumulatedDeltaRangeState);
|
||||
convertGnssMeasurementsState(in.measurements[i].stateMask,
|
||||
out.measurements[i].v2_0.state);
|
||||
out.measurements[i].basebandCN0DbHz = in.measurements[i].basebandCarrierToNoiseDbHz;
|
||||
|
||||
if (in.measurements[i].flags & GNSS_MEASUREMENTS_DATA_SIGNAL_TO_NOISE_RATIO_BIT) {
|
||||
out.measurements[i].flags |=
|
||||
V2_1::IGnssMeasurementCallback::GnssMeasurementFlags::HAS_SNR;
|
||||
}
|
||||
if (in.measurements[i].flags & GNSS_MEASUREMENTS_DATA_CARRIER_FREQUENCY_BIT) {
|
||||
out.measurements[i].flags |=
|
||||
V2_1::IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_FREQUENCY;
|
||||
}
|
||||
if (in.measurements[i].flags & GNSS_MEASUREMENTS_DATA_CARRIER_CYCLES_BIT) {
|
||||
out.measurements[i].flags |=
|
||||
V2_1::IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_CYCLES;
|
||||
}
|
||||
if (in.measurements[i].flags & GNSS_MEASUREMENTS_DATA_CARRIER_PHASE_BIT) {
|
||||
out.measurements[i].flags |=
|
||||
V2_1::IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_PHASE;
|
||||
}
|
||||
if (in.measurements[i].flags & GNSS_MEASUREMENTS_DATA_CARRIER_PHASE_UNCERTAINTY_BIT) {
|
||||
out.measurements[i].flags |=
|
||||
V2_1::IGnssMeasurementCallback::
|
||||
GnssMeasurementFlags::HAS_CARRIER_PHASE_UNCERTAINTY;
|
||||
}
|
||||
if (in.measurements[i].flags & GNSS_MEASUREMENTS_DATA_AUTOMATIC_GAIN_CONTROL_BIT) {
|
||||
out.measurements[i].flags |=
|
||||
V2_1::IGnssMeasurementCallback::GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL;
|
||||
}
|
||||
if (in.measurements[i].flags & GNSS_MEASUREMENTS_DATA_FULL_ISB_BIT) {
|
||||
out.measurements[i].fullInterSignalBiasNs = in.measurements[i].fullInterSignalBiasNs;
|
||||
out.measurements[i].flags |=
|
||||
V2_1::IGnssMeasurementCallback::GnssMeasurementFlags::HAS_FULL_ISB;
|
||||
}
|
||||
if (in.measurements[i].flags & GNSS_MEASUREMENTS_DATA_FULL_ISB_UNCERTAINTY_BIT) {
|
||||
out.measurements[i].fullInterSignalBiasUncertaintyNs =
|
||||
in.measurements[i].fullInterSignalBiasUncertaintyNs;
|
||||
out.measurements[i].flags |=
|
||||
V2_1::IGnssMeasurementCallback::
|
||||
GnssMeasurementFlags::HAS_FULL_ISB_UNCERTAINTY;
|
||||
}
|
||||
if (in.measurements[i].flags & GNSS_MEASUREMENTS_DATA_SATELLITE_ISB_BIT) {
|
||||
out.measurements[i].satelliteInterSignalBiasNs =
|
||||
in.measurements[i].satelliteInterSignalBiasNs;
|
||||
out.measurements[i].flags |=
|
||||
V2_1::IGnssMeasurementCallback::GnssMeasurementFlags::HAS_SATELLITE_ISB;
|
||||
}
|
||||
if (in.measurements[i].flags & GNSS_MEASUREMENTS_DATA_SATELLITE_ISB_UNCERTAINTY_BIT) {
|
||||
out.measurements[i].satelliteInterSignalBiasUncertaintyNs =
|
||||
in.measurements[i].satelliteInterSignalBiasUncertaintyNs;
|
||||
out.measurements[i].flags |=
|
||||
V2_1::IGnssMeasurementCallback::
|
||||
GnssMeasurementFlags::HAS_SATELLITE_ISB_UNCERTAINTY;
|
||||
}
|
||||
}
|
||||
convertGnssClock_2_1(in.clock, out.clock);
|
||||
convertElapsedRealtimeNanos(in, out.elapsedRealtime);
|
||||
}
|
||||
|
||||
static void convertElapsedRealtimeNanos(GnssMeasurementsNotification& in,
|
||||
::android::hardware::gnss::V2_0::ElapsedRealtime& elapsedRealtime)
|
||||
{
|
||||
if (in.clock.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_ELAPSED_REAL_TIME_BIT) {
|
||||
elapsedRealtime.flags |= V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS;
|
||||
elapsedRealtime.timestampNs = in.clock.elapsedRealTime;
|
||||
elapsedRealtime.flags |= V2_0::ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS;
|
||||
elapsedRealtime.timeUncertaintyNs = in.clock.elapsedRealTimeUnc;
|
||||
LOC_LOGd("elapsedRealtime.timestampNs=%" PRIi64 ""
|
||||
" elapsedRealtime.timeUncertaintyNs=%" PRIi64 " elapsedRealtime.flags=0x%X",
|
||||
elapsedRealtime.timestampNs,
|
||||
elapsedRealtime.timeUncertaintyNs, elapsedRealtime.flags);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_1
|
||||
} // namespace gnss
|
||||
} // namespace hardware
|
||||
} // namespace android
|
96
gps/android/2.1/location_api/MeasurementAPIClient.h
Normal file
96
gps/android/2.1/location_api/MeasurementAPIClient.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/* 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 MEASUREMENT_API_CLINET_H
|
||||
#define MEASUREMENT_API_CLINET_H
|
||||
|
||||
#include <mutex>
|
||||
#include <android/hardware/gnss/2.1/IGnssMeasurement.h>
|
||||
//#include <android/hardware/gnss/1.1/IGnssMeasurementCallback.h>
|
||||
#include <android/hardware/gnss/2.1/IGnssMeasurementCallback.h>
|
||||
#include <LocationAPIClientBase.h>
|
||||
#include <hidl/Status.h>
|
||||
#include <gps_extended_c.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace gnss {
|
||||
namespace V2_1 {
|
||||
namespace implementation {
|
||||
|
||||
using ::android::sp;
|
||||
|
||||
class MeasurementAPIClient : public LocationAPIClientBase
|
||||
{
|
||||
public:
|
||||
MeasurementAPIClient();
|
||||
MeasurementAPIClient(const MeasurementAPIClient&) = delete;
|
||||
MeasurementAPIClient& operator=(const MeasurementAPIClient&) = delete;
|
||||
|
||||
// for GpsMeasurementInterface
|
||||
Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> measurementSetCallback(
|
||||
const sp<V1_0::IGnssMeasurementCallback>& callback);
|
||||
Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> measurementSetCallback_1_1(
|
||||
const sp<V1_1::IGnssMeasurementCallback>& callback,
|
||||
GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID,
|
||||
uint32_t timeBetweenMeasurement = GPS_DEFAULT_FIX_INTERVAL_MS);
|
||||
Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> measurementSetCallback_2_0(
|
||||
const sp<V2_0::IGnssMeasurementCallback>& callback,
|
||||
GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID,
|
||||
uint32_t timeBetweenMeasurement = GPS_DEFAULT_FIX_INTERVAL_MS);
|
||||
Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> measurementSetCallback_2_1(
|
||||
const sp<V2_1::IGnssMeasurementCallback>& callback,
|
||||
GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID,
|
||||
uint32_t timeBetweenMeasurement = GPS_DEFAULT_FIX_INTERVAL_MS);
|
||||
void measurementClose();
|
||||
Return<IGnssMeasurement::GnssMeasurementStatus> startTracking(
|
||||
GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID,
|
||||
uint32_t timeBetweenMeasurement = GPS_DEFAULT_FIX_INTERVAL_MS);
|
||||
|
||||
// callbacks we are interested in
|
||||
void onGnssMeasurementsCb(GnssMeasurementsNotification gnssMeasurementsNotification) final;
|
||||
|
||||
private:
|
||||
virtual ~MeasurementAPIClient();
|
||||
|
||||
std::mutex mMutex;
|
||||
sp<V1_0::IGnssMeasurementCallback> mGnssMeasurementCbIface;
|
||||
sp<V1_1::IGnssMeasurementCallback> mGnssMeasurementCbIface_1_1;
|
||||
sp<V2_0::IGnssMeasurementCallback> mGnssMeasurementCbIface_2_0;
|
||||
sp<V2_1::IGnssMeasurementCallback> mGnssMeasurementCbIface_2_1;
|
||||
bool mTracking;
|
||||
void clearInterfaces();
|
||||
};
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_1
|
||||
} // namespace gnss
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
#endif // MEASUREMENT_API_CLINET_H
|
Reference in New Issue
Block a user