wayne: Import GPS
* QC Tag: LA.UM.6.2.r1-06100-sdm660.0 Change-Id: I26da3b90caa473ed5f88408627463ec7f7655f23 Signed-off-by: Isaac Chen <isaacchen@isaacchen.cn>
This commit is contained in:
parent
71ad0c9e53
commit
6a15b2379f
158 changed files with 32010 additions and 0 deletions
5
gps/Android.mk
Normal file
5
gps/Android.mk
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)
|
||||||
|
LOCAL_PATH := $(call my-dir)
|
||||||
|
|
||||||
|
include $(call all-makefiles-under,$(LOCAL_PATH))
|
||||||
|
endif
|
50
gps/CleanSpec.mk
Normal file
50
gps/CleanSpec.mk
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
# Copyright (C) 2007 The Android Open Source Project
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
# If you don't need to do a full clean build but would like to touch
|
||||||
|
# a file or delete some intermediate files, add a clean step to the end
|
||||||
|
# of the list. These steps will only be run once, if they haven't been
|
||||||
|
# run before.
|
||||||
|
#
|
||||||
|
# E.g.:
|
||||||
|
# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
|
||||||
|
# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
|
||||||
|
#
|
||||||
|
# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
|
||||||
|
# files that are missing or have been moved.
|
||||||
|
#
|
||||||
|
# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
|
||||||
|
# Use $(OUT_DIR) to refer to the "out" directory.
|
||||||
|
#
|
||||||
|
# If you need to re-do something that's already mentioned, just copy
|
||||||
|
# the command and add it to the bottom of the list. E.g., if a change
|
||||||
|
# that you made last week required touching a file and a change you
|
||||||
|
# made today requires touching the same file, just copy the old
|
||||||
|
# touch step and add it to the end of the list.
|
||||||
|
#
|
||||||
|
# ************************************************
|
||||||
|
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
|
||||||
|
# ************************************************
|
||||||
|
|
||||||
|
# For example:
|
||||||
|
#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
|
||||||
|
#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
|
||||||
|
#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
|
||||||
|
#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
|
||||||
|
|
||||||
|
# ************************************************
|
||||||
|
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
|
||||||
|
# ************************************************
|
||||||
|
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libloc_api*)
|
10
gps/Makefile.am
Normal file
10
gps/Makefile.am
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# Makefile.am - Automake script for gps loc_api
|
||||||
|
#
|
||||||
|
|
||||||
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
|
|
||||||
|
SUBDIRS = core location gnss
|
||||||
|
|
||||||
|
pkgconfigdir = $(libdir)/pkgconfig
|
||||||
|
pkgconfig_DATA = loc-hal.pc
|
||||||
|
EXTRA_DIST = $(pkgconfig_DATA)
|
188
gps/android/AGnss.cpp
Normal file
188
gps/android/AGnss.cpp
Normal file
|
@ -0,0 +1,188 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
* Not a Contribution
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LOG_TAG "LocSvc_AGnssInterface"
|
||||||
|
|
||||||
|
#include <log_util.h>
|
||||||
|
#include "Gnss.h"
|
||||||
|
#include "AGnss.h"
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
namespace hardware {
|
||||||
|
namespace gnss {
|
||||||
|
namespace V1_0 {
|
||||||
|
namespace implementation {
|
||||||
|
|
||||||
|
sp<IAGnssCallback> AGnss::sAGnssCbIface = nullptr;
|
||||||
|
|
||||||
|
AGnss::AGnss(Gnss* gnss) : mGnss(gnss) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void AGnss::agnssStatusIpV4Cb(AGnssExtStatusIpV4 status){
|
||||||
|
IAGnssCallback::AGnssStatusIpV4 st = {};
|
||||||
|
|
||||||
|
switch (status.type) {
|
||||||
|
case LOC_AGPS_TYPE_SUPL:
|
||||||
|
st.type = IAGnssCallback::AGnssType::TYPE_SUPL;
|
||||||
|
break;
|
||||||
|
case LOC_AGPS_TYPE_C2K:
|
||||||
|
st.type = IAGnssCallback::AGnssType::TYPE_C2K;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOC_LOGE("invalid type: %d", status.type);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (status.status) {
|
||||||
|
case LOC_GPS_REQUEST_AGPS_DATA_CONN:
|
||||||
|
st.status = IAGnssCallback::AGnssStatusValue::REQUEST_AGNSS_DATA_CONN;
|
||||||
|
break;
|
||||||
|
case LOC_GPS_RELEASE_AGPS_DATA_CONN:
|
||||||
|
st.status = IAGnssCallback::AGnssStatusValue::RELEASE_AGNSS_DATA_CONN;
|
||||||
|
break;
|
||||||
|
case LOC_GPS_AGPS_DATA_CONNECTED:
|
||||||
|
st.status = IAGnssCallback::AGnssStatusValue::AGNSS_DATA_CONNECTED;
|
||||||
|
break;
|
||||||
|
case LOC_GPS_AGPS_DATA_CONN_DONE:
|
||||||
|
st.status = IAGnssCallback::AGnssStatusValue::AGNSS_DATA_CONN_DONE;
|
||||||
|
break;
|
||||||
|
case LOC_GPS_AGPS_DATA_CONN_FAILED:
|
||||||
|
st.status = IAGnssCallback::AGnssStatusValue::AGNSS_DATA_CONN_FAILED;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOC_LOGE("invalid status: %d", status.status);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
st.ipV4Addr = status.ipV4Addr;
|
||||||
|
|
||||||
|
auto r = sAGnssCbIface->agnssStatusIpV4Cb(st);
|
||||||
|
if (!r.isOk()) {
|
||||||
|
LOC_LOGE("Error invoking AGNSS status cb %s", r.description().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<void> AGnss::setCallback(const sp<IAGnssCallback>& callback) {
|
||||||
|
|
||||||
|
if(mGnss == nullptr || mGnss->getGnssInterface() == nullptr){
|
||||||
|
LOC_LOGE("Null GNSS interface");
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the interface
|
||||||
|
sAGnssCbIface = callback;
|
||||||
|
|
||||||
|
AgpsCbInfo cbInfo = {};
|
||||||
|
cbInfo.statusV4Cb = (void*)agnssStatusIpV4Cb;
|
||||||
|
cbInfo.cbPriority = AGPS_CB_PRIORITY_LOW;
|
||||||
|
|
||||||
|
mGnss->getGnssInterface()->agpsInit(cbInfo);
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<bool> AGnss::dataConnClosed() {
|
||||||
|
|
||||||
|
if(mGnss == nullptr || mGnss->getGnssInterface() == nullptr){
|
||||||
|
LOC_LOGE("Null GNSS interface");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mGnss->getGnssInterface()->agpsDataConnClosed(LOC_AGPS_TYPE_SUPL);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<bool> AGnss::dataConnFailed() {
|
||||||
|
|
||||||
|
if(mGnss == nullptr || mGnss->getGnssInterface() == nullptr){
|
||||||
|
LOC_LOGE("Null GNSS interface");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mGnss->getGnssInterface()->agpsDataConnFailed(LOC_AGPS_TYPE_SUPL);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<bool> AGnss::dataConnOpen(const hidl_string& apn,
|
||||||
|
IAGnss::ApnIpType apnIpType) {
|
||||||
|
|
||||||
|
if(mGnss == nullptr || mGnss->getGnssInterface() == nullptr){
|
||||||
|
LOC_LOGE("Null GNSS interface");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate */
|
||||||
|
if(apn.empty()){
|
||||||
|
LOC_LOGE("Invalid APN");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOC_LOGD("dataConnOpen APN name = [%s]", apn.c_str());
|
||||||
|
|
||||||
|
AGpsBearerType bearerType;
|
||||||
|
switch (apnIpType) {
|
||||||
|
case IAGnss::ApnIpType::IPV4:
|
||||||
|
bearerType = AGPS_APN_BEARER_IPV4;
|
||||||
|
break;
|
||||||
|
case IAGnss::ApnIpType::IPV6:
|
||||||
|
bearerType = AGPS_APN_BEARER_IPV6;
|
||||||
|
break;
|
||||||
|
case IAGnss::ApnIpType::IPV4V6:
|
||||||
|
bearerType = AGPS_APN_BEARER_IPV4V6;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
bearerType = AGPS_APN_BEARER_IPV4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
mGnss->getGnssInterface()->agpsDataConnOpen(
|
||||||
|
LOC_AGPS_TYPE_SUPL, apn.c_str(), apn.size(), (int)bearerType);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<bool> AGnss::setServer(IAGnssCallback::AGnssType type,
|
||||||
|
const hidl_string& hostname,
|
||||||
|
int32_t port) {
|
||||||
|
if (mGnss == nullptr) {
|
||||||
|
LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GnssConfig config;
|
||||||
|
memset(&config, 0, sizeof(GnssConfig));
|
||||||
|
config.size = sizeof(GnssConfig);
|
||||||
|
config.flags = GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT;
|
||||||
|
config.assistanceServer.size = sizeof(GnssConfigSetAssistanceServer);
|
||||||
|
if (type == IAGnssCallback::AGnssType::TYPE_SUPL) {
|
||||||
|
config.assistanceServer.type = GNSS_ASSISTANCE_TYPE_SUPL;
|
||||||
|
} else if (type == IAGnssCallback::AGnssType::TYPE_C2K) {
|
||||||
|
config.assistanceServer.type = GNSS_ASSISTANCE_TYPE_C2K;
|
||||||
|
} else {
|
||||||
|
LOC_LOGE("%s]: invalid AGnssType: %d", __FUNCTION__, static_cast<int>(type));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
config.assistanceServer.hostName = strdup(hostname.c_str());
|
||||||
|
config.assistanceServer.port = port;
|
||||||
|
return mGnss->updateConfiguration(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace implementation
|
||||||
|
} // namespace V1_0
|
||||||
|
} // namespace gnss
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
77
gps/android/AGnss.h
Normal file
77
gps/android/AGnss.h
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
* Not a Contribution
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ANDROID_HARDWARE_GNSS_V1_1_AGNSS_H
|
||||||
|
#define ANDROID_HARDWARE_GNSS_V1_1_AGNSS_H
|
||||||
|
|
||||||
|
#include <android/hardware/gnss/1.0/IAGnss.h>
|
||||||
|
#include <hidl/Status.h>
|
||||||
|
#include <gps_extended_c.h>
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
namespace hardware {
|
||||||
|
namespace gnss {
|
||||||
|
namespace V1_0 {
|
||||||
|
namespace implementation {
|
||||||
|
|
||||||
|
using ::android::hardware::gnss::V1_0::IAGnss;
|
||||||
|
using ::android::hardware::gnss::V1_0::IAGnssCallback;
|
||||||
|
using ::android::hardware::Return;
|
||||||
|
using ::android::hardware::Void;
|
||||||
|
using ::android::hardware::hidl_vec;
|
||||||
|
using ::android::hardware::hidl_string;
|
||||||
|
using ::android::sp;
|
||||||
|
|
||||||
|
struct Gnss;
|
||||||
|
struct AGnss : public IAGnss {
|
||||||
|
|
||||||
|
AGnss(Gnss* gnss);
|
||||||
|
~AGnss() = default;
|
||||||
|
/*
|
||||||
|
* Methods from ::android::hardware::gnss::V1_0::IAGnss interface follow.
|
||||||
|
* These declarations were generated from IAGnss.hal.
|
||||||
|
*/
|
||||||
|
Return<void> setCallback(const sp<IAGnssCallback>& callback) override;
|
||||||
|
|
||||||
|
Return<bool> dataConnClosed() override;
|
||||||
|
|
||||||
|
Return<bool> dataConnFailed() override;
|
||||||
|
|
||||||
|
Return<bool> dataConnOpen(const hidl_string& apn,
|
||||||
|
IAGnss::ApnIpType apnIpType) override;
|
||||||
|
|
||||||
|
Return<bool> setServer(IAGnssCallback::AGnssType type,
|
||||||
|
const hidl_string& hostname, int32_t port) override;
|
||||||
|
|
||||||
|
/* Data call setup callback passed down to GNSS HAL implementation */
|
||||||
|
static void agnssStatusIpV4Cb(AGnssExtStatusIpV4 status);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Gnss* mGnss = nullptr;
|
||||||
|
static sp<IAGnssCallback> sAGnssCbIface;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace implementation
|
||||||
|
} // namespace V1_0
|
||||||
|
} // namespace gnss
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
||||||
|
|
||||||
|
#endif // ANDROID_HARDWARE_GNSS_V1_1_AGNSS_H
|
93
gps/android/AGnssRil.cpp
Normal file
93
gps/android/AGnssRil.cpp
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
* Not a Contribution
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LOG_TAG "LocSvc__AGnssRilInterface"
|
||||||
|
|
||||||
|
#include <log_util.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include "Gnss.h"
|
||||||
|
#include "AGnssRil.h"
|
||||||
|
#include <DataItemConcreteTypesBase.h>
|
||||||
|
|
||||||
|
typedef void* (getLocationInterface)();
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
namespace hardware {
|
||||||
|
namespace gnss {
|
||||||
|
namespace V1_0 {
|
||||||
|
namespace implementation {
|
||||||
|
|
||||||
|
|
||||||
|
AGnssRil::AGnssRil(Gnss* gnss) : mGnss(gnss) {
|
||||||
|
ENTRY_LOG_CALLFLOW();
|
||||||
|
}
|
||||||
|
|
||||||
|
AGnssRil::~AGnssRil() {
|
||||||
|
ENTRY_LOG_CALLFLOW();
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<bool> AGnssRil::updateNetworkState(bool connected, NetworkType type, bool /*roaming*/) {
|
||||||
|
ENTRY_LOG_CALLFLOW();
|
||||||
|
|
||||||
|
// for XTRA
|
||||||
|
if (nullptr != mGnss && ( nullptr != mGnss->getGnssInterface() )) {
|
||||||
|
int8_t typeout = loc_core::NetworkInfoDataItemBase::TYPE_UNKNOWN;
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
case IAGnssRil::NetworkType::MOBILE:
|
||||||
|
typeout = loc_core::NetworkInfoDataItemBase::TYPE_MOBILE;
|
||||||
|
break;
|
||||||
|
case IAGnssRil::NetworkType::WIFI:
|
||||||
|
typeout = loc_core::NetworkInfoDataItemBase::TYPE_WIFI;
|
||||||
|
break;
|
||||||
|
case IAGnssRil::NetworkType::MMS:
|
||||||
|
typeout = loc_core::NetworkInfoDataItemBase::TYPE_MMS;
|
||||||
|
break;
|
||||||
|
case IAGnssRil::NetworkType::SUPL:
|
||||||
|
typeout = loc_core::NetworkInfoDataItemBase::TYPE_SUPL;
|
||||||
|
break;
|
||||||
|
case IAGnssRil::NetworkType::DUN:
|
||||||
|
typeout = loc_core::NetworkInfoDataItemBase::TYPE_DUN;
|
||||||
|
break;
|
||||||
|
case IAGnssRil::NetworkType::HIPRI:
|
||||||
|
typeout = loc_core::NetworkInfoDataItemBase::TYPE_HIPRI;
|
||||||
|
break;
|
||||||
|
case IAGnssRil::NetworkType::WIMAX:
|
||||||
|
typeout = loc_core::NetworkInfoDataItemBase::TYPE_WIMAX;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
typeout = loc_core::NetworkInfoDataItemBase::TYPE_UNKNOWN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mGnss->getGnssInterface()->updateConnectionStatus(connected, typeout);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace implementation
|
||||||
|
} // namespace V1_0
|
||||||
|
} // namespace gnss
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
83
gps/android/AGnssRil.h
Normal file
83
gps/android/AGnssRil.h
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
* Not a Contribution
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ANDROID_HARDWARE_GNSS_V1_0_AGNSSRIL_H_
|
||||||
|
#define ANDROID_HARDWARE_GNSS_V1_0_AGNSSRIL_H_
|
||||||
|
|
||||||
|
#include <android/hardware/gnss/1.0/IAGnssRil.h>
|
||||||
|
#include <hidl/Status.h>
|
||||||
|
#include <location_interface.h>
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
namespace hardware {
|
||||||
|
namespace gnss {
|
||||||
|
namespace V1_0 {
|
||||||
|
namespace implementation {
|
||||||
|
|
||||||
|
using ::android::hardware::gnss::V1_0::IAGnssRil;
|
||||||
|
using ::android::hardware::gnss::V1_0::IAGnssRilCallback;
|
||||||
|
using ::android::hardware::Return;
|
||||||
|
using ::android::hardware::Void;
|
||||||
|
using ::android::hardware::hidl_vec;
|
||||||
|
using ::android::hardware::hidl_string;
|
||||||
|
using ::android::sp;
|
||||||
|
|
||||||
|
struct Gnss;
|
||||||
|
/*
|
||||||
|
* Extended interface for AGNSS RIL support. An Assisted GNSS Radio Interface Layer interface
|
||||||
|
* allows the GNSS chipset to request radio interface layer information from Android platform.
|
||||||
|
* Examples of such information are reference location, unique subscriber ID, phone number string
|
||||||
|
* and network availability changes. Also contains wrapper methods to allow methods from
|
||||||
|
* IAGnssiRilCallback interface to be passed into the conventional implementation of the GNSS HAL.
|
||||||
|
*/
|
||||||
|
struct AGnssRil : public IAGnssRil {
|
||||||
|
AGnssRil(Gnss* gnss);
|
||||||
|
~AGnssRil();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Methods from ::android::hardware::gnss::V1_0::IAGnssRil follow.
|
||||||
|
* These declarations were generated from IAGnssRil.hal.
|
||||||
|
*/
|
||||||
|
Return<void> setCallback(const sp<IAGnssRilCallback>& /*callback*/) override {
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
Return<void> setRefLocation(const IAGnssRil::AGnssRefLocation& /*agnssReflocation*/) override {
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
Return<bool> setSetId(IAGnssRil::SetIDType /*type*/, const hidl_string& /*setid*/) override {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Return<bool> updateNetworkAvailability(bool /*available*/,
|
||||||
|
const hidl_string& /*apn*/) override {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Return<bool> updateNetworkState(bool connected, NetworkType type, bool roaming) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Gnss* mGnss = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace implementation
|
||||||
|
} // namespace V1_0
|
||||||
|
} // namespace gnss
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
||||||
|
|
||||||
|
#endif // ANDROID_HARDWARE_GNSS_V1_0_AGNSSRIL_H_
|
96
gps/android/Android.mk
Normal file
96
gps/android/Android.mk
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
LOCAL_PATH := $(call my-dir)
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
LOCAL_MODULE := android.hardware.gnss@1.0-impl-qti
|
||||||
|
LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib
|
||||||
|
LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64
|
||||||
|
LOCAL_MODULE_RELATIVE_PATH := hw
|
||||||
|
LOCAL_SRC_FILES := \
|
||||||
|
AGnss.cpp \
|
||||||
|
Gnss.cpp \
|
||||||
|
GnssBatching.cpp \
|
||||||
|
GnssGeofencing.cpp \
|
||||||
|
GnssMeasurement.cpp \
|
||||||
|
GnssNi.cpp \
|
||||||
|
GnssConfiguration.cpp \
|
||||||
|
GnssDebug.cpp \
|
||||||
|
AGnssRil.cpp
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES += \
|
||||||
|
location_api/LocationUtil.cpp \
|
||||||
|
location_api/GnssAPIClient.cpp \
|
||||||
|
location_api/GeofenceAPIClient.cpp \
|
||||||
|
location_api/BatchingAPIClient.cpp \
|
||||||
|
location_api/MeasurementAPIClient.cpp \
|
||||||
|
|
||||||
|
LOCAL_C_INCLUDES:= \
|
||||||
|
$(LOCAL_PATH)/location_api
|
||||||
|
LOCAL_HEADER_LIBRARIES := \
|
||||||
|
libgps.utils_headers \
|
||||||
|
libloc_core_headers \
|
||||||
|
libloc_pla_headers \
|
||||||
|
liblocation_api_headers
|
||||||
|
|
||||||
|
LOCAL_SHARED_LIBRARIES := \
|
||||||
|
liblog \
|
||||||
|
libhidlbase \
|
||||||
|
libhidltransport \
|
||||||
|
libhwbinder \
|
||||||
|
libutils \
|
||||||
|
android.hardware.gnss@1.0 \
|
||||||
|
|
||||||
|
LOCAL_SHARED_LIBRARIES += \
|
||||||
|
libloc_core \
|
||||||
|
libgps.utils \
|
||||||
|
libdl \
|
||||||
|
libloc_pla \
|
||||||
|
liblocation_api \
|
||||||
|
|
||||||
|
LOCAL_CFLAGS += $(GNSS_CFLAGS)
|
||||||
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
|
|
||||||
|
BUILD_GNSS_HIDL_SERVICE := true
|
||||||
|
ifneq ($(BOARD_VENDOR_QCOM_LOC_PDK_FEATURE_SET), true)
|
||||||
|
ifneq ($(LW_FEATURE_SET),true)
|
||||||
|
ifneq ($(TARGET_HAS_LOW_RAM),true)
|
||||||
|
BUILD_GNSS_HIDL_SERVICE := false
|
||||||
|
endif # TARGET_HAS_LOW_RAM
|
||||||
|
endif # LW_FEATURE_SET
|
||||||
|
endif # BOARD_VENDOR_QCOM_LOC_PDK_FEATURE_SET
|
||||||
|
|
||||||
|
ifeq ($(BUILD_GNSS_HIDL_SERVICE), true)
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
LOCAL_MODULE := android.hardware.gnss@1.0-service-qti
|
||||||
|
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_EXECUTABLES)
|
||||||
|
LOCAL_MODULE_RELATIVE_PATH := hw
|
||||||
|
LOCAL_VENDOR_MODULE := true
|
||||||
|
LOCAL_MODULE_OWNER := qti
|
||||||
|
LOCAL_INIT_RC := android.hardware.gnss@1.0-service-qti.rc
|
||||||
|
LOCAL_SRC_FILES := \
|
||||||
|
service.cpp \
|
||||||
|
|
||||||
|
LOCAL_C_INCLUDES:= \
|
||||||
|
$(LOCAL_PATH)/location_api
|
||||||
|
LOCAL_HEADER_LIBRARIES := \
|
||||||
|
libgps.utils_headers \
|
||||||
|
libloc_core_headers \
|
||||||
|
libloc_pla_headers \
|
||||||
|
liblocation_api_headers
|
||||||
|
|
||||||
|
|
||||||
|
LOCAL_SHARED_LIBRARIES := \
|
||||||
|
liblog \
|
||||||
|
libcutils \
|
||||||
|
libdl \
|
||||||
|
libbase \
|
||||||
|
libutils \
|
||||||
|
|
||||||
|
LOCAL_SHARED_LIBRARIES += \
|
||||||
|
libhwbinder \
|
||||||
|
libhidlbase \
|
||||||
|
libhidltransport \
|
||||||
|
android.hardware.gnss@1.0 \
|
||||||
|
|
||||||
|
LOCAL_CFLAGS += $(GNSS_CFLAGS)
|
||||||
|
include $(BUILD_EXECUTABLE)
|
||||||
|
endif # BUILD_GNSS_HIDL_SERVICE
|
338
gps/android/Gnss.cpp
Normal file
338
gps/android/Gnss.cpp
Normal file
|
@ -0,0 +1,338 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
* Not a Contribution
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LOG_TAG "LocSvc_GnssInterface"
|
||||||
|
|
||||||
|
#include <log_util.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include "Gnss.h"
|
||||||
|
typedef void* (getLocationInterface)();
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
namespace hardware {
|
||||||
|
namespace gnss {
|
||||||
|
namespace V1_0 {
|
||||||
|
namespace implementation {
|
||||||
|
|
||||||
|
void Gnss::GnssDeathRecipient::serviceDied(uint64_t cookie, const wp<IBase>& who) {
|
||||||
|
LOC_LOGE("%s] service died. cookie: %llu, who: %p",
|
||||||
|
__FUNCTION__, static_cast<unsigned long long>(cookie), &who);
|
||||||
|
if (mGnss != nullptr) {
|
||||||
|
mGnss->stop();
|
||||||
|
mGnss->cleanup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Gnss::Gnss() {
|
||||||
|
ENTRY_LOG_CALLFLOW();
|
||||||
|
// clear pending GnssConfig
|
||||||
|
memset(&mPendingConfig, 0, sizeof(GnssConfig));
|
||||||
|
|
||||||
|
mGnssDeathRecipient = new GnssDeathRecipient(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
Gnss::~Gnss() {
|
||||||
|
ENTRY_LOG_CALLFLOW();
|
||||||
|
if (mApi != nullptr) {
|
||||||
|
delete mApi;
|
||||||
|
mApi = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GnssAPIClient* Gnss::getApi() {
|
||||||
|
if (mApi == nullptr && (mGnssCbIface != nullptr || mGnssNiCbIface != nullptr)) {
|
||||||
|
mApi = new GnssAPIClient(mGnssCbIface, mGnssNiCbIface);
|
||||||
|
if (mApi == nullptr) {
|
||||||
|
LOC_LOGE("%s] faild to create GnssAPIClient", __FUNCTION__);
|
||||||
|
return mApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mPendingConfig.size == sizeof(GnssConfig)) {
|
||||||
|
// we have pending GnssConfig
|
||||||
|
mApi->gnssConfigurationUpdate(mPendingConfig);
|
||||||
|
// clear size to invalid mPendingConfig
|
||||||
|
mPendingConfig.size = 0;
|
||||||
|
if (mPendingConfig.assistanceServer.hostName != nullptr) {
|
||||||
|
free((void*)mPendingConfig.assistanceServer.hostName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mApi == nullptr) {
|
||||||
|
LOC_LOGW("%s] GnssAPIClient is not ready", __FUNCTION__);
|
||||||
|
}
|
||||||
|
return mApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
GnssInterface* Gnss::getGnssInterface() {
|
||||||
|
static bool getGnssInterfaceFailed = false;
|
||||||
|
if (nullptr == mGnssInterface && !getGnssInterfaceFailed) {
|
||||||
|
LOC_LOGD("%s]: loading libgnss.so::getGnssInterface ...", __func__);
|
||||||
|
getLocationInterface* getter = NULL;
|
||||||
|
const char *error = NULL;
|
||||||
|
dlerror();
|
||||||
|
void *handle = dlopen("libgnss.so", RTLD_NOW);
|
||||||
|
if (NULL == handle || (error = dlerror()) != NULL) {
|
||||||
|
LOC_LOGW("dlopen for libgnss.so failed, error = %s", error);
|
||||||
|
} else {
|
||||||
|
getter = (getLocationInterface*)dlsym(handle, "getGnssInterface");
|
||||||
|
if ((error = dlerror()) != NULL) {
|
||||||
|
LOC_LOGW("dlsym for libgnss.so::getGnssInterface failed, error = %s", error);
|
||||||
|
getter = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NULL == getter) {
|
||||||
|
getGnssInterfaceFailed = true;
|
||||||
|
} else {
|
||||||
|
mGnssInterface = (GnssInterface*)(*getter)();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mGnssInterface;
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<bool> Gnss::setCallback(const sp<IGnssCallback>& callback) {
|
||||||
|
ENTRY_LOG_CALLFLOW();
|
||||||
|
if (mGnssCbIface != nullptr) {
|
||||||
|
mGnssCbIface->unlinkToDeath(mGnssDeathRecipient);
|
||||||
|
}
|
||||||
|
mGnssCbIface = callback;
|
||||||
|
if (mGnssCbIface != nullptr) {
|
||||||
|
mGnssCbIface->linkToDeath(mGnssDeathRecipient, 0 /*cookie*/);
|
||||||
|
}
|
||||||
|
|
||||||
|
GnssAPIClient* api = getApi();
|
||||||
|
if (api != nullptr) {
|
||||||
|
api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface);
|
||||||
|
api->gnssEnable(LOCATION_TECHNOLOGY_TYPE_GNSS);
|
||||||
|
api->requestCapabilities();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<bool> Gnss::setGnssNiCb(const sp<IGnssNiCallback>& callback) {
|
||||||
|
ENTRY_LOG_CALLFLOW();
|
||||||
|
mGnssNiCbIface = callback;
|
||||||
|
GnssAPIClient* api = getApi();
|
||||||
|
if (api != nullptr) {
|
||||||
|
api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<bool> Gnss::updateConfiguration(GnssConfig& gnssConfig) {
|
||||||
|
ENTRY_LOG_CALLFLOW();
|
||||||
|
GnssAPIClient* api = getApi();
|
||||||
|
if (api) {
|
||||||
|
api->gnssConfigurationUpdate(gnssConfig);
|
||||||
|
} else if (gnssConfig.flags != 0) {
|
||||||
|
// api is not ready yet, update mPendingConfig with gnssConfig
|
||||||
|
mPendingConfig.size = sizeof(GnssConfig);
|
||||||
|
|
||||||
|
if (gnssConfig.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) {
|
||||||
|
mPendingConfig.flags |= GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT;
|
||||||
|
mPendingConfig.gpsLock = gnssConfig.gpsLock;
|
||||||
|
}
|
||||||
|
if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) {
|
||||||
|
mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT;
|
||||||
|
mPendingConfig.suplVersion = gnssConfig.suplVersion;
|
||||||
|
}
|
||||||
|
if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT) {
|
||||||
|
mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT;
|
||||||
|
mPendingConfig.assistanceServer.size = sizeof(GnssConfigSetAssistanceServer);
|
||||||
|
mPendingConfig.assistanceServer.type = gnssConfig.assistanceServer.type;
|
||||||
|
if (mPendingConfig.assistanceServer.hostName != nullptr) {
|
||||||
|
free((void*)mPendingConfig.assistanceServer.hostName);
|
||||||
|
mPendingConfig.assistanceServer.hostName =
|
||||||
|
strdup(gnssConfig.assistanceServer.hostName);
|
||||||
|
}
|
||||||
|
mPendingConfig.assistanceServer.port = gnssConfig.assistanceServer.port;
|
||||||
|
}
|
||||||
|
if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
|
||||||
|
mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT;
|
||||||
|
mPendingConfig.lppProfile = gnssConfig.lppProfile;
|
||||||
|
}
|
||||||
|
if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
|
||||||
|
mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT;
|
||||||
|
mPendingConfig.lppeControlPlaneMask = gnssConfig.lppeControlPlaneMask;
|
||||||
|
}
|
||||||
|
if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT) {
|
||||||
|
mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT;
|
||||||
|
mPendingConfig.lppeUserPlaneMask = gnssConfig.lppeUserPlaneMask;
|
||||||
|
}
|
||||||
|
if (gnssConfig.flags & GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT) {
|
||||||
|
mPendingConfig.flags |= GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT;
|
||||||
|
mPendingConfig.aGlonassPositionProtocolMask = gnssConfig.aGlonassPositionProtocolMask;
|
||||||
|
}
|
||||||
|
if (gnssConfig.flags & GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT) {
|
||||||
|
mPendingConfig.flags |= GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT;
|
||||||
|
mPendingConfig.emergencyPdnForEmergencySupl = gnssConfig.emergencyPdnForEmergencySupl;
|
||||||
|
}
|
||||||
|
if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT) {
|
||||||
|
mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT;
|
||||||
|
mPendingConfig.suplEmergencyServices = gnssConfig.suplEmergencyServices;
|
||||||
|
}
|
||||||
|
if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_MODE_BIT) {
|
||||||
|
mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_MODE_BIT;
|
||||||
|
mPendingConfig.suplModeMask = gnssConfig.suplModeMask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<bool> Gnss::start() {
|
||||||
|
ENTRY_LOG_CALLFLOW();
|
||||||
|
bool retVal = false;
|
||||||
|
GnssAPIClient* api = getApi();
|
||||||
|
if (api) {
|
||||||
|
retVal = api->gnssStart();
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<bool> Gnss::stop() {
|
||||||
|
ENTRY_LOG_CALLFLOW();
|
||||||
|
bool retVal = false;
|
||||||
|
GnssAPIClient* api = getApi();
|
||||||
|
if (api) {
|
||||||
|
retVal = api->gnssStop();
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<void> Gnss::cleanup() {
|
||||||
|
ENTRY_LOG_CALLFLOW();
|
||||||
|
|
||||||
|
if (mApi != nullptr) {
|
||||||
|
mApi->gnssDisable();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<bool> Gnss::injectLocation(double latitudeDegrees,
|
||||||
|
double longitudeDegrees,
|
||||||
|
float accuracyMeters) {
|
||||||
|
ENTRY_LOG_CALLFLOW();
|
||||||
|
GnssInterface* gnssInterface = getGnssInterface();
|
||||||
|
if (nullptr != gnssInterface) {
|
||||||
|
gnssInterface->injectLocation(latitudeDegrees, longitudeDegrees, accuracyMeters);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<bool> Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs,
|
||||||
|
int32_t uncertaintyMs) {
|
||||||
|
ENTRY_LOG_CALLFLOW();
|
||||||
|
GnssInterface* gnssInterface = getGnssInterface();
|
||||||
|
if (nullptr != gnssInterface) {
|
||||||
|
gnssInterface->injectTime(timeMs, timeReferenceMs, uncertaintyMs);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<void> Gnss::deleteAidingData(IGnss::GnssAidingData aidingDataFlags) {
|
||||||
|
ENTRY_LOG_CALLFLOW();
|
||||||
|
GnssAPIClient* api = getApi();
|
||||||
|
if (api) {
|
||||||
|
api->gnssDeleteAidingData(aidingDataFlags);
|
||||||
|
}
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<bool> Gnss::setPositionMode(IGnss::GnssPositionMode mode,
|
||||||
|
IGnss::GnssPositionRecurrence recurrence,
|
||||||
|
uint32_t minIntervalMs,
|
||||||
|
uint32_t preferredAccuracyMeters,
|
||||||
|
uint32_t preferredTimeMs) {
|
||||||
|
ENTRY_LOG_CALLFLOW();
|
||||||
|
bool retVal = false;
|
||||||
|
GnssAPIClient* api = getApi();
|
||||||
|
if (api) {
|
||||||
|
retVal = api->gnssSetPositionMode(mode, recurrence, minIntervalMs,
|
||||||
|
preferredAccuracyMeters, preferredTimeMs);
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<sp<IAGnss>> Gnss::getExtensionAGnss() {
|
||||||
|
ENTRY_LOG_CALLFLOW();
|
||||||
|
mAGnssIface = new AGnss(this);
|
||||||
|
return mAGnssIface;
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<sp<IGnssNi>> Gnss::getExtensionGnssNi() {
|
||||||
|
ENTRY_LOG_CALLFLOW();
|
||||||
|
mGnssNi = new GnssNi(this);
|
||||||
|
return mGnssNi;
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<sp<IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() {
|
||||||
|
ENTRY_LOG_CALLFLOW();
|
||||||
|
mGnssMeasurement = new GnssMeasurement();
|
||||||
|
return mGnssMeasurement;
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<sp<IGnssConfiguration>> Gnss::getExtensionGnssConfiguration() {
|
||||||
|
ENTRY_LOG_CALLFLOW();
|
||||||
|
mGnssConfig = new GnssConfiguration(this);
|
||||||
|
return mGnssConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<sp<IGnssGeofencing>> Gnss::getExtensionGnssGeofencing() {
|
||||||
|
ENTRY_LOG_CALLFLOW();
|
||||||
|
mGnssGeofencingIface = new GnssGeofencing();
|
||||||
|
return mGnssGeofencingIface;
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<sp<IGnssBatching>> Gnss::getExtensionGnssBatching() {
|
||||||
|
mGnssBatching = new GnssBatching();
|
||||||
|
return mGnssBatching;
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<sp<IGnssDebug>> Gnss::getExtensionGnssDebug() {
|
||||||
|
ENTRY_LOG_CALLFLOW();
|
||||||
|
mGnssDebug = new GnssDebug(this);
|
||||||
|
return mGnssDebug;
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<sp<IAGnssRil>> Gnss::getExtensionAGnssRil() {
|
||||||
|
mGnssRil = new AGnssRil(this);
|
||||||
|
return mGnssRil;
|
||||||
|
}
|
||||||
|
|
||||||
|
IGnss* HIDL_FETCH_IGnss(const char* hal) {
|
||||||
|
ENTRY_LOG_CALLFLOW();
|
||||||
|
IGnss* iface = nullptr;
|
||||||
|
iface = new Gnss();
|
||||||
|
if (iface == nullptr) {
|
||||||
|
LOC_LOGE("%s]: failed to get %s", __FUNCTION__, hal);
|
||||||
|
}
|
||||||
|
return iface;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace implementation
|
||||||
|
} // namespace V1_0
|
||||||
|
} // namespace gnss
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
149
gps/android/Gnss.h
Normal file
149
gps/android/Gnss.h
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
* Not a Contribution
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ANDROID_HARDWARE_GNSS_V1_1_GNSS_H
|
||||||
|
#define ANDROID_HARDWARE_GNSS_V1_1_GNSS_H
|
||||||
|
|
||||||
|
#include <AGnss.h>
|
||||||
|
#include <AGnssRil.h>
|
||||||
|
#include <GnssBatching.h>
|
||||||
|
#include <GnssConfiguration.h>
|
||||||
|
#include <GnssGeofencing.h>
|
||||||
|
#include <GnssMeasurement.h>
|
||||||
|
#include <GnssNi.h>
|
||||||
|
#include <GnssDebug.h>
|
||||||
|
|
||||||
|
#include <android/hardware/gnss/1.0/IGnss.h>
|
||||||
|
#include <hidl/Status.h>
|
||||||
|
|
||||||
|
#include <GnssAPIClient.h>
|
||||||
|
#include <location_interface.h>
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
namespace hardware {
|
||||||
|
namespace gnss {
|
||||||
|
namespace V1_0 {
|
||||||
|
namespace implementation {
|
||||||
|
|
||||||
|
using ::android::hardware::Return;
|
||||||
|
using ::android::hardware::Void;
|
||||||
|
using ::android::hardware::hidl_vec;
|
||||||
|
using ::android::hardware::hidl_string;
|
||||||
|
using ::android::sp;
|
||||||
|
|
||||||
|
struct Gnss : public IGnss {
|
||||||
|
Gnss();
|
||||||
|
~Gnss();
|
||||||
|
|
||||||
|
// registerAsService will call interfaceChain to determine the version of service
|
||||||
|
/* comment this out until we know really how to manipulate hidl version
|
||||||
|
using interfaceChain_cb = std::function<
|
||||||
|
void(const ::android::hardware::hidl_vec<::android::hardware::hidl_string>& descriptors)>;
|
||||||
|
virtual ::android::hardware::Return<void> interfaceChain(interfaceChain_cb _hidl_cb) override {
|
||||||
|
_hidl_cb({
|
||||||
|
"android.hardware.gnss@1.1::IGnss",
|
||||||
|
::android::hidl::base::V1_0::IBase::descriptor,
|
||||||
|
});
|
||||||
|
return ::android::hardware::Void();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Methods from ::android::hardware::gnss::V1_0::IGnss follow.
|
||||||
|
* These declarations were generated from Gnss.hal.
|
||||||
|
*/
|
||||||
|
Return<bool> setCallback(const sp<IGnssCallback>& callback) override;
|
||||||
|
Return<bool> start() override;
|
||||||
|
Return<bool> stop() override;
|
||||||
|
Return<void> cleanup() override;
|
||||||
|
Return<bool> injectLocation(double latitudeDegrees,
|
||||||
|
double longitudeDegrees,
|
||||||
|
float accuracyMeters) override;
|
||||||
|
Return<bool> injectTime(int64_t timeMs,
|
||||||
|
int64_t timeReferenceMs,
|
||||||
|
int32_t uncertaintyMs) override;
|
||||||
|
Return<void> deleteAidingData(IGnss::GnssAidingData aidingDataFlags) override;
|
||||||
|
Return<bool> setPositionMode(IGnss::GnssPositionMode mode,
|
||||||
|
IGnss::GnssPositionRecurrence recurrence,
|
||||||
|
uint32_t minIntervalMs,
|
||||||
|
uint32_t preferredAccuracyMeters,
|
||||||
|
uint32_t preferredTimeMs) override;
|
||||||
|
Return<sp<IAGnss>> getExtensionAGnss() override;
|
||||||
|
Return<sp<IGnssNi>> getExtensionGnssNi() override;
|
||||||
|
Return<sp<IGnssMeasurement>> getExtensionGnssMeasurement() override;
|
||||||
|
Return<sp<IGnssConfiguration>> getExtensionGnssConfiguration() override;
|
||||||
|
Return<sp<IGnssGeofencing>> getExtensionGnssGeofencing() override;
|
||||||
|
Return<sp<IGnssBatching>> getExtensionGnssBatching() override;
|
||||||
|
|
||||||
|
Return<sp<IAGnssRil>> getExtensionAGnssRil() override;
|
||||||
|
|
||||||
|
inline Return<sp<IGnssNavigationMessage>> getExtensionGnssNavigationMessage() override {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Return<sp<IGnssXtra>> getExtensionXtra() override {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<sp<IGnssDebug>> getExtensionGnssDebug() override;
|
||||||
|
|
||||||
|
// These methods are not part of the IGnss base class.
|
||||||
|
GnssAPIClient* getApi();
|
||||||
|
Return<bool> setGnssNiCb(const sp<IGnssNiCallback>& niCb);
|
||||||
|
Return<bool> updateConfiguration(GnssConfig& gnssConfig);
|
||||||
|
GnssInterface* getGnssInterface();
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct GnssDeathRecipient : hidl_death_recipient {
|
||||||
|
GnssDeathRecipient(sp<Gnss> gnss) : mGnss(gnss) {
|
||||||
|
}
|
||||||
|
~GnssDeathRecipient() = default;
|
||||||
|
virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
|
||||||
|
sp<Gnss> mGnss;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
sp<GnssDeathRecipient> mGnssDeathRecipient = nullptr;
|
||||||
|
|
||||||
|
sp<AGnss> mAGnssIface = nullptr;
|
||||||
|
sp<GnssNi> mGnssNi = nullptr;
|
||||||
|
sp<GnssMeasurement> mGnssMeasurement = nullptr;
|
||||||
|
sp<GnssConfiguration> mGnssConfig = nullptr;
|
||||||
|
sp<GnssGeofencing> mGnssGeofencingIface = nullptr;
|
||||||
|
sp<GnssBatching> mGnssBatching = nullptr;
|
||||||
|
sp<IGnssDebug> mGnssDebug = nullptr;
|
||||||
|
sp<AGnssRil> mGnssRil = nullptr;
|
||||||
|
|
||||||
|
GnssAPIClient* mApi = nullptr;
|
||||||
|
sp<IGnssCallback> mGnssCbIface = nullptr;
|
||||||
|
sp<IGnssNiCallback> mGnssNiCbIface = nullptr;
|
||||||
|
GnssConfig mPendingConfig;
|
||||||
|
GnssInterface* mGnssInterface = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern "C" IGnss* HIDL_FETCH_IGnss(const char* name);
|
||||||
|
|
||||||
|
} // namespace implementation
|
||||||
|
} // namespace V1_0
|
||||||
|
} // namespace gnss
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
||||||
|
|
||||||
|
#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSS_H
|
130
gps/android/GnssBatching.cpp
Normal file
130
gps/android/GnssBatching.cpp
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
* Not a Contribution
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LOG_TAG "LocSvc_GnssBatchingInterface"
|
||||||
|
|
||||||
|
#include <log_util.h>
|
||||||
|
#include <BatchingAPIClient.h>
|
||||||
|
#include "GnssBatching.h"
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
namespace hardware {
|
||||||
|
namespace gnss {
|
||||||
|
namespace V1_0 {
|
||||||
|
namespace implementation {
|
||||||
|
|
||||||
|
void GnssBatching::GnssBatchingDeathRecipient::serviceDied(
|
||||||
|
uint64_t cookie, const wp<IBase>& who) {
|
||||||
|
LOC_LOGE("%s] service died. cookie: %llu, who: %p",
|
||||||
|
__FUNCTION__, static_cast<unsigned long long>(cookie), &who);
|
||||||
|
if (mGnssBatching != nullptr) {
|
||||||
|
mGnssBatching->stop();
|
||||||
|
mGnssBatching->cleanup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GnssBatching::GnssBatching() : mApi(nullptr) {
|
||||||
|
mGnssBatchingDeathRecipient = new GnssBatchingDeathRecipient(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
GnssBatching::~GnssBatching() {
|
||||||
|
if (mApi != nullptr) {
|
||||||
|
delete mApi;
|
||||||
|
mApi = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Methods from ::android::hardware::gnss::V1_0::IGnssBatching follow.
|
||||||
|
Return<bool> GnssBatching::init(const sp<IGnssBatchingCallback>& callback) {
|
||||||
|
if (mApi != nullptr) {
|
||||||
|
LOC_LOGD("%s]: mApi is NOT nullptr, delete it first", __FUNCTION__);
|
||||||
|
delete mApi;
|
||||||
|
mApi = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
mApi = new BatchingAPIClient(callback);
|
||||||
|
if (mApi == nullptr) {
|
||||||
|
LOC_LOGE("%s]: failed to create mApi", __FUNCTION__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mGnssBatchingCbIface != nullptr) {
|
||||||
|
mGnssBatchingCbIface->unlinkToDeath(mGnssBatchingDeathRecipient);
|
||||||
|
}
|
||||||
|
mGnssBatchingCbIface = callback;
|
||||||
|
if (mGnssBatchingCbIface != nullptr) {
|
||||||
|
mGnssBatchingCbIface->linkToDeath(mGnssBatchingDeathRecipient, 0 /*cookie*/);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<uint16_t> GnssBatching::getBatchSize() {
|
||||||
|
uint16_t ret = 0;
|
||||||
|
if (mApi == nullptr) {
|
||||||
|
LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
|
||||||
|
} else {
|
||||||
|
ret = mApi->getBatchSize();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<bool> GnssBatching::start(const IGnssBatching::Options& options) {
|
||||||
|
bool ret = false;
|
||||||
|
if (mApi == nullptr) {
|
||||||
|
LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
|
||||||
|
} else {
|
||||||
|
ret = mApi->startSession(options);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<void> GnssBatching::flush() {
|
||||||
|
if (mApi == nullptr) {
|
||||||
|
LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
|
||||||
|
} else {
|
||||||
|
mApi->flushBatchedLocations();
|
||||||
|
}
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<bool> GnssBatching::stop() {
|
||||||
|
bool ret = false;
|
||||||
|
if (mApi == nullptr) {
|
||||||
|
LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
|
||||||
|
} else {
|
||||||
|
ret = mApi->stopSession();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<void> GnssBatching::cleanup() {
|
||||||
|
if (mGnssBatchingCbIface != nullptr) {
|
||||||
|
mGnssBatchingCbIface->unlinkToDeath(mGnssBatchingDeathRecipient);
|
||||||
|
}
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace implementation
|
||||||
|
} // namespace V1_0
|
||||||
|
} // namespace gnss
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
80
gps/android/GnssBatching.h
Normal file
80
gps/android/GnssBatching.h
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
* Not a Contribution
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ANDROID_HARDWARE_GNSS_V1_1_GNSSBATCHING_H
|
||||||
|
#define ANDROID_HARDWARE_GNSS_V1_1_GNSSBATCHING_H
|
||||||
|
|
||||||
|
#include <android/hardware/gnss/1.0/IGnssBatching.h>
|
||||||
|
#include <hidl/Status.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
namespace hardware {
|
||||||
|
namespace gnss {
|
||||||
|
namespace V1_0 {
|
||||||
|
namespace implementation {
|
||||||
|
|
||||||
|
using ::android::hardware::gnss::V1_0::IGnssBatching;
|
||||||
|
using ::android::hardware::gnss::V1_0::IGnssBatchingCallback;
|
||||||
|
using ::android::hidl::base::V1_0::IBase;
|
||||||
|
using ::android::hardware::hidl_array;
|
||||||
|
using ::android::hardware::hidl_memory;
|
||||||
|
using ::android::hardware::hidl_string;
|
||||||
|
using ::android::hardware::hidl_vec;
|
||||||
|
using ::android::hardware::Return;
|
||||||
|
using ::android::hardware::Void;
|
||||||
|
using ::android::sp;
|
||||||
|
|
||||||
|
class BatchingAPIClient;
|
||||||
|
struct GnssBatching : public IGnssBatching {
|
||||||
|
GnssBatching();
|
||||||
|
~GnssBatching();
|
||||||
|
|
||||||
|
// Methods from ::android::hardware::gnss::V1_0::IGnssBatching follow.
|
||||||
|
Return<bool> init(const sp<IGnssBatchingCallback>& callback) override;
|
||||||
|
Return<uint16_t> getBatchSize() override;
|
||||||
|
Return<bool> start(const IGnssBatching::Options& options ) override;
|
||||||
|
Return<void> flush() override;
|
||||||
|
Return<bool> stop() override;
|
||||||
|
Return<void> cleanup() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct GnssBatchingDeathRecipient : hidl_death_recipient {
|
||||||
|
GnssBatchingDeathRecipient(sp<GnssBatching> gnssBatching) :
|
||||||
|
mGnssBatching(gnssBatching) {
|
||||||
|
}
|
||||||
|
~GnssBatchingDeathRecipient() = default;
|
||||||
|
virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
|
||||||
|
sp<GnssBatching> mGnssBatching;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
sp<GnssBatchingDeathRecipient> mGnssBatchingDeathRecipient = nullptr;
|
||||||
|
sp<IGnssBatchingCallback> mGnssBatchingCbIface = nullptr;
|
||||||
|
BatchingAPIClient* mApi = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace implementation
|
||||||
|
} // namespace V1_0
|
||||||
|
} // namespace gnss
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
||||||
|
|
||||||
|
#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSSBATCHING_H
|
227
gps/android/GnssConfiguration.cpp
Normal file
227
gps/android/GnssConfiguration.cpp
Normal file
|
@ -0,0 +1,227 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
* Not a Contribution
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LOG_TAG "LocSvc_GnssConfigurationInterface"
|
||||||
|
|
||||||
|
#include <log_util.h>
|
||||||
|
#include "Gnss.h"
|
||||||
|
#include "GnssConfiguration.h"
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
namespace hardware {
|
||||||
|
namespace gnss {
|
||||||
|
namespace V1_0 {
|
||||||
|
namespace implementation {
|
||||||
|
|
||||||
|
GnssConfiguration::GnssConfiguration(Gnss* gnss) : mGnss(gnss) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Methods from ::android::hardware::gps::V1_0::IGnssConfiguration follow.
|
||||||
|
Return<bool> GnssConfiguration::setSuplEs(bool enabled) {
|
||||||
|
if (mGnss == nullptr) {
|
||||||
|
LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GnssConfig config;
|
||||||
|
memset(&config, 0, sizeof(GnssConfig));
|
||||||
|
config.size = sizeof(GnssConfig);
|
||||||
|
config.flags = GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT;
|
||||||
|
config.suplEmergencyServices = (enabled ?
|
||||||
|
GNSS_CONFIG_SUPL_EMERGENCY_SERVICES_YES :
|
||||||
|
GNSS_CONFIG_SUPL_EMERGENCY_SERVICES_NO);
|
||||||
|
|
||||||
|
return mGnss->updateConfiguration(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<bool> GnssConfiguration::setSuplVersion(uint32_t version) {
|
||||||
|
if (mGnss == nullptr) {
|
||||||
|
LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GnssConfig config;
|
||||||
|
memset(&config, 0, sizeof(GnssConfig));
|
||||||
|
config.size = sizeof(GnssConfig);
|
||||||
|
config.flags = GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT;
|
||||||
|
switch (version) {
|
||||||
|
case 0x00020002:
|
||||||
|
config.suplVersion = GNSS_CONFIG_SUPL_VERSION_2_0_2;
|
||||||
|
break;
|
||||||
|
case 0x00020000:
|
||||||
|
config.suplVersion = GNSS_CONFIG_SUPL_VERSION_2_0_0;
|
||||||
|
break;
|
||||||
|
case 0x00010000:
|
||||||
|
config.suplVersion = GNSS_CONFIG_SUPL_VERSION_1_0_0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOC_LOGE("%s]: invalid version: 0x%x.", __FUNCTION__, version);
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mGnss->updateConfiguration(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<bool> GnssConfiguration::setSuplMode(uint8_t mode) {
|
||||||
|
if (mGnss == nullptr) {
|
||||||
|
LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GnssConfig config;
|
||||||
|
memset(&config, 0, sizeof(GnssConfig));
|
||||||
|
config.size = sizeof(GnssConfig);
|
||||||
|
config.flags = GNSS_CONFIG_FLAGS_SUPL_MODE_BIT;
|
||||||
|
switch (mode) {
|
||||||
|
case 0:
|
||||||
|
config.suplModeMask = 0; // STANDALONE ONLY
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
config.suplModeMask = GNSS_CONFIG_SUPL_MODE_MSB_BIT;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
config.suplModeMask = GNSS_CONFIG_SUPL_MODE_MSA_BIT;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
config.suplModeMask = GNSS_CONFIG_SUPL_MODE_MSB_BIT | GNSS_CONFIG_SUPL_MODE_MSA_BIT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOC_LOGE("%s]: invalid mode: %d.", __FUNCTION__, mode);
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mGnss->updateConfiguration(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<bool> GnssConfiguration::setLppProfile(uint8_t lppProfile) {
|
||||||
|
if (mGnss == nullptr) {
|
||||||
|
LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GnssConfig config;
|
||||||
|
memset(&config, 0, sizeof(GnssConfig));
|
||||||
|
config.size = sizeof(GnssConfig);
|
||||||
|
config.flags = GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT;
|
||||||
|
switch (lppProfile) {
|
||||||
|
case 0:
|
||||||
|
config.lppProfile = GNSS_CONFIG_LPP_PROFILE_RRLP_ON_LTE;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
config.lppProfile = GNSS_CONFIG_LPP_PROFILE_USER_PLANE;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
config.lppProfile = GNSS_CONFIG_LPP_PROFILE_CONTROL_PLANE;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
config.lppProfile = GNSS_CONFIG_LPP_PROFILE_USER_PLANE_AND_CONTROL_PLANE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOC_LOGE("%s]: invalid lppProfile: %d.", __FUNCTION__, lppProfile);
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mGnss->updateConfiguration(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<bool> GnssConfiguration::setGlonassPositioningProtocol(uint8_t protocol) {
|
||||||
|
if (mGnss == nullptr) {
|
||||||
|
LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GnssConfig config;
|
||||||
|
memset(&config, 0, sizeof(GnssConfig));
|
||||||
|
config.size = sizeof(GnssConfig);
|
||||||
|
|
||||||
|
config.flags = GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT;
|
||||||
|
if (protocol & (1<<0)) {
|
||||||
|
config.aGlonassPositionProtocolMask |= GNSS_CONFIG_RRC_CONTROL_PLANE_BIT;
|
||||||
|
}
|
||||||
|
if (protocol & (1<<1)) {
|
||||||
|
config.aGlonassPositionProtocolMask |= GNSS_CONFIG_RRLP_USER_PLANE_BIT;
|
||||||
|
}
|
||||||
|
if (protocol & (1<<2)) {
|
||||||
|
config.aGlonassPositionProtocolMask |= GNSS_CONFIG_LLP_USER_PLANE_BIT;
|
||||||
|
}
|
||||||
|
if (protocol & (1<<3)) {
|
||||||
|
config.aGlonassPositionProtocolMask |= GNSS_CONFIG_LLP_CONTROL_PLANE_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mGnss->updateConfiguration(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<bool> GnssConfiguration::setGpsLock(uint8_t lock) {
|
||||||
|
if (mGnss == nullptr) {
|
||||||
|
LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GnssConfig config;
|
||||||
|
memset(&config, 0, sizeof(GnssConfig));
|
||||||
|
config.size = sizeof(GnssConfig);
|
||||||
|
config.flags = GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT;
|
||||||
|
switch (lock) {
|
||||||
|
case 0:
|
||||||
|
config.gpsLock = GNSS_CONFIG_GPS_LOCK_NONE;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
config.gpsLock = GNSS_CONFIG_GPS_LOCK_MO;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
config.gpsLock = GNSS_CONFIG_GPS_LOCK_NI;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
config.gpsLock = GNSS_CONFIG_GPS_LOCK_MO_AND_NI;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOC_LOGE("%s]: invalid lock: %d.", __FUNCTION__, lock);
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mGnss->updateConfiguration(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<bool> GnssConfiguration::setEmergencySuplPdn(bool enabled) {
|
||||||
|
if (mGnss == nullptr) {
|
||||||
|
LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GnssConfig config;
|
||||||
|
memset(&config, 0, sizeof(GnssConfig));
|
||||||
|
config.size = sizeof(GnssConfig);
|
||||||
|
config.flags = GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT;
|
||||||
|
config.emergencyPdnForEmergencySupl = (enabled ?
|
||||||
|
GNSS_CONFIG_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_YES :
|
||||||
|
GNSS_CONFIG_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_NO);
|
||||||
|
|
||||||
|
return mGnss->updateConfiguration(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace implementation
|
||||||
|
} // namespace V1_0
|
||||||
|
} // namespace gnss
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
71
gps/android/GnssConfiguration.h
Normal file
71
gps/android/GnssConfiguration.h
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
* Not a Contribution
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copyright (C) 2016 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef ANDROID_HARDWARE_GNSS_V1_1_GNSSCONFIGURATION_H
|
||||||
|
#define ANDROID_HARDWARE_GNSS_V1_1_GNSSCONFIGURATION_H
|
||||||
|
|
||||||
|
#include <android/hardware/gnss/1.0/IGnssConfiguration.h>
|
||||||
|
#include <hidl/Status.h>
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
namespace hardware {
|
||||||
|
namespace gnss {
|
||||||
|
namespace V1_0 {
|
||||||
|
namespace implementation {
|
||||||
|
|
||||||
|
using ::android::hardware::gnss::V1_0::IGnssConfiguration;
|
||||||
|
using ::android::hardware::Return;
|
||||||
|
using ::android::hardware::Void;
|
||||||
|
using ::android::hardware::hidl_vec;
|
||||||
|
using ::android::hardware::hidl_string;
|
||||||
|
using ::android::sp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interface for passing GNSS configuration info from platform to HAL.
|
||||||
|
*/
|
||||||
|
struct Gnss;
|
||||||
|
struct GnssConfiguration : public IGnssConfiguration {
|
||||||
|
GnssConfiguration(Gnss* gnss);
|
||||||
|
~GnssConfiguration() = default;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Methods from ::android::hardware::gnss::V1_0::IGnssConfiguration follow.
|
||||||
|
* These declarations were generated from IGnssConfiguration.hal.
|
||||||
|
*/
|
||||||
|
Return<bool> setSuplVersion(uint32_t version) override;
|
||||||
|
Return<bool> setSuplMode(uint8_t mode) override;
|
||||||
|
Return<bool> setSuplEs(bool enabled) override;
|
||||||
|
Return<bool> setLppProfile(uint8_t lppProfile) override;
|
||||||
|
Return<bool> setGlonassPositioningProtocol(uint8_t protocol) override;
|
||||||
|
Return<bool> setEmergencySuplPdn(bool enable) override;
|
||||||
|
Return<bool> setGpsLock(uint8_t lock) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Gnss* mGnss = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace implementation
|
||||||
|
} // namespace V1_0
|
||||||
|
} // namespace gnss
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
||||||
|
|
||||||
|
#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSSCONFIGURATION_H
|
143
gps/android/GnssDebug.cpp
Normal file
143
gps/android/GnssDebug.cpp
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LOG_TAG "LocSvc_GnssDebugInterface"
|
||||||
|
|
||||||
|
#include <log/log.h>
|
||||||
|
#include <log_util.h>
|
||||||
|
#include "Gnss.h"
|
||||||
|
#include "GnssDebug.h"
|
||||||
|
#include "LocationUtil.h"
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
namespace hardware {
|
||||||
|
namespace gnss {
|
||||||
|
namespace V1_0 {
|
||||||
|
namespace implementation {
|
||||||
|
|
||||||
|
using ::android::hardware::hidl_vec;
|
||||||
|
|
||||||
|
#define GNSS_DEBUG_UNKNOWN_UTC_TIME (1483228800000ULL) // 1/1/2017 00:00 GMT
|
||||||
|
#define GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC (1.57783680E17) // 5 years in ns
|
||||||
|
|
||||||
|
GnssDebug::GnssDebug(Gnss* gnss) : mGnss(gnss)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This methods requests position, time and satellite ephemeris debug information
|
||||||
|
* from the HAL.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
Return<void> GnssDebug::getDebugData(getDebugData_cb _hidl_cb)
|
||||||
|
{
|
||||||
|
LOC_LOGD("%s]: ", __func__);
|
||||||
|
|
||||||
|
DebugData data = { };
|
||||||
|
|
||||||
|
if((nullptr == mGnss) || (nullptr == mGnss->getGnssInterface())){
|
||||||
|
LOC_LOGE("GnssDebug - Null GNSS interface");
|
||||||
|
_hidl_cb(data);
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
// get debug report snapshot via hal interface
|
||||||
|
GnssDebugReport reports = { };
|
||||||
|
mGnss->getGnssInterface()->getDebugReport(reports);
|
||||||
|
|
||||||
|
// location block
|
||||||
|
if (reports.mLocation.mValid) {
|
||||||
|
data.position.valid = true;
|
||||||
|
data.position.latitudeDegrees = reports.mLocation.mLocation.latitude;
|
||||||
|
data.position.longitudeDegrees = reports.mLocation.mLocation.longitude;
|
||||||
|
data.position.altitudeMeters = reports.mLocation.mLocation.altitude;
|
||||||
|
|
||||||
|
data.position.speedMetersPerSec =
|
||||||
|
(double)(reports.mLocation.mLocation.speed);
|
||||||
|
data.position.bearingDegrees =
|
||||||
|
(double)(reports.mLocation.mLocation.bearing);
|
||||||
|
data.position.horizontalAccuracyMeters =
|
||||||
|
(double)(reports.mLocation.mLocation.accuracy);
|
||||||
|
data.position.verticalAccuracyMeters =
|
||||||
|
reports.mLocation.verticalAccuracyMeters;
|
||||||
|
data.position.speedAccuracyMetersPerSecond =
|
||||||
|
reports.mLocation.speedAccuracyMetersPerSecond;
|
||||||
|
data.position.bearingAccuracyDegrees =
|
||||||
|
reports.mLocation.bearingAccuracyDegrees;
|
||||||
|
|
||||||
|
timeval tv_now, tv_report;
|
||||||
|
tv_report.tv_sec = reports.mLocation.mUtcReported.tv_sec;
|
||||||
|
tv_report.tv_usec = reports.mLocation.mUtcReported.tv_nsec / 1000ULL;
|
||||||
|
gettimeofday(&tv_now, NULL);
|
||||||
|
data.position.ageSeconds =
|
||||||
|
(tv_now.tv_sec - tv_report.tv_sec) +
|
||||||
|
(float)((tv_now.tv_usec - tv_report.tv_usec)) / 1000000;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
data.position.valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// time block
|
||||||
|
if (reports.mTime.mValid) {
|
||||||
|
data.time.timeEstimate = reports.mTime.timeEstimate;
|
||||||
|
data.time.timeUncertaintyNs = reports.mTime.timeUncertaintyNs;
|
||||||
|
data.time.frequencyUncertaintyNsPerSec =
|
||||||
|
reports.mTime.frequencyUncertaintyNsPerSec;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
data.time.timeEstimate = GNSS_DEBUG_UNKNOWN_UTC_TIME;
|
||||||
|
data.time.timeUncertaintyNs = (float)(GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC);
|
||||||
|
data.time.frequencyUncertaintyNsPerSec = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// satellite data block
|
||||||
|
SatelliteData s = { };
|
||||||
|
std::vector<SatelliteData> s_array = { };
|
||||||
|
|
||||||
|
for (uint32_t i=0; i<reports.mSatelliteInfo.size(); i++) {
|
||||||
|
memset(&s, 0, sizeof(s));
|
||||||
|
s.svid = reports.mSatelliteInfo[i].svid;
|
||||||
|
convertGnssConstellationType(
|
||||||
|
reports.mSatelliteInfo[i].constellation, s.constellation);
|
||||||
|
convertGnssEphemerisType(
|
||||||
|
reports.mSatelliteInfo[i].mEphemerisType, s.ephemerisType);
|
||||||
|
convertGnssEphemerisSource(
|
||||||
|
reports.mSatelliteInfo[i].mEphemerisSource, s.ephemerisSource);
|
||||||
|
convertGnssEphemerisHealth(
|
||||||
|
reports.mSatelliteInfo[i].mEphemerisHealth, s.ephemerisHealth);
|
||||||
|
|
||||||
|
s.ephemerisAgeSeconds =
|
||||||
|
reports.mSatelliteInfo[i].ephemerisAgeSeconds;
|
||||||
|
s.serverPredictionIsAvailable =
|
||||||
|
reports.mSatelliteInfo[i].serverPredictionIsAvailable;
|
||||||
|
s.serverPredictionAgeSeconds =
|
||||||
|
reports.mSatelliteInfo[i].serverPredictionAgeSeconds;
|
||||||
|
|
||||||
|
s_array.push_back(s);
|
||||||
|
}
|
||||||
|
data.satelliteDataArray = s_array;
|
||||||
|
|
||||||
|
// callback HIDL with collected debug data
|
||||||
|
_hidl_cb(data);
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace implementation
|
||||||
|
} // namespace V1_0
|
||||||
|
} // namespace gnss
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
59
gps/android/GnssDebug.h
Normal file
59
gps/android/GnssDebug.h
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ANDROID_HARDWARE_GNSS_V1_1_GNSSDEBUG_H
|
||||||
|
#define ANDROID_HARDWARE_GNSS_V1_1_GNSSDEBUG_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <android/hardware/gnss/1.0/IGnssDebug.h>
|
||||||
|
#include <hidl/Status.h>
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
namespace hardware {
|
||||||
|
namespace gnss {
|
||||||
|
namespace V1_0 {
|
||||||
|
namespace implementation {
|
||||||
|
|
||||||
|
using ::android::hardware::gnss::V1_0::IGnssDebug;
|
||||||
|
using ::android::hardware::Return;
|
||||||
|
using ::android::hardware::Void;
|
||||||
|
using ::android::hardware::hidl_vec;
|
||||||
|
using ::android::hardware::hidl_string;
|
||||||
|
using ::android::sp;
|
||||||
|
|
||||||
|
/* Interface for GNSS Debug support. */
|
||||||
|
struct Gnss;
|
||||||
|
struct GnssDebug : public IGnssDebug {
|
||||||
|
GnssDebug(Gnss* gnss);
|
||||||
|
~GnssDebug() {};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Methods from ::android::hardware::gnss::V1_0::IGnssDebug follow.
|
||||||
|
* These declarations were generated from IGnssDebug.hal.
|
||||||
|
*/
|
||||||
|
Return<void> getDebugData(getDebugData_cb _hidl_cb) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Gnss* mGnss = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace implementation
|
||||||
|
} // namespace V1_0
|
||||||
|
} // namespace gnss
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
||||||
|
|
||||||
|
#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSSDEBUG_H
|
141
gps/android/GnssGeofencing.cpp
Normal file
141
gps/android/GnssGeofencing.cpp
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
* Not a Contribution
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LOG_TAG "GnssHal_GnssGeofencing"
|
||||||
|
|
||||||
|
#include <log_util.h>
|
||||||
|
#include <GeofenceAPIClient.h>
|
||||||
|
#include "GnssGeofencing.h"
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
namespace hardware {
|
||||||
|
namespace gnss {
|
||||||
|
namespace V1_0 {
|
||||||
|
namespace implementation {
|
||||||
|
|
||||||
|
void GnssGeofencing::GnssGeofencingDeathRecipient::serviceDied(
|
||||||
|
uint64_t cookie, const wp<IBase>& who) {
|
||||||
|
LOC_LOGE("%s] service died. cookie: %llu, who: %p",
|
||||||
|
__FUNCTION__, static_cast<unsigned long long>(cookie), &who);
|
||||||
|
if (mGnssGeofencing != nullptr) {
|
||||||
|
mGnssGeofencing->removeAllGeofences();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GnssGeofencing::GnssGeofencing() : mApi(nullptr) {
|
||||||
|
mGnssGeofencingDeathRecipient = new GnssGeofencingDeathRecipient(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
GnssGeofencing::~GnssGeofencing() {
|
||||||
|
if (mApi != nullptr) {
|
||||||
|
delete mApi;
|
||||||
|
mApi = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Methods from ::android::hardware::gnss::V1_0::IGnssGeofencing follow.
|
||||||
|
Return<void> GnssGeofencing::setCallback(const sp<IGnssGeofenceCallback>& callback) {
|
||||||
|
if (mApi != nullptr) {
|
||||||
|
LOC_LOGE("%s]: mApi is NOT nullptr", __FUNCTION__);
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
mApi = new GeofenceAPIClient(callback);
|
||||||
|
if (mApi == nullptr) {
|
||||||
|
LOC_LOGE("%s]: failed to create mApi", __FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mGnssGeofencingCbIface != nullptr) {
|
||||||
|
mGnssGeofencingCbIface->unlinkToDeath(mGnssGeofencingDeathRecipient);
|
||||||
|
}
|
||||||
|
mGnssGeofencingCbIface = callback;
|
||||||
|
if (mGnssGeofencingCbIface != nullptr) {
|
||||||
|
mGnssGeofencingCbIface->linkToDeath(mGnssGeofencingDeathRecipient, 0 /*cookie*/);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<void> GnssGeofencing::addGeofence(
|
||||||
|
int32_t geofenceId,
|
||||||
|
double latitudeDegrees,
|
||||||
|
double longitudeDegrees,
|
||||||
|
double radiusMeters,
|
||||||
|
IGnssGeofenceCallback::GeofenceTransition lastTransition,
|
||||||
|
int32_t monitorTransitions,
|
||||||
|
uint32_t notificationResponsivenessMs,
|
||||||
|
uint32_t unknownTimerMs) {
|
||||||
|
if (mApi == nullptr) {
|
||||||
|
LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
|
||||||
|
} else {
|
||||||
|
mApi->geofenceAdd(
|
||||||
|
geofenceId,
|
||||||
|
latitudeDegrees,
|
||||||
|
longitudeDegrees,
|
||||||
|
radiusMeters,
|
||||||
|
static_cast<int32_t>(lastTransition),
|
||||||
|
monitorTransitions,
|
||||||
|
notificationResponsivenessMs,
|
||||||
|
unknownTimerMs);
|
||||||
|
}
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<void> GnssGeofencing::pauseGeofence(int32_t geofenceId) {
|
||||||
|
if (mApi == nullptr) {
|
||||||
|
LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
|
||||||
|
} else {
|
||||||
|
mApi->geofencePause(geofenceId);
|
||||||
|
}
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<void> GnssGeofencing::resumeGeofence(int32_t geofenceId, int32_t monitorTransitions) {
|
||||||
|
if (mApi == nullptr) {
|
||||||
|
LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
|
||||||
|
} else {
|
||||||
|
mApi->geofenceResume(geofenceId, monitorTransitions);
|
||||||
|
}
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<void> GnssGeofencing::removeGeofence(int32_t geofenceId) {
|
||||||
|
if (mApi == nullptr) {
|
||||||
|
LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
|
||||||
|
} else {
|
||||||
|
mApi->geofenceRemove(geofenceId);
|
||||||
|
}
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<void> GnssGeofencing::removeAllGeofences() {
|
||||||
|
if (mApi == nullptr) {
|
||||||
|
LOC_LOGD("%s]: mApi is nullptr, do nothing", __FUNCTION__);
|
||||||
|
} else {
|
||||||
|
mApi->geofenceRemoveAll();
|
||||||
|
}
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace implementation
|
||||||
|
} // namespace V1_0
|
||||||
|
} // namespace gnss
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
91
gps/android/GnssGeofencing.h
Normal file
91
gps/android/GnssGeofencing.h
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
* Not a Contribution
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ANDROID_HARDWARE_GNSS_V1_1_GNSSGEOFENCING_H
|
||||||
|
#define ANDROID_HARDWARE_GNSS_V1_1_GNSSGEOFENCING_H
|
||||||
|
|
||||||
|
#include <android/hardware/gnss/1.0/IGnssGeofencing.h>
|
||||||
|
#include <hidl/Status.h>
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
namespace hardware {
|
||||||
|
namespace gnss {
|
||||||
|
namespace V1_0 {
|
||||||
|
namespace implementation {
|
||||||
|
|
||||||
|
using ::android::hardware::gnss::V1_0::IGnssGeofenceCallback;
|
||||||
|
using ::android::hardware::gnss::V1_0::IGnssGeofencing;
|
||||||
|
using ::android::hardware::Return;
|
||||||
|
using ::android::hardware::Void;
|
||||||
|
using ::android::hardware::hidl_vec;
|
||||||
|
using ::android::hardware::hidl_string;
|
||||||
|
using ::android::sp;
|
||||||
|
|
||||||
|
class GeofenceAPIClient;
|
||||||
|
struct GnssGeofencing : public IGnssGeofencing {
|
||||||
|
GnssGeofencing();
|
||||||
|
~GnssGeofencing();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Methods from ::android::hardware::gnss::V1_0::IGnssGeofencing follow.
|
||||||
|
* These declarations were generated from IGnssGeofencing.hal.
|
||||||
|
*/
|
||||||
|
Return<void> setCallback(const sp<IGnssGeofenceCallback>& callback) override;
|
||||||
|
Return<void> addGeofence(int32_t geofenceId,
|
||||||
|
double latitudeDegrees,
|
||||||
|
double longitudeDegrees,
|
||||||
|
double radiusMeters,
|
||||||
|
IGnssGeofenceCallback::GeofenceTransition lastTransition,
|
||||||
|
int32_t monitorTransitions,
|
||||||
|
uint32_t notificationResponsivenessMs,
|
||||||
|
uint32_t unknownTimerMs) override;
|
||||||
|
|
||||||
|
Return<void> pauseGeofence(int32_t geofenceId) override;
|
||||||
|
Return<void> resumeGeofence(int32_t geofenceId, int32_t monitorTransitions) override;
|
||||||
|
Return<void> removeGeofence(int32_t geofenceId) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// This method is not part of the IGnss base class.
|
||||||
|
// It is called by GnssGeofencingDeathRecipient to remove all geofences added so far.
|
||||||
|
Return<void> removeAllGeofences();
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct GnssGeofencingDeathRecipient : hidl_death_recipient {
|
||||||
|
GnssGeofencingDeathRecipient(sp<GnssGeofencing> gnssGeofencing) :
|
||||||
|
mGnssGeofencing(gnssGeofencing) {
|
||||||
|
}
|
||||||
|
~GnssGeofencingDeathRecipient() = default;
|
||||||
|
virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
|
||||||
|
sp<GnssGeofencing> mGnssGeofencing;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
sp<GnssGeofencingDeathRecipient> mGnssGeofencingDeathRecipient = nullptr;
|
||||||
|
sp<IGnssGeofenceCallback> mGnssGeofencingCbIface = nullptr;
|
||||||
|
GeofenceAPIClient* mApi = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace implementation
|
||||||
|
} // namespace V1_0
|
||||||
|
} // namespace gnss
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
||||||
|
|
||||||
|
#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSSGEOFENCING_H
|
99
gps/android/GnssMeasurement.cpp
Normal file
99
gps/android/GnssMeasurement.cpp
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
* Not a Contribution
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LOG_TAG "LocSvc_GnssMeasurementInterface"
|
||||||
|
|
||||||
|
#include <log_util.h>
|
||||||
|
#include <MeasurementAPIClient.h>
|
||||||
|
#include "GnssMeasurement.h"
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
namespace hardware {
|
||||||
|
namespace gnss {
|
||||||
|
namespace V1_0 {
|
||||||
|
namespace implementation {
|
||||||
|
|
||||||
|
void GnssMeasurement::GnssMeasurementDeathRecipient::serviceDied(
|
||||||
|
uint64_t cookie, const wp<IBase>& who) {
|
||||||
|
LOC_LOGE("%s] service died. cookie: %llu, who: %p",
|
||||||
|
__FUNCTION__, static_cast<unsigned long long>(cookie), &who);
|
||||||
|
if (mGnssMeasurement != nullptr) {
|
||||||
|
mGnssMeasurement->close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GnssMeasurement::GnssMeasurement() {
|
||||||
|
mGnssMeasurementDeathRecipient = new GnssMeasurementDeathRecipient(this);
|
||||||
|
mApi = new MeasurementAPIClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
GnssMeasurement::~GnssMeasurement() {
|
||||||
|
if (mApi) {
|
||||||
|
delete mApi;
|
||||||
|
mApi = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Methods from ::android::hardware::gnss::V1_0::IGnssMeasurement follow.
|
||||||
|
Return<IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback(
|
||||||
|
const sp<IGnssMeasurementCallback>& callback) {
|
||||||
|
|
||||||
|
Return<IGnssMeasurement::GnssMeasurementStatus> ret =
|
||||||
|
IGnssMeasurement::GnssMeasurementStatus::ERROR_GENERIC;
|
||||||
|
if (mGnssMeasurementCbIface != nullptr) {
|
||||||
|
LOC_LOGE("%s]: GnssMeasurementCallback is already set", __FUNCTION__);
|
||||||
|
return IGnssMeasurement::GnssMeasurementStatus::ERROR_ALREADY_INIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callback == nullptr) {
|
||||||
|
LOC_LOGE("%s]: callback is nullptr", __FUNCTION__);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (mApi == nullptr) {
|
||||||
|
LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mGnssMeasurementCbIface = callback;
|
||||||
|
mGnssMeasurementCbIface->linkToDeath(mGnssMeasurementDeathRecipient, 0 /*cookie*/);
|
||||||
|
|
||||||
|
return mApi->measurementSetCallback(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<void> GnssMeasurement::close() {
|
||||||
|
if (mApi == nullptr) {
|
||||||
|
LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mGnssMeasurementCbIface != nullptr) {
|
||||||
|
mGnssMeasurementCbIface->unlinkToDeath(mGnssMeasurementDeathRecipient);
|
||||||
|
mGnssMeasurementCbIface = nullptr;
|
||||||
|
}
|
||||||
|
mApi->measurementClose();
|
||||||
|
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace implementation
|
||||||
|
} // namespace V1_0
|
||||||
|
} // namespace gnss
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
76
gps/android/GnssMeasurement.h
Normal file
76
gps/android/GnssMeasurement.h
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
* Not a Contribution
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ANDROID_HARDWARE_GNSS_V1_1_GNSSMEASUREMENT_H
|
||||||
|
#define ANDROID_HARDWARE_GNSS_V1_1_GNSSMEASUREMENT_H
|
||||||
|
|
||||||
|
#include <android/hardware/gnss/1.0/IGnssMeasurement.h>
|
||||||
|
#include <hidl/Status.h>
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
namespace hardware {
|
||||||
|
namespace gnss {
|
||||||
|
namespace V1_0 {
|
||||||
|
namespace implementation {
|
||||||
|
|
||||||
|
using ::android::hardware::gnss::V1_0::IGnssMeasurement;
|
||||||
|
using ::android::hardware::gnss::V1_0::IGnssMeasurementCallback;
|
||||||
|
using ::android::hardware::Return;
|
||||||
|
using ::android::hardware::Void;
|
||||||
|
using ::android::hardware::hidl_vec;
|
||||||
|
using ::android::hardware::hidl_string;
|
||||||
|
using ::android::sp;
|
||||||
|
|
||||||
|
class MeasurementAPIClient;
|
||||||
|
struct GnssMeasurement : public IGnssMeasurement {
|
||||||
|
GnssMeasurement();
|
||||||
|
~GnssMeasurement();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Methods from ::android::hardware::gnss::V1_0::IGnssMeasurement follow.
|
||||||
|
* These declarations were generated from IGnssMeasurement.hal.
|
||||||
|
*/
|
||||||
|
Return<GnssMeasurementStatus> setCallback(
|
||||||
|
const sp<IGnssMeasurementCallback>& callback) override;
|
||||||
|
Return<void> close() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct GnssMeasurementDeathRecipient : hidl_death_recipient {
|
||||||
|
GnssMeasurementDeathRecipient(sp<GnssMeasurement> gnssMeasurement) :
|
||||||
|
mGnssMeasurement(gnssMeasurement) {
|
||||||
|
}
|
||||||
|
~GnssMeasurementDeathRecipient() = default;
|
||||||
|
virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
|
||||||
|
sp<GnssMeasurement> mGnssMeasurement;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
sp<GnssMeasurementDeathRecipient> mGnssMeasurementDeathRecipient = nullptr;
|
||||||
|
sp<IGnssMeasurementCallback> mGnssMeasurementCbIface = nullptr;
|
||||||
|
MeasurementAPIClient* mApi;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace implementation
|
||||||
|
} // namespace V1_0
|
||||||
|
} // namespace gnss
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
||||||
|
|
||||||
|
#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSSMEASUREMENT_H
|
85
gps/android/GnssNi.cpp
Normal file
85
gps/android/GnssNi.cpp
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
* Not a Contribution
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LOG_TAG "LocSvc_GnssNiInterface"
|
||||||
|
|
||||||
|
#include <log_util.h>
|
||||||
|
#include "Gnss.h"
|
||||||
|
#include "GnssNi.h"
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
namespace hardware {
|
||||||
|
namespace gnss {
|
||||||
|
namespace V1_0 {
|
||||||
|
namespace implementation {
|
||||||
|
|
||||||
|
void GnssNi::GnssNiDeathRecipient::serviceDied(uint64_t cookie, const wp<IBase>& who) {
|
||||||
|
LOC_LOGE("%s] service died. cookie: %llu, who: %p",
|
||||||
|
__FUNCTION__, static_cast<unsigned long long>(cookie), &who);
|
||||||
|
// we do nothing here
|
||||||
|
// Gnss::GnssDeathRecipient will stop the session
|
||||||
|
}
|
||||||
|
|
||||||
|
GnssNi::GnssNi(Gnss* gnss) : mGnss(gnss) {
|
||||||
|
mGnssNiDeathRecipient = new GnssNiDeathRecipient(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Methods from ::android::hardware::gnss::V1_0::IGnssNi follow.
|
||||||
|
Return<void> GnssNi::setCallback(const sp<IGnssNiCallback>& callback) {
|
||||||
|
if (mGnss == nullptr) {
|
||||||
|
LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
mGnss->setGnssNiCb(callback);
|
||||||
|
|
||||||
|
if (mGnssNiCbIface != nullptr) {
|
||||||
|
mGnssNiCbIface->unlinkToDeath(mGnssNiDeathRecipient);
|
||||||
|
}
|
||||||
|
mGnssNiCbIface = callback;
|
||||||
|
if (mGnssNiCbIface != nullptr) {
|
||||||
|
mGnssNiCbIface->linkToDeath(mGnssNiDeathRecipient, 0 /*cookie*/);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<void> GnssNi::respond(int32_t notifId, IGnssNiCallback::GnssUserResponseType userResponse) {
|
||||||
|
if (mGnss == nullptr) {
|
||||||
|
LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
GnssAPIClient* api = mGnss->getApi();
|
||||||
|
if (api == nullptr) {
|
||||||
|
LOC_LOGE("%s]: api is nullptr", __FUNCTION__);
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
api->gnssNiRespond(notifId, userResponse);
|
||||||
|
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace implementation
|
||||||
|
} // namespace V1_0
|
||||||
|
} // namespace gnss
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
75
gps/android/GnssNi.h
Normal file
75
gps/android/GnssNi.h
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
* Not a Contribution
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ANDROID_HARDWARE_GNSS_V1_1_GNSSNI_H
|
||||||
|
#define ANDROID_HARDWARE_GNSS_V1_1_GNSSNI_H
|
||||||
|
|
||||||
|
#include <android/hardware/gnss/1.0/IGnssNi.h>
|
||||||
|
#include <hidl/Status.h>
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
namespace hardware {
|
||||||
|
namespace gnss {
|
||||||
|
namespace V1_0 {
|
||||||
|
namespace implementation {
|
||||||
|
|
||||||
|
using ::android::hardware::gnss::V1_0::IGnssNi;
|
||||||
|
using ::android::hardware::gnss::V1_0::IGnssNiCallback;
|
||||||
|
using ::android::hardware::Return;
|
||||||
|
using ::android::hardware::Void;
|
||||||
|
using ::android::hardware::hidl_vec;
|
||||||
|
using ::android::hardware::hidl_string;
|
||||||
|
using ::android::sp;
|
||||||
|
|
||||||
|
struct Gnss;
|
||||||
|
struct GnssNi : public IGnssNi {
|
||||||
|
GnssNi(Gnss* gnss);
|
||||||
|
~GnssNi() = default;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Methods from ::android::hardware::gnss::V1_0::IGnssNi follow.
|
||||||
|
* These declarations were generated from IGnssNi.hal.
|
||||||
|
*/
|
||||||
|
Return<void> setCallback(const sp<IGnssNiCallback>& callback) override;
|
||||||
|
Return<void> respond(int32_t notifId,
|
||||||
|
IGnssNiCallback::GnssUserResponseType userResponse) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct GnssNiDeathRecipient : hidl_death_recipient {
|
||||||
|
GnssNiDeathRecipient(sp<GnssNi> gnssNi) : mGnssNi(gnssNi) {
|
||||||
|
}
|
||||||
|
~GnssNiDeathRecipient() = default;
|
||||||
|
virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
|
||||||
|
sp<GnssNi> mGnssNi;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
sp<GnssNiDeathRecipient> mGnssNiDeathRecipient = nullptr;
|
||||||
|
sp<IGnssNiCallback> mGnssNiCbIface = nullptr;
|
||||||
|
Gnss* mGnss = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace implementation
|
||||||
|
} // namespace V1_0
|
||||||
|
} // namespace gnss
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
||||||
|
|
||||||
|
#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSSNI_H
|
4
gps/android/android.hardware.gnss@1.0-service-qti.rc
Normal file
4
gps/android/android.hardware.gnss@1.0-service-qti.rc
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
service gnss_service /vendor/bin/hw/android.hardware.gnss@1.0-service-qti
|
||||||
|
class main
|
||||||
|
user gps
|
||||||
|
group system gps radio
|
191
gps/android/location_api/BatchingAPIClient.cpp
Normal file
191
gps/android/location_api/BatchingAPIClient.cpp
Normal file
|
@ -0,0 +1,191 @@
|
||||||
|
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LOG_NDEBUG 0
|
||||||
|
#define LOG_TAG "LocSvc_BatchingAPIClient"
|
||||||
|
|
||||||
|
#include <log_util.h>
|
||||||
|
#include <loc_cfg.h>
|
||||||
|
|
||||||
|
#include "LocationUtil.h"
|
||||||
|
#include "BatchingAPIClient.h"
|
||||||
|
|
||||||
|
#include "limits.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
namespace hardware {
|
||||||
|
namespace gnss {
|
||||||
|
namespace V1_0 {
|
||||||
|
namespace implementation {
|
||||||
|
|
||||||
|
static void convertBatchOption(const IGnssBatching::Options& in, LocationOptions& out,
|
||||||
|
LocationCapabilitiesMask mask);
|
||||||
|
|
||||||
|
BatchingAPIClient::BatchingAPIClient(const sp<IGnssBatchingCallback>& callback) :
|
||||||
|
LocationAPIClientBase(),
|
||||||
|
mGnssBatchingCbIface(callback),
|
||||||
|
mDefaultId(UINT_MAX),
|
||||||
|
mLocationCapabilitiesMask(0)
|
||||||
|
{
|
||||||
|
LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
|
||||||
|
|
||||||
|
LocationCallbacks locationCallbacks;
|
||||||
|
memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
|
||||||
|
locationCallbacks.size = sizeof(LocationCallbacks);
|
||||||
|
|
||||||
|
locationCallbacks.trackingCb = nullptr;
|
||||||
|
locationCallbacks.batchingCb = nullptr;
|
||||||
|
if (mGnssBatchingCbIface != 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
BatchingAPIClient::~BatchingAPIClient()
|
||||||
|
{
|
||||||
|
LOC_LOGD("%s]: ()", __FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
int BatchingAPIClient::getBatchSize()
|
||||||
|
{
|
||||||
|
LOC_LOGD("%s]: ()", __FUNCTION__);
|
||||||
|
return locAPIGetBatchSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
int BatchingAPIClient::startSession(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 (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()
|
||||||
|
{
|
||||||
|
LOC_LOGD("%s]: ", __FUNCTION__);
|
||||||
|
int retVal = -1;
|
||||||
|
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__);
|
||||||
|
locAPIGetBatchedLocations(mDefaultId, SIZE_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BatchingAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
|
||||||
|
{
|
||||||
|
LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
|
||||||
|
mLocationCapabilitiesMask = capabilitiesMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BatchingAPIClient::onBatchingCb(size_t count, Location* location, BatchingOptions batchOptions)
|
||||||
|
{
|
||||||
|
LOC_LOGD("%s]: (count: %zu)", __FUNCTION__, count);
|
||||||
|
if (mGnssBatchingCbIface != nullptr && count > 0) {
|
||||||
|
hidl_vec<GnssLocation> locationVec;
|
||||||
|
locationVec.resize(count);
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
convertGnssLocation(location[i], locationVec[i]);
|
||||||
|
}
|
||||||
|
auto r = mGnssBatchingCbIface->gnssLocationBatchCb(locationVec);
|
||||||
|
if (!r.isOk()) {
|
||||||
|
LOC_LOGE("%s] Error from gnssLocationBatchCb description=%s",
|
||||||
|
__func__, r.description().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 V1_0
|
||||||
|
} // namespace gnss
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
75
gps/android/location_api/BatchingAPIClient.h
Normal file
75
gps/android/location_api/BatchingAPIClient.h
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BATCHING_API_CLINET_H
|
||||||
|
#define BATCHING_API_CLINET_H
|
||||||
|
|
||||||
|
#include <android/hardware/gnss/1.0/IGnssBatching.h>
|
||||||
|
#include <android/hardware/gnss/1.0/IGnssBatchingCallback.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <LocationAPIClientBase.h>
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
namespace hardware {
|
||||||
|
namespace gnss {
|
||||||
|
namespace V1_0 {
|
||||||
|
namespace implementation {
|
||||||
|
|
||||||
|
class BatchingAPIClient : public LocationAPIClientBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BatchingAPIClient(const sp<IGnssBatchingCallback>& callback);
|
||||||
|
~BatchingAPIClient();
|
||||||
|
int getBatchSize();
|
||||||
|
int startSession(const IGnssBatching::Options& options);
|
||||||
|
int updateSessionOptions(const 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:
|
||||||
|
sp<IGnssBatchingCallback> mGnssBatchingCbIface;
|
||||||
|
uint32_t mDefaultId;
|
||||||
|
int mBatchSize;
|
||||||
|
LocationCapabilitiesMask mLocationCapabilitiesMask;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace implementation
|
||||||
|
} // namespace V1_0
|
||||||
|
} // namespace gnss
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
||||||
|
#endif // BATCHING_API_CLINET_H
|
273
gps/android/location_api/GeofenceAPIClient.cpp
Normal file
273
gps/android/location_api/GeofenceAPIClient.cpp
Normal file
|
@ -0,0 +1,273 @@
|
||||||
|
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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 V1_0 {
|
||||||
|
namespace implementation {
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
if (mGnssGeofencingCbIface != 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::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;
|
||||||
|
|
||||||
|
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__);
|
||||||
|
// TODO locAPIRemoveAllGeofences();
|
||||||
|
}
|
||||||
|
|
||||||
|
// callbacks
|
||||||
|
void GeofenceAPIClient::onGeofenceBreachCb(GeofenceBreachNotification geofenceBreachNotification)
|
||||||
|
{
|
||||||
|
LOC_LOGD("%s]: (%zu)", __FUNCTION__, geofenceBreachNotification.count);
|
||||||
|
if (mGnssGeofencingCbIface != 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 = mGnssGeofencingCbIface->gnssGeofenceTransitionCb(
|
||||||
|
geofenceBreachNotification.ids[i], gnssLocation, transition,
|
||||||
|
static_cast<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);
|
||||||
|
if (mGnssGeofencingCbIface != 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 = mGnssGeofencingCbIface->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);
|
||||||
|
if (mGnssGeofencingCbIface != 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 = mGnssGeofencingCbIface->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);
|
||||||
|
if (mGnssGeofencingCbIface != 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 = mGnssGeofencingCbIface->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);
|
||||||
|
if (mGnssGeofencingCbIface != 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 = mGnssGeofencingCbIface->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);
|
||||||
|
if (mGnssGeofencingCbIface != 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 = mGnssGeofencingCbIface->gnssGeofenceResumeCb(ids[i], status);
|
||||||
|
if (!r.isOk()) {
|
||||||
|
LOC_LOGE("%s] Error from gnssGeofenceResumeCb description=%s",
|
||||||
|
__func__, r.description().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace implementation
|
||||||
|
} // namespace V1_0
|
||||||
|
} // namespace gnss
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
76
gps/android/location_api/GeofenceAPIClient.h
Normal file
76
gps/android/location_api/GeofenceAPIClient.h
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GEOFENCE_API_CLINET_H
|
||||||
|
#define GEOFENCE_API_CLINET_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <android/hardware/gnss/1.0/IGnssGeofenceCallback.h>
|
||||||
|
#include <LocationAPIClientBase.h>
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
namespace hardware {
|
||||||
|
namespace gnss {
|
||||||
|
namespace V1_0 {
|
||||||
|
namespace implementation {
|
||||||
|
|
||||||
|
using ::android::sp;
|
||||||
|
|
||||||
|
class GeofenceAPIClient : public LocationAPIClientBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GeofenceAPIClient(const sp<IGnssGeofenceCallback>& callback);
|
||||||
|
virtual ~GeofenceAPIClient() = default;
|
||||||
|
|
||||||
|
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:
|
||||||
|
sp<IGnssGeofenceCallback> mGnssGeofencingCbIface;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace implementation
|
||||||
|
} // namespace V1_0
|
||||||
|
} // namespace gnss
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
||||||
|
#endif // GEOFENCE_API_CLINET_H
|
528
gps/android/location_api/GnssAPIClient.cpp
Normal file
528
gps/android/location_api/GnssAPIClient.cpp
Normal file
|
@ -0,0 +1,528 @@
|
||||||
|
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LOG_NDEBUG 0
|
||||||
|
#define LOG_TAG "LocSvc_GnssAPIClient"
|
||||||
|
|
||||||
|
#include <log_util.h>
|
||||||
|
#include <loc_cfg.h>
|
||||||
|
|
||||||
|
#include "LocationUtil.h"
|
||||||
|
#include "GnssAPIClient.h"
|
||||||
|
#include <LocDualContext.h>
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
namespace hardware {
|
||||||
|
namespace gnss {
|
||||||
|
namespace V1_0 {
|
||||||
|
namespace implementation {
|
||||||
|
|
||||||
|
static void convertGnssSvStatus(GnssSvNotification& in, IGnssCallback::GnssSvStatus& out);
|
||||||
|
|
||||||
|
GnssAPIClient::GnssAPIClient(const sp<IGnssCallback>& gpsCb,
|
||||||
|
const sp<IGnssNiCallback>& niCb) :
|
||||||
|
LocationAPIClientBase(),
|
||||||
|
mGnssCbIface(nullptr),
|
||||||
|
mGnssNiCbIface(nullptr),
|
||||||
|
mControlClient(new LocationAPIControlClient()),
|
||||||
|
mLocationCapabilitiesMask(0),
|
||||||
|
mLocationCapabilitiesCached(false)
|
||||||
|
{
|
||||||
|
LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb);
|
||||||
|
|
||||||
|
// set default LocationOptions.
|
||||||
|
memset(&mLocationOptions, 0, sizeof(LocationOptions));
|
||||||
|
mLocationOptions.size = sizeof(LocationOptions);
|
||||||
|
mLocationOptions.minInterval = 1000;
|
||||||
|
mLocationOptions.minDistance = 0;
|
||||||
|
mLocationOptions.mode = GNSS_SUPL_MODE_STANDALONE;
|
||||||
|
|
||||||
|
gnssUpdateCallbacks(gpsCb, niCb);
|
||||||
|
}
|
||||||
|
|
||||||
|
GnssAPIClient::~GnssAPIClient()
|
||||||
|
{
|
||||||
|
LOC_LOGD("%s]: ()", __FUNCTION__);
|
||||||
|
if (mControlClient) {
|
||||||
|
delete mControlClient;
|
||||||
|
mControlClient = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// for GpsInterface
|
||||||
|
void GnssAPIClient::gnssUpdateCallbacks(const sp<IGnssCallback>& gpsCb,
|
||||||
|
const sp<IGnssNiCallback>& niCb)
|
||||||
|
{
|
||||||
|
LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb);
|
||||||
|
|
||||||
|
mMutex.lock();
|
||||||
|
mGnssCbIface = gpsCb;
|
||||||
|
mGnssNiCbIface = niCb;
|
||||||
|
mMutex.unlock();
|
||||||
|
|
||||||
|
LocationCallbacks locationCallbacks;
|
||||||
|
memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
|
||||||
|
locationCallbacks.size = sizeof(LocationCallbacks);
|
||||||
|
|
||||||
|
locationCallbacks.trackingCb = nullptr;
|
||||||
|
if (mGnssCbIface != nullptr) {
|
||||||
|
locationCallbacks.trackingCb = [this](Location location) {
|
||||||
|
onTrackingCb(location);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
locationCallbacks.batchingCb = nullptr;
|
||||||
|
locationCallbacks.geofenceBreachCb = nullptr;
|
||||||
|
locationCallbacks.geofenceStatusCb = nullptr;
|
||||||
|
locationCallbacks.gnssLocationInfoCb = nullptr;
|
||||||
|
|
||||||
|
locationCallbacks.gnssNiCb = nullptr;
|
||||||
|
loc_core::ContextBase* context =
|
||||||
|
loc_core::LocDualContext::getLocFgContext(
|
||||||
|
NULL, NULL,
|
||||||
|
loc_core::LocDualContext::mLocationHalName, false);
|
||||||
|
if (mGnssNiCbIface != nullptr && !context->hasAgpsExtendedCapabilities()) {
|
||||||
|
LOC_LOGD("Registering NI CB");
|
||||||
|
locationCallbacks.gnssNiCb = [this](uint32_t id, GnssNiNotification gnssNiNotification) {
|
||||||
|
onGnssNiCb(id, gnssNiNotification);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
locationCallbacks.gnssSvCb = nullptr;
|
||||||
|
if (mGnssCbIface != nullptr) {
|
||||||
|
locationCallbacks.gnssSvCb = [this](GnssSvNotification gnssSvNotification) {
|
||||||
|
onGnssSvCb(gnssSvNotification);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
locationCallbacks.gnssNmeaCb = nullptr;
|
||||||
|
if (mGnssCbIface != nullptr) {
|
||||||
|
locationCallbacks.gnssNmeaCb = [this](GnssNmeaNotification gnssNmeaNotification) {
|
||||||
|
onGnssNmeaCb(gnssNmeaNotification);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
locationCallbacks.gnssMeasurementsCb = nullptr;
|
||||||
|
|
||||||
|
locAPISetCallbacks(locationCallbacks);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GnssAPIClient::gnssStart()
|
||||||
|
{
|
||||||
|
LOC_LOGD("%s]: ()", __FUNCTION__);
|
||||||
|
bool retVal = true;
|
||||||
|
locAPIStartTracking(mLocationOptions);
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GnssAPIClient::gnssStop()
|
||||||
|
{
|
||||||
|
LOC_LOGD("%s]: ()", __FUNCTION__);
|
||||||
|
bool retVal = true;
|
||||||
|
locAPIStopTracking();
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GnssAPIClient::gnssSetPositionMode(IGnss::GnssPositionMode mode,
|
||||||
|
IGnss::GnssPositionRecurrence recurrence, uint32_t minIntervalMs,
|
||||||
|
uint32_t preferredAccuracyMeters, uint32_t preferredTimeMs)
|
||||||
|
{
|
||||||
|
LOC_LOGD("%s]: (%d %d %d %d %d)", __FUNCTION__,
|
||||||
|
(int)mode, recurrence, minIntervalMs, preferredAccuracyMeters, preferredTimeMs);
|
||||||
|
bool retVal = true;
|
||||||
|
memset(&mLocationOptions, 0, sizeof(LocationOptions));
|
||||||
|
mLocationOptions.size = sizeof(LocationOptions);
|
||||||
|
mLocationOptions.minInterval = minIntervalMs;
|
||||||
|
mLocationOptions.minDistance = preferredAccuracyMeters;
|
||||||
|
if (mode == IGnss::GnssPositionMode::STANDALONE)
|
||||||
|
mLocationOptions.mode = GNSS_SUPL_MODE_STANDALONE;
|
||||||
|
else if (mode == IGnss::GnssPositionMode::MS_BASED)
|
||||||
|
mLocationOptions.mode = GNSS_SUPL_MODE_MSB;
|
||||||
|
else if (mode == IGnss::GnssPositionMode::MS_ASSISTED)
|
||||||
|
mLocationOptions.mode = GNSS_SUPL_MODE_MSA;
|
||||||
|
else {
|
||||||
|
LOC_LOGD("%s]: invalid GnssPositionMode: %d", __FUNCTION__, (int)mode);
|
||||||
|
retVal = false;
|
||||||
|
}
|
||||||
|
locAPIUpdateTrackingOptions(mLocationOptions);
|
||||||
|
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 = GNSS_NI_RESPONSE_IGNORE;
|
||||||
|
if (userResponse == IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT)
|
||||||
|
data = GNSS_NI_RESPONSE_ACCEPT;
|
||||||
|
else if (userResponse == IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY)
|
||||||
|
data = GNSS_NI_RESPONSE_DENY;
|
||||||
|
else if (userResponse == IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP)
|
||||||
|
data = GNSS_NI_RESPONSE_NO_RESPONSE;
|
||||||
|
else {
|
||||||
|
LOC_LOGD("%s]: invalid GnssUserResponseType: %d", __FUNCTION__, (int)userResponse);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
|
||||||
|
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]: (%02x)", __FUNCTION__, capabilitiesMask);
|
||||||
|
mLocationCapabilitiesMask = capabilitiesMask;
|
||||||
|
mLocationCapabilitiesCached = true;
|
||||||
|
|
||||||
|
mMutex.lock();
|
||||||
|
auto gnssCbIface(mGnssCbIface);
|
||||||
|
mMutex.unlock();
|
||||||
|
|
||||||
|
if (gnssCbIface != nullptr) {
|
||||||
|
uint32_t data = 0;
|
||||||
|
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 |= IGnssCallback::Capabilities::GEOFENCING;
|
||||||
|
if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT)
|
||||||
|
data |= 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;
|
||||||
|
auto r = gnssCbIface->gnssSetCapabilitesCb(data);
|
||||||
|
if (!r.isOk()) {
|
||||||
|
LOC_LOGE("%s] Error from gnssSetCapabilitesCb description=%s",
|
||||||
|
__func__, r.description().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (gnssCbIface != nullptr) {
|
||||||
|
IGnssCallback::GnssSystemInfo gnssInfo;
|
||||||
|
if (capabilitiesMask & LOCATION_CAPABILITIES_DEBUG_NMEA_BIT) {
|
||||||
|
gnssInfo.yearOfHw = 2017;
|
||||||
|
} else if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT) {
|
||||||
|
gnssInfo.yearOfHw = 2016;
|
||||||
|
} else {
|
||||||
|
gnssInfo.yearOfHw = 2015;
|
||||||
|
}
|
||||||
|
LOC_LOGV("%s:%d] set_system_info_cb (%d)", __FUNCTION__, __LINE__, gnssInfo.yearOfHw);
|
||||||
|
auto 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)
|
||||||
|
{
|
||||||
|
LOC_LOGD("%s]: (flags: %02x)", __FUNCTION__, location.flags);
|
||||||
|
mMutex.lock();
|
||||||
|
auto gnssCbIface(mGnssCbIface);
|
||||||
|
mMutex.unlock();
|
||||||
|
|
||||||
|
if (gnssCbIface != nullptr) {
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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: %zu)", __FUNCTION__, gnssSvNotification.count);
|
||||||
|
mMutex.lock();
|
||||||
|
auto gnssCbIface(mGnssCbIface);
|
||||||
|
mMutex.unlock();
|
||||||
|
|
||||||
|
if (gnssCbIface != nullptr) {
|
||||||
|
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);
|
||||||
|
mMutex.unlock();
|
||||||
|
|
||||||
|
if (gnssCbIface != nullptr) {
|
||||||
|
android::hardware::hidl_string nmeaString;
|
||||||
|
nmeaString.setToExternal(gnssNmeaNotification.nmea, gnssNmeaNotification.length);
|
||||||
|
auto r = gnssCbIface->gnssNmeaCb(
|
||||||
|
static_cast<GnssUtcTime>(gnssNmeaNotification.timestamp), nmeaString);
|
||||||
|
if (!r.isOk()) {
|
||||||
|
LOC_LOGE("%s] Error from gnssNmeaCb nmea=%s length=%zu description=%s", __func__,
|
||||||
|
gnssNmeaNotification.nmea, gnssNmeaNotification.length, r.description().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GnssAPIClient::onStartTrackingCb(LocationError error)
|
||||||
|
{
|
||||||
|
LOC_LOGD("%s]: (%d)", __FUNCTION__, error);
|
||||||
|
mMutex.lock();
|
||||||
|
auto gnssCbIface(mGnssCbIface);
|
||||||
|
mMutex.unlock();
|
||||||
|
|
||||||
|
if (error == LOCATION_ERROR_SUCCESS && 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);
|
||||||
|
mMutex.unlock();
|
||||||
|
|
||||||
|
if (error == LOCATION_ERROR_SUCCESS && 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, IGnssCallback::GnssSvStatus& out)
|
||||||
|
{
|
||||||
|
memset(&out, 0, sizeof(IGnssCallback::GnssSvStatus));
|
||||||
|
out.numSvs = in.count;
|
||||||
|
if (out.numSvs > static_cast<uint32_t>(GnssMax::SVS_COUNT)) {
|
||||||
|
LOC_LOGW("%s]: Too many satellites %zd. Clamps to %d.",
|
||||||
|
__FUNCTION__, out.numSvs, GnssMax::SVS_COUNT);
|
||||||
|
out.numSvs = static_cast<uint32_t>(GnssMax::SVS_COUNT);
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < out.numSvs; i++) {
|
||||||
|
IGnssCallback::GnssSvInfo& info = out.gnssSvList[i];
|
||||||
|
info.svid = in.gnssSvs[i].svId;
|
||||||
|
convertGnssConstellationType(in.gnssSvs[i].type, info.constellation);
|
||||||
|
info.cN0Dbhz = in.gnssSvs[i].cN0Dbhz;
|
||||||
|
info.elevationDegrees = in.gnssSvs[i].elevation;
|
||||||
|
info.azimuthDegrees = in.gnssSvs[i].azimuth;
|
||||||
|
info.svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE);
|
||||||
|
if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT)
|
||||||
|
info.svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
|
||||||
|
if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT)
|
||||||
|
info.svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA;
|
||||||
|
if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT)
|
||||||
|
info.svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace implementation
|
||||||
|
} // namespace V1_0
|
||||||
|
} // namespace gnss
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
106
gps/android/location_api/GnssAPIClient.h
Normal file
106
gps/android/location_api/GnssAPIClient.h
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GNSS_API_CLINET_H
|
||||||
|
#define GNSS_API_CLINET_H
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <android/hardware/gnss/1.0/IGnss.h>
|
||||||
|
#include <android/hardware/gnss/1.0/IGnssCallback.h>
|
||||||
|
#include <android/hardware/gnss/1.0/IGnssNiCallback.h>
|
||||||
|
#include <LocationAPIClientBase.h>
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
namespace hardware {
|
||||||
|
namespace gnss {
|
||||||
|
namespace V1_0 {
|
||||||
|
namespace implementation {
|
||||||
|
|
||||||
|
using ::android::sp;
|
||||||
|
|
||||||
|
class GnssAPIClient : public LocationAPIClientBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GnssAPIClient(const sp<IGnssCallback>& gpsCb,
|
||||||
|
const sp<IGnssNiCallback>& niCb);
|
||||||
|
virtual ~GnssAPIClient();
|
||||||
|
GnssAPIClient(const GnssAPIClient&) = delete;
|
||||||
|
GnssAPIClient& operator=(const GnssAPIClient&) = delete;
|
||||||
|
|
||||||
|
// for GpsInterface
|
||||||
|
void gnssUpdateCallbacks(const sp<IGnssCallback>& gpsCb,
|
||||||
|
const sp<IGnssNiCallback>& niCb);
|
||||||
|
bool gnssStart();
|
||||||
|
bool gnssStop();
|
||||||
|
bool gnssSetPositionMode(IGnss::GnssPositionMode mode,
|
||||||
|
IGnss::GnssPositionRecurrence recurrence,
|
||||||
|
uint32_t minIntervalMs,
|
||||||
|
uint32_t preferredAccuracyMeters,
|
||||||
|
uint32_t preferredTimeMs);
|
||||||
|
|
||||||
|
// for GpsNiInterface
|
||||||
|
void gnssNiRespond(int32_t notifId, IGnssNiCallback::GnssUserResponseType userResponse);
|
||||||
|
|
||||||
|
// these apis using LocationAPIControlClient
|
||||||
|
void gnssDeleteAidingData(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 onStartTrackingCb(LocationError error) final;
|
||||||
|
void onStopTrackingCb(LocationError error) final;
|
||||||
|
|
||||||
|
private:
|
||||||
|
sp<IGnssCallback> mGnssCbIface;
|
||||||
|
sp<IGnssNiCallback> mGnssNiCbIface;
|
||||||
|
std::mutex mMutex;
|
||||||
|
LocationAPIControlClient* mControlClient;
|
||||||
|
LocationCapabilitiesMask mLocationCapabilitiesMask;
|
||||||
|
bool mLocationCapabilitiesCached;
|
||||||
|
LocationOptions mLocationOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace implementation
|
||||||
|
} // namespace V1_0
|
||||||
|
} // namespace gnss
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
||||||
|
#endif // GNSS_API_CLINET_H
|
153
gps/android/location_api/LocationUtil.cpp
Normal file
153
gps/android/location_api/LocationUtil.cpp
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <LocationUtil.h>
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
namespace hardware {
|
||||||
|
namespace gnss {
|
||||||
|
namespace V1_0 {
|
||||||
|
namespace implementation {
|
||||||
|
|
||||||
|
void convertGnssLocation(Location& in, GnssLocation& out)
|
||||||
|
{
|
||||||
|
memset(&out, 0, sizeof(GnssLocation));
|
||||||
|
if (in.flags & LOCATION_HAS_LAT_LONG_BIT)
|
||||||
|
out.gnssLocationFlags |= GnssLocationFlags::HAS_LAT_LONG;
|
||||||
|
if (in.flags & LOCATION_HAS_ALTITUDE_BIT)
|
||||||
|
out.gnssLocationFlags |= GnssLocationFlags::HAS_ALTITUDE;
|
||||||
|
if (in.flags & LOCATION_HAS_SPEED_BIT)
|
||||||
|
out.gnssLocationFlags |= GnssLocationFlags::HAS_SPEED;
|
||||||
|
if (in.flags & LOCATION_HAS_BEARING_BIT)
|
||||||
|
out.gnssLocationFlags |= GnssLocationFlags::HAS_BEARING;
|
||||||
|
if (in.flags & LOCATION_HAS_ACCURACY_BIT)
|
||||||
|
out.gnssLocationFlags |= GnssLocationFlags::HAS_HORIZONTAL_ACCURACY;
|
||||||
|
if (in.flags & LOCATION_HAS_VERTICAL_ACCURACY_BIT)
|
||||||
|
out.gnssLocationFlags |= GnssLocationFlags::HAS_VERTICAL_ACCURACY;
|
||||||
|
if (in.flags & LOCATION_HAS_SPEED_ACCURACY_BIT)
|
||||||
|
out.gnssLocationFlags |= GnssLocationFlags::HAS_SPEED_ACCURACY;
|
||||||
|
if (in.flags & LOCATION_HAS_BEARING_ACCURACY_BIT)
|
||||||
|
out.gnssLocationFlags |= GnssLocationFlags::HAS_BEARING_ACCURACY;
|
||||||
|
out.latitudeDegrees = in.latitude;
|
||||||
|
out.longitudeDegrees = in.longitude;
|
||||||
|
out.altitudeMeters = in.altitude;
|
||||||
|
out.speedMetersPerSec = in.speed;
|
||||||
|
out.bearingDegrees = in.bearing;
|
||||||
|
out.horizontalAccuracyMeters = in.accuracy;
|
||||||
|
out.verticalAccuracyMeters = in.verticalAccuracy;
|
||||||
|
out.speedAccuracyMetersPerSecond = in.speedAccuracy;
|
||||||
|
out.bearingAccuracyDegrees = in.bearingAccuracy;
|
||||||
|
out.timestamp = static_cast<GnssUtcTime>(in.timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void convertGnssConstellationType(GnssSvType& in, GnssConstellationType& out)
|
||||||
|
{
|
||||||
|
switch(in) {
|
||||||
|
case GNSS_SV_TYPE_GPS:
|
||||||
|
out = GnssConstellationType::GPS;
|
||||||
|
break;
|
||||||
|
case GNSS_SV_TYPE_SBAS:
|
||||||
|
out = GnssConstellationType::SBAS;
|
||||||
|
break;
|
||||||
|
case GNSS_SV_TYPE_GLONASS:
|
||||||
|
out = GnssConstellationType::GLONASS;
|
||||||
|
break;
|
||||||
|
case GNSS_SV_TYPE_QZSS:
|
||||||
|
out = GnssConstellationType::QZSS;
|
||||||
|
break;
|
||||||
|
case GNSS_SV_TYPE_BEIDOU:
|
||||||
|
out = GnssConstellationType::BEIDOU;
|
||||||
|
break;
|
||||||
|
case GNSS_SV_TYPE_GALILEO:
|
||||||
|
out = GnssConstellationType::GALILEO;
|
||||||
|
break;
|
||||||
|
case GNSS_SV_TYPE_UNKNOWN:
|
||||||
|
default:
|
||||||
|
out = GnssConstellationType::UNKNOWN;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace implementation
|
||||||
|
} // namespace V1_0
|
||||||
|
} // namespace gnss
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
54
gps/android/location_api/LocationUtil.h
Normal file
54
gps/android/location_api/LocationUtil.h
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LOCATION_UTIL_H
|
||||||
|
#define LOCATION_UTIL_H
|
||||||
|
|
||||||
|
#include <android/hardware/gnss/1.0/types.h>
|
||||||
|
#include <LocationAPI.h>
|
||||||
|
#include <GnssDebug.h>
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
namespace hardware {
|
||||||
|
namespace gnss {
|
||||||
|
namespace V1_0 {
|
||||||
|
namespace implementation {
|
||||||
|
|
||||||
|
void convertGnssLocation(Location& in, GnssLocation& out);
|
||||||
|
void convertGnssConstellationType(GnssSvType& in, GnssConstellationType& out);
|
||||||
|
void convertGnssEphemerisType(GnssEphemerisType& in, GnssDebug::SatelliteEphemerisType& out);
|
||||||
|
void convertGnssEphemerisSource(GnssEphemerisSource& in, GnssDebug::SatelliteEphemerisSource& out);
|
||||||
|
void convertGnssEphemerisHealth(GnssEphemerisHealth& in, GnssDebug::SatelliteEphemerisHealth& out);
|
||||||
|
|
||||||
|
} // namespace implementation
|
||||||
|
} // namespace V1_0
|
||||||
|
} // namespace gnss
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
||||||
|
#endif // LOCATION_UTIL_H
|
263
gps/android/location_api/MeasurementAPIClient.cpp
Normal file
263
gps/android/location_api/MeasurementAPIClient.cpp
Normal file
|
@ -0,0 +1,263 @@
|
||||||
|
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LOG_NDEBUG 0
|
||||||
|
#define LOG_TAG "LocSvc_MeasurementAPIClient"
|
||||||
|
|
||||||
|
#include <log_util.h>
|
||||||
|
#include <loc_cfg.h>
|
||||||
|
|
||||||
|
#include "LocationUtil.h"
|
||||||
|
#include "MeasurementAPIClient.h"
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
namespace hardware {
|
||||||
|
namespace gnss {
|
||||||
|
namespace V1_0 {
|
||||||
|
namespace implementation {
|
||||||
|
|
||||||
|
static void convertGnssData(GnssMeasurementsNotification& in,
|
||||||
|
IGnssMeasurementCallback::GnssData& out);
|
||||||
|
static void convertGnssMeasurement(GnssMeasurementsData& in,
|
||||||
|
IGnssMeasurementCallback::GnssMeasurement& out);
|
||||||
|
static void convertGnssClock(GnssMeasurementsClock& in, IGnssMeasurementCallback::GnssClock& out);
|
||||||
|
|
||||||
|
MeasurementAPIClient::MeasurementAPIClient() :
|
||||||
|
mGnssMeasurementCbIface(nullptr),
|
||||||
|
mTracking(false)
|
||||||
|
{
|
||||||
|
LOC_LOGD("%s]: ()", __FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
MeasurementAPIClient::~MeasurementAPIClient()
|
||||||
|
{
|
||||||
|
LOC_LOGD("%s]: ()", __FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
// for GpsInterface
|
||||||
|
Return<IGnssMeasurement::GnssMeasurementStatus>
|
||||||
|
MeasurementAPIClient::measurementSetCallback(const sp<IGnssMeasurementCallback>& callback)
|
||||||
|
{
|
||||||
|
LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
|
||||||
|
|
||||||
|
mMutex.lock();
|
||||||
|
mGnssMeasurementCbIface = callback;
|
||||||
|
mMutex.unlock();
|
||||||
|
|
||||||
|
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 != nullptr) {
|
||||||
|
locationCallbacks.gnssMeasurementsCb =
|
||||||
|
[this](GnssMeasurementsNotification gnssMeasurementsNotification) {
|
||||||
|
onGnssMeasurementsCb(gnssMeasurementsNotification);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
locAPISetCallbacks(locationCallbacks);
|
||||||
|
LocationOptions options;
|
||||||
|
memset(&options, 0, sizeof(LocationOptions));
|
||||||
|
options.size = sizeof(LocationOptions);
|
||||||
|
options.minInterval = 1000;
|
||||||
|
options.mode = GNSS_SUPL_MODE_STANDALONE;
|
||||||
|
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: %zu active: %zu)",
|
||||||
|
__FUNCTION__, gnssMeasurementsNotification.count, mTracking);
|
||||||
|
if (mTracking) {
|
||||||
|
mMutex.lock();
|
||||||
|
auto gnssMeasurementCbIface(mGnssMeasurementCbIface);
|
||||||
|
mMutex.unlock();
|
||||||
|
|
||||||
|
if (gnssMeasurementCbIface != nullptr) {
|
||||||
|
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,
|
||||||
|
IGnssMeasurementCallback::GnssMeasurement& out)
|
||||||
|
{
|
||||||
|
memset(&out, 0, sizeof(IGnssMeasurementCallback::GnssMeasurement));
|
||||||
|
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;
|
||||||
|
out.svid = in.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(IGnssMeasurementCallback::GnssClock));
|
||||||
|
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 convertGnssData(GnssMeasurementsNotification& in,
|
||||||
|
IGnssMeasurementCallback::GnssData& out)
|
||||||
|
{
|
||||||
|
out.measurementCount = in.count;
|
||||||
|
if (out.measurementCount > static_cast<uint32_t>(GnssMax::SVS_COUNT)) {
|
||||||
|
LOC_LOGW("%s]: Too many measurement %zd. Clamps to %d.",
|
||||||
|
__FUNCTION__, out.measurementCount, GnssMax::SVS_COUNT);
|
||||||
|
out.measurementCount = static_cast<uint32_t>(GnssMax::SVS_COUNT);
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < out.measurementCount; i++) {
|
||||||
|
convertGnssMeasurement(in.measurements[i], out.measurements[i]);
|
||||||
|
}
|
||||||
|
convertGnssClock(in.clock, out.clock);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace implementation
|
||||||
|
} // namespace V1_0
|
||||||
|
} // namespace gnss
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
75
gps/android/location_api/MeasurementAPIClient.h
Normal file
75
gps/android/location_api/MeasurementAPIClient.h
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MEASUREMENT_API_CLINET_H
|
||||||
|
#define MEASUREMENT_API_CLINET_H
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <android/hardware/gnss/1.0/IGnssMeasurement.h>
|
||||||
|
#include <android/hardware/gnss/1.0/IGnssMeasurementCallback.h>
|
||||||
|
#include <LocationAPIClientBase.h>
|
||||||
|
#include <hidl/Status.h>
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
namespace hardware {
|
||||||
|
namespace gnss {
|
||||||
|
namespace V1_0 {
|
||||||
|
namespace implementation {
|
||||||
|
|
||||||
|
using ::android::hardware::gnss::V1_0::IGnssMeasurement;
|
||||||
|
using ::android::sp;
|
||||||
|
|
||||||
|
class MeasurementAPIClient : public LocationAPIClientBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MeasurementAPIClient();
|
||||||
|
virtual ~MeasurementAPIClient();
|
||||||
|
MeasurementAPIClient(const MeasurementAPIClient&) = delete;
|
||||||
|
MeasurementAPIClient& operator=(const MeasurementAPIClient&) = delete;
|
||||||
|
|
||||||
|
// for GpsMeasurementInterface
|
||||||
|
Return<IGnssMeasurement::GnssMeasurementStatus> measurementSetCallback(
|
||||||
|
const sp<IGnssMeasurementCallback>& callback);
|
||||||
|
void measurementClose();
|
||||||
|
|
||||||
|
// callbacks we are interested in
|
||||||
|
void onGnssMeasurementsCb(GnssMeasurementsNotification gnssMeasurementsNotification) final;
|
||||||
|
|
||||||
|
private:
|
||||||
|
sp<IGnssMeasurementCallback> mGnssMeasurementCbIface;
|
||||||
|
std::mutex mMutex;
|
||||||
|
bool mTracking;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace implementation
|
||||||
|
} // namespace V1_0
|
||||||
|
} // namespace gnss
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
||||||
|
#endif // MEASUREMENT_API_CLINET_H
|
31
gps/android/service.cpp
Normal file
31
gps/android/service.cpp
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
* Not a Contribution
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LOG_TAG "android.hardware.gnss@1.0-service-qti"
|
||||||
|
|
||||||
|
#include <android/hardware/gnss/1.0/IGnss.h>
|
||||||
|
#include <hidl/LegacySupport.h>
|
||||||
|
|
||||||
|
using android::hardware::gnss::V1_0::IGnss;
|
||||||
|
using android::hardware::defaultPassthroughServiceImplementation;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
return defaultPassthroughServiceImplementation<IGnss>();
|
||||||
|
}
|
91
gps/configure.ac
Normal file
91
gps/configure.ac
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
# configure.ac -- Autoconf script for gps loc_hal
|
||||||
|
#
|
||||||
|
# Process this file with autoconf to produce a configure script
|
||||||
|
|
||||||
|
# Requires autoconf tool later than 2.61
|
||||||
|
AC_PREREQ(2.61)
|
||||||
|
# Initialize the gps loc-hal package version 1.0.0
|
||||||
|
AC_INIT([loc-hal],1.0.0)
|
||||||
|
# Does not strictly follow GNU Coding standards
|
||||||
|
AM_INIT_AUTOMAKE([foreign])
|
||||||
|
# Disables auto rebuilding of configure, Makefile.ins
|
||||||
|
AM_MAINTAINER_MODE
|
||||||
|
# Verifies the --srcdir is correct by checking for the path
|
||||||
|
AC_CONFIG_SRCDIR([utils/loc_cfg.cpp])
|
||||||
|
# defines some macros variable to be included by source
|
||||||
|
AC_CONFIG_HEADERS([config.h])
|
||||||
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
|
|
||||||
|
# Checks for programs.
|
||||||
|
AC_PROG_LIBTOOL
|
||||||
|
AC_PROG_CXX
|
||||||
|
AC_PROG_CC
|
||||||
|
AM_PROG_CC_C_O
|
||||||
|
AC_PROG_AWK
|
||||||
|
AC_PROG_CPP
|
||||||
|
AC_PROG_INSTALL
|
||||||
|
AC_PROG_LN_S
|
||||||
|
AC_PROG_MAKE_SET
|
||||||
|
PKG_PROG_PKG_CONFIG
|
||||||
|
|
||||||
|
# Checks for libraries.
|
||||||
|
PKG_CHECK_MODULES([QMI], [qmi])
|
||||||
|
AC_SUBST([QMI_CFLAGS])
|
||||||
|
AC_SUBST([QMI_LIBS])
|
||||||
|
|
||||||
|
PKG_CHECK_MODULES([QMIF], [qmi-framework])
|
||||||
|
AC_SUBST([QMIF_CFLAGS])
|
||||||
|
AC_SUBST([QMIF_LIBS])
|
||||||
|
|
||||||
|
PKG_CHECK_MODULES([DATA], [data])
|
||||||
|
AC_SUBST([DATA_CFLAGS])
|
||||||
|
AC_SUBST([DATA_LIBS])
|
||||||
|
|
||||||
|
PKG_CHECK_MODULES([LOCPLA], [loc-pla])
|
||||||
|
AC_SUBST([LOCPLA_CFLAGS])
|
||||||
|
AC_SUBST([LOCPLA_LIBS])
|
||||||
|
|
||||||
|
PKG_CHECK_MODULES([GPSUTILS], [gps-utils])
|
||||||
|
AC_SUBST([GPSUTILS_CFLAGS])
|
||||||
|
AC_SUBST([GPSUTILS_LIBS])
|
||||||
|
|
||||||
|
AC_ARG_WITH([core_includes],
|
||||||
|
AC_HELP_STRING([--with-core-includes=@<:@dir@:>@],
|
||||||
|
[Specify the location of the core headers]),
|
||||||
|
[core_incdir=$withval],
|
||||||
|
with_core_includes=no)
|
||||||
|
|
||||||
|
if test "x$with_core_includes" != "xno"; then
|
||||||
|
CPPFLAGS="${CPPFLAGS} -I${core_incdir}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_SUBST([CPPFLAGS])
|
||||||
|
|
||||||
|
AC_ARG_WITH([glib],
|
||||||
|
AC_HELP_STRING([--with-glib],
|
||||||
|
[enable glib, building HLOS systems which use glib]))
|
||||||
|
|
||||||
|
if (test "x${with_glib}" = "xyes"); then
|
||||||
|
AC_DEFINE(ENABLE_USEGLIB, 1, [Define if HLOS systems uses glib])
|
||||||
|
PKG_CHECK_MODULES(GTHREAD, gthread-2.0 >= 2.16, dummy=yes,
|
||||||
|
AC_MSG_ERROR(GThread >= 2.16 is required))
|
||||||
|
PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.16, dummy=yes,
|
||||||
|
AC_MSG_ERROR(GLib >= 2.16 is required))
|
||||||
|
GLIB_CFLAGS="$GLIB_CFLAGS $GTHREAD_CFLAGS"
|
||||||
|
GLIB_LIBS="$GLIB_LIBS $GTHREAD_LIBS"
|
||||||
|
|
||||||
|
AC_SUBST(GLIB_CFLAGS)
|
||||||
|
AC_SUBST(GLIB_LIBS)
|
||||||
|
fi
|
||||||
|
|
||||||
|
AM_CONDITIONAL(USE_GLIB, test "x${with_glib}" = "xyes")
|
||||||
|
|
||||||
|
AC_CONFIG_FILES([ \
|
||||||
|
Makefile \
|
||||||
|
core/Makefile \
|
||||||
|
location/Makefile \
|
||||||
|
gnss/Makefile \
|
||||||
|
loc-hal.pc \
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_OUTPUT
|
69
gps/core/Android.mk
Normal file
69
gps/core/Android.mk
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)
|
||||||
|
ifneq ($(BUILD_TINY_ANDROID),true)
|
||||||
|
|
||||||
|
LOCAL_PATH := $(call my-dir)
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE := libloc_core
|
||||||
|
LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib
|
||||||
|
LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64
|
||||||
|
LOCAL_MODULE_TAGS := optional
|
||||||
|
|
||||||
|
ifeq ($(TARGET_DEVICE),apq8026_lw)
|
||||||
|
LOCAL_CFLAGS += -DPDK_FEATURE_SET
|
||||||
|
else ifeq ($(BOARD_VENDOR_QCOM_LOC_PDK_FEATURE_SET),true)
|
||||||
|
LOCAL_CFLAGS += -DPDK_FEATURE_SET
|
||||||
|
endif
|
||||||
|
|
||||||
|
LOCAL_SHARED_LIBRARIES := \
|
||||||
|
liblog \
|
||||||
|
libutils \
|
||||||
|
libcutils \
|
||||||
|
libgps.utils \
|
||||||
|
libdl \
|
||||||
|
liblog \
|
||||||
|
libloc_pla
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES += \
|
||||||
|
LocApiBase.cpp \
|
||||||
|
LocAdapterBase.cpp \
|
||||||
|
ContextBase.cpp \
|
||||||
|
LocDualContext.cpp \
|
||||||
|
loc_core_log.cpp \
|
||||||
|
data-items/DataItemsFactoryProxy.cpp \
|
||||||
|
data-items/common/ClientIndex.cpp \
|
||||||
|
data-items/common/DataItemIndex.cpp \
|
||||||
|
data-items/common/IndexFactory.cpp \
|
||||||
|
SystemStatusOsObserver.cpp \
|
||||||
|
SystemStatus.cpp
|
||||||
|
|
||||||
|
LOCAL_CFLAGS += \
|
||||||
|
-fno-short-enums \
|
||||||
|
-D_ANDROID_
|
||||||
|
|
||||||
|
LOCAL_C_INCLUDES:= \
|
||||||
|
$(LOCAL_PATH)/data-items \
|
||||||
|
$(LOCAL_PATH)/data-items/common \
|
||||||
|
$(LOCAL_PATH)/observer \
|
||||||
|
|
||||||
|
LOCAL_HEADER_LIBRARIES := \
|
||||||
|
libgps.utils_headers \
|
||||||
|
libloc_pla_headers \
|
||||||
|
liblocation_api_headers
|
||||||
|
|
||||||
|
LOCAL_CFLAGS += $(GNSS_CFLAGS)
|
||||||
|
|
||||||
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
LOCAL_MODULE := libloc_core_headers
|
||||||
|
LOCAL_EXPORT_C_INCLUDE_DIRS := \
|
||||||
|
$(LOCAL_PATH) \
|
||||||
|
$(LOCAL_PATH)/data-items \
|
||||||
|
$(LOCAL_PATH)/data-items/common \
|
||||||
|
$(LOCAL_PATH)/observer
|
||||||
|
include $(BUILD_HEADER_LIBRARY)
|
||||||
|
|
||||||
|
endif # not BUILD_TINY_ANDROID
|
||||||
|
endif # BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE
|
248
gps/core/ContextBase.cpp
Normal file
248
gps/core/ContextBase.cpp
Normal file
|
@ -0,0 +1,248 @@
|
||||||
|
/* Copyright (c) 2011-2014,2016-2017 The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define LOG_NDEBUG 0
|
||||||
|
#define LOG_TAG "LocSvc_CtxBase"
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <cutils/sched_policy.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <ContextBase.h>
|
||||||
|
#include <msg_q.h>
|
||||||
|
#include <loc_target.h>
|
||||||
|
#include <platform_lib_includes.h>
|
||||||
|
#include <loc_log.h>
|
||||||
|
|
||||||
|
namespace loc_core {
|
||||||
|
|
||||||
|
loc_gps_cfg_s_type ContextBase::mGps_conf {};
|
||||||
|
loc_sap_cfg_s_type ContextBase::mSap_conf {};
|
||||||
|
|
||||||
|
const loc_param_s_type ContextBase::mGps_conf_table[] =
|
||||||
|
{
|
||||||
|
{"GPS_LOCK", &mGps_conf.GPS_LOCK, NULL, 'n'},
|
||||||
|
{"SUPL_VER", &mGps_conf.SUPL_VER, NULL, 'n'},
|
||||||
|
{"LPP_PROFILE", &mGps_conf.LPP_PROFILE, NULL, 'n'},
|
||||||
|
{"A_GLONASS_POS_PROTOCOL_SELECT", &mGps_conf.A_GLONASS_POS_PROTOCOL_SELECT, NULL, 'n'},
|
||||||
|
{"LPPE_CP_TECHNOLOGY", &mGps_conf.LPPE_CP_TECHNOLOGY, NULL, 'n'},
|
||||||
|
{"LPPE_UP_TECHNOLOGY", &mGps_conf.LPPE_UP_TECHNOLOGY, NULL, 'n'},
|
||||||
|
{"AGPS_CERT_WRITABLE_MASK", &mGps_conf.AGPS_CERT_WRITABLE_MASK, NULL, 'n'},
|
||||||
|
{"SUPL_MODE", &mGps_conf.SUPL_MODE, NULL, 'n'},
|
||||||
|
{"SUPL_ES", &mGps_conf.SUPL_ES, NULL, 'n'},
|
||||||
|
{"INTERMEDIATE_POS", &mGps_conf.INTERMEDIATE_POS, NULL, 'n'},
|
||||||
|
{"ACCURACY_THRES", &mGps_conf.ACCURACY_THRES, NULL, 'n'},
|
||||||
|
{"NMEA_PROVIDER", &mGps_conf.NMEA_PROVIDER, NULL, 'n'},
|
||||||
|
{"CAPABILITIES", &mGps_conf.CAPABILITIES, NULL, 'n'},
|
||||||
|
{"XTRA_VERSION_CHECK", &mGps_conf.XTRA_VERSION_CHECK, NULL, 'n'},
|
||||||
|
{"XTRA_SERVER_1", &mGps_conf.XTRA_SERVER_1, NULL, 's'},
|
||||||
|
{"XTRA_SERVER_2", &mGps_conf.XTRA_SERVER_2, NULL, 's'},
|
||||||
|
{"XTRA_SERVER_3", &mGps_conf.XTRA_SERVER_3, NULL, 's'},
|
||||||
|
{"USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL", &mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL, NULL, 'n'},
|
||||||
|
{"AGPS_CONFIG_INJECT", &mGps_conf.AGPS_CONFIG_INJECT, NULL, 'n'},
|
||||||
|
{"EXTERNAL_DR_ENABLED", &mGps_conf.EXTERNAL_DR_ENABLED, NULL, 'n'},
|
||||||
|
};
|
||||||
|
|
||||||
|
const loc_param_s_type ContextBase::mSap_conf_table[] =
|
||||||
|
{
|
||||||
|
{"GYRO_BIAS_RANDOM_WALK", &mSap_conf.GYRO_BIAS_RANDOM_WALK, &mSap_conf.GYRO_BIAS_RANDOM_WALK_VALID, 'f'},
|
||||||
|
{"ACCEL_RANDOM_WALK_SPECTRAL_DENSITY", &mSap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY, &mSap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'},
|
||||||
|
{"ANGLE_RANDOM_WALK_SPECTRAL_DENSITY", &mSap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY, &mSap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'},
|
||||||
|
{"RATE_RANDOM_WALK_SPECTRAL_DENSITY", &mSap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY, &mSap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'},
|
||||||
|
{"VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY", &mSap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY, &mSap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'},
|
||||||
|
{"SENSOR_ACCEL_BATCHES_PER_SEC", &mSap_conf.SENSOR_ACCEL_BATCHES_PER_SEC, NULL, 'n'},
|
||||||
|
{"SENSOR_ACCEL_SAMPLES_PER_BATCH", &mSap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH, NULL, 'n'},
|
||||||
|
{"SENSOR_GYRO_BATCHES_PER_SEC", &mSap_conf.SENSOR_GYRO_BATCHES_PER_SEC, NULL, 'n'},
|
||||||
|
{"SENSOR_GYRO_SAMPLES_PER_BATCH", &mSap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH, NULL, 'n'},
|
||||||
|
{"SENSOR_ACCEL_BATCHES_PER_SEC_HIGH", &mSap_conf.SENSOR_ACCEL_BATCHES_PER_SEC_HIGH, NULL, 'n'},
|
||||||
|
{"SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH", &mSap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH, NULL, 'n'},
|
||||||
|
{"SENSOR_GYRO_BATCHES_PER_SEC_HIGH", &mSap_conf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH, NULL, 'n'},
|
||||||
|
{"SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH", &mSap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH, NULL, 'n'},
|
||||||
|
{"SENSOR_CONTROL_MODE", &mSap_conf.SENSOR_CONTROL_MODE, NULL, 'n'},
|
||||||
|
{"SENSOR_USAGE", &mSap_conf.SENSOR_USAGE, NULL, 'n'},
|
||||||
|
{"SENSOR_ALGORITHM_CONFIG_MASK", &mSap_conf.SENSOR_ALGORITHM_CONFIG_MASK, NULL, 'n'},
|
||||||
|
{"SENSOR_PROVIDER", &mSap_conf.SENSOR_PROVIDER, NULL, 'n'}
|
||||||
|
};
|
||||||
|
|
||||||
|
void ContextBase::readConfig()
|
||||||
|
{
|
||||||
|
/*Defaults for gps.conf*/
|
||||||
|
mGps_conf.INTERMEDIATE_POS = 0;
|
||||||
|
mGps_conf.ACCURACY_THRES = 0;
|
||||||
|
mGps_conf.NMEA_PROVIDER = 0;
|
||||||
|
mGps_conf.GPS_LOCK = 0;
|
||||||
|
mGps_conf.SUPL_VER = 0x10000;
|
||||||
|
mGps_conf.SUPL_MODE = 0x1;
|
||||||
|
mGps_conf.SUPL_ES = 0;
|
||||||
|
mGps_conf.CAPABILITIES = 0x7;
|
||||||
|
/* LTE Positioning Profile configuration is disable by default*/
|
||||||
|
mGps_conf.LPP_PROFILE = 0;
|
||||||
|
/*By default no positioning protocol is selected on A-GLONASS system*/
|
||||||
|
mGps_conf.A_GLONASS_POS_PROTOCOL_SELECT = 0;
|
||||||
|
/*XTRA version check is disabled by default*/
|
||||||
|
mGps_conf.XTRA_VERSION_CHECK=0;
|
||||||
|
/*Use emergency PDN by default*/
|
||||||
|
mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL = 1;
|
||||||
|
/* By default no LPPe CP technology is enabled*/
|
||||||
|
mGps_conf.LPPE_CP_TECHNOLOGY = 0;
|
||||||
|
/* By default no LPPe UP technology is enabled*/
|
||||||
|
mGps_conf.LPPE_UP_TECHNOLOGY = 0;
|
||||||
|
|
||||||
|
/*Defaults for sap.conf*/
|
||||||
|
mSap_conf.GYRO_BIAS_RANDOM_WALK = 0;
|
||||||
|
mSap_conf.SENSOR_ACCEL_BATCHES_PER_SEC = 2;
|
||||||
|
mSap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH = 5;
|
||||||
|
mSap_conf.SENSOR_GYRO_BATCHES_PER_SEC = 2;
|
||||||
|
mSap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH = 5;
|
||||||
|
mSap_conf.SENSOR_ACCEL_BATCHES_PER_SEC_HIGH = 4;
|
||||||
|
mSap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH = 25;
|
||||||
|
mSap_conf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH = 4;
|
||||||
|
mSap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH = 25;
|
||||||
|
mSap_conf.SENSOR_CONTROL_MODE = 0; /* AUTO */
|
||||||
|
mSap_conf.SENSOR_USAGE = 0; /* Enabled */
|
||||||
|
mSap_conf.SENSOR_ALGORITHM_CONFIG_MASK = 0; /* INS Disabled = FALSE*/
|
||||||
|
/* Values MUST be set by OEMs in configuration for sensor-assisted
|
||||||
|
navigation to work. There are NO default values */
|
||||||
|
mSap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY = 0;
|
||||||
|
mSap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY = 0;
|
||||||
|
mSap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY = 0;
|
||||||
|
mSap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY = 0;
|
||||||
|
mSap_conf.GYRO_BIAS_RANDOM_WALK_VALID = 0;
|
||||||
|
mSap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
|
||||||
|
mSap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
|
||||||
|
mSap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
|
||||||
|
mSap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
|
||||||
|
/* default provider is SSC */
|
||||||
|
mSap_conf.SENSOR_PROVIDER = 1;
|
||||||
|
|
||||||
|
/* None of the 10 slots for agps certificates are writable by default */
|
||||||
|
mGps_conf.AGPS_CERT_WRITABLE_MASK = 0;
|
||||||
|
|
||||||
|
/* inject supl config to modem with config values from config.xml or gps.conf, default 1 */
|
||||||
|
mGps_conf.AGPS_CONFIG_INJECT = 1;
|
||||||
|
|
||||||
|
UTIL_READ_CONF(LOC_PATH_GPS_CONF, mGps_conf_table);
|
||||||
|
UTIL_READ_CONF(LOC_PATH_SAP_CONF, mSap_conf_table);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ContextBase::getCarrierCapabilities() {
|
||||||
|
#define carrierMSA (uint32_t)0x2
|
||||||
|
#define carrierMSB (uint32_t)0x1
|
||||||
|
#define gpsConfMSA (uint32_t)0x4
|
||||||
|
#define gpsConfMSB (uint32_t)0x2
|
||||||
|
uint32_t capabilities = mGps_conf.CAPABILITIES;
|
||||||
|
if ((mGps_conf.SUPL_MODE & carrierMSA) != carrierMSA) {
|
||||||
|
capabilities &= ~gpsConfMSA;
|
||||||
|
}
|
||||||
|
if ((mGps_conf.SUPL_MODE & carrierMSB) != carrierMSB) {
|
||||||
|
capabilities &= ~gpsConfMSB;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOC_LOGV("getCarrierCapabilities: CAPABILITIES %x, SUPL_MODE %x, carrier capabilities %x",
|
||||||
|
mGps_conf.CAPABILITIES, mGps_conf.SUPL_MODE, capabilities);
|
||||||
|
return capabilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
LBSProxyBase* ContextBase::getLBSProxy(const char* libName)
|
||||||
|
{
|
||||||
|
LBSProxyBase* proxy = NULL;
|
||||||
|
LOC_LOGD("%s:%d]: getLBSProxy libname: %s\n", __func__, __LINE__, libName);
|
||||||
|
void* lib = dlopen(libName, RTLD_NOW);
|
||||||
|
|
||||||
|
if ((void*)NULL != lib) {
|
||||||
|
getLBSProxy_t* getter = (getLBSProxy_t*)dlsym(lib, "getLBSProxy");
|
||||||
|
if (NULL != getter) {
|
||||||
|
proxy = (*getter)();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOC_LOGW("%s:%d]: FAILED TO LOAD libname: %s\n", __func__, __LINE__, libName);
|
||||||
|
}
|
||||||
|
if (NULL == proxy) {
|
||||||
|
proxy = new LBSProxyBase();
|
||||||
|
}
|
||||||
|
LOC_LOGD("%s:%d]: Exiting\n", __func__, __LINE__);
|
||||||
|
return proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocApiBase* ContextBase::createLocApi(LOC_API_ADAPTER_EVENT_MASK_T exMask)
|
||||||
|
{
|
||||||
|
LocApiBase* locApi = NULL;
|
||||||
|
|
||||||
|
// Check the target
|
||||||
|
if (TARGET_NO_GNSS != loc_get_target()){
|
||||||
|
|
||||||
|
if (NULL == (locApi = mLBSProxy->getLocApi(mMsgTask, exMask, this))) {
|
||||||
|
void *handle = NULL;
|
||||||
|
//try to see if LocApiV02 is present
|
||||||
|
if ((handle = dlopen("libloc_api_v02.so", RTLD_NOW)) != NULL) {
|
||||||
|
LOC_LOGD("%s:%d]: libloc_api_v02.so is present", __func__, __LINE__);
|
||||||
|
getLocApi_t* getter = (getLocApi_t*) dlsym(handle, "getLocApi");
|
||||||
|
if (getter != NULL) {
|
||||||
|
LOC_LOGD("%s:%d]: getter is not NULL for LocApiV02", __func__,
|
||||||
|
__LINE__);
|
||||||
|
locApi = (*getter)(mMsgTask, exMask, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// only RPC is the option now
|
||||||
|
else {
|
||||||
|
LOC_LOGD("%s:%d]: libloc_api_v02.so is NOT present. Trying RPC",
|
||||||
|
__func__, __LINE__);
|
||||||
|
handle = dlopen("libloc_api-rpc-qc.so", RTLD_NOW);
|
||||||
|
if (NULL != handle) {
|
||||||
|
getLocApi_t* getter = (getLocApi_t*) dlsym(handle, "getLocApi");
|
||||||
|
if (NULL != getter) {
|
||||||
|
LOC_LOGD("%s:%d]: getter is not NULL in RPC", __func__,
|
||||||
|
__LINE__);
|
||||||
|
locApi = (*getter)(mMsgTask, exMask, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// locApi could still be NULL at this time
|
||||||
|
// we would then create a dummy one
|
||||||
|
if (NULL == locApi) {
|
||||||
|
locApi = new LocApiBase(mMsgTask, exMask, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return locApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
ContextBase::ContextBase(const MsgTask* msgTask,
|
||||||
|
LOC_API_ADAPTER_EVENT_MASK_T exMask,
|
||||||
|
const char* libName) :
|
||||||
|
mLBSProxy(getLBSProxy(libName)),
|
||||||
|
mMsgTask(msgTask),
|
||||||
|
mLocApi(createLocApi(exMask)),
|
||||||
|
mLocApiProxy(mLocApi->getLocApiProxy())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
148
gps/core/ContextBase.h
Normal file
148
gps/core/ContextBase.h
Normal file
|
@ -0,0 +1,148 @@
|
||||||
|
/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef __LOC_CONTEXT_BASE__
|
||||||
|
#define __LOC_CONTEXT_BASE__
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <MsgTask.h>
|
||||||
|
#include <LocApiBase.h>
|
||||||
|
#include <LBSProxyBase.h>
|
||||||
|
#include <loc_cfg.h>
|
||||||
|
|
||||||
|
#define MAX_XTRA_SERVER_URL_LENGTH 256
|
||||||
|
|
||||||
|
/* GPS.conf support */
|
||||||
|
/* NOTE: the implementaiton of the parser casts number
|
||||||
|
fields to 32 bit. To ensure all 'n' fields working,
|
||||||
|
they must all be 32 bit fields. */
|
||||||
|
typedef struct loc_gps_cfg_s
|
||||||
|
{
|
||||||
|
uint32_t INTERMEDIATE_POS;
|
||||||
|
uint32_t ACCURACY_THRES;
|
||||||
|
uint32_t SUPL_VER;
|
||||||
|
uint32_t SUPL_MODE;
|
||||||
|
uint32_t SUPL_ES;
|
||||||
|
uint32_t CAPABILITIES;
|
||||||
|
uint32_t LPP_PROFILE;
|
||||||
|
uint32_t XTRA_VERSION_CHECK;
|
||||||
|
char XTRA_SERVER_1[MAX_XTRA_SERVER_URL_LENGTH];
|
||||||
|
char XTRA_SERVER_2[MAX_XTRA_SERVER_URL_LENGTH];
|
||||||
|
char XTRA_SERVER_3[MAX_XTRA_SERVER_URL_LENGTH];
|
||||||
|
uint32_t USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL;
|
||||||
|
uint32_t NMEA_PROVIDER;
|
||||||
|
uint32_t GPS_LOCK;
|
||||||
|
uint32_t A_GLONASS_POS_PROTOCOL_SELECT;
|
||||||
|
uint32_t AGPS_CERT_WRITABLE_MASK;
|
||||||
|
uint32_t AGPS_CONFIG_INJECT;
|
||||||
|
uint32_t LPPE_CP_TECHNOLOGY;
|
||||||
|
uint32_t LPPE_UP_TECHNOLOGY;
|
||||||
|
uint32_t EXTERNAL_DR_ENABLED;
|
||||||
|
} loc_gps_cfg_s_type;
|
||||||
|
|
||||||
|
/* NOTE: the implementaiton of the parser casts number
|
||||||
|
fields to 32 bit. To ensure all 'n' fields working,
|
||||||
|
they must all be 32 bit fields. */
|
||||||
|
/* Meanwhile, *_valid fields are 8 bit fields, and 'f'
|
||||||
|
fields are double. Rigid as they are, it is the
|
||||||
|
the status quo, until the parsing mechanism is
|
||||||
|
change, that is. */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t GYRO_BIAS_RANDOM_WALK_VALID;
|
||||||
|
double GYRO_BIAS_RANDOM_WALK;
|
||||||
|
uint32_t SENSOR_ACCEL_BATCHES_PER_SEC;
|
||||||
|
uint32_t SENSOR_ACCEL_SAMPLES_PER_BATCH;
|
||||||
|
uint32_t SENSOR_GYRO_BATCHES_PER_SEC;
|
||||||
|
uint32_t SENSOR_GYRO_SAMPLES_PER_BATCH;
|
||||||
|
uint32_t SENSOR_ACCEL_BATCHES_PER_SEC_HIGH;
|
||||||
|
uint32_t SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH;
|
||||||
|
uint32_t SENSOR_GYRO_BATCHES_PER_SEC_HIGH;
|
||||||
|
uint32_t SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH;
|
||||||
|
uint32_t SENSOR_CONTROL_MODE;
|
||||||
|
uint32_t SENSOR_USAGE;
|
||||||
|
uint32_t SENSOR_ALGORITHM_CONFIG_MASK;
|
||||||
|
uint8_t ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID;
|
||||||
|
double ACCEL_RANDOM_WALK_SPECTRAL_DENSITY;
|
||||||
|
uint8_t ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID;
|
||||||
|
double ANGLE_RANDOM_WALK_SPECTRAL_DENSITY;
|
||||||
|
uint8_t RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID;
|
||||||
|
double RATE_RANDOM_WALK_SPECTRAL_DENSITY;
|
||||||
|
uint8_t VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID;
|
||||||
|
double VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY;
|
||||||
|
uint32_t SENSOR_PROVIDER;
|
||||||
|
} loc_sap_cfg_s_type;
|
||||||
|
|
||||||
|
namespace loc_core {
|
||||||
|
|
||||||
|
class LocAdapterBase;
|
||||||
|
|
||||||
|
class ContextBase {
|
||||||
|
static LBSProxyBase* getLBSProxy(const char* libName);
|
||||||
|
LocApiBase* createLocApi(LOC_API_ADAPTER_EVENT_MASK_T excludedMask);
|
||||||
|
static const loc_param_s_type mGps_conf_table[];
|
||||||
|
static const loc_param_s_type mSap_conf_table[];
|
||||||
|
protected:
|
||||||
|
const LBSProxyBase* mLBSProxy;
|
||||||
|
const MsgTask* mMsgTask;
|
||||||
|
LocApiBase* mLocApi;
|
||||||
|
LocApiProxyBase *mLocApiProxy;
|
||||||
|
public:
|
||||||
|
ContextBase(const MsgTask* msgTask,
|
||||||
|
LOC_API_ADAPTER_EVENT_MASK_T exMask,
|
||||||
|
const char* libName);
|
||||||
|
inline virtual ~ContextBase() { delete mLocApi; delete mLBSProxy; }
|
||||||
|
|
||||||
|
inline const MsgTask* getMsgTask() { return mMsgTask; }
|
||||||
|
inline LocApiBase* getLocApi() { return mLocApi; }
|
||||||
|
inline LocApiProxyBase* getLocApiProxy() { return mLocApiProxy; }
|
||||||
|
inline bool hasAgpsExtendedCapabilities() { return mLBSProxy->hasAgpsExtendedCapabilities(); }
|
||||||
|
inline bool hasCPIExtendedCapabilities() { return mLBSProxy->hasCPIExtendedCapabilities(); }
|
||||||
|
inline bool hasNativeXtraClient() { return mLBSProxy->hasNativeXtraClient(); }
|
||||||
|
inline void modemPowerVote(bool power) const { return mLBSProxy->modemPowerVote(power); }
|
||||||
|
inline void requestUlp(LocAdapterBase* adapter,
|
||||||
|
unsigned long capabilities) {
|
||||||
|
mLBSProxy->requestUlp(adapter, capabilities);
|
||||||
|
}
|
||||||
|
inline IzatDevId_t getIzatDevId() const {
|
||||||
|
return mLBSProxy->getIzatDevId();
|
||||||
|
}
|
||||||
|
inline void sendMsg(const LocMsg *msg) { getMsgTask()->sendMsg(msg); }
|
||||||
|
|
||||||
|
static loc_gps_cfg_s_type mGps_conf;
|
||||||
|
static loc_sap_cfg_s_type mSap_conf;
|
||||||
|
|
||||||
|
void readConfig();
|
||||||
|
static uint32_t getCarrierCapabilities();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace loc_core
|
||||||
|
|
||||||
|
#endif //__LOC_CONTEXT_BASE__
|
80
gps/core/LBSProxyBase.h
Normal file
80
gps/core/LBSProxyBase.h
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef IZAT_PROXY_BASE_H
|
||||||
|
#define IZAT_PROXY_BASE_H
|
||||||
|
#include <gps_extended.h>
|
||||||
|
#include <MsgTask.h>
|
||||||
|
|
||||||
|
namespace loc_core {
|
||||||
|
|
||||||
|
class LocApiBase;
|
||||||
|
class LocAdapterBase;
|
||||||
|
class ContextBase;
|
||||||
|
|
||||||
|
class LBSProxyBase {
|
||||||
|
friend class ContextBase;
|
||||||
|
inline virtual LocApiBase*
|
||||||
|
getLocApi(const MsgTask* msgTask,
|
||||||
|
LOC_API_ADAPTER_EVENT_MASK_T exMask,
|
||||||
|
ContextBase* context) const {
|
||||||
|
|
||||||
|
(void)msgTask;
|
||||||
|
(void)exMask;
|
||||||
|
(void)context;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
inline LBSProxyBase() {}
|
||||||
|
public:
|
||||||
|
inline virtual ~LBSProxyBase() {}
|
||||||
|
inline virtual void requestUlp(LocAdapterBase* adapter,
|
||||||
|
unsigned long capabilities) const {
|
||||||
|
|
||||||
|
(void)adapter;
|
||||||
|
(void)capabilities;
|
||||||
|
}
|
||||||
|
inline virtual bool hasAgpsExtendedCapabilities() const { return false; }
|
||||||
|
inline virtual bool hasCPIExtendedCapabilities() const { return false; }
|
||||||
|
inline virtual void modemPowerVote(bool power) const {
|
||||||
|
|
||||||
|
(void)power;
|
||||||
|
}
|
||||||
|
virtual void injectFeatureConfig(ContextBase* context) const {
|
||||||
|
|
||||||
|
(void)context;
|
||||||
|
}
|
||||||
|
inline virtual bool hasNativeXtraClient() const { return false; }
|
||||||
|
inline virtual IzatDevId_t getIzatDevId() const { return 0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef LBSProxyBase* (getLBSProxy_t)();
|
||||||
|
|
||||||
|
} // namespace loc_core
|
||||||
|
|
||||||
|
#endif // IZAT_PROXY_BASE_H
|
164
gps/core/LocAdapterBase.cpp
Normal file
164
gps/core/LocAdapterBase.cpp
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
/* Copyright (c) 2011-2014, 2016-2017The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define LOG_NDEBUG 0
|
||||||
|
#define LOG_TAG "LocSvc_LocAdapterBase"
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <LocAdapterBase.h>
|
||||||
|
#include <loc_target.h>
|
||||||
|
#include <platform_lib_log_util.h>
|
||||||
|
#include <LocAdapterProxyBase.h>
|
||||||
|
|
||||||
|
namespace loc_core {
|
||||||
|
|
||||||
|
// This is the top level class, so the constructor will
|
||||||
|
// always gets called. Here we prepare for the default.
|
||||||
|
// But if getLocApi(targetEnumType target) is overriden,
|
||||||
|
// the right locApi should get created.
|
||||||
|
LocAdapterBase::LocAdapterBase(const LOC_API_ADAPTER_EVENT_MASK_T mask,
|
||||||
|
ContextBase* context, LocAdapterProxyBase *adapterProxyBase) :
|
||||||
|
mEvtMask(mask), mContext(context),
|
||||||
|
mLocApi(context->getLocApi()), mLocAdapterProxyBase(adapterProxyBase),
|
||||||
|
mMsgTask(context->getMsgTask())
|
||||||
|
{
|
||||||
|
mLocApi->addAdapter(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t LocAdapterBase::mSessionIdCounter(1);
|
||||||
|
|
||||||
|
uint32_t LocAdapterBase::generateSessionId()
|
||||||
|
{
|
||||||
|
if (++mSessionIdCounter == 0xFFFFFFFF)
|
||||||
|
mSessionIdCounter = 1;
|
||||||
|
|
||||||
|
return mSessionIdCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocAdapterBase::handleEngineUpEvent()
|
||||||
|
{
|
||||||
|
if (mLocAdapterProxyBase) {
|
||||||
|
mLocAdapterProxyBase->handleEngineUpEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocAdapterBase::handleEngineDownEvent()
|
||||||
|
{
|
||||||
|
if (mLocAdapterProxyBase) {
|
||||||
|
mLocAdapterProxyBase->handleEngineDownEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocAdapterBase::
|
||||||
|
reportPositionEvent(const UlpLocation& location,
|
||||||
|
const GpsLocationExtended& locationExtended,
|
||||||
|
enum loc_sess_status status,
|
||||||
|
LocPosTechMask loc_technology_mask,
|
||||||
|
bool /*fromUlp*/) {
|
||||||
|
if (mLocAdapterProxyBase != NULL) {
|
||||||
|
mLocAdapterProxyBase->reportPositionEvent((UlpLocation&)location,
|
||||||
|
(GpsLocationExtended&)locationExtended,
|
||||||
|
status,
|
||||||
|
loc_technology_mask);
|
||||||
|
} else {
|
||||||
|
DEFAULT_IMPL()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocAdapterBase::
|
||||||
|
reportSvEvent(const GnssSvNotification& /*svNotify*/, bool /*fromUlp*/)
|
||||||
|
DEFAULT_IMPL()
|
||||||
|
|
||||||
|
void LocAdapterBase::
|
||||||
|
reportSvMeasurementEvent(GnssSvMeasurementSet &/*svMeasurementSet*/)
|
||||||
|
DEFAULT_IMPL()
|
||||||
|
|
||||||
|
void LocAdapterBase::
|
||||||
|
reportSvPolynomialEvent(GnssSvPolynomial &/*svPolynomial*/)
|
||||||
|
DEFAULT_IMPL()
|
||||||
|
|
||||||
|
void LocAdapterBase::
|
||||||
|
reportStatus(LocGpsStatusValue /*status*/)
|
||||||
|
DEFAULT_IMPL()
|
||||||
|
|
||||||
|
|
||||||
|
void LocAdapterBase::
|
||||||
|
reportNmeaEvent(const char* /*nmea*/, size_t /*length*/, bool /*fromUlp*/)
|
||||||
|
DEFAULT_IMPL()
|
||||||
|
|
||||||
|
bool LocAdapterBase::
|
||||||
|
reportXtraServer(const char* /*url1*/, const char* /*url2*/,
|
||||||
|
const char* /*url3*/, const int /*maxlength*/)
|
||||||
|
DEFAULT_IMPL(false)
|
||||||
|
|
||||||
|
bool LocAdapterBase::
|
||||||
|
requestXtraData()
|
||||||
|
DEFAULT_IMPL(false)
|
||||||
|
|
||||||
|
bool LocAdapterBase::
|
||||||
|
requestTime()
|
||||||
|
DEFAULT_IMPL(false)
|
||||||
|
|
||||||
|
bool LocAdapterBase::
|
||||||
|
requestLocation()
|
||||||
|
DEFAULT_IMPL(false)
|
||||||
|
|
||||||
|
bool LocAdapterBase::
|
||||||
|
requestATL(int /*connHandle*/, LocAGpsType /*agps_type*/)
|
||||||
|
DEFAULT_IMPL(false)
|
||||||
|
|
||||||
|
bool LocAdapterBase::
|
||||||
|
releaseATL(int /*connHandle*/)
|
||||||
|
DEFAULT_IMPL(false)
|
||||||
|
|
||||||
|
bool LocAdapterBase::
|
||||||
|
requestSuplES(int /*connHandle*/)
|
||||||
|
DEFAULT_IMPL(false)
|
||||||
|
|
||||||
|
bool LocAdapterBase::
|
||||||
|
reportDataCallOpened()
|
||||||
|
DEFAULT_IMPL(false)
|
||||||
|
|
||||||
|
bool LocAdapterBase::
|
||||||
|
reportDataCallClosed()
|
||||||
|
DEFAULT_IMPL(false)
|
||||||
|
|
||||||
|
bool LocAdapterBase::
|
||||||
|
requestNiNotifyEvent(const GnssNiNotification &/*notify*/, const void* /*data*/)
|
||||||
|
DEFAULT_IMPL(false)
|
||||||
|
|
||||||
|
void LocAdapterBase::
|
||||||
|
reportGnssMeasurementDataEvent(const GnssMeasurementsNotification& /*measurements*/,
|
||||||
|
int /*msInWeek*/)
|
||||||
|
DEFAULT_IMPL()
|
||||||
|
|
||||||
|
bool LocAdapterBase::
|
||||||
|
reportWwanZppFix(LocGpsLocation &/*zppLoc*/)
|
||||||
|
DEFAULT_IMPL(false)
|
||||||
|
|
||||||
|
} // namespace loc_core
|
160
gps/core/LocAdapterBase.h
Normal file
160
gps/core/LocAdapterBase.h
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
/* Copyright (c) 2011-2014, 2016-2017 The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LOC_API_ADAPTER_BASE_H
|
||||||
|
#define LOC_API_ADAPTER_BASE_H
|
||||||
|
|
||||||
|
#include <gps_extended.h>
|
||||||
|
#include <UlpProxyBase.h>
|
||||||
|
#include <ContextBase.h>
|
||||||
|
#include <LocationAPI.h>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
typedef struct LocationSessionKey {
|
||||||
|
LocationAPI* client;
|
||||||
|
uint32_t id;
|
||||||
|
inline LocationSessionKey(LocationAPI* _client, uint32_t _id) :
|
||||||
|
client(_client), id(_id) {}
|
||||||
|
} LocationSessionKey;
|
||||||
|
inline bool operator <(LocationSessionKey const& left, LocationSessionKey const& right) {
|
||||||
|
return left.id < right.id || (left.id == right.id && left.client < right.client);
|
||||||
|
}
|
||||||
|
inline bool operator ==(LocationSessionKey const& left, LocationSessionKey const& right) {
|
||||||
|
return left.id == right.id && left.client == right.client;
|
||||||
|
}
|
||||||
|
inline bool operator !=(LocationSessionKey const& left, LocationSessionKey const& right) {
|
||||||
|
return left.id != right.id || left.client != right.client;
|
||||||
|
}
|
||||||
|
typedef std::map<LocationSessionKey, LocationOptions> LocationSessionMap;
|
||||||
|
|
||||||
|
namespace loc_core {
|
||||||
|
|
||||||
|
class LocAdapterProxyBase;
|
||||||
|
|
||||||
|
class LocAdapterBase {
|
||||||
|
private:
|
||||||
|
static uint32_t mSessionIdCounter;
|
||||||
|
protected:
|
||||||
|
LOC_API_ADAPTER_EVENT_MASK_T mEvtMask;
|
||||||
|
ContextBase* mContext;
|
||||||
|
LocApiBase* mLocApi;
|
||||||
|
LocAdapterProxyBase* mLocAdapterProxyBase;
|
||||||
|
const MsgTask* mMsgTask;
|
||||||
|
inline LocAdapterBase(const MsgTask* msgTask) :
|
||||||
|
mEvtMask(0), mContext(NULL), mLocApi(NULL),
|
||||||
|
mLocAdapterProxyBase(NULL), mMsgTask(msgTask) {}
|
||||||
|
public:
|
||||||
|
inline virtual ~LocAdapterBase() { mLocApi->removeAdapter(this); }
|
||||||
|
LocAdapterBase(const LOC_API_ADAPTER_EVENT_MASK_T mask,
|
||||||
|
ContextBase* context, LocAdapterProxyBase *adapterProxyBase = NULL);
|
||||||
|
inline LOC_API_ADAPTER_EVENT_MASK_T
|
||||||
|
checkMask(LOC_API_ADAPTER_EVENT_MASK_T mask) const {
|
||||||
|
return mEvtMask & mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline LOC_API_ADAPTER_EVENT_MASK_T getEvtMask() const {
|
||||||
|
return mEvtMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void sendMsg(const LocMsg* msg) const {
|
||||||
|
mMsgTask->sendMsg(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void sendMsg(const LocMsg* msg) {
|
||||||
|
mMsgTask->sendMsg(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void updateEvtMask(LOC_API_ADAPTER_EVENT_MASK_T event,
|
||||||
|
loc_registration_mask_status status)
|
||||||
|
{
|
||||||
|
switch(status) {
|
||||||
|
case (LOC_REGISTRATION_MASK_ENABLED):
|
||||||
|
mEvtMask = mEvtMask | event;
|
||||||
|
break;
|
||||||
|
case (LOC_REGISTRATION_MASK_DISABLED):
|
||||||
|
mEvtMask = mEvtMask &~ event;
|
||||||
|
break;
|
||||||
|
case (LOC_REGISTRATION_MASK_SET):
|
||||||
|
mEvtMask = event;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mLocApi->updateEvtMask();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool isFeatureSupported(uint8_t featureVal) {
|
||||||
|
return mLocApi->isFeatureSupported(featureVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t generateSessionId();
|
||||||
|
|
||||||
|
// This will be overridden by the individual adapters
|
||||||
|
// if necessary.
|
||||||
|
inline virtual void setUlpProxyCommand(UlpProxyBase* ulp) {
|
||||||
|
|
||||||
|
(void)ulp;
|
||||||
|
}
|
||||||
|
virtual void handleEngineUpEvent();
|
||||||
|
virtual void handleEngineDownEvent();
|
||||||
|
inline virtual void setPositionModeCommand(LocPosMode& posMode) {
|
||||||
|
|
||||||
|
(void)posMode;
|
||||||
|
}
|
||||||
|
virtual void startTrackingCommand() {}
|
||||||
|
virtual void stopTrackingCommand() {}
|
||||||
|
virtual void getZppCommand() {}
|
||||||
|
virtual void reportPositionEvent(const UlpLocation& location,
|
||||||
|
const GpsLocationExtended& locationExtended,
|
||||||
|
enum loc_sess_status status,
|
||||||
|
LocPosTechMask loc_technology_mask,
|
||||||
|
bool fromUlp=false);
|
||||||
|
virtual void reportSvEvent(const GnssSvNotification& svNotify, bool fromUlp=false);
|
||||||
|
virtual void reportNmeaEvent(const char* nmea, size_t length, bool fromUlp=false);
|
||||||
|
virtual void reportSvMeasurementEvent(GnssSvMeasurementSet &svMeasurementSet);
|
||||||
|
virtual void reportSvPolynomialEvent(GnssSvPolynomial &svPolynomial);
|
||||||
|
virtual void reportStatus(LocGpsStatusValue status);
|
||||||
|
virtual bool reportXtraServer(const char* url1, const char* url2,
|
||||||
|
const char* url3, const int maxlength);
|
||||||
|
virtual bool requestXtraData();
|
||||||
|
virtual bool requestTime();
|
||||||
|
virtual bool requestLocation();
|
||||||
|
virtual bool requestATL(int connHandle, LocAGpsType agps_type);
|
||||||
|
virtual bool releaseATL(int connHandle);
|
||||||
|
virtual bool requestSuplES(int connHandle);
|
||||||
|
virtual bool reportDataCallOpened();
|
||||||
|
virtual bool reportDataCallClosed();
|
||||||
|
virtual bool requestNiNotifyEvent(const GnssNiNotification ¬ify, const void* data);
|
||||||
|
inline virtual bool isInSession() { return false; }
|
||||||
|
ContextBase* getContext() const { return mContext; }
|
||||||
|
virtual void reportGnssMeasurementDataEvent(const GnssMeasurementsNotification& measurements,
|
||||||
|
int msInWeek);
|
||||||
|
virtual bool reportWwanZppFix(LocGpsLocation &zppLoc);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace loc_core
|
||||||
|
|
||||||
|
#endif //LOC_API_ADAPTER_BASE_H
|
78
gps/core/LocAdapterProxyBase.h
Normal file
78
gps/core/LocAdapterProxyBase.h
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/* Copyright (c) 2014, 2016-2017 The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LOC_ADAPTER_PROXY_BASE_H
|
||||||
|
#define LOC_ADAPTER_PROXY_BASE_H
|
||||||
|
|
||||||
|
#include <ContextBase.h>
|
||||||
|
#include <gps_extended.h>
|
||||||
|
|
||||||
|
namespace loc_core {
|
||||||
|
|
||||||
|
class LocAdapterProxyBase {
|
||||||
|
private:
|
||||||
|
LocAdapterBase *mLocAdapterBase;
|
||||||
|
protected:
|
||||||
|
inline LocAdapterProxyBase(const LOC_API_ADAPTER_EVENT_MASK_T mask,
|
||||||
|
ContextBase* context):
|
||||||
|
mLocAdapterBase(new LocAdapterBase(mask, context, this)) {
|
||||||
|
}
|
||||||
|
inline virtual ~LocAdapterProxyBase() {
|
||||||
|
delete mLocAdapterBase;
|
||||||
|
}
|
||||||
|
inline void updateEvtMask(LOC_API_ADAPTER_EVENT_MASK_T event,
|
||||||
|
loc_registration_mask_status isEnabled) {
|
||||||
|
mLocAdapterBase->updateEvtMask(event,isEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint32_t generateSessionId() {
|
||||||
|
return mLocAdapterBase->generateSessionId();
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
inline ContextBase* getContext() const {
|
||||||
|
return mLocAdapterBase->getContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline virtual void handleEngineUpEvent() {};
|
||||||
|
inline virtual void handleEngineDownEvent() {};
|
||||||
|
inline virtual void reportPositionEvent(UlpLocation &location,
|
||||||
|
GpsLocationExtended &locationExtended,
|
||||||
|
enum loc_sess_status status,
|
||||||
|
LocPosTechMask loc_technology_mask) {
|
||||||
|
|
||||||
|
(void)location;
|
||||||
|
(void)locationExtended;
|
||||||
|
(void)status;
|
||||||
|
(void)loc_technology_mask;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace loc_core
|
||||||
|
|
||||||
|
#endif //LOC_ADAPTER_PROXY_BASE_H
|
608
gps/core/LocApiBase.cpp
Normal file
608
gps/core/LocApiBase.cpp
Normal file
|
@ -0,0 +1,608 @@
|
||||||
|
/* Copyright (c) 2011-2014, 2016-2017 The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define LOG_NDEBUG 0 //Define to enable LOGV
|
||||||
|
#define LOG_TAG "LocSvc_LocApiBase"
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <LocApiBase.h>
|
||||||
|
#include <LocAdapterBase.h>
|
||||||
|
#include <platform_lib_log_util.h>
|
||||||
|
#include <LocDualContext.h>
|
||||||
|
|
||||||
|
namespace loc_core {
|
||||||
|
|
||||||
|
#define TO_ALL_LOCADAPTERS(call) TO_ALL_ADAPTERS(mLocAdapters, (call))
|
||||||
|
#define TO_1ST_HANDLING_LOCADAPTERS(call) TO_1ST_HANDLING_ADAPTER(mLocAdapters, (call))
|
||||||
|
|
||||||
|
int hexcode(char *hexstring, int string_size,
|
||||||
|
const char *data, int data_size)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < data_size; i++)
|
||||||
|
{
|
||||||
|
char ch = data[i];
|
||||||
|
if (i*2 + 3 <= string_size)
|
||||||
|
{
|
||||||
|
snprintf(&hexstring[i*2], 3, "%02X", ch);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
int decodeAddress(char *addr_string, int string_size,
|
||||||
|
const char *data, int data_size)
|
||||||
|
{
|
||||||
|
const char addr_prefix = 0x91;
|
||||||
|
int i, idxOutput = 0;
|
||||||
|
|
||||||
|
if (!data || !addr_string) { return 0; }
|
||||||
|
|
||||||
|
if (data[0] != addr_prefix)
|
||||||
|
{
|
||||||
|
LOC_LOGW("decodeAddress: address prefix is not 0x%x but 0x%x", addr_prefix, data[0]);
|
||||||
|
addr_string[0] = '\0';
|
||||||
|
return 0; // prefix not correct
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; i < data_size; i++)
|
||||||
|
{
|
||||||
|
unsigned char ch = data[i], low = ch & 0x0F, hi = ch >> 4;
|
||||||
|
if (low <= 9 && idxOutput < string_size - 1) { addr_string[idxOutput++] = low + '0'; }
|
||||||
|
if (hi <= 9 && idxOutput < string_size - 1) { addr_string[idxOutput++] = hi + '0'; }
|
||||||
|
}
|
||||||
|
|
||||||
|
addr_string[idxOutput] = '\0'; // Terminates the string
|
||||||
|
|
||||||
|
return idxOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct LocSsrMsg : public LocMsg {
|
||||||
|
LocApiBase* mLocApi;
|
||||||
|
inline LocSsrMsg(LocApiBase* locApi) :
|
||||||
|
LocMsg(), mLocApi(locApi)
|
||||||
|
{
|
||||||
|
locallog();
|
||||||
|
}
|
||||||
|
inline virtual void proc() const {
|
||||||
|
mLocApi->close();
|
||||||
|
mLocApi->open(mLocApi->getEvtMask());
|
||||||
|
}
|
||||||
|
inline void locallog() const {
|
||||||
|
LOC_LOGV("LocSsrMsg");
|
||||||
|
}
|
||||||
|
inline virtual void log() const {
|
||||||
|
locallog();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LocOpenMsg : public LocMsg {
|
||||||
|
LocApiBase* mLocApi;
|
||||||
|
LOC_API_ADAPTER_EVENT_MASK_T mMask;
|
||||||
|
inline LocOpenMsg(LocApiBase* locApi,
|
||||||
|
LOC_API_ADAPTER_EVENT_MASK_T mask) :
|
||||||
|
LocMsg(), mLocApi(locApi), mMask(mask)
|
||||||
|
{
|
||||||
|
locallog();
|
||||||
|
}
|
||||||
|
inline virtual void proc() const {
|
||||||
|
mLocApi->open(mMask);
|
||||||
|
}
|
||||||
|
inline void locallog() const {
|
||||||
|
LOC_LOGV("%s:%d]: LocOpen Mask: %x\n",
|
||||||
|
__func__, __LINE__, mMask);
|
||||||
|
}
|
||||||
|
inline virtual void log() const {
|
||||||
|
locallog();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
LocApiBase::LocApiBase(const MsgTask* msgTask,
|
||||||
|
LOC_API_ADAPTER_EVENT_MASK_T excludedMask,
|
||||||
|
ContextBase* context) :
|
||||||
|
mMsgTask(msgTask), mContext(context), mSupportedMsg(0),
|
||||||
|
mMask(0), mExcludedMask(excludedMask)
|
||||||
|
{
|
||||||
|
memset(mLocAdapters, 0, sizeof(mLocAdapters));
|
||||||
|
memset(mFeaturesSupported, 0, sizeof(mFeaturesSupported));
|
||||||
|
}
|
||||||
|
|
||||||
|
LOC_API_ADAPTER_EVENT_MASK_T LocApiBase::getEvtMask()
|
||||||
|
{
|
||||||
|
LOC_API_ADAPTER_EVENT_MASK_T mask = 0;
|
||||||
|
|
||||||
|
TO_ALL_LOCADAPTERS(mask |= mLocAdapters[i]->getEvtMask());
|
||||||
|
|
||||||
|
return mask & ~mExcludedMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LocApiBase::isInSession()
|
||||||
|
{
|
||||||
|
bool inSession = false;
|
||||||
|
|
||||||
|
for (int i = 0;
|
||||||
|
!inSession && i < MAX_ADAPTERS && NULL != mLocAdapters[i];
|
||||||
|
i++) {
|
||||||
|
inSession = mLocAdapters[i]->isInSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
return inSession;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocApiBase::addAdapter(LocAdapterBase* adapter)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MAX_ADAPTERS && mLocAdapters[i] != adapter; i++) {
|
||||||
|
if (mLocAdapters[i] == NULL) {
|
||||||
|
mLocAdapters[i] = adapter;
|
||||||
|
mMsgTask->sendMsg(new LocOpenMsg(this,
|
||||||
|
(adapter->getEvtMask())));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocApiBase::removeAdapter(LocAdapterBase* adapter)
|
||||||
|
{
|
||||||
|
for (int i = 0;
|
||||||
|
i < MAX_ADAPTERS && NULL != mLocAdapters[i];
|
||||||
|
i++) {
|
||||||
|
if (mLocAdapters[i] == adapter) {
|
||||||
|
mLocAdapters[i] = NULL;
|
||||||
|
|
||||||
|
// shift the rest of the adapters up so that the pointers
|
||||||
|
// in the array do not have holes. This should be more
|
||||||
|
// performant, because the array maintenance is much much
|
||||||
|
// less frequent than event handlings, which need to linear
|
||||||
|
// search all the adapters
|
||||||
|
int j = i;
|
||||||
|
while (++i < MAX_ADAPTERS && mLocAdapters[i] != NULL);
|
||||||
|
|
||||||
|
// i would be MAX_ADAPTERS or point to a NULL
|
||||||
|
i--;
|
||||||
|
// i now should point to a none NULL adapter within valid
|
||||||
|
// range although i could be equal to j, but it won't hurt.
|
||||||
|
// No need to check it, as it gains nothing.
|
||||||
|
mLocAdapters[j] = mLocAdapters[i];
|
||||||
|
// this makes sure that we exit the for loop
|
||||||
|
mLocAdapters[i] = NULL;
|
||||||
|
|
||||||
|
// if we have an empty list of adapters
|
||||||
|
if (0 == i) {
|
||||||
|
close();
|
||||||
|
} else {
|
||||||
|
// else we need to remove the bit
|
||||||
|
mMsgTask->sendMsg(new LocOpenMsg(this, getEvtMask()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocApiBase::updateEvtMask()
|
||||||
|
{
|
||||||
|
mMsgTask->sendMsg(new LocOpenMsg(this, getEvtMask()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocApiBase::handleEngineUpEvent()
|
||||||
|
{
|
||||||
|
// This will take care of renegotiating the loc handle
|
||||||
|
mMsgTask->sendMsg(new LocSsrMsg(this));
|
||||||
|
|
||||||
|
LocDualContext::injectFeatureConfig(mContext);
|
||||||
|
|
||||||
|
// loop through adapters, and deliver to all adapters.
|
||||||
|
TO_ALL_LOCADAPTERS(mLocAdapters[i]->handleEngineUpEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocApiBase::handleEngineDownEvent()
|
||||||
|
{
|
||||||
|
// loop through adapters, and deliver to all adapters.
|
||||||
|
TO_ALL_LOCADAPTERS(mLocAdapters[i]->handleEngineDownEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocApiBase::reportPosition(UlpLocation& location,
|
||||||
|
GpsLocationExtended& locationExtended,
|
||||||
|
enum loc_sess_status status,
|
||||||
|
LocPosTechMask loc_technology_mask)
|
||||||
|
{
|
||||||
|
// print the location info before delivering
|
||||||
|
LOC_LOGD("flags: %d\n source: %d\n latitude: %f\n longitude: %f\n "
|
||||||
|
"altitude: %f\n speed: %f\n bearing: %f\n accuracy: %f\n "
|
||||||
|
"timestamp: %" PRId64 "\n rawDataSize: %d\n rawData: %p\n "
|
||||||
|
"Session status: %d\n Technology mask: %u\n "
|
||||||
|
"SV used in fix (gps/glo/bds/gal/qzss) : \
|
||||||
|
(%" PRIx64 "/%" PRIx64 "/%" PRIx64 "/%" PRIx64 "/%" PRIx64 ")",
|
||||||
|
location.gpsLocation.flags, location.position_source,
|
||||||
|
location.gpsLocation.latitude, location.gpsLocation.longitude,
|
||||||
|
location.gpsLocation.altitude, location.gpsLocation.speed,
|
||||||
|
location.gpsLocation.bearing, location.gpsLocation.accuracy,
|
||||||
|
location.gpsLocation.timestamp, location.rawDataSize,
|
||||||
|
location.rawData, status, loc_technology_mask,
|
||||||
|
locationExtended.gnss_sv_used_ids.gps_sv_used_ids_mask,
|
||||||
|
locationExtended.gnss_sv_used_ids.glo_sv_used_ids_mask,
|
||||||
|
locationExtended.gnss_sv_used_ids.bds_sv_used_ids_mask,
|
||||||
|
locationExtended.gnss_sv_used_ids.gal_sv_used_ids_mask,
|
||||||
|
locationExtended.gnss_sv_used_ids.qzss_sv_used_ids_mask);
|
||||||
|
// loop through adapters, and deliver to all adapters.
|
||||||
|
TO_ALL_LOCADAPTERS(
|
||||||
|
mLocAdapters[i]->reportPositionEvent(location, locationExtended,
|
||||||
|
status, loc_technology_mask)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocApiBase::reportWwanZppFix(LocGpsLocation &zppLoc)
|
||||||
|
{
|
||||||
|
// loop through adapters, and deliver to the first handling adapter.
|
||||||
|
TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->reportWwanZppFix(zppLoc));
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocApiBase::reportSv(GnssSvNotification& svNotify)
|
||||||
|
{
|
||||||
|
const char* constellationString[] = { "Unknown", "GPS", "SBAS", "GLONASS",
|
||||||
|
"QZSS", "BEIDOU", "GALILEO" };
|
||||||
|
|
||||||
|
// print the SV info before delivering
|
||||||
|
LOC_LOGV("num sv: %zu\n"
|
||||||
|
" sv: constellation svid cN0"
|
||||||
|
" elevation azimuth flags",
|
||||||
|
svNotify.count);
|
||||||
|
for (size_t i = 0; i < svNotify.count && i < LOC_GNSS_MAX_SVS; i++) {
|
||||||
|
if (svNotify.gnssSvs[i].type >
|
||||||
|
sizeof(constellationString) / sizeof(constellationString[0]) - 1) {
|
||||||
|
svNotify.gnssSvs[i].type = GNSS_SV_TYPE_UNKNOWN;
|
||||||
|
}
|
||||||
|
LOC_LOGV(" %03zu: %*s %02d %f %f %f 0x%02X",
|
||||||
|
i,
|
||||||
|
13,
|
||||||
|
constellationString[svNotify.gnssSvs[i].type],
|
||||||
|
svNotify.gnssSvs[i].svId,
|
||||||
|
svNotify.gnssSvs[i].cN0Dbhz,
|
||||||
|
svNotify.gnssSvs[i].elevation,
|
||||||
|
svNotify.gnssSvs[i].azimuth,
|
||||||
|
svNotify.gnssSvs[i].gnssSvOptionsMask);
|
||||||
|
}
|
||||||
|
// loop through adapters, and deliver to all adapters.
|
||||||
|
TO_ALL_LOCADAPTERS(
|
||||||
|
mLocAdapters[i]->reportSvEvent(svNotify)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocApiBase::reportSvMeasurement(GnssSvMeasurementSet &svMeasurementSet)
|
||||||
|
{
|
||||||
|
// loop through adapters, and deliver to all adapters.
|
||||||
|
TO_ALL_LOCADAPTERS(
|
||||||
|
mLocAdapters[i]->reportSvMeasurementEvent(svMeasurementSet)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocApiBase::reportSvPolynomial(GnssSvPolynomial &svPolynomial)
|
||||||
|
{
|
||||||
|
// loop through adapters, and deliver to all adapters.
|
||||||
|
TO_ALL_LOCADAPTERS(
|
||||||
|
mLocAdapters[i]->reportSvPolynomialEvent(svPolynomial)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocApiBase::reportStatus(LocGpsStatusValue status)
|
||||||
|
{
|
||||||
|
// loop through adapters, and deliver to all adapters.
|
||||||
|
TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportStatus(status));
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocApiBase::reportNmea(const char* nmea, int length)
|
||||||
|
{
|
||||||
|
// loop through adapters, and deliver to all adapters.
|
||||||
|
TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportNmeaEvent(nmea, length));
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocApiBase::reportXtraServer(const char* url1, const char* url2,
|
||||||
|
const char* url3, const int maxlength)
|
||||||
|
{
|
||||||
|
// loop through adapters, and deliver to the first handling adapter.
|
||||||
|
TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->reportXtraServer(url1, url2, url3, maxlength));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocApiBase::requestXtraData()
|
||||||
|
{
|
||||||
|
// loop through adapters, and deliver to the first handling adapter.
|
||||||
|
TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->requestXtraData());
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocApiBase::requestTime()
|
||||||
|
{
|
||||||
|
// loop through adapters, and deliver to the first handling adapter.
|
||||||
|
TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->requestTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocApiBase::requestLocation()
|
||||||
|
{
|
||||||
|
// loop through adapters, and deliver to the first handling adapter.
|
||||||
|
TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->requestLocation());
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocApiBase::requestATL(int connHandle, LocAGpsType agps_type)
|
||||||
|
{
|
||||||
|
// loop through adapters, and deliver to the first handling adapter.
|
||||||
|
TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->requestATL(connHandle, agps_type));
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocApiBase::releaseATL(int connHandle)
|
||||||
|
{
|
||||||
|
// loop through adapters, and deliver to the first handling adapter.
|
||||||
|
TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->releaseATL(connHandle));
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocApiBase::requestSuplES(int connHandle)
|
||||||
|
{
|
||||||
|
// loop through adapters, and deliver to the first handling adapter.
|
||||||
|
TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->requestSuplES(connHandle));
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocApiBase::reportDataCallOpened()
|
||||||
|
{
|
||||||
|
// loop through adapters, and deliver to the first handling adapter.
|
||||||
|
TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->reportDataCallOpened());
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocApiBase::reportDataCallClosed()
|
||||||
|
{
|
||||||
|
// loop through adapters, and deliver to the first handling adapter.
|
||||||
|
TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->reportDataCallClosed());
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocApiBase::requestNiNotify(GnssNiNotification ¬ify, const void* data)
|
||||||
|
{
|
||||||
|
// loop through adapters, and deliver to the first handling adapter.
|
||||||
|
TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->requestNiNotifyEvent(notify, data));
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocApiBase::saveSupportedMsgList(uint64_t supportedMsgList)
|
||||||
|
{
|
||||||
|
mSupportedMsg = supportedMsgList;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocApiBase::saveSupportedFeatureList(uint8_t *featureList)
|
||||||
|
{
|
||||||
|
memcpy((void *)mFeaturesSupported, (void *)featureList, sizeof(mFeaturesSupported));
|
||||||
|
}
|
||||||
|
|
||||||
|
void* LocApiBase :: getSibling()
|
||||||
|
DEFAULT_IMPL(NULL)
|
||||||
|
|
||||||
|
LocApiProxyBase* LocApiBase :: getLocApiProxy()
|
||||||
|
DEFAULT_IMPL(NULL)
|
||||||
|
|
||||||
|
void LocApiBase::reportGnssMeasurementData(GnssMeasurementsNotification& measurements,
|
||||||
|
int msInWeek)
|
||||||
|
{
|
||||||
|
// loop through adapters, and deliver to all adapters.
|
||||||
|
TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportGnssMeasurementDataEvent(measurements, msInWeek));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum loc_api_adapter_err LocApiBase::
|
||||||
|
open(LOC_API_ADAPTER_EVENT_MASK_T /*mask*/)
|
||||||
|
DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
|
||||||
|
|
||||||
|
enum loc_api_adapter_err LocApiBase::
|
||||||
|
close()
|
||||||
|
DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
|
||||||
|
|
||||||
|
enum loc_api_adapter_err LocApiBase::
|
||||||
|
startFix(const LocPosMode& /*posMode*/)
|
||||||
|
DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
|
||||||
|
|
||||||
|
enum loc_api_adapter_err LocApiBase::
|
||||||
|
stopFix()
|
||||||
|
DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
|
||||||
|
|
||||||
|
LocationError LocApiBase::
|
||||||
|
deleteAidingData(const GnssAidingData& /*data*/)
|
||||||
|
DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
|
||||||
|
|
||||||
|
enum loc_api_adapter_err LocApiBase::
|
||||||
|
enableData(int /*enable*/)
|
||||||
|
DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
|
||||||
|
|
||||||
|
enum loc_api_adapter_err LocApiBase::
|
||||||
|
setAPN(char* /*apn*/, int /*len*/)
|
||||||
|
DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
|
||||||
|
|
||||||
|
enum loc_api_adapter_err LocApiBase::
|
||||||
|
injectPosition(double /*latitude*/, double /*longitude*/, float /*accuracy*/)
|
||||||
|
DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
|
||||||
|
|
||||||
|
enum loc_api_adapter_err LocApiBase::
|
||||||
|
setTime(LocGpsUtcTime /*time*/, int64_t /*timeReference*/, int /*uncertainty*/)
|
||||||
|
DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
|
||||||
|
|
||||||
|
enum loc_api_adapter_err LocApiBase::
|
||||||
|
setXtraData(char* /*data*/, int /*length*/)
|
||||||
|
DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
|
||||||
|
|
||||||
|
enum loc_api_adapter_err LocApiBase::
|
||||||
|
requestXtraServer()
|
||||||
|
DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
|
||||||
|
|
||||||
|
enum loc_api_adapter_err LocApiBase::
|
||||||
|
atlOpenStatus(int /*handle*/, int /*is_succ*/, char* /*apn*/,
|
||||||
|
AGpsBearerType /*bear*/, LocAGpsType /*agpsType*/)
|
||||||
|
DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
|
||||||
|
|
||||||
|
enum loc_api_adapter_err LocApiBase::
|
||||||
|
atlCloseStatus(int /*handle*/, int /*is_succ*/)
|
||||||
|
DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
|
||||||
|
|
||||||
|
enum loc_api_adapter_err LocApiBase::
|
||||||
|
setPositionMode(const LocPosMode& /*posMode*/)
|
||||||
|
DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
|
||||||
|
|
||||||
|
LocationError LocApiBase::
|
||||||
|
setServer(const char* /*url*/, int /*len*/)
|
||||||
|
DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
|
||||||
|
|
||||||
|
LocationError LocApiBase::
|
||||||
|
setServer(unsigned int /*ip*/, int /*port*/, LocServerType /*type*/)
|
||||||
|
DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
|
||||||
|
|
||||||
|
LocationError LocApiBase::
|
||||||
|
informNiResponse(GnssNiResponse /*userResponse*/, const void* /*passThroughData*/)
|
||||||
|
DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
|
||||||
|
|
||||||
|
LocationError LocApiBase::
|
||||||
|
setSUPLVersion(GnssConfigSuplVersion /*version*/)
|
||||||
|
DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
|
||||||
|
|
||||||
|
enum loc_api_adapter_err LocApiBase::
|
||||||
|
setNMEATypes (uint32_t /*typesMask*/)
|
||||||
|
DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
|
||||||
|
|
||||||
|
LocationError LocApiBase::
|
||||||
|
setLPPConfig(GnssConfigLppProfile /*profile*/)
|
||||||
|
DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
|
||||||
|
|
||||||
|
enum loc_api_adapter_err LocApiBase::
|
||||||
|
setSensorControlConfig(int /*sensorUsage*/,
|
||||||
|
int /*sensorProvider*/)
|
||||||
|
DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
|
||||||
|
|
||||||
|
enum loc_api_adapter_err LocApiBase::
|
||||||
|
setSensorProperties(bool /*gyroBiasVarianceRandomWalk_valid*/,
|
||||||
|
float /*gyroBiasVarianceRandomWalk*/,
|
||||||
|
bool /*accelBiasVarianceRandomWalk_valid*/,
|
||||||
|
float /*accelBiasVarianceRandomWalk*/,
|
||||||
|
bool /*angleBiasVarianceRandomWalk_valid*/,
|
||||||
|
float /*angleBiasVarianceRandomWalk*/,
|
||||||
|
bool /*rateBiasVarianceRandomWalk_valid*/,
|
||||||
|
float /*rateBiasVarianceRandomWalk*/,
|
||||||
|
bool /*velocityBiasVarianceRandomWalk_valid*/,
|
||||||
|
float /*velocityBiasVarianceRandomWalk*/)
|
||||||
|
DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
|
||||||
|
|
||||||
|
enum loc_api_adapter_err LocApiBase::
|
||||||
|
setSensorPerfControlConfig(int /*controlMode*/,
|
||||||
|
int /*accelSamplesPerBatch*/,
|
||||||
|
int /*accelBatchesPerSec*/,
|
||||||
|
int /*gyroSamplesPerBatch*/,
|
||||||
|
int /*gyroBatchesPerSec*/,
|
||||||
|
int /*accelSamplesPerBatchHigh*/,
|
||||||
|
int /*accelBatchesPerSecHigh*/,
|
||||||
|
int /*gyroSamplesPerBatchHigh*/,
|
||||||
|
int /*gyroBatchesPerSecHigh*/,
|
||||||
|
int /*algorithmConfig*/)
|
||||||
|
DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
|
||||||
|
|
||||||
|
LocationError LocApiBase::
|
||||||
|
setAGLONASSProtocol(GnssConfigAGlonassPositionProtocolMask /*aGlonassProtocol*/)
|
||||||
|
DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
|
||||||
|
|
||||||
|
LocationError LocApiBase::
|
||||||
|
setLPPeProtocolCp(GnssConfigLppeControlPlaneMask /*lppeCP*/)
|
||||||
|
DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
|
||||||
|
|
||||||
|
LocationError LocApiBase::
|
||||||
|
setLPPeProtocolUp(GnssConfigLppeUserPlaneMask /*lppeUP*/)
|
||||||
|
DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
|
||||||
|
|
||||||
|
enum loc_api_adapter_err LocApiBase::
|
||||||
|
getWwanZppFix()
|
||||||
|
DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
|
||||||
|
|
||||||
|
enum loc_api_adapter_err LocApiBase::
|
||||||
|
getBestAvailableZppFix(LocGpsLocation& zppLoc)
|
||||||
|
{
|
||||||
|
memset(&zppLoc, 0, sizeof(zppLoc));
|
||||||
|
DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
|
||||||
|
}
|
||||||
|
|
||||||
|
enum loc_api_adapter_err LocApiBase::
|
||||||
|
getBestAvailableZppFix(LocGpsLocation & zppLoc, GpsLocationExtended & locationExtended,
|
||||||
|
LocPosTechMask & tech_mask)
|
||||||
|
{
|
||||||
|
memset(&zppLoc, 0, sizeof(zppLoc));
|
||||||
|
memset(&tech_mask, 0, sizeof(tech_mask));
|
||||||
|
memset(&locationExtended, 0, sizeof (locationExtended));
|
||||||
|
DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
|
||||||
|
}
|
||||||
|
|
||||||
|
int LocApiBase::
|
||||||
|
initDataServiceClient(bool /*isDueToSsr*/)
|
||||||
|
DEFAULT_IMPL(-1)
|
||||||
|
|
||||||
|
int LocApiBase::
|
||||||
|
openAndStartDataCall()
|
||||||
|
DEFAULT_IMPL(-1)
|
||||||
|
|
||||||
|
void LocApiBase::
|
||||||
|
stopDataCall()
|
||||||
|
DEFAULT_IMPL()
|
||||||
|
|
||||||
|
void LocApiBase::
|
||||||
|
closeDataCall()
|
||||||
|
DEFAULT_IMPL()
|
||||||
|
|
||||||
|
void LocApiBase::
|
||||||
|
releaseDataServiceClient()
|
||||||
|
DEFAULT_IMPL()
|
||||||
|
|
||||||
|
LocationError LocApiBase::
|
||||||
|
setGpsLock(GnssConfigGpsLock /*lock*/)
|
||||||
|
DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
|
||||||
|
|
||||||
|
void LocApiBase::
|
||||||
|
installAGpsCert(const LocDerEncodedCertificate* /*pData*/,
|
||||||
|
size_t /*length*/,
|
||||||
|
uint32_t /*slotBitMask*/)
|
||||||
|
DEFAULT_IMPL()
|
||||||
|
|
||||||
|
int LocApiBase::
|
||||||
|
getGpsLock()
|
||||||
|
DEFAULT_IMPL(-1)
|
||||||
|
|
||||||
|
LocationError LocApiBase::
|
||||||
|
setXtraVersionCheck(uint32_t /*check*/)
|
||||||
|
DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
|
||||||
|
|
||||||
|
bool LocApiBase::
|
||||||
|
gnssConstellationConfig()
|
||||||
|
DEFAULT_IMPL(false)
|
||||||
|
|
||||||
|
bool LocApiBase::
|
||||||
|
isFeatureSupported(uint8_t featureVal)
|
||||||
|
{
|
||||||
|
uint8_t arrayIndex = featureVal >> 3;
|
||||||
|
uint8_t bitPos = featureVal & 7;
|
||||||
|
|
||||||
|
if (arrayIndex >= MAX_FEATURE_LENGTH) return false;
|
||||||
|
return ((mFeaturesSupported[arrayIndex] >> bitPos ) & 0x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace loc_core
|
266
gps/core/LocApiBase.h
Normal file
266
gps/core/LocApiBase.h
Normal file
|
@ -0,0 +1,266 @@
|
||||||
|
/* Copyright (c) 2011-2014, 2016-2017 The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LOC_API_BASE_H
|
||||||
|
#define LOC_API_BASE_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <gps_extended.h>
|
||||||
|
#include <LocationAPI.h>
|
||||||
|
#include <MsgTask.h>
|
||||||
|
#include <platform_lib_log_util.h>
|
||||||
|
|
||||||
|
namespace loc_core {
|
||||||
|
class ContextBase;
|
||||||
|
|
||||||
|
int hexcode(char *hexstring, int string_size,
|
||||||
|
const char *data, int data_size);
|
||||||
|
int decodeAddress(char *addr_string, int string_size,
|
||||||
|
const char *data, int data_size);
|
||||||
|
|
||||||
|
#define MAX_ADAPTERS 10
|
||||||
|
#define MAX_FEATURE_LENGTH 100
|
||||||
|
|
||||||
|
#define TO_ALL_ADAPTERS(adapters, call) \
|
||||||
|
for (int i = 0; i < MAX_ADAPTERS && NULL != (adapters)[i]; i++) { \
|
||||||
|
call; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TO_1ST_HANDLING_ADAPTER(adapters, call) \
|
||||||
|
for (int i = 0; i <MAX_ADAPTERS && NULL != (adapters)[i] && !(call); i++);
|
||||||
|
|
||||||
|
enum xtra_version_check {
|
||||||
|
DISABLED,
|
||||||
|
AUTO,
|
||||||
|
XTRA2,
|
||||||
|
XTRA3
|
||||||
|
};
|
||||||
|
|
||||||
|
class LocAdapterBase;
|
||||||
|
struct LocSsrMsg;
|
||||||
|
struct LocOpenMsg;
|
||||||
|
|
||||||
|
class LocApiProxyBase {
|
||||||
|
public:
|
||||||
|
inline LocApiProxyBase() {}
|
||||||
|
inline virtual ~LocApiProxyBase() {}
|
||||||
|
inline virtual void* getSibling2() { return NULL; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class LocApiBase {
|
||||||
|
friend struct LocSsrMsg;
|
||||||
|
//LocOpenMsg calls open() which makes it necessary to declare
|
||||||
|
//it as a friend
|
||||||
|
friend struct LocOpenMsg;
|
||||||
|
friend class ContextBase;
|
||||||
|
const MsgTask* mMsgTask;
|
||||||
|
ContextBase *mContext;
|
||||||
|
LocAdapterBase* mLocAdapters[MAX_ADAPTERS];
|
||||||
|
uint64_t mSupportedMsg;
|
||||||
|
uint8_t mFeaturesSupported[MAX_FEATURE_LENGTH];
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual enum loc_api_adapter_err
|
||||||
|
open(LOC_API_ADAPTER_EVENT_MASK_T mask);
|
||||||
|
virtual enum loc_api_adapter_err
|
||||||
|
close();
|
||||||
|
LOC_API_ADAPTER_EVENT_MASK_T getEvtMask();
|
||||||
|
LOC_API_ADAPTER_EVENT_MASK_T mMask;
|
||||||
|
LocApiBase(const MsgTask* msgTask,
|
||||||
|
LOC_API_ADAPTER_EVENT_MASK_T excludedMask,
|
||||||
|
ContextBase* context = NULL);
|
||||||
|
inline virtual ~LocApiBase() { close(); }
|
||||||
|
bool isInSession();
|
||||||
|
const LOC_API_ADAPTER_EVENT_MASK_T mExcludedMask;
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline void sendMsg(const LocMsg* msg) const {
|
||||||
|
mMsgTask->sendMsg(msg);
|
||||||
|
}
|
||||||
|
void addAdapter(LocAdapterBase* adapter);
|
||||||
|
void removeAdapter(LocAdapterBase* adapter);
|
||||||
|
|
||||||
|
// upward calls
|
||||||
|
void handleEngineUpEvent();
|
||||||
|
void handleEngineDownEvent();
|
||||||
|
void reportPosition(UlpLocation& location,
|
||||||
|
GpsLocationExtended& locationExtended,
|
||||||
|
enum loc_sess_status status,
|
||||||
|
LocPosTechMask loc_technology_mask =
|
||||||
|
LOC_POS_TECH_MASK_DEFAULT);
|
||||||
|
void reportSv(GnssSvNotification& svNotify);
|
||||||
|
void reportSvMeasurement(GnssSvMeasurementSet &svMeasurementSet);
|
||||||
|
void reportSvPolynomial(GnssSvPolynomial &svPolynomial);
|
||||||
|
void reportStatus(LocGpsStatusValue status);
|
||||||
|
void reportNmea(const char* nmea, int length);
|
||||||
|
void reportXtraServer(const char* url1, const char* url2,
|
||||||
|
const char* url3, const int maxlength);
|
||||||
|
void requestXtraData();
|
||||||
|
void requestTime();
|
||||||
|
void requestLocation();
|
||||||
|
void requestATL(int connHandle, LocAGpsType agps_type);
|
||||||
|
void releaseATL(int connHandle);
|
||||||
|
void requestSuplES(int connHandle);
|
||||||
|
void reportDataCallOpened();
|
||||||
|
void reportDataCallClosed();
|
||||||
|
void requestNiNotify(GnssNiNotification ¬ify, const void* data);
|
||||||
|
void saveSupportedMsgList(uint64_t supportedMsgList);
|
||||||
|
void reportGnssMeasurementData(GnssMeasurementsNotification& measurements, int msInWeek);
|
||||||
|
void saveSupportedFeatureList(uint8_t *featureList);
|
||||||
|
void reportWwanZppFix(LocGpsLocation &zppLoc);
|
||||||
|
|
||||||
|
// downward calls
|
||||||
|
// All below functions are to be defined by adapter specific modules:
|
||||||
|
// RPC, QMI, etc. The default implementation is empty.
|
||||||
|
|
||||||
|
virtual void* getSibling();
|
||||||
|
virtual LocApiProxyBase* getLocApiProxy();
|
||||||
|
virtual enum loc_api_adapter_err
|
||||||
|
startFix(const LocPosMode& posMode);
|
||||||
|
virtual enum loc_api_adapter_err
|
||||||
|
stopFix();
|
||||||
|
virtual LocationError
|
||||||
|
deleteAidingData(const GnssAidingData& data);
|
||||||
|
virtual enum loc_api_adapter_err
|
||||||
|
enableData(int enable);
|
||||||
|
virtual enum loc_api_adapter_err
|
||||||
|
setAPN(char* apn, int len);
|
||||||
|
virtual enum loc_api_adapter_err
|
||||||
|
injectPosition(double latitude, double longitude, float accuracy);
|
||||||
|
virtual enum loc_api_adapter_err
|
||||||
|
setTime(LocGpsUtcTime time, int64_t timeReference, int uncertainty);
|
||||||
|
virtual enum loc_api_adapter_err
|
||||||
|
setXtraData(char* data, int length);
|
||||||
|
virtual enum loc_api_adapter_err
|
||||||
|
requestXtraServer();
|
||||||
|
virtual enum loc_api_adapter_err
|
||||||
|
atlOpenStatus(int handle, int is_succ, char* apn, AGpsBearerType bear, LocAGpsType agpsType);
|
||||||
|
virtual enum loc_api_adapter_err
|
||||||
|
atlCloseStatus(int handle, int is_succ);
|
||||||
|
virtual enum loc_api_adapter_err
|
||||||
|
setPositionMode(const LocPosMode& posMode);
|
||||||
|
virtual LocationError
|
||||||
|
setServer(const char* url, int len);
|
||||||
|
virtual LocationError
|
||||||
|
setServer(unsigned int ip, int port,
|
||||||
|
LocServerType type);
|
||||||
|
virtual LocationError
|
||||||
|
informNiResponse(GnssNiResponse userResponse, const void* passThroughData);
|
||||||
|
virtual LocationError setSUPLVersion(GnssConfigSuplVersion version);
|
||||||
|
virtual enum loc_api_adapter_err
|
||||||
|
setNMEATypes (uint32_t typesMask);
|
||||||
|
virtual LocationError setLPPConfig(GnssConfigLppProfile profile);
|
||||||
|
virtual enum loc_api_adapter_err
|
||||||
|
setSensorControlConfig(int sensorUsage, int sensorProvider);
|
||||||
|
virtual enum loc_api_adapter_err
|
||||||
|
setSensorProperties(bool gyroBiasVarianceRandomWalk_valid,
|
||||||
|
float gyroBiasVarianceRandomWalk,
|
||||||
|
bool accelBiasVarianceRandomWalk_valid,
|
||||||
|
float accelBiasVarianceRandomWalk,
|
||||||
|
bool angleBiasVarianceRandomWalk_valid,
|
||||||
|
float angleBiasVarianceRandomWalk,
|
||||||
|
bool rateBiasVarianceRandomWalk_valid,
|
||||||
|
float rateBiasVarianceRandomWalk,
|
||||||
|
bool velocityBiasVarianceRandomWalk_valid,
|
||||||
|
float velocityBiasVarianceRandomWalk);
|
||||||
|
virtual enum loc_api_adapter_err
|
||||||
|
setSensorPerfControlConfig(int controlMode,
|
||||||
|
int accelSamplesPerBatch,
|
||||||
|
int accelBatchesPerSec,
|
||||||
|
int gyroSamplesPerBatch,
|
||||||
|
int gyroBatchesPerSec,
|
||||||
|
int accelSamplesPerBatchHigh,
|
||||||
|
int accelBatchesPerSecHigh,
|
||||||
|
int gyroSamplesPerBatchHigh,
|
||||||
|
int gyroBatchesPerSecHigh,
|
||||||
|
int algorithmConfig);
|
||||||
|
virtual LocationError
|
||||||
|
setAGLONASSProtocol(GnssConfigAGlonassPositionProtocolMask aGlonassProtocol);
|
||||||
|
virtual LocationError setLPPeProtocolCp(GnssConfigLppeControlPlaneMask lppeCP);
|
||||||
|
virtual LocationError setLPPeProtocolUp(GnssConfigLppeUserPlaneMask lppeUP);
|
||||||
|
virtual enum loc_api_adapter_err
|
||||||
|
getWwanZppFix();
|
||||||
|
virtual enum loc_api_adapter_err
|
||||||
|
getBestAvailableZppFix(LocGpsLocation & zppLoc);
|
||||||
|
virtual enum loc_api_adapter_err
|
||||||
|
getBestAvailableZppFix(LocGpsLocation & zppLoc, GpsLocationExtended & locationExtended,
|
||||||
|
LocPosTechMask & tech_mask);
|
||||||
|
virtual int initDataServiceClient(bool isDueToSsr);
|
||||||
|
virtual int openAndStartDataCall();
|
||||||
|
virtual void stopDataCall();
|
||||||
|
virtual void closeDataCall();
|
||||||
|
virtual void releaseDataServiceClient();
|
||||||
|
virtual void installAGpsCert(const LocDerEncodedCertificate* pData,
|
||||||
|
size_t length,
|
||||||
|
uint32_t slotBitMask);
|
||||||
|
inline virtual void setInSession(bool inSession) {
|
||||||
|
|
||||||
|
(void)inSession;
|
||||||
|
}
|
||||||
|
inline bool isMessageSupported (LocCheckingMessagesID msgID) const {
|
||||||
|
|
||||||
|
// confirm if msgID is not larger than the number of bits in
|
||||||
|
// mSupportedMsg
|
||||||
|
if ((uint64_t)msgID > (sizeof(mSupportedMsg) << 3)) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
uint32_t messageChecker = 1 << msgID;
|
||||||
|
return (messageChecker & mSupportedMsg) == messageChecker;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateEvtMask();
|
||||||
|
|
||||||
|
virtual LocationError setGpsLock(GnssConfigGpsLock lock);
|
||||||
|
/*
|
||||||
|
Returns
|
||||||
|
Current value of GPS Lock on success
|
||||||
|
-1 on failure
|
||||||
|
*/
|
||||||
|
virtual int getGpsLock(void);
|
||||||
|
|
||||||
|
virtual LocationError setXtraVersionCheck(uint32_t check);
|
||||||
|
/*
|
||||||
|
Check if the modem support the service
|
||||||
|
*/
|
||||||
|
virtual bool gnssConstellationConfig();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check if a feature is supported
|
||||||
|
*/
|
||||||
|
bool isFeatureSupported(uint8_t featureVal);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef LocApiBase* (getLocApi_t)(const MsgTask* msgTask,
|
||||||
|
LOC_API_ADAPTER_EVENT_MASK_T exMask,
|
||||||
|
ContextBase *context);
|
||||||
|
|
||||||
|
} // namespace loc_core
|
||||||
|
|
||||||
|
#endif //LOC_API_BASE_H
|
150
gps/core/LocDualContext.cpp
Normal file
150
gps/core/LocDualContext.cpp
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
/* Copyright (c) 2011-2014, 2016-2017 The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define LOG_NDEBUG 0
|
||||||
|
#define LOG_TAG "LocSvc_DualCtx"
|
||||||
|
|
||||||
|
#include <cutils/sched_policy.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <LocDualContext.h>
|
||||||
|
#include <msg_q.h>
|
||||||
|
#include <platform_lib_log_util.h>
|
||||||
|
#include <loc_log.h>
|
||||||
|
|
||||||
|
namespace loc_core {
|
||||||
|
|
||||||
|
// nothing exclude for foreground
|
||||||
|
const LOC_API_ADAPTER_EVENT_MASK_T
|
||||||
|
LocDualContext::mFgExclMask = 0;
|
||||||
|
// excluded events for background clients
|
||||||
|
const LOC_API_ADAPTER_EVENT_MASK_T
|
||||||
|
LocDualContext::mBgExclMask =
|
||||||
|
(LOC_API_ADAPTER_BIT_SATELLITE_REPORT |
|
||||||
|
LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT |
|
||||||
|
LOC_API_ADAPTER_BIT_NMEA_POSITION_REPORT |
|
||||||
|
LOC_API_ADAPTER_BIT_IOCTL_REPORT |
|
||||||
|
LOC_API_ADAPTER_BIT_STATUS_REPORT |
|
||||||
|
LOC_API_ADAPTER_BIT_GEOFENCE_GEN_ALERT |
|
||||||
|
LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT);
|
||||||
|
|
||||||
|
const MsgTask* LocDualContext::mMsgTask = NULL;
|
||||||
|
ContextBase* LocDualContext::mFgContext = NULL;
|
||||||
|
ContextBase* LocDualContext::mBgContext = NULL;
|
||||||
|
ContextBase* LocDualContext::mInjectContext = NULL;
|
||||||
|
// the name must be shorter than 15 chars
|
||||||
|
const char* LocDualContext::mLocationHalName = "Loc_hal_worker";
|
||||||
|
#ifndef USE_GLIB
|
||||||
|
const char* LocDualContext::mLBSLibName = "liblbs_core.so";
|
||||||
|
#else
|
||||||
|
const char* LocDualContext::mLBSLibName = "liblbs_core.so.1";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pthread_mutex_t LocDualContext::mGetLocContextMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
const MsgTask* LocDualContext::getMsgTask(LocThread::tCreate tCreator,
|
||||||
|
const char* name, bool joinable)
|
||||||
|
{
|
||||||
|
if (NULL == mMsgTask) {
|
||||||
|
mMsgTask = new MsgTask(tCreator, name, joinable);
|
||||||
|
}
|
||||||
|
return mMsgTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
const MsgTask* LocDualContext::getMsgTask(const char* name, bool joinable) {
|
||||||
|
return getMsgTask((LocThread::tCreate)NULL, name, joinable);
|
||||||
|
}
|
||||||
|
|
||||||
|
ContextBase* LocDualContext::getLocFgContext(LocThread::tCreate tCreator,
|
||||||
|
LocMsg* firstMsg, const char* name, bool joinable)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&LocDualContext::mGetLocContextMutex);
|
||||||
|
LOC_LOGD("%s:%d]: querying ContextBase with tCreator", __func__, __LINE__);
|
||||||
|
if (NULL == mFgContext) {
|
||||||
|
LOC_LOGD("%s:%d]: creating msgTask with tCreator", __func__, __LINE__);
|
||||||
|
const MsgTask* msgTask = getMsgTask(tCreator, name, joinable);
|
||||||
|
mFgContext = new LocDualContext(msgTask,
|
||||||
|
mFgExclMask);
|
||||||
|
}
|
||||||
|
if(NULL == mInjectContext) {
|
||||||
|
LOC_LOGD("%s:%d]: mInjectContext is FgContext", __func__, __LINE__);
|
||||||
|
mInjectContext = mFgContext;
|
||||||
|
injectFeatureConfig(mInjectContext);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&LocDualContext::mGetLocContextMutex);
|
||||||
|
|
||||||
|
if (firstMsg) {
|
||||||
|
mFgContext->sendMsg(firstMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mFgContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
ContextBase* LocDualContext::getLocBgContext(LocThread::tCreate tCreator,
|
||||||
|
LocMsg* firstMsg, const char* name, bool joinable)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&LocDualContext::mGetLocContextMutex);
|
||||||
|
LOC_LOGD("%s:%d]: querying ContextBase with tCreator", __func__, __LINE__);
|
||||||
|
if (NULL == mBgContext) {
|
||||||
|
LOC_LOGD("%s:%d]: creating msgTask with tCreator", __func__, __LINE__);
|
||||||
|
const MsgTask* msgTask = getMsgTask(tCreator, name, joinable);
|
||||||
|
mBgContext = new LocDualContext(msgTask,
|
||||||
|
mBgExclMask);
|
||||||
|
}
|
||||||
|
if(NULL == mInjectContext) {
|
||||||
|
LOC_LOGD("%s:%d]: mInjectContext is BgContext", __func__, __LINE__);
|
||||||
|
mInjectContext = mBgContext;
|
||||||
|
injectFeatureConfig(mInjectContext);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&LocDualContext::mGetLocContextMutex);
|
||||||
|
|
||||||
|
if (firstMsg) {
|
||||||
|
mBgContext->sendMsg(firstMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mBgContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocDualContext :: injectFeatureConfig(ContextBase *curContext)
|
||||||
|
{
|
||||||
|
LOC_LOGD("%s:%d]: Enter", __func__, __LINE__);
|
||||||
|
if(curContext == mInjectContext) {
|
||||||
|
LOC_LOGD("%s:%d]: Calling LBSProxy (%p) to inject feature config",
|
||||||
|
__func__, __LINE__, ((LocDualContext *)mInjectContext)->mLBSProxy);
|
||||||
|
((LocDualContext *)mInjectContext)->mLBSProxy->injectFeatureConfig(curContext);
|
||||||
|
}
|
||||||
|
LOC_LOGD("%s:%d]: Exit", __func__, __LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
LocDualContext::LocDualContext(const MsgTask* msgTask,
|
||||||
|
LOC_API_ADAPTER_EVENT_MASK_T exMask) :
|
||||||
|
ContextBase(msgTask, exMask, mLBSLibName)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
76
gps/core/LocDualContext.h
Normal file
76
gps/core/LocDualContext.h
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
/* Copyright (c) 2011-2014, 2017 The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef __LOC_ENG_CONTEXT__
|
||||||
|
#define __LOC_ENG_CONTEXT__
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <ContextBase.h>
|
||||||
|
|
||||||
|
namespace loc_core {
|
||||||
|
|
||||||
|
class LocDualContext : public ContextBase {
|
||||||
|
static const MsgTask* mMsgTask;
|
||||||
|
static ContextBase* mFgContext;
|
||||||
|
static ContextBase* mBgContext;
|
||||||
|
static ContextBase* mInjectContext;
|
||||||
|
static const MsgTask* getMsgTask(LocThread::tCreate tCreator,
|
||||||
|
const char* name, bool joinable = true);
|
||||||
|
static const MsgTask* getMsgTask(const char* name, bool joinable = true);
|
||||||
|
static pthread_mutex_t mGetLocContextMutex;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
LocDualContext(const MsgTask* msgTask,
|
||||||
|
LOC_API_ADAPTER_EVENT_MASK_T exMask);
|
||||||
|
inline virtual ~LocDualContext() {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
static const char* mLBSLibName;
|
||||||
|
static const LOC_API_ADAPTER_EVENT_MASK_T mFgExclMask;
|
||||||
|
static const LOC_API_ADAPTER_EVENT_MASK_T mBgExclMask;
|
||||||
|
static const char* mLocationHalName;
|
||||||
|
|
||||||
|
static ContextBase* getLocFgContext(LocThread::tCreate tCreator, LocMsg* firstMsg,
|
||||||
|
const char* name, bool joinable = true);
|
||||||
|
inline static ContextBase* getLocFgContext(const char* name, bool joinable = true) {
|
||||||
|
return getLocFgContext(NULL, NULL, name, joinable);
|
||||||
|
}
|
||||||
|
static ContextBase* getLocBgContext(LocThread::tCreate tCreator, LocMsg* firstMsg,
|
||||||
|
const char* name, bool joinable = true);
|
||||||
|
inline static ContextBase* getLocBgContext(const char* name, bool joinable = true) {
|
||||||
|
return getLocBgContext(NULL, NULL, name, joinable);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void injectFeatureConfig(ContextBase *context);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //__LOC_ENG_CONTEXT__
|
62
gps/core/Makefile.am
Normal file
62
gps/core/Makefile.am
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
AM_CFLAGS = -I./ \
|
||||||
|
-I../utils \
|
||||||
|
-I../location \
|
||||||
|
$(LOCPLA_CFLAGS) \
|
||||||
|
$(GPSUTILS_CFLAGS) \
|
||||||
|
-I$(WORKSPACE)/gps-noship/flp \
|
||||||
|
-D__func__=__PRETTY_FUNCTION__ \
|
||||||
|
-fno-short-enums \
|
||||||
|
-std=c++11
|
||||||
|
|
||||||
|
libloc_core_la_h_sources = \
|
||||||
|
LocApiBase.h \
|
||||||
|
LocAdapterBase.h \
|
||||||
|
ContextBase.h \
|
||||||
|
LocDualContext.h \
|
||||||
|
LBSProxyBase.h \
|
||||||
|
UlpProxyBase.h \
|
||||||
|
loc_core_log.h \
|
||||||
|
LocAdapterProxyBase.h \
|
||||||
|
data-items/DataItemId.h \
|
||||||
|
data-items/IDataItemCore.h \
|
||||||
|
data-items/DataItemConcreteTypesBase.h \
|
||||||
|
observer/IDataItemObserver.h \
|
||||||
|
observer/IDataItemSubscription.h \
|
||||||
|
observer/IFrameworkActionReq.h \
|
||||||
|
observer/IOsObserver.h \
|
||||||
|
SystemStatusOsObserver.h \
|
||||||
|
SystemStatus.h
|
||||||
|
|
||||||
|
libloc_core_la_c_sources = \
|
||||||
|
LocApiBase.cpp \
|
||||||
|
LocAdapterBase.cpp \
|
||||||
|
ContextBase.cpp \
|
||||||
|
LocDualContext.cpp \
|
||||||
|
loc_core_log.cpp \
|
||||||
|
data-items/DataItemsFactoryProxy.cpp \
|
||||||
|
data-items/common/ClientIndex.cpp \
|
||||||
|
data-items/common/DataItemIndex.cpp \
|
||||||
|
data-items/common/IndexFactory.cpp \
|
||||||
|
SystemStatusOsObserver.cpp \
|
||||||
|
SystemStatus.cpp
|
||||||
|
|
||||||
|
library_includedir = $(pkgincludedir)/core
|
||||||
|
|
||||||
|
library_include_HEADERS = $(libloc_core_la_h_sources)
|
||||||
|
|
||||||
|
libloc_core_la_SOURCES = $(libloc_core_la_c_sources)
|
||||||
|
|
||||||
|
if USE_GLIB
|
||||||
|
libloc_core_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@
|
||||||
|
libloc_core_la_LDFLAGS = -lstdc++ -Wl,-z,defs -lpthread @GLIB_LIBS@ -shared -version-info 1:0:0
|
||||||
|
libloc_core_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@
|
||||||
|
else
|
||||||
|
libloc_core_la_CFLAGS = $(AM_CFLAGS)
|
||||||
|
libloc_core_la_LDFLAGS = -Wl,-z,defs -lpthread -shared -version-info 1:0:0
|
||||||
|
libloc_core_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
libloc_core_la_LIBADD = -lstdc++ -ldl $(LOCPLA_LIBS) $(GPSUTILS_LIBS)
|
||||||
|
|
||||||
|
#Create and Install libraries
|
||||||
|
lib_LTLIBRARIES = libloc_core.la
|
1693
gps/core/SystemStatus.cpp
Normal file
1693
gps/core/SystemStatus.cpp
Normal file
File diff suppressed because it is too large
Load diff
806
gps/core/SystemStatus.h
Normal file
806
gps/core/SystemStatus.h
Normal file
|
@ -0,0 +1,806 @@
|
||||||
|
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef __SYSTEM_STATUS__
|
||||||
|
#define __SYSTEM_STATUS__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <platform_lib_log_util.h>
|
||||||
|
#include <MsgTask.h>
|
||||||
|
#include <IDataItemCore.h>
|
||||||
|
#include <IOsObserver.h>
|
||||||
|
#include <DataItemConcreteTypesBase.h>
|
||||||
|
#include <SystemStatusOsObserver.h>
|
||||||
|
|
||||||
|
#include <gps_extended_c.h>
|
||||||
|
|
||||||
|
#define GPS_MIN (1) //1-32
|
||||||
|
#define SBAS_MIN (33)
|
||||||
|
#define GLO_MIN (65) //65-88
|
||||||
|
#define QZSS_MIN (193) //193-197
|
||||||
|
#define BDS_MIN (201) //201-237
|
||||||
|
#define GAL_MIN (301) //301-336
|
||||||
|
|
||||||
|
#define GPS_NUM (32)
|
||||||
|
#define SBAS_NUM (32)
|
||||||
|
#define GLO_NUM (24)
|
||||||
|
#define QZSS_NUM (5)
|
||||||
|
#define BDS_NUM (37)
|
||||||
|
#define GAL_NUM (36)
|
||||||
|
#define SV_ALL_NUM (GPS_NUM+GLO_NUM+QZSS_NUM+BDS_NUM+GAL_NUM) //=134
|
||||||
|
|
||||||
|
namespace loc_core
|
||||||
|
{
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
SystemStatus report data structure
|
||||||
|
******************************************************************************/
|
||||||
|
class SystemStatusItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
timespec mUtcTime; // UTC timestamp when this info was last updated
|
||||||
|
timespec mUtcReported; // UTC timestamp when this info was reported
|
||||||
|
static const uint32_t maxItem = 5;
|
||||||
|
|
||||||
|
SystemStatusItemBase() {
|
||||||
|
timeval tv;
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
mUtcTime.tv_sec = tv.tv_sec;
|
||||||
|
mUtcTime.tv_nsec = tv.tv_usec *1000ULL;
|
||||||
|
mUtcReported = mUtcTime;
|
||||||
|
};
|
||||||
|
virtual ~SystemStatusItemBase() { };
|
||||||
|
virtual void dump(void) { };
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusLocation : public SystemStatusItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool mValid;
|
||||||
|
UlpLocation mLocation;
|
||||||
|
GpsLocationExtended mLocationEx;
|
||||||
|
inline SystemStatusLocation() :
|
||||||
|
mValid(false) {}
|
||||||
|
inline SystemStatusLocation(const UlpLocation& location,
|
||||||
|
const GpsLocationExtended& locationEx) :
|
||||||
|
mValid(true),
|
||||||
|
mLocation(location),
|
||||||
|
mLocationEx(locationEx) { }
|
||||||
|
bool equals(const SystemStatusLocation& peer);
|
||||||
|
void dump(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusPQWM1;
|
||||||
|
class SystemStatusTimeAndClock : public SystemStatusItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint16_t mGpsWeek;
|
||||||
|
uint32_t mGpsTowMs;
|
||||||
|
uint8_t mTimeValid;
|
||||||
|
uint8_t mTimeSource;
|
||||||
|
int32_t mTimeUnc;
|
||||||
|
int32_t mClockFreqBias;
|
||||||
|
int32_t mClockFreqBiasUnc;
|
||||||
|
int32_t mLeapSeconds;
|
||||||
|
int32_t mLeapSecUnc;
|
||||||
|
inline SystemStatusTimeAndClock() :
|
||||||
|
mGpsWeek(0),
|
||||||
|
mGpsTowMs(0),
|
||||||
|
mTimeValid(0),
|
||||||
|
mTimeSource(0),
|
||||||
|
mTimeUnc(0),
|
||||||
|
mClockFreqBias(0),
|
||||||
|
mClockFreqBiasUnc(0),
|
||||||
|
mLeapSeconds(0),
|
||||||
|
mLeapSecUnc(0) {}
|
||||||
|
inline SystemStatusTimeAndClock(const SystemStatusPQWM1& nmea);
|
||||||
|
bool equals(const SystemStatusTimeAndClock& peer);
|
||||||
|
void dump(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusXoState : public SystemStatusItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint8_t mXoState;
|
||||||
|
inline SystemStatusXoState() :
|
||||||
|
mXoState(0) {}
|
||||||
|
inline SystemStatusXoState(const SystemStatusPQWM1& nmea);
|
||||||
|
bool equals(const SystemStatusXoState& peer);
|
||||||
|
void dump(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusRfAndParams : public SystemStatusItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int32_t mPgaGain;
|
||||||
|
uint32_t mGpsBpAmpI;
|
||||||
|
uint32_t mGpsBpAmpQ;
|
||||||
|
uint32_t mAdcI;
|
||||||
|
uint32_t mAdcQ;
|
||||||
|
uint32_t mJammerGps;
|
||||||
|
uint32_t mJammerGlo;
|
||||||
|
uint32_t mJammerBds;
|
||||||
|
uint32_t mJammerGal;
|
||||||
|
double mAgcGps;
|
||||||
|
double mAgcGlo;
|
||||||
|
double mAgcBds;
|
||||||
|
double mAgcGal;
|
||||||
|
inline SystemStatusRfAndParams() :
|
||||||
|
mPgaGain(0),
|
||||||
|
mGpsBpAmpI(0),
|
||||||
|
mGpsBpAmpQ(0),
|
||||||
|
mAdcI(0),
|
||||||
|
mAdcQ(0),
|
||||||
|
mJammerGps(0),
|
||||||
|
mJammerGlo(0),
|
||||||
|
mJammerBds(0),
|
||||||
|
mJammerGal(0),
|
||||||
|
mAgcGps(0),
|
||||||
|
mAgcGlo(0),
|
||||||
|
mAgcBds(0),
|
||||||
|
mAgcGal(0) {}
|
||||||
|
inline SystemStatusRfAndParams(const SystemStatusPQWM1& nmea);
|
||||||
|
bool equals(const SystemStatusRfAndParams& peer);
|
||||||
|
void dump(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusErrRecovery : public SystemStatusItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint32_t mRecErrorRecovery;
|
||||||
|
inline SystemStatusErrRecovery() :
|
||||||
|
mRecErrorRecovery(0) {};
|
||||||
|
inline SystemStatusErrRecovery(const SystemStatusPQWM1& nmea);
|
||||||
|
bool equals(const SystemStatusErrRecovery& peer);
|
||||||
|
void dump(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusPQWP1;
|
||||||
|
class SystemStatusInjectedPosition : public SystemStatusItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint8_t mEpiValidity;
|
||||||
|
float mEpiLat;
|
||||||
|
float mEpiLon;
|
||||||
|
float mEpiAlt;
|
||||||
|
float mEpiHepe;
|
||||||
|
float mEpiAltUnc;
|
||||||
|
uint8_t mEpiSrc;
|
||||||
|
inline SystemStatusInjectedPosition() :
|
||||||
|
mEpiValidity(0),
|
||||||
|
mEpiLat(0),
|
||||||
|
mEpiLon(0),
|
||||||
|
mEpiAlt(0),
|
||||||
|
mEpiHepe(0),
|
||||||
|
mEpiAltUnc(0),
|
||||||
|
mEpiSrc(0) {}
|
||||||
|
inline SystemStatusInjectedPosition(const SystemStatusPQWP1& nmea);
|
||||||
|
bool equals(const SystemStatusInjectedPosition& peer);
|
||||||
|
void dump(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusPQWP2;
|
||||||
|
class SystemStatusBestPosition : public SystemStatusItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool mValid;
|
||||||
|
float mBestLat;
|
||||||
|
float mBestLon;
|
||||||
|
float mBestAlt;
|
||||||
|
float mBestHepe;
|
||||||
|
float mBestAltUnc;
|
||||||
|
inline SystemStatusBestPosition() :
|
||||||
|
mValid(false),
|
||||||
|
mBestLat(0),
|
||||||
|
mBestLon(0),
|
||||||
|
mBestAlt(0),
|
||||||
|
mBestHepe(0),
|
||||||
|
mBestAltUnc(0) {}
|
||||||
|
inline SystemStatusBestPosition(const SystemStatusPQWP2& nmea);
|
||||||
|
bool equals(const SystemStatusBestPosition& peer);
|
||||||
|
void dump(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusPQWP3;
|
||||||
|
class SystemStatusXtra : public SystemStatusItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint8_t mXtraValidMask;
|
||||||
|
uint32_t mGpsXtraAge;
|
||||||
|
uint32_t mGloXtraAge;
|
||||||
|
uint32_t mBdsXtraAge;
|
||||||
|
uint32_t mGalXtraAge;
|
||||||
|
uint32_t mQzssXtraAge;
|
||||||
|
uint32_t mGpsXtraValid;
|
||||||
|
uint32_t mGloXtraValid;
|
||||||
|
uint64_t mBdsXtraValid;
|
||||||
|
uint64_t mGalXtraValid;
|
||||||
|
uint8_t mQzssXtraValid;
|
||||||
|
inline SystemStatusXtra() :
|
||||||
|
mXtraValidMask(0),
|
||||||
|
mGpsXtraAge(0),
|
||||||
|
mGloXtraAge(0),
|
||||||
|
mBdsXtraAge(0),
|
||||||
|
mGalXtraAge(0),
|
||||||
|
mQzssXtraAge(0),
|
||||||
|
mGpsXtraValid(0),
|
||||||
|
mGloXtraValid(0),
|
||||||
|
mBdsXtraValid(0ULL),
|
||||||
|
mGalXtraValid(0ULL),
|
||||||
|
mQzssXtraValid(0) {}
|
||||||
|
inline SystemStatusXtra(const SystemStatusPQWP3& nmea);
|
||||||
|
bool equals(const SystemStatusXtra& peer);
|
||||||
|
void dump(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusPQWP4;
|
||||||
|
class SystemStatusEphemeris : public SystemStatusItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint32_t mGpsEpheValid;
|
||||||
|
uint32_t mGloEpheValid;
|
||||||
|
uint64_t mBdsEpheValid;
|
||||||
|
uint64_t mGalEpheValid;
|
||||||
|
uint8_t mQzssEpheValid;
|
||||||
|
inline SystemStatusEphemeris() :
|
||||||
|
mGpsEpheValid(0),
|
||||||
|
mGloEpheValid(0),
|
||||||
|
mBdsEpheValid(0ULL),
|
||||||
|
mGalEpheValid(0ULL),
|
||||||
|
mQzssEpheValid(0) {}
|
||||||
|
inline SystemStatusEphemeris(const SystemStatusPQWP4& nmea);
|
||||||
|
bool equals(const SystemStatusEphemeris& peer);
|
||||||
|
void dump(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusPQWP5;
|
||||||
|
class SystemStatusSvHealth : public SystemStatusItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint32_t mGpsUnknownMask;
|
||||||
|
uint32_t mGloUnknownMask;
|
||||||
|
uint64_t mBdsUnknownMask;
|
||||||
|
uint64_t mGalUnknownMask;
|
||||||
|
uint8_t mQzssUnknownMask;
|
||||||
|
uint32_t mGpsGoodMask;
|
||||||
|
uint32_t mGloGoodMask;
|
||||||
|
uint64_t mBdsGoodMask;
|
||||||
|
uint64_t mGalGoodMask;
|
||||||
|
uint8_t mQzssGoodMask;
|
||||||
|
uint32_t mGpsBadMask;
|
||||||
|
uint32_t mGloBadMask;
|
||||||
|
uint64_t mBdsBadMask;
|
||||||
|
uint64_t mGalBadMask;
|
||||||
|
uint8_t mQzssBadMask;
|
||||||
|
inline SystemStatusSvHealth() :
|
||||||
|
mGpsUnknownMask(0),
|
||||||
|
mGloUnknownMask(0),
|
||||||
|
mBdsUnknownMask(0ULL),
|
||||||
|
mGalUnknownMask(0ULL),
|
||||||
|
mQzssUnknownMask(0),
|
||||||
|
mGpsGoodMask(0),
|
||||||
|
mGloGoodMask(0),
|
||||||
|
mBdsGoodMask(0ULL),
|
||||||
|
mGalGoodMask(0ULL),
|
||||||
|
mQzssGoodMask(0),
|
||||||
|
mGpsBadMask(0),
|
||||||
|
mGloBadMask(0),
|
||||||
|
mBdsBadMask(0ULL),
|
||||||
|
mGalBadMask(0ULL),
|
||||||
|
mQzssBadMask(0) {}
|
||||||
|
inline SystemStatusSvHealth(const SystemStatusPQWP5& nmea);
|
||||||
|
bool equals(const SystemStatusSvHealth& peer);
|
||||||
|
void dump(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusPQWP6;
|
||||||
|
class SystemStatusPdr : public SystemStatusItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint32_t mFixInfoMask;
|
||||||
|
inline SystemStatusPdr() :
|
||||||
|
mFixInfoMask(0) {}
|
||||||
|
inline SystemStatusPdr(const SystemStatusPQWP6& nmea);
|
||||||
|
bool equals(const SystemStatusPdr& peer);
|
||||||
|
void dump(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusPQWP7;
|
||||||
|
struct SystemStatusNav
|
||||||
|
{
|
||||||
|
GnssEphemerisType mType;
|
||||||
|
GnssEphemerisSource mSource;
|
||||||
|
int32_t mAgeSec;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusNavData : public SystemStatusItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SystemStatusNav mNav[SV_ALL_NUM];
|
||||||
|
inline SystemStatusNavData() {
|
||||||
|
for (uint32_t i=0; i<SV_ALL_NUM; i++) {
|
||||||
|
mNav[i].mType = GNSS_EPH_TYPE_UNKNOWN;
|
||||||
|
mNav[i].mSource = GNSS_EPH_SOURCE_UNKNOWN;
|
||||||
|
mNav[i].mAgeSec = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inline SystemStatusNavData(const SystemStatusPQWP7& nmea);
|
||||||
|
bool equals(const SystemStatusNavData& peer);
|
||||||
|
void dump(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusPQWS1;
|
||||||
|
class SystemStatusPositionFailure : public SystemStatusItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint32_t mFixInfoMask;
|
||||||
|
uint32_t mHepeLimit;
|
||||||
|
inline SystemStatusPositionFailure() :
|
||||||
|
mFixInfoMask(0),
|
||||||
|
mHepeLimit(0) {}
|
||||||
|
inline SystemStatusPositionFailure(const SystemStatusPQWS1& nmea);
|
||||||
|
bool equals(const SystemStatusPositionFailure& peer);
|
||||||
|
void dump(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
SystemStatus report data structure - from DataItem observer
|
||||||
|
******************************************************************************/
|
||||||
|
class SystemStatusAirplaneMode : public SystemStatusItemBase,
|
||||||
|
public AirplaneModeDataItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline SystemStatusAirplaneMode(bool mode=false) :
|
||||||
|
AirplaneModeDataItemBase(mode) {}
|
||||||
|
inline SystemStatusAirplaneMode(const AirplaneModeDataItemBase& itemBase) :
|
||||||
|
AirplaneModeDataItemBase(itemBase) {}
|
||||||
|
inline bool equals(const SystemStatusAirplaneMode& peer) {
|
||||||
|
return (mMode == peer.mMode);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusENH : public SystemStatusItemBase,
|
||||||
|
public ENHDataItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline SystemStatusENH(bool enabled=false) :
|
||||||
|
ENHDataItemBase(enabled) {}
|
||||||
|
inline SystemStatusENH(const ENHDataItemBase& itemBase) :
|
||||||
|
ENHDataItemBase(itemBase) {}
|
||||||
|
inline bool equals(const SystemStatusENH& peer) {
|
||||||
|
return (mEnabled == peer.mEnabled);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusGpsState : public SystemStatusItemBase,
|
||||||
|
public GPSStateDataItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline SystemStatusGpsState(bool enabled=false) :
|
||||||
|
GPSStateDataItemBase(enabled) {}
|
||||||
|
inline SystemStatusGpsState(const GPSStateDataItemBase& itemBase) :
|
||||||
|
GPSStateDataItemBase(itemBase) {}
|
||||||
|
inline bool equals(const SystemStatusGpsState& peer) {
|
||||||
|
return (mEnabled == peer.mEnabled);
|
||||||
|
}
|
||||||
|
inline void dump(void) override {
|
||||||
|
LOC_LOGD("GpsState: state=%u", mEnabled);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusNLPStatus : public SystemStatusItemBase,
|
||||||
|
public NLPStatusDataItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline SystemStatusNLPStatus(bool enabled=false) :
|
||||||
|
NLPStatusDataItemBase(enabled) {}
|
||||||
|
inline SystemStatusNLPStatus(const NLPStatusDataItemBase& itemBase) :
|
||||||
|
NLPStatusDataItemBase(itemBase) {}
|
||||||
|
inline bool equals(const SystemStatusNLPStatus& peer) {
|
||||||
|
return (mEnabled == peer.mEnabled);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusWifiHardwareState : public SystemStatusItemBase,
|
||||||
|
public WifiHardwareStateDataItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline SystemStatusWifiHardwareState(bool enabled=false) :
|
||||||
|
WifiHardwareStateDataItemBase(enabled) {}
|
||||||
|
inline SystemStatusWifiHardwareState(const WifiHardwareStateDataItemBase& itemBase) :
|
||||||
|
WifiHardwareStateDataItemBase(itemBase) {}
|
||||||
|
inline bool equals(const SystemStatusWifiHardwareState& peer) {
|
||||||
|
return (mEnabled == peer.mEnabled);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusNetworkInfo : public SystemStatusItemBase,
|
||||||
|
public NetworkInfoDataItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline SystemStatusNetworkInfo(
|
||||||
|
int32_t type=0,
|
||||||
|
std::string typeName="",
|
||||||
|
string subTypeName="",
|
||||||
|
bool available=false,
|
||||||
|
bool connected=false,
|
||||||
|
bool roaming=false) :
|
||||||
|
NetworkInfoDataItemBase(
|
||||||
|
type,
|
||||||
|
typeName,
|
||||||
|
subTypeName,
|
||||||
|
available,
|
||||||
|
connected,
|
||||||
|
roaming) {}
|
||||||
|
inline SystemStatusNetworkInfo(const NetworkInfoDataItemBase& itemBase) :
|
||||||
|
NetworkInfoDataItemBase(itemBase) {
|
||||||
|
mType = itemBase.getType();
|
||||||
|
}
|
||||||
|
inline bool equals(const SystemStatusNetworkInfo& peer) {
|
||||||
|
if ((mType == peer.mType) &&
|
||||||
|
(mTypeName == peer.mTypeName) &&
|
||||||
|
(mSubTypeName == peer.mSubTypeName) &&
|
||||||
|
(mAvailable == peer.mAvailable) &&
|
||||||
|
(mConnected == peer.mConnected) &&
|
||||||
|
(mRoaming == peer.mRoaming)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
inline void dump(void) override {
|
||||||
|
LOC_LOGD("NetworkInfo: type=%u connected=%u", mType, mConnected);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusServiceInfo : public SystemStatusItemBase,
|
||||||
|
public RilServiceInfoDataItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline SystemStatusServiceInfo() :
|
||||||
|
RilServiceInfoDataItemBase() {}
|
||||||
|
inline SystemStatusServiceInfo(const RilServiceInfoDataItemBase& itemBase) :
|
||||||
|
RilServiceInfoDataItemBase(itemBase) {}
|
||||||
|
inline bool equals(const SystemStatusServiceInfo& /*peer*/) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusRilCellInfo : public SystemStatusItemBase,
|
||||||
|
public RilCellInfoDataItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline SystemStatusRilCellInfo() :
|
||||||
|
RilCellInfoDataItemBase() {}
|
||||||
|
inline SystemStatusRilCellInfo(const RilCellInfoDataItemBase& itemBase) :
|
||||||
|
RilCellInfoDataItemBase(itemBase) {}
|
||||||
|
inline bool equals(const SystemStatusRilCellInfo& /*peer*/) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusServiceStatus : public SystemStatusItemBase,
|
||||||
|
public ServiceStatusDataItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline SystemStatusServiceStatus(int32_t mServiceState=0) :
|
||||||
|
ServiceStatusDataItemBase(mServiceState) {}
|
||||||
|
inline SystemStatusServiceStatus(const ServiceStatusDataItemBase& itemBase) :
|
||||||
|
ServiceStatusDataItemBase(itemBase) {}
|
||||||
|
inline bool equals(const SystemStatusServiceStatus& peer) {
|
||||||
|
return (mServiceState == peer.mServiceState);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusModel : public SystemStatusItemBase,
|
||||||
|
public ModelDataItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline SystemStatusModel(string name="") :
|
||||||
|
ModelDataItemBase(name) {}
|
||||||
|
inline SystemStatusModel(const ModelDataItemBase& itemBase) :
|
||||||
|
ModelDataItemBase(itemBase) {}
|
||||||
|
inline bool equals(const SystemStatusModel& peer) {
|
||||||
|
return (mModel == peer.mModel);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusManufacturer : public SystemStatusItemBase,
|
||||||
|
public ManufacturerDataItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline SystemStatusManufacturer(string name="") :
|
||||||
|
ManufacturerDataItemBase(name) {}
|
||||||
|
inline SystemStatusManufacturer(const ManufacturerDataItemBase& itemBase) :
|
||||||
|
ManufacturerDataItemBase(itemBase) {}
|
||||||
|
inline bool equals(const SystemStatusManufacturer& peer) {
|
||||||
|
return (mManufacturer == peer.mManufacturer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusAssistedGps : public SystemStatusItemBase,
|
||||||
|
public AssistedGpsDataItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline SystemStatusAssistedGps(bool enabled=false) :
|
||||||
|
AssistedGpsDataItemBase(enabled) {}
|
||||||
|
inline SystemStatusAssistedGps(const AssistedGpsDataItemBase& itemBase) :
|
||||||
|
AssistedGpsDataItemBase(itemBase) {}
|
||||||
|
inline bool equals(const SystemStatusAssistedGps& peer) {
|
||||||
|
return (mEnabled == peer.mEnabled);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusScreenState : public SystemStatusItemBase,
|
||||||
|
public ScreenStateDataItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline SystemStatusScreenState(bool state=false) :
|
||||||
|
ScreenStateDataItemBase(state) {}
|
||||||
|
inline SystemStatusScreenState(const ScreenStateDataItemBase& itemBase) :
|
||||||
|
ScreenStateDataItemBase(itemBase) {}
|
||||||
|
inline bool equals(const SystemStatusScreenState& peer) {
|
||||||
|
return (mState == peer.mState);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusPowerConnectState : public SystemStatusItemBase,
|
||||||
|
public PowerConnectStateDataItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline SystemStatusPowerConnectState(bool state=false) :
|
||||||
|
PowerConnectStateDataItemBase(state) {}
|
||||||
|
inline SystemStatusPowerConnectState(const PowerConnectStateDataItemBase& itemBase) :
|
||||||
|
PowerConnectStateDataItemBase(itemBase) {}
|
||||||
|
inline bool equals(const SystemStatusPowerConnectState& peer) {
|
||||||
|
return (mState == peer.mState);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusTimeZoneChange : public SystemStatusItemBase,
|
||||||
|
public TimeZoneChangeDataItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline SystemStatusTimeZoneChange(
|
||||||
|
int64_t currTimeMillis=0ULL, int32_t rawOffset=0, int32_t dstOffset=0) :
|
||||||
|
TimeZoneChangeDataItemBase(currTimeMillis, rawOffset, dstOffset) {}
|
||||||
|
inline SystemStatusTimeZoneChange(const TimeZoneChangeDataItemBase& itemBase) :
|
||||||
|
TimeZoneChangeDataItemBase(itemBase) {}
|
||||||
|
inline bool equals(const SystemStatusTimeZoneChange& peer) {
|
||||||
|
return ((mCurrTimeMillis == peer.mCurrTimeMillis) &&
|
||||||
|
(mRawOffsetTZ == peer.mRawOffsetTZ) &&
|
||||||
|
(mDstOffsetTZ == peer.mDstOffsetTZ));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusTimeChange : public SystemStatusItemBase,
|
||||||
|
public TimeChangeDataItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline SystemStatusTimeChange(
|
||||||
|
int64_t currTimeMillis=0ULL, int32_t rawOffset=0, int32_t dstOffset=0) :
|
||||||
|
TimeChangeDataItemBase(currTimeMillis, rawOffset, dstOffset) {}
|
||||||
|
inline SystemStatusTimeChange(const TimeChangeDataItemBase& itemBase) :
|
||||||
|
TimeChangeDataItemBase(itemBase) {}
|
||||||
|
inline bool equals(const SystemStatusTimeChange& peer) {
|
||||||
|
return ((mCurrTimeMillis == peer.mCurrTimeMillis) &&
|
||||||
|
(mRawOffsetTZ == peer.mRawOffsetTZ) &&
|
||||||
|
(mDstOffsetTZ == peer.mDstOffsetTZ));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusWifiSupplicantStatus : public SystemStatusItemBase,
|
||||||
|
public WifiSupplicantStatusDataItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline SystemStatusWifiSupplicantStatus() :
|
||||||
|
WifiSupplicantStatusDataItemBase() {}
|
||||||
|
inline SystemStatusWifiSupplicantStatus(const WifiSupplicantStatusDataItemBase& itemBase) :
|
||||||
|
WifiSupplicantStatusDataItemBase(itemBase) {}
|
||||||
|
inline bool equals(const SystemStatusWifiSupplicantStatus& peer) {
|
||||||
|
return ((mState == peer.mState) &&
|
||||||
|
(mApMacAddressValid == peer.mApMacAddressValid) &&
|
||||||
|
(mWifiApSsidValid == peer.mWifiApSsidValid) &&
|
||||||
|
(mWifiApSsid == peer.mWifiApSsid));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusShutdownState : public SystemStatusItemBase,
|
||||||
|
public ShutdownStateDataItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline SystemStatusShutdownState(bool state=false) :
|
||||||
|
ShutdownStateDataItemBase(state) {}
|
||||||
|
inline SystemStatusShutdownState(const ShutdownStateDataItemBase& itemBase) :
|
||||||
|
ShutdownStateDataItemBase(itemBase) {}
|
||||||
|
inline bool equals(const SystemStatusShutdownState& peer) {
|
||||||
|
return (mState == peer.mState);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusTac : public SystemStatusItemBase,
|
||||||
|
public TacDataItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline SystemStatusTac(std::string value="") :
|
||||||
|
TacDataItemBase(value) {}
|
||||||
|
inline SystemStatusTac(const TacDataItemBase& itemBase) :
|
||||||
|
TacDataItemBase(itemBase) {}
|
||||||
|
inline bool equals(const SystemStatusTac& peer) {
|
||||||
|
return (mValue == peer.mValue);
|
||||||
|
}
|
||||||
|
inline void dump(void) {
|
||||||
|
LOC_LOGD("Tac: value=%s", mValue.c_str());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusMccMnc : public SystemStatusItemBase,
|
||||||
|
public MccmncDataItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline SystemStatusMccMnc(std::string value="") :
|
||||||
|
MccmncDataItemBase(value) {}
|
||||||
|
inline SystemStatusMccMnc(const MccmncDataItemBase& itemBase) :
|
||||||
|
MccmncDataItemBase(itemBase) {}
|
||||||
|
inline bool equals(const SystemStatusMccMnc& peer) {
|
||||||
|
return (mValue == peer.mValue);
|
||||||
|
}
|
||||||
|
inline void dump(void) {
|
||||||
|
LOC_LOGD("TacMccMnc value=%s", mValue.c_str());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusBtDeviceScanDetail : public SystemStatusItemBase,
|
||||||
|
public BtDeviceScanDetailsDataItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline SystemStatusBtDeviceScanDetail() :
|
||||||
|
BtDeviceScanDetailsDataItemBase() {}
|
||||||
|
inline SystemStatusBtDeviceScanDetail(const BtDeviceScanDetailsDataItemBase& itemBase) :
|
||||||
|
BtDeviceScanDetailsDataItemBase(itemBase) {}
|
||||||
|
inline bool equals(const SystemStatusBtDeviceScanDetail& /*peer*/) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemStatusBtleDeviceScanDetail : public SystemStatusItemBase,
|
||||||
|
public BtLeDeviceScanDetailsDataItemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline SystemStatusBtleDeviceScanDetail() :
|
||||||
|
BtLeDeviceScanDetailsDataItemBase() {}
|
||||||
|
inline SystemStatusBtleDeviceScanDetail(const BtLeDeviceScanDetailsDataItemBase& itemBase) :
|
||||||
|
BtLeDeviceScanDetailsDataItemBase(itemBase) {}
|
||||||
|
inline bool equals(const SystemStatusBtleDeviceScanDetail& /*peer*/) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
SystemStatusReports
|
||||||
|
******************************************************************************/
|
||||||
|
class SystemStatusReports
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// from QMI_LOC indication
|
||||||
|
std::vector<SystemStatusLocation> mLocation;
|
||||||
|
|
||||||
|
// from ME debug NMEA
|
||||||
|
std::vector<SystemStatusTimeAndClock> mTimeAndClock;
|
||||||
|
std::vector<SystemStatusXoState> mXoState;
|
||||||
|
std::vector<SystemStatusRfAndParams> mRfAndParams;
|
||||||
|
std::vector<SystemStatusErrRecovery> mErrRecovery;
|
||||||
|
|
||||||
|
// from PE debug NMEA
|
||||||
|
std::vector<SystemStatusInjectedPosition> mInjectedPosition;
|
||||||
|
std::vector<SystemStatusBestPosition> mBestPosition;
|
||||||
|
std::vector<SystemStatusXtra> mXtra;
|
||||||
|
std::vector<SystemStatusEphemeris> mEphemeris;
|
||||||
|
std::vector<SystemStatusSvHealth> mSvHealth;
|
||||||
|
std::vector<SystemStatusPdr> mPdr;
|
||||||
|
std::vector<SystemStatusNavData> mNavData;
|
||||||
|
|
||||||
|
// from SM debug NMEA
|
||||||
|
std::vector<SystemStatusPositionFailure> mPositionFailure;
|
||||||
|
|
||||||
|
// from dataitems observer
|
||||||
|
std::vector<SystemStatusAirplaneMode> mAirplaneMode;
|
||||||
|
std::vector<SystemStatusENH> mENH;
|
||||||
|
std::vector<SystemStatusGpsState> mGPSState;
|
||||||
|
std::vector<SystemStatusNLPStatus> mNLPStatus;
|
||||||
|
std::vector<SystemStatusWifiHardwareState> mWifiHardwareState;
|
||||||
|
std::vector<SystemStatusNetworkInfo> mNetworkInfo;
|
||||||
|
std::vector<SystemStatusServiceInfo> mRilServiceInfo;
|
||||||
|
std::vector<SystemStatusRilCellInfo> mRilCellInfo;
|
||||||
|
std::vector<SystemStatusServiceStatus> mServiceStatus;
|
||||||
|
std::vector<SystemStatusModel> mModel;
|
||||||
|
std::vector<SystemStatusManufacturer> mManufacturer;
|
||||||
|
std::vector<SystemStatusAssistedGps> mAssistedGps;
|
||||||
|
std::vector<SystemStatusScreenState> mScreenState;
|
||||||
|
std::vector<SystemStatusPowerConnectState> mPowerConnectState;
|
||||||
|
std::vector<SystemStatusTimeZoneChange> mTimeZoneChange;
|
||||||
|
std::vector<SystemStatusTimeChange> mTimeChange;
|
||||||
|
std::vector<SystemStatusWifiSupplicantStatus> mWifiSupplicantStatus;
|
||||||
|
std::vector<SystemStatusShutdownState> mShutdownState;
|
||||||
|
std::vector<SystemStatusTac> mTac;
|
||||||
|
std::vector<SystemStatusMccMnc> mMccMnc;
|
||||||
|
std::vector<SystemStatusBtDeviceScanDetail> mBtDeviceScanDetail;
|
||||||
|
std::vector<SystemStatusBtleDeviceScanDetail> mBtLeDeviceScanDetail;
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
SystemStatus
|
||||||
|
******************************************************************************/
|
||||||
|
class SystemStatus
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
static SystemStatus *mInstance;
|
||||||
|
SystemStatusOsObserver mSysStatusObsvr;
|
||||||
|
// ctor
|
||||||
|
SystemStatus(const MsgTask* msgTask);
|
||||||
|
// dtor
|
||||||
|
inline ~SystemStatus() {}
|
||||||
|
|
||||||
|
// Data members
|
||||||
|
static pthread_mutex_t mMutexSystemStatus;
|
||||||
|
SystemStatusReports mCache;
|
||||||
|
bool mConnected;
|
||||||
|
|
||||||
|
template <typename TYPE_SYSTEMSTATUS_ITEM, typename TYPE_REPORT, typename TYPE_ITEMBASE>
|
||||||
|
bool setItemBaseinReport(TYPE_REPORT& report, const TYPE_ITEMBASE& s);
|
||||||
|
|
||||||
|
template <typename TYPE_REPORT, typename TYPE_ITEM>
|
||||||
|
bool setIteminReport(TYPE_REPORT& report, const TYPE_ITEM& s);
|
||||||
|
|
||||||
|
// set default dataitem derived item in report cache
|
||||||
|
template <typename TYPE_REPORT, typename TYPE_ITEM>
|
||||||
|
void setDefaultIteminReport(TYPE_REPORT& report, const TYPE_ITEM& s);
|
||||||
|
|
||||||
|
template <typename TYPE_REPORT, typename TYPE_ITEM>
|
||||||
|
void getIteminReport(TYPE_REPORT& reportout, const TYPE_ITEM& c) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Static methods
|
||||||
|
static SystemStatus* getInstance(const MsgTask* msgTask);
|
||||||
|
static void destroyInstance();
|
||||||
|
IOsObserver* getOsObserver();
|
||||||
|
|
||||||
|
// Helpers
|
||||||
|
bool eventPosition(const UlpLocation& location,const GpsLocationExtended& locationEx);
|
||||||
|
bool eventDataItemNotify(IDataItemCore* dataitem);
|
||||||
|
bool setNmeaString(const char *data, uint32_t len);
|
||||||
|
bool getReport(SystemStatusReports& reports, bool isLatestonly = false) const;
|
||||||
|
bool setDefaultReport(void);
|
||||||
|
bool eventConnectionStatus(bool connected, uint8_t type);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace loc_core
|
||||||
|
|
||||||
|
#endif //__SYSTEM_STATUS__
|
||||||
|
|
595
gps/core/SystemStatusOsObserver.cpp
Normal file
595
gps/core/SystemStatusOsObserver.cpp
Normal file
|
@ -0,0 +1,595 @@
|
||||||
|
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define LOG_TAG "LocSvc_SystemStatusOsObserver"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <SystemStatus.h>
|
||||||
|
#include <SystemStatusOsObserver.h>
|
||||||
|
#include <IDataItemCore.h>
|
||||||
|
#include <IClientIndex.h>
|
||||||
|
#include <IDataItemIndex.h>
|
||||||
|
#include <IndexFactory.h>
|
||||||
|
#include <DataItemsFactoryProxy.h>
|
||||||
|
|
||||||
|
namespace loc_core
|
||||||
|
{
|
||||||
|
SystemStatusOsObserver::SystemStatusOsObserver(
|
||||||
|
SystemStatus* systemstatus, const MsgTask* msgTask) :
|
||||||
|
mSystemStatus(systemstatus),
|
||||||
|
mAddress("SystemStatusOsObserver"),
|
||||||
|
mClientIndex(IndexFactory<IDataItemObserver*, DataItemId> :: createClientIndex()),
|
||||||
|
mDataItemIndex(IndexFactory<IDataItemObserver*, DataItemId> :: createDataItemIndex())
|
||||||
|
{
|
||||||
|
mContext.mMsgTask = msgTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemStatusOsObserver::~SystemStatusOsObserver()
|
||||||
|
{
|
||||||
|
// Close data-item library handle
|
||||||
|
DataItemsFactoryProxy::closeDataItemLibraryHandle();
|
||||||
|
|
||||||
|
// Destroy cache
|
||||||
|
for (auto each : mDataItemCache) {
|
||||||
|
if (nullptr != each.second) {
|
||||||
|
delete each.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mDataItemCache.clear();
|
||||||
|
delete mClientIndex;
|
||||||
|
delete mDataItemIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SystemStatusOsObserver::setSubscriptionObj(IDataItemSubscription* subscriptionObj)
|
||||||
|
{
|
||||||
|
mContext.mSubscriptionObj = subscriptionObj;
|
||||||
|
|
||||||
|
LOC_LOGD("Request cache size - Subscribe:%zu RequestData:%zu",
|
||||||
|
mSubscribeReqCache.size(), mReqDataCache.size());
|
||||||
|
|
||||||
|
// we have received the subscription object. process cached requests
|
||||||
|
// process - subscribe request cache
|
||||||
|
for (auto each : mSubscribeReqCache) {
|
||||||
|
subscribe(each.second, each.first);
|
||||||
|
}
|
||||||
|
// process - requestData request cache
|
||||||
|
for (auto each : mReqDataCache) {
|
||||||
|
requestData(each.second, each.first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper to cache requests subscribe and requestData till subscription obj is obtained
|
||||||
|
void SystemStatusOsObserver::cacheObserverRequest(ObserverReqCache& reqCache,
|
||||||
|
const list<DataItemId>& l, IDataItemObserver* client)
|
||||||
|
{
|
||||||
|
ObserverReqCache::iterator dicIter = reqCache.find(client);
|
||||||
|
if (dicIter != reqCache.end()) {
|
||||||
|
// found
|
||||||
|
list<DataItemId> difference(0);
|
||||||
|
set_difference(l.begin(), l.end(),
|
||||||
|
dicIter->second.begin(), dicIter->second.end(),
|
||||||
|
inserter(difference, difference.begin()));
|
||||||
|
if (!difference.empty()) {
|
||||||
|
difference.sort();
|
||||||
|
dicIter->second.merge(difference);
|
||||||
|
dicIter->second.unique();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// not found
|
||||||
|
reqCache[client] = l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
IDataItemSubscription Overrides
|
||||||
|
******************************************************************************/
|
||||||
|
void SystemStatusOsObserver::subscribe(
|
||||||
|
const list<DataItemId>& l, IDataItemObserver* client)
|
||||||
|
{
|
||||||
|
if (nullptr == mContext.mSubscriptionObj) {
|
||||||
|
LOC_LOGD("%s]: Subscription object is NULL. Caching requests", __func__);
|
||||||
|
cacheObserverRequest(mSubscribeReqCache, l, client);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct HandleSubscribeReq : public LocMsg {
|
||||||
|
HandleSubscribeReq(SystemStatusOsObserver* parent,
|
||||||
|
const list<DataItemId>& l, IDataItemObserver* client) :
|
||||||
|
mParent(parent), mClient(client), mDataItemList(l) {}
|
||||||
|
virtual ~HandleSubscribeReq() {}
|
||||||
|
void proc() const {
|
||||||
|
|
||||||
|
if (mDataItemList.empty()) {
|
||||||
|
LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle First Response
|
||||||
|
list<DataItemId> pendingFirstResponseList(0);
|
||||||
|
mParent->mClientIndex->add(mClient, mDataItemList, pendingFirstResponseList);
|
||||||
|
|
||||||
|
// Do not send first response for only pendingFirstResponseList,
|
||||||
|
// instead send for all the data items (present in the cache) that
|
||||||
|
// have been subscribed for each time.
|
||||||
|
mParent->sendFirstResponse(mDataItemList, mClient);
|
||||||
|
|
||||||
|
list<DataItemId> yetToSubscribeDataItemsList(0);
|
||||||
|
mParent->mDataItemIndex->add(mClient, mDataItemList, yetToSubscribeDataItemsList);
|
||||||
|
|
||||||
|
// Send subscription list to framework
|
||||||
|
if (!yetToSubscribeDataItemsList.empty()) {
|
||||||
|
mParent->mContext.mSubscriptionObj->subscribe(yetToSubscribeDataItemsList, mParent);
|
||||||
|
LOC_LOGD("Subscribe Request sent to framework for the following");
|
||||||
|
mParent->logMe(yetToSubscribeDataItemsList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SystemStatusOsObserver* mParent;
|
||||||
|
IDataItemObserver* mClient;
|
||||||
|
const list<DataItemId> mDataItemList;
|
||||||
|
};
|
||||||
|
mContext.mMsgTask->sendMsg(new (nothrow) HandleSubscribeReq(this, l, client));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SystemStatusOsObserver::updateSubscription(
|
||||||
|
const list<DataItemId>& l, IDataItemObserver* client)
|
||||||
|
{
|
||||||
|
if (nullptr == mContext.mSubscriptionObj) {
|
||||||
|
LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct HandleUpdateSubscriptionReq : public LocMsg {
|
||||||
|
HandleUpdateSubscriptionReq(SystemStatusOsObserver* parent,
|
||||||
|
const list<DataItemId>& l, IDataItemObserver* client) :
|
||||||
|
mParent(parent), mClient(client), mDataItemList(l) {}
|
||||||
|
virtual ~HandleUpdateSubscriptionReq() {}
|
||||||
|
void proc() const {
|
||||||
|
if (mDataItemList.empty()) {
|
||||||
|
LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
list<DataItemId> currentlySubscribedList(0);
|
||||||
|
mParent->mClientIndex->getSubscribedList(mClient, currentlySubscribedList);
|
||||||
|
|
||||||
|
list<DataItemId> removeDataItemList(0);
|
||||||
|
set_difference(currentlySubscribedList.begin(), currentlySubscribedList.end(),
|
||||||
|
mDataItemList.begin(), mDataItemList.end(),
|
||||||
|
inserter(removeDataItemList,removeDataItemList.begin()));
|
||||||
|
|
||||||
|
// Handle First Response
|
||||||
|
list<DataItemId> pendingFirstResponseList(0);
|
||||||
|
mParent->mClientIndex->add(mClient, mDataItemList, pendingFirstResponseList);
|
||||||
|
|
||||||
|
// Send First Response
|
||||||
|
mParent->sendFirstResponse(pendingFirstResponseList, mClient);
|
||||||
|
|
||||||
|
list<DataItemId> yetToSubscribeDataItemsList(0);
|
||||||
|
mParent->mDataItemIndex->add(
|
||||||
|
mClient, mDataItemList, yetToSubscribeDataItemsList);
|
||||||
|
|
||||||
|
// Send subscription list to framework
|
||||||
|
if (!yetToSubscribeDataItemsList.empty()) {
|
||||||
|
mParent->mContext.mSubscriptionObj->subscribe(
|
||||||
|
yetToSubscribeDataItemsList, mParent);
|
||||||
|
LOC_LOGD("Subscribe Request sent to framework for the following");
|
||||||
|
mParent->logMe(yetToSubscribeDataItemsList);
|
||||||
|
}
|
||||||
|
|
||||||
|
list<DataItemId> unsubscribeList(0);
|
||||||
|
list<DataItemId> unused(0);
|
||||||
|
mParent->mClientIndex->remove(mClient, removeDataItemList, unused);
|
||||||
|
|
||||||
|
if (!mParent->mClientIndex->isSubscribedClient(mClient)) {
|
||||||
|
mParent->mDataItemIndex->remove(
|
||||||
|
list<IDataItemObserver*> (1,mClient), unsubscribeList);
|
||||||
|
}
|
||||||
|
if (!unsubscribeList.empty()) {
|
||||||
|
// Send unsubscribe to framework
|
||||||
|
mParent->mContext.mSubscriptionObj->unsubscribe(unsubscribeList, mParent);
|
||||||
|
LOC_LOGD("Unsubscribe Request sent to framework for the following");
|
||||||
|
mParent->logMe(unsubscribeList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SystemStatusOsObserver* mParent;
|
||||||
|
IDataItemObserver* mClient;
|
||||||
|
const list<DataItemId> mDataItemList;
|
||||||
|
};
|
||||||
|
mContext.mMsgTask->sendMsg(new (nothrow) HandleUpdateSubscriptionReq(this, l, client));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SystemStatusOsObserver::requestData(
|
||||||
|
const list<DataItemId>& l, IDataItemObserver* client)
|
||||||
|
{
|
||||||
|
if (nullptr == mContext.mSubscriptionObj) {
|
||||||
|
LOC_LOGD("%s]: Subscription object is NULL. Caching requests", __func__);
|
||||||
|
cacheObserverRequest(mReqDataCache, l, client);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct HandleRequestData : public LocMsg {
|
||||||
|
HandleRequestData(SystemStatusOsObserver* parent,
|
||||||
|
const list<DataItemId>& l, IDataItemObserver* client) :
|
||||||
|
mParent(parent), mClient(client), mDataItemList(l) {}
|
||||||
|
virtual ~HandleRequestData() {}
|
||||||
|
void proc() const {
|
||||||
|
if (mDataItemList.empty()) {
|
||||||
|
LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
list<DataItemId> yetToSubscribeDataItemsList(0);
|
||||||
|
mParent->mClientIndex->add(
|
||||||
|
mClient, mDataItemList, yetToSubscribeDataItemsList);
|
||||||
|
mParent->mDataItemIndex->add(
|
||||||
|
mClient, mDataItemList, yetToSubscribeDataItemsList);
|
||||||
|
|
||||||
|
// Send subscription list to framework
|
||||||
|
if (!mDataItemList.empty()) {
|
||||||
|
mParent->mContext.mSubscriptionObj->requestData(mDataItemList, mParent);
|
||||||
|
LOC_LOGD("Subscribe Request sent to framework for the following");
|
||||||
|
mParent->logMe(yetToSubscribeDataItemsList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SystemStatusOsObserver* mParent;
|
||||||
|
IDataItemObserver* mClient;
|
||||||
|
const list<DataItemId> mDataItemList;
|
||||||
|
};
|
||||||
|
mContext.mMsgTask->sendMsg(new (nothrow) HandleRequestData(this, l, client));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SystemStatusOsObserver::unsubscribe(
|
||||||
|
const list<DataItemId>& l, IDataItemObserver* client)
|
||||||
|
{
|
||||||
|
if (nullptr == mContext.mSubscriptionObj) {
|
||||||
|
LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
struct HandleUnsubscribeReq : public LocMsg {
|
||||||
|
HandleUnsubscribeReq(SystemStatusOsObserver* parent,
|
||||||
|
const list<DataItemId>& l, IDataItemObserver* client) :
|
||||||
|
mParent(parent), mClient(client), mDataItemList(l) {}
|
||||||
|
virtual ~HandleUnsubscribeReq() {}
|
||||||
|
void proc() const {
|
||||||
|
if (mDataItemList.empty()) {
|
||||||
|
LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
list<DataItemId> unsubscribeList(0);
|
||||||
|
list<DataItemId> unused(0);
|
||||||
|
mParent->mClientIndex->remove(mClient, mDataItemList, unused);
|
||||||
|
|
||||||
|
for (auto each : mDataItemList) {
|
||||||
|
list<IDataItemObserver*> clientListSubs(0);
|
||||||
|
list<IDataItemObserver*> clientListOut(0);
|
||||||
|
mParent->mDataItemIndex->remove(
|
||||||
|
each, list<IDataItemObserver*> (1,mClient), clientListOut);
|
||||||
|
// check if there are any other subscribed client for this data item id
|
||||||
|
mParent->mDataItemIndex->getListOfSubscribedClients(each, clientListSubs);
|
||||||
|
if (clientListSubs.empty())
|
||||||
|
{
|
||||||
|
LOC_LOGD("Client list subscribed is empty for dataitem - %d", each);
|
||||||
|
unsubscribeList.push_back(each);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!unsubscribeList.empty()) {
|
||||||
|
// Send unsubscribe to framework
|
||||||
|
mParent->mContext.mSubscriptionObj->unsubscribe(unsubscribeList, mParent);
|
||||||
|
LOC_LOGD("Unsubscribe Request sent to framework for the following data items");
|
||||||
|
mParent->logMe(unsubscribeList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SystemStatusOsObserver* mParent;
|
||||||
|
IDataItemObserver* mClient;
|
||||||
|
const list<DataItemId> mDataItemList;
|
||||||
|
};
|
||||||
|
mContext.mMsgTask->sendMsg(new (nothrow) HandleUnsubscribeReq(this, l, client));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SystemStatusOsObserver::unsubscribeAll(IDataItemObserver* client)
|
||||||
|
{
|
||||||
|
if (nullptr == mContext.mSubscriptionObj) {
|
||||||
|
LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct HandleUnsubscribeAllReq : public LocMsg {
|
||||||
|
HandleUnsubscribeAllReq(SystemStatusOsObserver* parent,
|
||||||
|
IDataItemObserver* client) :
|
||||||
|
mParent(parent), mClient(client) {}
|
||||||
|
virtual ~HandleUnsubscribeAllReq() {}
|
||||||
|
void proc() const {
|
||||||
|
list<IDataItemObserver*> clients(1, mClient);
|
||||||
|
list<DataItemId> unsubscribeList(0);
|
||||||
|
if(0 == mParent->mClientIndex->remove(mClient)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mParent->mDataItemIndex->remove(clients, unsubscribeList);
|
||||||
|
|
||||||
|
if (!unsubscribeList.empty()) {
|
||||||
|
// Send unsubscribe to framework
|
||||||
|
mParent->mContext.mSubscriptionObj->unsubscribe(unsubscribeList, mParent);
|
||||||
|
LOC_LOGD("Unsubscribe Request sent to framework for the following data items");
|
||||||
|
mParent->logMe(unsubscribeList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SystemStatusOsObserver* mParent;
|
||||||
|
IDataItemObserver* mClient;
|
||||||
|
};
|
||||||
|
mContext.mMsgTask->sendMsg(new (nothrow) HandleUnsubscribeAllReq(this, client));
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
IDataItemObserver Overrides
|
||||||
|
******************************************************************************/
|
||||||
|
void SystemStatusOsObserver::notify(const list<IDataItemCore*>& dlist)
|
||||||
|
{
|
||||||
|
list<IDataItemCore*> dataItemList(0);
|
||||||
|
|
||||||
|
for (auto each : dlist) {
|
||||||
|
string dv;
|
||||||
|
each->stringify(dv);
|
||||||
|
LOC_LOGD("notify: DataItem In Value:%s", dv.c_str());
|
||||||
|
|
||||||
|
IDataItemCore* di = DataItemsFactoryProxy::createNewDataItem(each->getId());
|
||||||
|
if (nullptr == di) {
|
||||||
|
LOC_LOGE("Unable to create dataitem:%d", each->getId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy contents into the newly created data item
|
||||||
|
di->copy(each);
|
||||||
|
|
||||||
|
// Request systemstatus to record this dataitem in its cache
|
||||||
|
if (mSystemStatus->eventDataItemNotify(di)) {
|
||||||
|
// add this dataitem if updated from last one
|
||||||
|
dataItemList.push_back(di);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct HandleNotify : public LocMsg {
|
||||||
|
HandleNotify(SystemStatusOsObserver* parent, const list<IDataItemCore*>& l) :
|
||||||
|
mParent(parent), mDList(l) {}
|
||||||
|
virtual ~HandleNotify() {
|
||||||
|
for (auto each : mDList) {
|
||||||
|
delete each;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void proc() const {
|
||||||
|
// Update Cache with received data items and prepare
|
||||||
|
// list of data items to be sent.
|
||||||
|
list<DataItemId> dataItemIdsToBeSent(0);
|
||||||
|
for (auto item : mDList) {
|
||||||
|
bool dataItemUpdated = false;
|
||||||
|
mParent->updateCache(item, dataItemUpdated);
|
||||||
|
if (dataItemUpdated) {
|
||||||
|
dataItemIdsToBeSent.push_back(item->getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send data item to all subscribed clients
|
||||||
|
list<IDataItemObserver*> clientList(0);
|
||||||
|
for (auto each : dataItemIdsToBeSent) {
|
||||||
|
list<IDataItemObserver*> clients(0);
|
||||||
|
mParent->mDataItemIndex->getListOfSubscribedClients(each, clients);
|
||||||
|
for (auto each_cient: clients) {
|
||||||
|
clientList.push_back(each_cient);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clientList.unique();
|
||||||
|
|
||||||
|
for (auto client : clientList) {
|
||||||
|
list<DataItemId> dataItemIdsSubscribedByThisClient(0);
|
||||||
|
list<DataItemId> dataItemIdsToBeSentForThisClient(0);
|
||||||
|
mParent->mClientIndex->getSubscribedList(
|
||||||
|
client, dataItemIdsSubscribedByThisClient);
|
||||||
|
dataItemIdsSubscribedByThisClient.sort();
|
||||||
|
dataItemIdsToBeSent.sort();
|
||||||
|
|
||||||
|
set_intersection(dataItemIdsToBeSent.begin(),
|
||||||
|
dataItemIdsToBeSent.end(),
|
||||||
|
dataItemIdsSubscribedByThisClient.begin(),
|
||||||
|
dataItemIdsSubscribedByThisClient.end(),
|
||||||
|
inserter(dataItemIdsToBeSentForThisClient,
|
||||||
|
dataItemIdsToBeSentForThisClient.begin()));
|
||||||
|
|
||||||
|
mParent->sendCachedDataItems(dataItemIdsToBeSentForThisClient, client);
|
||||||
|
dataItemIdsSubscribedByThisClient.clear();
|
||||||
|
dataItemIdsToBeSentForThisClient.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SystemStatusOsObserver* mParent;
|
||||||
|
const list<IDataItemCore*> mDList;
|
||||||
|
};
|
||||||
|
mContext.mMsgTask->sendMsg(new (nothrow) HandleNotify(this, dataItemList));
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
IFrameworkActionReq Overrides
|
||||||
|
******************************************************************************/
|
||||||
|
void SystemStatusOsObserver::turnOn(DataItemId dit, int timeOut)
|
||||||
|
{
|
||||||
|
if (nullptr == mContext.mFrameworkActionReqObj) {
|
||||||
|
LOC_LOGE("%s:%d]: Framework action request object is NULL", __func__, __LINE__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if data item exists in mActiveRequestCount
|
||||||
|
map<DataItemId, int>::iterator citer = mActiveRequestCount.find(dit);
|
||||||
|
if (citer == mActiveRequestCount.end()) {
|
||||||
|
// Data item not found in map
|
||||||
|
// Add reference count as 1 and add dataitem to map
|
||||||
|
pair<DataItemId, int> cpair(dit, 1);
|
||||||
|
mActiveRequestCount.insert(cpair);
|
||||||
|
LOC_LOGD("Sending turnOn request");
|
||||||
|
|
||||||
|
// Send action turn on to framework
|
||||||
|
struct HandleTurnOnMsg : public LocMsg {
|
||||||
|
HandleTurnOnMsg(IFrameworkActionReq* framework,
|
||||||
|
DataItemId dit, int timeOut) :
|
||||||
|
mFrameworkActionReqObj(framework), mDataItemId(dit), mTimeOut(timeOut) {}
|
||||||
|
virtual ~HandleTurnOnMsg() {}
|
||||||
|
void proc() const {
|
||||||
|
mFrameworkActionReqObj->turnOn(mDataItemId, mTimeOut);
|
||||||
|
}
|
||||||
|
IFrameworkActionReq* mFrameworkActionReqObj;
|
||||||
|
DataItemId mDataItemId;
|
||||||
|
int mTimeOut;
|
||||||
|
};
|
||||||
|
mContext.mMsgTask->sendMsg(new (nothrow) HandleTurnOnMsg(this, dit, timeOut));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Found in map, update reference count
|
||||||
|
citer->second++;
|
||||||
|
LOC_LOGD("turnOn - Data item:%d Num_refs:%d", dit, citer->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SystemStatusOsObserver::turnOff(DataItemId dit)
|
||||||
|
{
|
||||||
|
if (nullptr == mContext.mFrameworkActionReqObj) {
|
||||||
|
LOC_LOGE("%s:%d]: Framework action request object is NULL", __func__, __LINE__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if data item exists in mActiveRequestCount
|
||||||
|
map<DataItemId, int>::iterator citer = mActiveRequestCount.find(dit);
|
||||||
|
if (citer != mActiveRequestCount.end()) {
|
||||||
|
// found
|
||||||
|
citer->second--;
|
||||||
|
LOC_LOGD("turnOff - Data item:%d Remaining:%d", dit, citer->second);
|
||||||
|
if(citer->second == 0) {
|
||||||
|
// if this was last reference, remove item from map and turn off module
|
||||||
|
mActiveRequestCount.erase(citer);
|
||||||
|
|
||||||
|
// Send action turn off to framework
|
||||||
|
struct HandleTurnOffMsg : public LocMsg {
|
||||||
|
HandleTurnOffMsg(IFrameworkActionReq* framework, DataItemId dit) :
|
||||||
|
mFrameworkActionReqObj(framework), mDataItemId(dit) {}
|
||||||
|
virtual ~HandleTurnOffMsg() {}
|
||||||
|
void proc() const {
|
||||||
|
mFrameworkActionReqObj->turnOff(mDataItemId);
|
||||||
|
}
|
||||||
|
IFrameworkActionReq* mFrameworkActionReqObj;
|
||||||
|
DataItemId mDataItemId;
|
||||||
|
};
|
||||||
|
mContext.mMsgTask->sendMsg(
|
||||||
|
new (nothrow) HandleTurnOffMsg(mContext.mFrameworkActionReqObj, dit));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
Helpers
|
||||||
|
******************************************************************************/
|
||||||
|
void SystemStatusOsObserver::sendFirstResponse(
|
||||||
|
const list<DataItemId>& l, IDataItemObserver* to)
|
||||||
|
{
|
||||||
|
if (l.empty()) {
|
||||||
|
LOC_LOGV("list is empty. Nothing to do. Exiting");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string clientName;
|
||||||
|
to->getName(clientName);
|
||||||
|
list<IDataItemCore*> dataItems(0);
|
||||||
|
|
||||||
|
for (auto each : l) {
|
||||||
|
map<DataItemId, IDataItemCore*>::const_iterator citer = mDataItemCache.find(each);
|
||||||
|
if (citer != mDataItemCache.end()) {
|
||||||
|
string dv;
|
||||||
|
citer->second->stringify(dv);
|
||||||
|
LOC_LOGI("DataItem: %s >> %s", dv.c_str(), clientName.c_str());
|
||||||
|
dataItems.push_back(citer->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dataItems.empty()) {
|
||||||
|
LOC_LOGV("No items to notify. Nothing to do. Exiting");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
to->notify(dataItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SystemStatusOsObserver::sendCachedDataItems(
|
||||||
|
const list<DataItemId>& l, IDataItemObserver* to)
|
||||||
|
{
|
||||||
|
string clientName;
|
||||||
|
to->getName(clientName);
|
||||||
|
list<IDataItemCore*> dataItems(0);
|
||||||
|
|
||||||
|
for (auto each : l) {
|
||||||
|
string dv;
|
||||||
|
IDataItemCore* di = mDataItemCache[each];
|
||||||
|
di->stringify(dv);
|
||||||
|
LOC_LOGI("DataItem: %s >> %s", dv.c_str(), clientName.c_str());
|
||||||
|
dataItems.push_back(di);
|
||||||
|
}
|
||||||
|
to->notify(dataItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SystemStatusOsObserver::updateCache(IDataItemCore* d, bool& dataItemUpdated)
|
||||||
|
{
|
||||||
|
if (nullptr == d) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if data item exists in cache
|
||||||
|
map<DataItemId, IDataItemCore*>::iterator citer =
|
||||||
|
mDataItemCache.find(d->getId());
|
||||||
|
if (citer == mDataItemCache.end()) {
|
||||||
|
// New data item; not found in cache
|
||||||
|
IDataItemCore* dataitem = DataItemsFactoryProxy::createNewDataItem(d->getId());
|
||||||
|
if (nullptr == dataitem) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the contents of the data item
|
||||||
|
dataitem->copy(d);
|
||||||
|
pair<DataItemId, IDataItemCore*> cpair(d->getId(), dataitem);
|
||||||
|
// Insert in mDataItemCache
|
||||||
|
mDataItemCache.insert(cpair);
|
||||||
|
dataItemUpdated = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Found in cache; Update cache if necessary
|
||||||
|
if(0 == citer->second->copy(d, &dataItemUpdated)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dataItemUpdated) {
|
||||||
|
LOC_LOGV("DataItem:%d updated:%d", d->getId(), dataItemUpdated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace loc_core
|
||||||
|
|
137
gps/core/SystemStatusOsObserver.h
Normal file
137
gps/core/SystemStatusOsObserver.h
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef __SYSTEM_STATUS_OSOBSERVER__
|
||||||
|
#define __SYSTEM_STATUS_OSOBSERVER__
|
||||||
|
|
||||||
|
#include <cinttypes>
|
||||||
|
#include <string>
|
||||||
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
#include <new>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <MsgTask.h>
|
||||||
|
#include <DataItemId.h>
|
||||||
|
#include <IOsObserver.h>
|
||||||
|
#include <platform_lib_log_util.h>
|
||||||
|
|
||||||
|
namespace loc_core
|
||||||
|
{
|
||||||
|
/******************************************************************************
|
||||||
|
SystemStatusOsObserver
|
||||||
|
******************************************************************************/
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
// Forward Declarations
|
||||||
|
class IDataItemCore;
|
||||||
|
template<typename CT, typename DIT> class IClientIndex;
|
||||||
|
template<typename CT, typename DIT> class IDataItemIndex;
|
||||||
|
|
||||||
|
struct SystemContext {
|
||||||
|
IDataItemSubscription* mSubscriptionObj;
|
||||||
|
IFrameworkActionReq* mFrameworkActionReqObj;
|
||||||
|
const MsgTask* mMsgTask;
|
||||||
|
|
||||||
|
inline SystemContext() :
|
||||||
|
mSubscriptionObj(NULL),
|
||||||
|
mFrameworkActionReqObj(NULL),
|
||||||
|
mMsgTask(NULL) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef map<IDataItemObserver*, list<DataItemId>> ObserverReqCache;
|
||||||
|
|
||||||
|
// Clients wanting to get data from OS/Framework would need to
|
||||||
|
// subscribe with OSObserver using IDataItemSubscription interface.
|
||||||
|
// Such clients would need to implement IDataItemObserver interface
|
||||||
|
// to receive data when it becomes available.
|
||||||
|
class SystemStatus;
|
||||||
|
class SystemStatusOsObserver : public IOsObserver {
|
||||||
|
|
||||||
|
public:
|
||||||
|
// ctor
|
||||||
|
SystemStatusOsObserver(
|
||||||
|
SystemStatus* systemstatus, const MsgTask* msgTask);
|
||||||
|
// dtor
|
||||||
|
~SystemStatusOsObserver();
|
||||||
|
|
||||||
|
// To set the subscription object
|
||||||
|
virtual void setSubscriptionObj(IDataItemSubscription* subscriptionObj);
|
||||||
|
|
||||||
|
// To set the framework action request object
|
||||||
|
inline void setFrameworkActionReqObj(IFrameworkActionReq* frameworkActionReqObj) {
|
||||||
|
mContext.mFrameworkActionReqObj = frameworkActionReqObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
// IDataItemSubscription Overrides
|
||||||
|
virtual void subscribe(const list<DataItemId>& l, IDataItemObserver* client);
|
||||||
|
virtual void updateSubscription(const list<DataItemId>& l, IDataItemObserver* client);
|
||||||
|
virtual void requestData(const list<DataItemId>& l, IDataItemObserver* client);
|
||||||
|
virtual void unsubscribe(const list<DataItemId>& l, IDataItemObserver* client);
|
||||||
|
virtual void unsubscribeAll(IDataItemObserver* client);
|
||||||
|
|
||||||
|
// IDataItemObserver Overrides
|
||||||
|
virtual void notify(const list<IDataItemCore*>& dlist);
|
||||||
|
inline virtual void getName(string& name) {
|
||||||
|
name = mAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
// IFrameworkActionReq Overrides
|
||||||
|
virtual void turnOn(DataItemId dit, int timeOut = 0);
|
||||||
|
virtual void turnOff(DataItemId dit);
|
||||||
|
|
||||||
|
private:
|
||||||
|
SystemStatus* mSystemStatus;
|
||||||
|
SystemContext mContext;
|
||||||
|
const string mAddress;
|
||||||
|
IClientIndex<IDataItemObserver*, DataItemId>* mClientIndex;
|
||||||
|
IDataItemIndex<IDataItemObserver*, DataItemId>* mDataItemIndex;
|
||||||
|
map<DataItemId, IDataItemCore*> mDataItemCache;
|
||||||
|
map<DataItemId, int> mActiveRequestCount;
|
||||||
|
|
||||||
|
// Cache the subscribe and requestData till subscription obj is obtained
|
||||||
|
ObserverReqCache mSubscribeReqCache;
|
||||||
|
ObserverReqCache mReqDataCache;
|
||||||
|
void cacheObserverRequest(ObserverReqCache& reqCache,
|
||||||
|
const list<DataItemId>& l, IDataItemObserver* client);
|
||||||
|
|
||||||
|
// Helpers
|
||||||
|
void sendFirstResponse(const list<DataItemId>& l, IDataItemObserver* to);
|
||||||
|
void sendCachedDataItems(const list<DataItemId>& l, IDataItemObserver* to);
|
||||||
|
void updateCache(IDataItemCore* d, bool& dataItemUpdated);
|
||||||
|
inline void logMe(const list<DataItemId>& l) {
|
||||||
|
for (auto id : l) {
|
||||||
|
LOC_LOGD("DataItem %d", id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace loc_core
|
||||||
|
|
||||||
|
#endif //__SYSTEM_STATUS__
|
||||||
|
|
124
gps/core/UlpProxyBase.h
Normal file
124
gps/core/UlpProxyBase.h
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef ULP_PROXY_BASE_H
|
||||||
|
#define ULP_PROXY_BASE_H
|
||||||
|
|
||||||
|
#include <gps_extended.h>
|
||||||
|
#include <LocationAPI.h>
|
||||||
|
|
||||||
|
namespace loc_core {
|
||||||
|
|
||||||
|
class LocAdapterBase;
|
||||||
|
|
||||||
|
class UlpProxyBase {
|
||||||
|
public:
|
||||||
|
LocPosMode mPosMode;
|
||||||
|
bool mFixSet;
|
||||||
|
inline UlpProxyBase() {
|
||||||
|
mPosMode.mode = LOC_POSITION_MODE_INVALID;
|
||||||
|
mFixSet = false;
|
||||||
|
}
|
||||||
|
inline virtual ~UlpProxyBase() {}
|
||||||
|
inline virtual bool sendStartFix() { mFixSet = true; return false; }
|
||||||
|
inline virtual bool sendStopFix() { mFixSet = false; return false; }
|
||||||
|
inline virtual bool sendFixMode(LocPosMode ¶ms) {
|
||||||
|
mPosMode = params;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline virtual bool reportPosition(const UlpLocation &location,
|
||||||
|
const GpsLocationExtended &locationExtended,
|
||||||
|
enum loc_sess_status status,
|
||||||
|
LocPosTechMask loc_technology_mask) {
|
||||||
|
(void)location;
|
||||||
|
(void)locationExtended;
|
||||||
|
(void)status;
|
||||||
|
(void)loc_technology_mask;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
inline virtual bool reportSv(const GnssSvNotification& svNotify) {
|
||||||
|
(void)svNotify;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
inline virtual bool reportSvMeasurement(GnssSvMeasurementSet &svMeasurementSet) {
|
||||||
|
(void)svMeasurementSet;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline virtual bool reportSvPolynomial(GnssSvPolynomial &svPolynomial)
|
||||||
|
{
|
||||||
|
(void)svPolynomial;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
inline virtual bool reportStatus(LocGpsStatusValue status) {
|
||||||
|
|
||||||
|
(void)status;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
inline virtual void setAdapter(LocAdapterBase* adapter) {
|
||||||
|
|
||||||
|
(void)adapter;
|
||||||
|
}
|
||||||
|
inline virtual void setCapabilities(unsigned long capabilities) {
|
||||||
|
|
||||||
|
(void)capabilities;
|
||||||
|
}
|
||||||
|
inline virtual bool reportBatchingSession(const LocationOptions& options, bool active)
|
||||||
|
{
|
||||||
|
(void)options;
|
||||||
|
(void)active;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
inline virtual bool reportPositions(const UlpLocation* ulpLocations,
|
||||||
|
const GpsLocationExtended* extendedLocations,
|
||||||
|
const uint32_t* techMasks,
|
||||||
|
const size_t count)
|
||||||
|
{
|
||||||
|
(void)ulpLocations;
|
||||||
|
(void)extendedLocations;
|
||||||
|
(void)techMasks;
|
||||||
|
(void)count;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
inline virtual bool reportDeleteAidingData(LocGpsAidingData aidingData)
|
||||||
|
{
|
||||||
|
(void)aidingData;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
inline virtual bool reportNmea(const char* nmea, int length)
|
||||||
|
{
|
||||||
|
(void)nmea;
|
||||||
|
(void)length;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace loc_core
|
||||||
|
|
||||||
|
#endif // ULP_PROXY_BASE_H
|
461
gps/core/data-items/DataItemConcreteTypesBase.h
Normal file
461
gps/core/data-items/DataItemConcreteTypesBase.h
Normal file
|
@ -0,0 +1,461 @@
|
||||||
|
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DATAITEMCONCRETEBASETYPES__
|
||||||
|
#define __DATAITEMCONCRETEBASETYPES__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <cstring>
|
||||||
|
#include <DataItemId.h>
|
||||||
|
#include <IDataItemCore.h>
|
||||||
|
|
||||||
|
#define MAC_ADDRESS_LENGTH 6
|
||||||
|
// MAC address length in bytes
|
||||||
|
// QMI_LOC_SRN_MAC_ADDR_LENGTH_V02
|
||||||
|
#define SRN_MAC_ADDRESS_LENGTH 6
|
||||||
|
#define WIFI_SUPPLICANT_DEFAULT_STATE 0
|
||||||
|
|
||||||
|
namespace loc_core
|
||||||
|
{
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
class AirplaneModeDataItemBase : public IDataItemCore {
|
||||||
|
public:
|
||||||
|
AirplaneModeDataItemBase(bool mode):
|
||||||
|
mMode(mode),
|
||||||
|
mId(AIRPLANEMODE_DATA_ITEM_ID) {}
|
||||||
|
virtual ~AirplaneModeDataItemBase() {}
|
||||||
|
inline virtual DataItemId getId() { return mId; }
|
||||||
|
virtual void stringify(string& /*valueStr*/) {}
|
||||||
|
virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
|
||||||
|
// Data members
|
||||||
|
bool mMode;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
DataItemId mId;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ENHDataItemBase : public IDataItemCore {
|
||||||
|
public:
|
||||||
|
ENHDataItemBase(bool enabled) :
|
||||||
|
mEnabled(enabled),
|
||||||
|
mId(ENH_DATA_ITEM_ID) {}
|
||||||
|
virtual ~ENHDataItemBase() {}
|
||||||
|
inline virtual DataItemId getId() { return mId; }
|
||||||
|
virtual void stringify(string& /*valueStr*/) {}
|
||||||
|
virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
|
||||||
|
// Data members
|
||||||
|
bool mEnabled;
|
||||||
|
protected:
|
||||||
|
DataItemId mId;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GPSStateDataItemBase : public IDataItemCore {
|
||||||
|
public:
|
||||||
|
GPSStateDataItemBase(bool enabled) :
|
||||||
|
mEnabled(enabled),
|
||||||
|
mId(GPSSTATE_DATA_ITEM_ID) {}
|
||||||
|
virtual ~GPSStateDataItemBase() {}
|
||||||
|
inline virtual DataItemId getId() { return mId; }
|
||||||
|
virtual void stringify(string& /*valueStr*/) {}
|
||||||
|
virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
|
||||||
|
// Data members
|
||||||
|
bool mEnabled;
|
||||||
|
protected:
|
||||||
|
DataItemId mId;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NLPStatusDataItemBase : public IDataItemCore {
|
||||||
|
public:
|
||||||
|
NLPStatusDataItemBase(bool enabled) :
|
||||||
|
mEnabled(enabled),
|
||||||
|
mId(NLPSTATUS_DATA_ITEM_ID) {}
|
||||||
|
virtual ~NLPStatusDataItemBase() {}
|
||||||
|
inline virtual DataItemId getId() { return mId; }
|
||||||
|
virtual void stringify(string& /*valueStr*/) {}
|
||||||
|
virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
|
||||||
|
// Data members
|
||||||
|
bool mEnabled;
|
||||||
|
protected:
|
||||||
|
DataItemId mId;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WifiHardwareStateDataItemBase : public IDataItemCore {
|
||||||
|
public:
|
||||||
|
WifiHardwareStateDataItemBase(bool enabled) :
|
||||||
|
mEnabled(enabled),
|
||||||
|
mId(WIFIHARDWARESTATE_DATA_ITEM_ID) {}
|
||||||
|
virtual ~WifiHardwareStateDataItemBase() {}
|
||||||
|
inline virtual DataItemId getId() { return mId; }
|
||||||
|
virtual void stringify(string& /*valueStr*/) {}
|
||||||
|
virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
|
||||||
|
// Data members
|
||||||
|
bool mEnabled;
|
||||||
|
protected:
|
||||||
|
DataItemId mId;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ScreenStateDataItemBase : public IDataItemCore {
|
||||||
|
public:
|
||||||
|
ScreenStateDataItemBase(bool state) :
|
||||||
|
mState(state),
|
||||||
|
mId(SCREEN_STATE_DATA_ITEM_ID) {}
|
||||||
|
virtual ~ScreenStateDataItemBase() {}
|
||||||
|
inline virtual DataItemId getId() { return mId; }
|
||||||
|
virtual void stringify(string& /*valueStr*/) {}
|
||||||
|
virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
|
||||||
|
// Data members
|
||||||
|
bool mState;
|
||||||
|
protected:
|
||||||
|
DataItemId mId;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PowerConnectStateDataItemBase : public IDataItemCore {
|
||||||
|
public:
|
||||||
|
PowerConnectStateDataItemBase(bool state) :
|
||||||
|
mState(state),
|
||||||
|
mId(POWER_CONNECTED_STATE_DATA_ITEM_ID) {}
|
||||||
|
virtual ~PowerConnectStateDataItemBase() {}
|
||||||
|
inline virtual DataItemId getId() { return mId; }
|
||||||
|
virtual void stringify(string& /*valueStr*/) {}
|
||||||
|
virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
|
||||||
|
// Data members
|
||||||
|
bool mState;
|
||||||
|
protected:
|
||||||
|
DataItemId mId;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TimeZoneChangeDataItemBase : public IDataItemCore {
|
||||||
|
public:
|
||||||
|
TimeZoneChangeDataItemBase(int64_t currTimeMillis, int32_t rawOffset, int32_t dstOffset) :
|
||||||
|
mCurrTimeMillis (currTimeMillis),
|
||||||
|
mRawOffsetTZ (rawOffset),
|
||||||
|
mDstOffsetTZ (dstOffset),
|
||||||
|
mId(TIMEZONE_CHANGE_DATA_ITEM_ID) {}
|
||||||
|
virtual ~TimeZoneChangeDataItemBase() {}
|
||||||
|
inline virtual DataItemId getId() { return mId; }
|
||||||
|
virtual void stringify(string& /*valueStr*/) {}
|
||||||
|
virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
|
||||||
|
// Data members
|
||||||
|
int64_t mCurrTimeMillis;
|
||||||
|
int32_t mRawOffsetTZ;
|
||||||
|
int32_t mDstOffsetTZ;
|
||||||
|
protected:
|
||||||
|
DataItemId mId;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TimeChangeDataItemBase : public IDataItemCore {
|
||||||
|
public:
|
||||||
|
TimeChangeDataItemBase(int64_t currTimeMillis, int32_t rawOffset, int32_t dstOffset) :
|
||||||
|
mCurrTimeMillis (currTimeMillis),
|
||||||
|
mRawOffsetTZ (rawOffset),
|
||||||
|
mDstOffsetTZ (dstOffset),
|
||||||
|
mId(TIME_CHANGE_DATA_ITEM_ID) {}
|
||||||
|
virtual ~TimeChangeDataItemBase() {}
|
||||||
|
inline virtual DataItemId getId() { return mId; }
|
||||||
|
virtual void stringify(string& /*valueStr*/) {}
|
||||||
|
virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
|
||||||
|
// Data members
|
||||||
|
int64_t mCurrTimeMillis;
|
||||||
|
int32_t mRawOffsetTZ;
|
||||||
|
int32_t mDstOffsetTZ;
|
||||||
|
protected:
|
||||||
|
DataItemId mId;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ShutdownStateDataItemBase : public IDataItemCore {
|
||||||
|
public:
|
||||||
|
ShutdownStateDataItemBase(bool state) :
|
||||||
|
mState (state),
|
||||||
|
mId(SHUTDOWN_STATE_DATA_ITEM_ID) {}
|
||||||
|
virtual ~ShutdownStateDataItemBase() {}
|
||||||
|
inline virtual DataItemId getId() { return mId; }
|
||||||
|
virtual void stringify(string& /*valueStr*/) {}
|
||||||
|
virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
|
||||||
|
// Data members
|
||||||
|
bool mState;
|
||||||
|
protected:
|
||||||
|
DataItemId mId;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AssistedGpsDataItemBase : public IDataItemCore {
|
||||||
|
public:
|
||||||
|
AssistedGpsDataItemBase(bool enabled) :
|
||||||
|
mEnabled(enabled),
|
||||||
|
mId(ASSISTED_GPS_DATA_ITEM_ID) {}
|
||||||
|
virtual ~AssistedGpsDataItemBase() {}
|
||||||
|
inline virtual DataItemId getId() { return mId; }
|
||||||
|
virtual void stringify(string& /*valueStr*/) {}
|
||||||
|
virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
|
||||||
|
// Data members
|
||||||
|
bool mEnabled;
|
||||||
|
protected:
|
||||||
|
DataItemId mId;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NetworkInfoDataItemBase : public IDataItemCore {
|
||||||
|
public:
|
||||||
|
NetworkInfoDataItemBase(
|
||||||
|
int32_t type, string typeName, string subTypeName,
|
||||||
|
bool available, bool connected, bool roaming ):
|
||||||
|
mType(type),
|
||||||
|
mTypeName(typeName),
|
||||||
|
mSubTypeName(subTypeName),
|
||||||
|
mAvailable(available),
|
||||||
|
mConnected(connected),
|
||||||
|
mRoaming(roaming),
|
||||||
|
mId(NETWORKINFO_DATA_ITEM_ID) {}
|
||||||
|
virtual ~NetworkInfoDataItemBase() {}
|
||||||
|
inline virtual DataItemId getId() { return mId; }
|
||||||
|
virtual void stringify(string& /*valueStr*/) {}
|
||||||
|
virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
|
||||||
|
enum NetworkType {
|
||||||
|
TYPE_UNKNOWN,
|
||||||
|
TYPE_MOBILE,
|
||||||
|
TYPE_WIFI,
|
||||||
|
TYPE_ETHERNET,
|
||||||
|
TYPE_BLUETOOTH,
|
||||||
|
TYPE_MMS,
|
||||||
|
TYPE_SUPL,
|
||||||
|
TYPE_DUN,
|
||||||
|
TYPE_HIPRI,
|
||||||
|
TYPE_WIMAX
|
||||||
|
};
|
||||||
|
inline virtual NetworkType getType(void) const {
|
||||||
|
return (NetworkType)mType;
|
||||||
|
}
|
||||||
|
// Data members
|
||||||
|
int32_t mType;
|
||||||
|
string mTypeName;
|
||||||
|
string mSubTypeName;
|
||||||
|
bool mAvailable;
|
||||||
|
bool mConnected;
|
||||||
|
bool mRoaming;
|
||||||
|
protected:
|
||||||
|
DataItemId mId;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class ServiceStatusDataItemBase : public IDataItemCore {
|
||||||
|
public:
|
||||||
|
ServiceStatusDataItemBase(int32_t serviceState) :
|
||||||
|
mServiceState (serviceState),
|
||||||
|
mId(SERVICESTATUS_DATA_ITEM_ID) {}
|
||||||
|
virtual ~ServiceStatusDataItemBase() {}
|
||||||
|
inline virtual DataItemId getId() { return mId; }
|
||||||
|
virtual void stringify(string& /*valueStr*/) {}
|
||||||
|
virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
|
||||||
|
// Data members
|
||||||
|
int32_t mServiceState;
|
||||||
|
protected:
|
||||||
|
DataItemId mId;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ModelDataItemBase : public IDataItemCore {
|
||||||
|
public:
|
||||||
|
ModelDataItemBase(const string & name) :
|
||||||
|
mModel (name),
|
||||||
|
mId(MODEL_DATA_ITEM_ID) {}
|
||||||
|
virtual ~ModelDataItemBase() {}
|
||||||
|
inline virtual DataItemId getId() { return mId; }
|
||||||
|
virtual void stringify(string& /*valueStr*/) {}
|
||||||
|
virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
|
||||||
|
// Data members
|
||||||
|
string mModel;
|
||||||
|
protected:
|
||||||
|
DataItemId mId;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ManufacturerDataItemBase : public IDataItemCore {
|
||||||
|
public:
|
||||||
|
ManufacturerDataItemBase(const string & name) :
|
||||||
|
mManufacturer (name),
|
||||||
|
mId(MANUFACTURER_DATA_ITEM_ID) {}
|
||||||
|
virtual ~ManufacturerDataItemBase() {}
|
||||||
|
inline virtual DataItemId getId() { return mId; }
|
||||||
|
virtual void stringify(string& /*valueStr*/) {}
|
||||||
|
virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
|
||||||
|
// Data members
|
||||||
|
string mManufacturer;
|
||||||
|
protected:
|
||||||
|
DataItemId mId;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RilServiceInfoDataItemBase : public IDataItemCore {
|
||||||
|
public:
|
||||||
|
RilServiceInfoDataItemBase() :
|
||||||
|
mId(RILSERVICEINFO_DATA_ITEM_ID) {}
|
||||||
|
virtual ~RilServiceInfoDataItemBase() {}
|
||||||
|
inline virtual DataItemId getId() { return mId; }
|
||||||
|
virtual void stringify(string& /*valueStr*/) {}
|
||||||
|
virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
|
||||||
|
protected:
|
||||||
|
DataItemId mId;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RilCellInfoDataItemBase : public IDataItemCore {
|
||||||
|
public:
|
||||||
|
RilCellInfoDataItemBase() :
|
||||||
|
mId(RILCELLINFO_DATA_ITEM_ID) {}
|
||||||
|
virtual ~RilCellInfoDataItemBase() {}
|
||||||
|
inline virtual DataItemId getId() { return mId; }
|
||||||
|
virtual void stringify(string& /*valueStr*/) {}
|
||||||
|
virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
|
||||||
|
protected:
|
||||||
|
DataItemId mId;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WifiSupplicantStatusDataItemBase : public IDataItemCore {
|
||||||
|
public:
|
||||||
|
WifiSupplicantStatusDataItemBase() :
|
||||||
|
mState((WifiSupplicantState)WIFI_SUPPLICANT_DEFAULT_STATE),
|
||||||
|
mApMacAddressValid(false),
|
||||||
|
mWifiApSsidValid(false),
|
||||||
|
mId(WIFI_SUPPLICANT_STATUS_DATA_ITEM_ID) {
|
||||||
|
memset (&mApMacAddress, 0, sizeof (mApMacAddress));
|
||||||
|
mWifiApSsid.clear();
|
||||||
|
}
|
||||||
|
virtual ~WifiSupplicantStatusDataItemBase() {}
|
||||||
|
inline virtual DataItemId getId() { return mId; }
|
||||||
|
virtual void stringify(string& /*valueStr*/) {}
|
||||||
|
virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
|
||||||
|
// Data members
|
||||||
|
typedef enum WifiSupplicantState {
|
||||||
|
DISCONNECTED,
|
||||||
|
INTERFACE_DISABLED,
|
||||||
|
INACTIVE,
|
||||||
|
SCANNING,
|
||||||
|
AUTHENTICATING,
|
||||||
|
ASSOCIATING,
|
||||||
|
ASSOCIATED,
|
||||||
|
FOUR_WAY_HANDSHAKE,
|
||||||
|
GROUP_HANDSHAKE,
|
||||||
|
COMPLETED,
|
||||||
|
DORMANT,
|
||||||
|
UNINITIALIZED,
|
||||||
|
INVALID
|
||||||
|
} WifiSupplicantState;
|
||||||
|
/* Represents whether access point attach state*/
|
||||||
|
WifiSupplicantState mState;
|
||||||
|
/* Represents info on whether ap mac address is valid */
|
||||||
|
bool mApMacAddressValid;
|
||||||
|
/* Represents mac address of the wifi access point*/
|
||||||
|
uint8_t mApMacAddress[MAC_ADDRESS_LENGTH];
|
||||||
|
/* Represents info on whether ap SSID is valid */
|
||||||
|
bool mWifiApSsidValid;
|
||||||
|
/* Represents Wifi SSID string*/
|
||||||
|
string mWifiApSsid;
|
||||||
|
protected:
|
||||||
|
DataItemId mId;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TacDataItemBase : public IDataItemCore {
|
||||||
|
public:
|
||||||
|
TacDataItemBase(const string & name) :
|
||||||
|
mValue (name),
|
||||||
|
mId(TAC_DATA_ITEM_ID) {}
|
||||||
|
virtual ~TacDataItemBase() {}
|
||||||
|
inline virtual DataItemId getId() { return mId; }
|
||||||
|
virtual void stringify(string& /*valueStr*/) {}
|
||||||
|
virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
|
||||||
|
// Data members
|
||||||
|
string mValue;
|
||||||
|
protected:
|
||||||
|
DataItemId mId;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MccmncDataItemBase : public IDataItemCore {
|
||||||
|
public:
|
||||||
|
MccmncDataItemBase(const string & name) :
|
||||||
|
mValue (name),
|
||||||
|
mId(MCCMNC_DATA_ITEM_ID) {}
|
||||||
|
virtual ~MccmncDataItemBase() {}
|
||||||
|
inline virtual DataItemId getId() { return mId; }
|
||||||
|
virtual void stringify(string& /*valueStr*/) {}
|
||||||
|
virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
|
||||||
|
// Data members
|
||||||
|
string mValue;
|
||||||
|
protected:
|
||||||
|
DataItemId mId;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SrnDeviceScanDetailsDataItemBase : public IDataItemCore {
|
||||||
|
public:
|
||||||
|
SrnDeviceScanDetailsDataItemBase (DataItemId Id) :
|
||||||
|
mValidSrnData(false),
|
||||||
|
mApSrnRssi(-1),
|
||||||
|
mApSrnTimestamp(0),
|
||||||
|
mRequestTimestamp(0),
|
||||||
|
mReceiveTimestamp(0),
|
||||||
|
mErrorCause(-1),
|
||||||
|
mId(Id) {}
|
||||||
|
virtual ~SrnDeviceScanDetailsDataItemBase () {}
|
||||||
|
inline virtual DataItemId getId() { return mId; }
|
||||||
|
// Data members common to all SRN tech types
|
||||||
|
/* Represents info on whether SRN data is valid (no error)*/
|
||||||
|
bool mValidSrnData;
|
||||||
|
/* SRN device RSSI reported */
|
||||||
|
int32_t mApSrnRssi;
|
||||||
|
/* MAC adress of SRN device */
|
||||||
|
uint8_t mApSrnMacAddress[SRN_MAC_ADDRESS_LENGTH];
|
||||||
|
/* UTC timestamp at which the scan was requested.for this SRN device*/
|
||||||
|
int64_t mApSrnTimestamp;
|
||||||
|
/* UTC timestamp at which the scan was started. */
|
||||||
|
int64_t mRequestTimestamp;
|
||||||
|
/* UTC timestamp at which the scan was received.*/
|
||||||
|
int64_t mReceiveTimestamp;
|
||||||
|
/* Reason for the error/failure if SRN details are not valid */
|
||||||
|
int32_t mErrorCause;
|
||||||
|
protected:
|
||||||
|
DataItemId mId;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BtDeviceScanDetailsDataItemBase : public SrnDeviceScanDetailsDataItemBase {
|
||||||
|
|
||||||
|
public:
|
||||||
|
BtDeviceScanDetailsDataItemBase() :
|
||||||
|
SrnDeviceScanDetailsDataItemBase(BT_SCAN_DATA_ITEM_ID) {}
|
||||||
|
virtual ~BtDeviceScanDetailsDataItemBase() {}
|
||||||
|
virtual void stringify(string& /*valueStr*/) {}
|
||||||
|
virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
|
||||||
|
};
|
||||||
|
|
||||||
|
class BtLeDeviceScanDetailsDataItemBase : public SrnDeviceScanDetailsDataItemBase {
|
||||||
|
|
||||||
|
public:
|
||||||
|
BtLeDeviceScanDetailsDataItemBase() :
|
||||||
|
SrnDeviceScanDetailsDataItemBase(BTLE_SCAN_DATA_ITEM_ID) {}
|
||||||
|
virtual ~BtLeDeviceScanDetailsDataItemBase() {}
|
||||||
|
virtual void stringify(string& /*valueStr*/) {}
|
||||||
|
virtual int32_t copy(IDataItemCore* /*src*/, bool* /*dataItemCopied = NULL*/) {return 1;}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace loc_core
|
||||||
|
|
||||||
|
#endif //__DATAITEMCONCRETEBASETYPES__
|
73
gps/core/data-items/DataItemId.h
Normal file
73
gps/core/data-items/DataItemId.h
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
/* Copyright (c) 2015-2017 The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DATAITEMID_H__
|
||||||
|
#define __DATAITEMID_H__
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enumeration of Data Item types
|
||||||
|
* When add/remove/update changes are made to Data Items, this file needs to be updated
|
||||||
|
* accordingly
|
||||||
|
*/
|
||||||
|
typedef enum e_DataItemId {
|
||||||
|
INVALID_DATA_ITEM_ID = -1,
|
||||||
|
// 0 - 4
|
||||||
|
AIRPLANEMODE_DATA_ITEM_ID,
|
||||||
|
ENH_DATA_ITEM_ID,
|
||||||
|
GPSSTATE_DATA_ITEM_ID,
|
||||||
|
NLPSTATUS_DATA_ITEM_ID,
|
||||||
|
WIFIHARDWARESTATE_DATA_ITEM_ID,
|
||||||
|
// 5 - 9
|
||||||
|
NETWORKINFO_DATA_ITEM_ID,
|
||||||
|
RILVERSION_DATA_ITEM_ID,
|
||||||
|
RILSERVICEINFO_DATA_ITEM_ID,
|
||||||
|
RILCELLINFO_DATA_ITEM_ID,
|
||||||
|
SERVICESTATUS_DATA_ITEM_ID,
|
||||||
|
// 10 - 14
|
||||||
|
MODEL_DATA_ITEM_ID,
|
||||||
|
MANUFACTURER_DATA_ITEM_ID,
|
||||||
|
VOICECALL_DATA_ITEM,
|
||||||
|
ASSISTED_GPS_DATA_ITEM_ID,
|
||||||
|
SCREEN_STATE_DATA_ITEM_ID,
|
||||||
|
// 15 - 19
|
||||||
|
POWER_CONNECTED_STATE_DATA_ITEM_ID,
|
||||||
|
TIMEZONE_CHANGE_DATA_ITEM_ID,
|
||||||
|
TIME_CHANGE_DATA_ITEM_ID,
|
||||||
|
WIFI_SUPPLICANT_STATUS_DATA_ITEM_ID,
|
||||||
|
SHUTDOWN_STATE_DATA_ITEM_ID,
|
||||||
|
// 20 - 24
|
||||||
|
TAC_DATA_ITEM_ID,
|
||||||
|
MCCMNC_DATA_ITEM_ID,
|
||||||
|
BTLE_SCAN_DATA_ITEM_ID,
|
||||||
|
BT_SCAN_DATA_ITEM_ID,
|
||||||
|
OEM_GTP_UPLOAD_TRIGGER_READY_ITEM_ID,
|
||||||
|
MAX_DATA_ITEM_ID
|
||||||
|
} DataItemId;
|
||||||
|
|
||||||
|
#endif // #ifndef __DATAITEMID_H__
|
99
gps/core/data-items/DataItemsFactoryProxy.cpp
Normal file
99
gps/core/data-items/DataItemsFactoryProxy.cpp
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define LOG_TAG "DataItemsFactoryProxy"
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <DataItemId.h>
|
||||||
|
#include <IDataItemCore.h>
|
||||||
|
#include <DataItemsFactoryProxy.h>
|
||||||
|
#include <platform_lib_log_util.h>
|
||||||
|
|
||||||
|
namespace loc_core
|
||||||
|
{
|
||||||
|
void* DataItemsFactoryProxy::dataItemLibHandle = NULL;
|
||||||
|
get_concrete_data_item_fn* DataItemsFactoryProxy::getConcreteDIFunc = NULL;
|
||||||
|
|
||||||
|
IDataItemCore* DataItemsFactoryProxy::createNewDataItem(DataItemId id)
|
||||||
|
{
|
||||||
|
IDataItemCore *mydi = nullptr;
|
||||||
|
|
||||||
|
if (NULL != getConcreteDIFunc) {
|
||||||
|
mydi = (*getConcreteDIFunc)(id);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// first call to this function, symbol not yet loaded
|
||||||
|
if (NULL == dataItemLibHandle) {
|
||||||
|
LOC_LOGD("Loaded library %s",DATA_ITEMS_LIB_NAME);
|
||||||
|
dataItemLibHandle = dlopen(DATA_ITEMS_LIB_NAME, RTLD_NOW);
|
||||||
|
if (NULL == dataItemLibHandle) {
|
||||||
|
// dlopen failed.
|
||||||
|
const char * err = dlerror();
|
||||||
|
if (NULL == err)
|
||||||
|
{
|
||||||
|
err = "Unknown";
|
||||||
|
}
|
||||||
|
LOC_LOGE("%s:%d]: failed to load library %s; error=%s",
|
||||||
|
__func__, __LINE__, DATA_ITEMS_LIB_NAME, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// load sym - if dlopen handle is obtained and symbol is not yet obtained
|
||||||
|
if (NULL != dataItemLibHandle) {
|
||||||
|
getConcreteDIFunc = (get_concrete_data_item_fn * )
|
||||||
|
dlsym(dataItemLibHandle, DATA_ITEMS_GET_CONCRETE_DI);
|
||||||
|
if (NULL != getConcreteDIFunc) {
|
||||||
|
LOC_LOGD("Loaded function %s : %x",DATA_ITEMS_GET_CONCRETE_DI,getConcreteDIFunc);
|
||||||
|
mydi = (*getConcreteDIFunc)(id);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// dlysm failed.
|
||||||
|
const char * err = dlerror();
|
||||||
|
if (NULL == err)
|
||||||
|
{
|
||||||
|
err = "Unknown";
|
||||||
|
}
|
||||||
|
LOC_LOGE("%s:%d]: failed to find symbol %s; error=%s",
|
||||||
|
__func__, __LINE__, DATA_ITEMS_GET_CONCRETE_DI, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mydi;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataItemsFactoryProxy::closeDataItemLibraryHandle()
|
||||||
|
{
|
||||||
|
if (NULL != dataItemLibHandle) {
|
||||||
|
dlclose(dataItemLibHandle);
|
||||||
|
dataItemLibHandle = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace loc_core
|
||||||
|
|
||||||
|
|
55
gps/core/data-items/DataItemsFactoryProxy.h
Normal file
55
gps/core/data-items/DataItemsFactoryProxy.h
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DATAITEMFACTORYBASE__
|
||||||
|
#define __DATAITEMFACTORYBASE__
|
||||||
|
|
||||||
|
#include <DataItemId.h>
|
||||||
|
#include <IDataItemCore.h>
|
||||||
|
|
||||||
|
namespace loc_core
|
||||||
|
{
|
||||||
|
|
||||||
|
#define DATA_ITEMS_LIB_NAME "libdataitems.so"
|
||||||
|
#define DATA_ITEMS_GET_CONCRETE_DI "getConcreteDataItem"
|
||||||
|
|
||||||
|
typedef IDataItemCore * (get_concrete_data_item_fn)(DataItemId);
|
||||||
|
|
||||||
|
class DataItemsFactoryProxy {
|
||||||
|
public:
|
||||||
|
static IDataItemCore* createNewDataItem(DataItemId id);
|
||||||
|
static void closeDataItemLibraryHandle();
|
||||||
|
static void *dataItemLibHandle;
|
||||||
|
static get_concrete_data_item_fn *getConcreteDIFunc;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace loc_core
|
||||||
|
|
||||||
|
#endif //__DATAITEMFACTORYBASE__
|
||||||
|
|
82
gps/core/data-items/IDataItemCore.h
Normal file
82
gps/core/data-items/IDataItemCore.h
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __IDATAITEMCORE_H__
|
||||||
|
#define __IDATAITEMCORE_H__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <DataItemId.h>
|
||||||
|
|
||||||
|
namespace loc_core {
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief IDataItemCore interface.
|
||||||
|
* @details IDataItemCore interface.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class IDataItemCore {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Gets Data item id.
|
||||||
|
* @details Gets Data item id.
|
||||||
|
* @return Data item id.
|
||||||
|
*/
|
||||||
|
virtual DataItemId getId () = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stringify.
|
||||||
|
* @details Stringify.
|
||||||
|
*
|
||||||
|
* @param valueStr Reference to string.
|
||||||
|
*/
|
||||||
|
virtual void stringify (string & valueStr) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief copy.
|
||||||
|
* @details copy.
|
||||||
|
*
|
||||||
|
* @param src Where to copy from.
|
||||||
|
* @param dataItemCopied Boolean flag indicated whether or not copied.
|
||||||
|
*
|
||||||
|
* @return Zero for success or non zero for failure.
|
||||||
|
*/
|
||||||
|
virtual int32_t copy (IDataItemCore * src, bool *dataItemCopied = nullptr) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destructor.
|
||||||
|
* @details Destructor.
|
||||||
|
*/
|
||||||
|
virtual ~IDataItemCore () {}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace loc_core
|
||||||
|
|
||||||
|
#endif // __IDATAITEMCORE_H__
|
171
gps/core/data-items/common/ClientIndex.cpp
Normal file
171
gps/core/data-items/common/ClientIndex.cpp
Normal file
|
@ -0,0 +1,171 @@
|
||||||
|
/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iterator>
|
||||||
|
#include <string>
|
||||||
|
#include <platform_lib_log_util.h>
|
||||||
|
#include <ClientIndex.h>
|
||||||
|
#include <IDataItemObserver.h>
|
||||||
|
#include <DataItemId.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace loc_core;
|
||||||
|
|
||||||
|
template <typename CT, typename DIT>
|
||||||
|
inline ClientIndex <CT,DIT> :: ClientIndex () {}
|
||||||
|
|
||||||
|
template <typename CT, typename DIT>
|
||||||
|
inline ClientIndex <CT,DIT> :: ~ClientIndex () {}
|
||||||
|
|
||||||
|
template <typename CT, typename DIT>
|
||||||
|
bool ClientIndex <CT,DIT> :: isSubscribedClient (CT client) {
|
||||||
|
bool result = false;
|
||||||
|
ENTRY_LOG ();
|
||||||
|
typename map < CT, list <DIT> > :: iterator it =
|
||||||
|
mDataItemsPerClientMap.find (client);
|
||||||
|
if (it != mDataItemsPerClientMap.end ()) {
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
EXIT_LOG_WITH_ERROR ("%d",result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename CT, typename DIT>
|
||||||
|
void ClientIndex <CT,DIT> :: getSubscribedList (CT client, list <DIT> & out) {
|
||||||
|
ENTRY_LOG ();
|
||||||
|
typename map < CT, list <DIT> > :: iterator it =
|
||||||
|
mDataItemsPerClientMap.find (client);
|
||||||
|
if (it != mDataItemsPerClientMap.end ()) {
|
||||||
|
out = it->second;
|
||||||
|
}
|
||||||
|
EXIT_LOG_WITH_ERROR ("%d",0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename CT, typename DIT>
|
||||||
|
int ClientIndex <CT,DIT> :: remove (CT client) {
|
||||||
|
int result = 0;
|
||||||
|
ENTRY_LOG ();
|
||||||
|
mDataItemsPerClientMap.erase (client);
|
||||||
|
EXIT_LOG_WITH_ERROR ("%d",result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename CT, typename DIT>
|
||||||
|
void ClientIndex <CT,DIT> :: remove (const list <DIT> & r, list <CT> & out) {
|
||||||
|
ENTRY_LOG ();
|
||||||
|
typename map < CT, list <DIT> > :: iterator dicIter =
|
||||||
|
mDataItemsPerClientMap.begin ();
|
||||||
|
while (dicIter != mDataItemsPerClientMap.end()) {
|
||||||
|
typename list <DIT> :: const_iterator it = r.begin ();
|
||||||
|
for (; it != r.end (); ++it) {
|
||||||
|
typename list <DIT> :: iterator iter =
|
||||||
|
find (dicIter->second.begin (), dicIter->second.end (), *it);
|
||||||
|
if (iter != dicIter->second.end ()) {
|
||||||
|
dicIter->second.erase (iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dicIter->second.empty ()) {
|
||||||
|
out.push_back (dicIter->first);
|
||||||
|
// Post-increment operator increases the iterator but returns the
|
||||||
|
// prevous one that will be invalidated by erase()
|
||||||
|
mDataItemsPerClientMap.erase (dicIter++);
|
||||||
|
} else {
|
||||||
|
++dicIter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EXIT_LOG_WITH_ERROR ("%d",0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename CT, typename DIT>
|
||||||
|
void ClientIndex <CT,DIT> :: remove
|
||||||
|
(
|
||||||
|
CT client,
|
||||||
|
const list <DIT> & r,
|
||||||
|
list <DIT> & out
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ENTRY_LOG ();
|
||||||
|
typename map < CT, list <DIT> > :: iterator dicIter =
|
||||||
|
mDataItemsPerClientMap.find (client);
|
||||||
|
if (dicIter != mDataItemsPerClientMap.end ()) {
|
||||||
|
set_intersection (dicIter->second.begin (), dicIter->second.end (),
|
||||||
|
r.begin (), r.end (),
|
||||||
|
inserter (out,out.begin ()));
|
||||||
|
if (!out.empty ()) {
|
||||||
|
typename list <DIT> :: iterator it = out.begin ();
|
||||||
|
for (; it != out.end (); ++it) {
|
||||||
|
dicIter->second.erase (find (dicIter->second.begin (),
|
||||||
|
dicIter->second.end (),
|
||||||
|
*it));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dicIter->second.empty ()) {
|
||||||
|
mDataItemsPerClientMap.erase (dicIter);
|
||||||
|
EXIT_LOG_WITH_ERROR ("%d",0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EXIT_LOG_WITH_ERROR ("%d",0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename CT, typename DIT>
|
||||||
|
void ClientIndex <CT,DIT> :: add
|
||||||
|
(
|
||||||
|
CT client,
|
||||||
|
const list <DIT> & l,
|
||||||
|
list <DIT> & out
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ENTRY_LOG ();
|
||||||
|
list <DIT> difference;
|
||||||
|
typename map < CT, list <DIT> > :: iterator dicIter =
|
||||||
|
mDataItemsPerClientMap.find (client);
|
||||||
|
if (dicIter != mDataItemsPerClientMap.end ()) {
|
||||||
|
set_difference (l.begin (), l.end (),
|
||||||
|
dicIter->second.begin (), dicIter->second.end (),
|
||||||
|
inserter (difference,difference.begin ()));
|
||||||
|
if (!difference.empty ()) {
|
||||||
|
difference.sort ();
|
||||||
|
out = difference;
|
||||||
|
dicIter->second.merge (difference);
|
||||||
|
dicIter->second.unique ();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out = l;
|
||||||
|
pair < CT, list <DIT> > dicnpair (client, out);
|
||||||
|
mDataItemsPerClientMap.insert (dicnpair);
|
||||||
|
}
|
||||||
|
EXIT_LOG_WITH_ERROR ("%d",0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Explicit instantiation must occur in same namespace where class is defined
|
||||||
|
namespace loc_core
|
||||||
|
{
|
||||||
|
template class ClientIndex <IDataItemObserver *, DataItemId>;
|
||||||
|
template class ClientIndex <string, DataItemId>;
|
||||||
|
}
|
70
gps/core/data-items/common/ClientIndex.h
Normal file
70
gps/core/data-items/common/ClientIndex.h
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef __CLIENTINDEX_H__
|
||||||
|
#define __CLIENTINDEX_H__
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
#include <IClientIndex.h>
|
||||||
|
|
||||||
|
using loc_core::IClientIndex;
|
||||||
|
|
||||||
|
namespace loc_core
|
||||||
|
{
|
||||||
|
|
||||||
|
template <typename CT, typename DIT>
|
||||||
|
|
||||||
|
class ClientIndex : public IClientIndex <CT, DIT> {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ClientIndex ();
|
||||||
|
|
||||||
|
~ClientIndex ();
|
||||||
|
|
||||||
|
bool isSubscribedClient (CT client);
|
||||||
|
|
||||||
|
void getSubscribedList (CT client, std :: list <DIT> & out);
|
||||||
|
|
||||||
|
int remove (CT client);
|
||||||
|
|
||||||
|
void remove (const std :: list <DIT> & r, std :: list <CT> & out);
|
||||||
|
|
||||||
|
void remove (CT client, const std :: list <DIT> & r, std :: list <DIT> & out);
|
||||||
|
|
||||||
|
void add (CT client, const std :: list <DIT> & l, std :: list <DIT> & out);
|
||||||
|
|
||||||
|
private:
|
||||||
|
//Data members
|
||||||
|
std :: map < CT , std :: list <DIT> > mDataItemsPerClientMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace loc_core
|
||||||
|
|
||||||
|
#endif // #ifndef __CLIENTINDEX_H__
|
202
gps/core/data-items/common/DataItemIndex.cpp
Normal file
202
gps/core/data-items/common/DataItemIndex.cpp
Normal file
|
@ -0,0 +1,202 @@
|
||||||
|
/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iterator>
|
||||||
|
#include <DataItemIndex.h>
|
||||||
|
#include <platform_lib_log_util.h>
|
||||||
|
#include <IDataItemObserver.h>
|
||||||
|
#include <DataItemId.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace loc_core;
|
||||||
|
|
||||||
|
template <typename CT, typename DIT>
|
||||||
|
inline DataItemIndex <CT,DIT> :: DataItemIndex () {}
|
||||||
|
|
||||||
|
template <typename CT, typename DIT>
|
||||||
|
inline DataItemIndex <CT,DIT> :: ~DataItemIndex () {}
|
||||||
|
|
||||||
|
template <typename CT, typename DIT>
|
||||||
|
void DataItemIndex <CT,DIT> :: getListOfSubscribedClients
|
||||||
|
(
|
||||||
|
DIT id,
|
||||||
|
list <CT> & out
|
||||||
|
)
|
||||||
|
{
|
||||||
|
typename map < DIT, list <CT> > :: iterator cdiIter =
|
||||||
|
mClientsPerDataItemMap.find (id);
|
||||||
|
if (cdiIter != mClientsPerDataItemMap.end ()) {
|
||||||
|
out = cdiIter->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename CT, typename DIT>
|
||||||
|
int DataItemIndex <CT,DIT> :: remove (DIT id) {
|
||||||
|
int result = 0;
|
||||||
|
ENTRY_LOG ();
|
||||||
|
mClientsPerDataItemMap.erase (id);
|
||||||
|
EXIT_LOG_WITH_ERROR ("%d",result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename CT, typename DIT>
|
||||||
|
void DataItemIndex <CT,DIT> :: remove (const list <CT> & r, list <DIT> & out) {
|
||||||
|
ENTRY_LOG ();
|
||||||
|
typename map < DIT, list <CT> > :: iterator cdiIter =
|
||||||
|
mClientsPerDataItemMap.begin ();
|
||||||
|
while (cdiIter != mClientsPerDataItemMap.end()) {
|
||||||
|
typename list <CT> :: const_iterator it = r.begin ();
|
||||||
|
for (; it != r.end (); ++it) {
|
||||||
|
typename list <CT> :: iterator iter =
|
||||||
|
find
|
||||||
|
(
|
||||||
|
cdiIter->second.begin (),
|
||||||
|
cdiIter->second.end (),
|
||||||
|
*it
|
||||||
|
);
|
||||||
|
if (iter != cdiIter->second.end ()) {
|
||||||
|
cdiIter->second.erase (iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cdiIter->second.empty ()) {
|
||||||
|
out.push_back (cdiIter->first);
|
||||||
|
// Post-increment operator increases the iterator but returns the
|
||||||
|
// prevous one that will be invalidated by erase()
|
||||||
|
mClientsPerDataItemMap.erase (cdiIter++);
|
||||||
|
} else {
|
||||||
|
++cdiIter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EXIT_LOG_WITH_ERROR ("%d",0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename CT, typename DIT>
|
||||||
|
void DataItemIndex <CT,DIT> :: remove
|
||||||
|
(
|
||||||
|
DIT id,
|
||||||
|
const list <CT> & r,
|
||||||
|
list <CT> & out
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ENTRY_LOG ();
|
||||||
|
|
||||||
|
typename map < DIT, list <CT> > :: iterator cdiIter =
|
||||||
|
mClientsPerDataItemMap.find (id);
|
||||||
|
if (cdiIter != mClientsPerDataItemMap.end ()) {
|
||||||
|
set_intersection (cdiIter->second.begin (), cdiIter->second.end (),
|
||||||
|
r.begin (), r.end (),
|
||||||
|
inserter (out, out.begin ()));
|
||||||
|
if (!out.empty ()) {
|
||||||
|
typename list <CT> :: iterator it = out.begin ();
|
||||||
|
for (; it != out.end (); ++it) {
|
||||||
|
cdiIter->second.erase (find (cdiIter->second.begin (),
|
||||||
|
cdiIter->second.end (),
|
||||||
|
*it));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cdiIter->second.empty ()) {
|
||||||
|
mClientsPerDataItemMap.erase (cdiIter);
|
||||||
|
EXIT_LOG_WITH_ERROR ("%d",0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EXIT_LOG_WITH_ERROR ("%d",0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename CT, typename DIT>
|
||||||
|
void DataItemIndex <CT,DIT> :: add
|
||||||
|
(
|
||||||
|
DIT id,
|
||||||
|
const list <CT> & l,
|
||||||
|
list <CT> & out
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ENTRY_LOG ();
|
||||||
|
list <CT> difference;
|
||||||
|
typename map < DIT, list <CT> > :: iterator cdiIter =
|
||||||
|
mClientsPerDataItemMap.find (id);
|
||||||
|
if (cdiIter != mClientsPerDataItemMap.end ()) {
|
||||||
|
set_difference (l.begin (), l.end (),
|
||||||
|
cdiIter->second.begin (), cdiIter->second.end (),
|
||||||
|
inserter (difference, difference.begin ()));
|
||||||
|
if (!difference.empty ()) {
|
||||||
|
difference.sort ();
|
||||||
|
out = difference;
|
||||||
|
cdiIter->second.merge (difference);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out = l;
|
||||||
|
pair < DIT, list <CT> > cndipair (id, out);
|
||||||
|
mClientsPerDataItemMap.insert (cndipair);
|
||||||
|
}
|
||||||
|
EXIT_LOG_WITH_ERROR ("%d",0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename CT, typename DIT>
|
||||||
|
void DataItemIndex <CT,DIT> :: add
|
||||||
|
(
|
||||||
|
CT client,
|
||||||
|
const list <DIT> & l,
|
||||||
|
list <DIT> & out
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ENTRY_LOG ();
|
||||||
|
typename map < DIT, list <CT> > :: iterator cdiIter;
|
||||||
|
typename list <DIT> :: const_iterator it = l.begin ();
|
||||||
|
for (; it != l.end (); ++it) {
|
||||||
|
cdiIter = mClientsPerDataItemMap.find (*it);
|
||||||
|
if (cdiIter == mClientsPerDataItemMap.end ()) {
|
||||||
|
out.push_back (*it);
|
||||||
|
pair < DIT, list <CT> > cndiPair (*it, list <CT> (1, client));
|
||||||
|
mClientsPerDataItemMap.insert (cndiPair);
|
||||||
|
} else {
|
||||||
|
typename list<CT> :: iterator clientIter =
|
||||||
|
find
|
||||||
|
(
|
||||||
|
cdiIter->second.begin (),
|
||||||
|
cdiIter->second.end (),
|
||||||
|
client
|
||||||
|
);
|
||||||
|
if (clientIter == cdiIter->second.end()) {
|
||||||
|
cdiIter->second.push_back (client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EXIT_LOG_WITH_ERROR ("%d",0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Explicit instantiation must occur in same namespace where class is defined
|
||||||
|
namespace loc_core
|
||||||
|
{
|
||||||
|
template class DataItemIndex <IDataItemObserver *, DataItemId>;
|
||||||
|
template class DataItemIndex <string, DataItemId>;
|
||||||
|
}
|
70
gps/core/data-items/common/DataItemIndex.h
Normal file
70
gps/core/data-items/common/DataItemIndex.h
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DATAITEMINDEX_H__
|
||||||
|
#define __DATAITEMINDEX_H__
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
#include <IDataItemIndex.h>
|
||||||
|
|
||||||
|
using loc_core::IDataItemIndex;
|
||||||
|
|
||||||
|
namespace loc_core
|
||||||
|
{
|
||||||
|
|
||||||
|
template <typename CT, typename DIT>
|
||||||
|
|
||||||
|
class DataItemIndex : public IDataItemIndex <CT, DIT> {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
DataItemIndex ();
|
||||||
|
|
||||||
|
~DataItemIndex ();
|
||||||
|
|
||||||
|
void getListOfSubscribedClients (DIT id, std :: list <CT> & out);
|
||||||
|
|
||||||
|
int remove (DIT id);
|
||||||
|
|
||||||
|
void remove (const std :: list <CT> & r, std :: list <DIT> & out);
|
||||||
|
|
||||||
|
void remove (DIT id, const std :: list <CT> & r, std :: list <CT> & out);
|
||||||
|
|
||||||
|
void add (DIT id, const std :: list <CT> & l, std :: list <CT> & out);
|
||||||
|
|
||||||
|
void add (CT client, const std :: list <DIT> & l, std :: list <DIT> & out);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std :: map < DIT, std :: list <CT> > mClientsPerDataItemMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace loc_core
|
||||||
|
|
||||||
|
#endif // #ifndef __DATAITEMINDEX_H__
|
83
gps/core/data-items/common/IClientIndex.h
Normal file
83
gps/core/data-items/common/IClientIndex.h
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ICLIENTINDEX_H__
|
||||||
|
#define __ICLIENTINDEX_H__
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
namespace loc_core
|
||||||
|
{
|
||||||
|
|
||||||
|
template <typename CT, typename DIT>
|
||||||
|
|
||||||
|
class IClientIndex {
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Checks if client is subscribed
|
||||||
|
virtual bool isSubscribedClient (CT client) = 0;
|
||||||
|
|
||||||
|
// gets subscription list
|
||||||
|
virtual void getSubscribedList (CT client, std :: list <DIT> & out) = 0;
|
||||||
|
|
||||||
|
// removes an entry
|
||||||
|
virtual int remove (CT client) = 0;
|
||||||
|
|
||||||
|
// removes std :: list of data items and returns a list of clients
|
||||||
|
// removed if any.
|
||||||
|
virtual void remove
|
||||||
|
(
|
||||||
|
const std :: list <DIT> & r,
|
||||||
|
std :: list <CT> & out
|
||||||
|
) = 0;
|
||||||
|
|
||||||
|
// removes list of data items indexed by client and returns list
|
||||||
|
// of data items removed if any.
|
||||||
|
virtual void remove
|
||||||
|
(
|
||||||
|
CT client,
|
||||||
|
const std :: list <DIT> & r,
|
||||||
|
std :: list <DIT> & out
|
||||||
|
) = 0;
|
||||||
|
|
||||||
|
// adds/modifies entry in map and returns new data items added.
|
||||||
|
virtual void add
|
||||||
|
(
|
||||||
|
CT client,
|
||||||
|
const std :: list <DIT> & l,
|
||||||
|
std :: list <DIT> & out
|
||||||
|
) = 0;
|
||||||
|
|
||||||
|
// dtor
|
||||||
|
virtual ~IClientIndex () {}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace loc_core
|
||||||
|
|
||||||
|
#endif // #ifndef __ICLIENTINDEX_H__
|
94
gps/core/data-items/common/IDataItemIndex.h
Normal file
94
gps/core/data-items/common/IDataItemIndex.h
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __IDATAITEMINDEX_H__
|
||||||
|
#define __IDATAITEMINDEX_H__
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
namespace loc_core
|
||||||
|
{
|
||||||
|
|
||||||
|
template <typename CT, typename DIT>
|
||||||
|
|
||||||
|
class IDataItemIndex {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// gets std :: list of subscribed clients
|
||||||
|
virtual void getListOfSubscribedClients
|
||||||
|
(
|
||||||
|
DIT id,
|
||||||
|
std :: list <CT> & out
|
||||||
|
) = 0;
|
||||||
|
|
||||||
|
// removes an entry from
|
||||||
|
virtual int remove (DIT id) = 0;
|
||||||
|
|
||||||
|
// removes list of clients and returns a list of data items
|
||||||
|
// removed if any.
|
||||||
|
virtual void remove
|
||||||
|
(
|
||||||
|
const std :: list <CT> & r,
|
||||||
|
std :: list <DIT> & out
|
||||||
|
) = 0;
|
||||||
|
|
||||||
|
// removes list of clients indexed by data item and returns list of
|
||||||
|
// clients removed if any.
|
||||||
|
virtual void remove
|
||||||
|
(
|
||||||
|
DIT id,
|
||||||
|
const std :: list <CT> & r,
|
||||||
|
std :: list <CT> & out
|
||||||
|
) = 0;
|
||||||
|
|
||||||
|
// adds/modifies entry and returns new clients added
|
||||||
|
virtual void add
|
||||||
|
(
|
||||||
|
DIT id,
|
||||||
|
const std :: list <CT> & l,
|
||||||
|
std :: list <CT> & out
|
||||||
|
) = 0;
|
||||||
|
|
||||||
|
// adds/modifies entry and returns yet to subscribe list of data items
|
||||||
|
virtual void add
|
||||||
|
(
|
||||||
|
CT client,
|
||||||
|
const std :: list <DIT> & l,
|
||||||
|
std :: list <DIT> & out
|
||||||
|
) = 0;
|
||||||
|
|
||||||
|
// dtor
|
||||||
|
virtual ~IDataItemIndex () {}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace loc_core
|
||||||
|
|
||||||
|
#endif // #ifndef __IDATAITEMINDEX_H__
|
||||||
|
|
64
gps/core/data-items/common/IndexFactory.cpp
Normal file
64
gps/core/data-items/common/IndexFactory.cpp
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <IndexFactory.h>
|
||||||
|
#include <IClientIndex.h>
|
||||||
|
#include <ClientIndex.h>
|
||||||
|
#include <IDataItemIndex.h>
|
||||||
|
#include <DataItemIndex.h>
|
||||||
|
#include <IDataItemObserver.h>
|
||||||
|
#include <DataItemId.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using loc_core::IClientIndex;
|
||||||
|
using loc_core::IDataItemIndex;
|
||||||
|
using loc_core::IDataItemObserver;
|
||||||
|
using namespace loc_core;
|
||||||
|
|
||||||
|
template <typename CT, typename DIT>
|
||||||
|
inline IClientIndex <CT, DIT> * IndexFactory <CT, DIT> :: createClientIndex
|
||||||
|
()
|
||||||
|
{
|
||||||
|
return new (nothrow) ClientIndex <CT, DIT> ();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename CT, typename DIT>
|
||||||
|
inline IDataItemIndex <CT, DIT> * IndexFactory <CT, DIT> :: createDataItemIndex
|
||||||
|
()
|
||||||
|
{
|
||||||
|
return new (nothrow) DataItemIndex <CT, DIT> ();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Explicit instantiation must occur in same namespace where class is defined
|
||||||
|
namespace loc_core
|
||||||
|
{
|
||||||
|
template class IndexFactory <IDataItemObserver *, DataItemId>;
|
||||||
|
template class IndexFactory <string, DataItemId>;
|
||||||
|
}
|
48
gps/core/data-items/common/IndexFactory.h
Normal file
48
gps/core/data-items/common/IndexFactory.h
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __INDEXFACTORY_H__
|
||||||
|
#define __INDEXFACTORY_H__
|
||||||
|
|
||||||
|
#include <IClientIndex.h>
|
||||||
|
#include <IDataItemIndex.h>
|
||||||
|
|
||||||
|
namespace loc_core
|
||||||
|
{
|
||||||
|
template <typename CT, typename DIT>
|
||||||
|
class IndexFactory {
|
||||||
|
|
||||||
|
public:
|
||||||
|
static IClientIndex <CT, DIT> * createClientIndex ();
|
||||||
|
static IDataItemIndex <CT, DIT> * createDataItemIndex ();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace loc_core
|
||||||
|
|
||||||
|
#endif // #ifndef __INDEXFACTORY_H__
|
243
gps/core/loc_core_log.cpp
Normal file
243
gps/core/loc_core_log.cpp
Normal file
|
@ -0,0 +1,243 @@
|
||||||
|
/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LOG_NDEBUG 0
|
||||||
|
#define LOG_TAG "LocSvc_core_log"
|
||||||
|
|
||||||
|
#include <loc_log.h>
|
||||||
|
#include <loc_core_log.h>
|
||||||
|
#include <platform_lib_includes.h>
|
||||||
|
|
||||||
|
void LocPosMode::logv() const
|
||||||
|
{
|
||||||
|
LOC_LOGV ("Position mode: %s\n Position recurrence: %s\n "
|
||||||
|
"min interval: %d\n preferred accuracy: %d\n "
|
||||||
|
"preferred time: %d\n credentials: %s provider: %s",
|
||||||
|
loc_get_position_mode_name(mode),
|
||||||
|
loc_get_position_recurrence_name(recurrence),
|
||||||
|
min_interval,
|
||||||
|
preferred_accuracy,
|
||||||
|
preferred_time,
|
||||||
|
credentials,
|
||||||
|
provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* GPS status names */
|
||||||
|
static const loc_name_val_s_type gps_status_name[] =
|
||||||
|
{
|
||||||
|
NAME_VAL( LOC_GPS_STATUS_NONE ),
|
||||||
|
NAME_VAL( LOC_GPS_STATUS_SESSION_BEGIN ),
|
||||||
|
NAME_VAL( LOC_GPS_STATUS_SESSION_END ),
|
||||||
|
NAME_VAL( LOC_GPS_STATUS_ENGINE_ON ),
|
||||||
|
NAME_VAL( LOC_GPS_STATUS_ENGINE_OFF ),
|
||||||
|
};
|
||||||
|
static const int gps_status_num = sizeof(gps_status_name) / sizeof(loc_name_val_s_type);
|
||||||
|
|
||||||
|
/* Find Android GPS status name */
|
||||||
|
const char* loc_get_gps_status_name(LocGpsStatusValue gps_status)
|
||||||
|
{
|
||||||
|
return loc_get_name_from_val(gps_status_name, gps_status_num,
|
||||||
|
(long) gps_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static const loc_name_val_s_type loc_eng_position_modes[] =
|
||||||
|
{
|
||||||
|
NAME_VAL( LOC_POSITION_MODE_STANDALONE ),
|
||||||
|
NAME_VAL( LOC_POSITION_MODE_MS_BASED ),
|
||||||
|
NAME_VAL( LOC_POSITION_MODE_MS_ASSISTED ),
|
||||||
|
NAME_VAL( LOC_POSITION_MODE_RESERVED_1 ),
|
||||||
|
NAME_VAL( LOC_POSITION_MODE_RESERVED_2 ),
|
||||||
|
NAME_VAL( LOC_POSITION_MODE_RESERVED_3 ),
|
||||||
|
NAME_VAL( LOC_POSITION_MODE_RESERVED_4 ),
|
||||||
|
NAME_VAL( LOC_POSITION_MODE_RESERVED_5 )
|
||||||
|
};
|
||||||
|
static const int loc_eng_position_mode_num = sizeof(loc_eng_position_modes) / sizeof(loc_name_val_s_type);
|
||||||
|
|
||||||
|
const char* loc_get_position_mode_name(LocGpsPositionMode mode)
|
||||||
|
{
|
||||||
|
return loc_get_name_from_val(loc_eng_position_modes, loc_eng_position_mode_num, (long) mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static const loc_name_val_s_type loc_eng_position_recurrences[] =
|
||||||
|
{
|
||||||
|
NAME_VAL( LOC_GPS_POSITION_RECURRENCE_PERIODIC ),
|
||||||
|
NAME_VAL( LOC_GPS_POSITION_RECURRENCE_SINGLE )
|
||||||
|
};
|
||||||
|
static const int loc_eng_position_recurrence_num = sizeof(loc_eng_position_recurrences) / sizeof(loc_name_val_s_type);
|
||||||
|
|
||||||
|
const char* loc_get_position_recurrence_name(LocGpsPositionRecurrence recur)
|
||||||
|
{
|
||||||
|
return loc_get_name_from_val(loc_eng_position_recurrences, loc_eng_position_recurrence_num, (long) recur);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static const loc_name_val_s_type loc_eng_aiding_data_bits[] =
|
||||||
|
{
|
||||||
|
NAME_VAL( LOC_GPS_DELETE_EPHEMERIS ),
|
||||||
|
NAME_VAL( LOC_GPS_DELETE_ALMANAC ),
|
||||||
|
NAME_VAL( LOC_GPS_DELETE_POSITION ),
|
||||||
|
NAME_VAL( LOC_GPS_DELETE_TIME ),
|
||||||
|
NAME_VAL( LOC_GPS_DELETE_IONO ),
|
||||||
|
NAME_VAL( LOC_GPS_DELETE_UTC ),
|
||||||
|
NAME_VAL( LOC_GPS_DELETE_HEALTH ),
|
||||||
|
NAME_VAL( LOC_GPS_DELETE_SVDIR ),
|
||||||
|
NAME_VAL( LOC_GPS_DELETE_SVSTEER ),
|
||||||
|
NAME_VAL( LOC_GPS_DELETE_SADATA ),
|
||||||
|
NAME_VAL( LOC_GPS_DELETE_RTI ),
|
||||||
|
NAME_VAL( LOC_GPS_DELETE_CELLDB_INFO ),
|
||||||
|
NAME_VAL( LOC_GPS_DELETE_ALL)
|
||||||
|
};
|
||||||
|
static const int loc_eng_aiding_data_bit_num = sizeof(loc_eng_aiding_data_bits) / sizeof(loc_name_val_s_type);
|
||||||
|
|
||||||
|
const char* loc_get_aiding_data_mask_names(LocGpsAidingData /*data*/)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const loc_name_val_s_type loc_eng_agps_types[] =
|
||||||
|
{
|
||||||
|
NAME_VAL( LOC_AGPS_TYPE_INVALID ),
|
||||||
|
NAME_VAL( LOC_AGPS_TYPE_ANY ),
|
||||||
|
NAME_VAL( LOC_AGPS_TYPE_SUPL ),
|
||||||
|
NAME_VAL( LOC_AGPS_TYPE_C2K ),
|
||||||
|
NAME_VAL( LOC_AGPS_TYPE_WWAN_ANY )
|
||||||
|
};
|
||||||
|
static const int loc_eng_agps_type_num = sizeof(loc_eng_agps_types) / sizeof(loc_name_val_s_type);
|
||||||
|
|
||||||
|
const char* loc_get_agps_type_name(LocAGpsType type)
|
||||||
|
{
|
||||||
|
return loc_get_name_from_val(loc_eng_agps_types, loc_eng_agps_type_num, (long) type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const loc_name_val_s_type loc_eng_ni_types[] =
|
||||||
|
{
|
||||||
|
NAME_VAL( LOC_GPS_NI_TYPE_VOICE ),
|
||||||
|
NAME_VAL( LOC_GPS_NI_TYPE_UMTS_SUPL ),
|
||||||
|
NAME_VAL( LOC_GPS_NI_TYPE_UMTS_CTRL_PLANE ),
|
||||||
|
NAME_VAL( LOC_GPS_NI_TYPE_EMERGENCY_SUPL )
|
||||||
|
};
|
||||||
|
static const int loc_eng_ni_type_num = sizeof(loc_eng_ni_types) / sizeof(loc_name_val_s_type);
|
||||||
|
|
||||||
|
const char* loc_get_ni_type_name(LocGpsNiType type)
|
||||||
|
{
|
||||||
|
return loc_get_name_from_val(loc_eng_ni_types, loc_eng_ni_type_num, (long) type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const loc_name_val_s_type loc_eng_ni_responses[] =
|
||||||
|
{
|
||||||
|
NAME_VAL( LOC_GPS_NI_RESPONSE_ACCEPT ),
|
||||||
|
NAME_VAL( LOC_GPS_NI_RESPONSE_DENY ),
|
||||||
|
NAME_VAL( LOC_GPS_NI_RESPONSE_DENY )
|
||||||
|
};
|
||||||
|
static const int loc_eng_ni_reponse_num = sizeof(loc_eng_ni_responses) / sizeof(loc_name_val_s_type);
|
||||||
|
|
||||||
|
const char* loc_get_ni_response_name(LocGpsUserResponseType response)
|
||||||
|
{
|
||||||
|
return loc_get_name_from_val(loc_eng_ni_responses, loc_eng_ni_reponse_num, (long) response);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const loc_name_val_s_type loc_eng_ni_encodings[] =
|
||||||
|
{
|
||||||
|
NAME_VAL( LOC_GPS_ENC_NONE ),
|
||||||
|
NAME_VAL( LOC_GPS_ENC_SUPL_GSM_DEFAULT ),
|
||||||
|
NAME_VAL( LOC_GPS_ENC_SUPL_UTF8 ),
|
||||||
|
NAME_VAL( LOC_GPS_ENC_SUPL_UCS2 ),
|
||||||
|
NAME_VAL( LOC_GPS_ENC_UNKNOWN )
|
||||||
|
};
|
||||||
|
static const int loc_eng_ni_encoding_num = sizeof(loc_eng_ni_encodings) / sizeof(loc_name_val_s_type);
|
||||||
|
|
||||||
|
const char* loc_get_ni_encoding_name(LocGpsNiEncodingType encoding)
|
||||||
|
{
|
||||||
|
return loc_get_name_from_val(loc_eng_ni_encodings, loc_eng_ni_encoding_num, (long) encoding);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const loc_name_val_s_type loc_eng_agps_bears[] =
|
||||||
|
{
|
||||||
|
NAME_VAL( AGPS_APN_BEARER_INVALID ),
|
||||||
|
NAME_VAL( AGPS_APN_BEARER_IPV4 ),
|
||||||
|
NAME_VAL( AGPS_APN_BEARER_IPV6 ),
|
||||||
|
NAME_VAL( AGPS_APN_BEARER_IPV4V6 )
|
||||||
|
};
|
||||||
|
static const int loc_eng_agps_bears_num = sizeof(loc_eng_agps_bears) / sizeof(loc_name_val_s_type);
|
||||||
|
|
||||||
|
const char* loc_get_agps_bear_name(AGpsBearerType bearer)
|
||||||
|
{
|
||||||
|
return loc_get_name_from_val(loc_eng_agps_bears, loc_eng_agps_bears_num, (long) bearer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const loc_name_val_s_type loc_eng_server_types[] =
|
||||||
|
{
|
||||||
|
NAME_VAL( LOC_AGPS_CDMA_PDE_SERVER ),
|
||||||
|
NAME_VAL( LOC_AGPS_CUSTOM_PDE_SERVER ),
|
||||||
|
NAME_VAL( LOC_AGPS_MPC_SERVER ),
|
||||||
|
NAME_VAL( LOC_AGPS_SUPL_SERVER )
|
||||||
|
};
|
||||||
|
static const int loc_eng_server_types_num = sizeof(loc_eng_server_types) / sizeof(loc_name_val_s_type);
|
||||||
|
|
||||||
|
const char* loc_get_server_type_name(LocServerType type)
|
||||||
|
{
|
||||||
|
return loc_get_name_from_val(loc_eng_server_types, loc_eng_server_types_num, (long) type);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const loc_name_val_s_type loc_eng_position_sess_status_types[] =
|
||||||
|
{
|
||||||
|
NAME_VAL( LOC_SESS_SUCCESS ),
|
||||||
|
NAME_VAL( LOC_SESS_INTERMEDIATE ),
|
||||||
|
NAME_VAL( LOC_SESS_FAILURE )
|
||||||
|
};
|
||||||
|
static const int loc_eng_position_sess_status_num = sizeof(loc_eng_position_sess_status_types) / sizeof(loc_name_val_s_type);
|
||||||
|
|
||||||
|
const char* loc_get_position_sess_status_name(enum loc_sess_status status)
|
||||||
|
{
|
||||||
|
return loc_get_name_from_val(loc_eng_position_sess_status_types, loc_eng_position_sess_status_num, (long) status);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const loc_name_val_s_type loc_eng_agps_status_names[] =
|
||||||
|
{
|
||||||
|
NAME_VAL( LOC_GPS_REQUEST_AGPS_DATA_CONN ),
|
||||||
|
NAME_VAL( LOC_GPS_RELEASE_AGPS_DATA_CONN ),
|
||||||
|
NAME_VAL( LOC_GPS_AGPS_DATA_CONNECTED ),
|
||||||
|
NAME_VAL( LOC_GPS_AGPS_DATA_CONN_DONE ),
|
||||||
|
NAME_VAL( LOC_GPS_AGPS_DATA_CONN_FAILED )
|
||||||
|
};
|
||||||
|
static const int loc_eng_agps_status_num = sizeof(loc_eng_agps_status_names) / sizeof(loc_name_val_s_type);
|
||||||
|
|
||||||
|
const char* loc_get_agps_status_name(LocAGpsStatusValue status)
|
||||||
|
{
|
||||||
|
return loc_get_name_from_val(loc_eng_agps_status_names, loc_eng_agps_status_num, (long) status);
|
||||||
|
}
|
58
gps/core/loc_core_log.h
Normal file
58
gps/core/loc_core_log.h
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
/* Copyright (c) 2011-2013, 2016-2017 The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LOC_CORE_LOG_H
|
||||||
|
#define LOC_CORE_LOG_H
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <gps_extended.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const char* loc_get_gps_status_name(LocGpsStatusValue gps_status);
|
||||||
|
const char* loc_get_position_mode_name(LocGpsPositionMode mode);
|
||||||
|
const char* loc_get_position_recurrence_name(LocGpsPositionRecurrence recur);
|
||||||
|
const char* loc_get_aiding_data_mask_names(LocGpsAidingData data);
|
||||||
|
const char* loc_get_agps_type_name(LocAGpsType type);
|
||||||
|
const char* loc_get_ni_type_name(LocGpsNiType type);
|
||||||
|
const char* loc_get_ni_response_name(LocGpsUserResponseType response);
|
||||||
|
const char* loc_get_ni_encoding_name(LocGpsNiEncodingType encoding);
|
||||||
|
const char* loc_get_agps_bear_name(AGpsBearerType bear);
|
||||||
|
const char* loc_get_server_type_name(LocServerType type);
|
||||||
|
const char* loc_get_position_sess_status_name(enum loc_sess_status status);
|
||||||
|
const char* loc_get_agps_status_name(LocAGpsStatusValue status);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LOC_CORE_LOG_H */
|
76
gps/core/observer/IDataItemObserver.h
Normal file
76
gps/core/observer/IDataItemObserver.h
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __IDATAITEMOBSERVER_H__
|
||||||
|
#define __IDATAITEMOBSERVER_H__
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace loc_core
|
||||||
|
{
|
||||||
|
class IDataItemCore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief IDataItemObserver interface
|
||||||
|
* @details IDataItemObserver interface;
|
||||||
|
* In OS dependent code this type serves as a handle to an OS independent instance of this interface.
|
||||||
|
*/
|
||||||
|
class IDataItemObserver {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets name of Data Item Observer
|
||||||
|
* @details Gets name of Data Item Observer
|
||||||
|
*
|
||||||
|
* @param name reference to name of Data Item Observer
|
||||||
|
*/
|
||||||
|
virtual void getName (string & name) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Notify updated values of Data Items
|
||||||
|
* @details Notifys updated values of Data items
|
||||||
|
*
|
||||||
|
* @param dlist List of updated data items
|
||||||
|
*/
|
||||||
|
virtual void notify (const std :: list <IDataItemCore *> & dlist) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destructor
|
||||||
|
* @details Destructor
|
||||||
|
*/
|
||||||
|
virtual ~IDataItemObserver () {}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace loc_core
|
||||||
|
|
||||||
|
#endif // #ifndef __IDATAITEMOBSERVER_H__
|
129
gps/core/observer/IDataItemSubscription.h
Normal file
129
gps/core/observer/IDataItemSubscription.h
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __IDATAITEMSUBSCRIPTION_H__
|
||||||
|
#define __IDATAITEMSUBSCRIPTION_H__
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <DataItemId.h>
|
||||||
|
|
||||||
|
namespace loc_core
|
||||||
|
{
|
||||||
|
class IDataItemObserver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief IDataItemSubscription interface
|
||||||
|
* @details IDataItemSubscription interface;
|
||||||
|
* Defines an interface for operations such as subscribe,
|
||||||
|
* unsubscribe data items by their IDs.
|
||||||
|
* Must be implemented by OS dependent code.
|
||||||
|
*/
|
||||||
|
class IDataItemSubscription {
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Subscribe for data items by their IDs
|
||||||
|
* @details Subscribe for data items by their IDs;
|
||||||
|
* An IDataItemObserver implementer invokes this method to subscribe
|
||||||
|
* for a list of DataItems by passing in their Ids.
|
||||||
|
* A symbolic invocation of this method in the following order
|
||||||
|
* subscribe ( {1,2,3}, &obj), subscribe ( {2,3,4,5}, &obj)
|
||||||
|
* where the numbers enclosed in braces indicate a list of data item Ids
|
||||||
|
* will cause this class implementer to update its subscription list for
|
||||||
|
* &obj to only contain the following Data Item Ids 1,2,3,4,5.
|
||||||
|
*
|
||||||
|
* @param l List of DataItemId
|
||||||
|
* @param o Pointer to an instance of IDataItemObserver
|
||||||
|
*/
|
||||||
|
virtual void subscribe (const std :: list <DataItemId> & l, IDataItemObserver * o = NULL) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Update subscription for Data items
|
||||||
|
* @details Update subscription for Data items;
|
||||||
|
* An IDataItemObserver implementer invokes this method to update their
|
||||||
|
* subscription for a list of DataItems by passing in their Ids
|
||||||
|
* A symbolic invocation of this method in the following order
|
||||||
|
* updateSubscription ( {1,2,3}, &obj),updateSubscription ( {2,3,4,5}, &obj)
|
||||||
|
* where the numbers enclosed in braces indicate a list of data item Ids
|
||||||
|
* will cause this class implementer to update its subscription list for
|
||||||
|
* &obj to only contain the following Data Item Ids 2,3,4,5.
|
||||||
|
* Note that this method may or may not be called.
|
||||||
|
*
|
||||||
|
* @param l List of DataItemId
|
||||||
|
* @param o Pointer to an instance of IDataItemObserver
|
||||||
|
*/
|
||||||
|
virtual void updateSubscription (const std :: list <DataItemId> & l, IDataItemObserver * o = NULL) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Request Data
|
||||||
|
* @details Request Data
|
||||||
|
*
|
||||||
|
* @param l List of DataItemId
|
||||||
|
* @param o Pointer to an instance of IDataItemObserver
|
||||||
|
*/
|
||||||
|
virtual void requestData (const std :: list <DataItemId> & l, IDataItemObserver * o = NULL) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Unsubscribe Data items
|
||||||
|
* @details Unsubscrbe Data items;
|
||||||
|
* An IDataItemObserver implementer invokes this method to unsubscribe their
|
||||||
|
* subscription for a list of DataItems by passing in their Ids
|
||||||
|
* Suppose this class implementor has a currently active subscription list
|
||||||
|
* containing 1,2,3,4,5,6,7 for &obj then a symbolic invocation of this
|
||||||
|
* method in the following order
|
||||||
|
* unsubscribe ( {1,2,3}, &obj), unsubscribe ( {1,2,3,4}, &obj),
|
||||||
|
* unsubscribe ( {7}, &obj)
|
||||||
|
* where the numbers enclosed in braces indicate a list of data item Ids
|
||||||
|
* will cause this class implementer to update its subscription list for
|
||||||
|
* &obj to only contain the following data item id 5,6.
|
||||||
|
*
|
||||||
|
* @param l List of DataItemId
|
||||||
|
* @param o Pointer to an instance of IDataItemObserver
|
||||||
|
*/
|
||||||
|
virtual void unsubscribe (const std :: list <DataItemId> & l, IDataItemObserver * o = NULL) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Unsubscribe all data items
|
||||||
|
* @details Unsubscribe all data items
|
||||||
|
*
|
||||||
|
* @param o Pointer to an instance of IDataItemObserver
|
||||||
|
*/
|
||||||
|
virtual void unsubscribeAll (IDataItemObserver * o = NULL) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destructor
|
||||||
|
* @details Destructor
|
||||||
|
*/
|
||||||
|
virtual ~IDataItemSubscription () {}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace loc_core
|
||||||
|
|
||||||
|
#endif // #ifndef __IDATAITEMSUBSCRIPTION_H__
|
||||||
|
|
83
gps/core/observer/IFrameworkActionReq.h
Normal file
83
gps/core/observer/IFrameworkActionReq.h
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
/* Copyright (c) 2017 The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __IFRAMEWORKACTIONREQ_H__
|
||||||
|
#define __IFRAMEWORKACTIONREQ_H__
|
||||||
|
|
||||||
|
#include <DataItemId.h>
|
||||||
|
|
||||||
|
namespace loc_core
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief IFrameworkActionReq interface
|
||||||
|
* @details IFrameworkActionReq interface;
|
||||||
|
* Defines an interface for operations such as turnOn, turnOff a
|
||||||
|
* framework module described by the data item. Framework module
|
||||||
|
* could be bluetooth, wifi etc.
|
||||||
|
* Must be implemented by OS dependent code.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class IFrameworkActionReq {
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Turn on the framework module described by the data item.
|
||||||
|
* @details Turn on the framework module described by the data item;
|
||||||
|
* An IFrameworkActionReq implementer invokes this method to
|
||||||
|
* turn on the framework module described by the data item.
|
||||||
|
* Framework module could be bluetooth, wifi etc.
|
||||||
|
*
|
||||||
|
* @param dit DataItemId
|
||||||
|
* @param timeout Timeout after which to turn off the framework module.
|
||||||
|
*/
|
||||||
|
virtual void turnOn (DataItemId dit, int timeOut = 0) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Turn off the framework module described by the data item.
|
||||||
|
* @details Turn off the framework module described by the data item;
|
||||||
|
* An IFrameworkActionReq implementer invokes this method to
|
||||||
|
* turn off the framework module described by the data item.
|
||||||
|
* Framework module could be bluetooth, wifi etc.
|
||||||
|
*
|
||||||
|
* @param dit DataItemId
|
||||||
|
*/
|
||||||
|
virtual void turnOff (DataItemId dit) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destructor
|
||||||
|
* @details Destructor
|
||||||
|
*/
|
||||||
|
virtual ~IFrameworkActionReq () {}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace loc_core
|
||||||
|
|
||||||
|
#endif // #ifndef __IFRAMEWORKACTIONREQ_H__
|
||||||
|
|
103
gps/core/observer/IOsObserver.h
Normal file
103
gps/core/observer/IOsObserver.h
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __IOSOBSERVER_H__
|
||||||
|
#define __IOSOBSERVER_H__
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <string>
|
||||||
|
#include <IDataItemObserver.h>
|
||||||
|
#include <IDataItemSubscription.h>
|
||||||
|
#include <IFrameworkActionReq.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace loc_core
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief IOsObserver interface
|
||||||
|
* @details IOsObserver interface;
|
||||||
|
* In OS dependent code this type serves as a handle to
|
||||||
|
* an OS independent instance of this interface.
|
||||||
|
*/
|
||||||
|
class IOsObserver :
|
||||||
|
public IDataItemObserver,
|
||||||
|
public IDataItemSubscription,
|
||||||
|
public IFrameworkActionReq {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// To set the subscription object
|
||||||
|
virtual void setSubscriptionObj(IDataItemSubscription *subscriptionObj) = 0;
|
||||||
|
|
||||||
|
// To set the framework action request object
|
||||||
|
virtual void setFrameworkActionReqObj(IFrameworkActionReq *frameworkActionReqObj) = 0;
|
||||||
|
|
||||||
|
// IDataItemObserver Overrides
|
||||||
|
inline virtual void getName (string & /*name*/) {}
|
||||||
|
inline virtual void notify (const std::list <IDataItemCore *> & /*dlist*/) {}
|
||||||
|
|
||||||
|
// IDataItemSubscription Overrides
|
||||||
|
inline virtual void subscribe
|
||||||
|
(
|
||||||
|
const std :: list <DataItemId> & /*l*/,
|
||||||
|
IDataItemObserver * /*client*/
|
||||||
|
){}
|
||||||
|
inline virtual void updateSubscription
|
||||||
|
(
|
||||||
|
const std :: list <DataItemId> & /*l*/,
|
||||||
|
IDataItemObserver * /*client*/
|
||||||
|
){}
|
||||||
|
inline virtual void requestData
|
||||||
|
(
|
||||||
|
const std :: list <DataItemId> & /*l*/,
|
||||||
|
IDataItemObserver * /*client*/
|
||||||
|
){}
|
||||||
|
inline virtual void unsubscribe
|
||||||
|
(
|
||||||
|
const std :: list <DataItemId> & /*l*/,
|
||||||
|
IDataItemObserver * /*client*/
|
||||||
|
){}
|
||||||
|
inline virtual void unsubscribeAll (IDataItemObserver * /*client*/){}
|
||||||
|
|
||||||
|
// IFrameworkActionReq Overrides
|
||||||
|
inline virtual void turnOn (DataItemId /*dit*/, int /*timeOut*/){}
|
||||||
|
inline virtual void turnOff (DataItemId /*dit*/) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destructor
|
||||||
|
* @details Destructor
|
||||||
|
*/
|
||||||
|
virtual ~IOsObserver () {}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace loc_core
|
||||||
|
|
||||||
|
#endif // #ifndef __IOSOBSERVER_H__
|
12
gps/etc/Android.mk
Normal file
12
gps/etc/Android.mk
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
LOCAL_PATH := $(call my-dir)
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE := gps.conf
|
||||||
|
LOCAL_MODULE_TAGS := optional
|
||||||
|
LOCAL_MODULE_CLASS := ETC
|
||||||
|
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/
|
||||||
|
LOCAL_SRC_FILES := gps.conf
|
||||||
|
|
||||||
|
include $(BUILD_PREBUILT)
|
||||||
|
|
207
gps/etc/gps.conf
Normal file
207
gps/etc/gps.conf
Normal file
|
@ -0,0 +1,207 @@
|
||||||
|
#Uncommenting these urls would only enable
|
||||||
|
#the power up auto injection and force injection(test case).
|
||||||
|
#XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra2.bin
|
||||||
|
#XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra2.bin
|
||||||
|
#XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra2.bin
|
||||||
|
|
||||||
|
#Version check for XTRA
|
||||||
|
#DISABLE = 0
|
||||||
|
#AUTO = 1
|
||||||
|
#XTRA2 = 2
|
||||||
|
#XTRA3 = 3
|
||||||
|
XTRA_VERSION_CHECK=0
|
||||||
|
|
||||||
|
# Error Estimate
|
||||||
|
# _SET = 1
|
||||||
|
# _CLEAR = 0
|
||||||
|
ERR_ESTIMATE=0
|
||||||
|
|
||||||
|
#NTP server
|
||||||
|
NTP_SERVER=time.izatcloud.net
|
||||||
|
|
||||||
|
#XTRA CA path
|
||||||
|
XTRA_CA_PATH=/system/etc/security/cacerts
|
||||||
|
|
||||||
|
# DEBUG LEVELS: 0 - none, 1 - Error, 2 - Warning, 3 - Info
|
||||||
|
# 4 - Debug, 5 - Verbose
|
||||||
|
# If DEBUG_LEVEL is commented, Android's logging levels will be used
|
||||||
|
DEBUG_LEVEL = 3
|
||||||
|
|
||||||
|
# Intermediate position report, 1=enable, 0=disable
|
||||||
|
INTERMEDIATE_POS=0
|
||||||
|
|
||||||
|
# Below bit mask configures how GPS functionalities
|
||||||
|
# should be locked when user turns off GPS on Settings
|
||||||
|
# Set bit 0x1 if MO GPS functionalities are to be locked
|
||||||
|
# Set bit 0x2 if NI GPS functionalities are to be locked
|
||||||
|
# default - non is locked for backward compatibility
|
||||||
|
#GPS_LOCK = 0
|
||||||
|
|
||||||
|
# supl version 1.0
|
||||||
|
SUPL_VER=0x10000
|
||||||
|
|
||||||
|
# Emergency SUPL, 1=enable, 0=disable
|
||||||
|
#SUPL_ES=0
|
||||||
|
|
||||||
|
#Choose PDN for Emergency SUPL
|
||||||
|
#1 - Use emergency PDN
|
||||||
|
#0 - Use regular SUPL PDN for Emergency SUPL
|
||||||
|
#USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=0
|
||||||
|
|
||||||
|
#SUPL_MODE is a bit mask set in config.xml per carrier by default.
|
||||||
|
#If it is uncommented here, this value will overwrite the value from
|
||||||
|
#config.xml.
|
||||||
|
#MSA=0X2
|
||||||
|
#MSB=0X1
|
||||||
|
#SUPL_MODE=
|
||||||
|
|
||||||
|
# GPS Capabilities bit mask
|
||||||
|
# SCHEDULING = 0x01
|
||||||
|
# MSB = 0x02
|
||||||
|
# MSA = 0x04
|
||||||
|
# ON_DEMAND_TIME = 0x10
|
||||||
|
# GEOFENCE = 0x20
|
||||||
|
# default = ON_DEMAND_TIME | MSA | MSB | SCHEDULING | GEOFENCE
|
||||||
|
CAPABILITIES=0x37
|
||||||
|
|
||||||
|
# Accuracy threshold for intermediate positions
|
||||||
|
# less accurate positions are ignored, 0 for passing all positions
|
||||||
|
# ACCURACY_THRES=5000
|
||||||
|
|
||||||
|
################################
|
||||||
|
##### AGPS server settings #####
|
||||||
|
################################
|
||||||
|
|
||||||
|
# FOR SUPL SUPPORT, set the following
|
||||||
|
# SUPL_HOST=supl.host.com or IP
|
||||||
|
# SUPL_PORT=1234
|
||||||
|
|
||||||
|
# FOR C2K PDE SUPPORT, set the following
|
||||||
|
# C2K_HOST=c2k.pde.com or IP
|
||||||
|
# C2K_PORT=1234
|
||||||
|
|
||||||
|
# Bitmask of slots that are available
|
||||||
|
# for write/install to, where 1s indicate writable,
|
||||||
|
# and the default value is 0 where no slots
|
||||||
|
# are writable. For example, AGPS_CERT_WRITABLE_MASK
|
||||||
|
# of b1000001010 makes 3 slots available
|
||||||
|
# and the remaining 7 slots unwritable.
|
||||||
|
#AGPS_CERT_WRITABLE_MASK=0
|
||||||
|
|
||||||
|
####################################
|
||||||
|
# LTE Positioning Profile Settings
|
||||||
|
####################################
|
||||||
|
# 0: Enable RRLP on LTE(Default)
|
||||||
|
# 1: Enable LPP_User_Plane on LTE
|
||||||
|
# 2: Enable LPP_Control_Plane
|
||||||
|
# 3: Enable both LPP_User_Plane and LPP_Control_Plane
|
||||||
|
LPP_PROFILE = 2
|
||||||
|
|
||||||
|
################################
|
||||||
|
# EXTRA SETTINGS
|
||||||
|
################################
|
||||||
|
# NMEA provider (1=Modem Processor, 0=Application Processor)
|
||||||
|
NMEA_PROVIDER=0
|
||||||
|
# Mark if it is a SGLTE target (1=SGLTE, 0=nonSGLTE)
|
||||||
|
SGLTE_TARGET=0
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
# Select Positioning Protocol on A-GLONASS system
|
||||||
|
##################################################
|
||||||
|
# 0x1: RRC CPlane
|
||||||
|
# 0x2: RRLP UPlane
|
||||||
|
# 0x4: LLP Uplane
|
||||||
|
A_GLONASS_POS_PROTOCOL_SELECT = 0
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
# Select technology for LPPe Control Plane
|
||||||
|
##################################################
|
||||||
|
# 0x1: DBH for LPPe CP
|
||||||
|
# 0x2: WLAN AP Measurements for LPPe CP
|
||||||
|
# 0x4: SRN AP measurement for CP
|
||||||
|
# 0x8: Sensor Barometer Measurement LPPe CP
|
||||||
|
LPPE_CP_TECHNOLOGY = 0
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
# Select technology for LPPe User Plane
|
||||||
|
##################################################
|
||||||
|
# 0x1: DBH for LPPe UP
|
||||||
|
# 0x2: WLAN AP Measurements for LPPe UP
|
||||||
|
# 0x4: SRN AP measurement for UP
|
||||||
|
# 0x8: Sensor Barometer Measurement LPPe UP
|
||||||
|
LPPE_UP_TECHNOLOGY = 0
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
# AGPS_CONFIG_INJECT
|
||||||
|
##################################################
|
||||||
|
# enable/disable injection of AGPS configurations:
|
||||||
|
# SUPL_VER
|
||||||
|
# SUPL_HOST
|
||||||
|
# SUPL_PORT
|
||||||
|
# C2K_HOST
|
||||||
|
# C2K_PORT
|
||||||
|
# LPP_PROFILE
|
||||||
|
# A_GLONASS_POS_PROTOCOL_SELECT
|
||||||
|
# 0: disable
|
||||||
|
# 1: enable
|
||||||
|
AGPS_CONFIG_INJECT = 1
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
# GNSS settings for automotive use cases
|
||||||
|
# Configurations in following section are
|
||||||
|
# specific to automotive use cases, others
|
||||||
|
# please do not change, keep the default values
|
||||||
|
##################################################
|
||||||
|
|
||||||
|
# AP Coarse Timestamp Uncertainty
|
||||||
|
##################################################
|
||||||
|
# default : 10
|
||||||
|
# AP time stamp uncertainty, until GNSS receiver
|
||||||
|
# is able to acquire better timing information
|
||||||
|
AP_TIMESTAMP_UNCERTAINTY = 10
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
# QDR engine availability status
|
||||||
|
##################################################
|
||||||
|
# 0 : NO QDR (default)
|
||||||
|
# 1 : QDR enabled
|
||||||
|
# This settings enables QDR Configuration for
|
||||||
|
# automotive use case, if enabled then
|
||||||
|
# DR_AP_Service needs to be enabled in izat.conf
|
||||||
|
#EXTERNAL_DR_ENABLED = 0
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
# DR_SYNC Pulse Availability
|
||||||
|
#####################################
|
||||||
|
# 0 : DR_SYNC pulse not available (default)
|
||||||
|
# 1 : DR_SYNC pulse available
|
||||||
|
# This configuration enables the driver to make use
|
||||||
|
# of PPS events generated by DR_SYNC pulse
|
||||||
|
# Standard Linux PPS driver needs to be enabled
|
||||||
|
DR_SYNC_ENABLED = 0
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
# PPS Device name
|
||||||
|
#####################################
|
||||||
|
PPS_DEVICENAME = /dev/pps0
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
# AP Clock Accuracy
|
||||||
|
#####################################
|
||||||
|
# Quality of APPS processor clock (in PPM).
|
||||||
|
# Value specified is used for calculation of
|
||||||
|
# APPS time stamp uncertainty
|
||||||
|
AP_CLOCK_PPM = 100
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
# MAX ms difference to detect missing pulse
|
||||||
|
#####################################
|
||||||
|
# Specifies time threshold in ms to validate any missing PPS pulses
|
||||||
|
MISSING_PULSE_TIME_DELTA = 900
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
# Propagation time uncertainty
|
||||||
|
#####################################
|
||||||
|
# This settings enables time uncertainty propagation
|
||||||
|
# logic incase of missing PPS pulse
|
||||||
|
PROPAGATION_TIME_UNCERTAINTY = 1
|
912
gps/gnss/Agps.cpp
Normal file
912
gps/gnss/Agps.cpp
Normal file
|
@ -0,0 +1,912 @@
|
||||||
|
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LOG_TAG "LocSvc_Agps"
|
||||||
|
|
||||||
|
#include <Agps.h>
|
||||||
|
#include <platform_lib_includes.h>
|
||||||
|
#include <ContextBase.h>
|
||||||
|
#include <loc_timer.h>
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------
|
||||||
|
* AGPS State Machine Methods
|
||||||
|
* -------------------------------------------------------------------*/
|
||||||
|
void AgpsStateMachine::processAgpsEvent(AgpsEvent event){
|
||||||
|
|
||||||
|
LOC_LOGD("processAgpsEvent(): SM %p, Event %d, State %d",
|
||||||
|
this, event, mState);
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
|
||||||
|
case AGPS_EVENT_SUBSCRIBE:
|
||||||
|
processAgpsEventSubscribe();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AGPS_EVENT_UNSUBSCRIBE:
|
||||||
|
processAgpsEventUnsubscribe();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AGPS_EVENT_GRANTED:
|
||||||
|
processAgpsEventGranted();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AGPS_EVENT_RELEASED:
|
||||||
|
processAgpsEventReleased();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AGPS_EVENT_DENIED:
|
||||||
|
processAgpsEventDenied();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
LOC_LOGE("Invalid Loc Agps Event");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AgpsStateMachine::processAgpsEventSubscribe(){
|
||||||
|
|
||||||
|
switch (mState) {
|
||||||
|
|
||||||
|
case AGPS_STATE_RELEASED:
|
||||||
|
/* Add subscriber to list
|
||||||
|
* No notifications until we get RSRC_GRANTED */
|
||||||
|
addSubscriber(mCurrentSubscriber);
|
||||||
|
|
||||||
|
/* Send data request
|
||||||
|
* The if condition below is added so that if the data call setup
|
||||||
|
* fails for DS State Machine, we want to retry in released state.
|
||||||
|
* for Agps State Machine, sendRsrcRequest() will always return
|
||||||
|
* success. */
|
||||||
|
if (requestOrReleaseDataConn(true) == 0) {
|
||||||
|
// If data request successful, move to pending state
|
||||||
|
transitionState(AGPS_STATE_PENDING);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AGPS_STATE_PENDING:
|
||||||
|
/* Already requested for data connection,
|
||||||
|
* do nothing until we get RSRC_GRANTED event;
|
||||||
|
* Just add this subscriber to the list, for notifications */
|
||||||
|
addSubscriber(mCurrentSubscriber);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AGPS_STATE_ACQUIRED:
|
||||||
|
/* We already have the data connection setup,
|
||||||
|
* Notify current subscriber with GRANTED event,
|
||||||
|
* And add it to the subscriber list for further notifications. */
|
||||||
|
notifyEventToSubscriber(AGPS_EVENT_GRANTED, mCurrentSubscriber, false);
|
||||||
|
addSubscriber(mCurrentSubscriber);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AGPS_STATE_RELEASING:
|
||||||
|
addSubscriber(mCurrentSubscriber);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
LOC_LOGE("Invalid state: %d", mState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AgpsStateMachine::processAgpsEventUnsubscribe(){
|
||||||
|
|
||||||
|
switch (mState) {
|
||||||
|
|
||||||
|
case AGPS_STATE_RELEASED:
|
||||||
|
notifyEventToSubscriber(
|
||||||
|
AGPS_EVENT_UNSUBSCRIBE, mCurrentSubscriber, false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AGPS_STATE_PENDING:
|
||||||
|
case AGPS_STATE_ACQUIRED:
|
||||||
|
/* If the subscriber wishes to wait for connection close,
|
||||||
|
* before being removed from list, move to inactive state
|
||||||
|
* and notify */
|
||||||
|
if (mCurrentSubscriber->mWaitForCloseComplete) {
|
||||||
|
mCurrentSubscriber->mIsInactive = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Notify only current subscriber and then delete it from
|
||||||
|
* subscriberList */
|
||||||
|
notifyEventToSubscriber(
|
||||||
|
AGPS_EVENT_UNSUBSCRIBE, mCurrentSubscriber, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If no subscribers in list, release data connection */
|
||||||
|
if (mSubscriberList.empty()) {
|
||||||
|
transitionState(AGPS_STATE_RELEASED);
|
||||||
|
requestOrReleaseDataConn(false);
|
||||||
|
}
|
||||||
|
/* Some subscribers in list, but all inactive;
|
||||||
|
* Release data connection */
|
||||||
|
else if(!anyActiveSubscribers()) {
|
||||||
|
transitionState(AGPS_STATE_RELEASING);
|
||||||
|
requestOrReleaseDataConn(false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AGPS_STATE_RELEASING:
|
||||||
|
/* If the subscriber wishes to wait for connection close,
|
||||||
|
* before being removed from list, move to inactive state
|
||||||
|
* and notify */
|
||||||
|
if (mCurrentSubscriber->mWaitForCloseComplete) {
|
||||||
|
mCurrentSubscriber->mIsInactive = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Notify only current subscriber and then delete it from
|
||||||
|
* subscriberList */
|
||||||
|
notifyEventToSubscriber(
|
||||||
|
AGPS_EVENT_UNSUBSCRIBE, mCurrentSubscriber, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If no subscribers in list, just move the state.
|
||||||
|
* Request for releasing data connection should already have been
|
||||||
|
* sent */
|
||||||
|
if (mSubscriberList.empty()) {
|
||||||
|
transitionState(AGPS_STATE_RELEASED);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
LOC_LOGE("Invalid state: %d", mState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AgpsStateMachine::processAgpsEventGranted(){
|
||||||
|
|
||||||
|
switch (mState) {
|
||||||
|
|
||||||
|
case AGPS_STATE_RELEASED:
|
||||||
|
case AGPS_STATE_ACQUIRED:
|
||||||
|
case AGPS_STATE_RELEASING:
|
||||||
|
LOC_LOGE("Unexpected event GRANTED in state %d", mState);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AGPS_STATE_PENDING:
|
||||||
|
// Move to acquired state
|
||||||
|
transitionState(AGPS_STATE_ACQUIRED);
|
||||||
|
notifyAllSubscribers(
|
||||||
|
AGPS_EVENT_GRANTED, false,
|
||||||
|
AGPS_NOTIFICATION_TYPE_FOR_ACTIVE_SUBSCRIBERS);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
LOC_LOGE("Invalid state: %d", mState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AgpsStateMachine::processAgpsEventReleased(){
|
||||||
|
|
||||||
|
switch (mState) {
|
||||||
|
|
||||||
|
case AGPS_STATE_RELEASED:
|
||||||
|
/* Subscriber list should be empty if we are in released state */
|
||||||
|
if (!mSubscriberList.empty()) {
|
||||||
|
LOC_LOGE("Unexpected event RELEASED in RELEASED state");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AGPS_STATE_ACQUIRED:
|
||||||
|
/* Force release received */
|
||||||
|
LOC_LOGW("Force RELEASED event in ACQUIRED state");
|
||||||
|
transitionState(AGPS_STATE_RELEASED);
|
||||||
|
notifyAllSubscribers(
|
||||||
|
AGPS_EVENT_RELEASED, true,
|
||||||
|
AGPS_NOTIFICATION_TYPE_FOR_ALL_SUBSCRIBERS);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AGPS_STATE_RELEASING:
|
||||||
|
/* Notify all inactive subscribers about the event */
|
||||||
|
notifyAllSubscribers(
|
||||||
|
AGPS_EVENT_RELEASED, true,
|
||||||
|
AGPS_NOTIFICATION_TYPE_FOR_INACTIVE_SUBSCRIBERS);
|
||||||
|
|
||||||
|
/* If we have active subscribers now, they must be waiting for
|
||||||
|
* data conn setup */
|
||||||
|
if (anyActiveSubscribers()) {
|
||||||
|
transitionState(AGPS_STATE_PENDING);
|
||||||
|
requestOrReleaseDataConn(true);
|
||||||
|
}
|
||||||
|
/* No active subscribers, move to released state */
|
||||||
|
else {
|
||||||
|
transitionState(AGPS_STATE_RELEASED);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AGPS_STATE_PENDING:
|
||||||
|
/* NOOP */
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
LOC_LOGE("Invalid state: %d", mState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AgpsStateMachine::processAgpsEventDenied(){
|
||||||
|
|
||||||
|
switch (mState) {
|
||||||
|
|
||||||
|
case AGPS_STATE_RELEASED:
|
||||||
|
LOC_LOGE("Unexpected event DENIED in state %d", mState);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AGPS_STATE_ACQUIRED:
|
||||||
|
/* NOOP */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AGPS_STATE_RELEASING:
|
||||||
|
/* Notify all inactive subscribers about the event */
|
||||||
|
notifyAllSubscribers(
|
||||||
|
AGPS_EVENT_RELEASED, true,
|
||||||
|
AGPS_NOTIFICATION_TYPE_FOR_INACTIVE_SUBSCRIBERS);
|
||||||
|
|
||||||
|
/* If we have active subscribers now, they must be waiting for
|
||||||
|
* data conn setup */
|
||||||
|
if (anyActiveSubscribers()) {
|
||||||
|
transitionState(AGPS_STATE_PENDING);
|
||||||
|
requestOrReleaseDataConn(true);
|
||||||
|
}
|
||||||
|
/* No active subscribers, move to released state */
|
||||||
|
else {
|
||||||
|
transitionState(AGPS_STATE_RELEASED);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AGPS_STATE_PENDING:
|
||||||
|
transitionState(AGPS_STATE_RELEASED);
|
||||||
|
notifyAllSubscribers(
|
||||||
|
AGPS_EVENT_DENIED, true,
|
||||||
|
AGPS_NOTIFICATION_TYPE_FOR_ALL_SUBSCRIBERS);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
LOC_LOGE("Invalid state: %d", mState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Request or Release data connection
|
||||||
|
* bool request :
|
||||||
|
* true = Request data connection
|
||||||
|
* false = Release data connection */
|
||||||
|
int AgpsStateMachine::requestOrReleaseDataConn(bool request){
|
||||||
|
|
||||||
|
AGnssExtStatusIpV4 nifRequest;
|
||||||
|
memset(&nifRequest, 0, sizeof(nifRequest));
|
||||||
|
|
||||||
|
nifRequest.type = mAgpsType;
|
||||||
|
|
||||||
|
if (request) {
|
||||||
|
LOC_LOGD("AGPS Data Conn Request");
|
||||||
|
nifRequest.status = LOC_GPS_REQUEST_AGPS_DATA_CONN;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
LOC_LOGD("AGPS Data Conn Release");
|
||||||
|
nifRequest.status = LOC_GPS_RELEASE_AGPS_DATA_CONN;
|
||||||
|
}
|
||||||
|
|
||||||
|
mAgpsManager->mFrameworkStatusV4Cb(nifRequest);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AgpsStateMachine::notifyAllSubscribers(
|
||||||
|
AgpsEvent event, bool deleteSubscriberPostNotify,
|
||||||
|
AgpsNotificationType notificationType){
|
||||||
|
|
||||||
|
LOC_LOGD("notifyAllSubscribers(): "
|
||||||
|
"SM %p, Event %d Delete %d Notification Type %d",
|
||||||
|
this, event, deleteSubscriberPostNotify, notificationType);
|
||||||
|
|
||||||
|
std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
|
||||||
|
while ( it != mSubscriberList.end() ) {
|
||||||
|
|
||||||
|
AgpsSubscriber* subscriber = *it;
|
||||||
|
|
||||||
|
if (notificationType == AGPS_NOTIFICATION_TYPE_FOR_ALL_SUBSCRIBERS ||
|
||||||
|
(notificationType == AGPS_NOTIFICATION_TYPE_FOR_INACTIVE_SUBSCRIBERS &&
|
||||||
|
subscriber->mIsInactive) ||
|
||||||
|
(notificationType == AGPS_NOTIFICATION_TYPE_FOR_ACTIVE_SUBSCRIBERS &&
|
||||||
|
!subscriber->mIsInactive)) {
|
||||||
|
|
||||||
|
/* Deleting via this call would require another traversal
|
||||||
|
* through subscriber list, inefficient; hence pass in false*/
|
||||||
|
notifyEventToSubscriber(event, subscriber, false);
|
||||||
|
|
||||||
|
if (deleteSubscriberPostNotify) {
|
||||||
|
it = mSubscriberList.erase(it);
|
||||||
|
delete subscriber;
|
||||||
|
} else {
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AgpsStateMachine::notifyEventToSubscriber(
|
||||||
|
AgpsEvent event, AgpsSubscriber* subscriberToNotify,
|
||||||
|
bool deleteSubscriberPostNotify) {
|
||||||
|
|
||||||
|
LOC_LOGD("notifyEventToSubscriber(): "
|
||||||
|
"SM %p, Event %d Subscriber %p Delete %d",
|
||||||
|
this, event, subscriberToNotify, deleteSubscriberPostNotify);
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
|
||||||
|
case AGPS_EVENT_GRANTED:
|
||||||
|
mAgpsManager->mAtlOpenStatusCb(
|
||||||
|
subscriberToNotify->mConnHandle, 1, getAPN(),
|
||||||
|
getBearer(), mAgpsType);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AGPS_EVENT_DENIED:
|
||||||
|
mAgpsManager->mAtlOpenStatusCb(
|
||||||
|
subscriberToNotify->mConnHandle, 0, getAPN(),
|
||||||
|
getBearer(), mAgpsType);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AGPS_EVENT_UNSUBSCRIBE:
|
||||||
|
case AGPS_EVENT_RELEASED:
|
||||||
|
mAgpsManager->mAtlCloseStatusCb(subscriberToNotify->mConnHandle, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
LOC_LOGE("Invalid event %d", event);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Search this subscriber in list and delete */
|
||||||
|
if (deleteSubscriberPostNotify) {
|
||||||
|
deleteSubscriber(subscriberToNotify);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AgpsStateMachine::transitionState(AgpsState newState){
|
||||||
|
|
||||||
|
LOC_LOGD("transitionState(): SM %p, old %d, new %d",
|
||||||
|
this, mState, newState);
|
||||||
|
|
||||||
|
mState = newState;
|
||||||
|
|
||||||
|
// notify state transitions to all subscribers ?
|
||||||
|
}
|
||||||
|
|
||||||
|
void AgpsStateMachine::addSubscriber(AgpsSubscriber* subscriberToAdd){
|
||||||
|
|
||||||
|
LOC_LOGD("addSubscriber(): SM %p, Subscriber %p",
|
||||||
|
this, subscriberToAdd);
|
||||||
|
|
||||||
|
// Check if subscriber is already present in the current list
|
||||||
|
// If not, then add
|
||||||
|
std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
|
||||||
|
for (; it != mSubscriberList.end(); it++) {
|
||||||
|
AgpsSubscriber* subscriber = *it;
|
||||||
|
if (subscriber->equals(subscriberToAdd)) {
|
||||||
|
LOC_LOGE("Subscriber already in list");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AgpsSubscriber* cloned = subscriberToAdd->clone();
|
||||||
|
LOC_LOGD("addSubscriber(): cloned subscriber: %p", cloned);
|
||||||
|
mSubscriberList.push_back(cloned);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AgpsStateMachine::deleteSubscriber(AgpsSubscriber* subscriberToDelete){
|
||||||
|
|
||||||
|
LOC_LOGD("deleteSubscriber(): SM %p, Subscriber %p",
|
||||||
|
this, subscriberToDelete);
|
||||||
|
|
||||||
|
std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
|
||||||
|
while ( it != mSubscriberList.end() ) {
|
||||||
|
|
||||||
|
AgpsSubscriber* subscriber = *it;
|
||||||
|
if (subscriber && subscriber->equals(subscriberToDelete)) {
|
||||||
|
|
||||||
|
it = mSubscriberList.erase(it);
|
||||||
|
delete subscriber;
|
||||||
|
} else {
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AgpsStateMachine::anyActiveSubscribers(){
|
||||||
|
|
||||||
|
std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
|
||||||
|
for (; it != mSubscriberList.end(); it++) {
|
||||||
|
AgpsSubscriber* subscriber = *it;
|
||||||
|
if (!subscriber->mIsInactive) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AgpsStateMachine::setAPN(char* apn, unsigned int len){
|
||||||
|
|
||||||
|
if (NULL != mAPN) {
|
||||||
|
delete mAPN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (apn == NULL || len <= 0) {
|
||||||
|
LOC_LOGD("Invalid apn len (%d) or null apn", len);
|
||||||
|
mAPN = NULL;
|
||||||
|
mAPNLen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NULL != apn) {
|
||||||
|
mAPN = new char[len+1];
|
||||||
|
if (NULL != mAPN) {
|
||||||
|
memcpy(mAPN, apn, len);
|
||||||
|
mAPN[len] = '\0';
|
||||||
|
mAPNLen = len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AgpsSubscriber* AgpsStateMachine::getSubscriber(int connHandle){
|
||||||
|
|
||||||
|
/* Go over the subscriber list */
|
||||||
|
std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
|
||||||
|
for (; it != mSubscriberList.end(); it++) {
|
||||||
|
AgpsSubscriber* subscriber = *it;
|
||||||
|
if (subscriber->mConnHandle == connHandle) {
|
||||||
|
return subscriber;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Not found, return NULL */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
AgpsSubscriber* AgpsStateMachine::getFirstSubscriber(bool isInactive){
|
||||||
|
|
||||||
|
/* Go over the subscriber list */
|
||||||
|
std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
|
||||||
|
for (; it != mSubscriberList.end(); it++) {
|
||||||
|
AgpsSubscriber* subscriber = *it;
|
||||||
|
if(subscriber->mIsInactive == isInactive) {
|
||||||
|
return subscriber;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Not found, return NULL */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AgpsStateMachine::dropAllSubscribers(){
|
||||||
|
|
||||||
|
LOC_LOGD("dropAllSubscribers(): SM %p", this);
|
||||||
|
|
||||||
|
/* Go over the subscriber list */
|
||||||
|
std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
|
||||||
|
while ( it != mSubscriberList.end() ) {
|
||||||
|
AgpsSubscriber* subscriber = *it;
|
||||||
|
it = mSubscriberList.erase(it);
|
||||||
|
delete subscriber;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------
|
||||||
|
* DS State Machine Methods
|
||||||
|
* -------------------------------------------------------------------*/
|
||||||
|
const int DSStateMachine::MAX_START_DATA_CALL_RETRIES = 4;
|
||||||
|
const int DSStateMachine::DATA_CALL_RETRY_DELAY_MSEC = 500;
|
||||||
|
|
||||||
|
/* Overridden method
|
||||||
|
* DS SM needs to handle one scenario differently */
|
||||||
|
void DSStateMachine::processAgpsEvent(AgpsEvent event) {
|
||||||
|
|
||||||
|
LOC_LOGD("DSStateMachine::processAgpsEvent() %d", event);
|
||||||
|
|
||||||
|
/* DS Client call setup APIs don't return failure/closure separately.
|
||||||
|
* Hence we receive RELEASED event in both cases.
|
||||||
|
* If we are in pending, we should consider RELEASED as DENIED */
|
||||||
|
if (event == AGPS_EVENT_RELEASED && mState == AGPS_STATE_PENDING) {
|
||||||
|
|
||||||
|
LOC_LOGD("Translating RELEASED to DENIED event");
|
||||||
|
event = AGPS_EVENT_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Redirect process to base class */
|
||||||
|
AgpsStateMachine::processAgpsEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Timer Callback
|
||||||
|
* For the retry timer started in case of DS Client call setup failure */
|
||||||
|
void delay_callback(void *callbackData, int result)
|
||||||
|
{
|
||||||
|
LOC_LOGD("delay_callback(): cbData %p", callbackData);
|
||||||
|
|
||||||
|
(void)result;
|
||||||
|
|
||||||
|
if (callbackData == NULL) {
|
||||||
|
LOC_LOGE("delay_callback(): NULL argument received !");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DSStateMachine* dsStateMachine = (DSStateMachine *)callbackData;
|
||||||
|
dsStateMachine->retryCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Invoked from Timer Callback
|
||||||
|
* For the retry timer started in case of DS Client call setup failure */
|
||||||
|
void DSStateMachine :: retryCallback()
|
||||||
|
{
|
||||||
|
LOC_LOGD("DSStateMachine::retryCallback()");
|
||||||
|
|
||||||
|
/* Request SUPL ES
|
||||||
|
* There must be at least one active subscriber in list */
|
||||||
|
AgpsSubscriber* subscriber = getFirstSubscriber(false);
|
||||||
|
if (subscriber == NULL) {
|
||||||
|
|
||||||
|
LOC_LOGE("No active subscriber for DS Client call setup");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send message to retry */
|
||||||
|
mAgpsManager->mSendMsgToAdapterQueueFn(
|
||||||
|
new AgpsMsgRequestATL(
|
||||||
|
mAgpsManager, subscriber->mConnHandle,
|
||||||
|
LOC_AGPS_TYPE_SUPL_ES));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Overridden method
|
||||||
|
* Request or Release data connection
|
||||||
|
* bool request :
|
||||||
|
* true = Request data connection
|
||||||
|
* false = Release data connection */
|
||||||
|
int DSStateMachine::requestOrReleaseDataConn(bool request){
|
||||||
|
|
||||||
|
LOC_LOGD("DSStateMachine::requestOrReleaseDataConn(): "
|
||||||
|
"request %d", request);
|
||||||
|
|
||||||
|
/* Release data connection required ? */
|
||||||
|
if (!request && mAgpsManager->mDSClientStopDataCallFn) {
|
||||||
|
|
||||||
|
mAgpsManager->mDSClientStopDataCallFn();
|
||||||
|
LOC_LOGD("DS Client release data call request sent !");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setup data connection request
|
||||||
|
* There must be at least one active subscriber in list */
|
||||||
|
AgpsSubscriber* subscriber = getFirstSubscriber(false);
|
||||||
|
if (subscriber == NULL) {
|
||||||
|
|
||||||
|
LOC_LOGE("No active subscriber for DS Client call setup");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* DS Client Fn registered ? */
|
||||||
|
if (!mAgpsManager->mDSClientOpenAndStartDataCallFn) {
|
||||||
|
|
||||||
|
LOC_LOGE("DS Client start fn not registered, fallback to SUPL ATL");
|
||||||
|
notifyEventToSubscriber(AGPS_EVENT_DENIED, subscriber, false);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setup the call */
|
||||||
|
int ret = mAgpsManager->mDSClientOpenAndStartDataCallFn();
|
||||||
|
|
||||||
|
/* Check if data call start failed */
|
||||||
|
switch (ret) {
|
||||||
|
|
||||||
|
case LOC_API_ADAPTER_ERR_ENGINE_BUSY:
|
||||||
|
LOC_LOGE("DS Client open call failed, err: %d", ret);
|
||||||
|
mRetries++;
|
||||||
|
if (mRetries > MAX_START_DATA_CALL_RETRIES) {
|
||||||
|
|
||||||
|
LOC_LOGE("DS Client call retries exhausted, "
|
||||||
|
"falling back to normal SUPL ATL");
|
||||||
|
notifyEventToSubscriber(AGPS_EVENT_DENIED, subscriber, false);
|
||||||
|
}
|
||||||
|
/* Retry DS Client call setup after some delay */
|
||||||
|
else if(loc_timer_start(
|
||||||
|
DATA_CALL_RETRY_DELAY_MSEC, delay_callback, this)) {
|
||||||
|
LOC_LOGE("Error: Could not start delay thread\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LOC_API_ADAPTER_ERR_UNSUPPORTED:
|
||||||
|
LOC_LOGE("No emergency profile found. Fall back to normal SUPL ATL");
|
||||||
|
notifyEventToSubscriber(AGPS_EVENT_DENIED, subscriber, false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LOC_API_ADAPTER_ERR_SUCCESS:
|
||||||
|
LOC_LOGD("Request to start data call sent");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
LOC_LOGE("Unrecognized return value: %d", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSStateMachine::notifyEventToSubscriber(
|
||||||
|
AgpsEvent event, AgpsSubscriber* subscriberToNotify,
|
||||||
|
bool deleteSubscriberPostNotify) {
|
||||||
|
|
||||||
|
LOC_LOGD("DSStateMachine::notifyEventToSubscriber(): "
|
||||||
|
"SM %p, Event %d Subscriber %p Delete %d",
|
||||||
|
this, event, subscriberToNotify, deleteSubscriberPostNotify);
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
|
||||||
|
case AGPS_EVENT_GRANTED:
|
||||||
|
mAgpsManager->mAtlOpenStatusCb(
|
||||||
|
subscriberToNotify->mConnHandle, 1, NULL,
|
||||||
|
AGPS_APN_BEARER_INVALID, LOC_AGPS_TYPE_SUPL_ES);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AGPS_EVENT_DENIED:
|
||||||
|
/* Now try with regular SUPL
|
||||||
|
* We need to send request via message queue */
|
||||||
|
mRetries = 0;
|
||||||
|
mAgpsManager->mSendMsgToAdapterQueueFn(
|
||||||
|
new AgpsMsgRequestATL(
|
||||||
|
mAgpsManager, subscriberToNotify->mConnHandle,
|
||||||
|
LOC_AGPS_TYPE_SUPL));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AGPS_EVENT_UNSUBSCRIBE:
|
||||||
|
mAgpsManager->mAtlCloseStatusCb(subscriberToNotify->mConnHandle, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AGPS_EVENT_RELEASED:
|
||||||
|
mAgpsManager->mDSClientCloseDataCallFn();
|
||||||
|
mAgpsManager->mAtlCloseStatusCb(subscriberToNotify->mConnHandle, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
LOC_LOGE("Invalid event %d", event);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Search this subscriber in list and delete */
|
||||||
|
if (deleteSubscriberPostNotify) {
|
||||||
|
deleteSubscriber(subscriberToNotify);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------
|
||||||
|
* Loc AGPS Manager Methods
|
||||||
|
* -------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* CREATE AGPS STATE MACHINES
|
||||||
|
* Must be invoked in Msg Handler context */
|
||||||
|
void AgpsManager::createAgpsStateMachines() {
|
||||||
|
|
||||||
|
LOC_LOGD("AgpsManager::createAgpsStateMachines");
|
||||||
|
|
||||||
|
bool agpsCapable =
|
||||||
|
((loc_core::ContextBase::mGps_conf.CAPABILITIES & LOC_GPS_CAPABILITY_MSA) ||
|
||||||
|
(loc_core::ContextBase::mGps_conf.CAPABILITIES & LOC_GPS_CAPABILITY_MSB));
|
||||||
|
|
||||||
|
if (NULL == mInternetNif) {
|
||||||
|
mInternetNif = new AgpsStateMachine(this, LOC_AGPS_TYPE_WWAN_ANY);
|
||||||
|
LOC_LOGD("Internet NIF: %p", mInternetNif);
|
||||||
|
}
|
||||||
|
if (agpsCapable) {
|
||||||
|
if (NULL == mAgnssNif) {
|
||||||
|
mAgnssNif = new AgpsStateMachine(this, LOC_AGPS_TYPE_SUPL);
|
||||||
|
LOC_LOGD("AGNSS NIF: %p", mAgnssNif);
|
||||||
|
}
|
||||||
|
if (NULL == mDsNif &&
|
||||||
|
loc_core::ContextBase::mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL) {
|
||||||
|
|
||||||
|
if(!mDSClientInitFn){
|
||||||
|
|
||||||
|
LOC_LOGE("DS Client Init Fn not registered !");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mDSClientInitFn(false) != 0) {
|
||||||
|
|
||||||
|
LOC_LOGE("Failed to init data service client");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mDsNif = new DSStateMachine(this);
|
||||||
|
LOC_LOGD("DS NIF: %p", mDsNif);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AgpsStateMachine* AgpsManager::getAgpsStateMachine(AGpsExtType agpsType) {
|
||||||
|
|
||||||
|
LOC_LOGD("AgpsManager::getAgpsStateMachine(): agpsType %d", agpsType);
|
||||||
|
|
||||||
|
switch (agpsType) {
|
||||||
|
|
||||||
|
case LOC_AGPS_TYPE_INVALID:
|
||||||
|
case LOC_AGPS_TYPE_SUPL:
|
||||||
|
if (mAgnssNif == NULL) {
|
||||||
|
LOC_LOGE("NULL AGNSS NIF !");
|
||||||
|
}
|
||||||
|
return mAgnssNif;
|
||||||
|
|
||||||
|
case LOC_AGPS_TYPE_SUPL_ES:
|
||||||
|
if (loc_core::ContextBase::mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL) {
|
||||||
|
if (mDsNif == NULL) {
|
||||||
|
createAgpsStateMachines();
|
||||||
|
}
|
||||||
|
return mDsNif;
|
||||||
|
} else {
|
||||||
|
return mAgnssNif;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return mInternetNif;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOC_LOGE("No SM found !");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AgpsManager::requestATL(int connHandle, AGpsExtType agpsType){
|
||||||
|
|
||||||
|
LOC_LOGD("AgpsManager::requestATL(): connHandle %d, agpsType %d",
|
||||||
|
connHandle, agpsType);
|
||||||
|
|
||||||
|
AgpsStateMachine* sm = getAgpsStateMachine(agpsType);
|
||||||
|
|
||||||
|
if (sm == NULL) {
|
||||||
|
|
||||||
|
LOC_LOGE("No AGPS State Machine for agpsType: %d", agpsType);
|
||||||
|
mAtlOpenStatusCb(
|
||||||
|
connHandle, 0, NULL, AGPS_APN_BEARER_INVALID, agpsType);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Invoke AGPS SM processing */
|
||||||
|
AgpsSubscriber subscriber(connHandle, false, false);
|
||||||
|
sm->setCurrentSubscriber(&subscriber);
|
||||||
|
|
||||||
|
/* If DS State Machine, wait for close complete */
|
||||||
|
if (agpsType == LOC_AGPS_TYPE_SUPL_ES) {
|
||||||
|
subscriber.mWaitForCloseComplete = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send subscriber event */
|
||||||
|
sm->processAgpsEvent(AGPS_EVENT_SUBSCRIBE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AgpsManager::releaseATL(int connHandle){
|
||||||
|
|
||||||
|
LOC_LOGD("AgpsManager::releaseATL(): connHandle %d", connHandle);
|
||||||
|
|
||||||
|
/* First find the subscriber with specified handle.
|
||||||
|
* We need to search in all state machines. */
|
||||||
|
AgpsStateMachine* sm = NULL;
|
||||||
|
AgpsSubscriber* subscriber = NULL;
|
||||||
|
|
||||||
|
if (mAgnssNif &&
|
||||||
|
(subscriber = mAgnssNif->getSubscriber(connHandle)) != NULL) {
|
||||||
|
sm = mAgnssNif;
|
||||||
|
}
|
||||||
|
else if (mInternetNif &&
|
||||||
|
(subscriber = mInternetNif->getSubscriber(connHandle)) != NULL) {
|
||||||
|
sm = mInternetNif;
|
||||||
|
}
|
||||||
|
else if (mDsNif &&
|
||||||
|
(subscriber = mDsNif->getSubscriber(connHandle)) != NULL) {
|
||||||
|
sm = mDsNif;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sm == NULL) {
|
||||||
|
LOC_LOGE("Subscriber with connHandle %d not found in any SM",
|
||||||
|
connHandle);
|
||||||
|
mAtlCloseStatusCb(connHandle, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now send unsubscribe event */
|
||||||
|
sm->setCurrentSubscriber(subscriber);
|
||||||
|
sm->processAgpsEvent(AGPS_EVENT_UNSUBSCRIBE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AgpsManager::reportDataCallOpened(){
|
||||||
|
|
||||||
|
LOC_LOGD("AgpsManager::reportDataCallOpened");
|
||||||
|
|
||||||
|
if (mDsNif) {
|
||||||
|
mDsNif->processAgpsEvent(AGPS_EVENT_GRANTED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AgpsManager::reportDataCallClosed(){
|
||||||
|
|
||||||
|
LOC_LOGD("AgpsManager::reportDataCallClosed");
|
||||||
|
|
||||||
|
if (mDsNif) {
|
||||||
|
mDsNif->processAgpsEvent(AGPS_EVENT_RELEASED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AgpsManager::reportAtlOpenSuccess(
|
||||||
|
AGpsExtType agpsType, char* apnName, int apnLen,
|
||||||
|
AGpsBearerType bearerType){
|
||||||
|
|
||||||
|
LOC_LOGD("AgpsManager::reportAtlOpenSuccess(): "
|
||||||
|
"AgpsType %d, APN [%s], Len %d, BearerType %d",
|
||||||
|
agpsType, apnName, apnLen, bearerType);
|
||||||
|
|
||||||
|
/* Find the state machine instance */
|
||||||
|
AgpsStateMachine* sm = getAgpsStateMachine(agpsType);
|
||||||
|
|
||||||
|
/* Set bearer and apn info in state machine instance */
|
||||||
|
sm->setBearer(bearerType);
|
||||||
|
sm->setAPN(apnName, apnLen);
|
||||||
|
|
||||||
|
/* Send GRANTED event to state machine */
|
||||||
|
sm->processAgpsEvent(AGPS_EVENT_GRANTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AgpsManager::reportAtlOpenFailed(AGpsExtType agpsType){
|
||||||
|
|
||||||
|
LOC_LOGD("AgpsManager::reportAtlOpenFailed(): AgpsType %d", agpsType);
|
||||||
|
|
||||||
|
/* Fetch SM and send DENIED event */
|
||||||
|
AgpsStateMachine* sm = getAgpsStateMachine(agpsType);
|
||||||
|
sm->processAgpsEvent(AGPS_EVENT_DENIED);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AgpsManager::reportAtlClosed(AGpsExtType agpsType){
|
||||||
|
|
||||||
|
LOC_LOGD("AgpsManager::reportAtlClosed(): AgpsType %d", agpsType);
|
||||||
|
|
||||||
|
/* Fetch SM and send RELEASED event */
|
||||||
|
AgpsStateMachine* sm = getAgpsStateMachine(agpsType);
|
||||||
|
sm->processAgpsEvent(AGPS_EVENT_RELEASED);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AgpsManager::handleModemSSR(){
|
||||||
|
|
||||||
|
LOC_LOGD("AgpsManager::handleModemSSR");
|
||||||
|
|
||||||
|
/* Drop subscribers from all state machines */
|
||||||
|
if (mAgnssNif) {
|
||||||
|
mAgnssNif->dropAllSubscribers();
|
||||||
|
}
|
||||||
|
if (mInternetNif) {
|
||||||
|
mInternetNif->dropAllSubscribers();
|
||||||
|
}
|
||||||
|
if (mDsNif) {
|
||||||
|
mDsNif->dropAllSubscribers();
|
||||||
|
}
|
||||||
|
|
||||||
|
// reinitialize DS client in SSR mode
|
||||||
|
if (loc_core::ContextBase::mGps_conf.
|
||||||
|
USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL) {
|
||||||
|
|
||||||
|
mDSClientStopDataCallFn();
|
||||||
|
mDSClientCloseDataCallFn();
|
||||||
|
mDSClientReleaseFn();
|
||||||
|
|
||||||
|
mDSClientInitFn(true);
|
||||||
|
}
|
||||||
|
}
|
383
gps/gnss/Agps.h
Normal file
383
gps/gnss/Agps.h
Normal file
|
@ -0,0 +1,383 @@
|
||||||
|
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AGPS_H
|
||||||
|
#define AGPS_H
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <list>
|
||||||
|
#include <MsgTask.h>
|
||||||
|
#include <gps_extended_c.h>
|
||||||
|
#include <platform_lib_log_util.h>
|
||||||
|
|
||||||
|
/* ATL callback function pointers
|
||||||
|
* Passed in by Adapter to AgpsManager */
|
||||||
|
typedef std::function<void(
|
||||||
|
int handle, int isSuccess, char* apn,
|
||||||
|
AGpsBearerType bearerType, AGpsExtType agpsType)> AgpsAtlOpenStatusCb;
|
||||||
|
|
||||||
|
typedef std::function<void(int handle, int isSuccess)> AgpsAtlCloseStatusCb;
|
||||||
|
|
||||||
|
/* DS Client control APIs
|
||||||
|
* Passed in by Adapter to AgpsManager */
|
||||||
|
typedef std::function<int(bool isDueToSSR)> AgpsDSClientInitFn;
|
||||||
|
typedef std::function<int()> AgpsDSClientOpenAndStartDataCallFn;
|
||||||
|
typedef std::function<void()> AgpsDSClientStopDataCallFn;
|
||||||
|
typedef std::function<void()> AgpsDSClientCloseDataCallFn;
|
||||||
|
typedef std::function<void()> AgpsDSClientReleaseFn;
|
||||||
|
|
||||||
|
/* Post message to adapter's message queue */
|
||||||
|
typedef std::function<void(LocMsg* msg)> SendMsgToAdapterMsgQueueFn;
|
||||||
|
|
||||||
|
/* AGPS States */
|
||||||
|
typedef enum {
|
||||||
|
AGPS_STATE_INVALID = 0,
|
||||||
|
AGPS_STATE_RELEASED,
|
||||||
|
AGPS_STATE_PENDING,
|
||||||
|
AGPS_STATE_ACQUIRED,
|
||||||
|
AGPS_STATE_RELEASING
|
||||||
|
} AgpsState;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
AGPS_EVENT_INVALID = 0,
|
||||||
|
AGPS_EVENT_SUBSCRIBE,
|
||||||
|
AGPS_EVENT_UNSUBSCRIBE,
|
||||||
|
AGPS_EVENT_GRANTED,
|
||||||
|
AGPS_EVENT_RELEASED,
|
||||||
|
AGPS_EVENT_DENIED
|
||||||
|
} AgpsEvent;
|
||||||
|
|
||||||
|
/* Notification Types sent to subscribers */
|
||||||
|
typedef enum {
|
||||||
|
AGPS_NOTIFICATION_TYPE_INVALID = 0,
|
||||||
|
|
||||||
|
/* Meant for all subscribers, either active or inactive */
|
||||||
|
AGPS_NOTIFICATION_TYPE_FOR_ALL_SUBSCRIBERS,
|
||||||
|
|
||||||
|
/* Meant for only inactive subscribers */
|
||||||
|
AGPS_NOTIFICATION_TYPE_FOR_INACTIVE_SUBSCRIBERS,
|
||||||
|
|
||||||
|
/* Meant for only active subscribers */
|
||||||
|
AGPS_NOTIFICATION_TYPE_FOR_ACTIVE_SUBSCRIBERS
|
||||||
|
} AgpsNotificationType;
|
||||||
|
|
||||||
|
/* Classes in this header */
|
||||||
|
class AgpsSubscriber;
|
||||||
|
class AgpsManager;
|
||||||
|
class AgpsStateMachine;
|
||||||
|
class DSStateMachine;
|
||||||
|
|
||||||
|
|
||||||
|
/* SUBSCRIBER
|
||||||
|
* Each Subscriber instance corresponds to one AGPS request,
|
||||||
|
* received by the AGPS state machine */
|
||||||
|
class AgpsSubscriber {
|
||||||
|
|
||||||
|
public:
|
||||||
|
int mConnHandle;
|
||||||
|
|
||||||
|
/* Does this subscriber wait for data call close complete,
|
||||||
|
* before being notified ATL close ?
|
||||||
|
* While waiting for data call close, subscriber will be in
|
||||||
|
* inactive state. */
|
||||||
|
bool mWaitForCloseComplete;
|
||||||
|
bool mIsInactive;
|
||||||
|
|
||||||
|
inline AgpsSubscriber(
|
||||||
|
int connHandle, bool waitForCloseComplete, bool isInactive) :
|
||||||
|
mConnHandle(connHandle),
|
||||||
|
mWaitForCloseComplete(waitForCloseComplete),
|
||||||
|
mIsInactive(isInactive) {}
|
||||||
|
inline virtual ~AgpsSubscriber() {}
|
||||||
|
|
||||||
|
inline virtual bool equals(const AgpsSubscriber *s) const
|
||||||
|
{ return (mConnHandle == s->mConnHandle); }
|
||||||
|
|
||||||
|
inline virtual AgpsSubscriber* clone()
|
||||||
|
{ return new AgpsSubscriber(
|
||||||
|
mConnHandle, mWaitForCloseComplete, mIsInactive); }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* AGPS STATE MACHINE */
|
||||||
|
class AgpsStateMachine {
|
||||||
|
protected:
|
||||||
|
/* AGPS Manager instance, from where this state machine is created */
|
||||||
|
AgpsManager* mAgpsManager;
|
||||||
|
|
||||||
|
/* List of all subscribers for this State Machine.
|
||||||
|
* Once a subscriber is notified for ATL open/close status,
|
||||||
|
* it is deleted */
|
||||||
|
std::list<AgpsSubscriber*> mSubscriberList;
|
||||||
|
|
||||||
|
/* Current subscriber, whose request this State Machine is
|
||||||
|
* currently processing */
|
||||||
|
AgpsSubscriber* mCurrentSubscriber;
|
||||||
|
|
||||||
|
/* Current state for this state machine */
|
||||||
|
AgpsState mState;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* AGPS Type for this state machine
|
||||||
|
LOC_AGPS_TYPE_ANY 0
|
||||||
|
LOC_AGPS_TYPE_SUPL 1
|
||||||
|
LOC_AGPS_TYPE_WWAN_ANY 3
|
||||||
|
LOC_AGPS_TYPE_SUPL_ES 5 */
|
||||||
|
AGpsExtType mAgpsType;
|
||||||
|
|
||||||
|
/* APN and IP Type info for AGPS Call */
|
||||||
|
char* mAPN;
|
||||||
|
unsigned int mAPNLen;
|
||||||
|
AGpsBearerType mBearer;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/* CONSTRUCTOR */
|
||||||
|
AgpsStateMachine(AgpsManager* agpsManager, AGpsExtType agpsType):
|
||||||
|
mAgpsManager(agpsManager), mSubscriberList(),
|
||||||
|
mCurrentSubscriber(NULL), mState(AGPS_STATE_RELEASED),
|
||||||
|
mAgpsType(agpsType), mAPN(NULL), mAPNLen(0),
|
||||||
|
mBearer(AGPS_APN_BEARER_INVALID) {};
|
||||||
|
|
||||||
|
virtual ~AgpsStateMachine() { if(NULL != mAPN) delete[] mAPN; };
|
||||||
|
|
||||||
|
/* Getter/Setter methods */
|
||||||
|
void setAPN(char* apn, unsigned int len);
|
||||||
|
inline char* getAPN() const { return (char*)mAPN; }
|
||||||
|
inline void setBearer(AGpsBearerType bearer) { mBearer = bearer; }
|
||||||
|
inline AGpsBearerType getBearer() const { return mBearer; }
|
||||||
|
inline AGpsExtType getType() const { return mAgpsType; }
|
||||||
|
inline void setCurrentSubscriber(AgpsSubscriber* subscriber)
|
||||||
|
{ mCurrentSubscriber = subscriber; }
|
||||||
|
|
||||||
|
/* Fetch subscriber with specified handle */
|
||||||
|
AgpsSubscriber* getSubscriber(int connHandle);
|
||||||
|
|
||||||
|
/* Fetch first active or inactive subscriber in list
|
||||||
|
* isInactive = true : fetch first inactive subscriber
|
||||||
|
* isInactive = false : fetch first active subscriber */
|
||||||
|
AgpsSubscriber* getFirstSubscriber(bool isInactive);
|
||||||
|
|
||||||
|
/* Process LOC AGPS Event being passed in
|
||||||
|
* onRsrcEvent */
|
||||||
|
virtual void processAgpsEvent(AgpsEvent event);
|
||||||
|
|
||||||
|
/* Drop all subscribers, in case of Modem SSR */
|
||||||
|
void dropAllSubscribers();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/* Remove the specified subscriber from list if present.
|
||||||
|
* Also delete the subscriber instance. */
|
||||||
|
void deleteSubscriber(AgpsSubscriber* subscriber);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* Send call setup request to framework
|
||||||
|
* sendRsrcRequest(LOC_GPS_REQUEST_AGPS_DATA_CONN)
|
||||||
|
* sendRsrcRequest(LOC_GPS_RELEASE_AGPS_DATA_CONN) */
|
||||||
|
virtual int requestOrReleaseDataConn(bool request);
|
||||||
|
|
||||||
|
/* Individual event processing methods */
|
||||||
|
void processAgpsEventSubscribe();
|
||||||
|
void processAgpsEventUnsubscribe();
|
||||||
|
void processAgpsEventGranted();
|
||||||
|
void processAgpsEventReleased();
|
||||||
|
void processAgpsEventDenied();
|
||||||
|
|
||||||
|
/* Clone the passed in subscriber and add to the subscriber list
|
||||||
|
* if not already present */
|
||||||
|
void addSubscriber(AgpsSubscriber* subscriber);
|
||||||
|
|
||||||
|
/* Notify subscribers about AGPS events */
|
||||||
|
void notifyAllSubscribers(
|
||||||
|
AgpsEvent event, bool deleteSubscriberPostNotify,
|
||||||
|
AgpsNotificationType notificationType);
|
||||||
|
virtual void notifyEventToSubscriber(
|
||||||
|
AgpsEvent event, AgpsSubscriber* subscriber,
|
||||||
|
bool deleteSubscriberPostNotify);
|
||||||
|
|
||||||
|
/* Do we have any subscribers in active state */
|
||||||
|
bool anyActiveSubscribers();
|
||||||
|
|
||||||
|
/* Transition state */
|
||||||
|
void transitionState(AgpsState newState);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* DS STATE MACHINE */
|
||||||
|
class DSStateMachine : public AgpsStateMachine {
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const int MAX_START_DATA_CALL_RETRIES;
|
||||||
|
static const int DATA_CALL_RETRY_DELAY_MSEC;
|
||||||
|
|
||||||
|
int mRetries;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/* CONSTRUCTOR */
|
||||||
|
DSStateMachine(AgpsManager* agpsManager):
|
||||||
|
AgpsStateMachine(agpsManager, LOC_AGPS_TYPE_SUPL_ES), mRetries(0) {}
|
||||||
|
|
||||||
|
/* Overridden method
|
||||||
|
* DS SM needs to handle one event differently */
|
||||||
|
void processAgpsEvent(AgpsEvent event);
|
||||||
|
|
||||||
|
/* Retry callback, used in case call failure */
|
||||||
|
void retryCallback();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* Overridden method, different functionality for DS SM
|
||||||
|
* Send call setup request to framework
|
||||||
|
* sendRsrcRequest(LOC_GPS_REQUEST_AGPS_DATA_CONN)
|
||||||
|
* sendRsrcRequest(LOC_GPS_RELEASE_AGPS_DATA_CONN) */
|
||||||
|
int requestOrReleaseDataConn(bool request);
|
||||||
|
|
||||||
|
/* Overridden method, different functionality for DS SM */
|
||||||
|
void notifyEventToSubscriber(
|
||||||
|
AgpsEvent event, AgpsSubscriber* subscriber,
|
||||||
|
bool deleteSubscriberPostNotify);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* LOC AGPS MANAGER */
|
||||||
|
class AgpsManager {
|
||||||
|
|
||||||
|
friend class AgpsStateMachine;
|
||||||
|
friend class DSStateMachine;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/* CONSTRUCTOR */
|
||||||
|
AgpsManager():
|
||||||
|
mFrameworkStatusV4Cb(NULL),
|
||||||
|
mAtlOpenStatusCb(), mAtlCloseStatusCb(),
|
||||||
|
mDSClientInitFn(), mDSClientOpenAndStartDataCallFn(),
|
||||||
|
mDSClientStopDataCallFn(), mDSClientCloseDataCallFn(), mDSClientReleaseFn(),
|
||||||
|
mSendMsgToAdapterQueueFn(),
|
||||||
|
mAgnssNif(NULL), mInternetNif(NULL), mDsNif(NULL) {}
|
||||||
|
|
||||||
|
/* Register callbacks */
|
||||||
|
void registerCallbacks(
|
||||||
|
AgnssStatusIpV4Cb frameworkStatusV4Cb,
|
||||||
|
|
||||||
|
AgpsAtlOpenStatusCb atlOpenStatusCb,
|
||||||
|
AgpsAtlCloseStatusCb atlCloseStatusCb,
|
||||||
|
|
||||||
|
AgpsDSClientInitFn dsClientInitFn,
|
||||||
|
AgpsDSClientOpenAndStartDataCallFn dsClientOpenAndStartDataCallFn,
|
||||||
|
AgpsDSClientStopDataCallFn dsClientStopDataCallFn,
|
||||||
|
AgpsDSClientCloseDataCallFn dsClientCloseDataCallFn,
|
||||||
|
AgpsDSClientReleaseFn dsClientReleaseFn,
|
||||||
|
|
||||||
|
SendMsgToAdapterMsgQueueFn sendMsgToAdapterQueueFn ){
|
||||||
|
|
||||||
|
mFrameworkStatusV4Cb = frameworkStatusV4Cb;
|
||||||
|
|
||||||
|
mAtlOpenStatusCb = atlOpenStatusCb;
|
||||||
|
mAtlCloseStatusCb = atlCloseStatusCb;
|
||||||
|
|
||||||
|
mDSClientInitFn = dsClientInitFn;
|
||||||
|
mDSClientOpenAndStartDataCallFn = dsClientOpenAndStartDataCallFn;
|
||||||
|
mDSClientStopDataCallFn = dsClientStopDataCallFn;
|
||||||
|
mDSClientCloseDataCallFn = dsClientCloseDataCallFn;
|
||||||
|
mDSClientReleaseFn = dsClientReleaseFn;
|
||||||
|
|
||||||
|
mSendMsgToAdapterQueueFn = sendMsgToAdapterQueueFn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create all AGPS state machines */
|
||||||
|
void createAgpsStateMachines();
|
||||||
|
|
||||||
|
/* Process incoming ATL requests */
|
||||||
|
void requestATL(int connHandle, AGpsExtType agpsType);
|
||||||
|
void releaseATL(int connHandle);
|
||||||
|
|
||||||
|
/* Process incoming DS Client data call events */
|
||||||
|
void reportDataCallOpened();
|
||||||
|
void reportDataCallClosed();
|
||||||
|
|
||||||
|
/* Process incoming framework data call events */
|
||||||
|
void reportAtlOpenSuccess(AGpsExtType agpsType, char* apnName, int apnLen,
|
||||||
|
AGpsBearerType bearerType);
|
||||||
|
void reportAtlOpenFailed(AGpsExtType agpsType);
|
||||||
|
void reportAtlClosed(AGpsExtType agpsType);
|
||||||
|
|
||||||
|
/* Handle Modem SSR */
|
||||||
|
void handleModemSSR();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
AgnssStatusIpV4Cb mFrameworkStatusV4Cb;
|
||||||
|
|
||||||
|
AgpsAtlOpenStatusCb mAtlOpenStatusCb;
|
||||||
|
AgpsAtlCloseStatusCb mAtlCloseStatusCb;
|
||||||
|
|
||||||
|
AgpsDSClientInitFn mDSClientInitFn;
|
||||||
|
AgpsDSClientOpenAndStartDataCallFn mDSClientOpenAndStartDataCallFn;
|
||||||
|
AgpsDSClientStopDataCallFn mDSClientStopDataCallFn;
|
||||||
|
AgpsDSClientCloseDataCallFn mDSClientCloseDataCallFn;
|
||||||
|
AgpsDSClientReleaseFn mDSClientReleaseFn;
|
||||||
|
|
||||||
|
SendMsgToAdapterMsgQueueFn mSendMsgToAdapterQueueFn;
|
||||||
|
|
||||||
|
AgpsStateMachine* mAgnssNif;
|
||||||
|
AgpsStateMachine* mInternetNif;
|
||||||
|
AgpsStateMachine* mDsNif;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* Fetch state machine for handling request ATL call */
|
||||||
|
AgpsStateMachine* getAgpsStateMachine(AGpsExtType agpsType);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Request SUPL/INTERNET/SUPL_ES ATL
|
||||||
|
* This LocMsg is defined in this header since it has to be used from more
|
||||||
|
* than one place, other Agps LocMsg are restricted to GnssAdapter and
|
||||||
|
* declared inline */
|
||||||
|
struct AgpsMsgRequestATL: public LocMsg {
|
||||||
|
|
||||||
|
AgpsManager* mAgpsManager;
|
||||||
|
int mConnHandle;
|
||||||
|
AGpsExtType mAgpsType;
|
||||||
|
|
||||||
|
inline AgpsMsgRequestATL(AgpsManager* agpsManager, int connHandle,
|
||||||
|
AGpsExtType agpsType) :
|
||||||
|
LocMsg(), mAgpsManager(agpsManager), mConnHandle(connHandle), mAgpsType(
|
||||||
|
agpsType) {
|
||||||
|
|
||||||
|
LOC_LOGV("AgpsMsgRequestATL");
|
||||||
|
}
|
||||||
|
|
||||||
|
inline virtual void proc() const {
|
||||||
|
|
||||||
|
LOC_LOGV("AgpsMsgRequestATL::proc()");
|
||||||
|
mAgpsManager->requestATL(mConnHandle, mAgpsType);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace AgpsUtils {
|
||||||
|
|
||||||
|
AGpsBearerType ipTypeToBearerType(LocApnIpType ipType);
|
||||||
|
LocApnIpType bearerTypeToIpType(AGpsBearerType bearerType);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* AGPS_H */
|
47
gps/gnss/Android.mk
Normal file
47
gps/gnss/Android.mk
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)
|
||||||
|
ifneq ($(BUILD_TINY_ANDROID),true)
|
||||||
|
|
||||||
|
LOCAL_PATH := $(call my-dir)
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE := libgnss
|
||||||
|
LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib
|
||||||
|
LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64
|
||||||
|
LOCAL_MODULE_TAGS := optional
|
||||||
|
|
||||||
|
LOCAL_SHARED_LIBRARIES := \
|
||||||
|
libutils \
|
||||||
|
libcutils \
|
||||||
|
libdl \
|
||||||
|
liblog \
|
||||||
|
libloc_core \
|
||||||
|
libgps.utils
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES += \
|
||||||
|
location_gnss.cpp \
|
||||||
|
GnssAdapter.cpp \
|
||||||
|
Agps.cpp \
|
||||||
|
XtraSystemStatusObserver.cpp
|
||||||
|
|
||||||
|
LOCAL_CFLAGS += \
|
||||||
|
-fno-short-enums \
|
||||||
|
|
||||||
|
ifeq ($(TARGET_BUILD_VARIANT),user)
|
||||||
|
LOCAL_CFLAGS += -DTARGET_BUILD_VARIANT_USER
|
||||||
|
endif
|
||||||
|
|
||||||
|
LOCAL_HEADER_LIBRARIES := \
|
||||||
|
libgps.utils_headers \
|
||||||
|
libloc_core_headers \
|
||||||
|
libloc_pla_headers \
|
||||||
|
liblocation_api_headers
|
||||||
|
|
||||||
|
LOCAL_CFLAGS += $(GNSS_CFLAGS)
|
||||||
|
|
||||||
|
LOCAL_PRELINK_MODULE := false
|
||||||
|
|
||||||
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
|
|
||||||
|
endif # not BUILD_TINY_ANDROID
|
||||||
|
endif # BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE
|
3131
gps/gnss/GnssAdapter.cpp
Normal file
3131
gps/gnss/GnssAdapter.cpp
Normal file
File diff suppressed because it is too large
Load diff
287
gps/gnss/GnssAdapter.h
Normal file
287
gps/gnss/GnssAdapter.h
Normal file
|
@ -0,0 +1,287 @@
|
||||||
|
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef GNSS_ADAPTER_H
|
||||||
|
#define GNSS_ADAPTER_H
|
||||||
|
|
||||||
|
#include <LocAdapterBase.h>
|
||||||
|
#include <LocDualContext.h>
|
||||||
|
#include <UlpProxyBase.h>
|
||||||
|
#include <LocationAPI.h>
|
||||||
|
#include <Agps.h>
|
||||||
|
#include <SystemStatus.h>
|
||||||
|
#include <XtraSystemStatusObserver.h>
|
||||||
|
|
||||||
|
#define MAX_URL_LEN 256
|
||||||
|
#define NMEA_SENTENCE_MAX_LENGTH 200
|
||||||
|
#define GLONASS_SV_ID_OFFSET 64
|
||||||
|
#define MAX_SATELLITES_IN_USE 12
|
||||||
|
#define LOC_NI_NO_RESPONSE_TIME 20
|
||||||
|
#define LOC_GPS_NI_RESPONSE_IGNORE 4
|
||||||
|
|
||||||
|
class GnssAdapter;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
pthread_t thread; /* NI thread */
|
||||||
|
uint32_t respTimeLeft; /* examine time for NI response */
|
||||||
|
bool respRecvd; /* NI User reponse received or not from Java layer*/
|
||||||
|
void* rawRequest;
|
||||||
|
uint32_t reqID; /* ID to check against response */
|
||||||
|
GnssNiResponse resp;
|
||||||
|
pthread_cond_t tCond;
|
||||||
|
pthread_mutex_t tLock;
|
||||||
|
GnssAdapter* adapter;
|
||||||
|
} NiSession;
|
||||||
|
typedef struct {
|
||||||
|
NiSession session; /* SUPL NI Session */
|
||||||
|
NiSession sessionEs; /* Emergency SUPL NI Session */
|
||||||
|
uint32_t reqIDCounter;
|
||||||
|
} NiData;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
NMEA_PROVIDER_AP = 0, // Application Processor Provider of NMEA
|
||||||
|
NMEA_PROVIDER_MP // Modem Processor Provider of NMEA
|
||||||
|
} NmeaProviderType;
|
||||||
|
typedef struct {
|
||||||
|
GnssSvType svType;
|
||||||
|
const char* talker;
|
||||||
|
uint64_t mask;
|
||||||
|
uint32_t svIdOffset;
|
||||||
|
} NmeaSvMeta;
|
||||||
|
|
||||||
|
using namespace loc_core;
|
||||||
|
|
||||||
|
namespace loc_core {
|
||||||
|
class SystemStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
class GnssAdapter : public LocAdapterBase {
|
||||||
|
/* ==== ULP ============================================================================ */
|
||||||
|
UlpProxyBase* mUlpProxy;
|
||||||
|
|
||||||
|
/* ==== CLIENT ========================================================================= */
|
||||||
|
typedef std::map<LocationAPI*, LocationCallbacks> ClientDataMap;
|
||||||
|
ClientDataMap mClientData;
|
||||||
|
|
||||||
|
/* ==== TRACKING ======================================================================= */
|
||||||
|
LocationSessionMap mTrackingSessions;
|
||||||
|
LocPosMode mUlpPositionMode;
|
||||||
|
GnssSvUsedInPosition mGnssSvIdUsedInPosition;
|
||||||
|
bool mGnssSvIdUsedInPosAvail;
|
||||||
|
|
||||||
|
/* ==== CONTROL ======================================================================== */
|
||||||
|
LocationControlCallbacks mControlCallbacks;
|
||||||
|
uint32_t mPowerVoteId;
|
||||||
|
uint32_t mNmeaMask;
|
||||||
|
|
||||||
|
/* ==== NI ============================================================================= */
|
||||||
|
NiData mNiData;
|
||||||
|
|
||||||
|
/* ==== AGPS ========================================================*/
|
||||||
|
// This must be initialized via initAgps()
|
||||||
|
AgpsManager mAgpsManager;
|
||||||
|
AgpsCbInfo mAgpsCbInfo;
|
||||||
|
|
||||||
|
/* === SystemStatus ===================================================================== */
|
||||||
|
SystemStatus* mSystemStatus;
|
||||||
|
std::string mServerUrl;
|
||||||
|
XtraSystemStatusObserver mXtraObserver;
|
||||||
|
|
||||||
|
/*==== CONVERSION ===================================================================*/
|
||||||
|
static void convertOptions(LocPosMode& out, const LocationOptions& options);
|
||||||
|
static void convertLocation(Location& out, const LocGpsLocation& locGpsLocation,
|
||||||
|
const GpsLocationExtended& locationExtended,
|
||||||
|
const LocPosTechMask techMask);
|
||||||
|
static void convertLocationInfo(GnssLocationInfoNotification& out,
|
||||||
|
const GpsLocationExtended& locationExtended);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
GnssAdapter();
|
||||||
|
virtual inline ~GnssAdapter() { delete mUlpProxy; }
|
||||||
|
|
||||||
|
/* ==== SSR ============================================================================ */
|
||||||
|
/* ======== EVENTS ====(Called from QMI Thread)========================================= */
|
||||||
|
virtual void handleEngineUpEvent();
|
||||||
|
/* ======== UTILITIES ================================================================== */
|
||||||
|
void restartSessions();
|
||||||
|
|
||||||
|
/* ==== ULP ============================================================================ */
|
||||||
|
/* ======== COMMANDS ====(Called from ULP Thread)==================================== */
|
||||||
|
virtual void setUlpProxyCommand(UlpProxyBase* ulp);
|
||||||
|
/* ======== UTILITIES ================================================================== */
|
||||||
|
void setUlpProxy(UlpProxyBase* ulp);
|
||||||
|
inline UlpProxyBase* getUlpProxy() { return mUlpProxy; }
|
||||||
|
|
||||||
|
/* ==== CLIENT ========================================================================= */
|
||||||
|
/* ======== COMMANDS ====(Called from Client Thread)==================================== */
|
||||||
|
void addClientCommand(LocationAPI* client, const LocationCallbacks& callbacks);
|
||||||
|
void removeClientCommand(LocationAPI* client);
|
||||||
|
void requestCapabilitiesCommand(LocationAPI* client);
|
||||||
|
/* ======== UTILITIES ================================================================== */
|
||||||
|
void saveClient(LocationAPI* client, const LocationCallbacks& callbacks);
|
||||||
|
void eraseClient(LocationAPI* client);
|
||||||
|
void updateClientsEventMask();
|
||||||
|
void stopClientSessions(LocationAPI* client);
|
||||||
|
LocationCallbacks getClientCallbacks(LocationAPI* client);
|
||||||
|
LocationCapabilitiesMask getCapabilities();
|
||||||
|
void broadcastCapabilities(LocationCapabilitiesMask);
|
||||||
|
|
||||||
|
/* ==== TRACKING ======================================================================= */
|
||||||
|
/* ======== COMMANDS ====(Called from Client Thread)==================================== */
|
||||||
|
uint32_t startTrackingCommand(LocationAPI* client, LocationOptions& options);
|
||||||
|
void updateTrackingOptionsCommand(LocationAPI* client, uint32_t id, LocationOptions& options);
|
||||||
|
void stopTrackingCommand(LocationAPI* client, uint32_t id);
|
||||||
|
/* ======================(Called from ULP Thread)======================================= */
|
||||||
|
virtual void setPositionModeCommand(LocPosMode& locPosMode);
|
||||||
|
virtual void startTrackingCommand();
|
||||||
|
virtual void stopTrackingCommand();
|
||||||
|
virtual void getZppCommand();
|
||||||
|
/* ======== RESPONSES ================================================================== */
|
||||||
|
void reportResponse(LocationAPI* client, LocationError err, uint32_t sessionId);
|
||||||
|
/* ======== UTILITIES ================================================================== */
|
||||||
|
bool hasTrackingCallback(LocationAPI* client);
|
||||||
|
bool hasMeasurementsCallback(LocationAPI* client);
|
||||||
|
bool isTrackingSession(LocationAPI* client, uint32_t sessionId);
|
||||||
|
void saveTrackingSession(LocationAPI* client, uint32_t sessionId,
|
||||||
|
const LocationOptions& options);
|
||||||
|
void eraseTrackingSession(LocationAPI* client, uint32_t sessionId);
|
||||||
|
bool setUlpPositionMode(const LocPosMode& mode);
|
||||||
|
LocPosMode& getUlpPositionMode() { return mUlpPositionMode; }
|
||||||
|
LocationError startTrackingMultiplex(const LocationOptions& options);
|
||||||
|
LocationError startTracking(const LocationOptions& options);
|
||||||
|
LocationError stopTrackingMultiplex(LocationAPI* client, uint32_t id);
|
||||||
|
LocationError stopTracking();
|
||||||
|
LocationError updateTrackingMultiplex(LocationAPI* client, uint32_t id,
|
||||||
|
const LocationOptions& options);
|
||||||
|
|
||||||
|
/* ==== NI ============================================================================= */
|
||||||
|
/* ======== COMMANDS ====(Called from Client Thread)==================================== */
|
||||||
|
void gnssNiResponseCommand(LocationAPI* client, uint32_t id, GnssNiResponse response);
|
||||||
|
/* ======================(Called from NI Thread)======================================== */
|
||||||
|
void gnssNiResponseCommand(GnssNiResponse response, void* rawRequest);
|
||||||
|
/* ======== UTILITIES ================================================================== */
|
||||||
|
bool hasNiNotifyCallback(LocationAPI* client);
|
||||||
|
NiData& getNiData() { return mNiData; }
|
||||||
|
|
||||||
|
/* ==== CONTROL ======================================================================== */
|
||||||
|
/* ======== COMMANDS ====(Called from Client Thread)==================================== */
|
||||||
|
uint32_t enableCommand(LocationTechnologyType techType);
|
||||||
|
void disableCommand(uint32_t id);
|
||||||
|
void setControlCallbacksCommand(LocationControlCallbacks& controlCallbacks);
|
||||||
|
void readConfigCommand();
|
||||||
|
void setConfigCommand();
|
||||||
|
uint32_t* gnssUpdateConfigCommand(GnssConfig config);
|
||||||
|
uint32_t gnssDeleteAidingDataCommand(GnssAidingData& data);
|
||||||
|
|
||||||
|
void initDefaultAgpsCommand();
|
||||||
|
void initAgpsCommand(const AgpsCbInfo& cbInfo);
|
||||||
|
void dataConnOpenCommand(AGpsExtType agpsType,
|
||||||
|
const char* apnName, int apnLen, AGpsBearerType bearerType);
|
||||||
|
void dataConnClosedCommand(AGpsExtType agpsType);
|
||||||
|
void dataConnFailedCommand(AGpsExtType agpsType);
|
||||||
|
|
||||||
|
/* ======== RESPONSES ================================================================== */
|
||||||
|
void reportResponse(LocationError err, uint32_t sessionId);
|
||||||
|
void reportResponse(size_t count, LocationError* errs, uint32_t* ids);
|
||||||
|
/* ======== UTILITIES ================================================================== */
|
||||||
|
LocationControlCallbacks& getControlCallbacks() { return mControlCallbacks; }
|
||||||
|
void setControlCallbacks(const LocationControlCallbacks& controlCallbacks)
|
||||||
|
{ mControlCallbacks = controlCallbacks; }
|
||||||
|
void setPowerVoteId(uint32_t id) { mPowerVoteId = id; }
|
||||||
|
uint32_t getPowerVoteId() { return mPowerVoteId; }
|
||||||
|
bool resolveInAddress(const char* hostAddress, struct in_addr* inAddress);
|
||||||
|
virtual bool isInSession() { return !mTrackingSessions.empty(); }
|
||||||
|
void initDefaultAgps();
|
||||||
|
|
||||||
|
/* ==== REPORTS ======================================================================== */
|
||||||
|
/* ======== EVENTS ====(Called from QMI/ULP Thread)===================================== */
|
||||||
|
virtual void reportPositionEvent(const UlpLocation& ulpLocation,
|
||||||
|
const GpsLocationExtended& locationExtended,
|
||||||
|
enum loc_sess_status status,
|
||||||
|
LocPosTechMask techMask,
|
||||||
|
bool fromUlp=false);
|
||||||
|
virtual void reportSvEvent(const GnssSvNotification& svNotify, bool fromUlp=false);
|
||||||
|
virtual void reportNmeaEvent(const char* nmea, size_t length, bool fromUlp=false);
|
||||||
|
virtual bool requestNiNotifyEvent(const GnssNiNotification& notify, const void* data);
|
||||||
|
virtual void reportGnssMeasurementDataEvent(const GnssMeasurementsNotification& measurements,
|
||||||
|
int msInWeek);
|
||||||
|
virtual void reportSvMeasurementEvent(GnssSvMeasurementSet &svMeasurementSet);
|
||||||
|
virtual void reportSvPolynomialEvent(GnssSvPolynomial &svPolynomial);
|
||||||
|
|
||||||
|
virtual bool requestATL(int connHandle, LocAGpsType agps_type);
|
||||||
|
virtual bool releaseATL(int connHandle);
|
||||||
|
virtual bool requestSuplES(int connHandle);
|
||||||
|
virtual bool reportDataCallOpened();
|
||||||
|
virtual bool reportDataCallClosed();
|
||||||
|
|
||||||
|
/* ======== UTILITIES ================================================================= */
|
||||||
|
void reportPosition(const UlpLocation &ulpLocation,
|
||||||
|
const GpsLocationExtended &locationExtended,
|
||||||
|
enum loc_sess_status status,
|
||||||
|
LocPosTechMask techMask);
|
||||||
|
void reportSv(GnssSvNotification& svNotify);
|
||||||
|
void reportNmea(const char* nmea, size_t length);
|
||||||
|
bool requestNiNotify(const GnssNiNotification& notify, const void* data);
|
||||||
|
void reportGnssMeasurementData(const GnssMeasurementsNotification& measurements);
|
||||||
|
|
||||||
|
/*======== GNSSDEBUG ================================================================*/
|
||||||
|
bool getDebugReport(GnssDebugReport& report);
|
||||||
|
/* get AGC information from system status and fill it */
|
||||||
|
void getAgcInformation(GnssMeasurementsNotification& measurements, int msInWeek);
|
||||||
|
|
||||||
|
/*==== SYSTEM STATUS ================================================================*/
|
||||||
|
inline SystemStatus* getSystemStatus(void) { return mSystemStatus; }
|
||||||
|
std::string& getServerUrl(void) { return mServerUrl; }
|
||||||
|
void setServerUrl(const char* server) { mServerUrl.assign(server); }
|
||||||
|
|
||||||
|
/*==== CONVERSION ===================================================================*/
|
||||||
|
static uint32_t convertGpsLock(const GnssConfigGpsLock gpsLock);
|
||||||
|
static GnssConfigGpsLock convertGpsLock(const uint32_t gpsLock);
|
||||||
|
static uint32_t convertSuplVersion(const GnssConfigSuplVersion suplVersion);
|
||||||
|
static GnssConfigSuplVersion convertSuplVersion(const uint32_t suplVersion);
|
||||||
|
static uint32_t convertLppProfile(const GnssConfigLppProfile lppProfile);
|
||||||
|
static GnssConfigLppProfile convertLppProfile(const uint32_t lppProfile);
|
||||||
|
static uint32_t convertEP4ES(const GnssConfigEmergencyPdnForEmergencySupl);
|
||||||
|
static uint32_t convertSuplEs(const GnssConfigSuplEmergencyServices suplEmergencyServices);
|
||||||
|
static uint32_t convertLppeCp(const GnssConfigLppeControlPlaneMask lppeControlPlaneMask);
|
||||||
|
static GnssConfigLppeControlPlaneMask convertLppeCp(const uint32_t lppeControlPlaneMask);
|
||||||
|
static uint32_t convertLppeUp(const GnssConfigLppeUserPlaneMask lppeUserPlaneMask);
|
||||||
|
static GnssConfigLppeUserPlaneMask convertLppeUp(const uint32_t lppeUserPlaneMask);
|
||||||
|
static uint32_t convertAGloProt(const GnssConfigAGlonassPositionProtocolMask);
|
||||||
|
static uint32_t convertSuplMode(const GnssConfigSuplModeMask suplModeMask);
|
||||||
|
static void convertSatelliteInfo(std::vector<GnssDebugSatelliteInfo>& out,
|
||||||
|
const GnssSvType& in_constellation,
|
||||||
|
const SystemStatusReports& in);
|
||||||
|
|
||||||
|
void injectLocationCommand(double latitude, double longitude, float accuracy);
|
||||||
|
void injectTimeCommand(int64_t time, int64_t timeReference, int32_t uncertainty);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //GNSS_ADAPTER_H
|
99
gps/gnss/Makefile.am
Normal file
99
gps/gnss/Makefile.am
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
AM_CFLAGS = \
|
||||||
|
$(LOCPLA_CFLAGS) \
|
||||||
|
$(LOCHAL_CFLAGS) \
|
||||||
|
-I./ \
|
||||||
|
-I../utils \
|
||||||
|
-I../core \
|
||||||
|
-I../location \
|
||||||
|
-std=c++11
|
||||||
|
|
||||||
|
libgnss_la_SOURCES = \
|
||||||
|
location_gnss.cpp \
|
||||||
|
GnssAdapter.cpp \
|
||||||
|
Agps.cpp
|
||||||
|
|
||||||
|
if USE_GLIB
|
||||||
|
libgnss_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@
|
||||||
|
libgnss_la_LDFLAGS = -lstdc++ -lpthread @GLIB_LIBS@ -shared -avoid-version
|
||||||
|
libgnss_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@
|
||||||
|
else
|
||||||
|
libgnss_la_CFLAGS = $(AM_CFLAGS)
|
||||||
|
libgnss_la_LDFLAGS = -lpthread -shared -version-info 1:0:0
|
||||||
|
libgnss_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
libgnss_la_LIBADD = -lstdc++ $(LOCPLA_LIBS) $(LOCHAL_LIBS)
|
||||||
|
|
||||||
|
|
||||||
|
#Create and Install libraries
|
||||||
|
#lib_LTLIBRARIES = libgnss.la
|
||||||
|
|
||||||
|
#library_includedir = $(pkgincludedir)
|
||||||
|
#pkgconfigdir = $(libdir)/pkgconfig
|
||||||
|
#pkgconfig_DATA = location-api.pc
|
||||||
|
#EXTRA_DIST = $(pkgconfig_DATA)
|
||||||
|
|
||||||
|
|
||||||
|
libloc_ds_api_CFLAGS = \
|
||||||
|
$(QMIF_CFLAGS) \
|
||||||
|
$(QMI_CFLAGS) \
|
||||||
|
$(DATA_CFLAGS) \
|
||||||
|
$(GPSUTILS_CFLAGS) \
|
||||||
|
-I$(WORKSPACE)/qcom-opensource/location/loc_api/ds_api
|
||||||
|
|
||||||
|
libloc_ds_api_la_SOURCES = \
|
||||||
|
$(WORKSPACE)/qcom-opensource/location/loc_api/ds_api/ds_client.c
|
||||||
|
|
||||||
|
if USE_GLIB
|
||||||
|
libloc_ds_api_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(libloc_ds_api_CFLAGS) @GLIB_CFLAGS@
|
||||||
|
libloc_ds_api_la_LDFLAGS = -lstdc++ -Wl,-z,defs -lpthread @GLIB_LIBS@ -shared -version-info 1:0:0
|
||||||
|
libloc_ds_api_la_LDFLAGS += -Wl,--export-dynamic
|
||||||
|
libloc_ds_api_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(libloc_ds_api_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@
|
||||||
|
else
|
||||||
|
libloc_ds_api_la_CFLAGS = $(AM_CFLAGS) $(libloc_ds_api_CFLAGS)
|
||||||
|
libloc_ds_api_la_LDFLAGS = -lstdc++ -Wl,-z,defs -lpthread -Wl,--export-dynamic -shared -version-info 1:0:0
|
||||||
|
libloc_ds_api_la_LDFLAGS += -Wl,--export-dynamic
|
||||||
|
libloc_ds_api_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS) $(libloc_ds_api_CFLAGS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
libloc_ds_api_la_LIBADD = -lstdc++ $(QMIF_LIBS) -lqmiservices -ldsi_netctrl $(GPSUTILS_LIBS) $(LOCPLA_LIBS)
|
||||||
|
|
||||||
|
libloc_api_v02_CFLAGS = \
|
||||||
|
$(QMIF_CFLAGS) \
|
||||||
|
$(GPSUTILS_CFLAGS) \
|
||||||
|
-I$(WORKSPACE)/qcom-opensource/location/loc_api/ds_api \
|
||||||
|
-I$(WORKSPACE)/qcom-opensource/location/loc_api/loc_api_v02
|
||||||
|
|
||||||
|
libloc_api_v02_la_SOURCES = \
|
||||||
|
$(WORKSPACE)/qcom-opensource/location/loc_api/loc_api_v02/LocApiV02.cpp \
|
||||||
|
$(WORKSPACE)/qcom-opensource/location/loc_api/loc_api_v02/loc_api_v02_log.c \
|
||||||
|
$(WORKSPACE)/qcom-opensource/location/loc_api/loc_api_v02/loc_api_v02_client.c \
|
||||||
|
$(WORKSPACE)/qcom-opensource/location/loc_api/loc_api_v02/loc_api_sync_req.c \
|
||||||
|
$(WORKSPACE)/qcom-opensource/location/loc_api/loc_api_v02/location_service_v02.c
|
||||||
|
|
||||||
|
if USE_GLIB
|
||||||
|
libloc_api_v02_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(libloc_api_v02_CFLAGS) @GLIB_CFLAGS@
|
||||||
|
libloc_api_v02_la_LDFLAGS = -lstdc++ -g -Wl,-z,defs -lpthread @GLIB_LIBS@ -shared -version-info 1:0:0
|
||||||
|
libloc_api_v02_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(libloc_api_v02_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@
|
||||||
|
else
|
||||||
|
libloc_api_v02_la_CFLAGS = $(AM_CFLAGS) $(libloc_api_v02_CFLAGS)
|
||||||
|
libloc_api_v02_la_LDFLAGS = -lstdc++ -Wl,-z,defs -lpthread -shared -version-info 1:0:0
|
||||||
|
libloc_api_v02_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS) $(libloc_api_v02_CFLAGS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
libloc_api_v02_la_CXXFLAGS = -std=c++0x
|
||||||
|
libloc_api_v02_la_LIBADD = -lstdc++ -lqmi_cci -lqmi_common_so $(QMIF_LIBS) $(GPSUTILS_LIBS) $(LOCPLA_LIBS) ../core/libloc_core.la libloc_ds_api.la
|
||||||
|
|
||||||
|
library_include_HEADERS = \
|
||||||
|
$(WORKSPACE)/qcom-opensource/location/loc_api/ds_api/ds_client.h \
|
||||||
|
$(WORKSPACE)/qcom-opensource/location/loc_api/loc_api_v02/location_service_v02.h \
|
||||||
|
$(WORKSPACE)/qcom-opensource/location/loc_api/loc_api_v02/loc_api_v02_log.h \
|
||||||
|
$(WORKSPACE)/qcom-opensource/location/loc_api/loc_api_v02/loc_api_v02_client.h \
|
||||||
|
$(WORKSPACE)/qcom-opensource/location/loc_api/loc_api_v02/loc_api_sync_req.h \
|
||||||
|
$(WORKSPACE)/qcom-opensource/location/loc_api/loc_api_v02/LocApiV02.h \
|
||||||
|
$(WORKSPACE)/qcom-opensource/location/loc_api/loc_api_v02/loc_util_log.h
|
||||||
|
|
||||||
|
library_includedir = $(pkgincludedir)
|
||||||
|
|
||||||
|
#Create and Install libraries
|
||||||
|
lib_LTLIBRARIES = libgnss.la libloc_ds_api.la libloc_api_v02.la
|
237
gps/gnss/XtraSystemStatusObserver.cpp
Normal file
237
gps/gnss/XtraSystemStatusObserver.cpp
Normal file
|
@ -0,0 +1,237 @@
|
||||||
|
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define LOG_TAG "LocSvc_XtraSystemStatusObs"
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <cutils/properties.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <string>
|
||||||
|
#include <loc_log.h>
|
||||||
|
#include <loc_nmea.h>
|
||||||
|
#include <SystemStatus.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <sstream>
|
||||||
|
#include <XtraSystemStatusObserver.h>
|
||||||
|
#include <LocAdapterBase.h>
|
||||||
|
#include <DataItemId.h>
|
||||||
|
#include <DataItemsFactoryProxy.h>
|
||||||
|
#include <DataItemConcreteTypesBase.h>
|
||||||
|
|
||||||
|
using namespace loc_core;
|
||||||
|
|
||||||
|
#define XTRA_HAL_SOCKET_NAME "/data/vendor/location/xtra/socket_hal_xtra"
|
||||||
|
|
||||||
|
bool XtraSystemStatusObserver::updateLockStatus(uint32_t lock) {
|
||||||
|
stringstream ss;
|
||||||
|
ss << "gpslock";
|
||||||
|
ss << " " << lock;
|
||||||
|
ss << "\n"; // append seperator
|
||||||
|
return ( sendEvent(ss) );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XtraSystemStatusObserver::updateConnectionStatus(bool connected, uint32_t type) {
|
||||||
|
stringstream ss;
|
||||||
|
ss << "connection";
|
||||||
|
ss << " " << (connected ? "1" : "0");
|
||||||
|
ss << " " << (int)type;
|
||||||
|
ss << "\n"; // append seperator
|
||||||
|
return ( sendEvent(ss) );
|
||||||
|
}
|
||||||
|
bool XtraSystemStatusObserver::updateTac(const string& tac) {
|
||||||
|
stringstream ss;
|
||||||
|
ss << "tac";
|
||||||
|
ss << " " << tac.c_str();
|
||||||
|
ss << "\n"; // append seperator
|
||||||
|
return ( sendEvent(ss) );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XtraSystemStatusObserver::updateMccMnc(const string& mccmnc) {
|
||||||
|
stringstream ss;
|
||||||
|
ss << "mncmcc";
|
||||||
|
ss << " " << mccmnc.c_str();
|
||||||
|
ss << "\n"; // append seperator
|
||||||
|
return ( sendEvent(ss) );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XtraSystemStatusObserver::sendEvent(const stringstream& event) {
|
||||||
|
int socketFd = createSocket();
|
||||||
|
if (socketFd < 0) {
|
||||||
|
LOC_LOGe("XTRA unreachable. sending failed.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const string& data = event.str();
|
||||||
|
int remain = data.length();
|
||||||
|
ssize_t sent = 0;
|
||||||
|
while (remain > 0 &&
|
||||||
|
(sent = ::send(socketFd, data.c_str() + (data.length() - remain),
|
||||||
|
remain, MSG_NOSIGNAL)) > 0) {
|
||||||
|
remain -= sent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sent < 0) {
|
||||||
|
LOC_LOGe("sending error. reason:%s", strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
closeSocket(socketFd);
|
||||||
|
|
||||||
|
return (remain == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int XtraSystemStatusObserver::createSocket() {
|
||||||
|
int socketFd = -1;
|
||||||
|
|
||||||
|
if ((socketFd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
|
||||||
|
LOC_LOGe("create socket error. reason:%s", strerror(errno));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
const char* socketPath = XTRA_HAL_SOCKET_NAME ;
|
||||||
|
struct sockaddr_un addr = { .sun_family = AF_UNIX };
|
||||||
|
snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", socketPath);
|
||||||
|
|
||||||
|
if (::connect(socketFd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
|
||||||
|
LOC_LOGe("cannot connect to XTRA. reason:%s", strerror(errno));
|
||||||
|
if (::close(socketFd)) {
|
||||||
|
LOC_LOGe("close socket error. reason:%s", strerror(errno));
|
||||||
|
}
|
||||||
|
socketFd = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return socketFd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XtraSystemStatusObserver::closeSocket(const int socketFd) {
|
||||||
|
if (socketFd >= 0) {
|
||||||
|
if(::close(socketFd)) {
|
||||||
|
LOC_LOGe("close socket error. reason:%s", strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void XtraSystemStatusObserver::subscribe(bool yes)
|
||||||
|
{
|
||||||
|
// Subscription data list
|
||||||
|
list<DataItemId> subItemIdList;
|
||||||
|
subItemIdList.push_back(NETWORKINFO_DATA_ITEM_ID);
|
||||||
|
subItemIdList.push_back(MCCMNC_DATA_ITEM_ID);
|
||||||
|
|
||||||
|
if (yes) {
|
||||||
|
mSystemStatusObsrvr->subscribe(subItemIdList, this);
|
||||||
|
|
||||||
|
list<DataItemId> reqItemIdList;
|
||||||
|
reqItemIdList.push_back(TAC_DATA_ITEM_ID);
|
||||||
|
|
||||||
|
mSystemStatusObsrvr->requestData(reqItemIdList, this);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
mSystemStatusObsrvr->unsubscribe(subItemIdList, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IDataItemObserver overrides
|
||||||
|
void XtraSystemStatusObserver::getName(string& name)
|
||||||
|
{
|
||||||
|
name = "XtraSystemStatusObserver";
|
||||||
|
}
|
||||||
|
|
||||||
|
void XtraSystemStatusObserver::notify(const list<IDataItemCore*>& dlist)
|
||||||
|
{
|
||||||
|
struct handleOsObserverUpdateMsg : public LocMsg {
|
||||||
|
XtraSystemStatusObserver* mXtraSysStatObj;
|
||||||
|
list <IDataItemCore*> mDataItemList;
|
||||||
|
|
||||||
|
inline handleOsObserverUpdateMsg(XtraSystemStatusObserver* xtraSysStatObs,
|
||||||
|
const list<IDataItemCore*>& dataItemList) :
|
||||||
|
mXtraSysStatObj(xtraSysStatObs) {
|
||||||
|
for (auto eachItem : dataItemList) {
|
||||||
|
IDataItemCore* dataitem = DataItemsFactoryProxy::createNewDataItem(
|
||||||
|
eachItem->getId());
|
||||||
|
if (NULL == dataitem) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Copy the contents of the data item
|
||||||
|
dataitem->copy(eachItem);
|
||||||
|
|
||||||
|
mDataItemList.push_back(dataitem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ~handleOsObserverUpdateMsg() {
|
||||||
|
for (auto each : mDataItemList) {
|
||||||
|
delete each;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void proc() const {
|
||||||
|
for (auto each : mDataItemList) {
|
||||||
|
switch (each->getId())
|
||||||
|
{
|
||||||
|
case NETWORKINFO_DATA_ITEM_ID:
|
||||||
|
{
|
||||||
|
NetworkInfoDataItemBase* networkInfo =
|
||||||
|
static_cast<NetworkInfoDataItemBase*>(each);
|
||||||
|
mXtraSysStatObj->updateConnectionStatus(networkInfo->mConnected,
|
||||||
|
networkInfo->mType);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAC_DATA_ITEM_ID:
|
||||||
|
{
|
||||||
|
TacDataItemBase* tac =
|
||||||
|
static_cast<TacDataItemBase*>(each);
|
||||||
|
mXtraSysStatObj->updateTac(tac->mValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MCCMNC_DATA_ITEM_ID:
|
||||||
|
{
|
||||||
|
MccmncDataItemBase* mccmnc =
|
||||||
|
static_cast<MccmncDataItemBase*>(each);
|
||||||
|
mXtraSysStatObj->updateMccMnc(mccmnc->mValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
mMsgTask->sendMsg(new (nothrow) handleOsObserverUpdateMsg(this, dlist));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
71
gps/gnss/XtraSystemStatusObserver.h
Normal file
71
gps/gnss/XtraSystemStatusObserver.h
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef XTRA_SYSTEM_STATUS_OBS_H
|
||||||
|
#define XTRA_SYSTEM_STATUS_OBS_H
|
||||||
|
|
||||||
|
#include <cinttypes>
|
||||||
|
#include <MsgTask.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using loc_core::IOsObserver;
|
||||||
|
using loc_core::IDataItemObserver;
|
||||||
|
using loc_core::IDataItemCore;
|
||||||
|
|
||||||
|
|
||||||
|
class XtraSystemStatusObserver : public IDataItemObserver {
|
||||||
|
public :
|
||||||
|
// constructor & destructor
|
||||||
|
inline XtraSystemStatusObserver(IOsObserver* sysStatObs, const MsgTask* msgTask):
|
||||||
|
mSystemStatusObsrvr(sysStatObs), mMsgTask(msgTask) {
|
||||||
|
subscribe(true);
|
||||||
|
}
|
||||||
|
inline XtraSystemStatusObserver() {};
|
||||||
|
inline virtual ~XtraSystemStatusObserver() { subscribe(false); }
|
||||||
|
|
||||||
|
// IDataItemObserver overrides
|
||||||
|
inline virtual void getName(string& name);
|
||||||
|
virtual void notify(const list<IDataItemCore*>& dlist);
|
||||||
|
|
||||||
|
bool updateLockStatus(uint32_t lock);
|
||||||
|
bool updateConnectionStatus(bool connected, uint32_t type);
|
||||||
|
bool updateTac(const string& tac);
|
||||||
|
bool updateMccMnc(const string& mccmnc);
|
||||||
|
inline const MsgTask* getMsgTask() { return mMsgTask; }
|
||||||
|
void subscribe(bool yes);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int createSocket();
|
||||||
|
void closeSocket(const int32_t socketFd);
|
||||||
|
bool sendEvent(const stringstream& event);
|
||||||
|
IOsObserver* mSystemStatusObsrvr;
|
||||||
|
const MsgTask* mMsgTask;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
258
gps/gnss/location_gnss.cpp
Normal file
258
gps/gnss/location_gnss.cpp
Normal file
|
@ -0,0 +1,258 @@
|
||||||
|
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "GnssAdapter.h"
|
||||||
|
#include "location_interface.h"
|
||||||
|
|
||||||
|
static GnssAdapter* gGnssAdapter = NULL;
|
||||||
|
|
||||||
|
static void initialize();
|
||||||
|
static void deinitialize();
|
||||||
|
|
||||||
|
static void addClient(LocationAPI* client, const LocationCallbacks& callbacks);
|
||||||
|
static void removeClient(LocationAPI* client);
|
||||||
|
static void requestCapabilities(LocationAPI* client);
|
||||||
|
|
||||||
|
static uint32_t startTracking(LocationAPI* client, LocationOptions& options);
|
||||||
|
static void updateTrackingOptions(LocationAPI* client, uint32_t id, LocationOptions& options);
|
||||||
|
static void stopTracking(LocationAPI* client, uint32_t id);
|
||||||
|
|
||||||
|
static void gnssNiResponse(LocationAPI* client, uint32_t id, GnssNiResponse response);
|
||||||
|
static uint32_t gnssDeleteAidingData(GnssAidingData& data);
|
||||||
|
|
||||||
|
static void setControlCallbacks(LocationControlCallbacks& controlCallbacks);
|
||||||
|
static uint32_t enable(LocationTechnologyType techType);
|
||||||
|
static void disable(uint32_t id);
|
||||||
|
static uint32_t* gnssUpdateConfig(GnssConfig config);
|
||||||
|
|
||||||
|
static void injectLocation(double latitude, double longitude, float accuracy);
|
||||||
|
static void injectTime(int64_t time, int64_t timeReference, int32_t uncertainty);
|
||||||
|
|
||||||
|
static void agpsInit(const AgpsCbInfo& cbInfo);
|
||||||
|
static void agpsDataConnOpen(AGpsExtType agpsType, const char* apnName, int apnLen, int ipType);
|
||||||
|
static void agpsDataConnClosed(AGpsExtType agpsType);
|
||||||
|
static void agpsDataConnFailed(AGpsExtType agpsType);
|
||||||
|
static void getDebugReport(GnssDebugReport& report);
|
||||||
|
static void updateConnectionStatus(bool connected, uint8_t type);
|
||||||
|
|
||||||
|
static const GnssInterface gGnssInterface = {
|
||||||
|
sizeof(GnssInterface),
|
||||||
|
initialize,
|
||||||
|
deinitialize,
|
||||||
|
addClient,
|
||||||
|
removeClient,
|
||||||
|
requestCapabilities,
|
||||||
|
startTracking,
|
||||||
|
updateTrackingOptions,
|
||||||
|
stopTracking,
|
||||||
|
gnssNiResponse,
|
||||||
|
setControlCallbacks,
|
||||||
|
enable,
|
||||||
|
disable,
|
||||||
|
gnssUpdateConfig,
|
||||||
|
gnssDeleteAidingData,
|
||||||
|
injectLocation,
|
||||||
|
injectTime,
|
||||||
|
agpsInit,
|
||||||
|
agpsDataConnOpen,
|
||||||
|
agpsDataConnClosed,
|
||||||
|
agpsDataConnFailed,
|
||||||
|
getDebugReport,
|
||||||
|
updateConnectionStatus,
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef DEBUG_X86
|
||||||
|
extern "C" const GnssInterface* getGnssInterface()
|
||||||
|
#else
|
||||||
|
const GnssInterface* getGnssInterface()
|
||||||
|
#endif // DEBUG_X86
|
||||||
|
{
|
||||||
|
return &gGnssInterface;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void initialize()
|
||||||
|
{
|
||||||
|
if (NULL == gGnssAdapter) {
|
||||||
|
gGnssAdapter = new GnssAdapter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deinitialize()
|
||||||
|
{
|
||||||
|
if (NULL != gGnssAdapter) {
|
||||||
|
delete gGnssAdapter;
|
||||||
|
gGnssAdapter = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addClient(LocationAPI* client, const LocationCallbacks& callbacks)
|
||||||
|
{
|
||||||
|
if (NULL != gGnssAdapter) {
|
||||||
|
gGnssAdapter->addClientCommand(client, callbacks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void removeClient(LocationAPI* client)
|
||||||
|
{
|
||||||
|
if (NULL != gGnssAdapter) {
|
||||||
|
gGnssAdapter->removeClientCommand(client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void requestCapabilities(LocationAPI* client)
|
||||||
|
{
|
||||||
|
if (NULL != gGnssAdapter) {
|
||||||
|
gGnssAdapter->requestCapabilitiesCommand(client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t startTracking(LocationAPI* client, LocationOptions& options)
|
||||||
|
{
|
||||||
|
if (NULL != gGnssAdapter) {
|
||||||
|
return gGnssAdapter->startTrackingCommand(client, options);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updateTrackingOptions(LocationAPI* client, uint32_t id, LocationOptions& options)
|
||||||
|
{
|
||||||
|
if (NULL != gGnssAdapter) {
|
||||||
|
gGnssAdapter->updateTrackingOptionsCommand(client, id, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void stopTracking(LocationAPI* client, uint32_t id)
|
||||||
|
{
|
||||||
|
if (NULL != gGnssAdapter) {
|
||||||
|
gGnssAdapter->stopTrackingCommand(client, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gnssNiResponse(LocationAPI* client, uint32_t id, GnssNiResponse response)
|
||||||
|
{
|
||||||
|
if (NULL != gGnssAdapter) {
|
||||||
|
gGnssAdapter->gnssNiResponseCommand(client, id, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setControlCallbacks(LocationControlCallbacks& controlCallbacks)
|
||||||
|
{
|
||||||
|
if (NULL != gGnssAdapter) {
|
||||||
|
return gGnssAdapter->setControlCallbacksCommand(controlCallbacks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t enable(LocationTechnologyType techType)
|
||||||
|
{
|
||||||
|
if (NULL != gGnssAdapter) {
|
||||||
|
return gGnssAdapter->enableCommand(techType);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void disable(uint32_t id)
|
||||||
|
{
|
||||||
|
if (NULL != gGnssAdapter) {
|
||||||
|
return gGnssAdapter->disableCommand(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t* gnssUpdateConfig(GnssConfig config)
|
||||||
|
{
|
||||||
|
if (NULL != gGnssAdapter) {
|
||||||
|
return gGnssAdapter->gnssUpdateConfigCommand(config);
|
||||||
|
} else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t gnssDeleteAidingData(GnssAidingData& data)
|
||||||
|
{
|
||||||
|
if (NULL != gGnssAdapter) {
|
||||||
|
return gGnssAdapter->gnssDeleteAidingDataCommand(data);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void injectLocation(double latitude, double longitude, float accuracy)
|
||||||
|
{
|
||||||
|
if (NULL != gGnssAdapter) {
|
||||||
|
gGnssAdapter->injectLocationCommand(latitude, longitude, accuracy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void injectTime(int64_t time, int64_t timeReference, int32_t uncertainty)
|
||||||
|
{
|
||||||
|
if (NULL != gGnssAdapter) {
|
||||||
|
gGnssAdapter->injectTimeCommand(time, timeReference, uncertainty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void agpsInit(const AgpsCbInfo& cbInfo) {
|
||||||
|
|
||||||
|
if (NULL != gGnssAdapter) {
|
||||||
|
gGnssAdapter->initAgpsCommand(cbInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void agpsDataConnOpen(
|
||||||
|
AGpsExtType agpsType, const char* apnName, int apnLen, int ipType) {
|
||||||
|
|
||||||
|
if (NULL != gGnssAdapter) {
|
||||||
|
gGnssAdapter->dataConnOpenCommand(
|
||||||
|
agpsType, apnName, apnLen, (AGpsBearerType)ipType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void agpsDataConnClosed(AGpsExtType agpsType) {
|
||||||
|
|
||||||
|
if (NULL != gGnssAdapter) {
|
||||||
|
gGnssAdapter->dataConnClosedCommand(agpsType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void agpsDataConnFailed(AGpsExtType agpsType) {
|
||||||
|
|
||||||
|
if (NULL != gGnssAdapter) {
|
||||||
|
gGnssAdapter->dataConnFailedCommand(agpsType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void getDebugReport(GnssDebugReport& report) {
|
||||||
|
|
||||||
|
if (NULL != gGnssAdapter) {
|
||||||
|
gGnssAdapter->getDebugReport(report);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updateConnectionStatus(bool connected, uint8_t type) {
|
||||||
|
if (NULL != gGnssAdapter) {
|
||||||
|
gGnssAdapter->getSystemStatus()->eventConnectionStatus(connected, type);
|
||||||
|
}
|
||||||
|
}
|
10
gps/loc-hal.pc.in
Normal file
10
gps/loc-hal.pc.in
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
prefix=@prefix@
|
||||||
|
exec_prefix=@exec_prefix@
|
||||||
|
libdir=@libdir@
|
||||||
|
includedir=@includedir@
|
||||||
|
|
||||||
|
Name: loc-hal
|
||||||
|
Description: QTI GPS Loc HAL
|
||||||
|
Version: @VERSION
|
||||||
|
Libs: -L${libdir} -lloc_core -llocation_api -lgnss -lloc_ds_api -lloc_api_v02
|
||||||
|
Cflags: -I${includedir} -I${includedir}/loc-hal -I${includedir}/loc-hal/location -I${includedir}/loc-hal/gnss -I${includedir}/loc-hal/core
|
42
gps/location/Android.mk
Normal file
42
gps/location/Android.mk
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)
|
||||||
|
ifneq ($(BUILD_TINY_ANDROID),true)
|
||||||
|
|
||||||
|
LOCAL_PATH := $(call my-dir)
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE := liblocation_api
|
||||||
|
LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib
|
||||||
|
LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64
|
||||||
|
LOCAL_MODULE_TAGS := optional
|
||||||
|
|
||||||
|
LOCAL_SHARED_LIBRARIES := \
|
||||||
|
libutils \
|
||||||
|
libcutils \
|
||||||
|
libgps.utils \
|
||||||
|
libdl \
|
||||||
|
liblog
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES += \
|
||||||
|
LocationAPI.cpp \
|
||||||
|
LocationAPIClientBase.cpp
|
||||||
|
|
||||||
|
LOCAL_CFLAGS += \
|
||||||
|
-fno-short-enums
|
||||||
|
|
||||||
|
LOCAL_HEADER_LIBRARIES := \
|
||||||
|
libloc_pla_headers \
|
||||||
|
libgps.utils_headers
|
||||||
|
|
||||||
|
LOCAL_PRELINK_MODULE := false
|
||||||
|
|
||||||
|
LOCAL_CFLAGS += $(GNSS_CFLAGS)
|
||||||
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
LOCAL_MODULE := liblocation_api_headers
|
||||||
|
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
|
||||||
|
include $(BUILD_HEADER_LIBRARY)
|
||||||
|
|
||||||
|
endif # not BUILD_TINY_ANDROID
|
||||||
|
endif # BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE
|
644
gps/location/LocationAPI.cpp
Normal file
644
gps/location/LocationAPI.cpp
Normal file
|
@ -0,0 +1,644 @@
|
||||||
|
/* Copyright (c) 2017 The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#define LOG_TAG "LocSvc_LocationAPI"
|
||||||
|
|
||||||
|
#include <location_interface.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <platform_lib_log_util.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
typedef void* (getLocationInterface)();
|
||||||
|
typedef std::map<LocationAPI*, LocationCallbacks> LocationClientMap;
|
||||||
|
typedef struct {
|
||||||
|
LocationClientMap clientData;
|
||||||
|
LocationControlAPI* controlAPI;
|
||||||
|
LocationControlCallbacks controlCallbacks;
|
||||||
|
GnssInterface* gnssInterface;
|
||||||
|
GeofenceInterface* geofenceInterface;
|
||||||
|
FlpInterface* flpInterface;
|
||||||
|
} LocationAPIData;
|
||||||
|
static LocationAPIData gData = {};
|
||||||
|
static pthread_mutex_t gDataMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
static bool gGnssLoadFailed = false;
|
||||||
|
static bool gFlpLoadFailed = false;
|
||||||
|
static bool gGeofenceLoadFailed = false;
|
||||||
|
|
||||||
|
static bool needsGnssTrackingInfo(LocationCallbacks& locationCallbacks)
|
||||||
|
{
|
||||||
|
return (locationCallbacks.gnssLocationInfoCb != nullptr ||
|
||||||
|
locationCallbacks.gnssSvCb != nullptr ||
|
||||||
|
locationCallbacks.gnssNmeaCb != nullptr ||
|
||||||
|
locationCallbacks.gnssMeasurementsCb != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isGnssClient(LocationCallbacks& locationCallbacks)
|
||||||
|
{
|
||||||
|
return (locationCallbacks.gnssNiCb != nullptr ||
|
||||||
|
locationCallbacks.trackingCb != nullptr ||
|
||||||
|
locationCallbacks.gnssMeasurementsCb != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isFlpClient(LocationCallbacks& locationCallbacks)
|
||||||
|
{
|
||||||
|
return (locationCallbacks.trackingCb != nullptr ||
|
||||||
|
locationCallbacks.batchingCb != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isGeofenceClient(LocationCallbacks& locationCallbacks)
|
||||||
|
{
|
||||||
|
return (locationCallbacks.geofenceBreachCb != nullptr ||
|
||||||
|
locationCallbacks.geofenceStatusCb != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void* loadLocationInterface(const char* library, const char* name) {
|
||||||
|
LOC_LOGD("%s]: loading %s::%s ...", __func__, library, name);
|
||||||
|
if (NULL == library || NULL == name) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
getLocationInterface* getter = NULL;
|
||||||
|
const char *error = NULL;
|
||||||
|
dlerror();
|
||||||
|
void *handle = dlopen(library, RTLD_NOW);
|
||||||
|
if (NULL == handle || (error = dlerror()) != NULL) {
|
||||||
|
LOC_LOGW("dlopen for %s failed, error = %s", library, error);
|
||||||
|
} else {
|
||||||
|
getter = (getLocationInterface*)dlsym(handle, name);
|
||||||
|
if ((error = dlerror()) != NULL) {
|
||||||
|
LOC_LOGW("dlsym for %s::%s failed, error = %s", library, name, error);
|
||||||
|
getter = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NULL == getter) {
|
||||||
|
return (void*)getter;
|
||||||
|
} else {
|
||||||
|
return (*getter)();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LocationAPI*
|
||||||
|
LocationAPI::createInstance(LocationCallbacks& locationCallbacks)
|
||||||
|
{
|
||||||
|
if (nullptr == locationCallbacks.capabilitiesCb ||
|
||||||
|
nullptr == locationCallbacks.responseCb ||
|
||||||
|
nullptr == locationCallbacks.collectiveResponseCb) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocationAPI* newLocationAPI = new LocationAPI();
|
||||||
|
bool requestedCapabilities = false;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&gDataMutex);
|
||||||
|
|
||||||
|
if (isGnssClient(locationCallbacks)) {
|
||||||
|
if (NULL == gData.gnssInterface && !gGnssLoadFailed) {
|
||||||
|
gData.gnssInterface =
|
||||||
|
(GnssInterface*)loadLocationInterface("libgnss.so", "getGnssInterface");
|
||||||
|
if (NULL == gData.gnssInterface) {
|
||||||
|
gGnssLoadFailed = true;
|
||||||
|
LOC_LOGW("%s:%d]: No gnss interface available", __func__, __LINE__);
|
||||||
|
} else {
|
||||||
|
gData.gnssInterface->initialize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (NULL != gData.gnssInterface) {
|
||||||
|
gData.gnssInterface->addClient(newLocationAPI, locationCallbacks);
|
||||||
|
if (!requestedCapabilities) {
|
||||||
|
gData.gnssInterface->requestCapabilities(newLocationAPI);
|
||||||
|
requestedCapabilities = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isFlpClient(locationCallbacks)) {
|
||||||
|
if (NULL == gData.flpInterface && !gFlpLoadFailed) {
|
||||||
|
gData.flpInterface =
|
||||||
|
(FlpInterface*)loadLocationInterface("libflp.so", "getFlpInterface");
|
||||||
|
if (NULL == gData.flpInterface) {
|
||||||
|
gFlpLoadFailed = true;
|
||||||
|
LOC_LOGW("%s:%d]: No flp interface available", __func__, __LINE__);
|
||||||
|
} else {
|
||||||
|
gData.flpInterface->initialize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (NULL != gData.flpInterface) {
|
||||||
|
gData.flpInterface->addClient(newLocationAPI, locationCallbacks);
|
||||||
|
if (!requestedCapabilities) {
|
||||||
|
gData.flpInterface->requestCapabilities(newLocationAPI);
|
||||||
|
requestedCapabilities = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isGeofenceClient(locationCallbacks)) {
|
||||||
|
if (NULL == gData.geofenceInterface && !gGeofenceLoadFailed) {
|
||||||
|
gData.geofenceInterface =
|
||||||
|
(GeofenceInterface*)loadLocationInterface("libgeofence.so", "getGeofenceInterface");
|
||||||
|
if (NULL == gData.geofenceInterface) {
|
||||||
|
gGeofenceLoadFailed = true;
|
||||||
|
LOC_LOGW("%s:%d]: No geofence interface available", __func__, __LINE__);
|
||||||
|
} else {
|
||||||
|
gData.geofenceInterface->initialize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (NULL != gData.geofenceInterface) {
|
||||||
|
gData.geofenceInterface->addClient(newLocationAPI, locationCallbacks);
|
||||||
|
if (!requestedCapabilities) {
|
||||||
|
gData.geofenceInterface->requestCapabilities(newLocationAPI);
|
||||||
|
requestedCapabilities = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gData.clientData[newLocationAPI] = locationCallbacks;
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&gDataMutex);
|
||||||
|
|
||||||
|
return newLocationAPI;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LocationAPI::destroy()
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocationAPI::LocationAPI()
|
||||||
|
{
|
||||||
|
LOC_LOGD("LOCATION API CONSTRUCTOR");
|
||||||
|
}
|
||||||
|
|
||||||
|
LocationAPI::~LocationAPI()
|
||||||
|
{
|
||||||
|
LOC_LOGD("LOCATION API DESTRUCTOR");
|
||||||
|
pthread_mutex_lock(&gDataMutex);
|
||||||
|
|
||||||
|
auto it = gData.clientData.find(this);
|
||||||
|
if (it != gData.clientData.end()) {
|
||||||
|
if (isGnssClient(it->second) && NULL != gData.gnssInterface) {
|
||||||
|
gData.gnssInterface->removeClient(it->first);
|
||||||
|
}
|
||||||
|
if (isFlpClient(it->second) && NULL != gData.flpInterface) {
|
||||||
|
gData.flpInterface->removeClient(it->first);
|
||||||
|
}
|
||||||
|
if (isGeofenceClient(it->second) && NULL != gData.geofenceInterface) {
|
||||||
|
gData.geofenceInterface->removeClient(it->first);
|
||||||
|
}
|
||||||
|
gData.clientData.erase(it);
|
||||||
|
} else {
|
||||||
|
LOC_LOGE("%s:%d]: Location API client %p not found in client data",
|
||||||
|
__func__, __LINE__, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&gDataMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LocationAPI::updateCallbacks(LocationCallbacks& locationCallbacks)
|
||||||
|
{
|
||||||
|
if (nullptr == locationCallbacks.capabilitiesCb ||
|
||||||
|
nullptr == locationCallbacks.responseCb ||
|
||||||
|
nullptr == locationCallbacks.collectiveResponseCb) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_lock(&gDataMutex);
|
||||||
|
|
||||||
|
if (isGnssClient(locationCallbacks)) {
|
||||||
|
if (NULL == gData.gnssInterface && !gGnssLoadFailed) {
|
||||||
|
gData.gnssInterface =
|
||||||
|
(GnssInterface*)loadLocationInterface("libgnss.so", "getGnssInterface");
|
||||||
|
if (NULL == gData.gnssInterface) {
|
||||||
|
gGnssLoadFailed = true;
|
||||||
|
LOC_LOGW("%s:%d]: No gnss interface available", __func__, __LINE__);
|
||||||
|
} else {
|
||||||
|
gData.gnssInterface->initialize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (NULL != gData.gnssInterface) {
|
||||||
|
// either adds new Client or updates existing Client
|
||||||
|
gData.gnssInterface->addClient(this, locationCallbacks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isFlpClient(locationCallbacks)) {
|
||||||
|
if (NULL == gData.flpInterface && !gFlpLoadFailed) {
|
||||||
|
gData.flpInterface =
|
||||||
|
(FlpInterface*)loadLocationInterface("libflp.so", "getFlpInterface");
|
||||||
|
if (NULL == gData.flpInterface) {
|
||||||
|
gFlpLoadFailed = true;
|
||||||
|
LOC_LOGW("%s:%d]: No flp interface available", __func__, __LINE__);
|
||||||
|
} else {
|
||||||
|
gData.flpInterface->initialize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (NULL != gData.flpInterface) {
|
||||||
|
// either adds new Client or updates existing Client
|
||||||
|
gData.flpInterface->addClient(this, locationCallbacks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isGeofenceClient(locationCallbacks)) {
|
||||||
|
if (NULL == gData.geofenceInterface && !gGeofenceLoadFailed) {
|
||||||
|
gData.geofenceInterface =
|
||||||
|
(GeofenceInterface*)loadLocationInterface("libgeofence.so", "getGeofenceInterface");
|
||||||
|
if (NULL == gData.geofenceInterface) {
|
||||||
|
gGeofenceLoadFailed = true;
|
||||||
|
LOC_LOGW("%s:%d]: No geofence interface available", __func__, __LINE__);
|
||||||
|
} else {
|
||||||
|
gData.geofenceInterface->initialize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (NULL != gData.geofenceInterface) {
|
||||||
|
// either adds new Client or updates existing Client
|
||||||
|
gData.geofenceInterface->addClient(this, locationCallbacks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gData.clientData[this] = locationCallbacks;
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&gDataMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
LocationAPI::startTracking(LocationOptions& locationOptions)
|
||||||
|
{
|
||||||
|
uint32_t id = 0;
|
||||||
|
pthread_mutex_lock(&gDataMutex);
|
||||||
|
|
||||||
|
auto it = gData.clientData.find(this);
|
||||||
|
if (it != gData.clientData.end()) {
|
||||||
|
if (gData.flpInterface != NULL && locationOptions.minDistance > 0) {
|
||||||
|
id = gData.flpInterface->startTracking(this, locationOptions);
|
||||||
|
} else if (gData.gnssInterface != NULL && needsGnssTrackingInfo(it->second)) {
|
||||||
|
id = gData.gnssInterface->startTracking(this, locationOptions);
|
||||||
|
} else if (gData.flpInterface != NULL) {
|
||||||
|
id = gData.flpInterface->startTracking(this, locationOptions);
|
||||||
|
} else if (gData.gnssInterface != NULL) {
|
||||||
|
id = gData.gnssInterface->startTracking(this, locationOptions);
|
||||||
|
} else {
|
||||||
|
LOC_LOGE("%s:%d]: No gnss/flp interface available for Location API client %p ",
|
||||||
|
__func__, __LINE__, this);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOC_LOGE("%s:%d]: Location API client %p not found in client data",
|
||||||
|
__func__, __LINE__, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&gDataMutex);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LocationAPI::stopTracking(uint32_t id)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&gDataMutex);
|
||||||
|
|
||||||
|
auto it = gData.clientData.find(this);
|
||||||
|
if (it != gData.clientData.end()) {
|
||||||
|
// we don't know if tracking was started on flp or gnss, so we call stop on both, where
|
||||||
|
// stopTracking call to the incorrect interface will fail without response back to client
|
||||||
|
if (gData.gnssInterface != NULL) {
|
||||||
|
gData.gnssInterface->stopTracking(this, id);
|
||||||
|
}
|
||||||
|
if (gData.flpInterface != NULL) {
|
||||||
|
gData.flpInterface->stopTracking(this, id);
|
||||||
|
}
|
||||||
|
if (gData.flpInterface == NULL && gData.gnssInterface == NULL) {
|
||||||
|
LOC_LOGE("%s:%d]: No gnss/flp interface available for Location API client %p ",
|
||||||
|
__func__, __LINE__, this);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOC_LOGE("%s:%d]: Location API client %p not found in client data",
|
||||||
|
__func__, __LINE__, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&gDataMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LocationAPI::updateTrackingOptions(uint32_t id, LocationOptions& locationOptions)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&gDataMutex);
|
||||||
|
|
||||||
|
auto it = gData.clientData.find(this);
|
||||||
|
if (it != gData.clientData.end()) {
|
||||||
|
// we don't know if tracking was started on flp or gnss, so we call update on both, where
|
||||||
|
// updateTracking call to the incorrect interface will fail without response back to client
|
||||||
|
if (gData.gnssInterface != NULL) {
|
||||||
|
gData.gnssInterface->updateTrackingOptions(this, id, locationOptions);
|
||||||
|
}
|
||||||
|
if (gData.flpInterface != NULL) {
|
||||||
|
gData.flpInterface->updateTrackingOptions(this, id, locationOptions);
|
||||||
|
}
|
||||||
|
if (gData.flpInterface == NULL && gData.gnssInterface == NULL) {
|
||||||
|
LOC_LOGE("%s:%d]: No gnss/flp interface available for Location API client %p ",
|
||||||
|
__func__, __LINE__, this);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOC_LOGE("%s:%d]: Location API client %p not found in client data",
|
||||||
|
__func__, __LINE__, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&gDataMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
LocationAPI::startBatching(LocationOptions& locationOptions, BatchingOptions &batchingOptions)
|
||||||
|
{
|
||||||
|
uint32_t id = 0;
|
||||||
|
pthread_mutex_lock(&gDataMutex);
|
||||||
|
|
||||||
|
if (gData.flpInterface != NULL) {
|
||||||
|
id = gData.flpInterface->startBatching(this, locationOptions, batchingOptions);
|
||||||
|
} else {
|
||||||
|
LOC_LOGE("%s:%d]: No flp interface available for Location API client %p ",
|
||||||
|
__func__, __LINE__, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&gDataMutex);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LocationAPI::stopBatching(uint32_t id)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&gDataMutex);
|
||||||
|
|
||||||
|
if (gData.flpInterface != NULL) {
|
||||||
|
gData.flpInterface->stopBatching(this, id);
|
||||||
|
} else {
|
||||||
|
LOC_LOGE("%s:%d]: No flp interface available for Location API client %p ",
|
||||||
|
__func__, __LINE__, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&gDataMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LocationAPI::updateBatchingOptions(uint32_t id,
|
||||||
|
LocationOptions& locationOptions, BatchingOptions& batchOptions)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&gDataMutex);
|
||||||
|
|
||||||
|
if (gData.flpInterface != NULL) {
|
||||||
|
gData.flpInterface->updateBatchingOptions(this,
|
||||||
|
id,
|
||||||
|
locationOptions,
|
||||||
|
batchOptions);
|
||||||
|
} else {
|
||||||
|
LOC_LOGE("%s:%d]: No flp interface available for Location API client %p ",
|
||||||
|
__func__, __LINE__, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&gDataMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LocationAPI::getBatchedLocations(uint32_t id, size_t count)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&gDataMutex);
|
||||||
|
|
||||||
|
if (gData.flpInterface != NULL) {
|
||||||
|
gData.flpInterface->getBatchedLocations(this, id, count);
|
||||||
|
} else {
|
||||||
|
LOC_LOGE("%s:%d]: No flp interface available for Location API client %p ",
|
||||||
|
__func__, __LINE__, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&gDataMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t*
|
||||||
|
LocationAPI::addGeofences(size_t count, GeofenceOption* options, GeofenceInfo* info)
|
||||||
|
{
|
||||||
|
uint32_t* ids = NULL;
|
||||||
|
pthread_mutex_lock(&gDataMutex);
|
||||||
|
|
||||||
|
if (gData.geofenceInterface != NULL) {
|
||||||
|
ids = gData.geofenceInterface->addGeofences(this, count, options, info);
|
||||||
|
} else {
|
||||||
|
LOC_LOGE("%s:%d]: No geofence interface available for Location API client %p ",
|
||||||
|
__func__, __LINE__, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&gDataMutex);
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LocationAPI::removeGeofences(size_t count, uint32_t* ids)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&gDataMutex);
|
||||||
|
|
||||||
|
if (gData.geofenceInterface != NULL) {
|
||||||
|
gData.geofenceInterface->removeGeofences(this, count, ids);
|
||||||
|
} else {
|
||||||
|
LOC_LOGE("%s:%d]: No geofence interface available for Location API client %p ",
|
||||||
|
__func__, __LINE__, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&gDataMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LocationAPI::modifyGeofences(size_t count, uint32_t* ids, GeofenceOption* options)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&gDataMutex);
|
||||||
|
|
||||||
|
if (gData.geofenceInterface != NULL) {
|
||||||
|
gData.geofenceInterface->modifyGeofences(this, count, ids, options);
|
||||||
|
} else {
|
||||||
|
LOC_LOGE("%s:%d]: No geofence interface available for Location API client %p ",
|
||||||
|
__func__, __LINE__, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&gDataMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LocationAPI::pauseGeofences(size_t count, uint32_t* ids)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&gDataMutex);
|
||||||
|
|
||||||
|
if (gData.geofenceInterface != NULL) {
|
||||||
|
gData.geofenceInterface->pauseGeofences(this, count, ids);
|
||||||
|
} else {
|
||||||
|
LOC_LOGE("%s:%d]: No geofence interface available for Location API client %p ",
|
||||||
|
__func__, __LINE__, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&gDataMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LocationAPI::resumeGeofences(size_t count, uint32_t* ids)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&gDataMutex);
|
||||||
|
|
||||||
|
if (gData.geofenceInterface != NULL) {
|
||||||
|
gData.geofenceInterface->resumeGeofences(this, count, ids);
|
||||||
|
} else {
|
||||||
|
LOC_LOGE("%s:%d]: No geofence interface available for Location API client %p ",
|
||||||
|
__func__, __LINE__, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&gDataMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LocationAPI::gnssNiResponse(uint32_t id, GnssNiResponse response)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&gDataMutex);
|
||||||
|
|
||||||
|
if (gData.gnssInterface != NULL) {
|
||||||
|
gData.gnssInterface->gnssNiResponse(this, id, response);
|
||||||
|
} else {
|
||||||
|
LOC_LOGE("%s:%d]: No gnss interface available for Location API client %p ",
|
||||||
|
__func__, __LINE__, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&gDataMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
LocationControlAPI*
|
||||||
|
LocationControlAPI::createInstance(LocationControlCallbacks& locationControlCallbacks)
|
||||||
|
{
|
||||||
|
LocationControlAPI* controlAPI = NULL;
|
||||||
|
pthread_mutex_lock(&gDataMutex);
|
||||||
|
|
||||||
|
if (nullptr != locationControlCallbacks.responseCb && NULL == gData.controlAPI) {
|
||||||
|
if (NULL == gData.gnssInterface && !gGnssLoadFailed) {
|
||||||
|
gData.gnssInterface =
|
||||||
|
(GnssInterface*)loadLocationInterface("libgnss.so", "getGnssInterface");
|
||||||
|
if (NULL == gData.gnssInterface) {
|
||||||
|
gGnssLoadFailed = true;
|
||||||
|
LOC_LOGW("%s:%d]: No gnss interface available", __func__, __LINE__);
|
||||||
|
} else {
|
||||||
|
gData.gnssInterface->initialize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (NULL != gData.gnssInterface) {
|
||||||
|
gData.controlAPI = new LocationControlAPI();
|
||||||
|
gData.controlCallbacks = locationControlCallbacks;
|
||||||
|
gData.gnssInterface->setControlCallbacks(locationControlCallbacks);
|
||||||
|
controlAPI = gData.controlAPI;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&gDataMutex);
|
||||||
|
return controlAPI;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LocationControlAPI::destroy()
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocationControlAPI::LocationControlAPI()
|
||||||
|
{
|
||||||
|
LOC_LOGD("LOCATION CONTROL API CONSTRUCTOR");
|
||||||
|
}
|
||||||
|
|
||||||
|
LocationControlAPI::~LocationControlAPI()
|
||||||
|
{
|
||||||
|
LOC_LOGD("LOCATION CONTROL API DESTRUCTOR");
|
||||||
|
pthread_mutex_lock(&gDataMutex);
|
||||||
|
|
||||||
|
gData.controlAPI = NULL;
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&gDataMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
LocationControlAPI::enable(LocationTechnologyType techType)
|
||||||
|
{
|
||||||
|
uint32_t id = 0;
|
||||||
|
pthread_mutex_lock(&gDataMutex);
|
||||||
|
|
||||||
|
if (gData.gnssInterface != NULL) {
|
||||||
|
id = gData.gnssInterface->enable(techType);
|
||||||
|
} else {
|
||||||
|
LOC_LOGE("%s:%d]: No gnss interface available for Location Control API client %p ",
|
||||||
|
__func__, __LINE__, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&gDataMutex);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LocationControlAPI::disable(uint32_t id)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&gDataMutex);
|
||||||
|
|
||||||
|
if (gData.gnssInterface != NULL) {
|
||||||
|
gData.gnssInterface->disable(id);
|
||||||
|
} else {
|
||||||
|
LOC_LOGE("%s:%d]: No gnss interface available for Location Control API client %p ",
|
||||||
|
__func__, __LINE__, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&gDataMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t*
|
||||||
|
LocationControlAPI::gnssUpdateConfig(GnssConfig config)
|
||||||
|
{
|
||||||
|
uint32_t* ids = NULL;
|
||||||
|
pthread_mutex_lock(&gDataMutex);
|
||||||
|
|
||||||
|
if (gData.gnssInterface != NULL) {
|
||||||
|
ids = gData.gnssInterface->gnssUpdateConfig(config);
|
||||||
|
} else {
|
||||||
|
LOC_LOGE("%s:%d]: No gnss interface available for Location Control API client %p ",
|
||||||
|
__func__, __LINE__, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&gDataMutex);
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
LocationControlAPI::gnssDeleteAidingData(GnssAidingData& data)
|
||||||
|
{
|
||||||
|
uint32_t id = 0;
|
||||||
|
pthread_mutex_lock(&gDataMutex);
|
||||||
|
|
||||||
|
if (gData.gnssInterface != NULL) {
|
||||||
|
id = gData.gnssInterface->gnssDeleteAidingData(data);
|
||||||
|
} else {
|
||||||
|
LOC_LOGE("%s:%d]: No gnss interface available for Location Control API client %p ",
|
||||||
|
__func__, __LINE__, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&gDataMutex);
|
||||||
|
return id;
|
||||||
|
}
|
974
gps/location/LocationAPI.h
Normal file
974
gps/location/LocationAPI.h
Normal file
|
@ -0,0 +1,974 @@
|
||||||
|
/* Copyright (c) 2017 The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LOCATION_H
|
||||||
|
#define LOCATION_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <functional>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
#define GNSS_NI_REQUESTOR_MAX 256
|
||||||
|
#define GNSS_NI_MESSAGE_ID_MAX 2048
|
||||||
|
#define GNSS_SV_MAX 64
|
||||||
|
#define GNSS_MEASUREMENTS_MAX 64
|
||||||
|
#define GNSS_UTC_TIME_OFFSET (3657)
|
||||||
|
|
||||||
|
#define GNSS_BUGREPORT_GPS_MIN (1)
|
||||||
|
#define GNSS_BUGREPORT_SBAS_MIN (120)
|
||||||
|
#define GNSS_BUGREPORT_GLO_MIN (1)
|
||||||
|
#define GNSS_BUGREPORT_QZSS_MIN (193)
|
||||||
|
#define GNSS_BUGREPORT_BDS_MIN (1)
|
||||||
|
#define GNSS_BUGREPORT_GAL_MIN (1)
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
LOCATION_ERROR_SUCCESS = 0,
|
||||||
|
LOCATION_ERROR_GENERAL_FAILURE,
|
||||||
|
LOCATION_ERROR_CALLBACK_MISSING,
|
||||||
|
LOCATION_ERROR_INVALID_PARAMETER,
|
||||||
|
LOCATION_ERROR_ID_EXISTS,
|
||||||
|
LOCATION_ERROR_ID_UNKNOWN,
|
||||||
|
LOCATION_ERROR_ALREADY_STARTED,
|
||||||
|
LOCATION_ERROR_GEOFENCES_AT_MAX,
|
||||||
|
LOCATION_ERROR_NOT_SUPPORTED
|
||||||
|
} LocationError;
|
||||||
|
|
||||||
|
// Flags to indicate which values are valid in a Location
|
||||||
|
typedef uint16_t LocationFlagsMask;
|
||||||
|
typedef enum {
|
||||||
|
LOCATION_HAS_LAT_LONG_BIT = (1<<0), // location has valid latitude and longitude
|
||||||
|
LOCATION_HAS_ALTITUDE_BIT = (1<<1), // location has valid altitude
|
||||||
|
LOCATION_HAS_SPEED_BIT = (1<<2), // location has valid speed
|
||||||
|
LOCATION_HAS_BEARING_BIT = (1<<3), // location has valid bearing
|
||||||
|
LOCATION_HAS_ACCURACY_BIT = (1<<4), // location has valid accuracy
|
||||||
|
LOCATION_HAS_VERTICAL_ACCURACY_BIT = (1<<5), // location has valid vertical accuracy
|
||||||
|
LOCATION_HAS_SPEED_ACCURACY_BIT = (1<<6), // location has valid speed accuracy
|
||||||
|
LOCATION_HAS_BEARING_ACCURACY_BIT = (1<<7), // location has valid bearing accuracy
|
||||||
|
} LocationFlagsBits;
|
||||||
|
|
||||||
|
typedef uint16_t LocationTechnologyMask;
|
||||||
|
typedef enum {
|
||||||
|
LOCATION_TECHNOLOGY_GNSS_BIT = (1<<0), // location was calculated using GNSS
|
||||||
|
LOCATION_TECHNOLOGY_CELL_BIT = (1<<1), // location was calculated using Cell
|
||||||
|
LOCATION_TECHNOLOGY_WIFI_BIT = (1<<2), // location was calculated using WiFi
|
||||||
|
LOCATION_TECHNOLOGY_SENSORS_BIT = (1<<3), // location was calculated using Sensors
|
||||||
|
} LocationTechnologyBits;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
LOCATION_RELIABILITY_NOT_SET = 0,
|
||||||
|
LOCATION_RELIABILITY_VERY_LOW,
|
||||||
|
LOCATION_RELIABILITY_LOW,
|
||||||
|
LOCATION_RELIABILITY_MEDIUM,
|
||||||
|
LOCATION_RELIABILITY_HIGH,
|
||||||
|
} LocationReliability;
|
||||||
|
|
||||||
|
typedef uint32_t GnssLocationInfoFlagMask;
|
||||||
|
typedef enum {
|
||||||
|
GNSS_LOCATION_INFO_ALTITUDE_MEAN_SEA_LEVEL_BIT = (1<<0), // valid altitude mean sea level
|
||||||
|
GNSS_LOCATION_INFO_DOP_BIT = (1<<1), // valid pdop, hdop, and vdop
|
||||||
|
GNSS_LOCATION_INFO_MAGNETIC_DEVIATION_BIT = (1<<2), // valid magnetic deviation
|
||||||
|
GNSS_LOCATION_INFO_HOR_RELIABILITY_BIT = (1<<3), // valid horizontal reliability
|
||||||
|
GNSS_LOCATION_INFO_VER_RELIABILITY_BIT = (1<<4), // valid vertical reliability
|
||||||
|
GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_SEMI_MAJOR_BIT = (1<<5), // valid elipsode semi major
|
||||||
|
GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_SEMI_MINOR_BIT = (1<<6), // valid elipsode semi minor
|
||||||
|
GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_AZIMUTH_BIT = (1<<7),// valid accuracy elipsode azimuth
|
||||||
|
} GnssLocationInfoFlagBits;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GEOFENCE_BREACH_ENTER = 0,
|
||||||
|
GEOFENCE_BREACH_EXIT,
|
||||||
|
GEOFENCE_BREACH_DWELL_IN,
|
||||||
|
GEOFENCE_BREACH_DWELL_OUT,
|
||||||
|
GEOFENCE_BREACH_UNKNOWN,
|
||||||
|
} GeofenceBreachType;
|
||||||
|
|
||||||
|
typedef uint16_t GeofenceBreachTypeMask;
|
||||||
|
typedef enum {
|
||||||
|
GEOFENCE_BREACH_ENTER_BIT = (1<<0),
|
||||||
|
GEOFENCE_BREACH_EXIT_BIT = (1<<1),
|
||||||
|
GEOFENCE_BREACH_DWELL_IN_BIT = (1<<2),
|
||||||
|
GEOFENCE_BREACH_DWELL_OUT_BIT = (1<<3),
|
||||||
|
} GeofenceBreachTypeBits;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GEOFENCE_STATUS_AVAILABILE_NO = 0,
|
||||||
|
GEOFENCE_STATUS_AVAILABILE_YES,
|
||||||
|
} GeofenceStatusAvailable;
|
||||||
|
|
||||||
|
typedef uint32_t LocationCapabilitiesMask;
|
||||||
|
typedef enum {
|
||||||
|
// supports startTracking API with minInterval param
|
||||||
|
LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT = (1<<0),
|
||||||
|
// supports startBatching API with minInterval param
|
||||||
|
LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT = (1<<1),
|
||||||
|
// supports startTracking API with minDistance param
|
||||||
|
LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT = (1<<2),
|
||||||
|
// supports startBatching API with minDistance param
|
||||||
|
LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT = (1<<3),
|
||||||
|
// supports addGeofences API
|
||||||
|
LOCATION_CAPABILITIES_GEOFENCE_BIT = (1<<4),
|
||||||
|
// supports GnssMeasurementsCallback
|
||||||
|
LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT = (1<<5),
|
||||||
|
// supports startTracking/startBatching API with LocationOptions.mode of MSB (Ms Based)
|
||||||
|
LOCATION_CAPABILITIES_GNSS_MSB_BIT = (1<<6),
|
||||||
|
// supports startTracking/startBatching API with LocationOptions.mode of MSA (MS Assisted)
|
||||||
|
LOCATION_CAPABILITIES_GNSS_MSA_BIT = (1<<7),
|
||||||
|
// supports debug nmea sentences in the debugNmeaCallback
|
||||||
|
LOCATION_CAPABILITIES_DEBUG_NMEA_BIT = (1<<8),
|
||||||
|
// support outdoor trip batching
|
||||||
|
LOCATION_CAPABILITIES_OUTDOOR_TRIP_BATCHING_BIT = (1<<9)
|
||||||
|
} LocationCapabilitiesBits;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
LOCATION_TECHNOLOGY_TYPE_GNSS = 0,
|
||||||
|
} LocationTechnologyType;
|
||||||
|
|
||||||
|
// Configures how GPS is locked when GPS is disabled (through GnssDisable)
|
||||||
|
typedef enum {
|
||||||
|
GNSS_CONFIG_GPS_LOCK_NONE = 0, // gps is not locked when GPS is disabled (GnssDisable)
|
||||||
|
GNSS_CONFIG_GPS_LOCK_MO, // gps mobile originated (MO) is locked when GPS is disabled
|
||||||
|
GNSS_CONFIG_GPS_LOCK_NI, // gps network initiated (NI) is locked when GPS is disabled
|
||||||
|
GNSS_CONFIG_GPS_LOCK_MO_AND_NI,// gps MO and NI is locked when GPS is disabled
|
||||||
|
} GnssConfigGpsLock;
|
||||||
|
|
||||||
|
// SUPL version
|
||||||
|
typedef enum {
|
||||||
|
GNSS_CONFIG_SUPL_VERSION_1_0_0 = 1,
|
||||||
|
GNSS_CONFIG_SUPL_VERSION_2_0_0,
|
||||||
|
GNSS_CONFIG_SUPL_VERSION_2_0_2,
|
||||||
|
} GnssConfigSuplVersion;
|
||||||
|
|
||||||
|
// LTE Positioning Profile
|
||||||
|
typedef enum {
|
||||||
|
GNSS_CONFIG_LPP_PROFILE_RRLP_ON_LTE = 0, // RRLP on LTE (Default)
|
||||||
|
GNSS_CONFIG_LPP_PROFILE_USER_PLANE, // LPP User Plane (UP) on LTE
|
||||||
|
GNSS_CONFIG_LPP_PROFILE_CONTROL_PLANE, // LPP_Control_Plane (CP)
|
||||||
|
GNSS_CONFIG_LPP_PROFILE_USER_PLANE_AND_CONTROL_PLANE, // Both LPP UP and CP
|
||||||
|
} GnssConfigLppProfile;
|
||||||
|
|
||||||
|
// Technology for LPPe Control Plane
|
||||||
|
typedef uint16_t GnssConfigLppeControlPlaneMask;
|
||||||
|
typedef enum {
|
||||||
|
GNSS_CONFIG_LPPE_CONTROL_PLANE_DBH_BIT = (1<<0), // DBH
|
||||||
|
GNSS_CONFIG_LPPE_CONTROL_PLANE_WLAN_AP_MEASUREMENTS_BIT = (1<<1), // WLAN_AP_MEASUREMENTS
|
||||||
|
GNSS_CONFIG_LPPE_CONTROL_PLANE_SRN_AP_MEASUREMENTS_BIT = (1<<2), // SRN_AP_MEASUREMENTS
|
||||||
|
GNSS_CONFIG_LPPE_CONTROL_PLANE_SENSOR_BARO_MEASUREMENTS_BIT = (1<<3),
|
||||||
|
// SENSOR_BARO_MEASUREMENTS
|
||||||
|
} GnssConfigLppeControlPlaneBits;
|
||||||
|
|
||||||
|
// Technology for LPPe User Plane
|
||||||
|
typedef uint16_t GnssConfigLppeUserPlaneMask;
|
||||||
|
typedef enum {
|
||||||
|
GNSS_CONFIG_LPPE_USER_PLANE_DBH_BIT = (1<<0), // DBH
|
||||||
|
GNSS_CONFIG_LPPE_USER_PLANE_WLAN_AP_MEASUREMENTS_BIT = (1<<1), // WLAN_AP_MEASUREMENTS
|
||||||
|
GNSS_CONFIG_LPPE_USER_PLANE_SRN_AP_MEASUREMENTS_BIT = (1<<2), // SRN_AP_MEASUREMENTS
|
||||||
|
GNSS_CONFIG_LPPE_USER_PLANE_SENSOR_BARO_MEASUREMENTS_BIT = (1<<3),
|
||||||
|
// SENSOR_BARO_MEASUREMENTS
|
||||||
|
} GnssConfigLppeUserPlaneBits;
|
||||||
|
|
||||||
|
// Positioning Protocol on A-GLONASS system
|
||||||
|
typedef uint16_t GnssConfigAGlonassPositionProtocolMask;
|
||||||
|
typedef enum {
|
||||||
|
GNSS_CONFIG_RRC_CONTROL_PLANE_BIT = (1<<0), // RRC Control Plane
|
||||||
|
GNSS_CONFIG_RRLP_USER_PLANE_BIT = (1<<1), // RRLP User Plane
|
||||||
|
GNSS_CONFIG_LLP_USER_PLANE_BIT = (1<<2), // LPP User Plane
|
||||||
|
GNSS_CONFIG_LLP_CONTROL_PLANE_BIT = (1<<3), // LPP Control Plane
|
||||||
|
} GnssConfigAGlonassPositionProtocolBits;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GNSS_CONFIG_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_NO = 0,
|
||||||
|
GNSS_CONFIG_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_YES,
|
||||||
|
} GnssConfigEmergencyPdnForEmergencySupl;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GNSS_CONFIG_SUPL_EMERGENCY_SERVICES_NO = 0,
|
||||||
|
GNSS_CONFIG_SUPL_EMERGENCY_SERVICES_YES,
|
||||||
|
} GnssConfigSuplEmergencyServices;
|
||||||
|
|
||||||
|
typedef uint16_t GnssConfigSuplModeMask;
|
||||||
|
typedef enum {
|
||||||
|
GNSS_CONFIG_SUPL_MODE_MSB_BIT = (1<<0),
|
||||||
|
GNSS_CONFIG_SUPL_MODE_MSA_BIT = (1<<1),
|
||||||
|
} GnssConfigSuplModeBits;
|
||||||
|
|
||||||
|
typedef uint32_t GnssConfigFlagsMask;
|
||||||
|
typedef enum {
|
||||||
|
GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT = (1<<0),
|
||||||
|
GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT = (1<<1),
|
||||||
|
GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT = (1<<2),
|
||||||
|
GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT = (1<<3),
|
||||||
|
GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT = (1<<4),
|
||||||
|
GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT = (1<<5),
|
||||||
|
GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT = (1<<6),
|
||||||
|
GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT = (1<<7),
|
||||||
|
GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT = (1<<8),
|
||||||
|
GNSS_CONFIG_FLAGS_SUPL_MODE_BIT = (1<<9),
|
||||||
|
} GnssConfigFlagsBits;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GNSS_NI_ENCODING_TYPE_NONE = 0,
|
||||||
|
GNSS_NI_ENCODING_TYPE_GSM_DEFAULT,
|
||||||
|
GNSS_NI_ENCODING_TYPE_UTF8,
|
||||||
|
GNSS_NI_ENCODING_TYPE_UCS2,
|
||||||
|
} GnssNiEncodingType;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GNSS_NI_TYPE_VOICE = 0,
|
||||||
|
GNSS_NI_TYPE_SUPL,
|
||||||
|
GNSS_NI_TYPE_CONTROL_PLANE,
|
||||||
|
GNSS_NI_TYPE_EMERGENCY_SUPL
|
||||||
|
} GnssNiType;
|
||||||
|
|
||||||
|
typedef uint16_t GnssNiOptionsMask;
|
||||||
|
typedef enum {
|
||||||
|
GNSS_NI_OPTIONS_NOTIFICATION_BIT = (1<<0),
|
||||||
|
GNSS_NI_OPTIONS_VERIFICATION_BIT = (1<<1),
|
||||||
|
GNSS_NI_OPTIONS_PRIVACY_OVERRIDE_BIT = (1<<2),
|
||||||
|
} GnssNiOptionsBits;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GNSS_NI_RESPONSE_ACCEPT = 1,
|
||||||
|
GNSS_NI_RESPONSE_DENY,
|
||||||
|
GNSS_NI_RESPONSE_NO_RESPONSE,
|
||||||
|
GNSS_NI_RESPONSE_IGNORE,
|
||||||
|
} GnssNiResponse;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GNSS_SV_TYPE_UNKNOWN = 0,
|
||||||
|
GNSS_SV_TYPE_GPS,
|
||||||
|
GNSS_SV_TYPE_SBAS,
|
||||||
|
GNSS_SV_TYPE_GLONASS,
|
||||||
|
GNSS_SV_TYPE_QZSS,
|
||||||
|
GNSS_SV_TYPE_BEIDOU,
|
||||||
|
GNSS_SV_TYPE_GALILEO,
|
||||||
|
} GnssSvType;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GNSS_EPH_TYPE_UNKNOWN = 0,
|
||||||
|
GNSS_EPH_TYPE_EPHEMERIS,
|
||||||
|
GNSS_EPH_TYPE_ALMANAC,
|
||||||
|
} GnssEphemerisType;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GNSS_EPH_SOURCE_UNKNOWN = 0,
|
||||||
|
GNSS_EPH_SOURCE_DEMODULATED,
|
||||||
|
GNSS_EPH_SOURCE_SUPL_PROVIDED,
|
||||||
|
GNSS_EPH_SOURCE_OTHER_SERVER_PROVIDED,
|
||||||
|
GNSS_EPH_SOURCE_LOCAL,
|
||||||
|
} GnssEphemerisSource;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GNSS_EPH_HEALTH_UNKNOWN = 0,
|
||||||
|
GNSS_EPH_HEALTH_GOOD,
|
||||||
|
GNSS_EPH_HEALTH_BAD,
|
||||||
|
} GnssEphemerisHealth;
|
||||||
|
|
||||||
|
typedef uint16_t GnssSvOptionsMask;
|
||||||
|
typedef enum {
|
||||||
|
GNSS_SV_OPTIONS_HAS_EPHEMER_BIT = (1<<0),
|
||||||
|
GNSS_SV_OPTIONS_HAS_ALMANAC_BIT = (1<<1),
|
||||||
|
GNSS_SV_OPTIONS_USED_IN_FIX_BIT = (1<<2),
|
||||||
|
} GnssSvOptionsBits;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GNSS_ASSISTANCE_TYPE_SUPL = 0,
|
||||||
|
GNSS_ASSISTANCE_TYPE_C2K,
|
||||||
|
} GnssAssistanceType;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GNSS_SUPL_MODE_STANDALONE = 0,
|
||||||
|
GNSS_SUPL_MODE_MSB,
|
||||||
|
GNSS_SUPL_MODE_MSA,
|
||||||
|
} GnssSuplMode;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BATCHING_MODE_ROUTINE = 0, // positions are reported when batched positions memory is full
|
||||||
|
BATCHING_MODE_TRIP, // positions are reported when a certain distance is covered
|
||||||
|
BATCHING_MODE_NO_AUTO_REPORT // no report of positions automatically, instead queried on demand
|
||||||
|
} BatchingMode;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BATCHING_STATUS_TRIP_COMPLETED = 0,
|
||||||
|
BATCHING_STATUS_POSITION_AVAILABE,
|
||||||
|
BATCHING_STATUS_POSITION_UNAVAILABLE
|
||||||
|
} BatchingStatus;
|
||||||
|
|
||||||
|
typedef uint16_t GnssMeasurementsAdrStateMask;
|
||||||
|
typedef enum {
|
||||||
|
GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_UNKNOWN = 0,
|
||||||
|
GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_VALID_BIT = (1<<0),
|
||||||
|
GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_RESET_BIT = (1<<1),
|
||||||
|
GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_CYCLE_SLIP_BIT = (1<<2),
|
||||||
|
} GnssMeasurementsAdrStateBits;
|
||||||
|
|
||||||
|
typedef uint32_t GnssMeasurementsDataFlagsMask;
|
||||||
|
typedef enum {
|
||||||
|
GNSS_MEASUREMENTS_DATA_SV_ID_BIT = (1<<0),
|
||||||
|
GNSS_MEASUREMENTS_DATA_SV_TYPE_BIT = (1<<1),
|
||||||
|
GNSS_MEASUREMENTS_DATA_STATE_BIT = (1<<2),
|
||||||
|
GNSS_MEASUREMENTS_DATA_RECEIVED_SV_TIME_BIT = (1<<3),
|
||||||
|
GNSS_MEASUREMENTS_DATA_RECEIVED_SV_TIME_UNCERTAINTY_BIT = (1<<4),
|
||||||
|
GNSS_MEASUREMENTS_DATA_CARRIER_TO_NOISE_BIT = (1<<5),
|
||||||
|
GNSS_MEASUREMENTS_DATA_PSEUDORANGE_RATE_BIT = (1<<6),
|
||||||
|
GNSS_MEASUREMENTS_DATA_PSEUDORANGE_RATE_UNCERTAINTY_BIT = (1<<7),
|
||||||
|
GNSS_MEASUREMENTS_DATA_ADR_STATE_BIT = (1<<8),
|
||||||
|
GNSS_MEASUREMENTS_DATA_ADR_BIT = (1<<9),
|
||||||
|
GNSS_MEASUREMENTS_DATA_ADR_UNCERTAINTY_BIT = (1<<10),
|
||||||
|
GNSS_MEASUREMENTS_DATA_CARRIER_FREQUENCY_BIT = (1<<11),
|
||||||
|
GNSS_MEASUREMENTS_DATA_CARRIER_CYCLES_BIT = (1<<12),
|
||||||
|
GNSS_MEASUREMENTS_DATA_CARRIER_PHASE_BIT = (1<<13),
|
||||||
|
GNSS_MEASUREMENTS_DATA_CARRIER_PHASE_UNCERTAINTY_BIT = (1<<14),
|
||||||
|
GNSS_MEASUREMENTS_DATA_MULTIPATH_INDICATOR_BIT = (1<<15),
|
||||||
|
GNSS_MEASUREMENTS_DATA_SIGNAL_TO_NOISE_RATIO_BIT = (1<<16),
|
||||||
|
GNSS_MEASUREMENTS_DATA_AUTOMATIC_GAIN_CONTROL_BIT = (1<<17),
|
||||||
|
} GnssMeasurementsDataFlagsBits;
|
||||||
|
|
||||||
|
typedef uint32_t GnssMeasurementsStateMask;
|
||||||
|
typedef enum {
|
||||||
|
GNSS_MEASUREMENTS_STATE_UNKNOWN_BIT = 0,
|
||||||
|
GNSS_MEASUREMENTS_STATE_CODE_LOCK_BIT = (1<<0),
|
||||||
|
GNSS_MEASUREMENTS_STATE_BIT_SYNC_BIT = (1<<1),
|
||||||
|
GNSS_MEASUREMENTS_STATE_SUBFRAME_SYNC_BIT = (1<<2),
|
||||||
|
GNSS_MEASUREMENTS_STATE_TOW_DECODED_BIT = (1<<3),
|
||||||
|
GNSS_MEASUREMENTS_STATE_MSEC_AMBIGUOUS_BIT = (1<<4),
|
||||||
|
GNSS_MEASUREMENTS_STATE_SYMBOL_SYNC_BIT = (1<<5),
|
||||||
|
GNSS_MEASUREMENTS_STATE_GLO_STRING_SYNC_BIT = (1<<6),
|
||||||
|
GNSS_MEASUREMENTS_STATE_GLO_TOD_DECODED_BIT = (1<<7),
|
||||||
|
GNSS_MEASUREMENTS_STATE_BDS_D2_BIT_SYNC_BIT = (1<<8),
|
||||||
|
GNSS_MEASUREMENTS_STATE_BDS_D2_SUBFRAME_SYNC_BIT = (1<<9),
|
||||||
|
GNSS_MEASUREMENTS_STATE_GAL_E1BC_CODE_LOCK_BIT = (1<<10),
|
||||||
|
GNSS_MEASUREMENTS_STATE_GAL_E1C_2ND_CODE_LOCK_BIT = (1<<11),
|
||||||
|
GNSS_MEASUREMENTS_STATE_GAL_E1B_PAGE_SYNC_BIT = (1<<12),
|
||||||
|
GNSS_MEASUREMENTS_STATE_SBAS_SYNC_BIT = (1<<13),
|
||||||
|
} GnssMeasurementsStateBits;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GNSS_MEASUREMENTS_MULTIPATH_INDICATOR_UNKNOWN = 0,
|
||||||
|
GNSS_MEASUREMENTS_MULTIPATH_INDICATOR_PRESENT,
|
||||||
|
GNSS_MEASUREMENTS_MULTIPATH_INDICATOR_NOT_PRESENT,
|
||||||
|
} GnssMeasurementsMultipathIndicator;
|
||||||
|
|
||||||
|
typedef uint32_t GnssMeasurementsClockFlagsMask;
|
||||||
|
typedef enum {
|
||||||
|
GNSS_MEASUREMENTS_CLOCK_FLAGS_LEAP_SECOND_BIT = (1<<0),
|
||||||
|
GNSS_MEASUREMENTS_CLOCK_FLAGS_TIME_BIT = (1<<1),
|
||||||
|
GNSS_MEASUREMENTS_CLOCK_FLAGS_TIME_UNCERTAINTY_BIT = (1<<2),
|
||||||
|
GNSS_MEASUREMENTS_CLOCK_FLAGS_FULL_BIAS_BIT = (1<<3),
|
||||||
|
GNSS_MEASUREMENTS_CLOCK_FLAGS_BIAS_BIT = (1<<4),
|
||||||
|
GNSS_MEASUREMENTS_CLOCK_FLAGS_BIAS_UNCERTAINTY_BIT = (1<<5),
|
||||||
|
GNSS_MEASUREMENTS_CLOCK_FLAGS_DRIFT_BIT = (1<<6),
|
||||||
|
GNSS_MEASUREMENTS_CLOCK_FLAGS_DRIFT_UNCERTAINTY_BIT = (1<<7),
|
||||||
|
GNSS_MEASUREMENTS_CLOCK_FLAGS_HW_CLOCK_DISCONTINUITY_COUNT_BIT = (1<<8),
|
||||||
|
} GnssMeasurementsClockFlagsBits;
|
||||||
|
|
||||||
|
typedef uint32_t GnssAidingDataSvMask;
|
||||||
|
typedef enum {
|
||||||
|
GNSS_AIDING_DATA_SV_EPHEMERIS_BIT = (1<<0), // ephemeris
|
||||||
|
GNSS_AIDING_DATA_SV_ALMANAC_BIT = (1<<1), // almanac
|
||||||
|
GNSS_AIDING_DATA_SV_HEALTH_BIT = (1<<2), // health
|
||||||
|
GNSS_AIDING_DATA_SV_DIRECTION_BIT = (1<<3), // direction
|
||||||
|
GNSS_AIDING_DATA_SV_STEER_BIT = (1<<4), // steer
|
||||||
|
GNSS_AIDING_DATA_SV_ALMANAC_CORR_BIT = (1<<5), // almanac correction
|
||||||
|
GNSS_AIDING_DATA_SV_BLACKLIST_BIT = (1<<6), // blacklist SVs
|
||||||
|
GNSS_AIDING_DATA_SV_SA_DATA_BIT = (1<<7), // sensitivity assistance data
|
||||||
|
GNSS_AIDING_DATA_SV_NO_EXIST_BIT = (1<<8), // SV does not exist
|
||||||
|
GNSS_AIDING_DATA_SV_IONOSPHERE_BIT = (1<<9), // ionosphere correction
|
||||||
|
GNSS_AIDING_DATA_SV_TIME_BIT = (1<<10),// reset satellite time
|
||||||
|
} GnssAidingDataSvBits;
|
||||||
|
|
||||||
|
typedef uint32_t GnssAidingDataSvTypeMask;
|
||||||
|
typedef enum {
|
||||||
|
GNSS_AIDING_DATA_SV_TYPE_GPS_BIT = (1<<0),
|
||||||
|
GNSS_AIDING_DATA_SV_TYPE_GLONASS_BIT = (1<<1),
|
||||||
|
GNSS_AIDING_DATA_SV_TYPE_QZSS_BIT = (1<<2),
|
||||||
|
GNSS_AIDING_DATA_SV_TYPE_BEIDOU_BIT = (1<<3),
|
||||||
|
GNSS_AIDING_DATA_SV_TYPE_GALILEO_BIT = (1<<4),
|
||||||
|
} GnssAidingDataSvTypeBits;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GnssAidingDataSvMask svMask; // bitwise OR of GnssAidingDataSvBits
|
||||||
|
GnssAidingDataSvTypeMask svTypeMask; // bitwise OR of GnssAidingDataSvTypeBits
|
||||||
|
} GnssAidingDataSv;
|
||||||
|
|
||||||
|
typedef uint32_t GnssAidingDataCommonMask;
|
||||||
|
typedef enum {
|
||||||
|
GNSS_AIDING_DATA_COMMON_POSITION_BIT = (1<<0), // position estimate
|
||||||
|
GNSS_AIDING_DATA_COMMON_TIME_BIT = (1<<1), // reset all clock values
|
||||||
|
GNSS_AIDING_DATA_COMMON_UTC_BIT = (1<<2), // UTC estimate
|
||||||
|
GNSS_AIDING_DATA_COMMON_RTI_BIT = (1<<3), // RTI
|
||||||
|
GNSS_AIDING_DATA_COMMON_FREQ_BIAS_EST_BIT = (1<<4), // frequency bias estimate
|
||||||
|
GNSS_AIDING_DATA_COMMON_CELLDB_BIT = (1<<5), // all celldb info
|
||||||
|
} GnssAidingDataCommonBits;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GnssAidingDataCommonMask mask; // bitwise OR of GnssAidingDataCommonBits
|
||||||
|
} GnssAidingDataCommon;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool deleteAll; // if true, delete all aiding data and ignore other params
|
||||||
|
GnssAidingDataSv sv; // SV specific aiding data
|
||||||
|
GnssAidingDataCommon common; // common aiding data
|
||||||
|
} GnssAidingData;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t size; // set to sizeof(Location)
|
||||||
|
LocationFlagsMask flags; // bitwise OR of LocationFlagsBits to mark which params are valid
|
||||||
|
uint64_t timestamp; // UTC timestamp for location fix, milliseconds since January 1, 1970
|
||||||
|
double latitude; // in degrees
|
||||||
|
double longitude; // in degrees
|
||||||
|
double altitude; // in meters above the WGS 84 reference ellipsoid
|
||||||
|
float speed; // in meters per second
|
||||||
|
float bearing; // in degrees; range [0, 360)
|
||||||
|
float accuracy; // in meters
|
||||||
|
float verticalAccuracy; // in meters
|
||||||
|
float speedAccuracy; // in meters/second
|
||||||
|
float bearingAccuracy; // in degrees (0 to 359.999)
|
||||||
|
LocationTechnologyMask techMask;
|
||||||
|
} Location;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t size; // set to sizeof(LocationOptions)
|
||||||
|
uint32_t minInterval; // in milliseconds
|
||||||
|
uint32_t minDistance; // in meters. if minDistance > 0, gnssSvCallback/gnssNmeaCallback/
|
||||||
|
// gnssMeasurementsCallback may not be called
|
||||||
|
GnssSuplMode mode; // Standalone/MS-Based/MS-Assisted
|
||||||
|
} LocationOptions;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t size;
|
||||||
|
BatchingMode batchingMode;
|
||||||
|
} BatchingOptions;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t size;
|
||||||
|
BatchingStatus batchingStatus;
|
||||||
|
} BatchingStatusInfo;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t size; // set to sizeof(GeofenceOption)
|
||||||
|
GeofenceBreachTypeMask breachTypeMask; // bitwise OR of GeofenceBreachTypeBits
|
||||||
|
uint32_t responsiveness; // in milliseconds
|
||||||
|
uint32_t dwellTime; // in seconds
|
||||||
|
} GeofenceOption;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t size; // set to sizeof(GeofenceInfo)
|
||||||
|
double latitude; // in degrees
|
||||||
|
double longitude; // in degrees
|
||||||
|
double radius; // in meters
|
||||||
|
} GeofenceInfo;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t size; // set to sizeof(GeofenceBreachNotification)
|
||||||
|
size_t count; // number of ids in array
|
||||||
|
uint32_t* ids; // array of ids that have breached
|
||||||
|
Location location; // location associated with breach
|
||||||
|
GeofenceBreachType type; // type of breach
|
||||||
|
uint64_t timestamp; // timestamp of breach
|
||||||
|
} GeofenceBreachNotification;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t size; // set to sizeof(GeofenceBreachNotification)
|
||||||
|
GeofenceStatusAvailable available; // GEOFENCE_STATUS_AVAILABILE_NO/_YES
|
||||||
|
LocationTechnologyType techType; // GNSS
|
||||||
|
} GeofenceStatusNotification;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t size; // set to sizeof(GnssLocationInfo)
|
||||||
|
GnssLocationInfoFlagMask flags; // bitwise OR of GnssLocationInfoBits for param validity
|
||||||
|
float altitudeMeanSeaLevel; // altitude wrt mean sea level
|
||||||
|
float pdop; // position dilusion of precision
|
||||||
|
float hdop; // horizontal dilusion of precision
|
||||||
|
float vdop; // vertical dilusion of precision
|
||||||
|
float magneticDeviation; // magnetic deviation
|
||||||
|
LocationReliability horReliability; // horizontal reliability
|
||||||
|
LocationReliability verReliability; // vertical reliability
|
||||||
|
float horUncEllipseSemiMajor; // horizontal elliptical accuracy semi-major axis
|
||||||
|
float horUncEllipseSemiMinor; // horizontal elliptical accuracy semi-minor axis
|
||||||
|
float horUncEllipseOrientAzimuth; // horizontal elliptical accuracy azimuth
|
||||||
|
} GnssLocationInfoNotification;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t size; // set to sizeof(GnssNiNotification)
|
||||||
|
GnssNiType type; // type of NI (Voice, SUPL, Control Plane)
|
||||||
|
GnssNiOptionsMask options; // bitwise OR of GnssNiOptionsBits
|
||||||
|
uint32_t timeout; // time (seconds) to wait for user input
|
||||||
|
GnssNiResponse timeoutResponse; // the response that should be sent when timeout expires
|
||||||
|
char requestor[GNSS_NI_REQUESTOR_MAX]; // the requestor that is making the request
|
||||||
|
GnssNiEncodingType requestorEncoding; // the encoding type for requestor
|
||||||
|
char message[GNSS_NI_MESSAGE_ID_MAX]; // the message to show user
|
||||||
|
GnssNiEncodingType messageEncoding; // the encoding type for message
|
||||||
|
char extras[GNSS_NI_MESSAGE_ID_MAX];
|
||||||
|
} GnssNiNotification;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t size; // set to sizeof(GnssSv)
|
||||||
|
uint16_t svId; // Unique Identifier
|
||||||
|
GnssSvType type; // type of SV (GPS, SBAS, GLONASS, QZSS, BEIDOU, GALILEO)
|
||||||
|
float cN0Dbhz; // signal strength
|
||||||
|
float elevation; // elevation of SV (in degrees)
|
||||||
|
float azimuth; // azimuth of SV (in degrees)
|
||||||
|
GnssSvOptionsMask gnssSvOptionsMask; // Bitwise OR of GnssSvOptionsBits
|
||||||
|
} GnssSv;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t size; // set to sizeof(GnssConfigSetAssistanceServer)
|
||||||
|
GnssAssistanceType type; // SUPL or C2K
|
||||||
|
const char* hostName; // null terminated string
|
||||||
|
uint32_t port; // port of server
|
||||||
|
} GnssConfigSetAssistanceServer;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t size; // set to sizeof(GnssMeasurementsData)
|
||||||
|
GnssMeasurementsDataFlagsMask flags; // bitwise OR of GnssMeasurementsDataFlagsBits
|
||||||
|
int16_t svId;
|
||||||
|
GnssSvType svType;
|
||||||
|
double timeOffsetNs;
|
||||||
|
GnssMeasurementsStateMask stateMask; // bitwise OR of GnssMeasurementsStateBits
|
||||||
|
int64_t receivedSvTimeNs;
|
||||||
|
int64_t receivedSvTimeUncertaintyNs;
|
||||||
|
double carrierToNoiseDbHz;
|
||||||
|
double pseudorangeRateMps;
|
||||||
|
double pseudorangeRateUncertaintyMps;
|
||||||
|
GnssMeasurementsAdrStateMask adrStateMask; // bitwise OR of GnssMeasurementsAdrStateBits
|
||||||
|
double adrMeters;
|
||||||
|
double adrUncertaintyMeters;
|
||||||
|
float carrierFrequencyHz;
|
||||||
|
int64_t carrierCycles;
|
||||||
|
double carrierPhase;
|
||||||
|
double carrierPhaseUncertainty;
|
||||||
|
GnssMeasurementsMultipathIndicator multipathIndicator;
|
||||||
|
double signalToNoiseRatioDb;
|
||||||
|
double agcLevelDb;
|
||||||
|
} GnssMeasurementsData;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t size; // set to sizeof(GnssMeasurementsClock)
|
||||||
|
GnssMeasurementsClockFlagsMask flags; // bitwise OR of GnssMeasurementsClockFlagsBits
|
||||||
|
int16_t leapSecond;
|
||||||
|
int64_t timeNs;
|
||||||
|
double timeUncertaintyNs;
|
||||||
|
int64_t fullBiasNs;
|
||||||
|
double biasNs;
|
||||||
|
double biasUncertaintyNs;
|
||||||
|
double driftNsps;
|
||||||
|
double driftUncertaintyNsps;
|
||||||
|
uint32_t hwClockDiscontinuityCount;
|
||||||
|
} GnssMeasurementsClock;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t size; // set to sizeof(GnssSvNotification)
|
||||||
|
size_t count; // number of SVs in the GnssSv array
|
||||||
|
GnssSv gnssSvs[GNSS_SV_MAX]; // information on a number of SVs
|
||||||
|
} GnssSvNotification;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t size; // set to sizeof(GnssNmeaNotification)
|
||||||
|
uint64_t timestamp; // timestamp
|
||||||
|
const char* nmea; // nmea text
|
||||||
|
size_t length; // length of the nmea text
|
||||||
|
} GnssNmeaNotification;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t size; // set to sizeof(GnssMeasurementsNotification)
|
||||||
|
size_t count; // number of items in GnssMeasurements array
|
||||||
|
GnssMeasurementsData measurements[GNSS_MEASUREMENTS_MAX];
|
||||||
|
GnssMeasurementsClock clock; // clock
|
||||||
|
} GnssMeasurementsNotification;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t size; // set to sizeof(GnssConfig)
|
||||||
|
GnssConfigFlagsMask flags; // bitwise OR of GnssConfigFlagsBits to mark which params are valid
|
||||||
|
GnssConfigGpsLock gpsLock;
|
||||||
|
GnssConfigSuplVersion suplVersion;
|
||||||
|
GnssConfigSetAssistanceServer assistanceServer;
|
||||||
|
GnssConfigLppProfile lppProfile;
|
||||||
|
GnssConfigLppeControlPlaneMask lppeControlPlaneMask;
|
||||||
|
GnssConfigLppeUserPlaneMask lppeUserPlaneMask;
|
||||||
|
GnssConfigAGlonassPositionProtocolMask aGlonassPositionProtocolMask;
|
||||||
|
GnssConfigEmergencyPdnForEmergencySupl emergencyPdnForEmergencySupl;
|
||||||
|
GnssConfigSuplEmergencyServices suplEmergencyServices;
|
||||||
|
GnssConfigSuplModeMask suplModeMask; //bitwise OR of GnssConfigSuplModeBits
|
||||||
|
} GnssConfig;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t size; // set to sizeof
|
||||||
|
bool mValid;
|
||||||
|
Location mLocation;
|
||||||
|
double verticalAccuracyMeters;
|
||||||
|
double speedAccuracyMetersPerSecond;
|
||||||
|
double bearingAccuracyDegrees;
|
||||||
|
timespec mUtcReported;
|
||||||
|
} GnssDebugLocation;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t size; // set to sizeof
|
||||||
|
bool mValid;
|
||||||
|
int64_t timeEstimate;
|
||||||
|
float timeUncertaintyNs;
|
||||||
|
float frequencyUncertaintyNsPerSec;
|
||||||
|
} GnssDebugTime;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t size; // set to sizeof
|
||||||
|
uint32_t svid;
|
||||||
|
GnssSvType constellation;
|
||||||
|
GnssEphemerisType mEphemerisType;
|
||||||
|
GnssEphemerisSource mEphemerisSource;
|
||||||
|
GnssEphemerisHealth mEphemerisHealth;
|
||||||
|
float ephemerisAgeSeconds;
|
||||||
|
bool serverPredictionIsAvailable;
|
||||||
|
float serverPredictionAgeSeconds;
|
||||||
|
} GnssDebugSatelliteInfo;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t size; // set to sizeof
|
||||||
|
GnssDebugLocation mLocation;
|
||||||
|
GnssDebugTime mTime;
|
||||||
|
std::vector<GnssDebugSatelliteInfo> mSatelliteInfo;
|
||||||
|
} GnssDebugReport;
|
||||||
|
|
||||||
|
/* Provides the capabilities of the system
|
||||||
|
capabilities callback is called once soon after createInstance is called */
|
||||||
|
typedef std::function<void(
|
||||||
|
LocationCapabilitiesMask capabilitiesMask // bitwise OR of LocationCapabilitiesBits
|
||||||
|
)> capabilitiesCallback;
|
||||||
|
|
||||||
|
/* Used by tracking, batching, and miscellanous APIs
|
||||||
|
responseCallback is called for every Tracking, Batching API, and Miscellanous API */
|
||||||
|
typedef std::function<void(
|
||||||
|
LocationError err, // if not SUCCESS, then id is not valid
|
||||||
|
uint32_t id // id to be associated to the request
|
||||||
|
)> responseCallback;
|
||||||
|
|
||||||
|
/* Used by APIs that gets more than one LocationError in it's response
|
||||||
|
collectiveResponseCallback is called for every geofence API call.
|
||||||
|
ids array and LocationError array are only valid until collectiveResponseCallback returns. */
|
||||||
|
typedef std::function<void(
|
||||||
|
size_t count, // number of locations in arrays
|
||||||
|
LocationError* errs, // array of LocationError associated to the request
|
||||||
|
uint32_t* ids // array of ids to be associated to the request
|
||||||
|
)> collectiveResponseCallback;
|
||||||
|
|
||||||
|
/* Used for startTracking API, optional can be NULL
|
||||||
|
trackingCallback is called when delivering a location in a tracking session
|
||||||
|
broadcasted to all clients, no matter if a session has started by client */
|
||||||
|
typedef std::function<void(
|
||||||
|
Location location
|
||||||
|
)> trackingCallback;
|
||||||
|
|
||||||
|
/* Used for startBatching API, optional can be NULL
|
||||||
|
batchingCallback is called when delivering locations in a batching session.
|
||||||
|
broadcasted to all clients, no matter if a session has started by client */
|
||||||
|
typedef std::function<void(
|
||||||
|
size_t count, // number of locations in array
|
||||||
|
Location* location, // array of locations
|
||||||
|
BatchingOptions batchingOptions // Batching options
|
||||||
|
)> batchingCallback;
|
||||||
|
|
||||||
|
typedef std::function<void(
|
||||||
|
BatchingStatusInfo batchingStatus, // batch status
|
||||||
|
std::list<uint32_t> & listOfCompletedTrips
|
||||||
|
)> batchingStatusCallback;
|
||||||
|
|
||||||
|
/* Gives GNSS Location information, optional can be NULL
|
||||||
|
gnssLocationInfoCallback is called only during a tracking session
|
||||||
|
broadcasted to all clients, no matter if a session has started by client */
|
||||||
|
typedef std::function<void(
|
||||||
|
GnssLocationInfoNotification gnssLocationInfoNotification
|
||||||
|
)> gnssLocationInfoCallback;
|
||||||
|
|
||||||
|
/* Used for addGeofences API, optional can be NULL
|
||||||
|
geofenceBreachCallback is called when any number of geofences have a state change */
|
||||||
|
typedef std::function<void(
|
||||||
|
GeofenceBreachNotification geofenceBreachNotification
|
||||||
|
)> geofenceBreachCallback;
|
||||||
|
|
||||||
|
/* Used for addGeofences API, optional can be NULL
|
||||||
|
geofenceStatusCallback is called when any number of geofences have a status change */
|
||||||
|
typedef std::function<void(
|
||||||
|
GeofenceStatusNotification geofenceStatusNotification
|
||||||
|
)> geofenceStatusCallback;
|
||||||
|
|
||||||
|
/* Network Initiated request, optional can be NULL
|
||||||
|
This callback should be responded to by calling gnssNiResponse */
|
||||||
|
typedef std::function<void(
|
||||||
|
uint32_t id, // id that should be used to respond by calling gnssNiResponse
|
||||||
|
GnssNiNotification gnssNiNotification
|
||||||
|
)> gnssNiCallback;
|
||||||
|
|
||||||
|
/* Gives GNSS SV information, optional can be NULL
|
||||||
|
gnssSvCallback is called only during a tracking session
|
||||||
|
broadcasted to all clients, no matter if a session has started by client */
|
||||||
|
typedef std::function<void(
|
||||||
|
GnssSvNotification gnssSvNotification
|
||||||
|
)> gnssSvCallback;
|
||||||
|
|
||||||
|
/* Gives GNSS NMEA data, optional can be NULL
|
||||||
|
gnssNmeaCallback is called only during a tracking session
|
||||||
|
broadcasted to all clients, no matter if a session has started by client */
|
||||||
|
typedef std::function<void(
|
||||||
|
GnssNmeaNotification gnssNmeaNotification
|
||||||
|
)> gnssNmeaCallback;
|
||||||
|
|
||||||
|
/* Gives GNSS Measurements information, optional can be NULL
|
||||||
|
gnssMeasurementsCallback is called only during a tracking session
|
||||||
|
broadcasted to all clients, no matter if a session has started by client */
|
||||||
|
typedef std::function<void(
|
||||||
|
GnssMeasurementsNotification gnssMeasurementsNotification
|
||||||
|
)> gnssMeasurementsCallback;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t size; // set to sizeof(LocationCallbacks)
|
||||||
|
capabilitiesCallback capabilitiesCb; // mandatory
|
||||||
|
responseCallback responseCb; // mandatory
|
||||||
|
collectiveResponseCallback collectiveResponseCb; // mandatory
|
||||||
|
trackingCallback trackingCb; // optional
|
||||||
|
batchingCallback batchingCb; // optional
|
||||||
|
geofenceBreachCallback geofenceBreachCb; // optional
|
||||||
|
geofenceStatusCallback geofenceStatusCb; // optional
|
||||||
|
gnssLocationInfoCallback gnssLocationInfoCb; // optional
|
||||||
|
gnssNiCallback gnssNiCb; // optional
|
||||||
|
gnssSvCallback gnssSvCb; // optional
|
||||||
|
gnssNmeaCallback gnssNmeaCb; // optional
|
||||||
|
gnssMeasurementsCallback gnssMeasurementsCb; // optional
|
||||||
|
batchingStatusCallback batchingStatusCb; // optional
|
||||||
|
} LocationCallbacks;
|
||||||
|
|
||||||
|
class LocationAPI
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
LocationAPI();
|
||||||
|
~LocationAPI();
|
||||||
|
|
||||||
|
public:
|
||||||
|
/* creates an instance to LocationAPI object.
|
||||||
|
Will return NULL if mandatory parameters are invalid or if the maximum number
|
||||||
|
of instances have been reached */
|
||||||
|
static LocationAPI* createInstance(LocationCallbacks&);
|
||||||
|
|
||||||
|
/* destroy/cleans up the instance, which should be called when LocationAPI object is
|
||||||
|
no longer needed. LocationAPI* returned from createInstance will no longer valid
|
||||||
|
after destroy is called */
|
||||||
|
void destroy();
|
||||||
|
|
||||||
|
/* updates/changes the callbacks that will be called.
|
||||||
|
mandatory callbacks must be present for callbacks to be successfully updated
|
||||||
|
no return value */
|
||||||
|
void updateCallbacks(LocationCallbacks&);
|
||||||
|
|
||||||
|
/* ================================== TRACKING ================================== */
|
||||||
|
|
||||||
|
/* startTracking starts a tracking session, which returns a session id that will be
|
||||||
|
used by the other tracking APIs and also in the responseCallback to match command
|
||||||
|
with response. locations are reported on the trackingCallback passed in createInstance
|
||||||
|
periodically according to LocationOptions.
|
||||||
|
responseCallback returns:
|
||||||
|
LOCATION_ERROR_SUCCESS if session was successfully started
|
||||||
|
LOCATION_ERROR_ALREADY_STARTED if a startTracking session is already in progress
|
||||||
|
LOCATION_ERROR_CALLBACK_MISSING if no trackingCallback was passed in createInstance
|
||||||
|
LOCATION_ERROR_INVALID_PARAMETER if LocationOptions parameter is invalid */
|
||||||
|
uint32_t startTracking(LocationOptions&); // returns session id
|
||||||
|
|
||||||
|
/* stopTracking stops a tracking session associated with id parameter.
|
||||||
|
responseCallback returns:
|
||||||
|
LOCATION_ERROR_SUCCESS if successful
|
||||||
|
LOCATION_ERROR_ID_UNKNOWN if id is not associated with a tracking session */
|
||||||
|
void stopTracking(uint32_t id);
|
||||||
|
|
||||||
|
/* updateTrackingOptions changes the LocationOptions of a tracking session associated with id
|
||||||
|
responseCallback returns:
|
||||||
|
LOCATION_ERROR_SUCCESS if successful
|
||||||
|
LOCATION_ERROR_INVALID_PARAMETER if LocationOptions parameters are invalid
|
||||||
|
LOCATION_ERROR_ID_UNKNOWN if id is not associated with a tracking session */
|
||||||
|
void updateTrackingOptions(uint32_t id, LocationOptions&);
|
||||||
|
|
||||||
|
/* ================================== BATCHING ================================== */
|
||||||
|
|
||||||
|
/* startBatching starts a batching session, which returns a session id that will be
|
||||||
|
used by the other batching APIs and also in the responseCallback to match command
|
||||||
|
with response. locations are reported on the batchingCallback passed in createInstance
|
||||||
|
periodically according to LocationOptions. A batching session starts tracking on
|
||||||
|
the low power processor and delivers them in batches by the batchingCallback when
|
||||||
|
the batch is full or when getBatchedLocations is called. This allows for the processor
|
||||||
|
that calls this API to sleep when the low power processor can batch locations in the
|
||||||
|
backgroup and wake up the processor calling the API only when the batch is full, thus
|
||||||
|
saving power
|
||||||
|
responseCallback returns:
|
||||||
|
LOCATION_ERROR_SUCCESS if session was successful
|
||||||
|
LOCATION_ERROR_ALREADY_STARTED if a startBatching session is already in progress
|
||||||
|
LOCATION_ERROR_CALLBACK_MISSING if no batchingCallback was passed in createInstance
|
||||||
|
LOCATION_ERROR_INVALID_PARAMETER if a parameter is invalid
|
||||||
|
LOCATION_ERROR_NOT_SUPPORTED if batching is not supported */
|
||||||
|
uint32_t startBatching(LocationOptions&, BatchingOptions&); // returns session id
|
||||||
|
|
||||||
|
/* stopBatching stops a batching session associated with id parameter.
|
||||||
|
responseCallback returns:
|
||||||
|
LOCATION_ERROR_SUCCESS if successful
|
||||||
|
LOCATION_ERROR_ID_UNKNOWN if id is not associated with batching session */
|
||||||
|
void stopBatching(uint32_t id);
|
||||||
|
|
||||||
|
/* updateBatchingOptions changes the LocationOptions of a batching session associated with id
|
||||||
|
responseCallback returns:
|
||||||
|
LOCATION_ERROR_SUCCESS if successful
|
||||||
|
LOCATION_ERROR_INVALID_PARAMETER if LocationOptions parameters are invalid
|
||||||
|
LOCATION_ERROR_ID_UNKNOWN if id is not associated with a batching session */
|
||||||
|
void updateBatchingOptions(uint32_t id, LocationOptions&, BatchingOptions&);
|
||||||
|
|
||||||
|
/* getBatchedLocations gets a number of locations that are currently stored/batched
|
||||||
|
on the low power processor, delivered by the batchingCallback passed in createInstance.
|
||||||
|
Location are then deleted from the batch stored on the low power processor.
|
||||||
|
responseCallback returns:
|
||||||
|
LOCATION_ERROR_SUCCESS if successful, will be followed by batchingCallback call
|
||||||
|
LOCATION_ERROR_CALLBACK_MISSING if no batchingCallback was passed in createInstance
|
||||||
|
LOCATION_ERROR_ID_UNKNOWN if id is not associated with a batching session */
|
||||||
|
void getBatchedLocations(uint32_t id, size_t count);
|
||||||
|
|
||||||
|
/* ================================== GEOFENCE ================================== */
|
||||||
|
|
||||||
|
/* addGeofences adds any number of geofences and returns an array of geofence ids that
|
||||||
|
will be used by the other geofence APIs and also in the collectiveResponseCallback to
|
||||||
|
match command with response. The geofenceBreachCallback will deliver the status of each
|
||||||
|
geofence according to the GeofenceOption for each. The geofence id array returned will
|
||||||
|
be valid until the collectiveResponseCallback is called and has returned.
|
||||||
|
collectiveResponseCallback returns:
|
||||||
|
LOCATION_ERROR_SUCCESS if session was successful
|
||||||
|
LOCATION_ERROR_CALLBACK_MISSING if no geofenceBreachCallback
|
||||||
|
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
|
||||||
|
LOCATION_ERROR_NOT_SUPPORTED if geofence is not supported */
|
||||||
|
uint32_t* addGeofences(size_t count, GeofenceOption*, GeofenceInfo*); // returns id array
|
||||||
|
|
||||||
|
/* removeGeofences removes any number of geofences. Caller should delete ids array after
|
||||||
|
removeGeofences returneds.
|
||||||
|
collectiveResponseCallback returns:
|
||||||
|
LOCATION_ERROR_SUCCESS if successful
|
||||||
|
LOCATION_ERROR_ID_UNKNOWN if id is not associated with a geofence session */
|
||||||
|
void removeGeofences(size_t count, uint32_t* ids);
|
||||||
|
|
||||||
|
/* modifyGeofences modifies any number of geofences. Caller should delete ids array after
|
||||||
|
modifyGeofences returns.
|
||||||
|
collectiveResponseCallback returns:
|
||||||
|
LOCATION_ERROR_SUCCESS if successful
|
||||||
|
LOCATION_ERROR_ID_UNKNOWN if id is not associated with a geofence session
|
||||||
|
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid */
|
||||||
|
void modifyGeofences(size_t count, uint32_t* ids, GeofenceOption* options);
|
||||||
|
|
||||||
|
/* pauseGeofences pauses any number of geofences, which is similar to removeGeofences,
|
||||||
|
only that they can be resumed at any time. Caller should delete ids array after
|
||||||
|
pauseGeofences returns.
|
||||||
|
collectiveResponseCallback returns:
|
||||||
|
LOCATION_ERROR_SUCCESS if successful
|
||||||
|
LOCATION_ERROR_ID_UNKNOWN if id is not associated with a geofence session */
|
||||||
|
void pauseGeofences(size_t count, uint32_t* ids);
|
||||||
|
|
||||||
|
/* resumeGeofences resumes any number of geofences that are currently paused. Caller should
|
||||||
|
delete ids array after resumeGeofences returns.
|
||||||
|
collectiveResponseCallback returns:
|
||||||
|
LOCATION_ERROR_SUCCESS if successful
|
||||||
|
LOCATION_ERROR_ID_UNKNOWN if id is not associated with a geofence session */
|
||||||
|
void resumeGeofences(size_t count, uint32_t* ids);
|
||||||
|
|
||||||
|
/* ================================== GNSS ====================================== */
|
||||||
|
|
||||||
|
/* gnssNiResponse is called in response to a gnssNiCallback.
|
||||||
|
responseCallback returns:
|
||||||
|
LOCATION_ERROR_SUCCESS if session was successful
|
||||||
|
LOCATION_ERROR_INVALID_PARAMETER if any parameters in GnssNiResponse are invalid
|
||||||
|
LOCATION_ERROR_ID_UNKNOWN if id does not match a gnssNiCallback */
|
||||||
|
void gnssNiResponse(uint32_t id, GnssNiResponse response);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t size; // set to sizeof(LocationControlCallbacks)
|
||||||
|
responseCallback responseCb; // mandatory
|
||||||
|
collectiveResponseCallback collectiveResponseCb; // mandatory
|
||||||
|
} LocationControlCallbacks;
|
||||||
|
|
||||||
|
class LocationControlAPI
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
LocationControlAPI();
|
||||||
|
~LocationControlAPI();
|
||||||
|
|
||||||
|
public:
|
||||||
|
/* creates an instance to LocationControlAPI object.
|
||||||
|
Will return NULL if mandatory parameters are invalid or if the maximum number
|
||||||
|
of instances have been reached. Only once instance allowed */
|
||||||
|
static LocationControlAPI* createInstance(LocationControlCallbacks&);
|
||||||
|
|
||||||
|
/* destroy/cleans up the instance, which should be called when LocationControlAPI object is
|
||||||
|
no longer needed. LocationControlAPI* returned from createInstance will no longer valid
|
||||||
|
after destroy is called */
|
||||||
|
void destroy();
|
||||||
|
|
||||||
|
/* enable will enable specific location technology to be used for calculation locations and
|
||||||
|
will effectively start a control session if call is successful, which returns a session id
|
||||||
|
that will be returned in responseCallback to match command with response. The session id is
|
||||||
|
also needed to call the disable command.
|
||||||
|
This effect is global for all clients of LocationAPI
|
||||||
|
responseCallback returns:
|
||||||
|
LOCATION_ERROR_SUCCESS if successful
|
||||||
|
LOCATION_ERROR_ALREADY_STARTED if an enable was already called for this techType
|
||||||
|
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
|
||||||
|
LOCATION_ERROR_GENERAL_FAILURE if failure for any other reason */
|
||||||
|
uint32_t enable(LocationTechnologyType techType);
|
||||||
|
|
||||||
|
/* disable will disable specific location technology to be used for calculation locations and
|
||||||
|
effectively ends the control session if call is successful.
|
||||||
|
id parameter is the session id that was returned in enable responseCallback for techType.
|
||||||
|
The session id is no longer valid after disable's responseCallback returns success.
|
||||||
|
This effect is global for all clients of LocationAPI
|
||||||
|
responseCallback returns:
|
||||||
|
LOCATION_ERROR_SUCCESS if successful
|
||||||
|
LOCATION_ERROR_ID_UNKNOWN if id was not returned from responseCallback from enable
|
||||||
|
LOCATION_ERROR_GENERAL_FAILURE if failure for any other reason */
|
||||||
|
void disable(uint32_t id);
|
||||||
|
|
||||||
|
/* gnssUpdateConfig updates the gnss specific configuration, which returns a session id array
|
||||||
|
with an id for each of the bits set in GnssConfig.flags, order from low bits to high bits.
|
||||||
|
The response for each config that is set will be returned in collectiveResponseCallback.
|
||||||
|
The session id array returned will be valid until the collectiveResponseCallback is called
|
||||||
|
and has returned. This effect is global for all clients of LocationAPI
|
||||||
|
collectiveResponseCallback returns:
|
||||||
|
LOCATION_ERROR_SUCCESS if session was successful
|
||||||
|
LOCATION_ERROR_INVALID_PARAMETER if any other parameters are invalid
|
||||||
|
LOCATION_ERROR_GENERAL_FAILURE if failure for any other reason */
|
||||||
|
uint32_t* gnssUpdateConfig(GnssConfig config);
|
||||||
|
|
||||||
|
/* delete specific gnss aiding data for testing, which returns a session id
|
||||||
|
that will be returned in responseCallback to match command with response.
|
||||||
|
Only allowed in userdebug builds. This effect is global for all clients of LocationAPI
|
||||||
|
responseCallback returns:
|
||||||
|
LOCATION_ERROR_SUCCESS if successful
|
||||||
|
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
|
||||||
|
LOCATION_ERROR_NOT_SUPPORTED if build is not userdebug */
|
||||||
|
uint32_t gnssDeleteAidingData(GnssAidingData& data);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* LOCATION_H */
|
911
gps/location/LocationAPIClientBase.cpp
Normal file
911
gps/location/LocationAPIClientBase.cpp
Normal file
|
@ -0,0 +1,911 @@
|
||||||
|
/* Copyright (c) 2017 The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LOG_NDDEBUG 0
|
||||||
|
#define LOG_TAG "LocSvc_APIClientBase"
|
||||||
|
|
||||||
|
#include <platform_lib_log_util.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <loc_cfg.h>
|
||||||
|
#include "LocationAPIClientBase.h"
|
||||||
|
|
||||||
|
#define FLP_CONF_FILE "/etc/flp.conf"
|
||||||
|
#define GEOFENCE_SESSION_ID 0xFFFFFFFF
|
||||||
|
#define CONFIG_SESSION_ID 0xFFFFFFFF
|
||||||
|
|
||||||
|
// LocationAPIControlClient
|
||||||
|
LocationAPIControlClient::LocationAPIControlClient() :
|
||||||
|
mEnabled(false)
|
||||||
|
{
|
||||||
|
pthread_mutex_init(&mMutex, nullptr);
|
||||||
|
|
||||||
|
for (int i = 0; i < CTRL_REQUEST_MAX; i++) {
|
||||||
|
mRequestQueues[i].reset(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&mConfig, 0, sizeof(GnssConfig));
|
||||||
|
|
||||||
|
LocationControlCallbacks locationControlCallbacks;
|
||||||
|
locationControlCallbacks.size = sizeof(LocationControlCallbacks);
|
||||||
|
|
||||||
|
locationControlCallbacks.responseCb =
|
||||||
|
[this](LocationError error, uint32_t id) {
|
||||||
|
onCtrlResponseCb(error, id);
|
||||||
|
};
|
||||||
|
locationControlCallbacks.collectiveResponseCb =
|
||||||
|
[this](size_t count, LocationError* errors, uint32_t* ids) {
|
||||||
|
onCtrlCollectiveResponseCb(count, errors, ids);
|
||||||
|
};
|
||||||
|
|
||||||
|
mLocationControlAPI = LocationControlAPI::createInstance(locationControlCallbacks);
|
||||||
|
}
|
||||||
|
|
||||||
|
LocationAPIControlClient::~LocationAPIControlClient()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&mMutex);
|
||||||
|
|
||||||
|
if (mLocationControlAPI) {
|
||||||
|
mLocationControlAPI->destroy();
|
||||||
|
mLocationControlAPI = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < CTRL_REQUEST_MAX; i++) {
|
||||||
|
mRequestQueues[i].reset(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
|
||||||
|
pthread_mutex_destroy(&mMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t LocationAPIControlClient::locAPIGnssDeleteAidingData(GnssAidingData& data)
|
||||||
|
{
|
||||||
|
uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
|
||||||
|
pthread_mutex_lock(&mMutex);
|
||||||
|
if (mLocationControlAPI) {
|
||||||
|
uint32_t session = mLocationControlAPI->gnssDeleteAidingData(data);
|
||||||
|
LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, session);
|
||||||
|
mRequestQueues[CTRL_REQUEST_DELETEAIDINGDATA].reset(session);
|
||||||
|
mRequestQueues[CTRL_REQUEST_DELETEAIDINGDATA].push(new GnssDeleteAidingDataRequest(*this));
|
||||||
|
|
||||||
|
retVal = LOCATION_ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t LocationAPIControlClient::locAPIEnable(LocationTechnologyType techType)
|
||||||
|
{
|
||||||
|
uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
|
||||||
|
pthread_mutex_lock(&mMutex);
|
||||||
|
if (mEnabled) {
|
||||||
|
// just return success if already enabled
|
||||||
|
retVal = LOCATION_ERROR_SUCCESS;
|
||||||
|
} else if (mLocationControlAPI) {
|
||||||
|
uint32_t session = mLocationControlAPI->enable(techType);
|
||||||
|
LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, session);
|
||||||
|
mRequestQueues[CTRL_REQUEST_CONTROL].reset(session);
|
||||||
|
mRequestQueues[CTRL_REQUEST_CONTROL].push(new EnableRequest(*this));
|
||||||
|
retVal = LOCATION_ERROR_SUCCESS;
|
||||||
|
mEnabled = true;
|
||||||
|
} else {
|
||||||
|
LOC_LOGE("%s:%d] failed.", __FUNCTION__, __LINE__);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocationAPIControlClient::locAPIDisable()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&mMutex);
|
||||||
|
if (mEnabled && mLocationControlAPI) {
|
||||||
|
uint32_t session = 0;
|
||||||
|
session = mRequestQueues[CTRL_REQUEST_CONTROL].getSession();
|
||||||
|
if (session > 0) {
|
||||||
|
mRequestQueues[CTRL_REQUEST_CONTROL].push(new DisableRequest(*this));
|
||||||
|
mLocationControlAPI->disable(session);
|
||||||
|
mEnabled = false;
|
||||||
|
} else {
|
||||||
|
LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__, session);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t LocationAPIControlClient::locAPIGnssUpdateConfig(GnssConfig config)
|
||||||
|
{
|
||||||
|
uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
|
||||||
|
if (memcmp(&mConfig, &config, sizeof(GnssConfig)) == 0) {
|
||||||
|
LOC_LOGV("%s:%d] GnssConfig is identical to previous call", __FUNCTION__, __LINE__);
|
||||||
|
retVal = LOCATION_ERROR_SUCCESS;
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_lock(&mMutex);
|
||||||
|
if (mLocationControlAPI) {
|
||||||
|
|
||||||
|
memcpy(&mConfig, &config, sizeof(GnssConfig));
|
||||||
|
|
||||||
|
uint32_t session = 0;
|
||||||
|
uint32_t* idArray = mLocationControlAPI->gnssUpdateConfig(config);
|
||||||
|
LOC_LOGV("%s:%d] gnssUpdateConfig return array: %p", __FUNCTION__, __LINE__, idArray);
|
||||||
|
if (idArray != nullptr) {
|
||||||
|
if (mRequestQueues[CTRL_REQUEST_CONFIG].getSession() != CONFIG_SESSION_ID) {
|
||||||
|
mRequestQueues[CTRL_REQUEST_CONFIG].reset(CONFIG_SESSION_ID);
|
||||||
|
}
|
||||||
|
mRequestQueues[CTRL_REQUEST_CONFIG].push(new GnssUpdateConfigRequest(*this));
|
||||||
|
retVal = LOCATION_ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocationAPIControlClient::onCtrlResponseCb(LocationError error, uint32_t id)
|
||||||
|
{
|
||||||
|
if (error != LOCATION_ERROR_SUCCESS) {
|
||||||
|
LOC_LOGE("%s:%d] ERROR: %d ID: %d", __FUNCTION__, __LINE__, error, id);
|
||||||
|
} else {
|
||||||
|
LOC_LOGV("%s:%d] SUCCESS: %d id: %d", __FUNCTION__, __LINE__, error, id);
|
||||||
|
}
|
||||||
|
LocationAPIRequest* request = getRequestBySession(id);
|
||||||
|
if (request) {
|
||||||
|
request->onResponse(error, id);
|
||||||
|
delete request;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocationAPIControlClient::onCtrlCollectiveResponseCb(
|
||||||
|
size_t count, LocationError* errors, uint32_t* ids)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
if (errors[i] != LOCATION_ERROR_SUCCESS) {
|
||||||
|
LOC_LOGE("%s:%d] ERROR: %d ID: %d", __FUNCTION__, __LINE__, errors[i], ids[i]);
|
||||||
|
} else {
|
||||||
|
LOC_LOGV("%s:%d] SUCCESS: %d id: %d", __FUNCTION__, __LINE__, errors[i], ids[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LocationAPIRequest* request = nullptr;
|
||||||
|
pthread_mutex_lock(&mMutex);
|
||||||
|
if (mRequestQueues[CTRL_REQUEST_CONFIG].getSession() == CONFIG_SESSION_ID) {
|
||||||
|
request = mRequestQueues[CTRL_REQUEST_CONFIG].pop();
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
if (request) {
|
||||||
|
request->onCollectiveResponse(count, errors, ids);
|
||||||
|
delete request;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LocationAPIRequest* LocationAPIControlClient::getRequestBySession(uint32_t session)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&mMutex);
|
||||||
|
LocationAPIRequest* request = nullptr;
|
||||||
|
for (int i = 0; i < CTRL_REQUEST_MAX; i++) {
|
||||||
|
if (i != CTRL_REQUEST_CONFIG &&
|
||||||
|
mRequestQueues[i].getSession() == session) {
|
||||||
|
request = mRequestQueues[i].pop();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
// LocationAPIClientBase
|
||||||
|
LocationAPIClientBase::LocationAPIClientBase() :
|
||||||
|
mGeofenceBreachCallback(nullptr),
|
||||||
|
mBatchingStatusCallback(nullptr),
|
||||||
|
mLocationAPI(nullptr),
|
||||||
|
mBatchSize(-1),
|
||||||
|
mTracking(false)
|
||||||
|
{
|
||||||
|
|
||||||
|
// use recursive mutex, in case callback come from the same thread
|
||||||
|
pthread_mutexattr_t attr;
|
||||||
|
pthread_mutexattr_init(&attr);
|
||||||
|
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||||
|
pthread_mutex_init(&mMutex, &attr);
|
||||||
|
|
||||||
|
for (int i = 0; i < REQUEST_MAX; i++) {
|
||||||
|
mRequestQueues[i].reset(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocationAPIClientBase::locAPISetCallbacks(LocationCallbacks& locationCallbacks)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&mMutex);
|
||||||
|
|
||||||
|
if (locationCallbacks.geofenceBreachCb != nullptr) {
|
||||||
|
mGeofenceBreachCallback = locationCallbacks.geofenceBreachCb;
|
||||||
|
locationCallbacks.geofenceBreachCb =
|
||||||
|
[this](GeofenceBreachNotification geofenceBreachNotification) {
|
||||||
|
beforeGeofenceBreachCb(geofenceBreachNotification);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
locationCallbacks.capabilitiesCb =
|
||||||
|
[this](LocationCapabilitiesMask capabilitiesMask) {
|
||||||
|
onCapabilitiesCb(capabilitiesMask);
|
||||||
|
};
|
||||||
|
locationCallbacks.responseCb = [this](LocationError error, uint32_t id) {
|
||||||
|
onResponseCb(error, id);
|
||||||
|
};
|
||||||
|
locationCallbacks.collectiveResponseCb =
|
||||||
|
[this](size_t count, LocationError* errors, uint32_t* ids) {
|
||||||
|
onCollectiveResponseCb(count, errors, ids);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (locationCallbacks.batchingStatusCb != nullptr) {
|
||||||
|
mBatchingStatusCallback = locationCallbacks.batchingStatusCb;
|
||||||
|
locationCallbacks.batchingStatusCb =
|
||||||
|
[this](BatchingStatusInfo batchStatus, std::list<uint32_t> & tripCompletedList) {
|
||||||
|
beforeBatchingStatusCb(batchStatus, tripCompletedList);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mLocationAPI == nullptr ) {
|
||||||
|
mLocationAPI = LocationAPI::createInstance(locationCallbacks);
|
||||||
|
} else {
|
||||||
|
mLocationAPI->updateCallbacks(locationCallbacks);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
LocationAPIClientBase::~LocationAPIClientBase()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&mMutex);
|
||||||
|
|
||||||
|
mGeofenceBreachCallback = nullptr;
|
||||||
|
|
||||||
|
if (mLocationAPI) {
|
||||||
|
mLocationAPI->destroy();
|
||||||
|
mLocationAPI = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < REQUEST_MAX; i++) {
|
||||||
|
mRequestQueues[i].reset(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
|
||||||
|
pthread_mutex_destroy(&mMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t LocationAPIClientBase::locAPIStartTracking(LocationOptions& options)
|
||||||
|
{
|
||||||
|
uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
|
||||||
|
pthread_mutex_lock(&mMutex);
|
||||||
|
if (mLocationAPI) {
|
||||||
|
if (mTracking) {
|
||||||
|
LOC_LOGW("%s:%d] Existing tracking session present", __FUNCTION__, __LINE__);
|
||||||
|
} else {
|
||||||
|
uint32_t session = mLocationAPI->startTracking(options);
|
||||||
|
LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, session);
|
||||||
|
// onResponseCb might be called from other thread immediately after
|
||||||
|
// startTracking returns, so we are not going to unlock mutex
|
||||||
|
// until StartTrackingRequest is pushed into mRequestQueues[REQUEST_TRACKING]
|
||||||
|
mRequestQueues[REQUEST_TRACKING].reset(session);
|
||||||
|
mRequestQueues[REQUEST_TRACKING].push(new StartTrackingRequest(*this));
|
||||||
|
mTracking = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
retVal = LOCATION_ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocationAPIClientBase::locAPIStopTracking()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&mMutex);
|
||||||
|
if (mLocationAPI) {
|
||||||
|
uint32_t session = 0;
|
||||||
|
session = mRequestQueues[REQUEST_TRACKING].getSession();
|
||||||
|
if (session > 0) {
|
||||||
|
mRequestQueues[REQUEST_TRACKING].push(new StopTrackingRequest(*this));
|
||||||
|
mLocationAPI->stopTracking(session);
|
||||||
|
mTracking = false;
|
||||||
|
} else {
|
||||||
|
LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__, session);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocationAPIClientBase::locAPIUpdateTrackingOptions(LocationOptions& options)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&mMutex);
|
||||||
|
if (mLocationAPI) {
|
||||||
|
uint32_t session = 0;
|
||||||
|
session = mRequestQueues[REQUEST_TRACKING].getSession();
|
||||||
|
if (session > 0) {
|
||||||
|
mRequestQueues[REQUEST_TRACKING].push(new UpdateTrackingOptionsRequest(*this));
|
||||||
|
mLocationAPI->updateTrackingOptions(session, options);
|
||||||
|
} else {
|
||||||
|
LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__, session);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t LocationAPIClientBase::locAPIGetBatchSize()
|
||||||
|
{
|
||||||
|
if (mBatchSize == -1) {
|
||||||
|
const loc_param_s_type flp_conf_param_table[] =
|
||||||
|
{
|
||||||
|
{"BATCH_SIZE", &mBatchSize, nullptr, 'n'},
|
||||||
|
};
|
||||||
|
UTIL_READ_CONF(FLP_CONF_FILE, flp_conf_param_table);
|
||||||
|
if (mBatchSize < 0) {
|
||||||
|
// set mBatchSize to 0 if we got an illegal value from config file
|
||||||
|
mBatchSize = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mBatchSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t LocationAPIClientBase::locAPIStartSession(uint32_t id, uint32_t sessionMode,
|
||||||
|
LocationOptions& locationOptions)
|
||||||
|
{
|
||||||
|
uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
|
||||||
|
pthread_mutex_lock(&mMutex);
|
||||||
|
if (mLocationAPI) {
|
||||||
|
|
||||||
|
if (mSessionBiDict.hasId(id)) {
|
||||||
|
LOC_LOGE("%s:%d] session %d has already started.", __FUNCTION__, __LINE__, id);
|
||||||
|
retVal = LOCATION_ERROR_ALREADY_STARTED;
|
||||||
|
} else {
|
||||||
|
uint32_t trackingSession = 0;
|
||||||
|
uint32_t batchingSession = 0;
|
||||||
|
|
||||||
|
if (sessionMode == SESSION_MODE_ON_FIX) {
|
||||||
|
trackingSession = mLocationAPI->startTracking(locationOptions);
|
||||||
|
LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, trackingSession);
|
||||||
|
mRequestQueues[REQUEST_SESSION].push(new StartTrackingRequest(*this));
|
||||||
|
} else {
|
||||||
|
// Fill in the batch mode
|
||||||
|
BatchingOptions batchOptions = {};
|
||||||
|
batchOptions.size = sizeof(BatchingOptions);
|
||||||
|
switch (sessionMode) {
|
||||||
|
case SESSION_MODE_ON_FULL:
|
||||||
|
batchOptions.batchingMode = BATCHING_MODE_ROUTINE;
|
||||||
|
break;
|
||||||
|
case SESSION_MODE_ON_TRIP_COMPLETED:
|
||||||
|
batchOptions.batchingMode = BATCHING_MODE_TRIP;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
batchOptions.batchingMode = BATCHING_MODE_NO_AUTO_REPORT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
batchingSession = mLocationAPI->startBatching(locationOptions, batchOptions);
|
||||||
|
LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, batchingSession);
|
||||||
|
mRequestQueues[REQUEST_SESSION].setSession(batchingSession);
|
||||||
|
mRequestQueues[REQUEST_SESSION].push(new StartBatchingRequest(*this));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t session = ((sessionMode != SESSION_MODE_ON_FIX) ?
|
||||||
|
batchingSession : trackingSession);
|
||||||
|
|
||||||
|
SessionEntity entity;
|
||||||
|
entity.id = id;
|
||||||
|
entity.trackingSession = trackingSession;
|
||||||
|
entity.batchingSession = batchingSession;
|
||||||
|
entity.sessionMode = sessionMode;
|
||||||
|
mSessionBiDict.set(id, session, entity);
|
||||||
|
|
||||||
|
retVal = LOCATION_ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t LocationAPIClientBase::locAPIStopSession(uint32_t id)
|
||||||
|
{
|
||||||
|
uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
|
||||||
|
pthread_mutex_lock(&mMutex);
|
||||||
|
if (mLocationAPI) {
|
||||||
|
|
||||||
|
if (mSessionBiDict.hasId(id)) {
|
||||||
|
SessionEntity entity = mSessionBiDict.getExtById(id);
|
||||||
|
|
||||||
|
uint32_t trackingSession = entity.trackingSession;
|
||||||
|
uint32_t batchingSession = entity.batchingSession;
|
||||||
|
uint32_t sMode = entity.sessionMode;
|
||||||
|
|
||||||
|
if (sMode == SESSION_MODE_ON_FIX) {
|
||||||
|
mRequestQueues[REQUEST_SESSION].push(new StopTrackingRequest(*this));
|
||||||
|
mLocationAPI->stopTracking(trackingSession);
|
||||||
|
} else {
|
||||||
|
mRequestQueues[REQUEST_SESSION].push(new StopBatchingRequest(*this));
|
||||||
|
mLocationAPI->stopBatching(batchingSession);
|
||||||
|
}
|
||||||
|
|
||||||
|
retVal = LOCATION_ERROR_SUCCESS;
|
||||||
|
} else {
|
||||||
|
retVal = LOCATION_ERROR_ID_UNKNOWN;
|
||||||
|
LOC_LOGE("%s:%d] session %d is not exist.", __FUNCTION__, __LINE__, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t LocationAPIClientBase::locAPIUpdateSessionOptions(uint32_t id, uint32_t sessionMode,
|
||||||
|
LocationOptions& options)
|
||||||
|
{
|
||||||
|
uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
|
||||||
|
pthread_mutex_lock(&mMutex);
|
||||||
|
if (mLocationAPI) {
|
||||||
|
|
||||||
|
if (mSessionBiDict.hasId(id)) {
|
||||||
|
SessionEntity entity = mSessionBiDict.getExtById(id);
|
||||||
|
|
||||||
|
uint32_t trackingSession = entity.trackingSession;
|
||||||
|
uint32_t batchingSession = entity.batchingSession;
|
||||||
|
uint32_t sMode = entity.sessionMode;
|
||||||
|
|
||||||
|
if (sessionMode == SESSION_MODE_ON_FIX) {
|
||||||
|
// we only add an UpdateTrackingOptionsRequest to mRequestQueues[REQUEST_SESSION],
|
||||||
|
// even if this update request will stop batching and then start tracking.
|
||||||
|
mRequestQueues[REQUEST_SESSION].push(new UpdateTrackingOptionsRequest(*this));
|
||||||
|
if (sMode == SESSION_MODE_ON_FIX) {
|
||||||
|
mLocationAPI->updateTrackingOptions(trackingSession, options);
|
||||||
|
} else {
|
||||||
|
// stop batching
|
||||||
|
// batchingSession will be removed from mSessionBiDict soon,
|
||||||
|
// so we don't need to add a new request to mRequestQueues[REQUEST_SESSION].
|
||||||
|
mLocationAPI->stopBatching(batchingSession);
|
||||||
|
batchingSession = 0;
|
||||||
|
mRequestQueues[REQUEST_SESSION].setSession(batchingSession);
|
||||||
|
|
||||||
|
// start tracking
|
||||||
|
trackingSession = mLocationAPI->startTracking(options);
|
||||||
|
LOC_LOGI("%s:%d] start new session: %d",
|
||||||
|
__FUNCTION__, __LINE__, trackingSession);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// we only add an UpdateBatchingOptionsRequest to mRequestQueues[REQUEST_SESSION],
|
||||||
|
// even if this update request will stop tracking and then start batching.
|
||||||
|
mRequestQueues[REQUEST_SESSION].push(new UpdateBatchingOptionsRequest(*this));
|
||||||
|
BatchingOptions batchOptions = {};
|
||||||
|
batchOptions.size = sizeof(BatchingOptions);
|
||||||
|
switch (sessionMode) {
|
||||||
|
case SESSION_MODE_ON_FULL:
|
||||||
|
batchOptions.batchingMode = BATCHING_MODE_ROUTINE;
|
||||||
|
break;
|
||||||
|
case SESSION_MODE_ON_TRIP_COMPLETED:
|
||||||
|
batchOptions.batchingMode = BATCHING_MODE_TRIP;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
batchOptions.batchingMode = BATCHING_MODE_NO_AUTO_REPORT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sMode == SESSION_MODE_ON_FIX) {
|
||||||
|
// stop tracking
|
||||||
|
// trackingSession will be removed from mSessionBiDict soon,
|
||||||
|
// so we don't need to add a new request to mRequestQueues[REQUEST_SESSION].
|
||||||
|
mLocationAPI->stopTracking(trackingSession);
|
||||||
|
trackingSession = 0;
|
||||||
|
|
||||||
|
// start batching
|
||||||
|
batchingSession = mLocationAPI->startBatching(options, batchOptions);
|
||||||
|
LOC_LOGI("%s:%d] start new session: %d",
|
||||||
|
__FUNCTION__, __LINE__, batchingSession);
|
||||||
|
mRequestQueues[REQUEST_SESSION].setSession(batchingSession);
|
||||||
|
} else {
|
||||||
|
mLocationAPI->updateBatchingOptions(batchingSession, options, batchOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t session = ((sessionMode != SESSION_MODE_ON_FIX) ?
|
||||||
|
batchingSession : trackingSession);
|
||||||
|
|
||||||
|
entity.trackingSession = trackingSession;
|
||||||
|
entity.batchingSession = batchingSession;
|
||||||
|
entity.sessionMode = sessionMode;
|
||||||
|
// remove the old values from mSessionBiDict before we add a new one.
|
||||||
|
mSessionBiDict.rmById(id);
|
||||||
|
mSessionBiDict.set(id, session, entity);
|
||||||
|
|
||||||
|
retVal = LOCATION_ERROR_SUCCESS;
|
||||||
|
} else {
|
||||||
|
retVal = LOCATION_ERROR_ID_UNKNOWN;
|
||||||
|
LOC_LOGE("%s:%d] session %d is not exist.", __FUNCTION__, __LINE__, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t LocationAPIClientBase::locAPIGetBatchedLocations(uint32_t id, size_t count)
|
||||||
|
{
|
||||||
|
uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
|
||||||
|
pthread_mutex_lock(&mMutex);
|
||||||
|
if (mLocationAPI) {
|
||||||
|
if (mSessionBiDict.hasId(id)) {
|
||||||
|
SessionEntity entity = mSessionBiDict.getExtById(id);
|
||||||
|
uint32_t batchingSession = entity.batchingSession;
|
||||||
|
mRequestQueues[REQUEST_SESSION].push(new GetBatchedLocationsRequest(*this));
|
||||||
|
mLocationAPI->getBatchedLocations(batchingSession, count);
|
||||||
|
retVal = LOCATION_ERROR_SUCCESS;
|
||||||
|
} else {
|
||||||
|
retVal = LOCATION_ERROR_ID_UNKNOWN;
|
||||||
|
LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t LocationAPIClientBase::locAPIAddGeofences(
|
||||||
|
size_t count, uint32_t* ids, GeofenceOption* options, GeofenceInfo* data)
|
||||||
|
{
|
||||||
|
uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
|
||||||
|
pthread_mutex_lock(&mMutex);
|
||||||
|
if (mLocationAPI) {
|
||||||
|
if (mRequestQueues[REQUEST_GEOFENCE].getSession() != GEOFENCE_SESSION_ID) {
|
||||||
|
mRequestQueues[REQUEST_GEOFENCE].reset(GEOFENCE_SESSION_ID);
|
||||||
|
}
|
||||||
|
uint32_t* sessions = mLocationAPI->addGeofences(count, options, data);
|
||||||
|
if (sessions) {
|
||||||
|
LOC_LOGI("%s:%d] start new sessions: %p", __FUNCTION__, __LINE__, sessions);
|
||||||
|
mRequestQueues[REQUEST_GEOFENCE].push(new AddGeofencesRequest(*this));
|
||||||
|
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
mGeofenceBiDict.set(ids[i], sessions[i], options[i].breachTypeMask);
|
||||||
|
}
|
||||||
|
retVal = LOCATION_ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocationAPIClientBase::locAPIRemoveGeofences(size_t count, uint32_t* ids)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&mMutex);
|
||||||
|
if (mLocationAPI) {
|
||||||
|
uint32_t* sessions = (uint32_t*)malloc(sizeof(uint32_t) * count);
|
||||||
|
if (sessions == NULL) {
|
||||||
|
LOC_LOGE("%s:%d] Failed to allocate %zu bytes !",
|
||||||
|
__FUNCTION__, __LINE__, sizeof(uint32_t) * count);
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mRequestQueues[REQUEST_GEOFENCE].getSession() == GEOFENCE_SESSION_ID) {
|
||||||
|
size_t j = 0;
|
||||||
|
uint32_t id_cb;
|
||||||
|
LocationError err;
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
sessions[j] = mGeofenceBiDict.getSession(ids[i]);
|
||||||
|
id_cb = ids[i];
|
||||||
|
if (sessions[j] > 0) {
|
||||||
|
mGeofenceBiDict.rmBySession(sessions[j]);
|
||||||
|
err = LOCATION_ERROR_SUCCESS;
|
||||||
|
onRemoveGeofencesCb(1, &err, &id_cb);
|
||||||
|
j++;
|
||||||
|
} else {
|
||||||
|
err = LOCATION_ERROR_ID_UNKNOWN;
|
||||||
|
onRemoveGeofencesCb(1, &err, &id_cb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j > 0) {
|
||||||
|
mRequestQueues[REQUEST_GEOFENCE].push(new RemoveGeofencesRequest(*this));
|
||||||
|
mLocationAPI->removeGeofences(j, sessions);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__,
|
||||||
|
mRequestQueues[REQUEST_GEOFENCE].getSession());
|
||||||
|
}
|
||||||
|
|
||||||
|
free(sessions);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocationAPIClientBase::locAPIModifyGeofences(
|
||||||
|
size_t count, uint32_t* ids, GeofenceOption* options)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&mMutex);
|
||||||
|
if (mLocationAPI) {
|
||||||
|
uint32_t* sessions = (uint32_t*)malloc(sizeof(uint32_t) * count);
|
||||||
|
if (sessions == NULL) {
|
||||||
|
LOC_LOGE("%s:%d] Failed to allocate %zu bytes !",
|
||||||
|
__FUNCTION__, __LINE__, sizeof(uint32_t) * count);
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mRequestQueues[REQUEST_GEOFENCE].getSession() == GEOFENCE_SESSION_ID) {
|
||||||
|
size_t j = 0;
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
sessions[j] = mGeofenceBiDict.getSession(ids[i]);
|
||||||
|
if (sessions[j] > 0) {
|
||||||
|
mGeofenceBiDict.set(ids[i], sessions[j], options[i].breachTypeMask);
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (j > 0) {
|
||||||
|
mRequestQueues[REQUEST_GEOFENCE].push(new ModifyGeofencesRequest(*this));
|
||||||
|
mLocationAPI->modifyGeofences(j, sessions, options);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__,
|
||||||
|
mRequestQueues[REQUEST_GEOFENCE].getSession());
|
||||||
|
}
|
||||||
|
|
||||||
|
free(sessions);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocationAPIClientBase::locAPIPauseGeofences(size_t count, uint32_t* ids)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&mMutex);
|
||||||
|
if (mLocationAPI) {
|
||||||
|
uint32_t* sessions = (uint32_t*)malloc(sizeof(uint32_t) * count);
|
||||||
|
if (sessions == NULL) {
|
||||||
|
LOC_LOGE("%s:%d] Failed to allocate %zu bytes !",
|
||||||
|
__FUNCTION__, __LINE__, sizeof(uint32_t) * count);
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mRequestQueues[REQUEST_GEOFENCE].getSession() == GEOFENCE_SESSION_ID) {
|
||||||
|
size_t j = 0;
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
sessions[j] = mGeofenceBiDict.getSession(ids[i]);
|
||||||
|
if (sessions[j] > 0) {
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (j > 0) {
|
||||||
|
mRequestQueues[REQUEST_GEOFENCE].push(new PauseGeofencesRequest(*this));
|
||||||
|
mLocationAPI->pauseGeofences(j, sessions);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__,
|
||||||
|
mRequestQueues[REQUEST_GEOFENCE].getSession());
|
||||||
|
}
|
||||||
|
|
||||||
|
free(sessions);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocationAPIClientBase::locAPIResumeGeofences(
|
||||||
|
size_t count, uint32_t* ids, GeofenceBreachTypeMask* mask)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&mMutex);
|
||||||
|
if (mLocationAPI) {
|
||||||
|
uint32_t* sessions = (uint32_t*)malloc(sizeof(uint32_t) * count);
|
||||||
|
if (sessions == NULL) {
|
||||||
|
LOC_LOGE("%s:%d] Failed to allocate %zu bytes !",
|
||||||
|
__FUNCTION__, __LINE__, sizeof(uint32_t) * count);
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mRequestQueues[REQUEST_GEOFENCE].getSession() == GEOFENCE_SESSION_ID) {
|
||||||
|
size_t j = 0;
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
sessions[j] = mGeofenceBiDict.getSession(ids[i]);
|
||||||
|
if (sessions[j] > 0) {
|
||||||
|
if (mask) {
|
||||||
|
mGeofenceBiDict.set(ids[i], sessions[j], mask[i]);
|
||||||
|
}
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (j > 0) {
|
||||||
|
mRequestQueues[REQUEST_GEOFENCE].push(new ResumeGeofencesRequest(*this));
|
||||||
|
mLocationAPI->resumeGeofences(j, sessions);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__,
|
||||||
|
mRequestQueues[REQUEST_GEOFENCE].getSession());
|
||||||
|
}
|
||||||
|
|
||||||
|
free(sessions);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocationAPIClientBase::locAPIRemoveAllGeofences()
|
||||||
|
{
|
||||||
|
std::vector<uint32_t> sessionsVec = mGeofenceBiDict.getAllSessions();
|
||||||
|
locAPIRemoveGeofences(sessionsVec.size(), &sessionsVec[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocationAPIClientBase::locAPIGnssNiResponse(uint32_t id, GnssNiResponse response)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&mMutex);
|
||||||
|
if (mLocationAPI) {
|
||||||
|
uint32_t session = id;
|
||||||
|
mLocationAPI->gnssNiResponse(id, response);
|
||||||
|
LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, session);
|
||||||
|
mRequestQueues[REQUEST_NIRESPONSE].reset(session);
|
||||||
|
mRequestQueues[REQUEST_NIRESPONSE].push(new GnssNiResponseRequest(*this));
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocationAPIClientBase::beforeGeofenceBreachCb(
|
||||||
|
GeofenceBreachNotification geofenceBreachNotification)
|
||||||
|
{
|
||||||
|
uint32_t* ids = (uint32_t*)malloc(sizeof(uint32_t) * geofenceBreachNotification.count);
|
||||||
|
uint32_t* backup = geofenceBreachNotification.ids;
|
||||||
|
size_t n = geofenceBreachNotification.count;
|
||||||
|
geofenceBreachCallback genfenceCallback = nullptr;
|
||||||
|
|
||||||
|
if (ids == NULL) {
|
||||||
|
LOC_LOGE("%s:%d] Failed to alloc %zu bytes",
|
||||||
|
__FUNCTION__, __LINE__,
|
||||||
|
sizeof(uint32_t) * geofenceBreachNotification.count);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_lock(&mMutex);
|
||||||
|
if (mGeofenceBreachCallback != nullptr) {
|
||||||
|
size_t count = 0;
|
||||||
|
for (size_t i = 0; i < n; i++) {
|
||||||
|
uint32_t id = mGeofenceBiDict.getId(geofenceBreachNotification.ids[i]);
|
||||||
|
GeofenceBreachTypeMask type =
|
||||||
|
mGeofenceBiDict.getExtBySession(geofenceBreachNotification.ids[i]);
|
||||||
|
// if type == 0, we will not head into the fllowing block anyway.
|
||||||
|
// so we don't need to check id and type
|
||||||
|
if ((geofenceBreachNotification.type == GEOFENCE_BREACH_ENTER &&
|
||||||
|
(type & GEOFENCE_BREACH_ENTER_BIT)) ||
|
||||||
|
(geofenceBreachNotification.type == GEOFENCE_BREACH_EXIT &&
|
||||||
|
(type & GEOFENCE_BREACH_EXIT_BIT))
|
||||||
|
) {
|
||||||
|
ids[count] = id;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
geofenceBreachNotification.count = count;
|
||||||
|
geofenceBreachNotification.ids = ids;
|
||||||
|
|
||||||
|
genfenceCallback = mGeofenceBreachCallback;
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
|
||||||
|
if (genfenceCallback != nullptr) {
|
||||||
|
genfenceCallback(geofenceBreachNotification);
|
||||||
|
}
|
||||||
|
|
||||||
|
// restore ids
|
||||||
|
geofenceBreachNotification.ids = backup;
|
||||||
|
geofenceBreachNotification.count = n;
|
||||||
|
free(ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocationAPIClientBase::beforeBatchingStatusCb(BatchingStatusInfo batchStatus,
|
||||||
|
std::list<uint32_t> & tripCompletedList) {
|
||||||
|
|
||||||
|
// map the trip ids to the client ids
|
||||||
|
std::list<uint32_t> tripCompletedClientIdList;
|
||||||
|
tripCompletedClientIdList.clear();
|
||||||
|
|
||||||
|
if (batchStatus.batchingStatus == BATCHING_STATUS_TRIP_COMPLETED) {
|
||||||
|
for (auto itt = tripCompletedList.begin(); itt != tripCompletedList.end(); itt++) {
|
||||||
|
if (mSessionBiDict.hasSession(*itt)) {
|
||||||
|
SessionEntity sessEntity = mSessionBiDict.getExtBySession(*itt);
|
||||||
|
|
||||||
|
if (sessEntity.sessionMode == SESSION_MODE_ON_TRIP_COMPLETED) {
|
||||||
|
tripCompletedClientIdList.push_back(sessEntity.id);
|
||||||
|
mSessionBiDict.rmBySession(*itt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mBatchingStatusCallback(batchStatus, tripCompletedClientIdList);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocationAPIClientBase::onResponseCb(LocationError error, uint32_t id)
|
||||||
|
{
|
||||||
|
if (error != LOCATION_ERROR_SUCCESS) {
|
||||||
|
LOC_LOGE("%s:%d] ERROR: %d ID: %d", __FUNCTION__, __LINE__, error, id);
|
||||||
|
} else {
|
||||||
|
LOC_LOGV("%s:%d] SUCCESS: %d id: %d", __FUNCTION__, __LINE__, error, id);
|
||||||
|
}
|
||||||
|
LocationAPIRequest* request = getRequestBySession(id);
|
||||||
|
if (request) {
|
||||||
|
request->onResponse(error, id);
|
||||||
|
delete request;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocationAPIClientBase::onCollectiveResponseCb(
|
||||||
|
size_t count, LocationError* errors, uint32_t* ids)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
if (errors[i] != LOCATION_ERROR_SUCCESS) {
|
||||||
|
LOC_LOGE("%s:%d] ERROR: %d ID: %d", __FUNCTION__, __LINE__, errors[i], ids[i]);
|
||||||
|
} else {
|
||||||
|
LOC_LOGV("%s:%d] SUCCESS: %d id: %d", __FUNCTION__, __LINE__, errors[i], ids[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LocationAPIRequest* request = nullptr;
|
||||||
|
pthread_mutex_lock(&mMutex);
|
||||||
|
if (mRequestQueues[REQUEST_GEOFENCE].getSession() == GEOFENCE_SESSION_ID) {
|
||||||
|
request = mRequestQueues[REQUEST_GEOFENCE].pop();
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
if (request) {
|
||||||
|
request->onCollectiveResponse(count, errors, ids);
|
||||||
|
delete request;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocationAPIClientBase::removeSession(uint32_t session) {
|
||||||
|
if (mSessionBiDict.hasSession(session)) {
|
||||||
|
mSessionBiDict.rmBySession(session);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LocationAPIRequest* LocationAPIClientBase::getRequestBySession(uint32_t session)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&mMutex);
|
||||||
|
LocationAPIRequest* request = nullptr;
|
||||||
|
for (int i = 0; i < REQUEST_MAX; i++) {
|
||||||
|
if (i != REQUEST_GEOFENCE &&
|
||||||
|
i != REQUEST_SESSION &&
|
||||||
|
mRequestQueues[i].getSession() == session) {
|
||||||
|
request = mRequestQueues[i].pop();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (request == nullptr) {
|
||||||
|
// Can't find a request with correct session,
|
||||||
|
// try to find it from mSessionBiDict
|
||||||
|
if (mSessionBiDict.hasSession(session)) {
|
||||||
|
request = mRequestQueues[REQUEST_SESSION].pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
return request;
|
||||||
|
}
|
545
gps/location/LocationAPIClientBase.h
Normal file
545
gps/location/LocationAPIClientBase.h
Normal file
|
@ -0,0 +1,545 @@
|
||||||
|
/* Copyright (c) 2017 The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LOCATION_API_CLINET_BASE_H
|
||||||
|
#define LOCATION_API_CLINET_BASE_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <queue>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include "LocationAPI.h"
|
||||||
|
|
||||||
|
enum SESSION_MODE {
|
||||||
|
SESSION_MODE_NONE = 0,
|
||||||
|
SESSION_MODE_ON_FULL,
|
||||||
|
SESSION_MODE_ON_FIX,
|
||||||
|
SESSION_MODE_ON_TRIP_COMPLETED
|
||||||
|
};
|
||||||
|
|
||||||
|
enum REQUEST_TYPE {
|
||||||
|
REQUEST_TRACKING = 0,
|
||||||
|
REQUEST_SESSION,
|
||||||
|
REQUEST_GEOFENCE,
|
||||||
|
REQUEST_NIRESPONSE,
|
||||||
|
REQUEST_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum CTRL_REQUEST_TYPE {
|
||||||
|
CTRL_REQUEST_DELETEAIDINGDATA = 0,
|
||||||
|
CTRL_REQUEST_CONTROL,
|
||||||
|
CTRL_REQUEST_CONFIG,
|
||||||
|
CTRL_REQUEST_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
class LocationAPIClientBase;
|
||||||
|
|
||||||
|
class LocationAPIRequest {
|
||||||
|
public:
|
||||||
|
LocationAPIRequest() {}
|
||||||
|
virtual ~LocationAPIRequest() {}
|
||||||
|
virtual void onResponse(LocationError /*error*/, uint32_t /*id*/) {}
|
||||||
|
virtual void onCollectiveResponse(
|
||||||
|
size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class RequestQueue {
|
||||||
|
public:
|
||||||
|
RequestQueue(): mSession(0) {
|
||||||
|
}
|
||||||
|
virtual ~RequestQueue() {
|
||||||
|
reset(0);
|
||||||
|
}
|
||||||
|
void inline setSession(uint32_t session) { mSession = session; }
|
||||||
|
void reset(uint32_t session) {
|
||||||
|
LocationAPIRequest* request = nullptr;
|
||||||
|
while (!mQueue.empty()) {
|
||||||
|
request = mQueue.front();
|
||||||
|
mQueue.pop();
|
||||||
|
delete request;
|
||||||
|
}
|
||||||
|
mSession = session;
|
||||||
|
}
|
||||||
|
void push(LocationAPIRequest* request) {
|
||||||
|
mQueue.push(request);
|
||||||
|
}
|
||||||
|
LocationAPIRequest* pop() {
|
||||||
|
LocationAPIRequest* request = nullptr;
|
||||||
|
if (!mQueue.empty()) {
|
||||||
|
request = mQueue.front();
|
||||||
|
mQueue.pop();
|
||||||
|
}
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
uint32_t getSession() { return mSession; }
|
||||||
|
private:
|
||||||
|
uint32_t mSession;
|
||||||
|
std::queue<LocationAPIRequest*> mQueue;
|
||||||
|
};
|
||||||
|
|
||||||
|
class LocationAPIControlClient {
|
||||||
|
public:
|
||||||
|
LocationAPIControlClient();
|
||||||
|
virtual ~LocationAPIControlClient();
|
||||||
|
LocationAPIControlClient(const LocationAPIControlClient&) = delete;
|
||||||
|
LocationAPIControlClient& operator=(const LocationAPIControlClient&) = delete;
|
||||||
|
|
||||||
|
LocationAPIRequest* getRequestBySession(uint32_t session);
|
||||||
|
|
||||||
|
// LocationControlAPI
|
||||||
|
uint32_t locAPIGnssDeleteAidingData(GnssAidingData& data);
|
||||||
|
uint32_t locAPIEnable(LocationTechnologyType techType);
|
||||||
|
void locAPIDisable();
|
||||||
|
uint32_t locAPIGnssUpdateConfig(GnssConfig config);
|
||||||
|
|
||||||
|
// callbacks
|
||||||
|
void onCtrlResponseCb(LocationError error, uint32_t id);
|
||||||
|
void onCtrlCollectiveResponseCb(size_t count, LocationError* errors, uint32_t* ids);
|
||||||
|
|
||||||
|
inline virtual void onGnssDeleteAidingDataCb(LocationError /*error*/) {}
|
||||||
|
inline virtual void onEnableCb(LocationError /*error*/) {}
|
||||||
|
inline virtual void onDisableCb(LocationError /*error*/) {}
|
||||||
|
inline virtual void onGnssUpdateConfigCb(
|
||||||
|
size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
|
||||||
|
|
||||||
|
class GnssDeleteAidingDataRequest : public LocationAPIRequest {
|
||||||
|
public:
|
||||||
|
GnssDeleteAidingDataRequest(LocationAPIControlClient& API) : mAPI(API) {}
|
||||||
|
inline void onResponse(LocationError error, uint32_t /*id*/) {
|
||||||
|
mAPI.onGnssDeleteAidingDataCb(error);
|
||||||
|
}
|
||||||
|
LocationAPIControlClient& mAPI;
|
||||||
|
};
|
||||||
|
|
||||||
|
class EnableRequest : public LocationAPIRequest {
|
||||||
|
public:
|
||||||
|
EnableRequest(LocationAPIControlClient& API) : mAPI(API) {}
|
||||||
|
inline void onResponse(LocationError error, uint32_t /*id*/) {
|
||||||
|
mAPI.onEnableCb(error);
|
||||||
|
}
|
||||||
|
LocationAPIControlClient& mAPI;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DisableRequest : public LocationAPIRequest {
|
||||||
|
public:
|
||||||
|
DisableRequest(LocationAPIControlClient& API) : mAPI(API) {}
|
||||||
|
inline void onResponse(LocationError error, uint32_t /*id*/) {
|
||||||
|
mAPI.onDisableCb(error);
|
||||||
|
}
|
||||||
|
LocationAPIControlClient& mAPI;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GnssUpdateConfigRequest : public LocationAPIRequest {
|
||||||
|
public:
|
||||||
|
GnssUpdateConfigRequest(LocationAPIControlClient& API) : mAPI(API) {}
|
||||||
|
inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* ids) {
|
||||||
|
mAPI.onGnssUpdateConfigCb(count, errors, ids);
|
||||||
|
}
|
||||||
|
LocationAPIControlClient& mAPI;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
pthread_mutex_t mMutex;
|
||||||
|
LocationControlAPI* mLocationControlAPI;
|
||||||
|
RequestQueue mRequestQueues[CTRL_REQUEST_MAX];
|
||||||
|
bool mEnabled;
|
||||||
|
GnssConfig mConfig;
|
||||||
|
};
|
||||||
|
|
||||||
|
class LocationAPIClientBase {
|
||||||
|
public:
|
||||||
|
LocationAPIClientBase();
|
||||||
|
virtual ~LocationAPIClientBase();
|
||||||
|
LocationAPIClientBase(const LocationAPIClientBase&) = delete;
|
||||||
|
LocationAPIClientBase& operator=(const LocationAPIClientBase&) = delete;
|
||||||
|
|
||||||
|
void locAPISetCallbacks(LocationCallbacks& locationCallbacks);
|
||||||
|
void removeSession(uint32_t session);
|
||||||
|
LocationAPIRequest* getRequestBySession(uint32_t session);
|
||||||
|
|
||||||
|
// LocationAPI
|
||||||
|
uint32_t locAPIStartTracking(LocationOptions& options);
|
||||||
|
void locAPIStopTracking();
|
||||||
|
void locAPIUpdateTrackingOptions(LocationOptions& options);
|
||||||
|
|
||||||
|
int32_t locAPIGetBatchSize();
|
||||||
|
uint32_t locAPIStartSession(uint32_t id, uint32_t sessionMode,
|
||||||
|
LocationOptions& options);
|
||||||
|
uint32_t locAPIStopSession(uint32_t id);
|
||||||
|
uint32_t locAPIUpdateSessionOptions(uint32_t id, uint32_t sessionMode,
|
||||||
|
LocationOptions& options);
|
||||||
|
uint32_t locAPIGetBatchedLocations(uint32_t id, size_t count);
|
||||||
|
|
||||||
|
uint32_t locAPIAddGeofences(size_t count, uint32_t* ids,
|
||||||
|
GeofenceOption* options, GeofenceInfo* data);
|
||||||
|
void locAPIRemoveGeofences(size_t count, uint32_t* ids);
|
||||||
|
void locAPIModifyGeofences(size_t count, uint32_t* ids, GeofenceOption* options);
|
||||||
|
void locAPIPauseGeofences(size_t count, uint32_t* ids);
|
||||||
|
void locAPIResumeGeofences(size_t count, uint32_t* ids, GeofenceBreachTypeMask* mask);
|
||||||
|
void locAPIRemoveAllGeofences();
|
||||||
|
|
||||||
|
void locAPIGnssNiResponse(uint32_t id, GnssNiResponse response);
|
||||||
|
|
||||||
|
// callbacks
|
||||||
|
void onResponseCb(LocationError error, uint32_t id);
|
||||||
|
void onCollectiveResponseCb(size_t count, LocationError* errors, uint32_t* ids);
|
||||||
|
|
||||||
|
void beforeGeofenceBreachCb(GeofenceBreachNotification geofenceBreachNotification);
|
||||||
|
|
||||||
|
inline virtual void onCapabilitiesCb(LocationCapabilitiesMask /*capabilitiesMask*/) {}
|
||||||
|
inline virtual void onGnssNmeaCb(GnssNmeaNotification /*gnssNmeaNotification*/) {}
|
||||||
|
inline virtual void onGnssMeasurementsCb(
|
||||||
|
GnssMeasurementsNotification /*gnssMeasurementsNotification*/) {}
|
||||||
|
|
||||||
|
inline virtual void onTrackingCb(Location /*location*/) {}
|
||||||
|
inline virtual void onGnssSvCb(GnssSvNotification /*gnssSvNotification*/) {}
|
||||||
|
inline virtual void onStartTrackingCb(LocationError /*error*/) {}
|
||||||
|
inline virtual void onStopTrackingCb(LocationError /*error*/) {}
|
||||||
|
inline virtual void onUpdateTrackingOptionsCb(LocationError /*error*/) {}
|
||||||
|
|
||||||
|
inline virtual void onGnssLocationInfoCb(
|
||||||
|
GnssLocationInfoNotification /*gnssLocationInfoNotification*/) {}
|
||||||
|
|
||||||
|
inline virtual void onBatchingCb(size_t /*count*/, Location* /*location*/,
|
||||||
|
BatchingOptions /*batchingOptions*/) {}
|
||||||
|
inline virtual void onBatchingStatusCb(BatchingStatusInfo /*batchingStatus*/,
|
||||||
|
std::list<uint32_t> &/*listOfCompletedTrips*/) {}
|
||||||
|
void beforeBatchingStatusCb(BatchingStatusInfo batchStatus,
|
||||||
|
std::list<uint32_t> & tripCompletedList);
|
||||||
|
inline virtual void onStartBatchingCb(LocationError /*error*/) {}
|
||||||
|
inline virtual void onStopBatchingCb(LocationError /*error*/) {}
|
||||||
|
inline virtual void onUpdateBatchingOptionsCb(LocationError /*error*/) {}
|
||||||
|
inline virtual void onGetBatchedLocationsCb(LocationError /*error*/) {}
|
||||||
|
|
||||||
|
inline virtual void onGeofenceBreachCb(
|
||||||
|
GeofenceBreachNotification /*geofenceBreachNotification*/) {}
|
||||||
|
inline virtual void onGeofenceStatusCb(
|
||||||
|
GeofenceStatusNotification /*geofenceStatusNotification*/) {}
|
||||||
|
inline virtual void onAddGeofencesCb(
|
||||||
|
size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
|
||||||
|
inline virtual void onRemoveGeofencesCb(
|
||||||
|
size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
|
||||||
|
inline virtual void onModifyGeofencesCb(
|
||||||
|
size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
|
||||||
|
inline virtual void onPauseGeofencesCb(
|
||||||
|
size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
|
||||||
|
inline virtual void onResumeGeofencesCb(
|
||||||
|
size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
|
||||||
|
|
||||||
|
inline virtual void onGnssNiCb(uint32_t /*id*/, GnssNiNotification /*gnssNiNotification*/) {}
|
||||||
|
inline virtual void onGnssNiResponseCb(LocationError /*error*/) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// private inner classes
|
||||||
|
typedef struct {
|
||||||
|
uint32_t id;
|
||||||
|
uint32_t trackingSession;
|
||||||
|
uint32_t batchingSession;
|
||||||
|
uint32_t sessionMode;
|
||||||
|
} SessionEntity;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class BiDict {
|
||||||
|
public:
|
||||||
|
BiDict() {
|
||||||
|
pthread_mutex_init(&mBiDictMutex, nullptr);
|
||||||
|
}
|
||||||
|
virtual ~BiDict() {
|
||||||
|
pthread_mutex_destroy(&mBiDictMutex);
|
||||||
|
}
|
||||||
|
bool hasId(uint32_t id) {
|
||||||
|
pthread_mutex_lock(&mBiDictMutex);
|
||||||
|
bool ret = (mForwardMap.find(id) != mForwardMap.end());
|
||||||
|
pthread_mutex_unlock(&mBiDictMutex);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
bool hasSession(uint32_t session) {
|
||||||
|
pthread_mutex_lock(&mBiDictMutex);
|
||||||
|
bool ret = (mBackwardMap.find(session) != mBackwardMap.end());
|
||||||
|
pthread_mutex_unlock(&mBiDictMutex);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
void set(uint32_t id, uint32_t session, T& ext) {
|
||||||
|
pthread_mutex_lock(&mBiDictMutex);
|
||||||
|
mForwardMap[id] = session;
|
||||||
|
mBackwardMap[session] = id;
|
||||||
|
mExtMap[session] = ext;
|
||||||
|
pthread_mutex_unlock(&mBiDictMutex);
|
||||||
|
}
|
||||||
|
void clear() {
|
||||||
|
pthread_mutex_lock(&mBiDictMutex);
|
||||||
|
mForwardMap.clear();
|
||||||
|
mBackwardMap.clear();
|
||||||
|
mExtMap.clear();
|
||||||
|
pthread_mutex_unlock(&mBiDictMutex);
|
||||||
|
}
|
||||||
|
void rmById(uint32_t id) {
|
||||||
|
pthread_mutex_lock(&mBiDictMutex);
|
||||||
|
mBackwardMap.erase(mForwardMap[id]);
|
||||||
|
mExtMap.erase(mForwardMap[id]);
|
||||||
|
mForwardMap.erase(id);
|
||||||
|
pthread_mutex_unlock(&mBiDictMutex);
|
||||||
|
}
|
||||||
|
void rmBySession(uint32_t session) {
|
||||||
|
pthread_mutex_lock(&mBiDictMutex);
|
||||||
|
mForwardMap.erase(mBackwardMap[session]);
|
||||||
|
mBackwardMap.erase(session);
|
||||||
|
mExtMap.erase(session);
|
||||||
|
pthread_mutex_unlock(&mBiDictMutex);
|
||||||
|
}
|
||||||
|
uint32_t getId(uint32_t session) {
|
||||||
|
pthread_mutex_lock(&mBiDictMutex);
|
||||||
|
uint32_t ret = 0;
|
||||||
|
auto it = mBackwardMap.find(session);
|
||||||
|
if (it != mBackwardMap.end()) {
|
||||||
|
ret = it->second;
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mBiDictMutex);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
uint32_t getSession(uint32_t id) {
|
||||||
|
pthread_mutex_lock(&mBiDictMutex);
|
||||||
|
uint32_t ret = 0;
|
||||||
|
auto it = mForwardMap.find(id);
|
||||||
|
if (it != mForwardMap.end()) {
|
||||||
|
ret = it->second;
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mBiDictMutex);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
T getExtById(uint32_t id) {
|
||||||
|
pthread_mutex_lock(&mBiDictMutex);
|
||||||
|
T ret;
|
||||||
|
memset(&ret, 0, sizeof(T));
|
||||||
|
uint32_t session = mForwardMap[id];
|
||||||
|
if (session > 0) {
|
||||||
|
auto it = mExtMap.find(session);
|
||||||
|
if (it != mExtMap.end()) {
|
||||||
|
ret = it->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mBiDictMutex);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
T getExtBySession(uint32_t session) {
|
||||||
|
pthread_mutex_lock(&mBiDictMutex);
|
||||||
|
T ret;
|
||||||
|
memset(&ret, 0, sizeof(T));
|
||||||
|
auto it = mExtMap.find(session);
|
||||||
|
if (it != mExtMap.end()) {
|
||||||
|
ret = it->second;
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mBiDictMutex);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
std::vector<uint32_t> getAllSessions() {
|
||||||
|
std::vector<uint32_t> ret;
|
||||||
|
pthread_mutex_lock(&mBiDictMutex);
|
||||||
|
for (auto it = mBackwardMap.begin(); it != mBackwardMap.end(); it++) {
|
||||||
|
ret.push_back(it->first);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mBiDictMutex);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
pthread_mutex_t mBiDictMutex;
|
||||||
|
// mForwarMap mapping id->session
|
||||||
|
std::map<uint32_t, uint32_t> mForwardMap;
|
||||||
|
// mBackwardMap mapping session->id
|
||||||
|
std::map<uint32_t, uint32_t> mBackwardMap;
|
||||||
|
// mExtMap mapping session->ext
|
||||||
|
std::map<uint32_t, T> mExtMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
class StartTrackingRequest : public LocationAPIRequest {
|
||||||
|
public:
|
||||||
|
StartTrackingRequest(LocationAPIClientBase& API) : mAPI(API) {}
|
||||||
|
inline void onResponse(LocationError error, uint32_t id) {
|
||||||
|
if (error != LOCATION_ERROR_SUCCESS) {
|
||||||
|
mAPI.removeSession(id);
|
||||||
|
}
|
||||||
|
mAPI.onStartTrackingCb(error);
|
||||||
|
}
|
||||||
|
LocationAPIClientBase& mAPI;
|
||||||
|
};
|
||||||
|
|
||||||
|
class StopTrackingRequest : public LocationAPIRequest {
|
||||||
|
public:
|
||||||
|
StopTrackingRequest(LocationAPIClientBase& API) : mAPI(API) {}
|
||||||
|
inline void onResponse(LocationError error, uint32_t id) {
|
||||||
|
mAPI.onStopTrackingCb(error);
|
||||||
|
if (error == LOCATION_ERROR_SUCCESS) {
|
||||||
|
mAPI.removeSession(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LocationAPIClientBase& mAPI;
|
||||||
|
};
|
||||||
|
|
||||||
|
class UpdateTrackingOptionsRequest : public LocationAPIRequest {
|
||||||
|
public:
|
||||||
|
UpdateTrackingOptionsRequest(LocationAPIClientBase& API) : mAPI(API) {}
|
||||||
|
inline void onResponse(LocationError error, uint32_t /*id*/) {
|
||||||
|
mAPI.onUpdateTrackingOptionsCb(error);
|
||||||
|
}
|
||||||
|
LocationAPIClientBase& mAPI;
|
||||||
|
};
|
||||||
|
|
||||||
|
class StartBatchingRequest : public LocationAPIRequest {
|
||||||
|
public:
|
||||||
|
StartBatchingRequest(LocationAPIClientBase& API) : mAPI(API) {}
|
||||||
|
inline void onResponse(LocationError error, uint32_t id) {
|
||||||
|
if (error != LOCATION_ERROR_SUCCESS) {
|
||||||
|
mAPI.removeSession(id);
|
||||||
|
}
|
||||||
|
mAPI.onStartBatchingCb(error);
|
||||||
|
}
|
||||||
|
LocationAPIClientBase& mAPI;
|
||||||
|
};
|
||||||
|
|
||||||
|
class StopBatchingRequest : public LocationAPIRequest {
|
||||||
|
public:
|
||||||
|
StopBatchingRequest(LocationAPIClientBase& API) : mAPI(API) {}
|
||||||
|
inline void onResponse(LocationError error, uint32_t id) {
|
||||||
|
mAPI.onStopBatchingCb(error);
|
||||||
|
if (error == LOCATION_ERROR_SUCCESS) {
|
||||||
|
mAPI.removeSession(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LocationAPIClientBase& mAPI;
|
||||||
|
};
|
||||||
|
|
||||||
|
class UpdateBatchingOptionsRequest : public LocationAPIRequest {
|
||||||
|
public:
|
||||||
|
UpdateBatchingOptionsRequest(LocationAPIClientBase& API) : mAPI(API) {}
|
||||||
|
inline void onResponse(LocationError error, uint32_t /*id*/) {
|
||||||
|
mAPI.onUpdateBatchingOptionsCb(error);
|
||||||
|
}
|
||||||
|
LocationAPIClientBase& mAPI;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GetBatchedLocationsRequest : public LocationAPIRequest {
|
||||||
|
public:
|
||||||
|
GetBatchedLocationsRequest(LocationAPIClientBase& API) : mAPI(API) {}
|
||||||
|
inline void onResponse(LocationError error, uint32_t /*id*/) {
|
||||||
|
mAPI.onGetBatchedLocationsCb(error);
|
||||||
|
}
|
||||||
|
LocationAPIClientBase& mAPI;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AddGeofencesRequest : public LocationAPIRequest {
|
||||||
|
public:
|
||||||
|
AddGeofencesRequest(LocationAPIClientBase& API) : mAPI(API) {}
|
||||||
|
inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) {
|
||||||
|
uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count);
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]);
|
||||||
|
}
|
||||||
|
mAPI.onAddGeofencesCb(count, errors, ids);
|
||||||
|
free(ids);
|
||||||
|
}
|
||||||
|
LocationAPIClientBase& mAPI;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RemoveGeofencesRequest : public LocationAPIRequest {
|
||||||
|
public:
|
||||||
|
RemoveGeofencesRequest(LocationAPIClientBase& API) : mAPI(API) {}
|
||||||
|
inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) {
|
||||||
|
// No need to handle collectiveResponse, cbs already notified
|
||||||
|
}
|
||||||
|
LocationAPIClientBase& mAPI;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ModifyGeofencesRequest : public LocationAPIRequest {
|
||||||
|
public:
|
||||||
|
ModifyGeofencesRequest(LocationAPIClientBase& API) : mAPI(API) {}
|
||||||
|
inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) {
|
||||||
|
uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count);
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]);
|
||||||
|
}
|
||||||
|
mAPI.onModifyGeofencesCb(count, errors, ids);
|
||||||
|
free(ids);
|
||||||
|
}
|
||||||
|
LocationAPIClientBase& mAPI;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PauseGeofencesRequest : public LocationAPIRequest {
|
||||||
|
public:
|
||||||
|
PauseGeofencesRequest(LocationAPIClientBase& API) : mAPI(API) {}
|
||||||
|
inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) {
|
||||||
|
uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count);
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]);
|
||||||
|
}
|
||||||
|
mAPI.onPauseGeofencesCb(count, errors, ids);
|
||||||
|
free(ids);
|
||||||
|
}
|
||||||
|
LocationAPIClientBase& mAPI;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ResumeGeofencesRequest : public LocationAPIRequest {
|
||||||
|
public:
|
||||||
|
ResumeGeofencesRequest(LocationAPIClientBase& API) : mAPI(API) {}
|
||||||
|
inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) {
|
||||||
|
uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count);
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]);
|
||||||
|
}
|
||||||
|
mAPI.onResumeGeofencesCb(count, errors, ids);
|
||||||
|
free(ids);
|
||||||
|
}
|
||||||
|
LocationAPIClientBase& mAPI;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GnssNiResponseRequest : public LocationAPIRequest {
|
||||||
|
public:
|
||||||
|
GnssNiResponseRequest(LocationAPIClientBase& API) : mAPI(API) {}
|
||||||
|
inline void onResponse(LocationError error, uint32_t /*id*/) {
|
||||||
|
mAPI.onGnssNiResponseCb(error);
|
||||||
|
}
|
||||||
|
LocationAPIClientBase& mAPI;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
pthread_mutex_t mMutex;
|
||||||
|
|
||||||
|
geofenceBreachCallback mGeofenceBreachCallback;
|
||||||
|
batchingStatusCallback mBatchingStatusCallback;
|
||||||
|
|
||||||
|
LocationAPI* mLocationAPI;
|
||||||
|
|
||||||
|
RequestQueue mRequestQueues[REQUEST_MAX];
|
||||||
|
BiDict<GeofenceBreachTypeMask> mGeofenceBiDict;
|
||||||
|
BiDict<SessionEntity> mSessionBiDict;
|
||||||
|
int32_t mBatchSize;
|
||||||
|
bool mTracking;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* LOCATION_API_CLINET_BASE_H */
|
40
gps/location/Makefile.am
Normal file
40
gps/location/Makefile.am
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
AM_CFLAGS = \
|
||||||
|
$(LOCPLA_CFLAGS) \
|
||||||
|
$(GPSUTILS_CFLAGS) \
|
||||||
|
$(LOCHAL_CFLAGS) \
|
||||||
|
-I./ \
|
||||||
|
-I../utils \
|
||||||
|
-std=c++11
|
||||||
|
|
||||||
|
liblocation_api_la_SOURCES = \
|
||||||
|
LocationAPI.cpp \
|
||||||
|
LocationAPIClientBase.cpp
|
||||||
|
|
||||||
|
if USE_GLIB
|
||||||
|
liblocation_api_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@
|
||||||
|
liblocation_api_la_LDFLAGS = -lstdc++ -lpthread @GLIB_LIBS@ -shared -version-info 1:0:0
|
||||||
|
liblocation_api_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@
|
||||||
|
else
|
||||||
|
liblocation_api_la_CFLAGS = $(AM_CFLAGS)
|
||||||
|
liblocation_api_la_LDFLAGS = -lpthread -shared -version-info 1:0:0
|
||||||
|
liblocation_api_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
liblocation_api_la_LIBADD = -lstdc++ $(LOCPLA_LIBS) $(GPSUTILS_LIBS) $(LOCHAL_LIBS)
|
||||||
|
|
||||||
|
library_include_HEADERS = \
|
||||||
|
LocationAPI.h \
|
||||||
|
LocationAPIClientBase.h \
|
||||||
|
location_interface.h
|
||||||
|
|
||||||
|
#Create and Install libraries
|
||||||
|
lib_LTLIBRARIES = liblocation_api.la
|
||||||
|
|
||||||
|
library_includedir = $(pkgincludedir)
|
||||||
|
#pkgconfigdir = $(libdir)/pkgconfig
|
||||||
|
#pkgconfig_DATA = location-api.pc
|
||||||
|
#EXTRA_DIST = $(pkgconfig_DATA)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
94
gps/location/location_interface.h
Normal file
94
gps/location/location_interface.h
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
/* Copyright (c) 2017 The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LOCATION_INTERFACE_H
|
||||||
|
#define LOCATION_INTERFACE_H
|
||||||
|
|
||||||
|
#include <LocationAPI.h>
|
||||||
|
#include <gps_extended_c.h>
|
||||||
|
|
||||||
|
struct GnssInterface {
|
||||||
|
size_t size;
|
||||||
|
void (*initialize)(void);
|
||||||
|
void (*deinitialize)(void);
|
||||||
|
void (*addClient)(LocationAPI* client, const LocationCallbacks& callbacks);
|
||||||
|
void (*removeClient)(LocationAPI* client);
|
||||||
|
void (*requestCapabilities)(LocationAPI* client);
|
||||||
|
uint32_t (*startTracking)(LocationAPI* client, LocationOptions& options);
|
||||||
|
void (*updateTrackingOptions)(LocationAPI* client, uint32_t id, LocationOptions& options);
|
||||||
|
void (*stopTracking)(LocationAPI* client, uint32_t id);
|
||||||
|
void (*gnssNiResponse)(LocationAPI* client, uint32_t id, GnssNiResponse response);
|
||||||
|
void (*setControlCallbacks)(LocationControlCallbacks& controlCallbacks);
|
||||||
|
uint32_t (*enable)(LocationTechnologyType techType);
|
||||||
|
void (*disable)(uint32_t id);
|
||||||
|
uint32_t* (*gnssUpdateConfig)(GnssConfig config);
|
||||||
|
uint32_t (*gnssDeleteAidingData)(GnssAidingData& data);
|
||||||
|
void (*injectLocation)(double latitude, double longitude, float accuracy);
|
||||||
|
void (*injectTime)(int64_t time, int64_t timeReference, int32_t uncertainty);
|
||||||
|
void (*agpsInit)(const AgpsCbInfo& cbInfo);
|
||||||
|
void (*agpsDataConnOpen)(AGpsExtType agpsType, const char* apnName, int apnLen, int ipType);
|
||||||
|
void (*agpsDataConnClosed)(AGpsExtType agpsType);
|
||||||
|
void (*agpsDataConnFailed)(AGpsExtType agpsType);
|
||||||
|
void (*getDebugReport)(GnssDebugReport& report);
|
||||||
|
void (*updateConnectionStatus)(bool connected, uint8_t type);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FlpInterface {
|
||||||
|
size_t size;
|
||||||
|
void (*initialize)(void);
|
||||||
|
void (*deinitialize)(void);
|
||||||
|
void (*addClient)(LocationAPI* client, const LocationCallbacks& callbacks);
|
||||||
|
void (*removeClient)(LocationAPI* client);
|
||||||
|
void (*requestCapabilities)(LocationAPI* client);
|
||||||
|
uint32_t (*startTracking)(LocationAPI* client, LocationOptions& options);
|
||||||
|
void (*updateTrackingOptions)(LocationAPI* client, uint32_t id, LocationOptions& options);
|
||||||
|
void (*stopTracking)(LocationAPI* client, uint32_t id);
|
||||||
|
uint32_t (*startBatching)(LocationAPI* client, LocationOptions&, BatchingOptions&);
|
||||||
|
void (*stopBatching)(LocationAPI* client, uint32_t id);
|
||||||
|
void (*updateBatchingOptions)(LocationAPI* client, uint32_t id, LocationOptions&,
|
||||||
|
BatchingOptions&);
|
||||||
|
void (*getBatchedLocations)(LocationAPI* client, uint32_t id, size_t count);
|
||||||
|
void (*getPowerStateChanges)(void* powerStateCb);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GeofenceInterface {
|
||||||
|
size_t size;
|
||||||
|
void (*initialize)(void);
|
||||||
|
void (*deinitialize)(void);
|
||||||
|
void (*addClient)(LocationAPI* client, const LocationCallbacks& callbacks);
|
||||||
|
void (*removeClient)(LocationAPI* client);
|
||||||
|
void (*requestCapabilities)(LocationAPI* client);
|
||||||
|
uint32_t* (*addGeofences)(LocationAPI* client, size_t count, GeofenceOption*, GeofenceInfo*);
|
||||||
|
void (*removeGeofences)(LocationAPI* client, size_t count, uint32_t* ids);
|
||||||
|
void (*modifyGeofences)(LocationAPI* client, size_t count, uint32_t* ids,
|
||||||
|
GeofenceOption* options);
|
||||||
|
void (*pauseGeofences)(LocationAPI* client, size_t count, uint32_t* ids);
|
||||||
|
void (*resumeGeofences)(LocationAPI* client, size_t count, uint32_t* ids);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* LOCATION_INTERFACE_H */
|
65
gps/utils/Android.mk
Normal file
65
gps/utils/Android.mk
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)
|
||||||
|
ifneq ($(BUILD_TINY_ANDROID),true)
|
||||||
|
#Compile this library only for builds with the latest modem image
|
||||||
|
|
||||||
|
LOCAL_PATH := $(call my-dir)
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
|
||||||
|
## Libs
|
||||||
|
LOCAL_SHARED_LIBRARIES := \
|
||||||
|
libutils \
|
||||||
|
libcutils \
|
||||||
|
liblog \
|
||||||
|
libloc_pla
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES += \
|
||||||
|
loc_log.cpp \
|
||||||
|
loc_cfg.cpp \
|
||||||
|
msg_q.c \
|
||||||
|
linked_list.c \
|
||||||
|
loc_target.cpp \
|
||||||
|
platform_lib_abstractions/elapsed_millis_since_boot.cpp \
|
||||||
|
LocHeap.cpp \
|
||||||
|
LocTimer.cpp \
|
||||||
|
LocThread.cpp \
|
||||||
|
MsgTask.cpp \
|
||||||
|
loc_misc_utils.cpp \
|
||||||
|
loc_nmea.cpp
|
||||||
|
|
||||||
|
# Flag -std=c++11 is not accepted by compiler when LOCAL_CLANG is set to true
|
||||||
|
LOCAL_CFLAGS += \
|
||||||
|
-fno-short-enums \
|
||||||
|
-D_ANDROID_
|
||||||
|
|
||||||
|
ifeq ($(TARGET_BUILD_VARIANT),user)
|
||||||
|
LOCAL_CFLAGS += -DTARGET_BUILD_VARIANT_USER
|
||||||
|
endif
|
||||||
|
|
||||||
|
LOCAL_LDFLAGS += -Wl,--export-dynamic
|
||||||
|
|
||||||
|
## Includes
|
||||||
|
LOCAL_HEADER_LIBRARIES := \
|
||||||
|
libloc_pla_headers \
|
||||||
|
liblocation_api_headers
|
||||||
|
|
||||||
|
LOCAL_MODULE := libgps.utils
|
||||||
|
LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib
|
||||||
|
LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64
|
||||||
|
LOCAL_MODULE_TAGS := optional
|
||||||
|
|
||||||
|
LOCAL_PRELINK_MODULE := false
|
||||||
|
|
||||||
|
LOCAL_CFLAGS += $(GNSS_CFLAGS)
|
||||||
|
|
||||||
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
LOCAL_MODULE := libgps.utils_headers
|
||||||
|
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
|
||||||
|
include $(BUILD_HEADER_LIBRARY)
|
||||||
|
|
||||||
|
include $(addsuffix /Android.mk, $(addprefix $(LOCAL_PATH)/, platform_lib_abstractions))
|
||||||
|
endif # not BUILD_TINY_ANDROID
|
||||||
|
endif # BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE
|
354
gps/utils/LocHeap.cpp
Normal file
354
gps/utils/LocHeap.cpp
Normal file
|
@ -0,0 +1,354 @@
|
||||||
|
/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <LocHeap.h>
|
||||||
|
|
||||||
|
class LocHeapNode {
|
||||||
|
friend class LocHeap;
|
||||||
|
|
||||||
|
// size of of the subtree, excluding self, 1 if no subtree
|
||||||
|
int mSize;
|
||||||
|
LocHeapNode* mLeft;
|
||||||
|
LocHeapNode* mRight;
|
||||||
|
LocRankable* mData;
|
||||||
|
public:
|
||||||
|
inline LocHeapNode(LocRankable& data) :
|
||||||
|
mSize(1), mLeft(NULL), mRight(NULL), mData(&data) {}
|
||||||
|
~LocHeapNode();
|
||||||
|
|
||||||
|
// this only swaps the data of the two nodes, so no
|
||||||
|
// detach / re-attached is necessary
|
||||||
|
void swap(LocHeapNode& node);
|
||||||
|
|
||||||
|
LocRankable* detachData();
|
||||||
|
|
||||||
|
// push a node into the tree stucture, keeping sorted by rank
|
||||||
|
void push(LocHeapNode& node);
|
||||||
|
|
||||||
|
// pop the head node out of the tree stucture. keeping sorted by rank
|
||||||
|
static LocHeapNode* pop(LocHeapNode*& top);
|
||||||
|
|
||||||
|
// remove a specific node from the tree
|
||||||
|
// returns the pointer to the node removed, which would be either the
|
||||||
|
// same as input (if successfully removed); or NULL (if failed).
|
||||||
|
static LocHeapNode* remove(LocHeapNode*& top, LocRankable& data);
|
||||||
|
|
||||||
|
// convenience method to compare data ranking
|
||||||
|
inline bool outRanks(LocHeapNode& node) { return mData->outRanks(*node.mData); }
|
||||||
|
inline bool outRanks(LocRankable& data) { return mData->outRanks(data); }
|
||||||
|
|
||||||
|
// checks if mSize is correct, AND this node is the highest ranking
|
||||||
|
// of the entire subtree
|
||||||
|
bool checkNodes();
|
||||||
|
|
||||||
|
inline int getSize() { return mSize; }
|
||||||
|
};
|
||||||
|
|
||||||
|
inline
|
||||||
|
LocHeapNode::~LocHeapNode() {
|
||||||
|
if (mLeft) {
|
||||||
|
delete mLeft;
|
||||||
|
mLeft = NULL;
|
||||||
|
}
|
||||||
|
if (mRight) {
|
||||||
|
delete mRight;
|
||||||
|
mRight = NULL;
|
||||||
|
}
|
||||||
|
if (mData) {
|
||||||
|
mData = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void LocHeapNode::swap(LocHeapNode& node) {
|
||||||
|
LocRankable* tmpData = node.mData;
|
||||||
|
node.mData = mData;
|
||||||
|
mData = tmpData;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
LocRankable* LocHeapNode::detachData() {
|
||||||
|
LocRankable* data = mData;
|
||||||
|
mData = NULL;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// push keeps the tree sorted by rank, it also tries to balance the
|
||||||
|
// tree by adding the new node to the smaller of the subtrees.
|
||||||
|
// The pointer to the tree and internal links never change. If the
|
||||||
|
// mData of tree top ranks lower than that of the incoming node,
|
||||||
|
// mData will be swapped with that of the incoming node to ensure
|
||||||
|
// ranking, no restructuring the container nodes.
|
||||||
|
void LocHeapNode::push(LocHeapNode& node) {
|
||||||
|
// ensure the current node ranks higher than in the incoming one
|
||||||
|
if (node.outRanks(*this)) {
|
||||||
|
swap(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
// now drop the new node (ensured lower than *this) into a subtree
|
||||||
|
if (NULL == mLeft) {
|
||||||
|
mLeft = &node;
|
||||||
|
} else if (NULL == mRight) {
|
||||||
|
mRight = &node;
|
||||||
|
} else if (mLeft->mSize <= mRight->mSize) {
|
||||||
|
mLeft->push(node);
|
||||||
|
} else {
|
||||||
|
mRight->push(node);
|
||||||
|
}
|
||||||
|
mSize++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// pop keeps the tree sorted by rank, but it does not try to balance
|
||||||
|
// the tree. It recursively swaps with the higher ranked top of the
|
||||||
|
// subtrees.
|
||||||
|
// The return is a popped out node from leaf level, that has the data
|
||||||
|
// swapped all the way down from the top. The pinter to the tree and
|
||||||
|
// internal links will not be changed or restructured, except for the
|
||||||
|
// node that is popped out.
|
||||||
|
// If the return pointer == this, this the last node in the tree.
|
||||||
|
LocHeapNode* LocHeapNode::pop(LocHeapNode*& top) {
|
||||||
|
// we know the top has the highest ranking at this point, else
|
||||||
|
// the tree is broken. This top will be popped out. But we need
|
||||||
|
// a node from the left or right child, whichever ranks higher,
|
||||||
|
// to replace the current top. This then will need to be done
|
||||||
|
// recursively to the leaf level. So we swap the mData of the
|
||||||
|
// current top node all the way down to the leaf level.
|
||||||
|
LocHeapNode* poppedNode = top;
|
||||||
|
// top is losing a node in its subtree
|
||||||
|
top->mSize--;
|
||||||
|
if (top->mLeft || top->mRight) {
|
||||||
|
// if mLeft is NULL, mRight for sure is NOT NULL, take that;
|
||||||
|
// else if mRight is NULL, mLeft for sure is NOT, take that;
|
||||||
|
// else we take the address of whatever has higher ranking mData
|
||||||
|
LocHeapNode*& subTop = (NULL == top->mLeft) ? top->mRight :
|
||||||
|
((NULL == top->mRight) ? top->mLeft :
|
||||||
|
(top->mLeft->outRanks(*(top->mRight)) ? top->mLeft : top->mRight));
|
||||||
|
// swap mData, the tree top gets updated with the new data.
|
||||||
|
top->swap(*subTop);
|
||||||
|
// pop out from the subtree
|
||||||
|
poppedNode = pop(subTop);
|
||||||
|
} else {
|
||||||
|
// if the top has only single node
|
||||||
|
// detach the poppedNode from the tree
|
||||||
|
// subTop is the reference of ether mLeft or mRight
|
||||||
|
// NOT a local stack pointer. so it MUST be NULL'ed here.
|
||||||
|
top = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return poppedNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// navigating through the tree and find the node that hass the input
|
||||||
|
// data. Since this is a heap, we do recursive linear search.
|
||||||
|
// returns the pointer to the node removed, which would be either the
|
||||||
|
// same as input (if successfully removed); or NULL (if failed).
|
||||||
|
LocHeapNode* LocHeapNode::remove(LocHeapNode*& top, LocRankable& data) {
|
||||||
|
LocHeapNode* removedNode = NULL;
|
||||||
|
// this is the node, by address
|
||||||
|
if (&data == (LocRankable*)(top->mData)) {
|
||||||
|
// pop this node out
|
||||||
|
removedNode = pop(top);
|
||||||
|
} else if (!data.outRanks(*top->mData)) {
|
||||||
|
// subtrees might have this node
|
||||||
|
if (top->mLeft) {
|
||||||
|
removedNode = remove(top->mLeft, data);
|
||||||
|
}
|
||||||
|
// if we did not find in mLeft, and mRight is not empty
|
||||||
|
if (!removedNode && top->mRight) {
|
||||||
|
removedNode = remove(top->mRight, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// top lost a node in its subtree
|
||||||
|
if (removedNode) {
|
||||||
|
top->mSize--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return removedNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// checks if mSize is correct, AND this node is the highest ranking
|
||||||
|
// of the entire subtree
|
||||||
|
bool LocHeapNode::checkNodes() {
|
||||||
|
// size of the current subtree
|
||||||
|
int totalSize = mSize;
|
||||||
|
if (mLeft) {
|
||||||
|
// check the consistency of left subtree
|
||||||
|
if (mLeft->outRanks(*this) || !mLeft->checkNodes()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// subtract the size of left subtree (with subtree head)
|
||||||
|
totalSize -= mLeft->mSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mRight) {
|
||||||
|
// check the consistency of right subtree
|
||||||
|
if (mRight->outRanks(*this) || !mRight->checkNodes()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// subtract the size of right subtree (with subtree head)
|
||||||
|
totalSize -= mRight->mSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for the tree nodes to consistent, totalSize must be 1 now
|
||||||
|
return totalSize == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocHeap::~LocHeap() {
|
||||||
|
if (mTree) {
|
||||||
|
delete mTree;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocHeap::push(LocRankable& node) {
|
||||||
|
LocHeapNode* heapNode = new LocHeapNode(node);
|
||||||
|
if (!mTree) {
|
||||||
|
mTree = heapNode;
|
||||||
|
} else {
|
||||||
|
mTree->push(*heapNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LocRankable* LocHeap::peek() {
|
||||||
|
LocRankable* top = NULL;
|
||||||
|
if (mTree) {
|
||||||
|
top = mTree->mData;
|
||||||
|
}
|
||||||
|
return top;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocRankable* LocHeap::pop() {
|
||||||
|
LocRankable* locNode = NULL;
|
||||||
|
if (mTree) {
|
||||||
|
// mTree may become NULL after this call
|
||||||
|
LocHeapNode* heapNode = LocHeapNode::pop(mTree);
|
||||||
|
locNode = heapNode->detachData();
|
||||||
|
delete heapNode;
|
||||||
|
}
|
||||||
|
return locNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocRankable* LocHeap::remove(LocRankable& rankable) {
|
||||||
|
LocRankable* locNode = NULL;
|
||||||
|
if (mTree) {
|
||||||
|
// mTree may become NULL after this call
|
||||||
|
LocHeapNode* heapNode = LocHeapNode::remove(mTree, rankable);
|
||||||
|
if (heapNode) {
|
||||||
|
locNode = heapNode->detachData();
|
||||||
|
delete heapNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return locNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __LOC_UNIT_TEST__
|
||||||
|
bool LocHeap::checkTree() {
|
||||||
|
return ((NULL == mTree) || mTree->checkNodes());
|
||||||
|
}
|
||||||
|
uint32_t LocHeap::getTreeSize() {
|
||||||
|
return (NULL == mTree) ? 0 : mTree->getSize();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __LOC_DEBUG__
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
class LocHeapDebug : public LocHeap {
|
||||||
|
public:
|
||||||
|
bool checkTree() {
|
||||||
|
return ((NULL == mTree) || mTree->checkNodes());
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t getTreeSize() {
|
||||||
|
return (NULL == mTree) ? 0 : (mTree->getSize());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class LocHeapDebugData : public LocRankable {
|
||||||
|
const int mID;
|
||||||
|
public:
|
||||||
|
LocHeapDebugData(int id) : mID(id) {}
|
||||||
|
inline virtual int ranks(LocRankable& rankable) {
|
||||||
|
LocHeapDebugData* testData = dynamic_cast<LocHeapDebugData*>(&rankable);
|
||||||
|
return testData->mID - mID;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// For Linux command line testing:
|
||||||
|
// compilation: g++ -D__LOC_HOST_DEBUG__ -D__LOC_DEBUG__ -g -I. -I../../../../vendor/qcom/proprietary/gps-internal/unit-tests/fakes_for_host -I../../../../system/core/include LocHeap.cpp
|
||||||
|
// test: valgrind --leak-check=full ./a.out 100
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
srand(time(NULL));
|
||||||
|
int tries = atoi(argv[1]);
|
||||||
|
int checks = tries >> 3;
|
||||||
|
LocHeapDebug heap;
|
||||||
|
int treeSize = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < tries; i++) {
|
||||||
|
if (i % checks == 0 && !heap.checkTree()) {
|
||||||
|
printf("tree check failed before %dth op\n", i);
|
||||||
|
}
|
||||||
|
int r = rand();
|
||||||
|
|
||||||
|
if (r & 1) {
|
||||||
|
LocHeapDebugData* data = new LocHeapDebugData(r >> 1);
|
||||||
|
heap.push(dynamic_cast<LocRankable&>(*data));
|
||||||
|
treeSize++;
|
||||||
|
} else {
|
||||||
|
LocRankable* rankable = heap.pop();
|
||||||
|
if (rankable) {
|
||||||
|
delete rankable;
|
||||||
|
}
|
||||||
|
treeSize ? treeSize-- : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s: %d == %d\n", (r&1)?"push":"pop", treeSize, heap.getTreeSize());
|
||||||
|
if (treeSize != heap.getTreeSize()) {
|
||||||
|
printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
|
||||||
|
tries = i+1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!heap.checkTree()) {
|
||||||
|
printf("!!!!!!!!!!tree check failed at the end after %d ops!!!!!!!\n", tries);
|
||||||
|
} else {
|
||||||
|
printf("success!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (LocRankable* data = heap.pop(); NULL != data; data = heap.pop()) {
|
||||||
|
delete data;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
96
gps/utils/LocHeap.h
Normal file
96
gps/utils/LocHeap.h
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef __LOC_HEAP__
|
||||||
|
#define __LOC_HEAP__
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
// abstract class to be implemented by client to provide a rankable class
|
||||||
|
class LocRankable {
|
||||||
|
public:
|
||||||
|
virtual inline ~LocRankable() {}
|
||||||
|
|
||||||
|
// method to rank objects of such type for sorting purposes.
|
||||||
|
// The pointer of the input node would be stored in the heap.
|
||||||
|
// >0 if ranks higher than the input;
|
||||||
|
// ==0 if equally ranks with the input;
|
||||||
|
// <0 if ranks lower than the input
|
||||||
|
virtual int ranks(LocRankable& rankable) = 0;
|
||||||
|
|
||||||
|
// convenient method to rank objects of such type for sorting purposes.
|
||||||
|
inline bool outRanks(LocRankable& rankable) { return ranks(rankable) > 0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// opaque class to provide service implementation.
|
||||||
|
class LocHeapNode;
|
||||||
|
|
||||||
|
// a heap whose left and right children are not sorted. It is sorted only vertically,
|
||||||
|
// i.e. parent always ranks higher than children, if they exist. Ranking algorithm is
|
||||||
|
// implemented in Rankable. The reason that there is no sort between children is to
|
||||||
|
// help beter balance the tree with lower cost. When a node is pushed to the tree,
|
||||||
|
// it is guaranteed that the subtree that is smaller gets to have the new node.
|
||||||
|
class LocHeap {
|
||||||
|
protected:
|
||||||
|
LocHeapNode* mTree;
|
||||||
|
public:
|
||||||
|
inline LocHeap() : mTree(NULL) {}
|
||||||
|
~LocHeap();
|
||||||
|
|
||||||
|
// push keeps the tree sorted by rank, it also tries to balance the
|
||||||
|
// tree by adding the new node to the smaller of the subtrees.
|
||||||
|
// node is reference to an obj that is managed by client, that client
|
||||||
|
// creates and destroyes. The destroy should happen after the
|
||||||
|
// node is popped out from the heap.
|
||||||
|
void push(LocRankable& node);
|
||||||
|
|
||||||
|
// Peeks the node data on tree top, which has currently the highest ranking
|
||||||
|
// There is no change the tree structure with this operation
|
||||||
|
// Returns NULL if the tree is empty, otherwise pointer to the node data of
|
||||||
|
// the tree top.
|
||||||
|
LocRankable* peek();
|
||||||
|
|
||||||
|
// pop keeps the tree sorted by rank, but it does not try to balance
|
||||||
|
// the tree.
|
||||||
|
// Return - pointer to the node popped out, or NULL if heap is already empty
|
||||||
|
LocRankable* pop();
|
||||||
|
|
||||||
|
// navigating through the tree and find the node that ranks the same
|
||||||
|
// as the input data, then remove it from the tree. Rank is implemented
|
||||||
|
// by rankable obj.
|
||||||
|
// returns the pointer to the node removed; or NULL (if failed).
|
||||||
|
LocRankable* remove(LocRankable& rankable);
|
||||||
|
|
||||||
|
#ifdef __LOC_UNIT_TEST__
|
||||||
|
bool checkTree();
|
||||||
|
uint32_t getTreeSize();
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //__LOC_HEAP__
|
59
gps/utils/LocSharedLock.h
Normal file
59
gps/utils/LocSharedLock.h
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef __LOC_SHARED_LOCK__
|
||||||
|
#define __LOC_SHARED_LOCK__
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <cutils/atomic.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
// This is a utility created for use cases such that there are more than
|
||||||
|
// one client who need to share the same lock, but it is not predictable
|
||||||
|
// which of these clients is to last to go away. This shared lock deletes
|
||||||
|
// itself when the last client calls its drop() method. To add a cient,
|
||||||
|
// this share lock's share() method has to be called, so that the obj
|
||||||
|
// can maintain an accurate client count.
|
||||||
|
class LocSharedLock {
|
||||||
|
volatile int32_t mRef;
|
||||||
|
pthread_mutex_t mMutex;
|
||||||
|
inline ~LocSharedLock() { pthread_mutex_destroy(&mMutex); }
|
||||||
|
public:
|
||||||
|
// first client to create this LockSharedLock
|
||||||
|
inline LocSharedLock() : mRef(1) { pthread_mutex_init(&mMutex, NULL); }
|
||||||
|
// following client(s) are to *share()* this lock created by the first client
|
||||||
|
inline LocSharedLock* share() { android_atomic_inc(&mRef); return this; }
|
||||||
|
// whe a client no longer needs this shared lock, drop() shall be called.
|
||||||
|
inline void drop() { if (1 == android_atomic_dec(&mRef)) delete this; }
|
||||||
|
// locking the lock to enter critical section
|
||||||
|
inline void lock() { pthread_mutex_lock(&mMutex); }
|
||||||
|
// unlocking the lock to leave the critical section
|
||||||
|
inline void unlock() { pthread_mutex_unlock(&mMutex); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //__LOC_SHARED_LOCK__
|
266
gps/utils/LocThread.cpp
Normal file
266
gps/utils/LocThread.cpp
Normal file
|
@ -0,0 +1,266 @@
|
||||||
|
/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <LocThread.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <platform_lib_macros.h>
|
||||||
|
|
||||||
|
class LocThreadDelegate {
|
||||||
|
LocRunnable* mRunnable;
|
||||||
|
bool mJoinable;
|
||||||
|
pthread_t mThandle;
|
||||||
|
pthread_mutex_t mMutex;
|
||||||
|
int mRefCount;
|
||||||
|
~LocThreadDelegate();
|
||||||
|
LocThreadDelegate(LocThread::tCreate creator, const char* threadName,
|
||||||
|
LocRunnable* runnable, bool joinable);
|
||||||
|
void destroy();
|
||||||
|
public:
|
||||||
|
static LocThreadDelegate* create(LocThread::tCreate creator,
|
||||||
|
const char* threadName, LocRunnable* runnable, bool joinable);
|
||||||
|
void stop();
|
||||||
|
// bye() is for the parent thread to go away. if joinable,
|
||||||
|
// parent must stop the spawned thread, join, and then
|
||||||
|
// destroy(); if detached, the parent can go straight
|
||||||
|
// ahead to destroy()
|
||||||
|
inline void bye() { mJoinable ? stop() : destroy(); }
|
||||||
|
inline bool isRunning() { return (NULL != mRunnable); }
|
||||||
|
static void* threadMain(void* arg);
|
||||||
|
};
|
||||||
|
|
||||||
|
// it is important to note that internal members must be
|
||||||
|
// initialized to values as if pthread_create succeeds.
|
||||||
|
// This is to avoid the race condition between the threads,
|
||||||
|
// once the thread is created, some of these values will
|
||||||
|
// be check in the spawned thread, and must set correctly
|
||||||
|
// then and there.
|
||||||
|
// However, upon pthread_create failure, the data members
|
||||||
|
// must be set to indicate failure, e.g. mRunnable, and
|
||||||
|
// threashold approprietly for destroy(), e.g. mRefCount.
|
||||||
|
LocThreadDelegate::LocThreadDelegate(LocThread::tCreate creator,
|
||||||
|
const char* threadName, LocRunnable* runnable, bool joinable) :
|
||||||
|
mRunnable(runnable), mJoinable(joinable), mThandle((pthread_t)NULL),
|
||||||
|
mMutex(PTHREAD_MUTEX_INITIALIZER), mRefCount(2) {
|
||||||
|
|
||||||
|
// set up thread name, if nothing is passed in
|
||||||
|
if (!threadName) {
|
||||||
|
threadName = "LocThread";
|
||||||
|
}
|
||||||
|
|
||||||
|
// create the thread here, then if successful
|
||||||
|
// and a name is given, we set the thread name
|
||||||
|
if (creator) {
|
||||||
|
mThandle = creator(threadName, threadMain, this);
|
||||||
|
} else if (pthread_create(&mThandle, NULL, threadMain, this)) {
|
||||||
|
// pthread_create() failed
|
||||||
|
mThandle = (pthread_t)NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mThandle) {
|
||||||
|
// set thread name
|
||||||
|
char lname[16];
|
||||||
|
int len = (sizeof(lname)>sizeof(threadName)) ?
|
||||||
|
(sizeof(threadName) -1):(sizeof(lname) - 1);
|
||||||
|
memcpy(lname, threadName, len);
|
||||||
|
lname[len] = 0;
|
||||||
|
// set the thread name here
|
||||||
|
pthread_setname_np(mThandle, lname);
|
||||||
|
|
||||||
|
// detach, if not joinable
|
||||||
|
if (!joinable) {
|
||||||
|
pthread_detach(mThandle);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// must set these values upon failure
|
||||||
|
mRunnable = NULL;
|
||||||
|
mJoinable = false;
|
||||||
|
mRefCount = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
LocThreadDelegate::~LocThreadDelegate() {
|
||||||
|
// at this point nothing should need done any more
|
||||||
|
}
|
||||||
|
|
||||||
|
// factory method so that we could return NULL upon failure
|
||||||
|
LocThreadDelegate* LocThreadDelegate::create(LocThread::tCreate creator,
|
||||||
|
const char* threadName, LocRunnable* runnable, bool joinable) {
|
||||||
|
LocThreadDelegate* thread = NULL;
|
||||||
|
if (runnable) {
|
||||||
|
thread = new LocThreadDelegate(creator, threadName, runnable, joinable);
|
||||||
|
if (thread && !thread->isRunning()) {
|
||||||
|
thread->destroy();
|
||||||
|
thread = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The order is importang
|
||||||
|
// NULLing mRunnalbe stops the while loop in threadMain()
|
||||||
|
// join() if mJoinble must come before destroy() call, as
|
||||||
|
// the obj must remain alive at this time so that mThandle
|
||||||
|
// remains valud.
|
||||||
|
void LocThreadDelegate::stop() {
|
||||||
|
// mRunnable and mJoinable are reset on different triggers.
|
||||||
|
// mRunnable may get nulled on the spawned thread's way out;
|
||||||
|
// or here.
|
||||||
|
// mJouinable (if ever been true) gets falsed when client
|
||||||
|
// thread triggers stop, with either a stop()
|
||||||
|
// call or the client releases thread obj handle.
|
||||||
|
if (mRunnable) {
|
||||||
|
mRunnable = NULL;
|
||||||
|
}
|
||||||
|
if (mJoinable) {
|
||||||
|
mJoinable = false;
|
||||||
|
pthread_join(mThandle, NULL);
|
||||||
|
}
|
||||||
|
// call destroy() to possibly delete the obj
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
// method for clients to call to release the obj
|
||||||
|
// when it is a detached thread, the client thread
|
||||||
|
// and the spawned thread can both try to destroy()
|
||||||
|
// asynchronously. And we delete this obj when
|
||||||
|
// mRefCount becomes 0.
|
||||||
|
void LocThreadDelegate::destroy() {
|
||||||
|
// else case shouldn't happen, unless there is a
|
||||||
|
// leaking obj. But only our code here has such
|
||||||
|
// obj, so if we test our code well, else case
|
||||||
|
// will never happen
|
||||||
|
if (mRefCount > 0) {
|
||||||
|
// we need a flag on the stack
|
||||||
|
bool callDelete = false;
|
||||||
|
|
||||||
|
// critical section between threads
|
||||||
|
pthread_mutex_lock(&mMutex);
|
||||||
|
// last destroy() call
|
||||||
|
callDelete = (1 == mRefCount--);
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
|
||||||
|
// upon last destroy() call we delete this obj
|
||||||
|
if (callDelete) {
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void* LocThreadDelegate::threadMain(void* arg) {
|
||||||
|
LocThreadDelegate* locThread = (LocThreadDelegate*)(arg);
|
||||||
|
|
||||||
|
if (locThread) {
|
||||||
|
LocRunnable* runnable = locThread->mRunnable;
|
||||||
|
|
||||||
|
if (runnable) {
|
||||||
|
if (locThread->isRunning()) {
|
||||||
|
runnable->prerun();
|
||||||
|
}
|
||||||
|
|
||||||
|
while (locThread->isRunning() && runnable->run());
|
||||||
|
|
||||||
|
if (locThread->isRunning()) {
|
||||||
|
runnable->postrun();
|
||||||
|
}
|
||||||
|
|
||||||
|
// at this time, locThread->mRunnable may or may not be NULL
|
||||||
|
// NULL it just to be safe and clean, as we want the field
|
||||||
|
// in the released memory slot to be NULL.
|
||||||
|
locThread->mRunnable = NULL;
|
||||||
|
delete runnable;
|
||||||
|
}
|
||||||
|
locThread->destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocThread::~LocThread() {
|
||||||
|
if (mThread) {
|
||||||
|
mThread->bye();
|
||||||
|
mThread = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LocThread::start(tCreate creator, const char* threadName, LocRunnable* runnable, bool joinable) {
|
||||||
|
bool success = false;
|
||||||
|
if (!mThread) {
|
||||||
|
mThread = LocThreadDelegate::create(creator, threadName, runnable, joinable);
|
||||||
|
// true only if thread is created successfully
|
||||||
|
success = (NULL != mThread);
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocThread::stop() {
|
||||||
|
if (mThread) {
|
||||||
|
mThread->stop();
|
||||||
|
mThread = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __LOC_DEBUG__
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
class LocRunnableTest1 : public LocRunnable {
|
||||||
|
int mID;
|
||||||
|
public:
|
||||||
|
LocRunnableTest1(int id) : LocRunnable(), mID(id) {}
|
||||||
|
virtual bool run() {
|
||||||
|
printf("LocRunnableTest1: %d\n", mID++);
|
||||||
|
sleep(1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// on linux command line:
|
||||||
|
// compile: g++ -D__LOC_HOST_DEBUG__ -D__LOC_DEBUG__ -g -std=c++0x -I. -I../../../../vendor/qcom/proprietary/gps-internal/unit-tests/fakes_for_host -I../../../../system/core/include -lpthread LocThread.cpp
|
||||||
|
// test detached thread: valgrind ./a.out 0
|
||||||
|
// test joinable thread: valgrind ./a.out 1
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
LocRunnableTest1 test(10);
|
||||||
|
|
||||||
|
LocThread thread;
|
||||||
|
thread.start("LocThreadTest", test, atoi(argv[1]));
|
||||||
|
|
||||||
|
sleep(10);
|
||||||
|
|
||||||
|
thread.stop();
|
||||||
|
|
||||||
|
sleep(5);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
92
gps/utils/LocThread.h
Normal file
92
gps/utils/LocThread.h
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef __LOC_THREAD__
|
||||||
|
#define __LOC_THREAD__
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
// abstract class to be implemented by client to provide a runnable class
|
||||||
|
// which gets scheduled by LocThread
|
||||||
|
class LocRunnable {
|
||||||
|
public:
|
||||||
|
inline LocRunnable() {}
|
||||||
|
inline virtual ~LocRunnable() {}
|
||||||
|
|
||||||
|
// The method to be implemented by thread clients
|
||||||
|
// and be scheduled by LocThread
|
||||||
|
// This method will be repeated called until it returns false; or
|
||||||
|
// until thread is stopped.
|
||||||
|
virtual bool run() = 0;
|
||||||
|
|
||||||
|
// The method to be run before thread loop (conditionally repeatedly)
|
||||||
|
// calls run()
|
||||||
|
inline virtual void prerun() {}
|
||||||
|
|
||||||
|
// The method to be run after thread loop (conditionally repeatedly)
|
||||||
|
// calls run()
|
||||||
|
inline virtual void postrun() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// opaque class to provide service implementation.
|
||||||
|
class LocThreadDelegate;
|
||||||
|
|
||||||
|
// A utility class to create a thread and run LocRunnable
|
||||||
|
// caller passes in.
|
||||||
|
class LocThread {
|
||||||
|
LocThreadDelegate* mThread;
|
||||||
|
public:
|
||||||
|
inline LocThread() : mThread(NULL) {}
|
||||||
|
virtual ~LocThread();
|
||||||
|
|
||||||
|
typedef pthread_t (*tCreate)(const char* name, void* (*start)(void*), void* arg);
|
||||||
|
// client starts thread with a runnable, which implements
|
||||||
|
// the logics to fun in the created thread context.
|
||||||
|
// The thread could be either joinable or detached.
|
||||||
|
// runnable is an obj managed by client. Client creates and
|
||||||
|
// frees it (but must be after stop() is called, or
|
||||||
|
// this LocThread obj is deleted).
|
||||||
|
// The obj will be deleted by LocThread if start()
|
||||||
|
// returns true. Else it is client's responsibility
|
||||||
|
// to delete the object
|
||||||
|
// Returns 0 if success; false if failure.
|
||||||
|
bool start(tCreate creator, const char* threadName, LocRunnable* runnable, bool joinable = true);
|
||||||
|
inline bool start(const char* threadName, LocRunnable* runnable, bool joinable = true) {
|
||||||
|
return start(NULL, threadName, runnable, joinable);
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: if this is a joinable thread, this stop may block
|
||||||
|
// for a while until the thread is joined.
|
||||||
|
void stop();
|
||||||
|
|
||||||
|
// thread status check
|
||||||
|
inline bool isRunning() { return NULL != mThread; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //__LOC_THREAD__
|
751
gps/utils/LocTimer.cpp
Normal file
751
gps/utils/LocTimer.cpp
Normal file
|
@ -0,0 +1,751 @@
|
||||||
|
/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <loc_timer.h>
|
||||||
|
#include <sys/timerfd.h>
|
||||||
|
#include <sys/epoll.h>
|
||||||
|
#include <LocTimer.h>
|
||||||
|
#include <LocHeap.h>
|
||||||
|
#include <LocThread.h>
|
||||||
|
#include <LocSharedLock.h>
|
||||||
|
#include <MsgTask.h>
|
||||||
|
|
||||||
|
#ifdef __HOST_UNIT_TEST__
|
||||||
|
#define EPOLLWAKEUP 0
|
||||||
|
#define CLOCK_BOOTTIME CLOCK_MONOTONIC
|
||||||
|
#define CLOCK_BOOTTIME_ALARM CLOCK_MONOTONIC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
There are implementations of 5 classes in this file:
|
||||||
|
LocTimer, LocTimerDelegate, LocTimerContainer, LocTimerPollTask, LocTimerWrapper
|
||||||
|
|
||||||
|
LocTimer - client front end, interface for client to start / stop timers, also
|
||||||
|
to provide a callback.
|
||||||
|
LocTimerDelegate - an internal timer entity, which also is a LocRankable obj.
|
||||||
|
Its life cycle is different than that of LocTimer. It gets
|
||||||
|
created when LocTimer::start() is called, and gets deleted
|
||||||
|
when it expires or clients calls the hosting LocTimer obj's
|
||||||
|
stop() method. When a LocTimerDelegate obj is ticking, it
|
||||||
|
stays in the corresponding LocTimerContainer. When expired
|
||||||
|
or stopped, the obj is removed from the container. Since it
|
||||||
|
is also a LocRankable obj, and LocTimerContainer also is a
|
||||||
|
heap, its ranks() implementation decides where it is placed
|
||||||
|
in the heap.
|
||||||
|
LocTimerContainer - core of the timer service. It is a container (derived from
|
||||||
|
LocHeap) for LocTimerDelegate (implements LocRankable) objs.
|
||||||
|
There are 2 of such containers, one for sw timers (or Linux
|
||||||
|
timers) one for hw timers (or Linux alarms). It adds one of
|
||||||
|
each (those that expire the soonest) to kernel via services
|
||||||
|
provided by LocTimerPollTask. All the heap management on the
|
||||||
|
LocTimerDelegate objs are done in the MsgTask context, such
|
||||||
|
that synchronization is ensured.
|
||||||
|
LocTimerPollTask - is a class that wraps timerfd and epoll POXIS APIs. It also
|
||||||
|
both implements LocRunnalbe with epoll_wait() in the run()
|
||||||
|
method. It is also a LocThread client, so as to loop the run
|
||||||
|
method.
|
||||||
|
LocTimerWrapper - a LocTimer client itself, to implement the existing C API with
|
||||||
|
APIs, loc_timer_start() and loc_timer_stop().
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
class LocTimerPollTask;
|
||||||
|
|
||||||
|
// This is a multi-functaional class that:
|
||||||
|
// * extends the LocHeap class for the detection of head update upon add / remove
|
||||||
|
// events. When that happens, soonest time out changes, so timerfd needs update.
|
||||||
|
// * contains the timers, and add / remove them into the heap
|
||||||
|
// * provides and maps 2 of such containers, one for timers (or mSwTimers), one
|
||||||
|
// for alarms (or mHwTimers);
|
||||||
|
// * provides a polling thread;
|
||||||
|
// * provides a MsgTask thread for synchronized add / remove / timer client callback.
|
||||||
|
class LocTimerContainer : public LocHeap {
|
||||||
|
// mutex to synchronize getters of static members
|
||||||
|
static pthread_mutex_t mMutex;
|
||||||
|
// Container of timers
|
||||||
|
static LocTimerContainer* mSwTimers;
|
||||||
|
// Container of alarms
|
||||||
|
static LocTimerContainer* mHwTimers;
|
||||||
|
// Msg task to provider msg Q, sender and reader.
|
||||||
|
static MsgTask* mMsgTask;
|
||||||
|
// Poll task to provide epoll call and threading to poll.
|
||||||
|
static LocTimerPollTask* mPollTask;
|
||||||
|
// timer / alarm fd
|
||||||
|
int mDevFd;
|
||||||
|
// ctor
|
||||||
|
LocTimerContainer(bool wakeOnExpire);
|
||||||
|
// dtor
|
||||||
|
~LocTimerContainer();
|
||||||
|
static MsgTask* getMsgTaskLocked();
|
||||||
|
static LocTimerPollTask* getPollTaskLocked();
|
||||||
|
// extend LocHeap and pop if the top outRanks input
|
||||||
|
LocTimerDelegate* popIfOutRanks(LocTimerDelegate& timer);
|
||||||
|
// update the timer POSIX calls with updated soonest timer spec
|
||||||
|
void updateSoonestTime(LocTimerDelegate* priorTop);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// factory method to control the creation of mSwTimers / mHwTimers
|
||||||
|
static LocTimerContainer* get(bool wakeOnExpire);
|
||||||
|
|
||||||
|
LocTimerDelegate* getSoonestTimer();
|
||||||
|
int getTimerFd();
|
||||||
|
// add a timer / alarm obj into the container
|
||||||
|
void add(LocTimerDelegate& timer);
|
||||||
|
// remove a timer / alarm obj from the container
|
||||||
|
void remove(LocTimerDelegate& timer);
|
||||||
|
// handling of timer / alarm expiration
|
||||||
|
void expire();
|
||||||
|
};
|
||||||
|
|
||||||
|
// This class implements the polling thread that epolls imer / alarm fds.
|
||||||
|
// The LocRunnable::run() contains the actual polling. The other methods
|
||||||
|
// will be run in the caller's thread context to add / remove timer / alarm
|
||||||
|
// fds the kernel, while the polling is blocked on epoll_wait() call.
|
||||||
|
// Since the design is that we have maximally 2 polls, one for all the
|
||||||
|
// timers; one for all the alarms, we will poll at most on 2 fds. But it
|
||||||
|
// is possile that all we have are only timers or alarms at one time, so we
|
||||||
|
// allow dynamically add / remove fds we poll on. The design decision of
|
||||||
|
// having 1 fd per container of timer / alarm is such that, we may not need
|
||||||
|
// to make a system call each time a timer / alarm is added / removed, unless
|
||||||
|
// that changes the "soonest" time out of that of all the timers / alarms.
|
||||||
|
class LocTimerPollTask : public LocRunnable {
|
||||||
|
// the epoll fd
|
||||||
|
const int mFd;
|
||||||
|
// the thread that calls run() method
|
||||||
|
LocThread* mThread;
|
||||||
|
friend class LocThreadDelegate;
|
||||||
|
// dtor
|
||||||
|
~LocTimerPollTask();
|
||||||
|
public:
|
||||||
|
// ctor
|
||||||
|
LocTimerPollTask();
|
||||||
|
// this obj will be deleted once thread is deleted
|
||||||
|
void destroy();
|
||||||
|
// add a container of timers. Each contain has a unique device fd, i.e.
|
||||||
|
// either timer or alarm fd, and a heap of timers / alarms. It is expected
|
||||||
|
// that container would have written to the device fd with the soonest
|
||||||
|
// time out value in the heap at the time of calling this method. So all
|
||||||
|
// this method does is to add the fd of the input container to the poll
|
||||||
|
// and also add the pointer of the container to the event data ptr, such
|
||||||
|
// when poll_wait wakes up on events, we know who is the owner of the fd.
|
||||||
|
void addPoll(LocTimerContainer& timerContainer);
|
||||||
|
// remove a fd that is assciated with a container. The expectation is that
|
||||||
|
// the atual timer would have been removed from the container.
|
||||||
|
void removePoll(LocTimerContainer& timerContainer);
|
||||||
|
// The polling thread context will call this method. This is where
|
||||||
|
// epoll_wait() is blocking and waiting for events..
|
||||||
|
virtual bool run();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Internal class of timer obj. It gets born when client calls LocTimer::start();
|
||||||
|
// and gets deleted when client calls LocTimer::stop() or when the it expire()'s.
|
||||||
|
// This class implements LocRankable::ranks() so that when an obj is added into
|
||||||
|
// the container (of LocHeap), it gets placed in sorted order.
|
||||||
|
class LocTimerDelegate : public LocRankable {
|
||||||
|
friend class LocTimerContainer;
|
||||||
|
friend class LocTimer;
|
||||||
|
LocTimer* mClient;
|
||||||
|
LocSharedLock* mLock;
|
||||||
|
struct timespec mFutureTime;
|
||||||
|
LocTimerContainer* mContainer;
|
||||||
|
// not a complete obj, just ctor for LocRankable comparisons
|
||||||
|
inline LocTimerDelegate(struct timespec& delay)
|
||||||
|
: mClient(NULL), mLock(NULL), mFutureTime(delay), mContainer(NULL) {}
|
||||||
|
inline ~LocTimerDelegate() { if (mLock) { mLock->drop(); mLock = NULL; } }
|
||||||
|
public:
|
||||||
|
LocTimerDelegate(LocTimer& client, struct timespec& futureTime, LocTimerContainer* container);
|
||||||
|
void destroyLocked();
|
||||||
|
// LocRankable virtual method
|
||||||
|
virtual int ranks(LocRankable& rankable);
|
||||||
|
void expire();
|
||||||
|
inline struct timespec getFutureTime() { return mFutureTime; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/***************************LocTimerContainer methods***************************/
|
||||||
|
|
||||||
|
// Most of these static recources are created on demand. They however are never
|
||||||
|
// destoyed. The theory is that there are processes that link to this util lib
|
||||||
|
// but never use timer, then these resources would never need to be created.
|
||||||
|
// For those processes that do use timer, it will likely also need to every
|
||||||
|
// once in a while. It might be cheaper keeping them around.
|
||||||
|
pthread_mutex_t LocTimerContainer::mMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
LocTimerContainer* LocTimerContainer::mSwTimers = NULL;
|
||||||
|
LocTimerContainer* LocTimerContainer::mHwTimers = NULL;
|
||||||
|
MsgTask* LocTimerContainer::mMsgTask = NULL;
|
||||||
|
LocTimerPollTask* LocTimerContainer::mPollTask = NULL;
|
||||||
|
|
||||||
|
// ctor - initialize timer heaps
|
||||||
|
// A container for swTimer (timer) is created, when wakeOnExpire is true; or
|
||||||
|
// HwTimer (alarm), when wakeOnExpire is false.
|
||||||
|
LocTimerContainer::LocTimerContainer(bool wakeOnExpire) :
|
||||||
|
mDevFd(timerfd_create(wakeOnExpire ? CLOCK_BOOTTIME_ALARM : CLOCK_BOOTTIME, 0)) {
|
||||||
|
|
||||||
|
if ((-1 == mDevFd) && (errno == EINVAL)) {
|
||||||
|
LOC_LOGW("%s: timerfd_create failure, fallback to CLOCK_MONOTONIC - %s",
|
||||||
|
__FUNCTION__, strerror(errno));
|
||||||
|
mDevFd = timerfd_create(CLOCK_MONOTONIC, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-1 != mDevFd) {
|
||||||
|
// ensure we have the necessary resources created
|
||||||
|
LocTimerContainer::getPollTaskLocked();
|
||||||
|
LocTimerContainer::getMsgTaskLocked();
|
||||||
|
} else {
|
||||||
|
LOC_LOGE("%s: timerfd_create failure - %s", __FUNCTION__, strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// dtor
|
||||||
|
// we do not ever destroy the static resources.
|
||||||
|
inline
|
||||||
|
LocTimerContainer::~LocTimerContainer() {
|
||||||
|
close(mDevFd);
|
||||||
|
}
|
||||||
|
|
||||||
|
LocTimerContainer* LocTimerContainer::get(bool wakeOnExpire) {
|
||||||
|
// get the reference of either mHwTimer or mSwTimers per wakeOnExpire
|
||||||
|
LocTimerContainer*& container = wakeOnExpire ? mHwTimers : mSwTimers;
|
||||||
|
// it is cheap to check pointer first than locking mutext unconditionally
|
||||||
|
if (!container) {
|
||||||
|
pthread_mutex_lock(&mMutex);
|
||||||
|
// let's check one more time to be safe
|
||||||
|
if (!container) {
|
||||||
|
container = new LocTimerContainer(wakeOnExpire);
|
||||||
|
// timerfd_create failure
|
||||||
|
if (-1 == container->getTimerFd()) {
|
||||||
|
delete container;
|
||||||
|
container = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
}
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
|
||||||
|
MsgTask* LocTimerContainer::getMsgTaskLocked() {
|
||||||
|
// it is cheap to check pointer first than locking mutext unconditionally
|
||||||
|
if (!mMsgTask) {
|
||||||
|
mMsgTask = new MsgTask("LocTimerMsgTask", false);
|
||||||
|
}
|
||||||
|
return mMsgTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocTimerPollTask* LocTimerContainer::getPollTaskLocked() {
|
||||||
|
// it is cheap to check pointer first than locking mutext unconditionally
|
||||||
|
if (!mPollTask) {
|
||||||
|
mPollTask = new LocTimerPollTask();
|
||||||
|
}
|
||||||
|
return mPollTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
LocTimerDelegate* LocTimerContainer::getSoonestTimer() {
|
||||||
|
return (LocTimerDelegate*)(peek());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
int LocTimerContainer::getTimerFd() {
|
||||||
|
return mDevFd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocTimerContainer::updateSoonestTime(LocTimerDelegate* priorTop) {
|
||||||
|
LocTimerDelegate* curTop = getSoonestTimer();
|
||||||
|
|
||||||
|
// check if top has changed
|
||||||
|
if (curTop != priorTop) {
|
||||||
|
struct itimerspec delay;
|
||||||
|
memset(&delay, 0, sizeof(struct itimerspec));
|
||||||
|
bool toSetTime = false;
|
||||||
|
// if tree is empty now, we remove poll and disarm timer
|
||||||
|
if (!curTop) {
|
||||||
|
mPollTask->removePoll(*this);
|
||||||
|
// setting the values to disarm timer
|
||||||
|
delay.it_value.tv_sec = 0;
|
||||||
|
delay.it_value.tv_nsec = 0;
|
||||||
|
toSetTime = true;
|
||||||
|
} else if (!priorTop || curTop->outRanks(*priorTop)) {
|
||||||
|
// do this first to avoid race condition, in case settime is called
|
||||||
|
// with too small an interval
|
||||||
|
mPollTask->addPoll(*this);
|
||||||
|
delay.it_value = curTop->getFutureTime();
|
||||||
|
toSetTime = true;
|
||||||
|
}
|
||||||
|
if (toSetTime) {
|
||||||
|
timerfd_settime(getTimerFd(), TFD_TIMER_ABSTIME, &delay, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// all the heap management is done in the MsgTask context.
|
||||||
|
inline
|
||||||
|
void LocTimerContainer::add(LocTimerDelegate& timer) {
|
||||||
|
struct MsgTimerPush : public LocMsg {
|
||||||
|
LocTimerContainer* mTimerContainer;
|
||||||
|
LocHeapNode* mTree;
|
||||||
|
LocTimerDelegate* mTimer;
|
||||||
|
inline MsgTimerPush(LocTimerContainer& container, LocTimerDelegate& timer) :
|
||||||
|
LocMsg(), mTimerContainer(&container), mTimer(&timer) {}
|
||||||
|
inline virtual void proc() const {
|
||||||
|
LocTimerDelegate* priorTop = mTimerContainer->getSoonestTimer();
|
||||||
|
mTimerContainer->push((LocRankable&)(*mTimer));
|
||||||
|
mTimerContainer->updateSoonestTime(priorTop);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mMsgTask->sendMsg(new MsgTimerPush(*this, timer));
|
||||||
|
}
|
||||||
|
|
||||||
|
// all the heap management is done in the MsgTask context.
|
||||||
|
void LocTimerContainer::remove(LocTimerDelegate& timer) {
|
||||||
|
struct MsgTimerRemove : public LocMsg {
|
||||||
|
LocTimerContainer* mTimerContainer;
|
||||||
|
LocTimerDelegate* mTimer;
|
||||||
|
inline MsgTimerRemove(LocTimerContainer& container, LocTimerDelegate& timer) :
|
||||||
|
LocMsg(), mTimerContainer(&container), mTimer(&timer) {}
|
||||||
|
inline virtual void proc() const {
|
||||||
|
LocTimerDelegate* priorTop = mTimerContainer->getSoonestTimer();
|
||||||
|
|
||||||
|
// update soonest timer only if mTimer is actually removed from
|
||||||
|
// mTimerContainer AND mTimer is not priorTop.
|
||||||
|
if (priorTop == ((LocHeap*)mTimerContainer)->remove((LocRankable&)*mTimer)) {
|
||||||
|
// if passing in NULL, we tell updateSoonestTime to update
|
||||||
|
// kernel with the current top timer interval.
|
||||||
|
mTimerContainer->updateSoonestTime(NULL);
|
||||||
|
}
|
||||||
|
// all timers are deleted here, and only here.
|
||||||
|
delete mTimer;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mMsgTask->sendMsg(new MsgTimerRemove(*this, timer));
|
||||||
|
}
|
||||||
|
|
||||||
|
// all the heap management is done in the MsgTask context.
|
||||||
|
// Upon expire, we check and continuously pop the heap until
|
||||||
|
// the top node's timeout is in the future.
|
||||||
|
void LocTimerContainer::expire() {
|
||||||
|
struct MsgTimerExpire : public LocMsg {
|
||||||
|
LocTimerContainer* mTimerContainer;
|
||||||
|
inline MsgTimerExpire(LocTimerContainer& container) :
|
||||||
|
LocMsg(), mTimerContainer(&container) {}
|
||||||
|
inline virtual void proc() const {
|
||||||
|
struct timespec now;
|
||||||
|
// get time spec of now
|
||||||
|
clock_gettime(CLOCK_BOOTTIME, &now);
|
||||||
|
LocTimerDelegate timerOfNow(now);
|
||||||
|
// pop everything in the heap that outRanks now, i.e. has time older than now
|
||||||
|
// and then call expire() on that timer.
|
||||||
|
for (LocTimerDelegate* timer = (LocTimerDelegate*)mTimerContainer->pop();
|
||||||
|
NULL != timer;
|
||||||
|
timer = mTimerContainer->popIfOutRanks(timerOfNow)) {
|
||||||
|
// the timer delegate obj will be deleted before the return of this call
|
||||||
|
timer->expire();
|
||||||
|
}
|
||||||
|
mTimerContainer->updateSoonestTime(NULL);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct itimerspec delay;
|
||||||
|
memset(&delay, 0, sizeof(struct itimerspec));
|
||||||
|
timerfd_settime(getTimerFd(), TFD_TIMER_ABSTIME, &delay, NULL);
|
||||||
|
mPollTask->removePoll(*this);
|
||||||
|
mMsgTask->sendMsg(new MsgTimerExpire(*this));
|
||||||
|
}
|
||||||
|
|
||||||
|
LocTimerDelegate* LocTimerContainer::popIfOutRanks(LocTimerDelegate& timer) {
|
||||||
|
LocTimerDelegate* poppedNode = NULL;
|
||||||
|
if (mTree && !timer.outRanks(*peek())) {
|
||||||
|
poppedNode = (LocTimerDelegate*)(pop());
|
||||||
|
}
|
||||||
|
|
||||||
|
return poppedNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************LocTimerPollTask methods***************************/
|
||||||
|
|
||||||
|
inline
|
||||||
|
LocTimerPollTask::LocTimerPollTask()
|
||||||
|
: mFd(epoll_create(2)), mThread(new LocThread()) {
|
||||||
|
// before a next call returens, a thread will be created. The run() method
|
||||||
|
// could already be running in parallel. Also, since each of the objs
|
||||||
|
// creates a thread, the container will make sure that there will be only
|
||||||
|
// one of such obj for our timer implementation.
|
||||||
|
if (!mThread->start("LocTimerPollTask", this)) {
|
||||||
|
delete mThread;
|
||||||
|
mThread = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
LocTimerPollTask::~LocTimerPollTask() {
|
||||||
|
// when fs is closed, epoll_wait() should fail run() should return false
|
||||||
|
// and the spawned thread should exit.
|
||||||
|
close(mFd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocTimerPollTask::destroy() {
|
||||||
|
if (mThread) {
|
||||||
|
LocThread* thread = mThread;
|
||||||
|
mThread = NULL;
|
||||||
|
delete thread;
|
||||||
|
} else {
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocTimerPollTask::addPoll(LocTimerContainer& timerContainer) {
|
||||||
|
struct epoll_event ev;
|
||||||
|
memset(&ev, 0, sizeof(ev));
|
||||||
|
|
||||||
|
ev.events = EPOLLIN | EPOLLWAKEUP;
|
||||||
|
ev.data.fd = timerContainer.getTimerFd();
|
||||||
|
// it is important that we set this context pointer with the input
|
||||||
|
// timer container this is how we know which container should handle
|
||||||
|
// which expiration.
|
||||||
|
ev.data.ptr = &timerContainer;
|
||||||
|
|
||||||
|
epoll_ctl(mFd, EPOLL_CTL_ADD, timerContainer.getTimerFd(), &ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void LocTimerPollTask::removePoll(LocTimerContainer& timerContainer) {
|
||||||
|
epoll_ctl(mFd, EPOLL_CTL_DEL, timerContainer.getTimerFd(), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The polling thread context will call this method. If run() method needs to
|
||||||
|
// be repetitvely called, it must return true from the previous call.
|
||||||
|
bool LocTimerPollTask::run() {
|
||||||
|
struct epoll_event ev[2];
|
||||||
|
|
||||||
|
// we have max 2 descriptors to poll from
|
||||||
|
int fds = epoll_wait(mFd, ev, 2, -1);
|
||||||
|
|
||||||
|
// we pretty much want to continually poll until the fd is closed
|
||||||
|
bool rerun = (fds > 0) || (errno == EINTR);
|
||||||
|
|
||||||
|
if (fds > 0) {
|
||||||
|
// we may have 2 events
|
||||||
|
for (int i = 0; i < fds; i++) {
|
||||||
|
// each fd has a context pointer associated with the right timer container
|
||||||
|
LocTimerContainer* container = (LocTimerContainer*)(ev[i].data.ptr);
|
||||||
|
if (container) {
|
||||||
|
container->expire();
|
||||||
|
} else {
|
||||||
|
epoll_ctl(mFd, EPOLL_CTL_DEL, ev[i].data.fd, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if rerun is true, we are requesting to be scheduled again
|
||||||
|
return rerun;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************LocTimerDelegate methods***************************/
|
||||||
|
|
||||||
|
inline
|
||||||
|
LocTimerDelegate::LocTimerDelegate(LocTimer& client,
|
||||||
|
struct timespec& futureTime,
|
||||||
|
LocTimerContainer* container)
|
||||||
|
: mClient(&client),
|
||||||
|
mLock(mClient->mLock->share()),
|
||||||
|
mFutureTime(futureTime),
|
||||||
|
mContainer(container) {
|
||||||
|
// adding the timer into the container
|
||||||
|
mContainer->add(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void LocTimerDelegate::destroyLocked() {
|
||||||
|
// client handle will likely be deleted soon after this
|
||||||
|
// method returns. Nulling this handle so that expire()
|
||||||
|
// won't call the callback on the dead handle any more.
|
||||||
|
mClient = NULL;
|
||||||
|
|
||||||
|
if (mContainer) {
|
||||||
|
LocTimerContainer* container = mContainer;
|
||||||
|
mContainer = NULL;
|
||||||
|
if (container) {
|
||||||
|
container->remove(*this);
|
||||||
|
}
|
||||||
|
} // else we do not do anything. No such *this* can be
|
||||||
|
// created and reached here with mContainer ever been
|
||||||
|
// a non NULL. So *this* must have reached the if clause
|
||||||
|
// once, and we want it reach there only once.
|
||||||
|
}
|
||||||
|
|
||||||
|
int LocTimerDelegate::ranks(LocRankable& rankable) {
|
||||||
|
int rank = -1;
|
||||||
|
LocTimerDelegate* timer = (LocTimerDelegate*)(&rankable);
|
||||||
|
if (timer) {
|
||||||
|
// larger time ranks lower!!!
|
||||||
|
// IOW, if input obj has bigger tv_sec/tv_nsec, this obj outRanks higher
|
||||||
|
rank = timer->mFutureTime.tv_sec - mFutureTime.tv_sec;
|
||||||
|
if(0 == rank)
|
||||||
|
{
|
||||||
|
//rank against tv_nsec for msec accuracy
|
||||||
|
rank = (int)(timer->mFutureTime.tv_nsec - mFutureTime.tv_nsec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rank;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void LocTimerDelegate::expire() {
|
||||||
|
// keeping a copy of client pointer to be safe
|
||||||
|
// when timeOutCallback() is called at the end of this
|
||||||
|
// method, *this* obj may be already deleted.
|
||||||
|
LocTimer* client = mClient;
|
||||||
|
// force a stop, which will lead to delete of this obj
|
||||||
|
if (client && client->stop()) {
|
||||||
|
// calling client callback with a pointer save on the stack
|
||||||
|
// only if stop() returns true, i.e. it hasn't been stopped
|
||||||
|
// already.
|
||||||
|
client->timeOutCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************LocTimer methods***************************/
|
||||||
|
LocTimer::LocTimer() : mTimer(NULL), mLock(new LocSharedLock()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
LocTimer::~LocTimer() {
|
||||||
|
stop();
|
||||||
|
if (mLock) {
|
||||||
|
mLock->drop();
|
||||||
|
mLock = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LocTimer::start(unsigned int timeOutInMs, bool wakeOnExpire) {
|
||||||
|
bool success = false;
|
||||||
|
mLock->lock();
|
||||||
|
if (!mTimer) {
|
||||||
|
struct timespec futureTime;
|
||||||
|
clock_gettime(CLOCK_BOOTTIME, &futureTime);
|
||||||
|
futureTime.tv_sec += timeOutInMs / 1000;
|
||||||
|
futureTime.tv_nsec += (timeOutInMs % 1000) * 1000000;
|
||||||
|
if (futureTime.tv_nsec >= 1000000000) {
|
||||||
|
futureTime.tv_sec += futureTime.tv_nsec / 1000000000;
|
||||||
|
futureTime.tv_nsec %= 1000000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocTimerContainer* container;
|
||||||
|
container = LocTimerContainer::get(wakeOnExpire);
|
||||||
|
if (NULL != container) {
|
||||||
|
mTimer = new LocTimerDelegate(*this, futureTime, container);
|
||||||
|
// if mTimer is non 0, success should be 0; or vice versa
|
||||||
|
}
|
||||||
|
success = (NULL != mTimer);
|
||||||
|
}
|
||||||
|
mLock->unlock();
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LocTimer::stop() {
|
||||||
|
bool success = false;
|
||||||
|
mLock->lock();
|
||||||
|
if (mTimer) {
|
||||||
|
LocTimerDelegate* timer = mTimer;
|
||||||
|
mTimer = NULL;
|
||||||
|
if (timer) {
|
||||||
|
timer->destroyLocked();
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mLock->unlock();
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************LocTimerWrapper methods***************************/
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// This section below wraps for the C style APIs
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
class LocTimerWrapper : public LocTimer {
|
||||||
|
loc_timer_callback mCb;
|
||||||
|
void* mCallerData;
|
||||||
|
LocTimerWrapper* mMe;
|
||||||
|
static pthread_mutex_t mMutex;
|
||||||
|
inline ~LocTimerWrapper() { mCb = NULL; mMe = NULL; }
|
||||||
|
public:
|
||||||
|
inline LocTimerWrapper(loc_timer_callback cb, void* callerData) :
|
||||||
|
mCb(cb), mCallerData(callerData), mMe(this) {
|
||||||
|
}
|
||||||
|
void destroy() {
|
||||||
|
pthread_mutex_lock(&mMutex);
|
||||||
|
if (NULL != mCb && this == mMe) {
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mMutex);
|
||||||
|
}
|
||||||
|
virtual void timeOutCallback() {
|
||||||
|
loc_timer_callback cb = mCb;
|
||||||
|
void* callerData = mCallerData;
|
||||||
|
if (cb) {
|
||||||
|
cb(callerData, 0);
|
||||||
|
}
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pthread_mutex_t LocTimerWrapper::mMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
void* loc_timer_start(uint64_t msec, loc_timer_callback cb_func,
|
||||||
|
void *caller_data, bool wake_on_expire)
|
||||||
|
{
|
||||||
|
LocTimerWrapper* locTimerWrapper = NULL;
|
||||||
|
|
||||||
|
if (cb_func) {
|
||||||
|
locTimerWrapper = new LocTimerWrapper(cb_func, caller_data);
|
||||||
|
|
||||||
|
if (locTimerWrapper) {
|
||||||
|
locTimerWrapper->start(msec, wake_on_expire);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return locTimerWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
void loc_timer_stop(void*& handle)
|
||||||
|
{
|
||||||
|
if (handle) {
|
||||||
|
LocTimerWrapper* locTimerWrapper = (LocTimerWrapper*)(handle);
|
||||||
|
locTimerWrapper->destroy();
|
||||||
|
handle = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// This section above wraps for the C style APIs
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifdef __LOC_DEBUG__
|
||||||
|
|
||||||
|
double getDeltaSeconds(struct timespec from, struct timespec to) {
|
||||||
|
return (double)to.tv_sec + (double)to.tv_nsec / 1000000000
|
||||||
|
- from.tv_sec - (double)from.tv_nsec / 1000000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct timespec getNow() {
|
||||||
|
struct timespec now;
|
||||||
|
clock_gettime(CLOCK_BOOTTIME, &now);
|
||||||
|
return now;
|
||||||
|
}
|
||||||
|
|
||||||
|
class LocTimerTest : public LocTimer, public LocRankable {
|
||||||
|
int mTimeOut;
|
||||||
|
const struct timespec mTimeOfBirth;
|
||||||
|
inline struct timespec getTimerWrapper(int timeout) {
|
||||||
|
struct timespec now;
|
||||||
|
clock_gettime(CLOCK_BOOTTIME, &now);
|
||||||
|
now.tv_sec += timeout;
|
||||||
|
return now;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
inline LocTimerTest(int timeout) : LocTimer(), LocRankable(),
|
||||||
|
mTimeOut(timeout), mTimeOfBirth(getTimerWrapper(0)) {}
|
||||||
|
inline virtual int ranks(LocRankable& rankable) {
|
||||||
|
LocTimerTest* timer = dynamic_cast<LocTimerTest*>(&rankable);
|
||||||
|
return timer->mTimeOut - mTimeOut;
|
||||||
|
}
|
||||||
|
inline virtual void timeOutCallback() {
|
||||||
|
printf("timeOutCallback() - ");
|
||||||
|
deviation();
|
||||||
|
}
|
||||||
|
double deviation() {
|
||||||
|
struct timespec now = getTimerWrapper(0);
|
||||||
|
double delta = getDeltaSeconds(mTimeOfBirth, now);
|
||||||
|
printf("%lf: %lf\n", delta, delta * 100 / mTimeOut);
|
||||||
|
return delta / mTimeOut;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// For Linux command line testing:
|
||||||
|
// compilation:
|
||||||
|
// g++ -D__LOC_HOST_DEBUG__ -D__LOC_DEBUG__ -g -I. -I../../../../system/core/include -o LocHeap.o LocHeap.cpp
|
||||||
|
// g++ -D__LOC_HOST_DEBUG__ -D__LOC_DEBUG__ -g -std=c++0x -I. -I../../../../system/core/include -lpthread -o LocThread.o LocThread.cpp
|
||||||
|
// g++ -D__LOC_HOST_DEBUG__ -D__LOC_DEBUG__ -g -I. -I../../../../system/core/include -o LocTimer.o LocTimer.cpp
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
struct timespec timeOfStart=getNow();
|
||||||
|
srand(time(NULL));
|
||||||
|
int tries = atoi(argv[1]);
|
||||||
|
int checks = tries >> 3;
|
||||||
|
LocTimerTest** timerArray = new LocTimerTest*[tries];
|
||||||
|
memset(timerArray, NULL, tries);
|
||||||
|
|
||||||
|
for (int i = 0; i < tries; i++) {
|
||||||
|
int r = rand() % tries;
|
||||||
|
LocTimerTest* timer = new LocTimerTest(r);
|
||||||
|
if (timerArray[r]) {
|
||||||
|
if (!timer->stop()) {
|
||||||
|
printf("%lf:\n", getDeltaSeconds(timeOfStart, getNow()));
|
||||||
|
printf("ERRER: %dth timer, id %d, not running when it should be\n", i, r);
|
||||||
|
exit(0);
|
||||||
|
} else {
|
||||||
|
printf("stop() - %d\n", r);
|
||||||
|
delete timer;
|
||||||
|
timerArray[r] = NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!timer->start(r, false)) {
|
||||||
|
printf("%lf:\n", getDeltaSeconds(timeOfStart, getNow()));
|
||||||
|
printf("ERRER: %dth timer, id %d, running when it should not be\n", i, r);
|
||||||
|
exit(0);
|
||||||
|
} else {
|
||||||
|
printf("stop() - %d\n", r);
|
||||||
|
timerArray[r] = timer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < tries; i++) {
|
||||||
|
if (timerArray[i]) {
|
||||||
|
if (!timerArray[i]->stop()) {
|
||||||
|
printf("%lf:\n", getDeltaSeconds(timeOfStart, getNow()));
|
||||||
|
printf("ERRER: %dth timer, not running when it should be\n", i);
|
||||||
|
exit(0);
|
||||||
|
} else {
|
||||||
|
printf("stop() - %d\n", i);
|
||||||
|
delete timerArray[i];
|
||||||
|
timerArray[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] timerArray;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
74
gps/utils/LocTimer.h
Normal file
74
gps/utils/LocTimer.h
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation, nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __LOC_TIMER_CPP_H__
|
||||||
|
#define __LOC_TIMER_CPP_H__
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <platform_lib_includes.h>
|
||||||
|
|
||||||
|
// opaque class to provide service implementation.
|
||||||
|
class LocTimerDelegate;
|
||||||
|
class LocSharedLock;
|
||||||
|
|
||||||
|
// LocTimer client must extend this class and implementthe callback.
|
||||||
|
// start() / stop() methods are to arm / disarm timer.
|
||||||
|
class LocTimer
|
||||||
|
{
|
||||||
|
LocTimerDelegate* mTimer;
|
||||||
|
LocSharedLock* mLock;
|
||||||
|
// don't really want mLock to be manipulated by clients, yet LocTimer
|
||||||
|
// has to have a reference to the lock so that the delete of LocTimer
|
||||||
|
// and LocTimerDelegate can work together on their share resources.
|
||||||
|
friend class LocTimerDelegate;
|
||||||
|
|
||||||
|
public:
|
||||||
|
LocTimer();
|
||||||
|
virtual ~LocTimer();
|
||||||
|
|
||||||
|
// timeOutInMs: timeout delay in ms
|
||||||
|
// wakeOnExpire: true if to wake up CPU (if sleeping) upon timer
|
||||||
|
// expiration and notify the client.
|
||||||
|
// false if to wait until next time CPU wakes up (if
|
||||||
|
// sleeping) and then notify the client.
|
||||||
|
// return: true on success;
|
||||||
|
// false on failure, e.g. timer is already running.
|
||||||
|
bool start(uint32_t timeOutInMs, bool wakeOnExpire);
|
||||||
|
|
||||||
|
// return: true on success;
|
||||||
|
// false on failure, e.g. timer is not running.
|
||||||
|
bool stop();
|
||||||
|
|
||||||
|
// LocTimer client Should implement this method.
|
||||||
|
// This method is used for timeout calling back to client. This method
|
||||||
|
// should be short enough (eg: send a message to your own thread).
|
||||||
|
virtual void timeOutCallback() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //__LOC_DELAY_H__
|
64
gps/utils/Makefile.am
Normal file
64
gps/utils/Makefile.am
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
AM_CFLAGS = -Wundef \
|
||||||
|
-I./ \
|
||||||
|
-std=c++11 \
|
||||||
|
$(LOCPLA_CFLAGS)
|
||||||
|
|
||||||
|
AM_CPPFLAGS = -Wundef \
|
||||||
|
-I./ \
|
||||||
|
-std=c++11 \
|
||||||
|
$(LOCPLA_CFLAGS)
|
||||||
|
|
||||||
|
libgps_utils_so_la_h_sources = \
|
||||||
|
msg_q.h \
|
||||||
|
linked_list.h \
|
||||||
|
loc_cfg.h \
|
||||||
|
loc_log.h \
|
||||||
|
loc_target.h \
|
||||||
|
loc_timer.h \
|
||||||
|
MsgTask.h \
|
||||||
|
LocHeap.h \
|
||||||
|
LocThread.h \
|
||||||
|
LocTimer.h \
|
||||||
|
loc_misc_utils.h \
|
||||||
|
loc_nmea.h \
|
||||||
|
gps_extended_c.h \
|
||||||
|
gps_extended.h \
|
||||||
|
loc_gps.h
|
||||||
|
|
||||||
|
libgps_utils_so_la_c_sources = \
|
||||||
|
linked_list.c \
|
||||||
|
msg_q.c \
|
||||||
|
loc_cfg.cpp \
|
||||||
|
loc_log.cpp \
|
||||||
|
loc_target.cpp \
|
||||||
|
LocHeap.cpp \
|
||||||
|
LocTimer.cpp \
|
||||||
|
LocThread.cpp \
|
||||||
|
MsgTask.cpp \
|
||||||
|
loc_misc_utils.cpp \
|
||||||
|
loc_nmea.cpp
|
||||||
|
|
||||||
|
|
||||||
|
library_include_HEADERS = $(libgps_utils_so_la_h_sources)
|
||||||
|
|
||||||
|
libgps_utils_so_la_SOURCES = $(libgps_utils_so_la_c_sources)
|
||||||
|
|
||||||
|
if USE_GLIB
|
||||||
|
libgps_utils_so_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@
|
||||||
|
libgps_utils_so_la_LDFLAGS = -lstdc++ -Wl,-z,defs -lpthread @GLIB_LIBS@ -shared -version-info 1:0:0
|
||||||
|
libgps_utils_so_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@
|
||||||
|
else
|
||||||
|
libgps_utils_so_la_CFLAGS = $(AM_CFLAGS)
|
||||||
|
libgps_utils_so_la_LDFLAGS = -Wl,-z,defs -lpthread -shared -version-info 1:0:0
|
||||||
|
libgps_utils_so_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
libgps_utils_so_la_LIBADD = -lcutils -lstdc++ -llog $(LOCPLA_LIBS)
|
||||||
|
|
||||||
|
#Create and Install libraries
|
||||||
|
lib_LTLIBRARIES = libgps_utils_so.la
|
||||||
|
library_includedir = $(pkgincludedir)
|
||||||
|
pkgconfigdir = $(libdir)/pkgconfig
|
||||||
|
|
||||||
|
pkgconfig_DATA = gps-utils.pc
|
||||||
|
EXTRA_DIST = $(pkgconfig_DATA)
|
104
gps/utils/MsgTask.cpp
Normal file
104
gps/utils/MsgTask.cpp
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
/* Copyright (c) 2011-2013, 2015, 2017The 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_MsgTask"
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <MsgTask.h>
|
||||||
|
#include <msg_q.h>
|
||||||
|
#include <loc_log.h>
|
||||||
|
#include <platform_lib_includes.h>
|
||||||
|
|
||||||
|
static void LocMsgDestroy(void* msg) {
|
||||||
|
delete (LocMsg*)msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
MsgTask::MsgTask(LocThread::tCreate tCreator,
|
||||||
|
const char* threadName, bool joinable) :
|
||||||
|
mQ(msg_q_init2()), mThread(new LocThread()) {
|
||||||
|
if (!mThread->start(tCreator, threadName, this, joinable)) {
|
||||||
|
delete mThread;
|
||||||
|
mThread = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MsgTask::MsgTask(const char* threadName, bool joinable) :
|
||||||
|
mQ(msg_q_init2()), mThread(new LocThread()) {
|
||||||
|
if (!mThread->start(threadName, this, joinable)) {
|
||||||
|
delete mThread;
|
||||||
|
mThread = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MsgTask::~MsgTask() {
|
||||||
|
msg_q_flush((void*)mQ);
|
||||||
|
msg_q_destroy((void**)&mQ);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MsgTask::destroy() {
|
||||||
|
LocThread* thread = mThread;
|
||||||
|
msg_q_unblock((void*)mQ);
|
||||||
|
if (thread) {
|
||||||
|
mThread = NULL;
|
||||||
|
delete thread;
|
||||||
|
} else {
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MsgTask::sendMsg(const LocMsg* msg) const {
|
||||||
|
if (msg) {
|
||||||
|
msg_q_snd((void*)mQ, (void*)msg, LocMsgDestroy);
|
||||||
|
} else {
|
||||||
|
LOC_LOGE("%s: msg is NULL", __func__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MsgTask::prerun() {
|
||||||
|
// make sure we do not run in background scheduling group
|
||||||
|
platform_lib_abstraction_set_sched_policy(platform_lib_abstraction_gettid(), PLA_SP_FOREGROUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MsgTask::run() {
|
||||||
|
LocMsg* msg;
|
||||||
|
msq_q_err_type result = msg_q_rcv((void*)mQ, (void **)&msg);
|
||||||
|
if (eMSG_Q_SUCCESS != result) {
|
||||||
|
LOC_LOGE("%s:%d] fail receiving msg: %s\n", __func__, __LINE__,
|
||||||
|
loc_get_msg_q_status(result));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg->log();
|
||||||
|
// there is where each individual msg handling is invoked
|
||||||
|
msg->proc();
|
||||||
|
|
||||||
|
delete msg;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue