summaryrefslogtreecommitdiffstats
path: root/gps/loc_api
diff options
context:
space:
mode:
Diffstat (limited to 'gps/loc_api')
-rw-r--r--gps/loc_api/Android.mk13
-rw-r--r--gps/loc_api/NOTICE13
-rw-r--r--gps/loc_api/libloc_api_50001/Android.mk101
-rw-r--r--gps/loc_api/libloc_api_50001/LocEngAdapter.cpp343
-rw-r--r--gps/loc_api/libloc_api_50001/LocEngAdapter.h306
-rw-r--r--gps/loc_api/libloc_api_50001/Makefile.am76
-rw-r--r--gps/loc_api/libloc_api_50001/gps.c72
-rw-r--r--gps/loc_api/libloc_api_50001/loc.cpp900
-rw-r--r--gps/loc_api/libloc_api_50001/loc.h66
-rw-r--r--gps/loc_api/libloc_api_50001/loc_eng.cpp2634
-rw-r--r--gps/loc_api/libloc_api_50001/loc_eng.h243
-rw-r--r--gps/loc_api/libloc_api_50001/loc_eng_agps.cpp970
-rw-r--r--gps/loc_api/libloc_api_50001/loc_eng_agps.h419
-rw-r--r--gps/loc_api/libloc_api_50001/loc_eng_dmn_conn.cpp270
-rw-r--r--gps/loc_api/libloc_api_50001/loc_eng_dmn_conn.h59
-rw-r--r--gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_glue_msg.c223
-rw-r--r--gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_glue_msg.h51
-rw-r--r--gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_glue_pipe.c214
-rw-r--r--gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_glue_pipe.h50
-rw-r--r--gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_handler.cpp237
-rw-r--r--gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_handler.h106
-rw-r--r--gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_thread_helper.c399
-rw-r--r--gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_thread_helper.h74
-rw-r--r--gps/loc_api/libloc_api_50001/loc_eng_log.cpp35
-rw-r--r--gps/loc_api/libloc_api_50001/loc_eng_log.h44
-rw-r--r--gps/loc_api/libloc_api_50001/loc_eng_msg.h296
-rw-r--r--gps/loc_api/libloc_api_50001/loc_eng_ni.cpp414
-rw-r--r--gps/loc_api/libloc_api_50001/loc_eng_ni.h59
-rw-r--r--gps/loc_api/libloc_api_50001/loc_eng_nmea.cpp836
-rw-r--r--gps/loc_api/libloc_api_50001/loc_eng_nmea.h42
-rw-r--r--gps/loc_api/libloc_api_50001/loc_eng_xtra.cpp213
-rw-r--r--gps/loc_api/libloc_api_50001/loc_eng_xtra.h47
32 files changed, 9825 insertions, 0 deletions
diff --git a/gps/loc_api/Android.mk b/gps/loc_api/Android.mk
new file mode 100644
index 0000000..8bfdd1b
--- /dev/null
+++ b/gps/loc_api/Android.mk
@@ -0,0 +1,13 @@
+LOCAL_PATH := $(call my-dir)
+
+# add RPC dirs if RPC is available
+ifneq ($(TARGET_NO_RPC),true)
+
+GPS_DIR_LIST += $(LOCAL_PATH)/libloc_api-rpc-50001/
+
+endif #TARGET_NO_RPC
+
+GPS_DIR_LIST += $(LOCAL_PATH)/libloc_api_50001/
+
+#call the subfolders
+include $(addsuffix Android.mk, $(GPS_DIR_LIST))
diff --git a/gps/loc_api/NOTICE b/gps/loc_api/NOTICE
new file mode 100644
index 0000000..85b5740
--- /dev/null
+++ b/gps/loc_api/NOTICE
@@ -0,0 +1,13 @@
+Copyright (c) 2009, QUALCOMM USA, INC.
+
+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 QUALCOMM USA, INC. 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/gps/loc_api/libloc_api_50001/Android.mk b/gps/loc_api/libloc_api_50001/Android.mk
new file mode 100644
index 0000000..75a5d2a
--- /dev/null
+++ b/gps/loc_api/libloc_api_50001/Android.mk
@@ -0,0 +1,101 @@
+ifneq ($(BUILD_TINY_ANDROID),true)
+#Compile this library only for builds with the latest modem image
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libloc_eng
+LOCAL_MODULE_OWNER := qcom
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SHARED_LIBRARIES := \
+ libutils \
+ libcutils \
+ libdl \
+ liblog \
+ libloc_core \
+ libgps.utils
+
+LOCAL_SRC_FILES += \
+ loc_eng.cpp \
+ loc_eng_agps.cpp \
+ loc_eng_xtra.cpp \
+ loc_eng_ni.cpp \
+ loc_eng_log.cpp \
+ loc_eng_nmea.cpp \
+ LocEngAdapter.cpp
+
+LOCAL_SRC_FILES += \
+ loc_eng_dmn_conn.cpp \
+ loc_eng_dmn_conn_handler.cpp \
+ loc_eng_dmn_conn_thread_helper.c \
+ loc_eng_dmn_conn_glue_msg.c \
+ loc_eng_dmn_conn_glue_pipe.c
+
+LOCAL_CFLAGS += \
+ -fno-short-enums \
+ -D_ANDROID_
+
+LOCAL_C_INCLUDES:= \
+ $(TARGET_OUT_HEADERS)/gps.utils \
+ $(TARGET_OUT_HEADERS)/libloc_core \
+ device/samsung/jf-common/gps/loc_api/libloc_api_50001
+
+LOCAL_COPY_HEADERS_TO:= libloc_eng/
+LOCAL_COPY_HEADERS:= \
+ LocEngAdapter.h \
+ loc.h \
+ loc_eng.h \
+ loc_eng_xtra.h \
+ loc_eng_ni.h \
+ loc_eng_agps.h \
+ loc_eng_msg.h \
+ loc_eng_log.h
+
+LOCAL_PRELINK_MODULE := false
+
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := gps.default
+LOCAL_MODULE_OWNER := qcom
+
+LOCAL_MODULE_TAGS := optional
+
+## Libs
+
+LOCAL_SHARED_LIBRARIES := \
+ libutils \
+ libcutils \
+ liblog \
+ libloc_eng \
+ libloc_core \
+ libgps.utils \
+ libdl
+
+LOCAL_SRC_FILES += \
+ loc.cpp \
+ gps.c
+
+LOCAL_CFLAGS += \
+ -fno-short-enums \
+ -D_ANDROID_ \
+
+ifeq ($(TARGET_USES_QCOM_BSP), true)
+LOCAL_CFLAGS += -DTARGET_USES_QCOM_BSP
+endif
+
+## Includes
+LOCAL_C_INCLUDES:= \
+ $(TARGET_OUT_HEADERS)/gps.utils \
+ $(TARGET_OUT_HEADERS)/libloc_core
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
+
+include $(BUILD_SHARED_LIBRARY)
+
+endif # not BUILD_TINY_ANDROID
diff --git a/gps/loc_api/libloc_api_50001/LocEngAdapter.cpp b/gps/loc_api/libloc_api_50001/LocEngAdapter.cpp
new file mode 100644
index 0000000..3d015cb
--- /dev/null
+++ b/gps/loc_api/libloc_api_50001/LocEngAdapter.cpp
@@ -0,0 +1,343 @@
+/* Copyright (c) 2011-2014, 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_EngAdapter"
+
+#include <LocEngAdapter.h>
+#include "loc_eng_msg.h"
+#include "loc_log.h"
+
+using namespace loc_core;
+
+LocInternalAdapter::LocInternalAdapter(LocEngAdapter* adapter) :
+ LocAdapterBase(adapter->getMsgTask()),
+ mLocEngAdapter(adapter)
+{
+}
+void LocInternalAdapter::setPositionModeInt(LocPosMode& posMode) {
+ sendMsg(new LocEngPositionMode(mLocEngAdapter, posMode));
+}
+void LocInternalAdapter::startFixInt() {
+ sendMsg(new LocEngStartFix(mLocEngAdapter));
+}
+void LocInternalAdapter::stopFixInt() {
+ sendMsg(new LocEngStopFix(mLocEngAdapter));
+}
+void LocInternalAdapter::getZppInt() {
+ sendMsg(new LocEngGetZpp(mLocEngAdapter));
+}
+
+LocEngAdapter::LocEngAdapter(LOC_API_ADAPTER_EVENT_MASK_T mask,
+ void* owner, ContextBase* context,
+ MsgTask::tCreate tCreator) :
+ LocAdapterBase(mask,
+ //Get the AFW context if VzW context has not already been intialized in
+ //loc_ext
+ context == NULL?
+ LocDualContext::getLocFgContext(tCreator,
+ LocDualContext::mLocationHalName)
+ :context),
+ mOwner(owner), mInternalAdapter(new LocInternalAdapter(this)),
+ mUlp(new UlpProxyBase()), mNavigating(false),
+ mSupportsAgpsRequests(false),
+ mSupportsPositionInjection(false)
+{
+ memset(&mFixCriteria, 0, sizeof(mFixCriteria));
+ mFixCriteria.mode = LOC_POSITION_MODE_INVALID;
+ LOC_LOGD("LocEngAdapter created");
+}
+
+inline
+LocEngAdapter::~LocEngAdapter()
+{
+ delete mInternalAdapter;
+ LOC_LOGV("LocEngAdapter deleted");
+}
+
+void LocInternalAdapter::setUlpProxy(UlpProxyBase* ulp) {
+ struct LocSetUlpProxy : public LocMsg {
+ LocAdapterBase* mAdapter;
+ UlpProxyBase* mUlp;
+ inline LocSetUlpProxy(LocAdapterBase* adapter, UlpProxyBase* ulp) :
+ LocMsg(), mAdapter(adapter), mUlp(ulp) {
+ }
+ virtual void proc() const {
+ LOC_LOGV("%s] ulp %p adapter %p", __func__,
+ mUlp, mAdapter);
+ mAdapter->setUlpProxy(mUlp);
+ }
+ };
+
+ sendMsg(new LocSetUlpProxy(mLocEngAdapter, ulp));
+}
+
+void LocEngAdapter::setUlpProxy(UlpProxyBase* ulp)
+{
+ if (ulp == mUlp) {
+ //This takes care of the case when double initalization happens
+ //and we get the same object back for UlpProxyBase . Do nothing
+ return;
+ }
+
+ LOC_LOGV("%s] %p", __func__, ulp);
+ if (NULL == ulp) {
+ LOC_LOGE("%s:%d]: ulp pointer is NULL", __func__, __LINE__);
+ ulp = new UlpProxyBase();
+ }
+
+ if (LOC_POSITION_MODE_INVALID != mUlp->mPosMode.mode) {
+ // need to send this mode and start msg to ULP
+ ulp->sendFixMode(mUlp->mPosMode);
+ }
+
+ if(mUlp->mFixSet) {
+ ulp->sendStartFix();
+ }
+
+ delete mUlp;
+ mUlp = ulp;
+}
+
+void LocInternalAdapter::reportPosition(UlpLocation &location,
+ GpsLocationExtended &locationExtended,
+ void* locationExt,
+ enum loc_sess_status status,
+ LocPosTechMask loc_technology_mask)
+{
+ sendMsg(new LocEngReportPosition(mLocEngAdapter,
+ location,
+ locationExtended,
+ locationExt,
+ status,
+ loc_technology_mask));
+}
+
+
+void LocEngAdapter::reportPosition(UlpLocation &location,
+ GpsLocationExtended &locationExtended,
+ void* locationExt,
+ enum loc_sess_status status,
+ LocPosTechMask loc_technology_mask)
+{
+ if (! mUlp->reportPosition(location,
+ locationExtended,
+ locationExt,
+ status,
+ loc_technology_mask )) {
+ mInternalAdapter->reportPosition(location,
+ locationExtended,
+ locationExt,
+ status,
+ loc_technology_mask);
+ }
+}
+
+void LocInternalAdapter::reportSv(GpsSvStatus &svStatus,
+ GpsLocationExtended &locationExtended,
+ void* svExt){
+ sendMsg(new LocEngReportSv(mLocEngAdapter, svStatus,
+ locationExtended, svExt));
+}
+
+void LocEngAdapter::reportSv(GpsSvStatus &svStatus,
+ GpsLocationExtended &locationExtended,
+ void* svExt)
+{
+
+ // We want to send SV info to ULP to help it in determining GNSS
+ // signal strength ULP will forward the SV reports to HAL without
+ // any modifications
+ if (! mUlp->reportSv(svStatus, locationExtended, svExt)) {
+ mInternalAdapter->reportSv(svStatus, locationExtended, svExt);
+ }
+}
+
+
+void LocEngAdapter::reportSvMeasurement(GnssSvMeasurementSet &svMeasurementSet)
+{
+ // We send SvMeasurementSet to AmtProxy/ULPProxy to be forwarded as necessary.
+ if (! mUlp->reportSvMeasurement(svMeasurementSet)) {
+ //Send to Internal Adapter later if needed by LA
+ }
+}
+
+void LocEngAdapter::reportSvPolynomial(GnssSvPolynomial &svPolynomial)
+{
+ // We send SvMeasurementSet to AmtProxy/ULPProxy to be forwarded as necessary.
+ if (! mUlp->reportSvPolynomial(svPolynomial)) {
+ //Send to Internal Adapter later if needed by LA
+ }
+}
+
+void LocEngAdapter::setInSession(bool inSession)
+{
+ mNavigating = inSession;
+ mLocApi->setInSession(inSession);
+ if (!mNavigating) {
+ mFixCriteria.mode = LOC_POSITION_MODE_INVALID;
+ }
+}
+
+void LocInternalAdapter::reportStatus(GpsStatusValue status)
+{
+ sendMsg(new LocEngReportStatus(mLocEngAdapter, status));
+}
+
+void LocEngAdapter::reportStatus(GpsStatusValue status)
+{
+ if (!mUlp->reportStatus(status)) {
+ mInternalAdapter->reportStatus(status);
+ }
+}
+
+inline
+void LocEngAdapter::reportNmea(const char* nmea, int length)
+{
+ sendMsg(new LocEngReportNmea(mOwner, nmea, length));
+}
+
+inline
+bool LocEngAdapter::reportXtraServer(const char* url1,
+ const char* url2,
+ const char* url3,
+ const int maxlength)
+{
+ if (mSupportsAgpsRequests) {
+ sendMsg(new LocEngReportXtraServer(mOwner, url1,
+ url2, url3, maxlength));
+ }
+ return mSupportsAgpsRequests;
+}
+
+inline
+bool LocEngAdapter::requestATL(int connHandle, AGpsType agps_type)
+{
+ if (mSupportsAgpsRequests) {
+ sendMsg(new LocEngRequestATL(mOwner,
+ connHandle, agps_type));
+ }
+ return mSupportsAgpsRequests;
+}
+
+inline
+bool LocEngAdapter::releaseATL(int connHandle)
+{
+ if (mSupportsAgpsRequests) {
+ sendMsg(new LocEngReleaseATL(mOwner, connHandle));
+ }
+ return mSupportsAgpsRequests;
+}
+
+inline
+bool LocEngAdapter::requestXtraData()
+{
+ if (mSupportsAgpsRequests) {
+ sendMsg(new LocEngRequestXtra(mOwner));
+ }
+ return mSupportsAgpsRequests;
+}
+
+inline
+bool LocEngAdapter::requestTime()
+{
+ if (mSupportsAgpsRequests) {
+ sendMsg(new LocEngRequestTime(mOwner));
+ }
+ return mSupportsAgpsRequests;
+}
+
+inline
+bool LocEngAdapter::requestNiNotify(GpsNiNotification &notif, const void* data)
+{
+ if (mSupportsAgpsRequests) {
+ notif.size = sizeof(notif);
+ notif.timeout = LOC_NI_NO_RESPONSE_TIME;
+
+ sendMsg(new LocEngRequestNi(mOwner, notif, data));
+ }
+ return mSupportsAgpsRequests;
+}
+
+inline
+bool LocEngAdapter::requestSuplES(int connHandle)
+{
+ if (mSupportsAgpsRequests)
+ sendMsg(new LocEngRequestSuplEs(mOwner, connHandle));
+ return mSupportsAgpsRequests;
+}
+
+inline
+bool LocEngAdapter::reportDataCallOpened()
+{
+ if(mSupportsAgpsRequests)
+ sendMsg(new LocEngSuplEsOpened(mOwner));
+ return mSupportsAgpsRequests;
+}
+
+inline
+bool LocEngAdapter::reportDataCallClosed()
+{
+ if(mSupportsAgpsRequests)
+ sendMsg(new LocEngSuplEsClosed(mOwner));
+ return mSupportsAgpsRequests;
+}
+
+inline
+void LocEngAdapter::handleEngineDownEvent()
+{
+ sendMsg(new LocEngDown(mOwner));
+}
+
+inline
+void LocEngAdapter::handleEngineUpEvent()
+{
+ sendMsg(new LocEngUp(mOwner));
+}
+
+enum loc_api_adapter_err LocEngAdapter::setXtraVersionCheck(int check)
+{
+ enum loc_api_adapter_err ret;
+ ENTRY_LOG();
+ enum xtra_version_check eCheck;
+ switch (check) {
+ case 0:
+ eCheck = DISABLED;
+ case 1:
+ eCheck = AUTO;
+ case 2:
+ eCheck = XTRA2;
+ case 3:
+ eCheck = XTRA3;
+ defaul:
+ eCheck = DISABLED;
+ }
+ ret = mLocApi->setXtraVersionCheck(eCheck);
+ EXIT_LOG(%d, ret);
+ return ret;
+}
diff --git a/gps/loc_api/libloc_api_50001/LocEngAdapter.h b/gps/loc_api/libloc_api_50001/LocEngAdapter.h
new file mode 100644
index 0000000..01726d2
--- /dev/null
+++ b/gps/loc_api/libloc_api_50001/LocEngAdapter.h
@@ -0,0 +1,306 @@
+/* Copyright (c) 2011-2014, 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_ENG_ADAPTER_H
+#define LOC_API_ENG_ADAPTER_H
+
+#include <ctype.h>
+#include "hardware/gps.h"
+#include <loc.h>
+#include <loc_eng_log.h>
+#include <log_util.h>
+#include <LocAdapterBase.h>
+#include <LocDualContext.h>
+#include <UlpProxyBase.h>
+#include <platform_lib_includes.h>
+
+#define MAX_URL_LEN 256
+
+using namespace loc_core;
+
+class LocEngAdapter;
+
+class LocInternalAdapter : public LocAdapterBase {
+ LocEngAdapter* mLocEngAdapter;
+public:
+ LocInternalAdapter(LocEngAdapter* adapter);
+
+ virtual void reportPosition(UlpLocation &location,
+ GpsLocationExtended &locationExtended,
+ void* locationExt,
+ enum loc_sess_status status,
+ LocPosTechMask loc_technology_mask);
+ virtual void reportSv(GpsSvStatus &svStatus,
+ GpsLocationExtended &locationExtended,
+ void* svExt);
+ virtual void reportStatus(GpsStatusValue status);
+ virtual void setPositionModeInt(LocPosMode& posMode);
+ virtual void startFixInt();
+ virtual void stopFixInt();
+ virtual void getZppInt();
+ virtual void setUlpProxy(UlpProxyBase* ulp);
+};
+
+typedef void (*loc_msg_sender)(void* loc_eng_data_p, void* msgp);
+
+class LocEngAdapter : public LocAdapterBase {
+ void* mOwner;
+ LocInternalAdapter* mInternalAdapter;
+ UlpProxyBase* mUlp;
+ LocPosMode mFixCriteria;
+ bool mNavigating;
+
+public:
+ bool mSupportsAgpsRequests;
+ bool mSupportsPositionInjection;
+
+ LocEngAdapter(LOC_API_ADAPTER_EVENT_MASK_T mask,
+ void* owner,ContextBase* context,
+ MsgTask::tCreate tCreator);
+ virtual ~LocEngAdapter();
+
+ virtual void setUlpProxy(UlpProxyBase* ulp);
+ inline void requestUlp(unsigned long capabilities) {
+ mContext->requestUlp(mInternalAdapter, capabilities);
+ }
+ inline LocInternalAdapter* getInternalAdapter() { return mInternalAdapter; }
+ inline UlpProxyBase* getUlpProxy() { return mUlp; }
+ inline void* getOwner() { return mOwner; }
+ inline bool hasAgpsExtendedCapabilities() {
+ return mContext->hasAgpsExtendedCapabilities();
+ }
+ inline bool hasCPIExtendedCapabilities() {
+ return mContext->hasCPIExtendedCapabilities();
+ }
+ inline const MsgTask* getMsgTask() { return mMsgTask; }
+
+ inline enum loc_api_adapter_err
+ startFix()
+ {
+ return mLocApi->startFix(mFixCriteria);
+ }
+ inline enum loc_api_adapter_err
+ stopFix()
+ {
+ return mLocApi->stopFix();
+ }
+ inline enum loc_api_adapter_err
+ deleteAidingData(GpsAidingData f)
+ {
+ return mLocApi->deleteAidingData(f);
+ }
+ inline enum loc_api_adapter_err
+ enableData(int enable)
+ {
+ return mLocApi->enableData(enable);
+ }
+ inline enum loc_api_adapter_err
+ setAPN(char* apn, int len)
+ {
+ return mLocApi->setAPN(apn, len);
+ }
+ inline enum loc_api_adapter_err
+ injectPosition(double latitude, double longitude, float accuracy)
+ {
+ return mLocApi->injectPosition(latitude, longitude, accuracy);
+ }
+ inline enum loc_api_adapter_err
+ setTime(GpsUtcTime time, int64_t timeReference, int uncertainty)
+ {
+ return mLocApi->setTime(time, timeReference, uncertainty);
+ }
+ inline enum loc_api_adapter_err
+ setXtraData(char* data, int length)
+ {
+ return mLocApi->setXtraData(data, length);
+ }
+ inline enum loc_api_adapter_err
+ requestXtraServer()
+ {
+ return mLocApi->requestXtraServer();
+ }
+ inline enum loc_api_adapter_err
+ atlOpenStatus(int handle, int is_succ, char* apn, AGpsBearerType bearer, AGpsType agpsType)
+ {
+ return mLocApi->atlOpenStatus(handle, is_succ, apn, bearer, agpsType);
+ }
+ inline enum loc_api_adapter_err
+ atlCloseStatus(int handle, int is_succ)
+ {
+ return mLocApi->atlCloseStatus(handle, is_succ);
+ }
+ inline enum loc_api_adapter_err
+ setPositionMode(const LocPosMode *posMode)
+ {
+ if (NULL != posMode) {
+ mFixCriteria = *posMode;
+ }
+ return mLocApi->setPositionMode(mFixCriteria);
+ }
+ inline enum loc_api_adapter_err
+ setServer(const char* url, int len)
+ {
+ return mLocApi->setServer(url, len);
+ }
+ inline enum loc_api_adapter_err
+ setServer(unsigned int ip, int port,
+ LocServerType type)
+ {
+ return mLocApi->setServer(ip, port, type);
+ }
+ inline enum loc_api_adapter_err
+ informNiResponse(GpsUserResponseType userResponse, const void* passThroughData)
+ {
+ return mLocApi->informNiResponse(userResponse, passThroughData);
+ }
+ inline enum loc_api_adapter_err
+ setSUPLVersion(uint32_t version)
+ {
+ return mLocApi->setSUPLVersion(version);
+ }
+ inline enum loc_api_adapter_err
+ setLPPConfig(uint32_t profile)
+ {
+ return mLocApi->setLPPConfig(profile);
+ }
+ inline enum loc_api_adapter_err
+ setSensorControlConfig(int sensorUsage, int sensorProvider)
+ {
+ return mLocApi->setSensorControlConfig(sensorUsage, sensorProvider);
+ }
+ inline 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)
+ {
+ return mLocApi->setSensorProperties(gyroBiasVarianceRandomWalk_valid, gyroBiasVarianceRandomWalk,
+ accelBiasVarianceRandomWalk_valid, accelBiasVarianceRandomWalk,
+ angleBiasVarianceRandomWalk_valid, angleBiasVarianceRandomWalk,
+ rateBiasVarianceRandomWalk_valid, rateBiasVarianceRandomWalk,
+ velocityBiasVarianceRandomWalk_valid, velocityBiasVarianceRandomWalk);
+ }
+ inline 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)
+ {
+ return mLocApi->setSensorPerfControlConfig(controlMode, accelSamplesPerBatch, accelBatchesPerSec,
+ gyroSamplesPerBatch, gyroBatchesPerSec,
+ accelSamplesPerBatchHigh, accelBatchesPerSecHigh,
+ gyroSamplesPerBatchHigh, gyroBatchesPerSecHigh,
+ algorithmConfig);
+ }
+ inline virtual enum loc_api_adapter_err
+ setExtPowerConfig(int isBatteryCharging)
+ {
+ return mLocApi->setExtPowerConfig(isBatteryCharging);
+ }
+ inline virtual enum loc_api_adapter_err
+ setAGLONASSProtocol(unsigned long aGlonassProtocol)
+ {
+ return mLocApi->setAGLONASSProtocol(aGlonassProtocol);
+ }
+ inline virtual int initDataServiceClient()
+ {
+ return mLocApi->initDataServiceClient();
+ }
+ inline virtual int openAndStartDataCall()
+ {
+ return mLocApi->openAndStartDataCall();
+ }
+ inline virtual void stopDataCall()
+ {
+ mLocApi->stopDataCall();
+ }
+ inline virtual void closeDataCall()
+ {
+ mLocApi->closeDataCall();
+ }
+ inline enum loc_api_adapter_err
+ getZpp(GpsLocation &zppLoc, LocPosTechMask &tech_mask)
+ {
+ return mLocApi->getZppFix(zppLoc, tech_mask);
+ }
+ enum loc_api_adapter_err setXtraVersionCheck(int check);
+ virtual void handleEngineDownEvent();
+ virtual void handleEngineUpEvent();
+ virtual void reportPosition(UlpLocation &location,
+ GpsLocationExtended &locationExtended,
+ void* locationExt,
+ enum loc_sess_status status,
+ LocPosTechMask loc_technology_mask);
+ virtual void reportSv(GpsSvStatus &svStatus,
+ GpsLocationExtended &locationExtended,
+ void* svExt);
+ virtual void reportSvMeasurement(GnssSvMeasurementSet &svMeasurementSet);
+ virtual void reportSvPolynomial(GnssSvPolynomial &svPolynomial);
+ virtual void reportStatus(GpsStatusValue status);
+ virtual void reportNmea(const char* nmea, int length);
+ virtual bool reportXtraServer(const char* url1, const char* url2,
+ const char* url3, const int maxlength);
+ virtual bool requestXtraData();
+ virtual bool requestTime();
+ virtual bool requestATL(int connHandle, AGpsType agps_type);
+ virtual bool releaseATL(int connHandle);
+ virtual bool requestNiNotify(GpsNiNotification &notify, const void* data);
+ virtual bool requestSuplES(int connHandle);
+ virtual bool reportDataCallOpened();
+ virtual bool reportDataCallClosed();
+
+ inline const LocPosMode& getPositionMode() const
+ {return mFixCriteria;}
+ inline virtual bool isInSession()
+ { return mNavigating; }
+ void setInSession(bool inSession);
+
+ /*Values for lock
+ 1 = Do not lock any position sessions
+ 2 = Lock MI position sessions
+ 3 = Lock MT position sessions
+ 4 = Lock all position sessions
+ */
+ inline int setGpsLock(unsigned int lock)
+ {
+ return mLocApi->setGpsLock(lock);
+ }
+ /*
+ Returns
+ Current value of GPS lock on success
+ -1 on failure
+ */
+ inline int getGpsLock()
+ {
+ return mLocApi->getGpsLock();
+ }
+
+};
+
+#endif //LOC_API_ENG_ADAPTER_H
diff --git a/gps/loc_api/libloc_api_50001/Makefile.am b/gps/loc_api/libloc_api_50001/Makefile.am
new file mode 100644
index 0000000..2374357
--- /dev/null
+++ b/gps/loc_api/libloc_api_50001/Makefile.am
@@ -0,0 +1,76 @@
+AM_CFLAGS = \
+ -I../../utils \
+ -I../../platform_lib_abstractions \
+ -fno-short-enums \
+ -DFEATURE_GNSS_BIT_API
+
+libloc_adapter_so_la_SOURCES = loc_eng_log.cpp LocEngAdapter.cpp
+
+if USE_GLIB
+libloc_adapter_so_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@
+libloc_adapter_so_la_LDFLAGS = -lstdc++ -lpthread @GLIB_LIBS@ -shared -version-info 1:0:0
+libloc_adapter_so_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@
+else
+libloc_adapter_so_la_CFLAGS = $(AM_CFLAGS)
+libloc_adapter_so_la_LDFLAGS = -lpthread -shared -version-info 1:0:0
+libloc_adapter_so_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS)
+endif
+libloc_adapter_so_la_LIBADD = -lstdc++ -lcutils ../../utils/libgps_utils_so.la
+
+
+libloc_eng_so_la_SOURCES = \
+ loc_eng.cpp \
+ loc_eng_agps.cpp \
+ loc_eng_xtra.cpp \
+ loc_eng_ni.cpp \
+ loc_eng_log.cpp \
+ loc_eng_dmn_conn.cpp \
+ loc_eng_dmn_conn_handler.cpp \
+ loc_eng_dmn_conn_thread_helper.c \
+ loc_eng_dmn_conn_glue_msg.c \
+ loc_eng_dmn_conn_glue_pipe.c
+
+
+if USE_GLIB
+libloc_eng_so_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@
+libloc_eng_so_la_LDFLAGS = -lstdc++ -lpthread @GLIB_LIBS@ -shared -version-info 1:0:0
+libloc_eng_so_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@
+else
+libloc_eng_so_la_CFLAGS = $(AM_CFLAGS)
+libloc_eng_so_la_LDFLAGS = -lpthread -shared -version-info 1:0:0
+libloc_eng_so_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS)
+endif
+
+libloc_eng_so_la_LIBADD = -lstdc++ -lcutils -ldl ../../utils/libgps_utils_so.la libloc_adapter_so.la
+
+
+libgps_default_so_la_SOURCES = \
+ loc.cpp \
+ gps.c
+
+if USE_GLIB
+libgps_default_so_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@
+libgps_default_so_la_LDFLAGS = -lstdc++ -lpthread @GLIB_LIBS@ -shared -version-info 1:0:0
+libgps_default_so_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@
+else
+libgps_default_so_la_CFLAGS = $(AM_CFLAGS)
+libgps_default_so_la_LDFLAGS = -lpthread -shared -version-info 1:0:0
+libgps_default_so_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS)
+endif
+
+libgps_default_so_la_LIBADD = -lstdc++ -lcutils ../../utils/libgps_utils_so.la -ldl libloc_eng_so.la
+
+library_include_HEADERS = \
+ LocEngAdapter.h \
+ loc.h \
+ loc_eng.h \
+ loc_eng_xtra.h \
+ loc_eng_ni.h \
+ loc_eng_agps.h \
+ loc_eng_msg.h \
+ loc_eng_log.h
+
+library_includedir = $(pkgincludedir)/libloc_api_50001
+
+#Create and Install libraries
+lib_LTLIBRARIES = libloc_adapter_so.la libloc_eng_so.la libgps_default_so.la
diff --git a/gps/loc_api/libloc_api_50001/gps.c b/gps/loc_api/libloc_api_50001/gps.c
new file mode 100644
index 0000000..87aca3d
--- /dev/null
+++ b/gps/loc_api/libloc_api_50001/gps.c
@@ -0,0 +1,72 @@
+/* Copyright (c) 2011 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 "hardware/gps.h"
+
+#include <stdlib.h>
+
+extern const GpsInterface* get_gps_interface();
+
+const GpsInterface* gps__get_gps_interface(struct gps_device_t* dev)
+{
+ return get_gps_interface();
+}
+
+static int open_gps(const struct hw_module_t* module, char const* name,
+ struct hw_device_t** device)
+{
+ struct gps_device_t *dev = (struct gps_device_t *) malloc(sizeof(struct gps_device_t));
+
+ if(dev == NULL)
+ return -1;
+
+ memset(dev, 0, sizeof(*dev));
+
+ dev->common.tag = HARDWARE_DEVICE_TAG;
+ dev->common.version = 0;
+ dev->common.module = (struct hw_module_t*)module;
+ dev->get_gps_interface = gps__get_gps_interface;
+
+ *device = (struct hw_device_t*)dev;
+ return 0;
+}
+
+static struct hw_module_methods_t gps_module_methods = {
+ .open = open_gps
+};
+
+struct hw_module_t HAL_MODULE_INFO_SYM = {
+ .tag = HARDWARE_MODULE_TAG,
+ .module_api_version = 1,
+ .hal_api_version = 0,
+ .id = GPS_HARDWARE_MODULE_ID,
+ .name = "loc_api GPS Module",
+ .author = "Qualcomm USA, Inc.",
+ .methods = &gps_module_methods,
+};
diff --git a/gps/loc_api/libloc_api_50001/loc.cpp b/gps/loc_api/libloc_api_50001/loc.cpp
new file mode 100644
index 0000000..3708eb2
--- /dev/null
+++ b/gps/loc_api/libloc_api_50001/loc.cpp
@@ -0,0 +1,900 @@
+/* Copyright (c) 2011-2013, 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_afw"
+
+#include "hardware/gps.h"
+#include <gps_extended.h>
+#include <loc_eng.h>
+#include <loc_target.h>
+#include <loc_log.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <LocDualContext.h>
+#include <cutils/properties.h>
+
+using namespace loc_core;
+
+//Globals defns
+static gps_location_callback gps_loc_cb = NULL;
+static gps_sv_status_callback gps_sv_cb = NULL;
+
+static void local_loc_cb(UlpLocation* location, void* locExt);
+static void local_sv_cb(GpsSvStatus* sv_status, void* svExt);
+
+static const GpsGeofencingInterface* get_geofence_interface(void);
+
+// Function declarations for sLocEngInterface
+static int loc_init(GpsCallbacks* callbacks);
+static int loc_start();
+static int loc_stop();
+static void loc_cleanup();
+static int loc_inject_time(GpsUtcTime time, int64_t timeReference, int uncertainty);
+static int loc_inject_location(double latitude, double longitude, float accuracy);
+static void loc_delete_aiding_data(GpsAidingData f);
+static int loc_set_position_mode(GpsPositionMode mode, GpsPositionRecurrence recurrence,
+ uint32_t min_interval, uint32_t preferred_accuracy,
+ uint32_t preferred_time);
+static const void* loc_get_extension(const char* name);
+
+// Defines the GpsInterface in gps.h
+static const GpsInterface sLocEngInterface =
+{
+ sizeof(GpsInterface),
+ loc_init,
+ loc_start,
+ loc_stop,
+ loc_cleanup,
+ loc_inject_time,
+ loc_inject_location,
+ loc_delete_aiding_data,
+ loc_set_position_mode,
+ loc_get_extension
+};
+
+// Function declarations for sLocEngAGpsInterface
+static void loc_agps_init(AGpsCallbacks* callbacks);
+static int loc_agps_open(const char* apn);
+static int loc_agps_closed();
+static int loc_agps_open_failed();
+static int loc_agps_set_server(AGpsType type, const char *hostname, int port);
+
+static const AGpsInterface sLocEngAGpsInterface =
+{
+ sizeof(AGpsInterface),
+ loc_agps_init,
+ loc_agps_open,
+ loc_agps_closed,
+ loc_agps_open_failed,
+ loc_agps_set_server
+};
+
+static int loc_xtra_init(GpsXtraCallbacks* callbacks);
+static int loc_xtra_inject_data(char* data, int length);
+
+static const GpsXtraInterface sLocEngXTRAInterface =
+{
+ sizeof(GpsXtraInterface),
+ loc_xtra_init,
+ loc_xtra_inject_data
+};
+
+static void loc_ni_init(GpsNiCallbacks *callbacks);
+static void loc_ni_respond(int notif_id, GpsUserResponseType user_response);
+
+const GpsNiInterface sLocEngNiInterface =
+{
+ sizeof(GpsNiInterface),
+ loc_ni_init,
+ loc_ni_respond,
+};
+
+static void loc_agps_ril_init( AGpsRilCallbacks* callbacks );
+static void loc_agps_ril_set_ref_location(const AGpsRefLocation *agps_reflocation, size_t sz_struct);
+static void loc_agps_ril_set_set_id(AGpsSetIDType type, const char* setid);
+static void loc_agps_ril_ni_message(uint8_t *msg, size_t len);
+static void loc_agps_ril_update_network_state(int connected, int type, int roaming, const char* extra_info);
+static void loc_agps_ril_update_network_availability(int avaiable, const char* apn);
+
+static const AGpsRilInterface sLocEngAGpsRilInterface =
+{
+ sizeof(AGpsRilInterface),
+ loc_agps_ril_init,
+ loc_agps_ril_set_ref_location,
+ loc_agps_ril_set_set_id,
+ loc_agps_ril_ni_message,
+ loc_agps_ril_update_network_state,
+ loc_agps_ril_update_network_availability
+};
+
+static loc_eng_data_s_type loc_afw_data;
+static int gss_fd = -1;
+
+/*===========================================================================
+FUNCTION gps_get_hardware_interface
+
+DESCRIPTION
+ Returns the GPS hardware interaface based on LOC API
+ if GPS is enabled.
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0: success
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+const GpsInterface* gps_get_hardware_interface ()
+{
+ ENTRY_LOG_CALLFLOW();
+ const GpsInterface* ret_val;
+
+ char propBuf[PROPERTY_VALUE_MAX];
+
+ loc_eng_read_config();
+
+ // check to see if GPS should be disabled
+ property_get("gps.disable", propBuf, "");
+ if (propBuf[0] == '1')
+ {
+ LOC_LOGD("gps_get_interface returning NULL because gps.disable=1\n");
+ ret_val = NULL;
+ } else {
+ ret_val = &sLocEngInterface;
+ }
+
+ loc_eng_read_config();
+
+ EXIT_LOG(%p, ret_val);
+ return ret_val;
+}
+
+// for gps.c
+extern "C" const GpsInterface* get_gps_interface()
+{
+ unsigned int target = TARGET_DEFAULT;
+ loc_eng_read_config();
+
+ target = loc_get_target();
+ LOC_LOGD("Target name check returned %s", loc_get_target_name(target));
+
+ int gnssType = getTargetGnssType(target);
+ switch (gnssType)
+ {
+ case GNSS_GSS:
+ case GNSS_AUTO:
+ //APQ8064
+ gps_conf.CAPABILITIES &= ~(GPS_CAPABILITY_MSA | GPS_CAPABILITY_MSB);
+ gss_fd = open("/dev/gss", O_RDONLY);
+ if (gss_fd < 0) {
+ LOC_LOGE("GSS open failed: %s\n", strerror(errno));
+ }
+ else {
+ LOC_LOGD("GSS open success! CAPABILITIES %0lx\n",
+ gps_conf.CAPABILITIES);
+ }
+ break;
+ case GNSS_NONE:
+ //MPQ8064
+ LOC_LOGE("No GPS HW on this target. Not returning interface.");
+ return NULL;
+ case GNSS_QCA1530:
+ // qca1530 chip is present
+ gps_conf.CAPABILITIES &= ~(GPS_CAPABILITY_MSA | GPS_CAPABILITY_MSB);
+ LOC_LOGD("qca1530 present: CAPABILITIES %0lx\n", gps_conf.CAPABILITIES);
+ break;
+ }
+ return &sLocEngInterface;
+}
+
+/*===========================================================================
+FUNCTION loc_init
+
+DESCRIPTION
+ Initialize the location engine, this include setting up global datas
+ and registers location engien with loc api service.
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0: success
+
+SIDE EFFECTS
+ N/Ax
+
+===========================================================================*/
+static int loc_init(GpsCallbacks* callbacks)
+{
+ int retVal = -1;
+ unsigned int target = (unsigned int) -1;
+ LOC_API_ADAPTER_EVENT_MASK_T event;
+ ENTRY_LOG();
+
+ if (NULL == callbacks) {
+ LOC_LOGE("loc_init failed. cb = NULL\n");
+ EXIT_LOG(%d, retVal);
+ return retVal;
+ }
+
+ event = LOC_API_ADAPTER_BIT_PARSED_POSITION_REPORT |
+ LOC_API_ADAPTER_BIT_SATELLITE_REPORT |
+ LOC_API_ADAPTER_BIT_LOCATION_SERVER_REQUEST |
+ LOC_API_ADAPTER_BIT_ASSISTANCE_DATA_REQUEST |
+ LOC_API_ADAPTER_BIT_IOCTL_REPORT |
+ LOC_API_ADAPTER_BIT_STATUS_REPORT |
+ LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT |
+ LOC_API_ADAPTER_BIT_NI_NOTIFY_VERIFY_REQUEST;
+
+ target = loc_get_target();
+
+ /*For "auto" platform enable Measurement report and SV Polynomial report*/
+ if(GNSS_AUTO == getTargetGnssType(target))
+ {
+ event |= LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT_REPORT |
+ LOC_API_ADAPTER_BIT_GNSS_SV_POLYNOMIAL_REPORT;
+ }
+
+ LocCallbacks clientCallbacks = {local_loc_cb, /* location_cb */
+ callbacks->status_cb, /* status_cb */
+ local_sv_cb, /* sv_status_cb */
+ callbacks->nmea_cb, /* nmea_cb */
+ callbacks->set_capabilities_cb, /* set_capabilities_cb */
+ callbacks->acquire_wakelock_cb, /* acquire_wakelock_cb */
+ callbacks->release_wakelock_cb, /* release_wakelock_cb */
+ callbacks->create_thread_cb, /* create_thread_cb */
+ NULL, /* location_ext_parser */
+ NULL, /* sv_ext_parser */
+ callbacks->request_utc_time_cb /* request_utc_time_cb */};
+
+ gps_loc_cb = callbacks->location_cb;
+ gps_sv_cb = callbacks->sv_status_cb;
+
+ retVal = loc_eng_init(loc_afw_data, &clientCallbacks, event, NULL);
+ loc_afw_data.adapter->requestUlp(gps_conf.CAPABILITIES);
+ loc_afw_data.adapter->mSupportsAgpsRequests = !loc_afw_data.adapter->hasAgpsExtendedCapabilities();
+ loc_afw_data.adapter->mSupportsPositionInjection = !loc_afw_data.adapter->hasCPIExtendedCapabilities();
+
+ EXIT_LOG(%d, retVal);
+ return retVal;
+}
+
+/*===========================================================================
+FUNCTION loc_cleanup
+
+DESCRIPTION
+ Cleans location engine. The location client handle will be released.
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ None
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static void loc_cleanup()
+{
+ ENTRY_LOG();
+ loc_eng_cleanup(loc_afw_data);
+ gps_loc_cb = NULL;
+ gps_sv_cb = NULL;
+
+/*
+ if (gss_fd >= 0)
+ {
+ close(gss_fd);
+ gss_fd = -1;
+ LOC_LOGD("GSS shutdown.\n");
+ }
+*/
+
+ EXIT_LOG(%s, VOID_RET);
+}
+
+/*===========================================================================
+FUNCTION loc_start
+
+DESCRIPTION
+ Starts the tracking session
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0: success
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static int loc_start()
+{
+ ENTRY_LOG();
+ int ret_val = loc_eng_start(loc_afw_data);
+
+ EXIT_LOG(%d, ret_val);
+ return ret_val;
+}
+
+/*===========================================================================
+FUNCTION loc_stop
+
+DESCRIPTION
+ Stops the tracking session
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0: success
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static int loc_stop()
+{
+ ENTRY_LOG();
+ int ret_val = -1;
+ ret_val = loc_eng_stop(loc_afw_data);
+
+ EXIT_LOG(%d, ret_val);
+ return ret_val;
+}
+
+/*===========================================================================
+FUNCTION loc_set_position_mode
+
+DESCRIPTION
+ Sets the mode and fix frequency for the tracking session.
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0: success
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static int loc_set_position_mode(GpsPositionMode mode,
+ GpsPositionRecurrence recurrence,
+ uint32_t min_interval,
+ uint32_t preferred_accuracy,
+ uint32_t preferred_time)
+{
+ ENTRY_LOG();
+ int ret_val = -1;
+ LocPositionMode locMode;
+ switch (mode) {
+ case GPS_POSITION_MODE_MS_BASED:
+ locMode = LOC_POSITION_MODE_MS_BASED;
+ break;
+ case GPS_POSITION_MODE_MS_ASSISTED:
+ locMode = LOC_POSITION_MODE_MS_ASSISTED;
+ break;
+ default:
+ locMode = LOC_POSITION_MODE_STANDALONE;
+ break;
+ }
+
+ LocPosMode params(locMode, recurrence, min_interval,
+ preferred_accuracy, preferred_time, NULL, NULL);
+ ret_val = loc_eng_set_position_mode(loc_afw_data, params);
+
+ EXIT_LOG(%d, ret_val);
+ return ret_val;
+}
+
+/*===========================================================================
+FUNCTION loc_inject_time
+
+DESCRIPTION
+ This is used by Java native function to do time injection.
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static int loc_inject_time(GpsUtcTime time, int64_t timeReference, int uncertainty)
+{
+ ENTRY_LOG();
+ int ret_val = 0;
+
+ ret_val = loc_eng_inject_time(loc_afw_data, time,
+ timeReference, uncertainty);
+
+ EXIT_LOG(%d, ret_val);
+ return ret_val;
+}
+
+
+/*===========================================================================
+FUNCTION loc_inject_location
+
+DESCRIPTION
+ This is used by Java native function to do location injection.
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0 : Successful
+ error code : Failure
+
+SIDE EFFECTS
+ N/A
+===========================================================================*/
+static int loc_inject_location(double latitude, double longitude, float accuracy)
+{
+ ENTRY_LOG();
+
+ int ret_val = 0;
+ ret_val = loc_eng_inject_location(loc_afw_data, latitude, longitude, accuracy);
+
+ EXIT_LOG(%d, ret_val);
+ return ret_val;
+}
+
+
+/*===========================================================================
+FUNCTION loc_delete_aiding_data
+
+DESCRIPTION
+ This is used by Java native function to delete the aiding data. The function
+ updates the global variable for the aiding data to be deleted. If the GPS
+ engine is off, the aiding data will be deleted. Otherwise, the actual action
+ will happen when gps engine is turned off.
+
+DEPENDENCIES
+ Assumes the aiding data type specified in GpsAidingData matches with
+ LOC API specification.
+
+RETURN VALUE
+ None
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static void loc_delete_aiding_data(GpsAidingData f)
+{
+ ENTRY_LOG();
+ loc_eng_delete_aiding_data(loc_afw_data, f);
+
+ EXIT_LOG(%s, VOID_RET);
+}
+
+const GpsGeofencingInterface* get_geofence_interface(void)
+{
+ ENTRY_LOG();
+ void *handle;
+ const char *error;
+ typedef const GpsGeofencingInterface* (*get_gps_geofence_interface_function) (void);
+ get_gps_geofence_interface_function get_gps_geofence_interface;
+ static const GpsGeofencingInterface* geofence_interface = NULL;
+
+ dlerror(); /* Clear any existing error */
+
+ handle = dlopen ("libgeofence.so", RTLD_NOW);
+
+ if (!handle)
+ {
+ if ((error = dlerror()) != NULL) {
+ LOC_LOGE ("%s, dlopen for libgeofence.so failed, error = %s\n", __func__, error);
+ }
+ goto exit;
+ }
+ dlerror(); /* Clear any existing error */
+ get_gps_geofence_interface = (get_gps_geofence_interface_function)dlsym(handle, "gps_geofence_get_interface");
+ if ((error = dlerror()) != NULL && NULL != get_gps_geofence_interface) {
+ LOC_LOGE ("%s, dlsym for get_gps_geofence_interface failed, error = %s\n", __func__, error);
+ goto exit;
+ }
+
+ geofence_interface = get_gps_geofence_interface();
+
+exit:
+ EXIT_LOG(%d, geofence_interface == NULL);
+ return geofence_interface;
+}
+/*===========================================================================
+FUNCTION loc_get_extension
+
+DESCRIPTION
+ Get the gps extension to support XTRA.
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ The GPS extension interface.
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+const void* loc_get_extension(const char* name)
+{
+ ENTRY_LOG();
+ const void* ret_val = NULL;
+
+ LOC_LOGD("%s:%d] For Interface = %s\n",__func__, __LINE__, name);
+ if (strcmp(name, GPS_XTRA_INTERFACE) == 0)
+ {
+ ret_val = &sLocEngXTRAInterface;
+ }
+ else if (strcmp(name, AGPS_INTERFACE) == 0)
+ {
+ ret_val = &sLocEngAGpsInterface;
+ }
+ else if (strcmp(name, GPS_NI_INTERFACE) == 0)
+ {
+ ret_val = &sLocEngNiInterface;
+ }
+ else if (strcmp(name, AGPS_RIL_INTERFACE) == 0)
+ {
+ char baseband[PROPERTY_VALUE_MAX];
+ property_get("ro.baseband", baseband, "msm");
+ if (strcmp(baseband, "csfb") == 0)
+ {
+ ret_val = &sLocEngAGpsRilInterface;
+ }
+ }
+ else if (strcmp(name, GPS_GEOFENCING_INTERFACE) == 0)
+ {
+ if ((gps_conf.CAPABILITIES | GPS_CAPABILITY_GEOFENCING) == gps_conf.CAPABILITIES ){
+ ret_val = get_geofence_interface();
+ }
+ }
+ else
+ {
+ LOC_LOGE ("get_extension: Invalid interface passed in\n");
+ }
+ EXIT_LOG(%p, ret_val);
+ return ret_val;
+}
+
+/*===========================================================================
+FUNCTION loc_agps_init
+
+DESCRIPTION
+ Initialize the AGps interface.
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ 0
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static void loc_agps_init(AGpsCallbacks* callbacks)
+{
+ ENTRY_LOG();
+ loc_eng_agps_init(loc_afw_data, (AGpsExtCallbacks*)callbacks);
+ EXIT_LOG(%s, VOID_RET);
+}
+
+/*===========================================================================
+FUNCTION loc_agps_open
+
+DESCRIPTION
+ This function is called when on-demand data connection opening is successful.
+It should inform ARM 9 about the data open result.
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ 0
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static int loc_agps_open(const char* apn)
+{
+ ENTRY_LOG();
+ AGpsType agpsType = AGPS_TYPE_SUPL;
+ AGpsBearerType bearerType = AGPS_APN_BEARER_IPV4;
+ int ret_val = loc_eng_agps_open(loc_afw_data, agpsType, apn, bearerType);
+
+ EXIT_LOG(%d, ret_val);
+ return ret_val;
+}
+
+/*===========================================================================
+FUNCTION loc_agps_closed
+
+DESCRIPTION
+ This function is called when on-demand data connection closing is done.
+It should inform ARM 9 about the data close result.
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ 0
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static int loc_agps_closed()
+{
+ ENTRY_LOG();
+ AGpsType agpsType = AGPS_TYPE_SUPL;
+ int ret_val = loc_eng_agps_closed(loc_afw_data, agpsType);
+
+ EXIT_LOG(%d, ret_val);
+ return ret_val;
+}
+
+/*===========================================================================
+FUNCTION loc_agps_open_failed
+
+DESCRIPTION
+ This function is called when on-demand data connection opening has failed.
+It should inform ARM 9 about the data open result.
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ 0
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_agps_open_failed()
+{
+ ENTRY_LOG();
+ AGpsType agpsType = AGPS_TYPE_SUPL;
+ int ret_val = loc_eng_agps_open_failed(loc_afw_data, agpsType);
+
+ EXIT_LOG(%d, ret_val);
+ return ret_val;
+}
+
+/*===========================================================================
+FUNCTION loc_agps_set_server
+
+DESCRIPTION
+ If loc_eng_set_server is called before loc_eng_init, it doesn't work. This
+ proxy buffers server settings and calls loc_eng_set_server when the client is
+ open.
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ 0
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static int loc_agps_set_server(AGpsType type, const char* hostname, int port)
+{
+ ENTRY_LOG();
+ LocServerType serverType;
+ switch (type) {
+ case AGPS_TYPE_SUPL:
+ serverType = LOC_AGPS_SUPL_SERVER;
+ break;
+ case AGPS_TYPE_C2K:
+ serverType = LOC_AGPS_CDMA_PDE_SERVER;
+ break;
+ default:
+ serverType = LOC_AGPS_SUPL_SERVER;
+ }
+ int ret_val = loc_eng_set_server_proxy(loc_afw_data, serverType, hostname, port);
+
+ EXIT_LOG(%d, ret_val);
+ return ret_val;
+}
+
+/*===========================================================================
+FUNCTIONf571
+ loc_xtra_init
+
+DESCRIPTION
+ Initialize XTRA module.
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0: success
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static int loc_xtra_init(GpsXtraCallbacks* callbacks)
+{
+ ENTRY_LOG();
+ int ret_val = loc_eng_xtra_init(loc_afw_data, (GpsXtraExtCallbacks*)callbacks);
+
+ EXIT_LOG(%d, ret_val);
+ return ret_val;
+}
+
+
+/*===========================================================================
+FUNCTION loc_xtra_inject_data
+
+DESCRIPTION
+ Initialize XTRA module.
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0: success
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static int loc_xtra_inject_data(char* data, int length)
+{
+ ENTRY_LOG();
+ int ret_val = -1;
+ if( (data != NULL) && ((unsigned int)length <= XTRA_DATA_MAX_SIZE))
+ ret_val = loc_eng_xtra_inject_data(loc_afw_data, data, length);
+ else
+ LOC_LOGE("%s, Could not inject XTRA data. Buffer address: %p, length: %d",
+ __func__, data, length);
+ EXIT_LOG(%d, ret_val);
+ return ret_val;
+}
+
+/*===========================================================================
+FUNCTION loc_ni_init
+
+DESCRIPTION
+ This function initializes the NI interface
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ None
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+void loc_ni_init(GpsNiCallbacks *callbacks)
+{
+ ENTRY_LOG();
+ loc_eng_ni_init(loc_afw_data,(GpsNiExtCallbacks*) callbacks);
+ EXIT_LOG(%s, VOID_RET);
+}
+
+/*===========================================================================
+FUNCTION loc_ni_respond
+
+DESCRIPTION
+ This function sends an NI respond to the modem processor
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ None
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+void loc_ni_respond(int notif_id, GpsUserResponseType user_response)
+{
+ ENTRY_LOG();
+ loc_eng_ni_respond(loc_afw_data, notif_id, user_response);
+ EXIT_LOG(%s, VOID_RET);
+}
+
+// Below stub functions are members of sLocEngAGpsRilInterface
+static void loc_agps_ril_init( AGpsRilCallbacks* callbacks ) {}
+static void loc_agps_ril_set_ref_location(const AGpsRefLocation *agps_reflocation, size_t sz_struct) {}
+static void loc_agps_ril_set_set_id(AGpsSetIDType type, const char* setid) {}
+static void loc_agps_ril_ni_message(uint8_t *msg, size_t len) {}
+static void loc_agps_ril_update_network_state(int connected, int type, int roaming, const char* extra_info) {}
+
+/*===========================================================================
+FUNCTION loc_agps_ril_update_network_availability
+
+DESCRIPTION
+ Sets data call allow vs disallow flag to modem
+ This is the only member of sLocEngAGpsRilInterface implemented.
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0: success
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static void loc_agps_ril_update_network_availability(int available, const char* apn)
+{
+ ENTRY_LOG();
+ loc_eng_agps_ril_update_network_availability(loc_afw_data, available, apn);
+ EXIT_LOG(%s, VOID_RET);
+}
+
+static void local_loc_cb(UlpLocation* location, void* locExt)
+{
+ ENTRY_LOG();
+ if (NULL != location) {
+ CALLBACK_LOG_CALLFLOW("location_cb - from", %d, location->position_source);
+
+ if (NULL != gps_loc_cb) {
+ gps_loc_cb(&location->gpsLocation);
+ }
+ }
+ EXIT_LOG(%s, VOID_RET);
+}
+
+static void local_sv_cb(GpsSvStatus* sv_status, void* svExt)
+{
+ ENTRY_LOG();
+ if (NULL != gps_sv_cb) {
+ CALLBACK_LOG_CALLFLOW("sv_status_cb -", %d, sv_status->num_svs);
+ gps_sv_cb(sv_status);
+ }
+ EXIT_LOG(%s, VOID_RET);
+}
diff --git a/gps/loc_api/libloc_api_50001/loc.h b/gps/loc_api/libloc_api_50001/loc.h
new file mode 100644
index 0000000..c29d005
--- /dev/null
+++ b/gps/loc_api/libloc_api_50001/loc.h
@@ -0,0 +1,66 @@
+/* Copyright (c) 2011-2013, 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_H__
+#define __LOC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <ctype.h>
+#include <cutils/properties.h>
+#include "hardware/gps.h"
+#include <gps_extended.h>
+
+#define XTRA_DATA_MAX_SIZE 100000 /*bytes*/
+
+typedef void (*loc_location_cb_ext) (UlpLocation* location, void* locExt);
+typedef void (*loc_sv_status_cb_ext) (GpsSvStatus* sv_status, void* svExt);
+typedef void* (*loc_ext_parser)(void* data);
+
+typedef struct {
+ loc_location_cb_ext location_cb;
+ gps_status_callback status_cb;
+ loc_sv_status_cb_ext sv_status_cb;
+ gps_nmea_callback nmea_cb;
+ gps_set_capabilities set_capabilities_cb;
+ gps_acquire_wakelock acquire_wakelock_cb;
+ gps_release_wakelock release_wakelock_cb;
+ gps_create_thread create_thread_cb;
+ loc_ext_parser location_ext_parser;
+ loc_ext_parser sv_ext_parser;
+ gps_request_utc_time request_utc_time_cb;
+} LocCallbacks;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif //__LOC_H__
diff --git a/gps/loc_api/libloc_api_50001/loc_eng.cpp b/gps/loc_api/libloc_api_50001/loc_eng.cpp
new file mode 100644
index 0000000..cb3dcc6
--- /dev/null
+++ b/gps/loc_api/libloc_api_50001/loc_eng.cpp
@@ -0,0 +1,2634 @@
+/* Copyright (c) 2009-2014, 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_eng"
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <dlfcn.h>
+#include <ctype.h>
+#include <math.h>
+#include <pthread.h>
+#include <arpa/inet.h>
+#include <netinet/in.h> /* struct sockaddr_in */
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netdb.h>
+#include <time.h>
+#include <new>
+#include <LocEngAdapter.h>
+
+#include <cutils/sched_policy.h>
+#ifndef USE_GLIB
+#include <utils/SystemClock.h>
+#include <utils/Log.h>
+#endif /* USE_GLIB */
+
+#ifdef USE_GLIB
+#include <glib.h>
+#include <sys/syscall.h>
+#endif /* USE_GLIB */
+
+#include <string.h>
+
+#include <loc_eng.h>
+#include <loc_eng_ni.h>
+#include <loc_eng_dmn_conn.h>
+#include <loc_eng_dmn_conn_handler.h>
+#include <loc_eng_msg.h>
+#include <loc_eng_nmea.h>
+#include <msg_q.h>
+#include <loc.h>
+#include "log_util.h"
+#include "platform_lib_includes.h"
+#include "loc_core_log.h"
+#include "loc_eng_log.h"
+
+#define SUCCESS TRUE
+#define FAILURE FALSE
+
+#ifndef GPS_CONF_FILE
+#define GPS_CONF_FILE "/etc/gps.conf" //??? platform independent
+#endif
+
+#ifndef SAP_CONF_FILE
+#define SAP_CONF_FILE "/etc/sap.conf"
+#endif
+
+#define XTRA1_GPSONEXTRA "xtra1.gpsonextra.net"
+
+using namespace loc_core;
+
+boolean configAlreadyRead = false;
+unsigned int agpsStatus = 0;
+loc_gps_cfg_s_type gps_conf;
+loc_sap_cfg_s_type sap_conf;
+
+/* Parameter spec table */
+static loc_param_s_type loc_parameter_table[] =
+{
+ {"INTERMEDIATE_POS", &gps_conf.INTERMEDIATE_POS, NULL, 'n'},
+ {"ACCURACY_THRES", &gps_conf.ACCURACY_THRES, NULL, 'n'},
+ {"NMEA_PROVIDER", &gps_conf.NMEA_PROVIDER, NULL, 'n'},
+ {"SUPL_VER", &gps_conf.SUPL_VER, NULL, 'n'},
+ {"CAPABILITIES", &gps_conf.CAPABILITIES, NULL, 'n'},
+ {"GYRO_BIAS_RANDOM_WALK", &sap_conf.GYRO_BIAS_RANDOM_WALK, &sap_conf.GYRO_BIAS_RANDOM_WALK_VALID, 'f'},
+ {"ACCEL_RANDOM_WALK_SPECTRAL_DENSITY", &sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY, &sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'},
+ {"ANGLE_RANDOM_WALK_SPECTRAL_DENSITY", &sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY, &sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'},
+ {"RATE_RANDOM_WALK_SPECTRAL_DENSITY", &sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY, &sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'},
+ {"VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY", &sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY, &sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'},
+ {"SENSOR_ACCEL_BATCHES_PER_SEC", &sap_conf.SENSOR_ACCEL_BATCHES_PER_SEC, NULL, 'n'},
+ {"SENSOR_ACCEL_SAMPLES_PER_BATCH", &sap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH, NULL, 'n'},
+ {"SENSOR_GYRO_BATCHES_PER_SEC", &sap_conf.SENSOR_GYRO_BATCHES_PER_SEC, NULL, 'n'},
+ {"SENSOR_GYRO_SAMPLES_PER_BATCH", &sap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH, NULL, 'n'},
+ {"SENSOR_ACCEL_BATCHES_PER_SEC_HIGH", &sap_conf.SENSOR_ACCEL_BATCHES_PER_SEC_HIGH, NULL, 'n'},
+ {"SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH", &sap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH, NULL, 'n'},
+ {"SENSOR_GYRO_BATCHES_PER_SEC_HIGH", &sap_conf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH, NULL, 'n'},
+ {"SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH", &sap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH, NULL, 'n'},
+ {"SENSOR_CONTROL_MODE", &sap_conf.SENSOR_CONTROL_MODE, NULL, 'n'},
+ {"SENSOR_USAGE", &sap_conf.SENSOR_USAGE, NULL, 'n'},
+ {"SENSOR_ALGORITHM_CONFIG_MASK", &sap_conf.SENSOR_ALGORITHM_CONFIG_MASK, NULL, 'n'},
+ {"QUIPC_ENABLED", &gps_conf.QUIPC_ENABLED, NULL, 'n'},
+ {"LPP_PROFILE", &gps_conf.LPP_PROFILE, NULL, 'n'},
+ {"A_GLONASS_POS_PROTOCOL_SELECT", &gps_conf.A_GLONASS_POS_PROTOCOL_SELECT, NULL, 'n'},
+ {"SENSOR_PROVIDER", &sap_conf.SENSOR_PROVIDER, NULL, 'n'},
+ {"XTRA_VERSION_CHECK", &gps_conf.XTRA_VERSION_CHECK, NULL, 'n'},
+ {"XTRA_SERVER_1", &gps_conf.XTRA_SERVER_1, NULL, 's'},
+ {"XTRA_SERVER_2", &gps_conf.XTRA_SERVER_2, NULL, 's'},
+ {"XTRA_SERVER_3", &gps_conf.XTRA_SERVER_3, NULL, 's'}
+};
+
+static void loc_default_parameters(void)
+{
+ /*Defaults for gps.conf*/
+ gps_conf.INTERMEDIATE_POS = 0;
+ gps_conf.ACCURACY_THRES = 0;
+ gps_conf.NMEA_PROVIDER = 0;
+ gps_conf.SUPL_VER = 0x10000;
+ gps_conf.CAPABILITIES = 0x7;
+ /* LTE Positioning Profile configuration is disable by default*/
+ gps_conf.LPP_PROFILE = 0;
+ /*By default no positioning protocol is selected on A-GLONASS system*/
+ gps_conf.A_GLONASS_POS_PROTOCOL_SELECT = 0;
+ /*XTRA version check is disabled by default*/
+ gps_conf.XTRA_VERSION_CHECK=0;
+
+ /*Defaults for sap.conf*/
+ sap_conf.GYRO_BIAS_RANDOM_WALK = 0;
+ sap_conf.SENSOR_ACCEL_BATCHES_PER_SEC = 2;
+ sap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH = 5;
+ sap_conf.SENSOR_GYRO_BATCHES_PER_SEC = 2;
+ sap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH = 5;
+ sap_conf.SENSOR_ACCEL_BATCHES_PER_SEC_HIGH = 4;
+ sap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH = 25;
+ sap_conf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH = 4;
+ sap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH = 25;
+ sap_conf.SENSOR_CONTROL_MODE = 0; /* AUTO */
+ sap_conf.SENSOR_USAGE = 0; /* Enabled */
+ sap_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 */
+ sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY = 0;
+ sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY = 0;
+ sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY = 0;
+ sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY = 0;
+ sap_conf.GYRO_BIAS_RANDOM_WALK_VALID = 0;
+ sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
+ sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
+ sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
+ sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
+ /* default provider is SSC */
+ sap_conf.SENSOR_PROVIDER = 1;
+}
+
+// 2nd half of init(), singled out for
+// modem restart to use.
+static int loc_eng_reinit(loc_eng_data_s_type &loc_eng_data);
+static void loc_eng_agps_reinit(loc_eng_data_s_type &loc_eng_data);
+
+static int loc_eng_set_server(loc_eng_data_s_type &loc_eng_data,
+ LocServerType type, const char *hostname, int port);
+// Internal functions
+static void loc_inform_gps_status(loc_eng_data_s_type &loc_eng_data,
+ GpsStatusValue status);
+static void loc_eng_report_status(loc_eng_data_s_type &loc_eng_data,
+ GpsStatusValue status);
+static void loc_eng_process_conn_request(loc_eng_data_s_type &loc_eng_data,
+ int connHandle, AGpsType agps_type);
+static void loc_eng_agps_close_status(loc_eng_data_s_type &loc_eng_data, int is_succ);
+static void loc_eng_handle_engine_down(loc_eng_data_s_type &loc_eng_data) ;
+static void loc_eng_handle_engine_up(loc_eng_data_s_type &loc_eng_data) ;
+
+static int loc_eng_start_handler(loc_eng_data_s_type &loc_eng_data);
+static int loc_eng_stop_handler(loc_eng_data_s_type &loc_eng_data);
+static int loc_eng_get_zpp_handler(loc_eng_data_s_type &loc_eng_data);
+
+static void deleteAidingData(loc_eng_data_s_type &logEng);
+static AgpsStateMachine*
+getAgpsStateMachine(loc_eng_data_s_type& logEng, AGpsExtType agpsType);
+static int dataCallCb(void *cb_data);
+static void update_aiding_data_for_deletion(loc_eng_data_s_type& loc_eng_data) {
+ if (loc_eng_data.engine_status != GPS_STATUS_ENGINE_ON &&
+ loc_eng_data.aiding_data_for_deletion != 0)
+ {
+ loc_eng_data.adapter->deleteAidingData(loc_eng_data.aiding_data_for_deletion);
+ loc_eng_data.aiding_data_for_deletion = 0;
+ }
+}
+
+static void* noProc(void* data)
+{
+ return NULL;
+}
+
+
+/*********************************************************************
+ * definitions of the static messages used in the file
+ *********************************************************************/
+// case LOC_ENG_MSG_REQUEST_NI:
+LocEngRequestNi::LocEngRequestNi(void* locEng,
+ GpsNiNotification &notif,
+ const void* data) :
+ LocMsg(), mLocEng(locEng), mNotify(notif), mPayload(data) {
+ locallog();
+}
+void LocEngRequestNi::proc() const {
+ loc_eng_ni_request_handler(*((loc_eng_data_s_type*)mLocEng),
+ &mNotify, mPayload);
+}
+void LocEngRequestNi::locallog() const
+{
+ LOC_LOGV("id: %d\n type: %s\n flags: %d\n time out: %d\n "
+ "default response: %s\n requestor id encoding: %s\n"
+ " text encoding: %s\n passThroughData: %p",
+ mNotify.notification_id,
+ loc_get_ni_type_name(mNotify.ni_type),
+ mNotify.notify_flags,
+ mNotify.timeout,
+ loc_get_ni_response_name(mNotify.default_response),
+ loc_get_ni_encoding_name(mNotify.requestor_id_encoding),
+ loc_get_ni_encoding_name(mNotify.text_encoding),
+ mPayload);
+}
+inline void LocEngRequestNi::log() const {
+ locallog();
+}
+
+// case LOC_ENG_MSG_INFORM_NI_RESPONSE:
+// in loc_eng_ni.cpp
+
+// case LOC_ENG_MSG_START_FIX:
+LocEngStartFix::LocEngStartFix(LocEngAdapter* adapter) :
+ LocMsg(), mAdapter(adapter)
+{
+ locallog();
+}
+inline void LocEngStartFix::proc() const
+{
+ loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mAdapter->getOwner();
+ loc_eng_start_handler(*locEng);
+}
+inline void LocEngStartFix::locallog() const
+{
+ LOC_LOGV("LocEngStartFix");
+}
+inline void LocEngStartFix::log() const
+{
+ locallog();
+}
+void LocEngStartFix::send() const {
+ mAdapter->sendMsg(this);
+}
+
+// case LOC_ENG_MSG_STOP_FIX:
+LocEngStopFix::LocEngStopFix(LocEngAdapter* adapter) :
+ LocMsg(), mAdapter(adapter)
+{
+ locallog();
+}
+inline void LocEngStopFix::proc() const
+{
+ loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mAdapter->getOwner();
+ loc_eng_stop_handler(*locEng);
+}
+inline void LocEngStopFix::locallog() const
+{
+ LOC_LOGV("LocEngStopFix");
+}
+inline void LocEngStopFix::log() const
+{
+ locallog();
+}
+void LocEngStopFix::send() const {
+ mAdapter->sendMsg(this);
+}
+
+// case LOC_ENG_MSG_SET_POSITION_MODE:
+LocEngPositionMode::LocEngPositionMode(LocEngAdapter* adapter,
+ LocPosMode &mode) :
+ LocMsg(), mAdapter(adapter), mPosMode(mode)
+{
+ mPosMode.logv();
+}
+inline void LocEngPositionMode::proc() const {
+ mAdapter->setPositionMode(&mPosMode);
+}
+inline void LocEngPositionMode::log() const {
+ mPosMode.logv();
+}
+void LocEngPositionMode::send() const {
+ mAdapter->sendMsg(this);
+}
+
+LocEngGetZpp::LocEngGetZpp(LocEngAdapter* adapter) :
+ LocMsg(), mAdapter(adapter)
+{
+ locallog();
+}
+inline void LocEngGetZpp::proc() const
+{
+ loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mAdapter->getOwner();
+ loc_eng_get_zpp_handler(*locEng);
+}
+inline void LocEngGetZpp::locallog() const
+{
+ LOC_LOGV("LocEngGetZpp");
+}
+inline void LocEngGetZpp::log() const
+{
+ locallog();
+}
+void LocEngGetZpp::send() const {
+ mAdapter->sendMsg(this);
+}
+
+// case LOC_ENG_MSG_SET_TIME:
+struct LocEngSetTime : public LocMsg {
+ LocEngAdapter* mAdapter;
+ const GpsUtcTime mTime;
+ const int64_t mTimeReference;
+ const int mUncertainty;
+ inline LocEngSetTime(LocEngAdapter* adapter,
+ GpsUtcTime t, int64_t tf, int unc) :
+ LocMsg(), mAdapter(adapter),
+ mTime(t), mTimeReference(tf), mUncertainty(unc)
+ {
+ locallog();
+ }
+ inline virtual void proc() const {
+ mAdapter->setTime(mTime, mTimeReference, mUncertainty);
+ }
+ inline void locallog() const {
+ LOC_LOGV("time: %lld\n timeReference: %lld\n uncertainty: %d",
+ mTime, mTimeReference, mUncertainty);
+ }
+ inline virtual void log() const {
+ locallog();
+ }
+};
+
+ // case LOC_ENG_MSG_INJECT_LOCATION:
+struct LocEngInjectLocation : public LocMsg {
+ LocEngAdapter* mAdapter;
+ const double mLatitude;
+ const double mLongitude;
+ const float mAccuracy;
+ inline LocEngInjectLocation(LocEngAdapter* adapter,
+ double lat, double lon, float accur) :
+ LocMsg(), mAdapter(adapter),
+ mLatitude(lat), mLongitude(lon), mAccuracy(accur)
+ {
+ locallog();
+ }
+ inline virtual void proc() const {
+ mAdapter->injectPosition(mLatitude, mLongitude, mAccuracy);
+ }
+ inline void locallog() const {
+ LOC_LOGV("latitude: %f\n longitude: %f\n accuracy: %f",
+ mLatitude, mLongitude, mAccuracy);
+ }
+ inline virtual void log() const {
+ locallog();
+ }
+};
+
+// case LOC_ENG_MSG_SET_SERVER_IPV4:
+struct LocEngSetServerIpv4 : public LocMsg {
+ LocEngAdapter* mAdapter;
+ const unsigned int mNlAddr;
+ const int mPort;
+ const LocServerType mServerType;
+ inline LocEngSetServerIpv4(LocEngAdapter* adapter,
+ unsigned int ip,
+ int port,
+ LocServerType type) :
+ LocMsg(), mAdapter(adapter),
+ mNlAddr(ip), mPort(port), mServerType(type)
+ {
+ locallog();
+ }
+ inline virtual void proc() const {
+ mAdapter->setServer(mNlAddr, mPort, mServerType);
+ }
+ inline void locallog() const {
+ LOC_LOGV("LocEngSetServerIpv4 - addr: %x, port: %d, type: %s",
+ mNlAddr, mPort, loc_get_server_type_name(mServerType));
+ }
+ inline virtual void log() const {
+ locallog();
+ }
+};
+
+// case LOC_ENG_MSG_SET_SERVER_URL:
+struct LocEngSetServerUrl : public LocMsg {
+ LocEngAdapter* mAdapter;
+ const int mLen;
+ char* mUrl;
+ inline LocEngSetServerUrl(LocEngAdapter* adapter,
+ char* urlString,
+ int url_len) :
+ LocMsg(), mAdapter(adapter),
+ mLen(url_len), mUrl(new char[mLen+1])
+ {
+ memcpy((void*)mUrl, (void*)urlString, url_len);
+ mUrl[mLen] = 0;
+ locallog();
+ }
+ inline ~LocEngSetServerUrl()
+ {
+ delete[] mUrl;
+ }
+ inline virtual void proc() const {
+ mAdapter->setServer(mUrl, mLen);
+ }
+ inline void locallog() const {
+ LOC_LOGV("LocEngSetServerUrl - url: %s", mUrl);
+ }
+ inline virtual void log() const {
+ locallog();
+ }
+};
+
+// case LOC_ENG_MSG_A_GLONASS_PROTOCOL:
+struct LocEngAGlonassProtocol : public LocMsg {
+ LocEngAdapter* mAdapter;
+ const unsigned long mAGlonassProtocl;
+ inline LocEngAGlonassProtocol(LocEngAdapter* adapter,
+ unsigned long protocol) :
+ LocMsg(), mAdapter(adapter), mAGlonassProtocl(protocol)
+ {
+ locallog();
+ }
+ inline virtual void proc() const {
+ mAdapter->setAGLONASSProtocol(mAGlonassProtocl);
+ }
+ inline void locallog() const {
+ LOC_LOGV("A-GLONASS protocol: 0x%lx", mAGlonassProtocl);
+ }
+ inline virtual void log() const {
+ locallog();
+ }
+};
+
+// case LOC_ENG_MSG_SUPL_VERSION:
+struct LocEngSuplVer : public LocMsg {
+ LocEngAdapter* mAdapter;
+ const int mSuplVer;
+ inline LocEngSuplVer(LocEngAdapter* adapter,
+ int suplVer) :
+ LocMsg(), mAdapter(adapter), mSuplVer(suplVer)
+ {
+ locallog();
+ }
+ inline virtual void proc() const {
+ mAdapter->setSUPLVersion(mSuplVer);
+ }
+ inline void locallog() const {
+ LOC_LOGV("SUPL Version: %d", mSuplVer);
+ }
+ inline virtual void log() const {
+ locallog();
+ }
+};
+
+// case LOC_ENG_MSG_LPP_CONFIG:
+struct LocEngLppConfig : public LocMsg {
+ LocEngAdapter* mAdapter;
+ const int mLppConfig;
+ inline LocEngLppConfig(LocEngAdapter* adapter,
+ int lppConfig) :
+ LocMsg(), mAdapter(adapter), mLppConfig(lppConfig)
+ {
+ locallog();
+ }
+ inline virtual void proc() const {
+ mAdapter->setLPPConfig(mLppConfig);
+ }
+ inline void locallog() const {
+ LOC_LOGV("LocEngLppConfig - profile: %d", mLppConfig);
+ }
+ inline virtual void log() const {
+ locallog();
+ }
+};
+
+// case LOC_ENG_MSG_SET_SENSOR_CONTROL_CONFIG:
+struct LocEngSensorControlConfig : public LocMsg {
+ LocEngAdapter* mAdapter;
+ const int mSensorsDisabled;
+ const int mSensorProvider;
+ inline LocEngSensorControlConfig(LocEngAdapter* adapter,
+ int sensorsDisabled, int sensorProvider) :
+ LocMsg(), mAdapter(adapter), mSensorsDisabled(sensorsDisabled),
+ mSensorProvider(sensorProvider)
+ {
+ locallog();
+ }
+ inline virtual void proc() const {
+ mAdapter->setSensorControlConfig(mSensorsDisabled, mSensorProvider);
+ }
+ inline void locallog() const {
+ LOC_LOGV("LocEngSensorControlConfig - Sensors Disabled: %d, Sensor Provider: %d",
+ mSensorsDisabled, mSensorProvider);
+ }
+ inline virtual void log() const {
+ locallog();
+ }
+};
+
+// case LOC_ENG_MSG_SET_SENSOR_PROPERTIES:
+struct LocEngSensorProperties : public LocMsg {
+ LocEngAdapter* mAdapter;
+ const bool mGyroBiasVarianceRandomWalkValid;
+ const float mGyroBiasVarianceRandomWalk;
+ const bool mAccelRandomWalkValid;
+ const float mAccelRandomWalk;
+ const bool mAngleRandomWalkValid;
+ const float mAngleRandomWalk;
+ const bool mRateRandomWalkValid;
+ const float mRateRandomWalk;
+ const bool mVelocityRandomWalkValid;
+ const float mVelocityRandomWalk;
+ inline LocEngSensorProperties(LocEngAdapter* adapter,
+ bool gyroBiasRandomWalk_valid,
+ float gyroBiasRandomWalk,
+ bool accelRandomWalk_valid,
+ float accelRandomWalk,
+ bool angleRandomWalk_valid,
+ float angleRandomWalk,
+ bool rateRandomWalk_valid,
+ float rateRandomWalk,
+ bool velocityRandomWalk_valid,
+ float velocityRandomWalk) :
+ LocMsg(), mAdapter(adapter),
+ mGyroBiasVarianceRandomWalkValid(gyroBiasRandomWalk_valid),
+ mGyroBiasVarianceRandomWalk(gyroBiasRandomWalk),
+ mAccelRandomWalkValid(accelRandomWalk_valid),
+ mAccelRandomWalk(accelRandomWalk),
+ mAngleRandomWalkValid(angleRandomWalk_valid),
+ mAngleRandomWalk(angleRandomWalk),
+ mRateRandomWalkValid(rateRandomWalk_valid),
+ mRateRandomWalk(rateRandomWalk),
+ mVelocityRandomWalkValid(velocityRandomWalk_valid),
+ mVelocityRandomWalk(velocityRandomWalk)
+ {
+ locallog();
+ }
+ inline virtual void proc() const {
+ mAdapter->setSensorProperties(mGyroBiasVarianceRandomWalkValid,
+ mGyroBiasVarianceRandomWalk,
+ mAccelRandomWalkValid,
+ mAccelRandomWalk,
+ mAngleRandomWalkValid,
+ mAngleRandomWalk,
+ mRateRandomWalkValid,
+ mRateRandomWalk,
+ mVelocityRandomWalkValid,
+ mVelocityRandomWalk);
+ }
+ inline void locallog() const {
+ LOC_LOGV("Sensor properties validity, Gyro Random walk: %d "
+ "Accel Random Walk: %d "
+ "Angle Random Walk: %d Rate Random Walk: %d "
+ "Velocity Random Walk: %d\n"
+ "Sensor properties, Gyro Random walk: %f "
+ "Accel Random Walk: %f "
+ "Angle Random Walk: %f Rate Random Walk: %f "
+ "Velocity Random Walk: %f",
+ mGyroBiasVarianceRandomWalkValid,
+ mAccelRandomWalkValid,
+ mAngleRandomWalkValid,
+ mRateRandomWalkValid,
+ mVelocityRandomWalkValid,
+ mGyroBiasVarianceRandomWalk,
+ mAccelRandomWalk,
+ mAngleRandomWalk,
+ mRateRandomWalk,
+ mVelocityRandomWalk
+ );
+ }
+ inline virtual void log() const {
+ locallog();
+ }
+};
+
+// case LOC_ENG_MSG_SET_SENSOR_PERF_CONTROL_CONFIG:
+struct LocEngSensorPerfControlConfig : public LocMsg {
+ LocEngAdapter* mAdapter;
+ const int mControlMode;
+ const int mAccelSamplesPerBatch;
+ const int mAccelBatchesPerSec;
+ const int mGyroSamplesPerBatch;
+ const int mGyroBatchesPerSec;
+ const int mAccelSamplesPerBatchHigh;
+ const int mAccelBatchesPerSecHigh;
+ const int mGyroSamplesPerBatchHigh;
+ const int mGyroBatchesPerSecHigh;
+ const int mAlgorithmConfig;
+ inline LocEngSensorPerfControlConfig(LocEngAdapter* adapter,
+ int controlMode,
+ int accelSamplesPerBatch,
+ int accelBatchesPerSec,
+ int gyroSamplesPerBatch,
+ int gyroBatchesPerSec,
+ int accelSamplesPerBatchHigh,
+ int accelBatchesPerSecHigh,
+ int gyroSamplesPerBatchHigh,
+ int gyroBatchesPerSecHigh,
+ int algorithmConfig) :
+ LocMsg(), mAdapter(adapter),
+ mControlMode(controlMode),
+ mAccelSamplesPerBatch(accelSamplesPerBatch),
+ mAccelBatchesPerSec(accelBatchesPerSec),
+ mGyroSamplesPerBatch(gyroSamplesPerBatch),
+ mGyroBatchesPerSec(gyroBatchesPerSec),
+ mAccelSamplesPerBatchHigh(accelSamplesPerBatchHigh),
+ mAccelBatchesPerSecHigh(accelBatchesPerSecHigh),
+ mGyroSamplesPerBatchHigh(gyroSamplesPerBatchHigh),
+ mGyroBatchesPerSecHigh(gyroBatchesPerSecHigh),
+ mAlgorithmConfig(algorithmConfig)
+ {
+ locallog();
+ }
+ inline virtual void proc() const {
+ mAdapter->setSensorPerfControlConfig(mControlMode,
+ mAccelSamplesPerBatch,
+ mAccelBatchesPerSec,
+ mGyroSamplesPerBatch,
+ mGyroBatchesPerSec,
+ mAccelSamplesPerBatchHigh,
+ mAccelBatchesPerSecHigh,
+ mGyroSamplesPerBatchHigh,
+ mGyroBatchesPerSecHigh,
+ mAlgorithmConfig);
+ }
+ inline void locallog() const {
+ LOC_LOGV("Sensor Perf Control Config (performanceControlMode)(%u) "
+ "accel(#smp,#batches) (%u,%u) "
+ "gyro(#smp,#batches) (%u,%u), "
+ "accel_high(#smp,#batches) (%u,%u) "
+ "gyro_high(#smp,#batches) (%u,%u), "
+ "algorithmConfig(%u)\n",
+ mControlMode,
+ mAccelSamplesPerBatch, mAccelBatchesPerSec,
+ mGyroSamplesPerBatch, mGyroBatchesPerSec,
+ mAccelSamplesPerBatchHigh, mAccelBatchesPerSecHigh,
+ mGyroSamplesPerBatchHigh, mGyroBatchesPerSecHigh,
+ mAlgorithmConfig);
+ }
+ inline virtual void log() const {
+ locallog();
+ }
+};
+
+// case LOC_ENG_MSG_EXT_POWER_CONFIG:
+struct LocEngExtPowerConfig : public LocMsg {
+ LocEngAdapter* mAdapter;
+ const int mIsBatteryCharging;
+ inline LocEngExtPowerConfig(LocEngAdapter* adapter,
+ int isBatteryCharging) :
+ LocMsg(), mAdapter(adapter),
+ mIsBatteryCharging(isBatteryCharging)
+ {
+ locallog();
+ }
+ inline virtual void proc() const {
+ mAdapter->setExtPowerConfig(mIsBatteryCharging);
+ }
+ inline void locallog() const {
+ LOC_LOGV("LocEngExtPowerConfig - isBatteryCharging: %d",
+ mIsBatteryCharging);
+ }
+ inline virtual void log() const {
+ locallog();
+ }
+};
+
+// case LOC_ENG_MSG_REPORT_POSITION:
+LocEngReportPosition::LocEngReportPosition(LocAdapterBase* adapter,
+ UlpLocation &loc,
+ GpsLocationExtended &locExtended,
+ void* locExt,
+ enum loc_sess_status st,
+ LocPosTechMask technology) :
+ LocMsg(), mAdapter(adapter), mLocation(loc),
+ mLocationExtended(locExtended),
+ mLocationExt(((loc_eng_data_s_type*)
+ ((LocEngAdapter*)
+ (mAdapter))->getOwner())->location_ext_parser(locExt)),
+ mStatus(st), mTechMask(technology)
+{
+ locallog();
+}
+void LocEngReportPosition::proc() const {
+ LocEngAdapter* adapter = (LocEngAdapter*)mAdapter;
+ loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)adapter->getOwner();
+
+ if (locEng->mute_session_state != LOC_MUTE_SESS_IN_SESSION) {
+ bool reported = false;
+ if (locEng->location_cb != NULL) {
+ if (LOC_SESS_FAILURE == mStatus) {
+ // in case we want to handle the failure case
+ locEng->location_cb(NULL, NULL);
+ reported = true;
+ }
+ // what's in the else if is... (line by line)
+ // 1. this is a final fix; and
+ // 1.1 it is a Satellite fix; or
+ // 1.2 it is a sensor fix
+ // 2. (must be intermediate fix... implicit)
+ // 2.1 we accepte intermediate; and
+ // 2.2 it is NOT the case that
+ // 2.2.1 there is inaccuracy; and
+ // 2.2.2 we care about inaccuracy; and
+ // 2.2.3 the inaccuracy exceeds our tolerance
+ else if ((LOC_SESS_SUCCESS == mStatus &&
+ ((LOC_POS_TECH_MASK_SATELLITE |
+ LOC_POS_TECH_MASK_SENSORS |
+ LOC_POS_TECH_MASK_HYBRID) &
+ mTechMask)) ||
+ (LOC_SESS_INTERMEDIATE == locEng->intermediateFix &&
+ !((mLocation.gpsLocation.flags &
+ GPS_LOCATION_HAS_ACCURACY) &&
+ (gps_conf.ACCURACY_THRES != 0) &&
+ (mLocation.gpsLocation.accuracy >
+ gps_conf.ACCURACY_THRES)))) {
+ locEng->location_cb((UlpLocation*)&(mLocation),
+ (void*)mLocationExt);
+ reported = true;
+ }
+ }
+
+ // if we have reported this fix
+ if (reported &&
+ // and if this is a singleshot
+ GPS_POSITION_RECURRENCE_SINGLE ==
+ locEng->adapter->getPositionMode().recurrence) {
+ if (LOC_SESS_INTERMEDIATE == mStatus) {
+ // modem could be still working for a final fix,
+ // although we no longer need it. So stopFix().
+ locEng->adapter->stopFix();
+ }
+ // turn off the session flag.
+ locEng->adapter->setInSession(false);
+ }
+
+ if (locEng->generateNmea &&
+ mLocation.position_source == ULP_LOCATION_IS_FROM_GNSS &&
+ mTechMask & (LOC_POS_TECH_MASK_SATELLITE |
+ LOC_POS_TECH_MASK_SENSORS |
+ LOC_POS_TECH_MASK_HYBRID))
+ {
+ unsigned char generate_nmea = reported &&
+ (mStatus != LOC_SESS_FAILURE);
+ loc_eng_nmea_generate_pos(locEng, mLocation, mLocationExtended,
+ generate_nmea);
+ }
+
+ // Free the allocated memory for rawData
+ UlpLocation* gp = (UlpLocation*)&(mLocation);
+ if (gp != NULL && gp->rawData != NULL)
+ {
+ delete (char*)gp->rawData;
+ gp->rawData = NULL;
+ gp->rawDataSize = 0;
+ }
+ }
+}
+void LocEngReportPosition::locallog() const {
+ LOC_LOGV("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: %lld\n rawDataSize: %d\n rawData: %p\n Session"
+ " status: %d\n Technology mask: %u",
+ mLocation.gpsLocation.flags, mLocation.position_source,
+ mLocation.gpsLocation.latitude, mLocation.gpsLocation.longitude,
+ mLocation.gpsLocation.altitude, mLocation.gpsLocation.speed,
+ mLocation.gpsLocation.bearing, mLocation.gpsLocation.accuracy,
+ mLocation.gpsLocation.timestamp, mLocation.rawDataSize,
+ mLocation.rawData, mStatus, mTechMask);
+}
+void LocEngReportPosition::log() const {
+ locallog();
+}
+void LocEngReportPosition::send() const {
+ mAdapter->sendMsg(this);
+}
+
+
+// case LOC_ENG_MSG_REPORT_SV:
+LocEngReportSv::LocEngReportSv(LocAdapterBase* adapter,
+ GpsSvStatus &sv,
+ GpsLocationExtended &locExtended,
+ void* svExt) :
+ LocMsg(), mAdapter(adapter), mSvStatus(sv),
+ mLocationExtended(locExtended),
+ mSvExt(((loc_eng_data_s_type*)
+ ((LocEngAdapter*)
+ (mAdapter))->getOwner())->sv_ext_parser(svExt))
+{
+ locallog();
+}
+void LocEngReportSv::proc() const {
+ LocEngAdapter* adapter = (LocEngAdapter*)mAdapter;
+ loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)adapter->getOwner();
+
+ if (locEng->mute_session_state != LOC_MUTE_SESS_IN_SESSION)
+ {
+ if (locEng->sv_status_cb != NULL) {
+ locEng->sv_status_cb((GpsSvStatus*)&(mSvStatus),
+ (void*)mSvExt);
+ }
+
+ if (locEng->generateNmea)
+ {
+ loc_eng_nmea_generate_sv(locEng, mSvStatus, mLocationExtended);
+ }
+ }
+}
+void LocEngReportSv::locallog() const {
+ LOC_LOGV("num sv: %d\n ephemeris mask: %dxn almanac mask: %x\n "
+ "used in fix mask: %x\n sv: prn snr "
+ "elevation azimuth",
+ mSvStatus.num_svs, mSvStatus.ephemeris_mask,
+ mSvStatus.almanac_mask, mSvStatus.used_in_fix_mask);
+ for (int i = 0; i < mSvStatus.num_svs && i < GPS_MAX_SVS; i++) {
+ LOC_LOGV(" %d: %d %f %f %f\n ",
+ i,
+ mSvStatus.sv_list[i].prn,
+ mSvStatus.sv_list[i].snr,
+ mSvStatus.sv_list[i].elevation,
+ mSvStatus.sv_list[i].azimuth);
+ }
+}
+inline void LocEngReportSv::log() const {
+ locallog();
+}
+void LocEngReportSv::send() const {
+ mAdapter->sendMsg(this);
+}
+
+// case LOC_ENG_MSG_REPORT_STATUS:
+LocEngReportStatus::LocEngReportStatus(LocAdapterBase* adapter,
+ GpsStatusValue engineStatus) :
+ LocMsg(), mAdapter(adapter), mStatus(engineStatus)
+{
+ locallog();
+}
+inline void LocEngReportStatus::proc() const
+{
+ LocEngAdapter* adapter = (LocEngAdapter*)mAdapter;
+ loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)adapter->getOwner();
+
+ loc_eng_report_status(*locEng, mStatus);
+ update_aiding_data_for_deletion(*locEng);
+}
+inline void LocEngReportStatus::locallog() const {
+ LOC_LOGV("LocEngReportStatus");
+}
+inline void LocEngReportStatus::log() const {
+ locallog();
+}
+
+// case LOC_ENG_MSG_REPORT_NMEA:
+LocEngReportNmea::LocEngReportNmea(void* locEng,
+ const char* data, int len) :
+ LocMsg(), mLocEng(locEng), mNmea(new char[len]), mLen(len)
+{
+ memcpy((void*)mNmea, (void*)data, len);
+ locallog();
+}
+void LocEngReportNmea::proc() const {
+ loc_eng_data_s_type* locEng = (loc_eng_data_s_type*) mLocEng;
+
+ struct timeval tv;
+ gettimeofday(&tv, (struct timezone *) NULL);
+ int64_t now = tv.tv_sec * 1000LL + tv.tv_usec / 1000;
+ CALLBACK_LOG_CALLFLOW("nmea_cb", %d, mLen);
+
+ if (locEng->nmea_cb != NULL)
+ locEng->nmea_cb(now, mNmea, mLen);
+}
+inline void LocEngReportNmea::locallog() const {
+ LOC_LOGV("LocEngReportNmea");
+}
+inline void LocEngReportNmea::log() const {
+ locallog();
+}
+
+// case LOC_ENG_MSG_REPORT_XTRA_SERVER:
+LocEngReportXtraServer::LocEngReportXtraServer(void* locEng,
+ const char *url1,
+ const char *url2,
+ const char *url3,
+ const int maxlength) :
+ LocMsg(), mLocEng(locEng), mMaxLen(maxlength),
+ mServers(new char[3*(mMaxLen+1)])
+{
+ char * cptr = mServers;
+ memset(mServers, 0, 3*(mMaxLen+1));
+
+ // Override modem URLs with uncommented gps.conf urls
+ if( gps_conf.XTRA_SERVER_1[0] != '\0' ) {
+ url1 = &gps_conf.XTRA_SERVER_1[0];
+ }
+ if( gps_conf.XTRA_SERVER_2[0] != '\0' ) {
+ url2 = &gps_conf.XTRA_SERVER_2[0];
+ }
+ if( gps_conf.XTRA_SERVER_3[0] != '\0' ) {
+ url3 = &gps_conf.XTRA_SERVER_3[0];
+ }
+ // copy non xtra1.gpsonextra.net URLs into the forwarding buffer.
+ if( NULL == strcasestr(url1, XTRA1_GPSONEXTRA) ) {
+ strlcpy(cptr, url1, mMaxLen + 1);
+ cptr += mMaxLen + 1;
+ }
+ if( NULL == strcasestr(url2, XTRA1_GPSONEXTRA) ) {
+ strlcpy(cptr, url2, mMaxLen + 1);
+ cptr += mMaxLen + 1;
+ }
+ if( NULL == strcasestr(url3, XTRA1_GPSONEXTRA) ) {
+ strlcpy(cptr, url3, mMaxLen + 1);
+ }
+ locallog();
+}
+
+void LocEngReportXtraServer::proc() const {
+ loc_eng_xtra_data_s_type* locEngXtra =
+ &(((loc_eng_data_s_type*)mLocEng)->xtra_module_data);
+
+ if (locEngXtra->report_xtra_server_cb != NULL) {
+ CALLBACK_LOG_CALLFLOW("report_xtra_server_cb", %s, mServers);
+ locEngXtra->report_xtra_server_cb(mServers,
+ &(mServers[mMaxLen+1]),
+ &(mServers[(mMaxLen+1)<<1]));
+ } else {
+ LOC_LOGE("Callback function for request xtra is NULL");
+ }
+}
+inline void LocEngReportXtraServer::locallog() const {
+ LOC_LOGV("LocEngReportXtraServers: server1: %s\n server2: %s\n"
+ " server3: %s\n",
+ mServers, &mServers[mMaxLen+1], &mServers[(mMaxLen+1)<<1]);
+}
+inline void LocEngReportXtraServer::log() const {
+ locallog();
+}
+
+// case LOC_ENG_MSG_REQUEST_BIT:
+// case LOC_ENG_MSG_RELEASE_BIT:
+LocEngReqRelBIT::LocEngReqRelBIT(void* locEng, AGpsExtType type,
+ int ipv4, char* ipv6, bool isReq) :
+ LocMsg(), mLocEng(locEng), mType(type), mIPv4Addr(ipv4),
+ mIPv6Addr(ipv6 ? new char[16] : NULL), mIsReq(isReq) {
+ if (NULL != ipv6)
+ memcpy(mIPv6Addr, ipv6, 16);
+ locallog();
+}
+inline LocEngReqRelBIT::~LocEngReqRelBIT() {
+ if (mIPv6Addr) {
+ delete[] mIPv6Addr;
+ }
+}
+void LocEngReqRelBIT::proc() const {
+ loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
+ BITSubscriber s(getAgpsStateMachine(*locEng, mType),
+ mIPv4Addr, mIPv6Addr);
+ AgpsStateMachine* sm = (AgpsStateMachine*)s.mStateMachine;
+
+ if (mIsReq) {
+ sm->subscribeRsrc((Subscriber*)&s);
+ } else {
+ sm->unsubscribeRsrc((Subscriber*)&s);
+ }
+}
+inline void LocEngReqRelBIT::locallog() const {
+ LOC_LOGV("LocEngRequestBIT - ipv4: %d.%d.%d.%d, ipv6: %s",
+ (unsigned char)mIPv4Addr,
+ (unsigned char)(mIPv4Addr>>8),
+ (unsigned char)(mIPv4Addr>>16),
+ (unsigned char)(mIPv4Addr>>24),
+ NULL != mIPv6Addr ? mIPv6Addr : "");
+}
+inline void LocEngReqRelBIT::log() const {
+ locallog();
+}
+void LocEngReqRelBIT::send() const {
+ loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
+ locEng->adapter->sendMsg(this);
+}
+
+// case LOC_ENG_MSG_RELEASE_BIT:
+struct LocEngReleaseBIT : public LocMsg {
+ const BITSubscriber mSubscriber;
+ inline LocEngReleaseBIT(const AgpsStateMachine* stateMachine,
+ unsigned int ipv4, char* ipv6) :
+ LocMsg(),
+ mSubscriber(stateMachine, ipv4, ipv6)
+ {
+ locallog();
+ }
+ inline virtual void proc() const
+ {
+ AgpsStateMachine* sm = (AgpsStateMachine*)mSubscriber.mStateMachine;
+ sm->unsubscribeRsrc((Subscriber*)&mSubscriber);
+ }
+ inline void locallog() const {
+ LOC_LOGV("LocEngReleaseBIT - ipv4: %d.%d.%d.%d, ipv6: %s",
+ (unsigned char)(mSubscriber.ID>>24),
+ (unsigned char)(mSubscriber.ID>>16),
+ (unsigned char)(mSubscriber.ID>>8),
+ (unsigned char)mSubscriber.ID,
+ NULL != mSubscriber.mIPv6Addr ? mSubscriber.mIPv6Addr : "");
+ }
+ virtual void log() const {
+ locallog();
+ }
+};
+
+// LocEngSuplEsOpened
+LocEngSuplEsOpened::LocEngSuplEsOpened(void* locEng) :
+ LocMsg(), mLocEng(locEng) {
+ locallog();
+}
+void LocEngSuplEsOpened::proc() const {
+ loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
+ if (locEng->ds_nif) {
+ AgpsStateMachine* sm = locEng->ds_nif;
+ sm->onRsrcEvent(RSRC_GRANTED);
+ }
+}
+void LocEngSuplEsOpened::locallog() const {
+ LOC_LOGV("LocEngSuplEsOpened");
+}
+void LocEngSuplEsOpened::log() const {
+ locallog();
+}
+
+// LocEngSuplEsClosed
+LocEngSuplEsClosed::LocEngSuplEsClosed(void* locEng) :
+ LocMsg(), mLocEng(locEng) {
+ locallog();
+}
+void LocEngSuplEsClosed::proc() const {
+ loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
+ if (locEng->ds_nif) {
+ AgpsStateMachine* sm = locEng->ds_nif;
+ sm->onRsrcEvent(RSRC_RELEASED);
+ }
+}
+void LocEngSuplEsClosed::locallog() const {
+ LOC_LOGV("LocEngSuplEsClosed");
+}
+void LocEngSuplEsClosed::log() const {
+ locallog();
+}
+
+
+// case LOC_ENG_MSG_REQUEST_SUPL_ES:
+LocEngRequestSuplEs::LocEngRequestSuplEs(void* locEng, int id) :
+ LocMsg(), mLocEng(locEng), mID(id) {
+ locallog();
+}
+void LocEngRequestSuplEs::proc() const {
+ loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
+ if (locEng->ds_nif) {
+ AgpsStateMachine* sm = locEng->ds_nif;
+ DSSubscriber s(sm, mID);
+ sm->subscribeRsrc((Subscriber*)&s);
+ } else {
+ locEng->adapter->atlOpenStatus(mID, 0, NULL, -1, -1);
+ }
+}
+inline void LocEngRequestSuplEs::locallog() const {
+ LOC_LOGV("LocEngRequestSuplEs");
+}
+inline void LocEngRequestSuplEs::log() const {
+ locallog();
+}
+
+// case LOC_ENG_MSG_REQUEST_ATL:
+LocEngRequestATL::LocEngRequestATL(void* locEng, int id,
+ AGpsExtType agps_type) :
+ LocMsg(), mLocEng(locEng), mID(id), mType(agps_type) {
+ locallog();
+}
+void LocEngRequestATL::proc() const {
+ loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
+ AgpsStateMachine* sm = (AgpsStateMachine*)
+ getAgpsStateMachine(*locEng, mType);
+ if (sm) {
+ ATLSubscriber s(mID,
+ sm,
+ locEng->adapter,
+ AGPS_TYPE_INVALID == mType);
+ sm->subscribeRsrc((Subscriber*)&s);
+ } else {
+ locEng->adapter->atlOpenStatus(mID, 0, NULL, -1, mType);
+ }
+}
+inline void LocEngRequestATL::locallog() const {
+ LOC_LOGV("LocEngRequestATL");
+}
+inline void LocEngRequestATL::log() const {
+ locallog();
+}
+
+// case LOC_ENG_MSG_RELEASE_ATL:
+LocEngReleaseATL::LocEngReleaseATL(void* locEng, int id) :
+ LocMsg(), mLocEng(locEng), mID(id) {
+ locallog();
+}
+void LocEngReleaseATL::proc() const {
+ loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
+
+ if (locEng->agnss_nif) {
+ ATLSubscriber s1(mID, locEng->agnss_nif, locEng->adapter, false);
+ if (locEng->agnss_nif->unsubscribeRsrc((Subscriber*)&s1)) {
+ LOC_LOGD("%s:%d]: Unsubscribed from agnss_nif",
+ __func__, __LINE__);
+ return;
+ }
+ }
+
+ if (locEng->internet_nif) {
+ ATLSubscriber s2(mID, locEng->internet_nif, locEng->adapter, false);
+ if (locEng->internet_nif->unsubscribeRsrc((Subscriber*)&s2)) {
+ LOC_LOGD("%s:%d]: Unsubscribed from internet_nif",
+ __func__, __LINE__);
+ return;
+ }
+ }
+
+ if (locEng->ds_nif) {
+ DSSubscriber s3(locEng->ds_nif, mID);
+ if (locEng->ds_nif->unsubscribeRsrc((Subscriber*)&s3)) {
+ LOC_LOGD("%s:%d]: Unsubscribed from ds_nif",
+ __func__, __LINE__);
+ return;
+ }
+ }
+
+ LOC_LOGW("%s:%d]: Could not release ATL. "
+ "No subscribers found\n",
+ __func__, __LINE__);
+ locEng->adapter->atlCloseStatus(mID, 0);
+}
+inline void LocEngReleaseATL::locallog() const {
+ LOC_LOGV("LocEngReleaseATL");
+}
+inline void LocEngReleaseATL::log() const {
+ locallog();
+}
+
+// case LOC_ENG_MSG_REQUEST_WIFI:
+// case LOC_ENG_MSG_RELEASE_WIFI:
+LocEngReqRelWifi::LocEngReqRelWifi(void* locEng, AGpsExtType type,
+ loc_if_req_sender_id_e_type sender_id,
+ char* s, char* p, bool isReq) :
+ LocMsg(), mLocEng(locEng), mType(type), mSenderId(sender_id),
+ mSSID(NULL == s ? NULL : new char[SSID_BUF_SIZE]),
+ mPassword(NULL == p ? NULL : new char[SSID_BUF_SIZE]),
+ mIsReq(isReq) {
+ if (NULL != s)
+ strlcpy(mSSID, s, SSID_BUF_SIZE);
+ if (NULL != p)
+ strlcpy(mPassword, p, SSID_BUF_SIZE);
+ locallog();
+}
+LocEngReqRelWifi::~LocEngReqRelWifi() {
+ if (NULL != mSSID) {
+ delete[] mSSID;
+ }
+ if (NULL != mPassword) {
+ delete[] mPassword;
+ }
+}
+void LocEngReqRelWifi::proc() const {
+ loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
+ if (locEng->wifi_nif) {
+ WIFISubscriber s(locEng->wifi_nif, mSSID, mPassword, mSenderId);
+ if (mIsReq) {
+ locEng->wifi_nif->subscribeRsrc((Subscriber*)&s);
+ } else {
+ locEng->wifi_nif->unsubscribeRsrc((Subscriber*)&s);
+ }
+ } else {
+ locEng->adapter->atlOpenStatus(mSenderId, 0, NULL, -1, mType);
+ }
+}
+inline void LocEngReqRelWifi::locallog() const {
+ LOC_LOGV("%s - senderId: %d, ssid: %s, password: %s",
+ mIsReq ? "LocEngRequestWifi" : "LocEngReleaseWifi",
+ mSenderId,
+ NULL != mSSID ? mSSID : "",
+ NULL != mPassword ? mPassword : "");
+}
+inline void LocEngReqRelWifi::log() const {
+ locallog();
+}
+void LocEngReqRelWifi::send() const {
+ loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
+ locEng->adapter->sendMsg(this);
+}
+
+// case LOC_ENG_MSG_REQUEST_XTRA_DATA:
+LocEngRequestXtra::LocEngRequestXtra(void* locEng) :
+ mLocEng(locEng) {
+ locallog();
+}
+void LocEngRequestXtra::proc() const
+{
+ loc_eng_xtra_data_s_type* locEngXtra =
+ &(((loc_eng_data_s_type*)mLocEng)->xtra_module_data);
+
+ if (locEngXtra->download_request_cb != NULL) {
+ CALLBACK_LOG_CALLFLOW("download_request_cb", %p, mLocEng);
+ locEngXtra->download_request_cb();
+ } else {
+ LOC_LOGE("Callback function for request xtra is NULL");
+ }
+}
+inline void LocEngRequestXtra::locallog() const {
+ LOC_LOGV("LocEngReqXtra");
+}
+inline void LocEngRequestXtra::log() const {
+ locallog();
+}
+
+// case LOC_ENG_MSG_REQUEST_TIME:
+LocEngRequestTime::LocEngRequestTime(void* locEng) :
+ LocMsg(), mLocEng(locEng)
+{
+ locallog();
+}
+void LocEngRequestTime::proc() const {
+ loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
+ if (gps_conf.CAPABILITIES & GPS_CAPABILITY_ON_DEMAND_TIME) {
+ if (locEng->request_utc_time_cb != NULL) {
+ locEng->request_utc_time_cb();
+ } else {
+ LOC_LOGE("Callback function for request time is NULL");
+ }
+ }
+}
+inline void LocEngRequestTime::locallog() const {
+ LOC_LOGV("LocEngReqTime");
+}
+inline void LocEngRequestTime::log() const {
+ locallog();
+}
+
+// case LOC_ENG_MSG_DELETE_AIDING_DATA:
+struct LocEngDelAidData : public LocMsg {
+ loc_eng_data_s_type* mLocEng;
+ const GpsAidingData mType;
+ inline LocEngDelAidData(loc_eng_data_s_type* locEng,
+ GpsAidingData f) :
+ LocMsg(), mLocEng(locEng), mType(f)
+ {
+ locallog();
+ }
+ inline virtual void proc() const {
+ mLocEng->aiding_data_for_deletion = mType;
+ update_aiding_data_for_deletion(*mLocEng);
+ }
+ inline void locallog() const {
+ LOC_LOGV("aiding data msak %d", mType);
+ }
+ virtual void log() const {
+ locallog();
+ }
+};
+
+// case LOC_ENG_MSG_ENABLE_DATA:
+struct LocEngEnableData : public LocMsg {
+ LocEngAdapter* mAdapter;
+ const int mEnable;
+ char* mAPN;
+ const int mLen;
+ inline LocEngEnableData(LocEngAdapter* adapter,
+ const char* name, int len, int enable) :
+ LocMsg(), mAdapter(adapter),
+ mEnable(enable), mAPN(NULL), mLen(len)
+ {
+ if (NULL != name) {
+ mAPN = new char[len+1];
+ memcpy((void*)mAPN, (void*)name, len);
+ mAPN[len] = 0;
+ }
+ locallog();
+ }
+ inline ~LocEngEnableData() {
+ if (NULL != mAPN) {
+ delete[] mAPN;
+ }
+ }
+ inline virtual void proc() const {
+ mAdapter->enableData(mEnable);
+ if (NULL != mAPN) {
+ mAdapter->setAPN(mAPN, mLen);
+ }
+ }
+ inline void locallog() const {
+ LOC_LOGV("apn: %s\n enable: %d",
+ (NULL == mAPN) ? "NULL" : mAPN, mEnable);
+ }
+ inline virtual void log() const {
+ locallog();
+ }
+};
+
+// case LOC_ENG_MSG_INJECT_XTRA_DATA:
+// loc_eng_xtra.cpp
+
+// case LOC_ENG_MSG_LOC_INIT:
+struct LocEngInit : public LocMsg {
+ loc_eng_data_s_type* mLocEng;
+ inline LocEngInit(loc_eng_data_s_type* locEng) :
+ LocMsg(), mLocEng(locEng)
+ {
+ locallog();
+ }
+ inline virtual void proc() const {
+ loc_eng_reinit(*mLocEng);
+ }
+ inline void locallog() const
+ {
+ LOC_LOGV("LocEngInit");
+ }
+ inline virtual void log() const
+ {
+ locallog();
+ }
+};
+
+// case LOC_ENG_MSG_REQUEST_XTRA_SERVER:
+// loc_eng_xtra.cpp
+
+// case LOC_ENG_MSG_ATL_OPEN_SUCCESS:
+struct LocEngAtlOpenSuccess : public LocMsg {
+ AgpsStateMachine* mStateMachine;
+ const int mLen;
+ char* mAPN;
+ const AGpsBearerType mBearerType;
+ inline LocEngAtlOpenSuccess(AgpsStateMachine* statemachine,
+ const char* name,
+ int len,
+ AGpsBearerType btype) :
+ LocMsg(),
+ mStateMachine(statemachine), mLen(len),
+ mAPN(new char[len+1]), mBearerType(btype)
+ {
+ memcpy((void*)mAPN, (void*)name, len);
+ mAPN[len] = 0;
+ locallog();
+ }
+ inline ~LocEngAtlOpenSuccess()
+ {
+ delete[] mAPN;
+ }
+ inline virtual void proc() const {
+ mStateMachine->setBearer(mBearerType);
+ mStateMachine->setAPN(mAPN, mLen);
+ mStateMachine->onRsrcEvent(RSRC_GRANTED);
+ }
+ inline void locallog() const {
+ LOC_LOGV("LocEngAtlOpenSuccess agps type: %s\n apn: %s\n"
+ " bearer type: %s",
+ loc_get_agps_type_name(mStateMachine->getType()),
+ mAPN,
+ loc_get_agps_bear_name(mBearerType));
+ }
+ inline virtual void log() const {
+ locallog();
+ }
+};
+
+// case LOC_ENG_MSG_ATL_CLOSED:
+struct LocEngAtlClosed : public LocMsg {
+ AgpsStateMachine* mStateMachine;
+ inline LocEngAtlClosed(AgpsStateMachine* statemachine) :
+ LocMsg(), mStateMachine(statemachine) {
+ locallog();
+ }
+ inline virtual void proc() const {
+ mStateMachine->onRsrcEvent(RSRC_RELEASED);
+ }
+ inline void locallog() const {
+ LOC_LOGV("LocEngAtlClosed");
+ }
+ inline virtual void log() const {
+ locallog();
+ }
+};
+
+// case LOC_ENG_MSG_ATL_OPEN_FAILED:
+struct LocEngAtlOpenFailed : public LocMsg {
+ AgpsStateMachine* mStateMachine;
+ inline LocEngAtlOpenFailed(AgpsStateMachine* statemachine) :
+ LocMsg(), mStateMachine(statemachine) {
+ locallog();
+ }
+ inline virtual void proc() const {
+ mStateMachine->onRsrcEvent(RSRC_DENIED);
+ }
+ inline void locallog() const {
+ LOC_LOGV("LocEngAtlOpenFailed");
+ }
+ inline virtual void log() const {
+ locallog();
+ }
+};
+
+// case LOC_ENG_MSG_ENGINE_DOWN:
+LocEngDown::LocEngDown(void* locEng) :
+ LocMsg(), mLocEng(locEng) {
+ locallog();
+}
+inline void LocEngDown::proc() const {
+ loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
+ loc_eng_handle_engine_down(*locEng);
+}
+inline void LocEngDown::locallog() const {
+ LOC_LOGV("LocEngDown");
+}
+inline void LocEngDown::log() const {
+ locallog();
+}
+
+// case LOC_ENG_MSG_ENGINE_UP:
+LocEngUp::LocEngUp(void* locEng) :
+ LocMsg(), mLocEng(locEng) {
+ locallog();
+}
+inline void LocEngUp::proc() const {
+ loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
+ loc_eng_handle_engine_up(*locEng);
+}
+inline void LocEngUp::locallog() const {
+ LOC_LOGV("LocEngUp");
+}
+inline void LocEngUp::log() const {
+ locallog();
+}
+
+struct LocEngDataClientInit : public LocMsg {
+ loc_eng_data_s_type* mLocEng;
+ inline LocEngDataClientInit(loc_eng_data_s_type* locEng) :
+ LocMsg(), mLocEng(locEng) {
+ locallog();
+ }
+ virtual void proc() const {
+ loc_eng_data_s_type *locEng = (loc_eng_data_s_type *)mLocEng;
+ if(!locEng->adapter->initDataServiceClient()) {
+ locEng->ds_nif = new DSStateMachine(servicerTypeExt,
+ (void *)dataCallCb,
+ locEng->adapter);
+ }
+ }
+ void locallog() const {
+ LOC_LOGV("LocEngDataClientInit\n");
+ }
+ virtual void log() const {
+ locallog();
+ }
+};
+
+
+/*********************************************************************
+ * Initialization checking macros
+ *********************************************************************/
+#define STATE_CHECK(ctx, x, ret) \
+ if (!(ctx)) \
+ { \
+ /* Not intialized, abort */\
+ LOC_LOGE("%s: log_eng state error: %s", __func__, x); \
+ EXIT_LOG(%s, x); \
+ ret; \
+ }
+#define INIT_CHECK(ctx, ret) STATE_CHECK(ctx, "instance not initialized", ret)
+
+/*===========================================================================
+FUNCTION loc_eng_init
+
+DESCRIPTION
+ Initialize the location engine, this include setting up global datas
+ and registers location engien with loc api service.
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0: success
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_init(loc_eng_data_s_type &loc_eng_data, LocCallbacks* callbacks,
+ LOC_API_ADAPTER_EVENT_MASK_T event, ContextBase* context)
+
+{
+ int ret_val = 0;
+
+ ENTRY_LOG_CALLFLOW();
+ if (NULL == callbacks || 0 == event) {
+ LOC_LOGE("loc_eng_init: bad parameters cb %p eMask %d", callbacks, event);
+ ret_val = -1;
+ EXIT_LOG(%d, ret_val);
+ return ret_val;
+ }
+
+ STATE_CHECK((NULL == loc_eng_data.adapter),
+ "instance already initialized", return 0);
+
+ memset(&loc_eng_data, 0, sizeof (loc_eng_data));
+
+ if (NULL != callbacks->set_capabilities_cb) {
+ callbacks->set_capabilities_cb(gps_conf.CAPABILITIES);
+ }
+
+ // Save callbacks
+ loc_eng_data.location_cb = callbacks->location_cb;
+ loc_eng_data.sv_status_cb = callbacks->sv_status_cb;
+ loc_eng_data.status_cb = callbacks->status_cb;
+ loc_eng_data.nmea_cb = callbacks->nmea_cb;
+ loc_eng_data.acquire_wakelock_cb = callbacks->acquire_wakelock_cb;
+ loc_eng_data.release_wakelock_cb = callbacks->release_wakelock_cb;
+ loc_eng_data.request_utc_time_cb = callbacks->request_utc_time_cb;
+ loc_eng_data.location_ext_parser = callbacks->location_ext_parser ?
+ callbacks->location_ext_parser : noProc;
+ loc_eng_data.sv_ext_parser = callbacks->sv_ext_parser ?
+ callbacks->sv_ext_parser : noProc;
+ loc_eng_data.intermediateFix = gps_conf.INTERMEDIATE_POS;
+
+ // initial states taken care of by the memset above
+ // loc_eng_data.engine_status -- GPS_STATUS_NONE;
+ // loc_eng_data.fix_session_status -- GPS_STATUS_NONE;
+ // loc_eng_data.mute_session_state -- LOC_MUTE_SESS_NONE;
+
+ if ((event & LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT) && (gps_conf.NMEA_PROVIDER == NMEA_PROVIDER_AP))
+ {
+ event = event ^ LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT; // unregister for modem NMEA report
+ loc_eng_data.generateNmea = true;
+ }
+ else
+ {
+ loc_eng_data.generateNmea = false;
+ }
+
+ loc_eng_data.adapter =
+ new LocEngAdapter(event, &loc_eng_data, context,
+ (MsgTask::tCreate)callbacks->create_thread_cb);
+
+ LOC_LOGD("loc_eng_init created client, id = %p\n",
+ loc_eng_data.adapter);
+ loc_eng_data.adapter->sendMsg(new LocEngInit(&loc_eng_data));
+
+ EXIT_LOG(%d, ret_val);
+ return ret_val;
+}
+
+static int loc_eng_reinit(loc_eng_data_s_type &loc_eng_data)
+{
+ ENTRY_LOG();
+ int ret_val = LOC_API_ADAPTER_ERR_SUCCESS;
+ LocEngAdapter* adapter = loc_eng_data.adapter;
+
+ adapter->sendMsg(new LocEngSuplVer(adapter, gps_conf.SUPL_VER));
+ adapter->sendMsg(new LocEngLppConfig(adapter, gps_conf.LPP_PROFILE));
+ adapter->sendMsg(new LocEngSensorControlConfig(adapter, sap_conf.SENSOR_USAGE,
+ sap_conf.SENSOR_PROVIDER));
+ adapter->sendMsg(new LocEngAGlonassProtocol(adapter, gps_conf.A_GLONASS_POS_PROTOCOL_SELECT));
+
+ /* Make sure at least one of the sensor property is specified by the user in the gps.conf file. */
+ if( sap_conf.GYRO_BIAS_RANDOM_WALK_VALID ||
+ sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID ||
+ sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID ||
+ sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID ||
+ sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID ) {
+ adapter->sendMsg(new LocEngSensorProperties(adapter,
+ sap_conf.GYRO_BIAS_RANDOM_WALK_VALID,
+ sap_conf.GYRO_BIAS_RANDOM_WALK,
+ sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
+ sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY,
+ sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
+ sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY,
+ sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
+ sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY,
+ sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
+ sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY));
+ }
+
+ adapter->sendMsg(new LocEngSensorPerfControlConfig(adapter,
+ sap_conf.SENSOR_CONTROL_MODE,
+ sap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH,
+ sap_conf.SENSOR_ACCEL_BATCHES_PER_SEC,
+ sap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH,
+ sap_conf.SENSOR_GYRO_BATCHES_PER_SEC,
+ sap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH,
+ sap_conf.SENSOR_ACCEL_BATCHES_PER_SEC_HIGH,
+ sap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH,
+ sap_conf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH,
+ sap_conf.SENSOR_ALGORITHM_CONFIG_MASK));
+
+ adapter->sendMsg(new LocEngEnableData(adapter, NULL, 0, (agpsStatus ? 1:0)));
+
+ loc_eng_xtra_version_check(loc_eng_data, gps_conf.XTRA_VERSION_CHECK);
+
+ LOC_LOGD("loc_eng_reinit reinit() successful");
+ EXIT_LOG(%d, ret_val);
+ return ret_val;
+}
+
+/*===========================================================================
+FUNCTION loc_eng_cleanup
+
+DESCRIPTION
+ Cleans location engine. The location client handle will be released.
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ None
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+void loc_eng_cleanup(loc_eng_data_s_type &loc_eng_data)
+{
+ ENTRY_LOG_CALLFLOW();
+ INIT_CHECK(loc_eng_data.adapter, return);
+
+ // XTRA has no state, so we are fine with it.
+
+ // we need to check and clear NI
+#if 0
+ // we need to check and clear ATL
+ if (NULL != loc_eng_data.agnss_nif) {
+ delete loc_eng_data.agnss_nif;
+ loc_eng_data.agnss_nif = NULL;
+ }
+ if (NULL != loc_eng_data.internet_nif) {
+ delete loc_eng_data.internet_nif;
+ loc_eng_data.internet_nif = NULL;
+ }
+#endif
+ if (loc_eng_data.adapter->isInSession())
+ {
+ LOC_LOGD("loc_eng_cleanup: fix not stopped. stop it now.");
+ loc_eng_stop(loc_eng_data);
+ }
+
+#if 0 // can't afford to actually clean up, for many reason.
+
+ LOC_LOGD("loc_eng_init: client opened. close it now.");
+ delete loc_eng_data.adapter;
+ loc_eng_data.adapter = NULL;
+
+ loc_eng_dmn_conn_loc_api_server_unblock();
+ loc_eng_dmn_conn_loc_api_server_join();
+
+#endif
+
+ EXIT_LOG(%s, VOID_RET);
+}
+
+
+/*===========================================================================
+FUNCTION loc_eng_start
+
+DESCRIPTION
+ Starts the tracking session
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0: success
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_start(loc_eng_data_s_type &loc_eng_data)
+{
+ ENTRY_LOG_CALLFLOW();
+ INIT_CHECK(loc_eng_data.adapter, return -1);
+
+ if(! loc_eng_data.adapter->getUlpProxy()->sendStartFix())
+ {
+ loc_eng_data.adapter->sendMsg(new LocEngStartFix(loc_eng_data.adapter));
+ }
+
+ EXIT_LOG(%d, 0);
+ return 0;
+}
+
+static int loc_eng_start_handler(loc_eng_data_s_type &loc_eng_data)
+{
+ ENTRY_LOG();
+ int ret_val = LOC_API_ADAPTER_ERR_SUCCESS;
+
+ if (!loc_eng_data.adapter->isInSession()) {
+ ret_val = loc_eng_data.adapter->startFix();
+
+ if (ret_val == LOC_API_ADAPTER_ERR_SUCCESS ||
+ ret_val == LOC_API_ADAPTER_ERR_ENGINE_DOWN ||
+ ret_val == LOC_API_ADAPTER_ERR_PHONE_OFFLINE ||
+ ret_val == LOC_API_ADAPTER_ERR_INTERNAL)
+ {
+ loc_eng_data.adapter->setInSession(TRUE);
+ loc_inform_gps_status(loc_eng_data, GPS_STATUS_SESSION_BEGIN);
+ }
+ }
+
+ EXIT_LOG(%d, ret_val);
+ return ret_val;
+}
+
+/*===========================================================================
+FUNCTION loc_eng_stop_wrapper
+
+DESCRIPTION
+ Stops the tracking session
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0: success
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_stop(loc_eng_data_s_type &loc_eng_data)
+{
+ ENTRY_LOG_CALLFLOW();
+ INIT_CHECK(loc_eng_data.adapter, return -1);
+
+ if(! loc_eng_data.adapter->getUlpProxy()->sendStopFix())
+ {
+ loc_eng_data.adapter->sendMsg(new LocEngStopFix(loc_eng_data.adapter));
+ }
+
+ EXIT_LOG(%d, 0);
+ return 0;
+}
+
+static int loc_eng_stop_handler(loc_eng_data_s_type &loc_eng_data)
+{
+ ENTRY_LOG();
+ int ret_val = LOC_API_ADAPTER_ERR_SUCCESS;
+
+ if (loc_eng_data.adapter->isInSession()) {
+
+ ret_val = loc_eng_data.adapter->stopFix();
+ if (ret_val == LOC_API_ADAPTER_ERR_SUCCESS)
+ {
+ loc_inform_gps_status(loc_eng_data, GPS_STATUS_SESSION_END);
+ }
+
+ loc_eng_data.adapter->setInSession(FALSE);
+ }
+
+ EXIT_LOG(%d, ret_val);
+ return ret_val;
+}
+
+/*===========================================================================
+FUNCTION loc_eng_mute_one_session
+
+DESCRIPTION
+ Mutes one session
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0: Success
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+void loc_eng_mute_one_session(loc_eng_data_s_type &loc_eng_data)
+{
+ ENTRY_LOG();
+ loc_eng_data.mute_session_state = LOC_MUTE_SESS_WAIT;
+ EXIT_LOG(%s, VOID_RET);
+}
+
+/*===========================================================================
+FUNCTION loc_eng_set_position_mode
+
+DESCRIPTION
+ Sets the mode and fix frequency for the tracking session.
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0: success
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_set_position_mode(loc_eng_data_s_type &loc_eng_data,
+ LocPosMode &params)
+{
+ ENTRY_LOG_CALLFLOW();
+ INIT_CHECK(loc_eng_data.adapter, return -1);
+
+ int gnssType = getTargetGnssType(loc_get_target());
+
+ // The position mode for GSS/QCA1530 can only be standalone
+ bool is1530 = gnssType == GNSS_QCA1530;
+ bool isAPQ = gnssType == GNSS_GSS;
+ if ((isAPQ || is1530) && params.mode != LOC_POSITION_MODE_STANDALONE) {
+ params.mode = LOC_POSITION_MODE_STANDALONE;
+ LOC_LOGD("Position mode changed to standalone for target with GSS/qca1530.");
+ }
+
+ if(! loc_eng_data.adapter->getUlpProxy()->sendFixMode(params))
+ {
+ LocEngAdapter* adapter = loc_eng_data.adapter;
+ adapter->sendMsg(new LocEngPositionMode(adapter, params));
+ }
+
+ EXIT_LOG(%d, 0);
+ return 0;
+}
+
+/*===========================================================================
+FUNCTION loc_eng_inject_time
+
+DESCRIPTION
+ This is used by Java native function to do time injection.
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_inject_time(loc_eng_data_s_type &loc_eng_data, GpsUtcTime time,
+ int64_t timeReference, int uncertainty)
+{
+ ENTRY_LOG_CALLFLOW();
+ INIT_CHECK(loc_eng_data.adapter, return -1);
+ LocEngAdapter* adapter = loc_eng_data.adapter;
+
+ adapter->sendMsg(new LocEngSetTime(adapter, time, timeReference,
+ uncertainty));
+
+ EXIT_LOG(%d, 0);
+ return 0;
+}
+
+
+/*===========================================================================
+FUNCTION loc_eng_inject_location
+
+DESCRIPTION
+ This is used by Java native function to do location injection.
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0 : Successful
+ error code : Failure
+
+SIDE EFFECTS
+ N/A
+===========================================================================*/
+int loc_eng_inject_location(loc_eng_data_s_type &loc_eng_data, double latitude,
+ double longitude, float accuracy)
+{
+ ENTRY_LOG_CALLFLOW();
+ INIT_CHECK(loc_eng_data.adapter, return -1);
+ LocEngAdapter* adapter = loc_eng_data.adapter;
+ if(adapter->mSupportsPositionInjection)
+ {
+ adapter->sendMsg(new LocEngInjectLocation(adapter, latitude, longitude,
+ accuracy));
+ }
+
+ EXIT_LOG(%d, 0);
+ return 0;
+}
+
+
+/*===========================================================================
+FUNCTION loc_eng_delete_aiding_data
+
+DESCRIPTION
+ This is used by Java native function to delete the aiding data. The function
+ updates the global variable for the aiding data to be deleted. If the GPS
+ engine is off, the aiding data will be deleted. Otherwise, the actual action
+ will happen when gps engine is turned off.
+
+DEPENDENCIES
+ Assumes the aiding data type specified in GpsAidingData matches with
+ LOC API specification.
+
+RETURN VALUE
+ None
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+void loc_eng_delete_aiding_data(loc_eng_data_s_type &loc_eng_data, GpsAidingData f)
+{
+ ENTRY_LOG_CALLFLOW();
+ INIT_CHECK(loc_eng_data.adapter, return);
+
+ loc_eng_data.adapter->sendMsg(new LocEngDelAidData(&loc_eng_data, f));
+
+ EXIT_LOG(%s, VOID_RET);
+}
+
+/*===========================================================================
+
+FUNCTION loc_inform_gps_state
+
+DESCRIPTION
+ Informs the GPS Provider about the GPS status
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ None
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static void loc_inform_gps_status(loc_eng_data_s_type &loc_eng_data, GpsStatusValue status)
+{
+ ENTRY_LOG();
+
+ if (loc_eng_data.status_cb)
+ {
+ GpsStatus gs = { sizeof(gs),status };
+ CALLBACK_LOG_CALLFLOW("status_cb", %s,
+ loc_get_gps_status_name(gs.status));
+ loc_eng_data.status_cb(&gs);
+ }
+
+ EXIT_LOG(%s, VOID_RET);
+}
+
+static int loc_eng_get_zpp_handler(loc_eng_data_s_type &loc_eng_data)
+{
+ ENTRY_LOG();
+ int ret_val = LOC_API_ADAPTER_ERR_SUCCESS;
+ UlpLocation location;
+ LocPosTechMask tech_mask = LOC_POS_TECH_MASK_DEFAULT;
+ GpsLocationExtended locationExtended;
+ memset(&locationExtended, 0, sizeof (GpsLocationExtended));
+ locationExtended.size = sizeof(locationExtended);
+
+ ret_val = loc_eng_data.adapter->getZpp(location.gpsLocation, tech_mask);
+ //Mark the location source as from ZPP
+ location.gpsLocation.flags |= LOCATION_HAS_SOURCE_INFO;
+ location.position_source = ULP_LOCATION_IS_FROM_ZPP;
+
+ loc_eng_data.adapter->getUlpProxy()->reportPosition(location,
+ locationExtended,
+ NULL,
+ LOC_SESS_SUCCESS,
+ tech_mask);
+
+ EXIT_LOG(%d, ret_val);
+ return ret_val;
+}
+
+/*
+ Callback function passed to Data Services State Machine
+ This becomes part of the state machine's servicer and
+ is used to send requests to the data services client
+*/
+static int dataCallCb(void *cb_data)
+{
+ LOC_LOGD("Enter dataCallCb\n");
+ int ret=0;
+ if(cb_data != NULL) {
+ dsCbData *cbData = (dsCbData *)cb_data;
+ LocEngAdapter *locAdapter = (LocEngAdapter *)cbData->mAdapter;
+ if(cbData->action == GPS_REQUEST_AGPS_DATA_CONN) {
+ LOC_LOGD("dataCallCb GPS_REQUEST_AGPS_DATA_CONN\n");
+ ret = locAdapter->openAndStartDataCall();
+ }
+ else if(cbData->action == GPS_RELEASE_AGPS_DATA_CONN) {
+ LOC_LOGD("dataCallCb GPS_RELEASE_AGPS_DATA_CONN\n");
+ locAdapter->stopDataCall();
+ }
+ }
+ else {
+ LOC_LOGE("NULL argument received. Failing.\n");
+ ret = -1;
+ goto err;
+ }
+
+err:
+ LOC_LOGD("Exit dataCallCb ret = %d\n", ret);
+ return ret;
+}
+
+/*===========================================================================
+FUNCTION loc_eng_agps_reinit
+
+DESCRIPTION
+ 2nd half of loc_eng_agps_init(), singled out for modem restart to use.
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ 0
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static void loc_eng_agps_reinit(loc_eng_data_s_type &loc_eng_data)
+{
+ ENTRY_LOG();
+
+ // Set server addresses which came before init
+ if (loc_eng_data.supl_host_set)
+ {
+ loc_eng_set_server(loc_eng_data, LOC_AGPS_SUPL_SERVER,
+ loc_eng_data.supl_host_buf,
+ loc_eng_data.supl_port_buf);
+ }
+
+ if (loc_eng_data.c2k_host_set)
+ {
+ loc_eng_set_server(loc_eng_data, LOC_AGPS_CDMA_PDE_SERVER,
+ loc_eng_data.c2k_host_buf,
+ loc_eng_data.c2k_port_buf);
+ }
+ EXIT_LOG(%s, VOID_RET);
+}
+/*===========================================================================
+FUNCTION loc_eng_agps_init
+
+DESCRIPTION
+ Initialize the AGps interface.
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ 0
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+void loc_eng_agps_init(loc_eng_data_s_type &loc_eng_data, AGpsExtCallbacks* callbacks)
+{
+ ENTRY_LOG_CALLFLOW();
+ INIT_CHECK(loc_eng_data.adapter, return);
+ STATE_CHECK((NULL == loc_eng_data.agps_status_cb),
+ "agps instance already initialized",
+ return);
+ if (callbacks == NULL) {
+ LOC_LOGE("loc_eng_agps_init: bad parameters cb %p", callbacks);
+ EXIT_LOG(%s, VOID_RET);
+ return;
+ }
+ LocEngAdapter* adapter = loc_eng_data.adapter;
+ loc_eng_data.agps_status_cb = callbacks->status_cb;
+
+ loc_eng_data.internet_nif = new AgpsStateMachine(servicerTypeAgps,
+ (void *)loc_eng_data.agps_status_cb,
+ AGPS_TYPE_WWAN_ANY,
+ false);
+ loc_eng_data.wifi_nif = new AgpsStateMachine(servicerTypeAgps,
+ (void *)loc_eng_data.agps_status_cb,
+ AGPS_TYPE_WIFI,
+ true);
+
+ int gnssType = getTargetGnssType(loc_get_target());
+ bool isAPQ = (gnssType == GNSS_GSS);
+ bool is1530 = (gnssType == GNSS_QCA1530);
+ if (!isAPQ && !is1530) {
+ loc_eng_data.agnss_nif = new AgpsStateMachine(servicerTypeAgps,
+ (void *)loc_eng_data.agps_status_cb,
+ AGPS_TYPE_SUPL,
+ false);
+
+ if (adapter->mSupportsAgpsRequests) {
+ loc_eng_data.adapter->sendMsg(new LocEngDataClientInit(&loc_eng_data));
+
+ loc_eng_dmn_conn_loc_api_server_launch(callbacks->create_thread_cb,
+ NULL, NULL, &loc_eng_data);
+ }
+ loc_eng_agps_reinit(loc_eng_data);
+ }
+
+ EXIT_LOG(%s, VOID_RET);
+}
+
+static void deleteAidingData(loc_eng_data_s_type &logEng) {
+ if (logEng.engine_status != GPS_STATUS_ENGINE_ON &&
+ logEng.aiding_data_for_deletion != 0) {
+ logEng.adapter->deleteAidingData(logEng.aiding_data_for_deletion);
+ logEng.aiding_data_for_deletion = 0;
+ }
+}
+
+static AgpsStateMachine*
+getAgpsStateMachine(loc_eng_data_s_type &locEng, AGpsExtType agpsType) {
+ AgpsStateMachine* stateMachine;
+ switch (agpsType) {
+ case AGPS_TYPE_WIFI: {
+ stateMachine = locEng.wifi_nif;
+ break;
+ }
+ case AGPS_TYPE_INVALID:
+ case AGPS_TYPE_SUPL: {
+ stateMachine = locEng.agnss_nif;
+ break;
+ }
+ case AGPS_TYPE_SUPL_ES: {
+ stateMachine = locEng.ds_nif;
+ break;
+ }
+ default:
+ stateMachine = locEng.internet_nif;
+ }
+ return stateMachine;
+}
+
+/*===========================================================================
+FUNCTION loc_eng_agps_open
+
+DESCRIPTION
+ This function is called when on-demand data connection opening is successful.
+It should inform engine about the data open result.
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ 0
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_agps_open(loc_eng_data_s_type &loc_eng_data, AGpsExtType agpsType,
+ const char* apn, AGpsBearerType bearerType)
+{
+ ENTRY_LOG_CALLFLOW();
+ INIT_CHECK(loc_eng_data.adapter && loc_eng_data.agps_status_cb,
+ return -1);
+
+ if (apn == NULL)
+ {
+ LOC_LOGE("APN Name NULL\n");
+ return 0;
+ }
+
+ LOC_LOGD("loc_eng_agps_open APN name = [%s]", apn);
+
+ int apn_len = smaller_of(strlen (apn), MAX_APN_LEN);
+ AgpsStateMachine* sm = getAgpsStateMachine(loc_eng_data, agpsType);
+
+ loc_eng_data.adapter->sendMsg(
+ new LocEngAtlOpenSuccess(sm, apn, apn_len, bearerType));
+
+ EXIT_LOG(%d, 0);
+ return 0;
+}
+
+/*===========================================================================
+FUNCTION loc_eng_agps_closed
+
+DESCRIPTION
+ This function is called when on-demand data connection closing is done.
+It should inform engine about the data close result.
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ 0
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_agps_closed(loc_eng_data_s_type &loc_eng_data, AGpsExtType agpsType)
+{
+ ENTRY_LOG_CALLFLOW();
+ INIT_CHECK(loc_eng_data.adapter && loc_eng_data.agps_status_cb,
+ return -1);
+
+ AgpsStateMachine* sm = getAgpsStateMachine(loc_eng_data, agpsType);
+ loc_eng_data.adapter->sendMsg(new LocEngAtlClosed(sm));
+
+ EXIT_LOG(%d, 0);
+ return 0;
+}
+
+/*===========================================================================
+FUNCTION loc_eng_agps_open_failed
+
+DESCRIPTION
+ This function is called when on-demand data connection opening has failed.
+It should inform engine about the data open result.
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ 0
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_agps_open_failed(loc_eng_data_s_type &loc_eng_data, AGpsExtType agpsType)
+{
+ ENTRY_LOG_CALLFLOW();
+ INIT_CHECK(loc_eng_data.adapter && loc_eng_data.agps_status_cb,
+ return -1);
+
+ AgpsStateMachine* sm = getAgpsStateMachine(loc_eng_data, agpsType);
+ loc_eng_data.adapter->sendMsg(new LocEngAtlOpenFailed(sm));
+
+ EXIT_LOG(%d, 0);
+ return 0;
+}
+
+/*===========================================================================
+
+FUNCTION resolve_in_addr
+
+DESCRIPTION
+ Translates a hostname to in_addr struct
+
+DEPENDENCIES
+ n/a
+
+RETURN VALUE
+ TRUE if successful
+
+SIDE EFFECTS
+ n/a
+
+===========================================================================*/
+static boolean resolve_in_addr(const char *host_addr, struct in_addr *in_addr_ptr)
+{
+ ENTRY_LOG();
+ boolean ret_val = TRUE;
+
+ struct hostent *hp;
+ hp = gethostbyname(host_addr);
+ if (hp != NULL) /* DNS OK */
+ {
+ memcpy(in_addr_ptr, hp->h_addr_list[0], hp->h_length);
+ }
+ else
+ {
+ /* Try IP representation */
+ if (inet_aton(host_addr, in_addr_ptr) == 0)
+ {
+ /* IP not valid */
+ LOC_LOGE("DNS query on '%s' failed\n", host_addr);
+ ret_val = FALSE;
+ }
+ }
+
+ EXIT_LOG(%s, loc_logger_boolStr[ret_val!=0]);
+ return ret_val;
+}
+
+/*===========================================================================
+FUNCTION loc_eng_set_server
+
+DESCRIPTION
+ This is used to set the default AGPS server. Server address is obtained
+ from gps.conf.
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ 0
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static int loc_eng_set_server(loc_eng_data_s_type &loc_eng_data,
+ LocServerType type, const char* hostname, int port)
+{
+ ENTRY_LOG();
+ int ret = 0;
+ LocEngAdapter* adapter = loc_eng_data.adapter;
+
+ if (LOC_AGPS_SUPL_SERVER == type) {
+ char url[MAX_URL_LEN];
+ unsigned int len = snprintf(url, sizeof(url), "%s:%u", hostname, (unsigned) port);
+
+ if (sizeof(url) > len) {
+ adapter->sendMsg(new LocEngSetServerUrl(adapter, url, len));
+ }
+ } else if (LOC_AGPS_CDMA_PDE_SERVER == type ||
+ LOC_AGPS_CUSTOM_PDE_SERVER == type ||
+ LOC_AGPS_MPC_SERVER == type) {
+ struct in_addr addr;
+ if (!resolve_in_addr(hostname, &addr))
+ {
+ LOC_LOGE("loc_eng_set_server, hostname %s cannot be resolved.\n", hostname);
+ ret = -2;
+ } else {
+ unsigned int ip = htonl(addr.s_addr);
+ adapter->sendMsg(new LocEngSetServerIpv4(adapter, ip, port, type));
+ }
+ } else {
+ LOC_LOGE("loc_eng_set_server, type %d cannot be resolved.\n", type);
+ }
+
+ EXIT_LOG(%d, ret);
+ return ret;
+}
+
+/*===========================================================================
+FUNCTION loc_eng_set_server_proxy
+
+DESCRIPTION
+ If loc_eng_set_server is called before loc_eng_init, it doesn't work. This
+ proxy buffers server settings and calls loc_eng_set_server when the client is
+ open.
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ 0
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_set_server_proxy(loc_eng_data_s_type &loc_eng_data,
+ LocServerType type,
+ const char* hostname, int port)
+{
+ ENTRY_LOG_CALLFLOW();
+ int ret_val = 0;
+
+ if (NULL != loc_eng_data.adapter)
+ {
+ ret_val = loc_eng_set_server(loc_eng_data, type, hostname, port);
+ } else {
+ LOC_LOGW("set_server called before init. save the address, type: %d, hostname: %s, port: %d",
+ (int) type, hostname, port);
+ switch (type)
+ {
+ case LOC_AGPS_SUPL_SERVER:
+ strlcpy(loc_eng_data.supl_host_buf, hostname,
+ sizeof(loc_eng_data.supl_host_buf));
+ loc_eng_data.supl_port_buf = port;
+ loc_eng_data.supl_host_set = 1;
+ break;
+ case LOC_AGPS_CDMA_PDE_SERVER:
+ strlcpy(loc_eng_data.c2k_host_buf, hostname,
+ sizeof(loc_eng_data.c2k_host_buf));
+ loc_eng_data.c2k_port_buf = port;
+ loc_eng_data.c2k_host_set = 1;
+ break;
+ default:
+ LOC_LOGE("loc_eng_set_server_proxy, unknown server type = %d", (int) type);
+ }
+ }
+
+ EXIT_LOG(%d, ret_val);
+ return ret_val;
+}
+
+/*===========================================================================
+FUNCTION loc_eng_agps_ril_update_network_availability
+
+DESCRIPTION
+ Sets data call allow vs disallow flag to modem
+ This is the only member of sLocEngAGpsRilInterface implemented.
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0: success
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+void loc_eng_agps_ril_update_network_availability(loc_eng_data_s_type &loc_eng_data,
+ int available, const char* apn)
+{
+ ENTRY_LOG_CALLFLOW();
+
+ //This is to store the status of data availability over the network.
+ //If GPS is not enabled, the INIT_CHECK will fail and the modem will
+ //not be updated with the network's availability. Since the data status
+ //can change before GPS is enabled the, storing the status will enable
+ //us to inform the modem after GPS is enabled
+ agpsStatus = available;
+
+ INIT_CHECK(loc_eng_data.adapter, return);
+ if (apn != NULL)
+ {
+ LOC_LOGD("loc_eng_agps_ril_update_network_availability: APN Name = [%s]\n", apn);
+ int apn_len = smaller_of(strlen (apn), MAX_APN_LEN);
+ LocEngAdapter* adapter = loc_eng_data.adapter;
+ adapter->sendMsg(new LocEngEnableData(adapter, apn, apn_len, available));
+ }
+ EXIT_LOG(%s, VOID_RET);
+}
+
+/*===========================================================================
+FUNCTION loc_eng_report_status
+
+DESCRIPTION
+ Reports GPS engine state to Java layer.
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ N/A
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static void loc_eng_report_status (loc_eng_data_s_type &loc_eng_data, GpsStatusValue status)
+{
+ ENTRY_LOG();
+ // Switch from WAIT to MUTE, for "engine on" or "session begin" event
+ if (status == GPS_STATUS_SESSION_BEGIN || status == GPS_STATUS_ENGINE_ON)
+ {
+ if (loc_eng_data.mute_session_state == LOC_MUTE_SESS_WAIT)
+ {
+ LOC_LOGD("loc_eng_report_status: mute_session_state changed from WAIT to IN SESSION");
+ loc_eng_data.mute_session_state = LOC_MUTE_SESS_IN_SESSION;
+ }
+ }
+
+ // Switch off MUTE session
+ if (loc_eng_data.mute_session_state == LOC_MUTE_SESS_IN_SESSION &&
+ (status == GPS_STATUS_SESSION_END || status == GPS_STATUS_ENGINE_OFF))
+ {
+ LOC_LOGD("loc_eng_report_status: mute_session_state changed from IN SESSION to NONE");
+ loc_eng_data.mute_session_state = LOC_MUTE_SESS_NONE;
+ }
+
+ // Session End is not reported during Android navigating state
+ boolean navigating = loc_eng_data.adapter->isInSession();
+ if (status != GPS_STATUS_NONE &&
+ !(status == GPS_STATUS_SESSION_END && navigating) &&
+ !(status == GPS_STATUS_SESSION_BEGIN && !navigating))
+ {
+ if (loc_eng_data.mute_session_state != LOC_MUTE_SESS_IN_SESSION)
+ {
+ // Inform GpsLocationProvider about mNavigating status
+ loc_inform_gps_status(loc_eng_data, status);
+ }
+ else {
+ LOC_LOGD("loc_eng_report_status: muting the status report.");
+ }
+ }
+
+ // Only keeps ENGINE ON/OFF in engine_status
+ if (status == GPS_STATUS_ENGINE_ON || status == GPS_STATUS_ENGINE_OFF)
+ {
+ loc_eng_data.engine_status = status;
+ }
+
+ // Only keeps SESSION BEGIN/END in fix_session_status
+ if (status == GPS_STATUS_SESSION_BEGIN || status == GPS_STATUS_SESSION_END)
+ {
+ loc_eng_data.fix_session_status = status;
+ }
+ EXIT_LOG(%s, VOID_RET);
+}
+
+/*===========================================================================
+FUNCTION loc_eng_handle_engine_down
+ loc_eng_handle_engine_up
+
+DESCRIPTION
+ Calls this function when it is detected that modem restart is happening.
+ Either we detected the modem is down or received modem up event.
+ This must be called from the deferred thread to avoid race condition.
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ None
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+void loc_eng_handle_engine_down(loc_eng_data_s_type &loc_eng_data)
+{
+ ENTRY_LOG();
+ loc_eng_ni_reset_on_engine_restart(loc_eng_data);
+ loc_eng_report_status(loc_eng_data, GPS_STATUS_ENGINE_OFF);
+ EXIT_LOG(%s, VOID_RET);
+}
+
+void loc_eng_handle_engine_up(loc_eng_data_s_type &loc_eng_data)
+{
+ ENTRY_LOG();
+ loc_eng_reinit(loc_eng_data);
+
+ if (loc_eng_data.agps_status_cb != NULL) {
+ if (loc_eng_data.agnss_nif)
+ loc_eng_data.agnss_nif->dropAllSubscribers();
+ if (loc_eng_data.internet_nif)
+ loc_eng_data.internet_nif->dropAllSubscribers();
+
+ loc_eng_agps_reinit(loc_eng_data);
+ }
+
+ loc_eng_report_status(loc_eng_data, GPS_STATUS_ENGINE_ON);
+
+ // modem is back up. If we crashed in the middle of navigating, we restart.
+ if (loc_eng_data.adapter->isInSession()) {
+ // This sets the copy in adapter to modem
+ loc_eng_data.adapter->setPositionMode(NULL);
+ loc_eng_data.adapter->setInSession(false);
+ loc_eng_start_handler(loc_eng_data);
+ }
+ EXIT_LOG(%s, VOID_RET);
+}
+
+#ifdef USE_GLIB
+/*===========================================================================
+FUNCTION set_sched_policy
+
+DESCRIPTION
+ Local copy of this function which bypasses android set_sched_policy
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static int set_sched_policy(int tid, SchedPolicy policy)
+{
+ return 0;
+}
+#endif /* USE_GLIB */
+
+/*===========================================================================
+FUNCTION loc_eng_read_config
+
+DESCRIPTION
+ Initiates the reading of the gps config file stored in /etc dir
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0: success
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_read_config(void)
+{
+ ENTRY_LOG_CALLFLOW();
+ if(configAlreadyRead == false)
+ {
+ // Initialize our defaults before reading of configuration file overwrites them.
+ loc_default_parameters();
+ // We only want to parse the conf file once. This is a good place to ensure that.
+ // In fact one day the conf file should go into context.
+ UTIL_READ_CONF(GPS_CONF_FILE, loc_parameter_table);
+ UTIL_READ_CONF(SAP_CONF_FILE, loc_parameter_table);
+ configAlreadyRead = true;
+ } else {
+ LOC_LOGV("GPS Config file has already been read\n");
+ }
+
+ EXIT_LOG(%d, 0);
+ return 0;
+}
diff --git a/gps/loc_api/libloc_api_50001/loc_eng.h b/gps/loc_api/libloc_api_50001/loc_eng.h
new file mode 100644
index 0000000..d5560b7
--- /dev/null
+++ b/gps/loc_api/libloc_api_50001/loc_eng.h
@@ -0,0 +1,243 @@
+/* Copyright (c) 2009-2014, 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_H
+#define LOC_ENG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+// Uncomment to keep all LOG messages (LOGD, LOGI, LOGV, etc.)
+#define MAX_NUM_ATL_CONNECTIONS 2
+
+// Define boolean type to be used by libgps on loc api module
+typedef unsigned char boolean;
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#include <loc.h>
+#include <loc_eng_xtra.h>
+#include <loc_eng_ni.h>
+#include <loc_eng_agps.h>
+#include <loc_cfg.h>
+#include <loc_log.h>
+#include <log_util.h>
+#include <loc_eng_agps.h>
+#include <LocEngAdapter.h>
+
+// The data connection minimal open time
+#define DATA_OPEN_MIN_TIME 1 /* sec */
+
+// The system sees GPS engine turns off after inactive for this period of time
+#define GPS_AUTO_OFF_TIME 2 /* secs */
+#define SUCCESS TRUE
+#define FAILURE FALSE
+#define INVALID_ATL_CONNECTION_HANDLE -1
+
+#define MAX_XTRA_SERVER_URL_LENGTH 256
+
+enum loc_nmea_provider_e_type {
+ NMEA_PROVIDER_AP = 0, // Application Processor Provider of NMEA
+ NMEA_PROVIDER_MP // Modem Processor Provider of NMEA
+};
+
+enum loc_mute_session_e_type {
+ LOC_MUTE_SESS_NONE = 0,
+ LOC_MUTE_SESS_WAIT,
+ LOC_MUTE_SESS_IN_SESSION
+};
+
+// Module data
+typedef struct loc_eng_data_s
+{
+ LocEngAdapter *adapter;
+ loc_location_cb_ext location_cb;
+ gps_status_callback status_cb;
+ loc_sv_status_cb_ext sv_status_cb;
+ agps_status_extended agps_status_cb;
+ gps_nmea_callback nmea_cb;
+ gps_ni_notify_callback ni_notify_cb;
+ gps_acquire_wakelock acquire_wakelock_cb;
+ gps_release_wakelock release_wakelock_cb;
+ gps_request_utc_time request_utc_time_cb;
+ boolean intermediateFix;
+ AGpsStatusValue agps_status;
+ loc_eng_xtra_data_s_type xtra_module_data;
+ loc_eng_ni_data_s_type loc_eng_ni_data;
+
+ // AGPS state machines
+ AgpsStateMachine* agnss_nif;
+ AgpsStateMachine* internet_nif;
+ AgpsStateMachine* wifi_nif;
+ //State machine for Data Services
+ AgpsStateMachine* ds_nif;
+
+ // GPS engine status
+ GpsStatusValue engine_status;
+ GpsStatusValue fix_session_status;
+
+ // Aiding data information to be deleted, aiding data can only be deleted when GPS engine is off
+ GpsAidingData aiding_data_for_deletion;
+
+ // For muting session broadcast
+ loc_mute_session_e_type mute_session_state;
+
+ // For nmea generation
+ boolean generateNmea;
+ uint32_t sv_used_mask;
+ float hdop;
+ float pdop;
+ float vdop;
+
+ // Address buffers, for addressing setting before init
+ int supl_host_set;
+ char supl_host_buf[101];
+ int supl_port_buf;
+ int c2k_host_set;
+ char c2k_host_buf[101];
+ int c2k_port_buf;
+ int mpc_host_set;
+ char mpc_host_buf[101];
+ int mpc_port_buf;
+
+ loc_ext_parser location_ext_parser;
+ loc_ext_parser sv_ext_parser;
+} loc_eng_data_s_type;
+
+/* GPS.conf support */
+typedef struct loc_gps_cfg_s
+{
+ unsigned long INTERMEDIATE_POS;
+ unsigned long ACCURACY_THRES;
+ unsigned long SUPL_VER;
+ unsigned long CAPABILITIES;
+ unsigned long QUIPC_ENABLED;
+ unsigned long LPP_PROFILE;
+ uint8_t NMEA_PROVIDER;
+ unsigned long A_GLONASS_POS_PROTOCOL_SELECT;
+ unsigned long 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];
+} loc_gps_cfg_s_type;
+
+typedef struct
+{
+ uint8_t GYRO_BIAS_RANDOM_WALK_VALID;
+ double GYRO_BIAS_RANDOM_WALK;
+ unsigned long SENSOR_ACCEL_BATCHES_PER_SEC;
+ unsigned long SENSOR_ACCEL_SAMPLES_PER_BATCH;
+ unsigned long SENSOR_GYRO_BATCHES_PER_SEC;
+ unsigned long SENSOR_GYRO_SAMPLES_PER_BATCH;
+ unsigned long SENSOR_ACCEL_BATCHES_PER_SEC_HIGH;
+ unsigned long SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH;
+ unsigned long SENSOR_GYRO_BATCHES_PER_SEC_HIGH;
+ unsigned long SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH;
+ unsigned long SENSOR_CONTROL_MODE;
+ unsigned long SENSOR_USAGE;
+ unsigned long 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;
+ unsigned long SENSOR_PROVIDER;
+} loc_sap_cfg_s_type;
+
+extern loc_gps_cfg_s_type gps_conf;
+extern loc_sap_cfg_s_type sap_conf;
+
+//loc_eng functions
+int loc_eng_init(loc_eng_data_s_type &loc_eng_data,
+ LocCallbacks* callbacks,
+ LOC_API_ADAPTER_EVENT_MASK_T event,
+ ContextBase* context);
+int loc_eng_start(loc_eng_data_s_type &loc_eng_data);
+int loc_eng_stop(loc_eng_data_s_type &loc_eng_data);
+void loc_eng_cleanup(loc_eng_data_s_type &loc_eng_data);
+int loc_eng_inject_time(loc_eng_data_s_type &loc_eng_data,
+ GpsUtcTime time, int64_t timeReference,
+ int uncertainty);
+int loc_eng_inject_location(loc_eng_data_s_type &loc_eng_data,
+ double latitude, double longitude,
+ float accuracy);
+void loc_eng_delete_aiding_data(loc_eng_data_s_type &loc_eng_data,
+ GpsAidingData f);
+int loc_eng_set_position_mode(loc_eng_data_s_type &loc_eng_data,
+ LocPosMode &params);
+const void* loc_eng_get_extension(loc_eng_data_s_type &loc_eng_data,
+ const char* name);
+int loc_eng_set_server_proxy(loc_eng_data_s_type &loc_eng_data,
+ LocServerType type, const char *hostname, int port);
+void loc_eng_mute_one_session(loc_eng_data_s_type &loc_eng_data);
+int loc_eng_read_config(void);
+
+//loc_eng_agps functions
+void loc_eng_agps_init(loc_eng_data_s_type &loc_eng_data,
+ AGpsExtCallbacks* callbacks);
+int loc_eng_agps_open(loc_eng_data_s_type &loc_eng_data, AGpsExtType agpsType,
+ const char* apn, AGpsBearerType bearerType);
+int loc_eng_agps_closed(loc_eng_data_s_type &loc_eng_data, AGpsExtType agpsType);
+int loc_eng_agps_open_failed(loc_eng_data_s_type &loc_eng_data, AGpsExtType agpsType);
+
+void loc_eng_agps_ril_update_network_availability(loc_eng_data_s_type &loc_eng_data,
+ int avaiable, const char* apn);
+
+//loc_eng_xtra functions
+int loc_eng_xtra_init (loc_eng_data_s_type &loc_eng_data,
+ GpsXtraExtCallbacks* callbacks);
+int loc_eng_xtra_inject_data(loc_eng_data_s_type &loc_eng_data,
+ char* data, int length);
+int loc_eng_xtra_request_server(loc_eng_data_s_type &loc_eng_data);
+void loc_eng_xtra_version_check(loc_eng_data_s_type &loc_eng_data, int check);
+
+//loc_eng_ni functions
+extern void loc_eng_ni_init(loc_eng_data_s_type &loc_eng_data,
+ GpsNiExtCallbacks *callbacks);
+extern void loc_eng_ni_respond(loc_eng_data_s_type &loc_eng_data,
+ int notif_id, GpsUserResponseType user_response);
+extern void loc_eng_ni_request_handler(loc_eng_data_s_type &loc_eng_data,
+ const GpsNiNotification *notif,
+ const void* passThrough);
+extern void loc_eng_ni_reset_on_engine_restart(loc_eng_data_s_type &loc_eng_data);
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif // LOC_ENG_H
diff --git a/gps/loc_api/libloc_api_50001/loc_eng_agps.cpp b/gps/loc_api/libloc_api_50001/loc_eng_agps.cpp
new file mode 100644
index 0000000..d6cc136
--- /dev/null
+++ b/gps/loc_api/libloc_api_50001/loc_eng_agps.cpp
@@ -0,0 +1,970 @@
+/* Copyright (c) 2011-2013, 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_eng"
+
+#include <loc_eng_agps.h>
+#include <loc_eng_log.h>
+#include <log_util.h>
+#include <platform_lib_includes.h>
+#include <loc_eng_dmn_conn_handler.h>
+#include <loc_eng_dmn_conn.h>
+#include <sys/time.h>
+
+//======================================================================
+// C callbacks
+//======================================================================
+
+// This is given to linked_list_add as the dealloc callback
+// data -- an instance of Subscriber
+static void deleteObj(void* data)
+{
+ delete (Subscriber*)data;
+}
+
+// This is given to linked_list_search() as the comparison callback
+// when the state manchine needs to process for particular subscriber
+// fromCaller -- caller provides this obj
+// fromList -- linked_list_search() function take this one from list
+static bool hasSubscriber(void* fromCaller, void* fromList)
+{
+ Notification* notification = (Notification*)fromCaller;
+ Subscriber* s1 = (Subscriber*)fromList;
+
+ return s1->forMe(*notification);
+}
+
+// This is gvien to linked_list_search() to notify subscriber objs
+// when the state machine needs to inform all subscribers of resource
+// status changes, e.g. when resource is GRANTED.
+// fromCaller -- caller provides this ptr to a Notification obj.
+// fromList -- linked_list_search() function take this one from list
+static bool notifySubscriber(void* fromCaller, void* fromList)
+{
+ Notification* notification = (Notification*)fromCaller;
+ Subscriber* s1 = (Subscriber*)fromList;
+
+ // we notify every subscriber indiscriminatively
+ // each subscriber decides if this notification is interesting.
+ return s1->notifyRsrcStatus(*notification) &&
+ // if we do not want to delete the subscriber from the
+ // the list, we must set this to false so this function
+ // returns false
+ notification->postNotifyDelete;
+}
+
+//======================================================================
+// Notification
+//======================================================================
+const int Notification::BROADCAST_ALL = 0x80000000;
+const int Notification::BROADCAST_ACTIVE = 0x80000001;
+const int Notification::BROADCAST_INACTIVE = 0x80000002;
+const unsigned char DSStateMachine::MAX_START_DATA_CALL_RETRIES = 4;
+const unsigned int DSStateMachine::DATA_CALL_RETRY_DELAY_MSEC = 500;
+//======================================================================
+// Subscriber: BITSubscriber / ATLSubscriber / WIFISubscriber
+//======================================================================
+bool Subscriber::forMe(Notification &notification)
+{
+ if (NULL != notification.rcver) {
+ return equals(notification.rcver);
+ } else {
+ return Notification::BROADCAST_ALL == notification.groupID ||
+ (Notification::BROADCAST_ACTIVE == notification.groupID &&
+ !isInactive()) ||
+ (Notification::BROADCAST_INACTIVE == notification.groupID &&
+ isInactive());
+ }
+}
+bool BITSubscriber::equals(const Subscriber *s) const
+{
+ BITSubscriber* bitS = (BITSubscriber*)s;
+
+ return (ID == bitS->ID &&
+ (INADDR_NONE != (unsigned int)ID ||
+ 0 == strncmp(mIPv6Addr, bitS->mIPv6Addr, sizeof(mIPv6Addr))));
+}
+
+bool BITSubscriber::notifyRsrcStatus(Notification &notification)
+{
+ bool notify = forMe(notification);
+
+ if (notify) {
+ switch(notification.rsrcStatus)
+ {
+ case RSRC_UNSUBSCRIBE:
+ case RSRC_RELEASED:
+ loc_eng_dmn_conn_loc_api_server_data_conn(
+ LOC_ENG_IF_REQUEST_SENDER_ID_GPSONE_DAEMON,
+ GPSONE_LOC_API_IF_RELEASE_SUCCESS);
+ break;
+ case RSRC_DENIED:
+ loc_eng_dmn_conn_loc_api_server_data_conn(
+ LOC_ENG_IF_REQUEST_SENDER_ID_GPSONE_DAEMON,
+ GPSONE_LOC_API_IF_FAILURE);
+ break;
+ case RSRC_GRANTED:
+ loc_eng_dmn_conn_loc_api_server_data_conn(
+ LOC_ENG_IF_REQUEST_SENDER_ID_GPSONE_DAEMON,
+ GPSONE_LOC_API_IF_REQUEST_SUCCESS);
+ break;
+ default:
+ notify = false;
+ }
+ }
+
+ return notify;
+}
+
+bool ATLSubscriber::notifyRsrcStatus(Notification &notification)
+{
+ bool notify = forMe(notification);
+
+ if (notify) {
+ switch(notification.rsrcStatus)
+ {
+ case RSRC_UNSUBSCRIBE:
+ case RSRC_RELEASED:
+ ((LocEngAdapter*)mLocAdapter)->atlCloseStatus(ID, 1);
+ break;
+ case RSRC_DENIED:
+ {
+ AGpsExtType type = mBackwardCompatibleMode ?
+ AGPS_TYPE_INVALID : mStateMachine->getType();
+ ((LocEngAdapter*)mLocAdapter)->atlOpenStatus(ID, 0,
+ (char*)mStateMachine->getAPN(),
+ mStateMachine->getBearer(),
+ type);
+ }
+ break;
+ case RSRC_GRANTED:
+ {
+ AGpsExtType type = mBackwardCompatibleMode ?
+ AGPS_TYPE_INVALID : mStateMachine->getType();
+ ((LocEngAdapter*)mLocAdapter)->atlOpenStatus(ID, 1,
+ (char*)mStateMachine->getAPN(),
+ mStateMachine->getBearer(),
+ type);
+ }
+ break;
+ default:
+ notify = false;
+ }
+ }
+
+ return notify;
+}
+
+bool WIFISubscriber::notifyRsrcStatus(Notification &notification)
+{
+ bool notify = forMe(notification);
+
+ if (notify) {
+ switch(notification.rsrcStatus)
+ {
+ case RSRC_UNSUBSCRIBE:
+ break;
+ case RSRC_RELEASED:
+ loc_eng_dmn_conn_loc_api_server_data_conn(
+ senderId,
+ GPSONE_LOC_API_IF_RELEASE_SUCCESS);
+ break;
+ case RSRC_DENIED:
+ loc_eng_dmn_conn_loc_api_server_data_conn(
+ senderId,
+ GPSONE_LOC_API_IF_FAILURE);
+ break;
+ case RSRC_GRANTED:
+ loc_eng_dmn_conn_loc_api_server_data_conn(
+ senderId,
+ GPSONE_LOC_API_IF_REQUEST_SUCCESS);
+ break;
+ default:
+ notify = false;
+ }
+ }
+
+ return notify;
+}
+bool DSSubscriber::notifyRsrcStatus(Notification &notification)
+{
+ bool notify = forMe(notification);
+ LOC_LOGD("DSSubscriber::notifyRsrcStatus. notify:%d \n",(int)(notify));
+ if(notify) {
+ switch(notification.rsrcStatus) {
+ case RSRC_UNSUBSCRIBE:
+ case RSRC_RELEASED:
+ case RSRC_DENIED:
+ case RSRC_GRANTED:
+ ((DSStateMachine *)mStateMachine)->informStatus(notification.rsrcStatus, ID);
+ break;
+ default:
+ notify = false;
+ }
+ }
+ return notify;
+}
+void DSSubscriber :: setInactive()
+{
+ mIsInactive = true;
+ ((DSStateMachine *)mStateMachine)->informStatus(RSRC_UNSUBSCRIBE, ID);
+}
+//======================================================================
+// AgpsState: AgpsReleasedState / AgpsPendingState / AgpsAcquiredState
+//======================================================================
+
+// AgpsReleasedState
+class AgpsReleasedState : public AgpsState
+{
+ friend class AgpsStateMachine;
+
+ inline AgpsReleasedState(AgpsStateMachine* stateMachine) :
+ AgpsState(stateMachine)
+ { mReleasedState = this; }
+
+ inline ~AgpsReleasedState() {}
+public:
+ virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data);
+ inline virtual char* whoami() {return (char*)"AgpsReleasedState";}
+};
+
+AgpsState* AgpsReleasedState::onRsrcEvent(AgpsRsrcStatus event, void* data)
+{
+ LOC_LOGD("AgpsReleasedState::onRsrcEvent; event:%d\n", (int)event);
+ if (mStateMachine->hasSubscribers()) {
+ LOC_LOGE("Error: %s subscriber list not empty!!!", whoami());
+ // I don't know how to recover from it. I am adding this rather
+ // for debugging purpose.
+ }
+
+ AgpsState* nextState = this;
+ switch (event)
+ {
+ case RSRC_SUBSCRIBE:
+ {
+ // no notification until we get RSRC_GRANTED
+ // but we need to add subscriber to the list
+ mStateMachine->addSubscriber((Subscriber*)data);
+ // request from connecivity service for NIF
+ //The if condition 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(!mStateMachine->sendRsrcRequest(GPS_REQUEST_AGPS_DATA_CONN)) {
+ // move the state to PENDING
+ nextState = mPendingState;
+ }
+ }
+ break;
+
+ case RSRC_UNSUBSCRIBE:
+ {
+ // the list should really be empty, nothing to remove.
+ // but we might as well just tell the client it is
+ // unsubscribed. False tolerance, right?
+ Subscriber* subscriber = (Subscriber*) data;
+ Notification notification(subscriber, event, false);
+ subscriber->notifyRsrcStatus(notification);
+ }
+ // break;
+ case RSRC_GRANTED:
+ case RSRC_RELEASED:
+ case RSRC_DENIED:
+ default:
+ LOC_LOGW("%s: unrecognized event %d", whoami(), event);
+ // no state change.
+ break;
+ }
+
+ LOC_LOGD("onRsrcEvent, old state %s, new state %s, event %d",
+ whoami(), nextState->whoami(), event);
+ return nextState;
+}
+
+// AgpsPendingState
+class AgpsPendingState : public AgpsState
+{
+ friend class AgpsStateMachine;
+
+ inline AgpsPendingState(AgpsStateMachine* stateMachine) :
+ AgpsState(stateMachine)
+ { mPendingState = this; }
+
+ inline ~AgpsPendingState() {}
+public:
+ virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data);
+ inline virtual char* whoami() {return (char*)"AgpsPendingState";}
+};
+
+AgpsState* AgpsPendingState::onRsrcEvent(AgpsRsrcStatus event, void* data)
+{
+ AgpsState* nextState = this;;
+ LOC_LOGD("AgpsPendingState::onRsrcEvent; event:%d\n", (int)event);
+ switch (event)
+ {
+ case RSRC_SUBSCRIBE:
+ {
+ // already requested for NIF resource,
+ // do nothing until we get RSRC_GRANTED indication
+ // but we need to add subscriber to the list
+ mStateMachine->addSubscriber((Subscriber*)data);
+ // no state change.
+ }
+ break;
+
+ case RSRC_UNSUBSCRIBE:
+ {
+ Subscriber* subscriber = (Subscriber*) data;
+ if (subscriber->waitForCloseComplete()) {
+ subscriber->setInactive();
+ } else {
+ // auto notify this subscriber of the unsubscribe
+ Notification notification(subscriber, event, true);
+ mStateMachine->notifySubscribers(notification);
+ }
+
+ // now check if there is any subscribers left
+ if (!mStateMachine->hasSubscribers()) {
+ // no more subscribers, move to RELEASED state
+ nextState = mReleasedState;
+
+ // tell connecivity service we can release NIF
+ mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN);
+ } else if (!mStateMachine->hasActiveSubscribers()) {
+ // only inactive subscribers, move to RELEASING state
+ nextState = mReleasingState;
+
+ // tell connecivity service we can release NIF
+ mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN);
+ }
+ }
+ break;
+
+ case RSRC_GRANTED:
+ {
+ nextState = mAcquiredState;
+ Notification notification(Notification::BROADCAST_ACTIVE, event, false);
+ // notify all subscribers NIF resource GRANTED
+ // by setting false, we keep subscribers on the linked list
+ mStateMachine->notifySubscribers(notification);
+ }
+ break;
+
+ case RSRC_RELEASED:
+ // no state change.
+ // we are expecting either GRANTED or DENIED. Handling RELEASED
+ // may like break our state machine in race conditions.
+ break;
+
+ case RSRC_DENIED:
+ {
+ nextState = mReleasedState;
+ Notification notification(Notification::BROADCAST_ALL, event, true);
+ // notify all subscribers NIF resource RELEASED or DENIED
+ // by setting true, we remove subscribers from the linked list
+ mStateMachine->notifySubscribers(notification);
+ }
+ break;
+
+ default:
+ LOC_LOGE("%s: unrecognized event %d", whoami(), event);
+ // no state change.
+ }
+
+ LOC_LOGD("onRsrcEvent, old state %s, new state %s, event %d",
+ whoami(), nextState->whoami(), event);
+ return nextState;
+}
+
+
+class AgpsAcquiredState : public AgpsState
+{
+ friend class AgpsStateMachine;
+
+ inline AgpsAcquiredState(AgpsStateMachine* stateMachine) :
+ AgpsState(stateMachine)
+ { mAcquiredState = this; }
+
+ inline ~AgpsAcquiredState() {}
+public:
+ virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data);
+ inline virtual char* whoami() { return (char*)"AgpsAcquiredState"; }
+};
+
+
+AgpsState* AgpsAcquiredState::onRsrcEvent(AgpsRsrcStatus event, void* data)
+{
+ AgpsState* nextState = this;
+ LOC_LOGD("AgpsAcquiredState::onRsrcEvent; event:%d\n", (int)event);
+ switch (event)
+ {
+ case RSRC_SUBSCRIBE:
+ {
+ // we already have the NIF resource, simply notify subscriber
+ Subscriber* subscriber = (Subscriber*) data;
+ // we have rsrc in hand, so grant it right away
+ Notification notification(subscriber, RSRC_GRANTED, false);
+ subscriber->notifyRsrcStatus(notification);
+ // add subscriber to the list
+ mStateMachine->addSubscriber(subscriber);
+ // no state change.
+ }
+ break;
+
+ case RSRC_UNSUBSCRIBE:
+ {
+ Subscriber* subscriber = (Subscriber*) data;
+ if (subscriber->waitForCloseComplete()) {
+ subscriber->setInactive();
+ } else {
+ // auto notify this subscriber of the unsubscribe
+ Notification notification(subscriber, event, true);
+ mStateMachine->notifySubscribers(notification);
+ }
+
+ // now check if there is any subscribers left
+ if (!mStateMachine->hasSubscribers()) {
+ // no more subscribers, move to RELEASED state
+ nextState = mReleasedState;
+
+ // tell connecivity service we can release NIF
+ mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN);
+ } else if (!mStateMachine->hasActiveSubscribers()) {
+ // only inactive subscribers, move to RELEASING state
+ nextState = mReleasingState;
+
+ // tell connecivity service we can release NIF
+ mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN);
+ }
+ }
+ break;
+
+ case RSRC_GRANTED:
+ LOC_LOGW("%s: %d, RSRC_GRANTED already received", whoami(), event);
+ // no state change.
+ break;
+
+ case RSRC_RELEASED:
+ {
+ LOC_LOGW("%s: %d, a force rsrc release", whoami(), event);
+ nextState = mReleasedState;
+ Notification notification(Notification::BROADCAST_ALL, event, true);
+ // by setting true, we remove subscribers from the linked list
+ mStateMachine->notifySubscribers(notification);
+ }
+ break;
+
+ case RSRC_DENIED:
+ // no state change.
+ // we are expecting RELEASED. Handling DENIED
+ // may like break our state machine in race conditions.
+ break;
+
+ default:
+ LOC_LOGE("%s: unrecognized event %d", whoami(), event);
+ // no state change.
+ }
+
+ LOC_LOGD("onRsrcEvent, old state %s, new state %s, event %d",
+ whoami(), nextState->whoami(), event);
+ return nextState;
+}
+
+// AgpsPendingState
+class AgpsReleasingState : public AgpsState
+{
+ friend class AgpsStateMachine;
+
+ inline AgpsReleasingState(AgpsStateMachine* stateMachine) :
+ AgpsState(stateMachine)
+ { mReleasingState = this; }
+
+ inline ~AgpsReleasingState() {}
+public:
+ virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data);
+ inline virtual char* whoami() {return (char*)"AgpsReleasingState";}
+};
+
+AgpsState* AgpsReleasingState::onRsrcEvent(AgpsRsrcStatus event, void* data)
+{
+ AgpsState* nextState = this;;
+ LOC_LOGD("AgpsReleasingState::onRsrcEvent; event:%d\n", (int)event);
+
+ switch (event)
+ {
+ case RSRC_SUBSCRIBE:
+ {
+ // already requested for NIF resource,
+ // do nothing until we get RSRC_GRANTED indication
+ // but we need to add subscriber to the list
+ mStateMachine->addSubscriber((Subscriber*)data);
+ // no state change.
+ }
+ break;
+
+ case RSRC_UNSUBSCRIBE:
+ {
+ Subscriber* subscriber = (Subscriber*) data;
+ if (subscriber->waitForCloseComplete()) {
+ subscriber->setInactive();
+ } else {
+ // auto notify this subscriber of the unsubscribe
+ Notification notification(subscriber, event, true);
+ mStateMachine->notifySubscribers(notification);
+ }
+
+ // now check if there is any subscribers left
+ if (!mStateMachine->hasSubscribers()) {
+ // no more subscribers, move to RELEASED state
+ nextState = mReleasedState;
+ }
+ }
+ break;
+
+ case RSRC_DENIED:
+ // A race condition subscriber unsubscribes before AFW denies resource.
+ case RSRC_RELEASED:
+ {
+ nextState = mAcquiredState;
+ Notification notification(Notification::BROADCAST_INACTIVE, event, true);
+ // notify all subscribers that are active NIF resource RELEASE
+ // by setting false, we keep subscribers on the linked list
+ mStateMachine->notifySubscribers(notification);
+
+ if (mStateMachine->hasActiveSubscribers()) {
+ nextState = mPendingState;
+ // request from connecivity service for NIF
+ mStateMachine->sendRsrcRequest(GPS_REQUEST_AGPS_DATA_CONN);
+ } else {
+ nextState = mReleasedState;
+ }
+ }
+ break;
+
+ case RSRC_GRANTED:
+ default:
+ LOC_LOGE("%s: unrecognized event %d", whoami(), event);
+ // no state change.
+ }
+
+ LOC_LOGD("onRsrcEvent, old state %s, new state %s, event %d",
+ whoami(), nextState->whoami(), event);
+ return nextState;
+}
+//======================================================================
+//Servicer
+//======================================================================
+Servicer* Servicer :: getServicer(servicerType type, void *cb_func)
+{
+ LOC_LOGD(" Enter getServicer type:%d\n", (int)type);
+ switch(type) {
+ case servicerTypeNoCbParam:
+ return (new Servicer(cb_func));
+ case servicerTypeExt:
+ return (new ExtServicer(cb_func));
+ case servicerTypeAgps:
+ return (new AGpsServicer(cb_func));
+ default:
+ return NULL;
+ }
+}
+
+int Servicer :: requestRsrc(void *cb_data)
+{
+ callback();
+ return 0;
+}
+
+int ExtServicer :: requestRsrc(void *cb_data)
+{
+ int ret=-1;
+ LOC_LOGD("Enter ExtServicer :: requestRsrc\n");
+ ret = callbackExt(cb_data);
+ LOC_LOGD("Exit ExtServicer :: requestRsrc\n");
+ return(ret);
+}
+
+int AGpsServicer :: requestRsrc(void *cb_data)
+{
+ callbackAGps((AGpsStatus *)cb_data);
+ return 0;
+}
+
+//======================================================================
+// AgpsStateMachine
+//======================================================================
+
+AgpsStateMachine::AgpsStateMachine(servicerType servType,
+ void *cb_func,
+ AGpsExtType type,
+ bool enforceSingleSubscriber) :
+ mStatePtr(new AgpsReleasedState(this)),mType(type),
+ mAPN(NULL),
+ mAPNLen(0),
+ mBearer(AGPS_APN_BEARER_INVALID),
+ mEnforceSingleSubscriber(enforceSingleSubscriber),
+ mServicer(Servicer :: getServicer(servType, (void *)cb_func))
+{
+ linked_list_init(&mSubscribers);
+
+ // setting up mReleasedState
+ mStatePtr->mPendingState = new AgpsPendingState(this);
+ mStatePtr->mAcquiredState = new AgpsAcquiredState(this);
+ mStatePtr->mReleasingState = new AgpsReleasingState(this);
+
+ // setting up mAcquiredState
+ mStatePtr->mAcquiredState->mReleasedState = mStatePtr;
+ mStatePtr->mAcquiredState->mPendingState = mStatePtr->mPendingState;
+ mStatePtr->mAcquiredState->mReleasingState = mStatePtr->mReleasingState;
+
+ // setting up mPendingState
+ mStatePtr->mPendingState->mAcquiredState = mStatePtr->mAcquiredState;
+ mStatePtr->mPendingState->mReleasedState = mStatePtr;
+ mStatePtr->mPendingState->mReleasingState = mStatePtr->mReleasingState;
+
+ // setting up mReleasingState
+ mStatePtr->mReleasingState->mReleasedState = mStatePtr;
+ mStatePtr->mReleasingState->mPendingState = mStatePtr->mPendingState;
+ mStatePtr->mReleasingState->mAcquiredState = mStatePtr->mAcquiredState;
+}
+
+AgpsStateMachine::~AgpsStateMachine()
+{
+ dropAllSubscribers();
+
+ // free the 3 states. We must read out all 3 pointers first.
+ // Otherwise we run the risk of getting pointers from already
+ // freed memory.
+ AgpsState* acquiredState = mStatePtr->mAcquiredState;
+ AgpsState* releasedState = mStatePtr->mReleasedState;
+ AgpsState* pendindState = mStatePtr->mPendingState;
+ AgpsState* releasingState = mStatePtr->mReleasingState;
+
+ delete acquiredState;
+ delete releasedState;
+ delete pendindState;
+ delete releasingState;
+ delete mServicer;
+ linked_list_destroy(&mSubscribers);
+
+ if (NULL != mAPN) {
+ delete[] mAPN;
+ mAPN = NULL;
+ }
+}
+
+void AgpsStateMachine::setAPN(const char* apn, unsigned int len)
+{
+ if (NULL != mAPN) {
+ delete mAPN;
+ }
+
+ if (NULL != apn) {
+ mAPN = new char[len+1];
+ memcpy(mAPN, apn, len);
+ mAPN[len] = NULL;
+
+ mAPNLen = len;
+ } else {
+ mAPN = NULL;
+ mAPNLen = 0;
+ }
+}
+
+void AgpsStateMachine::onRsrcEvent(AgpsRsrcStatus event)
+{
+ switch (event)
+ {
+ case RSRC_GRANTED:
+ case RSRC_RELEASED:
+ case RSRC_DENIED:
+ mStatePtr = mStatePtr->onRsrcEvent(event, NULL);
+ break;
+ default:
+ LOC_LOGW("AgpsStateMachine: unrecognized event %d", event);
+ break;
+ }
+}
+
+void AgpsStateMachine::notifySubscribers(Notification& notification) const
+{
+ if (notification.postNotifyDelete) {
+ // just any non NULL value to get started
+ Subscriber* s = (Subscriber*)~0;
+ while (NULL != s) {
+ s = NULL;
+ // if the last param sets to true, _search will delete
+ // the node from the list for us. But the problem is
+ // once that is done, _search returns, leaving the
+ // rest of the list unprocessed. So we need a loop.
+ linked_list_search(mSubscribers, (void**)&s, notifySubscriber,
+ (void*)&notification, true);
+ delete s;
+ }
+ } else {
+ // no loop needed if it the last param sets to false, which
+ // mean nothing gets deleted from the list.
+ linked_list_search(mSubscribers, NULL, notifySubscriber,
+ (void*)&notification, false);
+ }
+}
+
+void AgpsStateMachine::addSubscriber(Subscriber* subscriber) const
+{
+ Subscriber* s = NULL;
+ Notification notification((const Subscriber*)subscriber);
+ linked_list_search(mSubscribers, (void**)&s,
+ hasSubscriber, (void*)&notification, false);
+
+ if (NULL == s) {
+ linked_list_add(mSubscribers, subscriber->clone(), deleteObj);
+ }
+}
+
+int AgpsStateMachine::sendRsrcRequest(AGpsStatusValue action) const
+{
+ Subscriber* s = NULL;
+ Notification notification(Notification::BROADCAST_ACTIVE);
+ linked_list_search(mSubscribers, (void**)&s, hasSubscriber,
+ (void*)&notification, false);
+
+ if ((NULL == s) == (GPS_RELEASE_AGPS_DATA_CONN == action)) {
+ AGpsExtStatus nifRequest;
+ nifRequest.size = sizeof(nifRequest);
+ nifRequest.type = mType;
+ nifRequest.status = action;
+
+ if (s == NULL) {
+ nifRequest.ipv4_addr = INADDR_NONE;
+ nifRequest.ipv6_addr[0] = 0;
+ nifRequest.ssid[0] = '\0';
+ nifRequest.password[0] = '\0';
+ } else {
+ s->setIPAddresses(nifRequest.ipv4_addr, (char*)nifRequest.ipv6_addr);
+ s->setWifiInfo(nifRequest.ssid, nifRequest.password);
+ }
+
+ CALLBACK_LOG_CALLFLOW("agps_cb", %s, loc_get_agps_status_name(action));
+ mServicer->requestRsrc((void *)&nifRequest);
+ }
+ return 0;
+}
+
+void AgpsStateMachine::subscribeRsrc(Subscriber *subscriber)
+{
+ if (mEnforceSingleSubscriber && hasSubscribers()) {
+ Notification notification(Notification::BROADCAST_ALL, RSRC_DENIED, true);
+ notifySubscriber(&notification, subscriber);
+ } else {
+ mStatePtr = mStatePtr->onRsrcEvent(RSRC_SUBSCRIBE, (void*)subscriber);
+ }
+}
+
+bool AgpsStateMachine::unsubscribeRsrc(Subscriber *subscriber)
+{
+ Subscriber* s = NULL;
+ Notification notification((const Subscriber*)subscriber);
+ linked_list_search(mSubscribers, (void**)&s,
+ hasSubscriber, (void*)&notification, false);
+
+ if (NULL != s) {
+ mStatePtr = mStatePtr->onRsrcEvent(RSRC_UNSUBSCRIBE, (void*)s);
+ return true;
+ }
+ return false;
+}
+
+bool AgpsStateMachine::hasActiveSubscribers() const
+{
+ Subscriber* s = NULL;
+ Notification notification(Notification::BROADCAST_ACTIVE);
+ linked_list_search(mSubscribers, (void**)&s,
+ hasSubscriber, (void*)&notification, false);
+ return NULL != s;
+}
+
+//======================================================================
+// DSStateMachine
+//======================================================================
+void delay_callback(void *callbackData, int result)
+{
+ if(callbackData) {
+ DSStateMachine *DSSMInstance = (DSStateMachine *)callbackData;
+ DSSMInstance->retryCallback();
+ }
+ else {
+ LOC_LOGE(" NULL argument received. Failing.\n");
+ goto err;
+ }
+err:
+ return;
+}
+
+DSStateMachine :: DSStateMachine(servicerType type, void *cb_func,
+ LocEngAdapter* adapterHandle):
+ AgpsStateMachine(type, cb_func, AGPS_TYPE_INVALID,false),
+ mLocAdapter(adapterHandle)
+{
+ LOC_LOGD("%s:%d]: New DSStateMachine\n", __func__, __LINE__);
+ mRetries = 0;
+}
+
+void DSStateMachine :: retryCallback(void)
+{
+ DSSubscriber *subscriber = NULL;
+ Notification notification(Notification::BROADCAST_ACTIVE);
+ linked_list_search(mSubscribers, (void**)&subscriber, hasSubscriber,
+ (void*)&notification, false);
+ if(subscriber)
+ mLocAdapter->requestSuplES(subscriber->ID);
+ else
+ LOC_LOGE("DSStateMachine :: retryCallback: No subscriber found." \
+ "Cannot retry data call\n");
+ return;
+}
+
+int DSStateMachine :: sendRsrcRequest(AGpsStatusValue action) const
+{
+ DSSubscriber* s = NULL;
+ dsCbData cbData;
+ int ret=-1;
+ int connHandle=-1;
+ LOC_LOGD("Enter DSStateMachine :: sendRsrcRequest\n");
+ Notification notification(Notification::BROADCAST_ACTIVE);
+ linked_list_search(mSubscribers, (void**)&s, hasSubscriber,
+ (void*)&notification, false);
+ if(s) {
+ connHandle = s->ID;
+ LOC_LOGD("DSStateMachine :: sendRsrcRequest - subscriber found\n");
+ }
+ else
+ LOC_LOGD("DSStateMachine :: sendRsrcRequest - No subscriber found\n");
+
+ cbData.action = action;
+ cbData.mAdapter = mLocAdapter;
+ ret = mServicer->requestRsrc((void *)&cbData);
+ //Only the request to start data call returns a success/failure
+ //The request to stop data call will always succeed
+ //Hence, the below block will only be executed when the
+ //request to start the data call fails
+ switch(ret) {
+ case LOC_API_ADAPTER_ERR_ENGINE_BUSY:
+ LOC_LOGD("DSStateMachine :: sendRsrcRequest - Failure returned: %d\n",ret);
+ ((DSStateMachine *)this)->incRetries();
+ if(mRetries > MAX_START_DATA_CALL_RETRIES) {
+ LOC_LOGE(" Failed to start Data call. Fallback to normal ATL SUPL\n");
+ informStatus(RSRC_DENIED, connHandle);
+ }
+ else {
+ if(loc_timer_start(DATA_CALL_RETRY_DELAY_MSEC, delay_callback, (void *)this)) {
+ LOC_LOGE("Error: Could not start delay thread\n");
+ ret = -1;
+ goto err;
+ }
+ }
+ break;
+ case LOC_API_ADAPTER_ERR_UNSUPPORTED:
+ LOC_LOGE("No profile found for emergency call. Fallback to normal SUPL ATL\n");
+ informStatus(RSRC_DENIED, connHandle);
+ break;
+ case LOC_API_ADAPTER_ERR_SUCCESS:
+ LOC_LOGD("%s:%d]: Request to start data call sent\n", __func__, __LINE__);
+ break;
+ case -1:
+ //One of the ways this case can be encountered is if the callback function
+ //receives a null argument, it just exits with -1 error
+ LOC_LOGE("Error: Something went wrong somewhere. Falling back to normal SUPL ATL\n");
+ informStatus(RSRC_DENIED, connHandle);
+ break;
+ default:
+ LOC_LOGE("%s:%d]: Unrecognized return value\n", __func__, __LINE__);
+ }
+err:
+ LOC_LOGD("EXIT DSStateMachine :: sendRsrcRequest; ret = %d\n", ret);
+ return ret;
+}
+
+void DSStateMachine :: onRsrcEvent(AgpsRsrcStatus event)
+{
+ void* currState = (void *)mStatePtr;
+ LOC_LOGD("Enter DSStateMachine :: onRsrcEvent. event = %d\n", (int)event);
+ switch (event)
+ {
+ case RSRC_GRANTED:
+ LOC_LOGD("DSStateMachine :: onRsrcEvent RSRC_GRANTED\n");
+ mStatePtr = mStatePtr->onRsrcEvent(event, NULL);
+ break;
+ case RSRC_RELEASED:
+ LOC_LOGD("DSStateMachine :: onRsrcEvent RSRC_RELEASED\n");
+ mStatePtr = mStatePtr->onRsrcEvent(event, NULL);
+ //To handle the case where we get a RSRC_RELEASED in
+ //pending state, we translate that to a RSRC_DENIED state
+ //since the callback from DSI is either RSRC_GRANTED or RSRC_RELEASED
+ //for when the call is connected or disconnected respectively.
+ if((void *)mStatePtr != currState)
+ break;
+ else {
+ event = RSRC_DENIED;
+ LOC_LOGE(" Switching event to RSRC_DENIED\n");
+ }
+ case RSRC_DENIED:
+ mStatePtr = mStatePtr->onRsrcEvent(event, NULL);
+ break;
+ default:
+ LOC_LOGW("AgpsStateMachine: unrecognized event %d", event);
+ break;
+ }
+ LOC_LOGD("Exit DSStateMachine :: onRsrcEvent. event = %d\n", (int)event);
+}
+
+void DSStateMachine :: informStatus(AgpsRsrcStatus status, int ID) const
+{
+ LOC_LOGD("DSStateMachine :: informStatus. Status=%d\n",(int)status);
+ switch(status) {
+ case RSRC_UNSUBSCRIBE:
+ mLocAdapter->atlCloseStatus(ID, 1);
+ break;
+ case RSRC_RELEASED:
+ mLocAdapter->closeDataCall();
+ break;
+ case RSRC_DENIED:
+ ((DSStateMachine *)this)->mRetries = 0;
+ mLocAdapter->requestATL(ID, AGPS_TYPE_SUPL);
+ break;
+ case RSRC_GRANTED:
+ mLocAdapter->atlOpenStatus(ID, 1,
+ NULL,
+ AGPS_APN_BEARER_INVALID,
+ AGPS_TYPE_INVALID);
+ break;
+ default:
+ LOC_LOGW("DSStateMachine :: informStatus - unknown status");
+ }
+ return;
+}
diff --git a/gps/loc_api/libloc_api_50001/loc_eng_agps.h b/gps/loc_api/libloc_api_50001/loc_eng_agps.h
new file mode 100644
index 0000000..9915a70
--- /dev/null
+++ b/gps/loc_api/libloc_api_50001/loc_eng_agps.h
@@ -0,0 +1,419 @@
+/* Copyright (c) 2011-2013, 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_AGPS_H__
+#define __LOC_ENG_AGPS_H__
+
+#include <stdbool.h>
+#include <ctype.h>
+#include <string.h>
+#include <arpa/inet.h>
+#include "hardware/gps.h"
+#include <gps_extended.h>
+#include <loc_core_log.h>
+#include <linked_list.h>
+#include <loc_timer.h>
+#include <LocEngAdapter.h>
+
+// forward declaration
+class AgpsStateMachine;
+class Subscriber;
+
+// NIF resource events
+typedef enum {
+ RSRC_SUBSCRIBE,
+ RSRC_UNSUBSCRIBE,
+ RSRC_GRANTED,
+ RSRC_RELEASED,
+ RSRC_DENIED,
+ RSRC_STATUS_MAX
+} AgpsRsrcStatus;
+
+typedef enum {
+ servicerTypeNoCbParam,
+ servicerTypeAgps,
+ servicerTypeExt
+}servicerType;
+
+//DS Callback struct
+typedef struct {
+ LocEngAdapter *mAdapter;
+ AGpsStatusValue action;
+}dsCbData;
+
+// information bundle for subscribers
+struct Notification {
+ // goes to every subscriber
+ static const int BROADCAST_ALL;
+ // goes to every ACTIVE subscriber
+ static const int BROADCAST_ACTIVE;
+ // goes to every INACTIVE subscriber
+ static const int BROADCAST_INACTIVE;
+
+ // go to a specific subscriber
+ const Subscriber* rcver;
+ // broadcast
+ const int groupID;
+ // the new resource status event
+ const AgpsRsrcStatus rsrcStatus;
+ // should the subscriber be deleted after the notification
+ const bool postNotifyDelete;
+
+ // convenient constructor
+ inline Notification(const int broadcast,
+ const AgpsRsrcStatus status,
+ const bool deleteAfterwards) :
+ rcver(NULL), groupID(broadcast), rsrcStatus(status),
+ postNotifyDelete(deleteAfterwards) {}
+
+ // convenient constructor
+ inline Notification(const Subscriber* subscriber,
+ const AgpsRsrcStatus status,
+ const bool deleteAfterwards) :
+ rcver(subscriber), groupID(-1), rsrcStatus(status),
+ postNotifyDelete(deleteAfterwards) {}
+
+ // convenient constructor
+ inline Notification(const int broadcast) :
+ rcver(NULL), groupID(broadcast), rsrcStatus(RSRC_STATUS_MAX),
+ postNotifyDelete(false) {}
+
+ // convenient constructor
+ inline Notification(const Subscriber* subscriber) :
+ rcver(subscriber), groupID(-1), rsrcStatus(RSRC_STATUS_MAX),
+ postNotifyDelete(false) {}
+};
+
+class AgpsState {
+ // allows AgpsStateMachine to access private data
+ // no class members are public. We don't want
+ // anyone but state machine to use state.
+ friend class AgpsStateMachine;
+ friend class DSStateMachine;
+ // state transitions are done here.
+ // Each state implements its own transitions (of course).
+ inline virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data) = 0;
+
+protected:
+ // handle back to state machine
+ const AgpsStateMachine* mStateMachine;
+ // each state has pointers to all 3 states
+ // one of which is to itself.
+ AgpsState* mReleasedState;
+ AgpsState* mAcquiredState;
+ AgpsState* mPendingState;
+ AgpsState* mReleasingState;
+
+ inline AgpsState(const AgpsStateMachine *stateMachine) :
+ mStateMachine(stateMachine),
+ mReleasedState(NULL),
+ mAcquiredState(NULL),
+ mPendingState(NULL),
+ mReleasingState(NULL) {}
+ virtual ~AgpsState() {}
+
+public:
+ // for logging purpose
+ inline virtual char* whoami() = 0;
+};
+
+class Servicer {
+ void (*callback)(void);
+public:
+ static Servicer* getServicer(servicerType type, void *cb_func);
+ virtual int requestRsrc(void *cb_data);
+ Servicer() {}
+ Servicer(void *cb_func)
+ { callback = (void(*)(void))(cb_func); }
+ virtual ~Servicer(){}
+ inline virtual char *whoami() {return (char*)"Servicer";}
+};
+
+class ExtServicer : public Servicer {
+ int (*callbackExt)(void *cb_data);
+public:
+ int requestRsrc(void *cb_data);
+ ExtServicer() {}
+ ExtServicer(void *cb_func)
+ { callbackExt = (int(*)(void *))(cb_func); }
+ virtual ~ExtServicer(){}
+ inline virtual char *whoami() {return (char*)"ExtServicer";}
+};
+
+class AGpsServicer : public Servicer {
+ void (*callbackAGps)(AGpsStatus* status);
+public:
+ int requestRsrc(void *cb_data);
+ AGpsServicer() {}
+ AGpsServicer(void *cb_func)
+ { callbackAGps = (void(*)(AGpsStatus *))(cb_func); }
+ virtual ~AGpsServicer(){}
+ inline virtual char *whoami() {return (char*)"AGpsServicer";}
+};
+
+class AgpsStateMachine {
+protected:
+ // a linked list of subscribers.
+ void* mSubscribers;
+ //handle to whoever provides the service
+ Servicer *mServicer;
+ // allows AgpsState to access private data
+ // each state is really internal data to the
+ // state machine, so it should be able to
+ // access anything within the state machine.
+ friend class AgpsState;
+ // pointer to the current state.
+ AgpsState* mStatePtr;
+private:
+ // NIF type: AGNSS or INTERNET.
+ const AGpsExtType mType;
+ // apn to the NIF. Each state machine tracks
+ // resource state of a particular NIF. For each
+ // NIF, there is also an active APN.
+ char* mAPN;
+ // for convenience, we don't do strlen each time.
+ unsigned int mAPNLen;
+ // bear
+ AGpsBearerType mBearer;
+ // ipv4 address for routing
+ bool mEnforceSingleSubscriber;
+
+public:
+ AgpsStateMachine(servicerType servType, void *cb_func,
+ AGpsExtType type, bool enforceSingleSubscriber);
+ virtual ~AgpsStateMachine();
+
+ // self explanatory methods below
+ void setAPN(const char* apn, unsigned int len);
+ inline const char* getAPN() const { return (const char*)mAPN; }
+ inline void setBearer(AGpsBearerType bearer) { mBearer = bearer; }
+ inline AGpsBearerType getBearer() const { return mBearer; }
+ inline AGpsExtType getType() const { return (AGpsExtType)mType; }
+
+ // someone, a ATL client or BIT, is asking for NIF
+ void subscribeRsrc(Subscriber *subscriber);
+
+ // someone, a ATL client or BIT, is done with NIF
+ bool unsubscribeRsrc(Subscriber *subscriber);
+
+ // add a subscriber in the linked list, if not already there.
+ void addSubscriber(Subscriber* subscriber) const;
+
+ virtual void onRsrcEvent(AgpsRsrcStatus event);
+
+ // put the data together and send the FW
+ virtual int sendRsrcRequest(AGpsStatusValue action) const;
+
+ //if list is empty, linked_list_empty returns 1
+ //else if list is not empty, returns 0
+ //so hasSubscribers() returns 1 if list is not empty
+ //and returns 0 if list is empty
+ inline bool hasSubscribers() const
+ { return !linked_list_empty(mSubscribers); }
+
+ bool hasActiveSubscribers() const;
+
+ inline void dropAllSubscribers() const
+ { linked_list_flush(mSubscribers); }
+
+ // private. Only a state gets to call this.
+ void notifySubscribers(Notification& notification) const;
+
+};
+
+class DSStateMachine : public AgpsStateMachine {
+ static const unsigned char MAX_START_DATA_CALL_RETRIES;
+ static const unsigned int DATA_CALL_RETRY_DELAY_MSEC;
+ LocEngAdapter* mLocAdapter;
+ unsigned char mRetries;
+public:
+ DSStateMachine(servicerType type,
+ void *cb_func,
+ LocEngAdapter* adapterHandle);
+ int sendRsrcRequest(AGpsStatusValue action) const;
+ void onRsrcEvent(AgpsRsrcStatus event);
+ void retryCallback();
+ void informStatus(AgpsRsrcStatus status, int ID) const;
+ inline void incRetries() {mRetries++;}
+ inline virtual char *whoami() {return (char*)"DSStateMachine";}
+};
+
+// each subscriber is a AGPS client. In the case of ATL, there could be
+// multiple clients from modem. In the case of BIT, there is only one
+// cilent from BIT daemon.
+struct Subscriber {
+ const uint32_t ID;
+ const AgpsStateMachine* mStateMachine;
+ inline Subscriber(const int id,
+ const AgpsStateMachine* stateMachine) :
+ ID(id), mStateMachine(stateMachine) {}
+ inline virtual ~Subscriber() {}
+
+ virtual void setIPAddresses(uint32_t &v4, char* v6) = 0;
+ inline virtual void setWifiInfo(char* ssid, char* password)
+ { ssid[0] = 0; password[0] = 0; }
+
+ inline virtual bool equals(const Subscriber *s) const
+ { return ID == s->ID; }
+
+ // notifies a subscriber a new NIF resource status, usually
+ // either GRANTE, DENIED, or RELEASED
+ virtual bool notifyRsrcStatus(Notification &notification) = 0;
+
+ virtual bool waitForCloseComplete() { return false; }
+ virtual void setInactive() {}
+ virtual bool isInactive() { return false; }
+
+ virtual Subscriber* clone() = 0;
+ // checks if this notification is for me, i.e.
+ // either has my id, or has a broadcast id.
+ bool forMe(Notification &notification);
+};
+
+// BITSubscriber, created with requests from BIT daemon
+struct BITSubscriber : public Subscriber {
+ char mIPv6Addr[16];
+
+ inline BITSubscriber(const AgpsStateMachine* stateMachine,
+ unsigned int ipv4, char* ipv6) :
+ Subscriber(ipv4, stateMachine)
+ {
+ if (NULL == ipv6) {
+ mIPv6Addr[0] = 0;
+ } else {
+ memcpy(mIPv6Addr, ipv6, sizeof(mIPv6Addr));
+ }
+ }
+
+ virtual bool notifyRsrcStatus(Notification &notification);
+
+ inline virtual void setIPAddresses(uint32_t &v4, char* v6)
+ { v4 = ID; memcpy(v6, mIPv6Addr, sizeof(mIPv6Addr)); }
+
+ virtual Subscriber* clone()
+ {
+ return new BITSubscriber(mStateMachine, ID, mIPv6Addr);
+ }
+
+ virtual bool equals(const Subscriber *s) const;
+ inline virtual ~BITSubscriber(){}
+};
+
+// ATLSubscriber, created with requests from ATL
+struct ATLSubscriber : public Subscriber {
+ const LocEngAdapter* mLocAdapter;
+ const bool mBackwardCompatibleMode;
+ inline ATLSubscriber(const int id,
+ const AgpsStateMachine* stateMachine,
+ const LocEngAdapter* adapter,
+ const bool compatibleMode) :
+ Subscriber(id, stateMachine), mLocAdapter(adapter),
+ mBackwardCompatibleMode(compatibleMode){}
+ virtual bool notifyRsrcStatus(Notification &notification);
+
+ inline virtual void setIPAddresses(uint32_t &v4, char* v6)
+ { v4 = INADDR_NONE; v6[0] = 0; }
+
+ inline virtual Subscriber* clone()
+ {
+ return new ATLSubscriber(ID, mStateMachine, mLocAdapter,
+ mBackwardCompatibleMode);
+ }
+ inline virtual ~ATLSubscriber(){}
+};
+
+// WIFISubscriber, created with requests from MSAPM or QuIPC
+struct WIFISubscriber : public Subscriber {
+ char * mSSID;
+ char * mPassword;
+ loc_if_req_sender_id_e_type senderId;
+ bool mIsInactive;
+ inline WIFISubscriber(const AgpsStateMachine* stateMachine,
+ char * ssid, char * password, loc_if_req_sender_id_e_type sender_id) :
+ Subscriber(sender_id, stateMachine),
+ mSSID(NULL == ssid ? NULL : new char[SSID_BUF_SIZE]),
+ mPassword(NULL == password ? NULL : new char[SSID_BUF_SIZE]),
+ senderId(sender_id)
+ {
+ if (NULL != mSSID)
+ strlcpy(mSSID, ssid, SSID_BUF_SIZE);
+ if (NULL != mPassword)
+ strlcpy(mPassword, password, SSID_BUF_SIZE);
+ mIsInactive = false;
+ }
+
+ virtual bool notifyRsrcStatus(Notification &notification);
+
+ inline virtual void setIPAddresses(uint32_t &v4, char* v6) {}
+
+ inline virtual void setWifiInfo(char* ssid, char* password)
+ {
+ if (NULL != mSSID)
+ strlcpy(ssid, mSSID, SSID_BUF_SIZE);
+ else
+ ssid[0] = '\0';
+ if (NULL != mPassword)
+ strlcpy(password, mPassword, SSID_BUF_SIZE);
+ else
+ password[0] = '\0';
+ }
+
+ inline virtual bool waitForCloseComplete() { return true; }
+
+ inline virtual void setInactive() { mIsInactive = true; }
+ inline virtual bool isInactive() { return mIsInactive; }
+
+ virtual Subscriber* clone()
+ {
+ return new WIFISubscriber(mStateMachine, mSSID, mPassword, senderId);
+ }
+ inline virtual ~WIFISubscriber(){}
+};
+
+struct DSSubscriber : public Subscriber {
+ bool mIsInactive;
+ inline DSSubscriber(const AgpsStateMachine *stateMachine,
+ const int id) :
+ Subscriber(id, stateMachine)
+ {
+ mIsInactive = false;
+ }
+ inline virtual void setIPAddresses(uint32_t &v4, char* v6) {}
+ virtual Subscriber* clone()
+ {return new DSSubscriber(mStateMachine, ID);}
+ virtual bool notifyRsrcStatus(Notification &notification);
+ inline virtual bool waitForCloseComplete() { return true; }
+ virtual void setInactive();
+ inline virtual bool isInactive()
+ { return mIsInactive; }
+ inline virtual ~DSSubscriber(){}
+ inline virtual char *whoami() {return (char*)"DSSubscriber";}
+};
+
+#endif //__LOC_ENG_AGPS_H__
diff --git a/gps/loc_api/libloc_api_50001/loc_eng_dmn_conn.cpp b/gps/loc_api/libloc_api_50001/loc_eng_dmn_conn.cpp
new file mode 100644
index 0000000..c257dff
--- /dev/null
+++ b/gps/loc_api/libloc_api_50001/loc_eng_dmn_conn.cpp
@@ -0,0 +1,270 @@
+/* Copyright (c) 2011-2012, 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 <linux/stat.h>
+#include <fcntl.h>
+#include <linux/types.h>
+#include <unistd.h>
+#include <errno.h>
+#include <grp.h>
+#include <sys/stat.h>
+
+#include "log_util.h"
+#include "platform_lib_includes.h"
+#include "loc_eng_dmn_conn_glue_msg.h"
+#include "loc_eng_dmn_conn_handler.h"
+#include "loc_eng_dmn_conn.h"
+#include "loc_eng_msg.h"
+
+static int loc_api_server_msgqid;
+static int loc_api_resp_msgqid;
+static int quipc_msgqid;
+static int msapm_msgqid;
+static int msapu_msgqid;
+
+static const char * global_loc_api_q_path = GPSONE_LOC_API_Q_PATH;
+static const char * global_loc_api_resp_q_path = GPSONE_LOC_API_RESP_Q_PATH;
+static const char * global_quipc_ctrl_q_path = QUIPC_CTRL_Q_PATH;
+static const char * global_msapm_ctrl_q_path = MSAPM_CTRL_Q_PATH;
+static const char * global_msapu_ctrl_q_path = MSAPU_CTRL_Q_PATH;
+
+static int loc_api_server_proc_init(void *context)
+{
+ loc_api_server_msgqid = loc_eng_dmn_conn_glue_msgget(global_loc_api_q_path, O_RDWR);
+ //change mode/group for the global_loc_api_q_path pipe
+ int result = chmod (global_loc_api_q_path, 0660);
+ if (result != 0)
+ {
+ LOC_LOGE("failed to change mode for %s, error = %s\n", global_loc_api_q_path, strerror(errno));
+ }
+
+ struct group * gps_group = getgrnam("gps");
+ if (gps_group != NULL)
+ {
+ result = chown (global_loc_api_q_path, -1, gps_group->gr_gid);
+ if (result != 0)
+ {
+ LOC_LOGE("chown for pipe failed, pipe %s, gid = %d, result = %d, error = %s\n",
+ global_loc_api_q_path, gps_group->gr_gid, result, strerror(errno));
+ }
+ }
+ else
+ {
+ LOC_LOGE("getgrnam for gps failed, error code = %d\n", errno);
+ }
+
+ loc_api_resp_msgqid = loc_eng_dmn_conn_glue_msgget(global_loc_api_resp_q_path, O_RDWR);
+
+ //change mode/group for the global_loc_api_resp_q_path pipe
+ result = chmod (global_loc_api_resp_q_path, 0660);
+ if (result != 0)
+ {
+ LOC_LOGE("failed to change mode for %s, error = %s\n", global_loc_api_resp_q_path, strerror(errno));
+ }
+
+ if (gps_group != NULL)
+ {
+ result = chown (global_loc_api_resp_q_path, -1, gps_group->gr_gid);
+ if (result != 0)
+ {
+ LOC_LOGE("chown for pipe failed, pipe %s, gid = %d, result = %d, error = %s\n",
+ global_loc_api_resp_q_path,
+ gps_group->gr_gid, result, strerror(errno));
+ }
+ }
+
+ quipc_msgqid = loc_eng_dmn_conn_glue_msgget(global_quipc_ctrl_q_path, O_RDWR);
+ msapm_msgqid = loc_eng_dmn_conn_glue_msgget(global_msapm_ctrl_q_path , O_RDWR);
+ msapu_msgqid = loc_eng_dmn_conn_glue_msgget(global_msapu_ctrl_q_path , O_RDWR);
+
+ LOC_LOGD("%s:%d] loc_api_server_msgqid = %d\n", __func__, __LINE__, loc_api_server_msgqid);
+ return 0;
+}
+
+static int loc_api_server_proc_pre(void *context)
+{
+ return 0;
+}
+
+static int loc_api_server_proc(void *context)
+{
+ int length, sz;
+ int result = 0;
+ static int cnt = 0;
+ struct ctrl_msgbuf * p_cmsgbuf;
+ struct ctrl_msgbuf cmsg_resp;
+
+ sz = sizeof(struct ctrl_msgbuf) + 256;
+ p_cmsgbuf = (struct ctrl_msgbuf *) malloc(sz);
+
+ if (!p_cmsgbuf) {
+ LOC_LOGE("%s:%d] Out of memory\n", __func__, __LINE__);
+ return -1;
+ }
+
+ cnt ++;
+ LOC_LOGD("%s:%d] %d listening on %s...\n", __func__, __LINE__, cnt, (char *) context);
+ length = loc_eng_dmn_conn_glue_msgrcv(loc_api_server_msgqid, p_cmsgbuf, sz);
+ if (length <= 0) {
+ free(p_cmsgbuf);
+ LOC_LOGE("%s:%d] fail receiving msg from gpsone_daemon, retry later\n", __func__, __LINE__);
+ usleep(1000);
+ return -1;
+ }
+
+ LOC_LOGD("%s:%d] received ctrl_type = %d\n", __func__, __LINE__, p_cmsgbuf->ctrl_type);
+ switch(p_cmsgbuf->ctrl_type) {
+ case GPSONE_LOC_API_IF_REQUEST:
+ result = loc_eng_dmn_conn_loc_api_server_if_request_handler(p_cmsgbuf, length);
+ break;
+
+ case GPSONE_LOC_API_IF_RELEASE:
+ result = loc_eng_dmn_conn_loc_api_server_if_release_handler(p_cmsgbuf, length);
+ break;
+
+ case GPSONE_UNBLOCK:
+ LOC_LOGD("%s:%d] GPSONE_UNBLOCK\n", __func__, __LINE__);
+ break;
+
+ default:
+ LOC_LOGE("%s:%d] unsupported ctrl_type = %d\n",
+ __func__, __LINE__, p_cmsgbuf->ctrl_type);
+ break;
+ }
+
+ free(p_cmsgbuf);
+ return 0;
+}
+
+static int loc_api_server_proc_post(void *context)
+{
+ LOC_LOGD("%s:%d]\n", __func__, __LINE__);
+ loc_eng_dmn_conn_glue_msgremove( global_loc_api_q_path, loc_api_server_msgqid);
+ loc_eng_dmn_conn_glue_msgremove( global_loc_api_resp_q_path, loc_api_resp_msgqid);
+ loc_eng_dmn_conn_glue_msgremove( global_quipc_ctrl_q_path, quipc_msgqid);
+ loc_eng_dmn_conn_glue_msgremove( global_msapm_ctrl_q_path, msapm_msgqid);
+ loc_eng_dmn_conn_glue_msgremove( global_msapu_ctrl_q_path, msapu_msgqid);
+ return 0;
+}
+
+static int loc_eng_dmn_conn_unblock_proc(void)
+{
+ struct ctrl_msgbuf cmsgbuf;
+ cmsgbuf.ctrl_type = GPSONE_UNBLOCK;
+ LOC_LOGD("%s:%d]\n", __func__, __LINE__);
+ loc_eng_dmn_conn_glue_msgsnd(loc_api_server_msgqid, & cmsgbuf, sizeof(cmsgbuf));
+ return 0;
+}
+
+static struct loc_eng_dmn_conn_thelper thelper;
+
+int loc_eng_dmn_conn_loc_api_server_launch(thelper_create_thread create_thread_cb,
+ const char * loc_api_q_path, const char * resp_q_path, void *agps_handle)
+{
+ int result;
+
+ loc_api_handle = agps_handle;
+
+ if (loc_api_q_path) global_loc_api_q_path = loc_api_q_path;
+ if (resp_q_path) global_loc_api_resp_q_path = resp_q_path;
+
+ result = loc_eng_dmn_conn_launch_thelper( &thelper,
+ loc_api_server_proc_init,
+ loc_api_server_proc_pre,
+ loc_api_server_proc,
+ loc_api_server_proc_post,
+ create_thread_cb,
+ (char *) global_loc_api_q_path);
+ if (result != 0) {
+ LOC_LOGE("%s:%d]\n", __func__, __LINE__);
+ return -1;
+ }
+ return 0;
+}
+
+int loc_eng_dmn_conn_loc_api_server_unblock(void)
+{
+ loc_eng_dmn_conn_unblock_thelper(&thelper);
+ loc_eng_dmn_conn_unblock_proc();
+ return 0;
+}
+
+int loc_eng_dmn_conn_loc_api_server_join(void)
+{
+ loc_eng_dmn_conn_join_thelper(&thelper);
+ return 0;
+}
+
+int loc_eng_dmn_conn_loc_api_server_data_conn(int sender_id, int status) {
+ struct ctrl_msgbuf cmsgbuf;
+ LOC_LOGD("%s:%d] quipc_msgqid = %d\n", __func__, __LINE__, quipc_msgqid);
+ cmsgbuf.ctrl_type = GPSONE_LOC_API_RESPONSE;
+ cmsgbuf.cmsg.cmsg_response.result = status;
+ switch (sender_id) {
+ case LOC_ENG_IF_REQUEST_SENDER_ID_QUIPC: {
+ LOC_LOGD("%s:%d] sender_id = LOC_ENG_IF_REQUEST_SENDER_ID_QUIPC", __func__, __LINE__);
+ if (loc_eng_dmn_conn_glue_msgsnd(quipc_msgqid, & cmsgbuf, sizeof(struct ctrl_msgbuf)) < 0) {
+ LOC_LOGD("%s:%d] error! conn_glue_msgsnd failed\n", __func__, __LINE__);
+ return -1;
+ }
+ break;
+ }
+ case LOC_ENG_IF_REQUEST_SENDER_ID_MSAPM: {
+ LOC_LOGD("%s:%d] sender_id = LOC_ENG_IF_REQUEST_SENDER_ID_MSAPM", __func__, __LINE__);
+ if (loc_eng_dmn_conn_glue_msgsnd(msapm_msgqid, & cmsgbuf, sizeof(struct ctrl_msgbuf)) < 0) {
+ LOC_LOGD("%s:%d] error! conn_glue_msgsnd failed\n", __func__, __LINE__);
+ return -1;
+ }
+ break;
+ }
+ case LOC_ENG_IF_REQUEST_SENDER_ID_MSAPU: {
+ LOC_LOGD("%s:%d] sender_id = LOC_ENG_IF_REQUEST_SENDER_ID_MSAPU", __func__, __LINE__);
+ if (loc_eng_dmn_conn_glue_msgsnd(msapu_msgqid, & cmsgbuf, sizeof(struct ctrl_msgbuf)) < 0) {
+ LOC_LOGD("%s:%d] error! conn_glue_msgsnd failed\n", __func__, __LINE__);
+ return -1;
+ }
+ break;
+ }
+ case LOC_ENG_IF_REQUEST_SENDER_ID_GPSONE_DAEMON: {
+ LOC_LOGD("%s:%d] sender_id = LOC_ENG_IF_REQUEST_SENDER_ID_GPSONE_DAEMON", __func__, __LINE__);
+ if (loc_eng_dmn_conn_glue_msgsnd(loc_api_resp_msgqid, & cmsgbuf, sizeof(struct ctrl_msgbuf)) < 0) {
+ LOC_LOGD("%s:%d] error! conn_glue_msgsnd failed\n", __func__, __LINE__);
+ return -1;
+ }
+ break;
+ }
+ default: {
+ LOC_LOGD("%s:%d] invalid sender ID!", __func__, __LINE__);
+ }
+ }
+ return 0;
+}
+
diff --git a/gps/loc_api/libloc_api_50001/loc_eng_dmn_conn.h b/gps/loc_api/libloc_api_50001/loc_eng_dmn_conn.h
new file mode 100644
index 0000000..1d8c142
--- /dev/null
+++ b/gps/loc_api/libloc_api_50001/loc_eng_dmn_conn.h
@@ -0,0 +1,59 @@
+/* Copyright (c) 2011-2012,2014 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_DATA_SERVER_H
+#define LOC_ENG_DATA_SERVER_H
+
+#include "loc_eng_dmn_conn_thread_helper.h"
+
+#ifdef _ANDROID_
+
+#define GPSONE_LOC_API_Q_PATH "/data/misc/location/gpsone_d/gpsone_loc_api_q"
+#define GPSONE_LOC_API_RESP_Q_PATH "/data/misc/location/gpsone_d/gpsone_loc_api_resp_q"
+#define QUIPC_CTRL_Q_PATH "/data/misc/location/gpsone_d/quipc_ctrl_q"
+#define MSAPM_CTRL_Q_PATH "/data/misc/location/gpsone_d/msapm_ctrl_q"
+#define MSAPU_CTRL_Q_PATH "/data/misc/location/gpsone_d/msapu_ctrl_q"
+
+#else
+
+#define GPSONE_LOC_API_Q_PATH "/tmp/gpsone_loc_api_q"
+#define GPSONE_LOC_API_RESP_Q_PATH "/tmp/gpsone_loc_api_resp_q"
+#define QUIPC_CTRL_Q_PATH "/tmp/quipc_ctrl_q"
+#define MSAPM_CTRL_Q_PATH "/tmp/msapm_ctrl_q"
+#define MSAPU_CTRL_Q_PATH "/tmp/msapu_ctrl_q"
+
+#endif
+
+int loc_eng_dmn_conn_loc_api_server_launch(thelper_create_thread create_thread_cb,
+ const char * loc_api_q_path, const char * ctrl_q_path, void *agps_handle);
+int loc_eng_dmn_conn_loc_api_server_unblock(void);
+int loc_eng_dmn_conn_loc_api_server_join(void);
+int loc_eng_dmn_conn_loc_api_server_data_conn(int, int);
+
+#endif /* LOC_ENG_DATA_SERVER_H */
+
diff --git a/gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_glue_msg.c b/gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_glue_msg.c
new file mode 100644
index 0000000..a1076ff
--- /dev/null
+++ b/gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_glue_msg.c
@@ -0,0 +1,223 @@
+/* Copyright (c) 2011, 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 <linux/stat.h>
+#include <fcntl.h>
+
+#include <linux/types.h>
+
+#include "log_util.h"
+#include "platform_lib_includes.h"
+#include "loc_eng_dmn_conn_glue_msg.h"
+#include "loc_eng_dmn_conn_handler.h"
+
+/*===========================================================================
+FUNCTION loc_eng_dmn_conn_glue_msgget
+
+DESCRIPTION
+ This function get a message queue
+
+ q_path - name path of the message queue
+ mode -
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ message queue id
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_dmn_conn_glue_msgget(const char * q_path, int mode)
+{
+ int msgqid;
+ msgqid = loc_eng_dmn_conn_glue_pipeget(q_path, mode);
+ return msgqid;
+}
+
+/*===========================================================================
+FUNCTION loc_eng_dmn_conn_glue_msgremove
+
+DESCRIPTION
+ remove a message queue
+
+ q_path - name path of the message queue
+ msgqid - message queue id
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0: success or negative value for failure
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_dmn_conn_glue_msgremove(const char * q_path, int msgqid)
+{
+ int result;
+ result = loc_eng_dmn_conn_glue_piperemove(q_path, msgqid);
+ return result;
+}
+
+/*===========================================================================
+FUNCTION loc_eng_dmn_conn_glue_msgsnd
+
+DESCRIPTION
+ Send a message
+
+ msgqid - message queue id
+ msgp - pointer to the message to be sent
+ msgsz - size of the message
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ number of bytes sent out or negative value for failure
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_dmn_conn_glue_msgsnd(int msgqid, const void * msgp, size_t msgsz)
+{
+ int result;
+ struct ctrl_msgbuf *pmsg = (struct ctrl_msgbuf *) msgp;
+ pmsg->msgsz = msgsz;
+
+ result = loc_eng_dmn_conn_glue_pipewrite(msgqid, msgp, msgsz);
+ if (result != (int) msgsz) {
+ LOC_LOGE("%s:%d] pipe broken %d, msgsz = %d\n", __func__, __LINE__, result, (int) msgsz);
+ return -1;
+ }
+
+ return result;
+}
+
+/*===========================================================================
+FUNCTION loc_eng_dmn_conn_glue_msgrcv
+
+DESCRIPTION
+ receive a message
+
+ msgqid - message queue id
+ msgp - pointer to the buffer to hold the message
+ msgsz - size of the buffer
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ number of bytes received or negative value for failure
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_dmn_conn_glue_msgrcv(int msgqid, void *msgp, size_t msgbufsz)
+{
+ int result;
+ struct ctrl_msgbuf *pmsg = (struct ctrl_msgbuf *) msgp;
+
+ result = loc_eng_dmn_conn_glue_piperead(msgqid, &(pmsg->msgsz), sizeof(pmsg->msgsz));
+ if (result != sizeof(pmsg->msgsz)) {
+ LOC_LOGE("%s:%d] pipe broken %d\n", __func__, __LINE__, result);
+ return -1;
+ }
+
+ if (msgbufsz < pmsg->msgsz) {
+ LOC_LOGE("%s:%d] msgbuf is too small %d < %d\n", __func__, __LINE__, (int) msgbufsz, (int) pmsg->msgsz);
+ return -1;
+ }
+
+ result = loc_eng_dmn_conn_glue_piperead(msgqid, (uint8_t *) msgp + sizeof(pmsg->msgsz), pmsg->msgsz - sizeof(pmsg->msgsz));
+ if (result != (int) (pmsg->msgsz - sizeof(pmsg->msgsz))) {
+ LOC_LOGE("%s:%d] pipe broken %d, msgsz = %d\n", __func__, __LINE__, result, (int) pmsg->msgsz);
+ return -1;
+ }
+
+ return pmsg->msgsz;
+}
+
+/*===========================================================================
+FUNCTION loc_eng_dmn_conn_glue_msgunblock
+
+DESCRIPTION
+ unblock a message queue
+
+ msgqid - message queue id
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0: success
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_dmn_conn_glue_msgunblock(int msgqid)
+{
+ return loc_eng_dmn_conn_glue_pipeunblock(msgqid);
+}
+
+/*===========================================================================
+FUNCTION loc_eng_dmn_conn_glue_msgflush
+
+DESCRIPTION
+ flush out the message in a queue
+
+ msgqid - message queue id
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ number of bytes that are flushed out.
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_dmn_conn_glue_msgflush(int msgqid)
+{
+ int length;
+ char buf[128];
+
+ do {
+ length = loc_eng_dmn_conn_glue_piperead(msgqid, buf, 128);
+ LOC_LOGD("%s:%d] %s\n", __func__, __LINE__, buf);
+ } while(length);
+ return length;
+}
+
diff --git a/gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_glue_msg.h b/gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_glue_msg.h
new file mode 100644
index 0000000..d685c87
--- /dev/null
+++ b/gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_glue_msg.h
@@ -0,0 +1,51 @@
+/* Copyright (c) 2011, 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_DMN_CONN_GLUE_MSG_H
+#define LOC_ENG_DMN_CONN_GLUE_MSG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#include <linux/types.h>
+#include "loc_eng_dmn_conn_glue_pipe.h"
+
+int loc_eng_dmn_conn_glue_msgget(const char * q_path, int mode);
+int loc_eng_dmn_conn_glue_msgremove(const char * q_path, int msgqid);
+int loc_eng_dmn_conn_glue_msgsnd(int msgqid, const void * msgp, size_t msgsz);
+int loc_eng_dmn_conn_glue_msgrcv(int msgqid, void *msgp, size_t msgsz);
+int loc_eng_dmn_conn_glue_msgflush(int msgqid);
+int loc_eng_dmn_conn_glue_msgunblock(int msgqid);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LOC_ENG_DMN_CONN_GLUE_MSG_H */
diff --git a/gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_glue_pipe.c b/gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_glue_pipe.c
new file mode 100644
index 0000000..dffcad0
--- /dev/null
+++ b/gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_glue_pipe.c
@@ -0,0 +1,214 @@
+/* Copyright (c) 2011-2012, 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.h>
+#include <unistd.h>
+#include <errno.h>
+
+// #include <linux/stat.h>
+#include <fcntl.h>
+// #include <linux/types.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "loc_eng_dmn_conn_glue_pipe.h"
+#include "log_util.h"
+#include "platform_lib_includes.h"
+/*===========================================================================
+FUNCTION loc_eng_dmn_conn_glue_pipeget
+
+DESCRIPTION
+ create a named pipe.
+
+ pipe_name - pipe name path
+ mode - mode
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0: success or negative value for failure
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_dmn_conn_glue_pipeget(const char * pipe_name, int mode)
+{
+ int fd;
+ int result;
+
+ LOC_LOGD("%s, mode = %d\n", pipe_name, mode);
+ result = mkfifo(pipe_name, 0660);
+
+ if ((result == -1) && (errno != EEXIST)) {
+ LOC_LOGE("failed: %s\n", strerror(errno));
+ return result;
+ }
+
+ // The mode in mkfifo is not honoured and does not provide the
+ // group permissions. Doing chmod to add group permissions.
+ result = chmod (pipe_name, 0660);
+ if (result != 0){
+ LOC_LOGE ("%s failed to change mode for %s, error = %s\n", __func__,
+ pipe_name, strerror(errno));
+ }
+
+ fd = open(pipe_name, mode);
+ if (fd <= 0)
+ {
+ LOC_LOGE("failed: %s\n", strerror(errno));
+ }
+ LOC_LOGD("fd = %d, %s\n", fd, pipe_name);
+ return fd;
+}
+
+/*===========================================================================
+FUNCTION loc_eng_dmn_conn_glue_piperemove
+
+DESCRIPTION
+ remove a pipe
+
+ pipe_name - pipe name path
+ fd - fd for the pipe
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0: success
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_dmn_conn_glue_piperemove(const char * pipe_name, int fd)
+{
+ close(fd);
+ if (pipe_name) unlink(pipe_name);
+ LOC_LOGD("fd = %d, %s\n", fd, pipe_name);
+ return 0;
+}
+
+/*===========================================================================
+FUNCTION loc_eng_dmn_conn_glue_pipewrite
+
+DESCRIPTION
+ write to a pipe
+
+ fd - fd of a pipe
+ buf - buffer for the data to write
+ sz - size of the data in buffer
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ number of bytes written or negative value for failure
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_dmn_conn_glue_pipewrite(int fd, const void * buf, size_t sz)
+{
+ int result;
+
+ result = write(fd, buf, sz);
+
+ /* @todo check for non EINTR & EAGAIN, shall not do select again, select_tut Law 7) */
+
+ /* LOC_LOGD("fd = %d, buf = 0x%lx, size = %d, result = %d\n", fd, (long) buf, (int) sz, (int) result); */
+ return result;
+}
+
+/*===========================================================================
+FUNCTION loc_eng_dmn_conn_glue_piperead
+
+DESCRIPTION
+ read from a pipe
+
+ fd - fd for the pipe
+ buf - buffer to hold the data read from pipe
+ sz - size of the buffer
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ number of bytes read from pipe or negative value for failure
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_dmn_conn_glue_piperead(int fd, void * buf, size_t sz)
+{
+ int len;
+
+ len = read(fd, buf, sz);
+
+ /* @todo check for non EINTR & EAGAIN, shall not do select again, select_tut Law 7) */
+
+ /* LOC_LOGD("fd = %d, buf = 0x%lx, size = %d, len = %d\n", fd, (long) buf, (int) sz, len); */
+ return len;
+}
+
+/*===========================================================================
+FUNCTION loc_eng_dmn_conn_glue_pipeunblock
+
+DESCRIPTION
+ unblock a pipe
+
+ fd - fd for the pipe
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0 for success or negative value for failure
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_dmn_conn_glue_pipeunblock(int fd)
+{
+ int result;
+ struct flock flock_v;
+ LOC_LOGD("\n");
+// result = fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NDELAY);
+ flock_v.l_type = F_UNLCK;
+ flock_v.l_len = 32;
+ result = fcntl(fd, F_SETLK, &flock_v);
+ if (result < 0) {
+ LOC_LOGE("fcntl failure, %s\n", strerror(errno));
+ }
+
+ return result;
+}
diff --git a/gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_glue_pipe.h b/gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_glue_pipe.h
new file mode 100644
index 0000000..b2fa3a0
--- /dev/null
+++ b/gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_glue_pipe.h
@@ -0,0 +1,50 @@
+/* Copyright (c) 2011, 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_DMN_CONN_GLUE_PIPE_H
+#define LOC_ENG_DMN_CONN_GLUE_PIPE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <linux/types.h>
+
+int loc_eng_dmn_conn_glue_pipeget(const char * pipe_name, int mode);
+int loc_eng_dmn_conn_glue_piperemove(const char * pipe_name, int fd);
+int loc_eng_dmn_conn_glue_pipewrite(int fd, const void * buf, size_t sz);
+int loc_eng_dmn_conn_glue_piperead(int fd, void * buf, size_t sz);
+
+int loc_eng_dmn_conn_glue_pipeflush(int fd);
+int loc_eng_dmn_conn_glue_pipeunblock(int fd);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LOC_ENG_DMN_CONN_GLUE_PIPE_H */
diff --git a/gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_handler.cpp b/gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_handler.cpp
new file mode 100644
index 0000000..edd53f2
--- /dev/null
+++ b/gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_handler.cpp
@@ -0,0 +1,237 @@
+/* Copyright (c) 2011-2012, 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 <string.h>
+#include <unistd.h>
+
+#include "log_util.h"
+#include "platform_lib_includes.h"
+#include "loc_eng_msg.h"
+#include "loc_eng_dmn_conn.h"
+#include "loc_eng_dmn_conn_handler.h"
+
+void* loc_api_handle = NULL;
+
+int loc_eng_dmn_conn_loc_api_server_if_request_handler(struct ctrl_msgbuf *pmsg, int len)
+{
+ LOC_LOGD("%s:%d]\n", __func__, __LINE__);
+#ifndef DEBUG_DMN_LOC_API
+ if (NULL == loc_api_handle) {
+ LOC_LOGE("%s:%d] NO agps data handle\n", __func__, __LINE__);
+ return 1;
+ }
+
+ if (NULL != loc_api_handle) {
+ AGpsExtType type;
+ switch (pmsg->cmsg.cmsg_if_request.type) {
+ case IF_REQUEST_TYPE_SUPL:
+ {
+ LOC_LOGD("IF_REQUEST_TYPE_SUPL");
+ type = AGPS_TYPE_SUPL;
+ break;
+ }
+ case IF_REQUEST_TYPE_WIFI:
+ {
+ LOC_LOGD("IF_REQUEST_TYPE_WIFI");
+ type = AGPS_TYPE_WIFI;
+ break;
+ }
+ case IF_REQUEST_TYPE_ANY:
+ {
+ LOC_LOGD("IF_REQUEST_TYPE_ANY");
+ type = AGPS_TYPE_ANY;
+ break;
+ }
+ default:
+ {
+ LOC_LOGD("invalid IF_REQUEST_TYPE!");
+ return -1;
+ }
+ }
+ switch (pmsg->cmsg.cmsg_if_request.sender_id) {
+ case IF_REQUEST_SENDER_ID_QUIPC:
+ {
+ LOC_LOGD("IF_REQUEST_SENDER_ID_QUIPC");
+ LocEngReqRelWifi* msg =
+ new LocEngReqRelWifi(loc_api_handle,
+ type,
+ LOC_ENG_IF_REQUEST_SENDER_ID_QUIPC,
+ (char*)pmsg->cmsg.cmsg_if_request.ssid,
+ (char*)pmsg->cmsg.cmsg_if_request.password,
+ true);
+ msg->send();
+ break;
+ }
+ case IF_REQUEST_SENDER_ID_MSAPM:
+ {
+ LOC_LOGD("IF_REQUEST_SENDER_ID_MSAPM");
+ LocEngReqRelWifi* msg =
+ new LocEngReqRelWifi(loc_api_handle,
+ type,
+ LOC_ENG_IF_REQUEST_SENDER_ID_MSAPM,
+ (char*)pmsg->cmsg.cmsg_if_request.ssid,
+ (char*)pmsg->cmsg.cmsg_if_request.password,
+ true);
+ msg->send();
+ break;
+ }
+ case IF_REQUEST_SENDER_ID_MSAPU:
+ {
+ LOC_LOGD("IF_REQUEST_SENDER_ID_MSAPU");
+ LocEngReqRelWifi* msg =
+ new LocEngReqRelWifi(loc_api_handle,
+ type,
+ LOC_ENG_IF_REQUEST_SENDER_ID_MSAPU,
+ (char*)pmsg->cmsg.cmsg_if_request.ssid,
+ (char*)pmsg->cmsg.cmsg_if_request.password,
+ true);
+ msg->send();
+ break;
+ }
+ case IF_REQUEST_SENDER_ID_GPSONE_DAEMON:
+ {
+ LOC_LOGD("IF_REQUEST_SENDER_ID_GPSONE_DAEMON");
+ LocEngReqRelBIT* msg =
+ new LocEngReqRelBIT(loc_api_handle,
+ type,
+ pmsg->cmsg.cmsg_if_request.ipv4_addr,
+ (char*)pmsg->cmsg.cmsg_if_request.ipv6_addr,
+ true);
+ msg->send();
+ break;
+ }
+ default:
+ {
+ LOC_LOGD("invalid IF_REQUEST_SENDER_ID!");
+ return -1;
+ }
+ }
+ }
+
+#else
+ loc_eng_dmn_conn_loc_api_server_data_conn(LOC_ENG_IF_REQUEST_SENDER_ID_GPSONE_DAEMON, GPSONE_LOC_API_IF_REQUEST_SUCCESS);
+#endif
+ return 0;
+}
+
+int loc_eng_dmn_conn_loc_api_server_if_release_handler(struct ctrl_msgbuf *pmsg, int len)
+{
+ LOC_LOGD("%s:%d]\n", __func__, __LINE__);
+#ifndef DEBUG_DMN_LOC_API
+ AGpsExtType type;
+ switch (pmsg->cmsg.cmsg_if_request.type) {
+ case IF_REQUEST_TYPE_SUPL:
+ {
+ LOC_LOGD("IF_REQUEST_TYPE_SUPL");
+ type = AGPS_TYPE_SUPL;
+ break;
+ }
+ case IF_REQUEST_TYPE_WIFI:
+ {
+ LOC_LOGD("IF_REQUEST_TYPE_WIFI");
+ type = AGPS_TYPE_WIFI;
+ break;
+ }
+ case IF_REQUEST_TYPE_ANY:
+ {
+ LOC_LOGD("IF_REQUEST_TYPE_ANY");
+ type = AGPS_TYPE_ANY;
+ break;
+ }
+ default:
+ {
+ LOC_LOGD("invalid IF_REQUEST_TYPE!");
+ return -1;
+ }
+ }
+ switch (pmsg->cmsg.cmsg_if_request.sender_id) {
+ case IF_REQUEST_SENDER_ID_QUIPC:
+ {
+ LOC_LOGD("IF_REQUEST_SENDER_ID_QUIPC");
+ LocEngReqRelWifi* msg =
+ new LocEngReqRelWifi(loc_api_handle,
+ type,
+ LOC_ENG_IF_REQUEST_SENDER_ID_QUIPC,
+ (char*)pmsg->cmsg.cmsg_if_request.ssid,
+ (char*)pmsg->cmsg.cmsg_if_request.password,
+ false);
+ msg->send();
+ break;
+ }
+ case IF_REQUEST_SENDER_ID_MSAPM:
+ {
+ LOC_LOGD("IF_REQUEST_SENDER_ID_MSAPM");
+ LocEngReqRelWifi* msg =
+ new LocEngReqRelWifi(loc_api_handle,
+ type,
+ LOC_ENG_IF_REQUEST_SENDER_ID_MSAPM,
+ (char*)pmsg->cmsg.cmsg_if_request.ssid,
+ (char*)pmsg->cmsg.cmsg_if_request.password,
+ false);
+ msg->send();
+ break;
+ }
+ case IF_REQUEST_SENDER_ID_MSAPU:
+ {
+ LOC_LOGD("IF_REQUEST_SENDER_ID_MSAPU");
+ LocEngReqRelWifi* msg =
+ new LocEngReqRelWifi(loc_api_handle,
+ type,
+ LOC_ENG_IF_REQUEST_SENDER_ID_MSAPU,
+ (char*)pmsg->cmsg.cmsg_if_request.ssid,
+ (char*)pmsg->cmsg.cmsg_if_request.password,
+ false);
+ msg->send();
+ break;
+ }
+ case IF_REQUEST_SENDER_ID_GPSONE_DAEMON:
+ {
+ LOC_LOGD("IF_REQUEST_SENDER_ID_GPSONE_DAEMON");
+ LocEngReqRelBIT* msg =
+ new LocEngReqRelBIT(loc_api_handle,
+ type,
+ pmsg->cmsg.cmsg_if_request.ipv4_addr,
+ (char*)pmsg->cmsg.cmsg_if_request.ipv6_addr,
+ false);
+ msg->send();
+ break;
+ }
+ default:
+ {
+ LOC_LOGD("invalid IF_REQUEST_SENDER_ID!");
+ return -1;
+ }
+ }
+#else
+ loc_eng_dmn_conn_loc_api_server_data_conn(LOC_ENG_IF_REQUEST_SENDER_ID_GPSONE_DAEMON, GPSONE_LOC_API_IF_RELEASE_SUCCESS);
+#endif
+ return 0;
+}
+
diff --git a/gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_handler.h b/gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_handler.h
new file mode 100644
index 0000000..8cbb353
--- /dev/null
+++ b/gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_handler.h
@@ -0,0 +1,106 @@
+/* Copyright (c) 2011-2012, 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_DATA_SERVER_HANDLER
+#define LOC_ENG_DATA_SERVER_HANDLER
+
+#include <linux/types.h>
+#include <arpa/inet.h>
+
+//for SSID_BUF_SIZE
+#include "hardware/gps.h"
+
+#ifndef SSID_BUF_SIZE
+ #define SSID_BUF_SIZE (32+1)
+#endif
+
+enum {
+ /* 0x0 - 0xEF is reserved for daemon internal */
+ GPSONE_LOC_API_IF_REQUEST = 0xF0,
+ GPSONE_LOC_API_IF_RELEASE,
+ GPSONE_LOC_API_RESPONSE,
+ GPSONE_UNBLOCK,
+};
+
+enum {
+ GPSONE_LOC_API_IF_REQUEST_SUCCESS = 0xF0,
+ GPSONE_LOC_API_IF_RELEASE_SUCCESS,
+ GPSONE_LOC_API_IF_FAILURE,
+};
+
+
+struct ctrl_msg_response {
+ int result;
+};
+
+struct ctrl_msg_unblock {
+ int reserved;
+};
+
+typedef enum {
+ IF_REQUEST_TYPE_SUPL = 0,
+ IF_REQUEST_TYPE_WIFI,
+ IF_REQUEST_TYPE_ANY
+} ctrl_if_req_type_e_type;
+
+typedef enum {
+ IF_REQUEST_SENDER_ID_QUIPC = 0,
+ IF_REQUEST_SENDER_ID_MSAPM,
+ IF_REQUEST_SENDER_ID_MSAPU,
+ IF_REQUEST_SENDER_ID_GPSONE_DAEMON,
+ IF_REQUEST_SENDER_ID_MODEM
+} ctrl_if_req_sender_id_e_type;
+
+struct ctrl_msg_if_request {
+ ctrl_if_req_type_e_type type;
+ ctrl_if_req_sender_id_e_type sender_id;
+ unsigned long ipv4_addr;
+ unsigned char ipv6_addr[16];
+ char ssid[SSID_BUF_SIZE];
+ char password[SSID_BUF_SIZE];
+};
+
+/* do not change this structure */
+struct ctrl_msgbuf {
+ size_t msgsz;
+ uint16_t reserved1;
+ uint32_t reserved2;
+ uint8_t ctrl_type;
+ union {
+ struct ctrl_msg_response cmsg_response;
+ struct ctrl_msg_unblock cmsg_unblock;
+ struct ctrl_msg_if_request cmsg_if_request;
+ } cmsg;
+};
+
+extern void* loc_api_handle;
+
+int loc_eng_dmn_conn_loc_api_server_if_request_handler(struct ctrl_msgbuf *pmsg, int len);
+int loc_eng_dmn_conn_loc_api_server_if_release_handler(struct ctrl_msgbuf *pmsg, int len);
+
+#endif /* LOC_ENG_DATA_SERVER_HANDLER */
diff --git a/gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_thread_helper.c b/gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_thread_helper.c
new file mode 100644
index 0000000..9fed9d4
--- /dev/null
+++ b/gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_thread_helper.c
@@ -0,0 +1,399 @@
+/* Copyright (c) 2011, 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 "log_util.h"
+#include "platform_lib_includes.h"
+#include "loc_eng_dmn_conn_thread_helper.h"
+
+/*===========================================================================
+FUNCTION thelper_signal_init
+
+DESCRIPTION
+ This function will initialize the conditional variable resources.
+
+ thelper - thelper instance
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0: success or negative value for failure
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int thelper_signal_init(struct loc_eng_dmn_conn_thelper * thelper)
+{
+ int result;
+ thelper->thread_exit = 0;
+ thelper->thread_ready = 0;
+ result = pthread_cond_init( &thelper->thread_cond, NULL);
+ if (result) {
+ return result;
+ }
+
+ result = pthread_mutex_init(&thelper->thread_mutex, NULL);
+ if (result) {
+ pthread_cond_destroy(&thelper->thread_cond);
+ }
+ return result;
+}
+
+/*===========================================================================
+FUNCTION
+
+DESCRIPTION
+ This function will destroy the conditional variable resources
+
+ thelper - pointer to thelper instance
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0: success or negative value for failure
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int thelper_signal_destroy(struct loc_eng_dmn_conn_thelper * thelper)
+{
+ int result, ret_result = 0;
+ result = pthread_cond_destroy( &thelper->thread_cond);
+ if (result) {
+ ret_result = result;
+ }
+
+ result = pthread_mutex_destroy(&thelper->thread_mutex);
+ if (result) {
+ ret_result = result;
+ }
+
+ return ret_result;
+}
+
+/*===========================================================================
+FUNCTION thelper_signal_wait
+
+DESCRIPTION
+ This function will be blocked on the conditional variable until thelper_signal_ready
+ is called
+
+ thelper - pointer to thelper instance
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0: success or negative value for failure
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int thelper_signal_wait(struct loc_eng_dmn_conn_thelper * thelper)
+{
+ int result = 0;
+
+ pthread_mutex_lock(&thelper->thread_mutex);
+ if (!thelper->thread_ready && !thelper->thread_exit) {
+ result = pthread_cond_wait(&thelper->thread_cond, &thelper->thread_mutex);
+ }
+
+ if (thelper->thread_exit) {
+ result = -1;
+ }
+ pthread_mutex_unlock(&thelper->thread_mutex);
+
+ return result;
+}
+
+/*===========================================================================
+FUNCTION thelper_signal_ready
+
+DESCRIPTION
+ This function will wake up the conditional variable
+
+ thelper - pointer to thelper instance
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0: success or negative value for failure
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int thelper_signal_ready(struct loc_eng_dmn_conn_thelper * thelper)
+{
+ int result;
+
+ LOC_LOGD("%s:%d] 0x%lx\n", __func__, __LINE__, (long) thelper);
+
+ pthread_mutex_lock(&thelper->thread_mutex);
+ thelper->thread_ready = 1;
+ result = pthread_cond_signal(&thelper->thread_cond);
+ pthread_mutex_unlock(&thelper->thread_mutex);
+
+ return result;
+}
+
+/*===========================================================================
+FUNCTION thelper_signal_block
+
+DESCRIPTION
+ This function will set the thread ready to 0 to block the thelper_signal_wait
+
+ thelper - pointer to thelper instance
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ if thread_ready is set
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int thelper_signal_block(struct loc_eng_dmn_conn_thelper * thelper)
+{
+ int result = thelper->thread_ready;
+
+ LOC_LOGD("%s:%d] 0x%lx\n", __func__, __LINE__, (long) thelper);
+
+ pthread_mutex_lock(&thelper->thread_mutex);
+ thelper->thread_ready = 0;
+ pthread_mutex_unlock(&thelper->thread_mutex);
+
+ return result;
+}
+
+/*===========================================================================
+FUNCTION thelper_main
+
+DESCRIPTION
+ This function is the main thread. It will be launched as a child thread
+
+ data - pointer to the instance
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ NULL
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static void * thelper_main(void *data)
+{
+ int result = 0;
+ struct loc_eng_dmn_conn_thelper * thelper = (struct loc_eng_dmn_conn_thelper *) data;
+
+ if (thelper->thread_proc_init) {
+ result = thelper->thread_proc_init(thelper->thread_context);
+ if (result < 0) {
+ thelper->thread_exit = 1;
+ thelper_signal_ready(thelper);
+ LOC_LOGE("%s:%d] error: 0x%lx\n", __func__, __LINE__, (long) thelper);
+ return NULL;
+ }
+ }
+
+ thelper_signal_ready(thelper);
+
+ if (thelper->thread_proc_pre) {
+ result = thelper->thread_proc_pre(thelper->thread_context);
+ if (result < 0) {
+ thelper->thread_exit = 1;
+ LOC_LOGE("%s:%d] error: 0x%lx\n", __func__, __LINE__, (long) thelper);
+ return NULL;
+ }
+ }
+
+ do {
+ if (thelper->thread_proc) {
+ result = thelper->thread_proc(thelper->thread_context);
+ if (result < 0) {
+ thelper->thread_exit = 1;
+ LOC_LOGE("%s:%d] error: 0x%lx\n", __func__, __LINE__, (long) thelper);
+ }
+ }
+ } while (thelper->thread_exit == 0);
+
+ if (thelper->thread_proc_post) {
+ result = thelper->thread_proc_post(thelper->thread_context);
+ }
+
+ if (result != 0) {
+ LOC_LOGE("%s:%d] error: 0x%lx\n", __func__, __LINE__, (long) thelper);
+ }
+ return NULL;
+}
+
+static void thelper_main_2(void *data)
+{
+ thelper_main(data);
+ return;
+}
+
+
+/*===========================================================================
+FUNCTION loc_eng_dmn_conn_launch_thelper
+
+DESCRIPTION
+ This function will initialize the thread context and launch the thelper_main
+
+ thelper - pointer to thelper instance
+ thread_proc_init - The initialization function pointer
+ thread_proc_pre - The function to call before task loop and after initialization
+ thread_proc - The task loop
+ thread_proc_post - The function to call after the task loop
+ context - the context for the above four functions
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0: success or negative value for failure
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_dmn_conn_launch_thelper(struct loc_eng_dmn_conn_thelper * thelper,
+ int (*thread_proc_init) (void * context),
+ int (*thread_proc_pre) (void * context),
+ int (*thread_proc) (void * context),
+ int (*thread_proc_post) (void * context),
+ thelper_create_thread create_thread_cb,
+ void * context)
+{
+ int result;
+
+ thelper_signal_init(thelper);
+
+ if (context) {
+ thelper->thread_context = context;
+ }
+
+ thelper->thread_proc_init = thread_proc_init;
+ thelper->thread_proc_pre = thread_proc_pre;
+ thelper->thread_proc = thread_proc;
+ thelper->thread_proc_post = thread_proc_post;
+
+ LOC_LOGD("%s:%d] 0x%lx call pthread_create\n", __func__, __LINE__, (long) thelper);
+ if (create_thread_cb) {
+ result = 0;
+ thelper->thread_id = create_thread_cb("loc_eng_dmn_conn",
+ thelper_main_2, (void *)thelper);
+ } else {
+ result = pthread_create(&thelper->thread_id, NULL,
+ thelper_main, (void *)thelper);
+ }
+
+ if (result != 0) {
+ LOC_LOGE("%s:%d] 0x%lx\n", __func__, __LINE__, (long) thelper);
+ return -1;
+ }
+
+ LOC_LOGD("%s:%d] 0x%lx pthread_create done\n", __func__, __LINE__, (long) thelper);
+
+ thelper_signal_wait(thelper);
+
+ LOC_LOGD("%s:%d] 0x%lx pthread ready\n", __func__, __LINE__, (long) thelper);
+ return thelper->thread_exit;
+}
+
+/*===========================================================================
+FUNCTION loc_eng_dmn_conn_unblock_thelper
+
+DESCRIPTION
+ This function unblocks thelper_main to release the thread
+
+ thelper - pointer to thelper instance
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0: success
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_dmn_conn_unblock_thelper(struct loc_eng_dmn_conn_thelper * thelper)
+{
+ LOC_LOGD("%s:%d] 0x%lx\n", __func__, __LINE__, (long) thelper);
+ thelper->thread_exit = 1;
+ return 0;
+}
+
+/*===========================================================================
+FUNCTION loc_eng_dmn_conn_join_thelper
+
+ thelper - pointer to thelper instance
+
+DESCRIPTION
+ This function will wait for the thread of thelper_main to finish
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0: success or negative value for failure
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_dmn_conn_join_thelper(struct loc_eng_dmn_conn_thelper * thelper)
+{
+ int result;
+
+ LOC_LOGD("%s:%d] 0x%lx\n", __func__, __LINE__, (long) thelper);
+ result = pthread_join(thelper->thread_id, NULL);
+ if (result != 0) {
+ LOC_LOGE("%s:%d] 0x%lx\n", __func__, __LINE__, (long) thelper);
+ }
+ LOC_LOGD("%s:%d] 0x%lx\n", __func__, __LINE__, (long) thelper);
+
+ thelper_signal_destroy(thelper);
+
+ return result;
+}
+
diff --git a/gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_thread_helper.h b/gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_thread_helper.h
new file mode 100644
index 0000000..89e598b
--- /dev/null
+++ b/gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_thread_helper.h
@@ -0,0 +1,74 @@
+/* Copyright (c) 2011, 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_DMN_CONN_THREAD_HELPER_H__
+#define __LOC_ENG_DMN_CONN_THREAD_HELPER_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <pthread.h>
+
+struct loc_eng_dmn_conn_thelper {
+ unsigned char thread_exit;
+ unsigned char thread_ready;
+ pthread_cond_t thread_cond;
+ pthread_mutex_t thread_mutex;
+ pthread_t thread_id;
+ void * thread_context;
+ int (*thread_proc_init) (void * context);
+ int (*thread_proc_pre) (void * context);
+ int (*thread_proc) (void * context);
+ int (*thread_proc_post) (void * context);
+};
+
+typedef pthread_t (* thelper_create_thread)(const char* name, void (*start)(void *), void* arg);
+int loc_eng_dmn_conn_launch_thelper(struct loc_eng_dmn_conn_thelper * thelper,
+ int (*thread_proc_init) (void * context),
+ int (*thread_proc_pre) (void * context),
+ int (*thread_proc) (void * context),
+ int (*thread_proc_post) (void * context),
+ thelper_create_thread create_thread_cb,
+ void * context);
+
+int loc_eng_dmn_conn_unblock_thelper(struct loc_eng_dmn_conn_thelper * thelper);
+int loc_eng_dmn_conn_join_thelper(struct loc_eng_dmn_conn_thelper * thelper);
+
+/* if only need to use signal */
+int thelper_signal_init(struct loc_eng_dmn_conn_thelper * thelper);
+int thelper_signal_destroy(struct loc_eng_dmn_conn_thelper * thelper);
+int thelper_signal_wait(struct loc_eng_dmn_conn_thelper * thelper);
+int thelper_signal_ready(struct loc_eng_dmn_conn_thelper * thelper);
+int thelper_signal_block(struct loc_eng_dmn_conn_thelper * thelper);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __LOC_ENG_DMN_CONN_THREAD_HELPER_H__ */
diff --git a/gps/loc_api/libloc_api_50001/loc_eng_log.cpp b/gps/loc_api/libloc_api_50001/loc_eng_log.cpp
new file mode 100644
index 0000000..3a34167
--- /dev/null
+++ b/gps/loc_api/libloc_api_50001/loc_eng_log.cpp
@@ -0,0 +1,35 @@
+/* Copyright (c) 2011-2013, 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_eng"
+
+#include "loc_log.h"
+#include "loc_eng_log.h"
+
diff --git a/gps/loc_api/libloc_api_50001/loc_eng_log.h b/gps/loc_api/libloc_api_50001/loc_eng_log.h
new file mode 100644
index 0000000..a68bd84
--- /dev/null
+++ b/gps/loc_api/libloc_api_50001/loc_eng_log.h
@@ -0,0 +1,44 @@
+/* Copyright (c) 2011-2013, 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_LOG_H
+#define LOC_ENG_LOG_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <ctype.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LOC_ENG_LOG_H */
diff --git a/gps/loc_api/libloc_api_50001/loc_eng_msg.h b/gps/loc_api/libloc_api_50001/loc_eng_msg.h
new file mode 100644
index 0000000..c2e991a
--- /dev/null
+++ b/gps/loc_api/libloc_api_50001/loc_eng_msg.h
@@ -0,0 +1,296 @@
+/* Copyright (c) 2011-2013, 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_MSG_H
+#define LOC_ENG_MSG_H
+
+
+#include "hardware/gps.h"
+#include <gps_extended.h>
+#include <stdlib.h>
+#include <string.h>
+#include <log_util.h>
+#include <loc_eng_log.h>
+#include <loc_eng.h>
+#include <MsgTask.h>
+#include <LocEngAdapter.h>
+
+#ifndef SSID_BUF_SIZE
+ #define SSID_BUF_SIZE (32+1)
+#endif
+#ifdef USE_GLIB
+
+#include <glib.h>
+
+#endif /* USE_GLIB */
+#include "platform_lib_includes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+using namespace loc_core;
+
+struct LocEngPositionMode : public LocMsg {
+ LocEngAdapter* mAdapter;
+ const LocPosMode mPosMode;
+ LocEngPositionMode(LocEngAdapter* adapter, LocPosMode &mode);
+ virtual void proc() const;
+ virtual void log() const;
+ void send() const;
+};
+
+
+struct LocEngStartFix : public LocMsg {
+ LocEngAdapter* mAdapter;
+ LocEngStartFix(LocEngAdapter* adapter);
+ virtual void proc() const;
+ void locallog() const;
+ virtual void log() const;
+ void send() const;
+};
+
+struct LocEngStopFix : public LocMsg {
+ LocEngAdapter* mAdapter;
+ LocEngStopFix(LocEngAdapter* adapter);
+ virtual void proc() const;
+ void locallog() const;
+ virtual void log() const;
+ void send() const;
+};
+
+struct LocEngReportPosition : public LocMsg {
+ LocAdapterBase* mAdapter;
+ const UlpLocation mLocation;
+ const GpsLocationExtended mLocationExtended;
+ const void* mLocationExt;
+ const enum loc_sess_status mStatus;
+ const LocPosTechMask mTechMask;
+ LocEngReportPosition(LocAdapterBase* adapter,
+ UlpLocation &loc,
+ GpsLocationExtended &locExtended,
+ void* locExt,
+ enum loc_sess_status st,
+ LocPosTechMask technology);
+ virtual void proc() const;
+ void locallog() const;
+ virtual void log() const;
+ void send() const;
+};
+
+struct LocEngReportSv : public LocMsg {
+ LocAdapterBase* mAdapter;
+ const GpsSvStatus mSvStatus;
+ const GpsLocationExtended mLocationExtended;
+ const void* mSvExt;
+ LocEngReportSv(LocAdapterBase* adapter,
+ GpsSvStatus &sv,
+ GpsLocationExtended &locExtended,
+ void* svExtended);
+ virtual void proc() const;
+ void locallog() const;
+ virtual void log() const;
+ void send() const;
+};
+
+struct LocEngReportStatus : public LocMsg {
+ LocAdapterBase* mAdapter;
+ const GpsStatusValue mStatus;
+ LocEngReportStatus(LocAdapterBase* adapter,
+ GpsStatusValue engineStatus);
+ virtual void proc() const;
+ void locallog() const;
+ virtual void log() const;
+};
+
+struct LocEngReportNmea : public LocMsg {
+ void* mLocEng;
+ char* const mNmea;
+ const int mLen;
+ LocEngReportNmea(void* locEng,
+ const char* data, int len);
+ inline virtual ~LocEngReportNmea()
+ {
+ delete[] mNmea;
+ }
+ virtual void proc() const;
+ void locallog() const;
+ virtual void log() const;
+};
+
+struct LocEngReportXtraServer : public LocMsg {
+ void* mLocEng;
+ int mMaxLen;
+ char *mServers;
+ LocEngReportXtraServer(void* locEng,
+ const char *url1, const char *url2,
+ const char *url3, const int maxlength);
+ inline virtual ~LocEngReportXtraServer()
+ {
+ delete[] mServers;
+ }
+ virtual void proc() const;
+ void locallog() const;
+ virtual void log() const;
+};
+
+struct LocEngSuplEsOpened : public LocMsg {
+ void* mLocEng;
+ LocEngSuplEsOpened(void* locEng);
+ virtual void proc() const;
+ void locallog() const;
+ virtual void log() const;
+};
+
+struct LocEngSuplEsClosed : public LocMsg {
+ void* mLocEng;
+ LocEngSuplEsClosed(void* locEng);
+ virtual void proc() const;
+ void locallog() const;
+ virtual void log() const;
+};
+
+struct LocEngRequestSuplEs : public LocMsg {
+ void* mLocEng;
+ const int mID;
+ LocEngRequestSuplEs(void* locEng, int id);
+ virtual void proc() const;
+ void locallog() const;
+ virtual void log() const;
+};
+
+struct LocEngRequestATL : public LocMsg {
+ void* mLocEng;
+ const int mID;
+ const AGpsExtType mType;
+ LocEngRequestATL(void* locEng, int id,
+ AGpsExtType agps_type);
+ virtual void proc() const;
+ void locallog() const;
+ virtual void log() const;
+};
+
+struct LocEngReleaseATL : public LocMsg {
+ void* mLocEng;
+ const int mID;
+ LocEngReleaseATL(void* locEng, int id);
+ virtual void proc() const;
+ void locallog() const;
+ virtual void log() const;
+};
+
+struct LocEngReqRelBIT : public LocMsg {
+ void* mLocEng;
+ const AGpsExtType mType;
+ const int mIPv4Addr;
+ char* const mIPv6Addr;
+ const bool mIsReq;
+ LocEngReqRelBIT(void* instance, AGpsExtType type,
+ int ipv4, char* ipv6, bool isReq);
+ virtual ~LocEngReqRelBIT();
+ virtual void proc() const;
+ void locallog() const;
+ virtual void log() const;
+ void send() const;
+};
+
+struct LocEngReqRelWifi : public LocMsg {
+ void* mLocEng;
+ const AGpsExtType mType;
+ const loc_if_req_sender_id_e_type mSenderId;
+ char* const mSSID;
+ char* const mPassword;
+ const bool mIsReq;
+ LocEngReqRelWifi(void* locEng, AGpsExtType type,
+ loc_if_req_sender_id_e_type sender_id,
+ char* s, char* p, bool isReq);
+ virtual ~LocEngReqRelWifi();
+ virtual void proc() const;
+ void locallog() const;
+ virtual void log() const;
+ void send() const;
+};
+
+struct LocEngRequestXtra : public LocMsg {
+ void* mLocEng;
+ LocEngRequestXtra(void* locEng);
+ virtual void proc() const;
+ void locallog() const;
+ virtual void log() const;
+};
+
+struct LocEngRequestTime : public LocMsg {
+ void* mLocEng;
+ LocEngRequestTime(void* locEng);
+ virtual void proc() const;
+ void locallog() const;
+ virtual void log() const;
+};
+
+struct LocEngRequestNi : public LocMsg {
+ void* mLocEng;
+ const GpsNiNotification mNotify;
+ const void *mPayload;
+ LocEngRequestNi(void* locEng,
+ GpsNiNotification &notif,
+ const void* data);
+ virtual void proc() const;
+ void locallog() const;
+ virtual void log() const;
+};
+
+struct LocEngDown : public LocMsg {
+ void* mLocEng;
+ LocEngDown(void* locEng);
+ virtual void proc() const;
+ void locallog() const;
+ virtual void log() const;
+};
+
+struct LocEngUp : public LocMsg {
+ void* mLocEng;
+ LocEngUp(void* locEng);
+ virtual void proc() const;
+ void locallog() const;
+ virtual void log() const;
+};
+
+struct LocEngGetZpp : public LocMsg {
+ LocEngAdapter* mAdapter;
+ LocEngGetZpp(LocEngAdapter* adapter);
+ virtual void proc() const;
+ void locallog() const;
+ virtual void log() const;
+ void send() const;
+};
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LOC_ENG_MSG_H */
diff --git a/gps/loc_api/libloc_api_50001/loc_eng_ni.cpp b/gps/loc_api/libloc_api_50001/loc_eng_ni.cpp
new file mode 100644
index 0000000..4597b98
--- /dev/null
+++ b/gps/loc_api/libloc_api_50001/loc_eng_ni.cpp
@@ -0,0 +1,414 @@
+/* Copyright (c) 2009-2014, 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_eng"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <pthread.h>
+#include <errno.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <time.h>
+#include <MsgTask.h>
+
+#include <loc_eng.h>
+
+#include "log_util.h"
+#include "platform_lib_includes.h"
+
+using namespace loc_core;
+
+/*=============================================================================
+ *
+ * DATA DECLARATION
+ *
+ *============================================================================*/
+
+/*=============================================================================
+ *
+ * FUNCTION DECLARATIONS
+ *
+ *============================================================================*/
+static void* ni_thread_proc(void *args);
+
+struct LocEngInformNiResponse : public LocMsg {
+ LocEngAdapter* mAdapter;
+ const GpsUserResponseType mResponse;
+ const void *mPayload;
+ inline LocEngInformNiResponse(LocEngAdapter* adapter,
+ GpsUserResponseType resp,
+ const void* data) :
+ LocMsg(), mAdapter(adapter),
+ mResponse(resp), mPayload(data)
+ {
+ locallog();
+ }
+ inline ~LocEngInformNiResponse()
+ {
+ // this is a bit weird since mPayload is not
+ // allocated by this class. But there is no better way.
+ // mPayload actually won't be NULL here.
+ free((void*)mPayload);
+ }
+ inline virtual void proc() const
+ {
+ mAdapter->informNiResponse(mResponse, mPayload);
+ }
+ inline void locallog() const
+ {
+ LOC_LOGV("LocEngInformNiResponse - "
+ "response: %s\n mPayload: %p",
+ loc_get_ni_response_name(mResponse),
+ mPayload);
+ }
+ inline virtual void log() const
+ {
+ locallog();
+ }
+};
+
+/*===========================================================================
+
+FUNCTION loc_eng_ni_request_handler
+
+DESCRIPTION
+ Displays the NI request and awaits user input. If a previous request is
+ in session, it is ignored.
+
+RETURN VALUE
+ none
+
+===========================================================================*/
+void loc_eng_ni_request_handler(loc_eng_data_s_type &loc_eng_data,
+ const GpsNiNotification *notif,
+ const void* passThrough)
+{
+ ENTRY_LOG();
+ char lcs_addr[32]; // Decoded LCS address for UMTS CP NI
+ loc_eng_ni_data_s_type* loc_eng_ni_data_p = &loc_eng_data.loc_eng_ni_data;
+ loc_eng_ni_session_s_type* pSession = NULL;
+
+ if (NULL == loc_eng_data.ni_notify_cb) {
+ EXIT_LOG(%s, "loc_eng_ni_init hasn't happened yet.");
+ return;
+ }
+
+ if (notif->ni_type == GPS_NI_TYPE_EMERGENCY_SUPL) {
+ if (NULL != loc_eng_ni_data_p->sessionEs.rawRequest) {
+ LOC_LOGW("loc_eng_ni_request_handler, supl es NI in progress, new supl es NI ignored, type: %d",
+ notif->ni_type);
+ if (NULL != passThrough) {
+ free((void*)passThrough);
+ }
+ } else {
+ pSession = &loc_eng_ni_data_p->sessionEs;
+ }
+ } else {
+ if (NULL != loc_eng_ni_data_p->session.rawRequest ||
+ NULL != loc_eng_ni_data_p->sessionEs.rawRequest) {
+ LOC_LOGW("loc_eng_ni_request_handler, supl NI in progress, new supl NI ignored, type: %d",
+ notif->ni_type);
+ if (NULL != passThrough) {
+ free((void*)passThrough);
+ }
+ } else {
+ pSession = &loc_eng_ni_data_p->session;
+ }
+ }
+
+
+ if (pSession) {
+ /* Save request */
+ pSession->rawRequest = (void*)passThrough;
+ pSession->reqID = ++loc_eng_ni_data_p->reqIDCounter;
+ pSession->adapter = loc_eng_data.adapter;
+
+ /* Fill in notification */
+ ((GpsNiNotification*)notif)->notification_id = pSession->reqID;
+
+ if (notif->notify_flags == GPS_NI_PRIVACY_OVERRIDE)
+ {
+ loc_eng_mute_one_session(loc_eng_data);
+ }
+
+ /* Log requestor ID and text for debugging */
+ LOC_LOGI("Notification: notif_type: %d, timeout: %d, default_resp: %d", notif->ni_type, notif->timeout, notif->default_response);
+ LOC_LOGI(" requestor_id: %s (encoding: %d)", notif->requestor_id, notif->requestor_id_encoding);
+ LOC_LOGI(" text: %s text (encoding: %d)", notif->text, notif->text_encoding);
+ if (notif->extras[0])
+ {
+ LOC_LOGI(" extras: %s", notif->extras);
+ }
+
+ /* For robustness, spawn a thread at this point to timeout to clear up the notification status, even though
+ * the OEM layer in java does not do so.
+ **/
+ pSession->respTimeLeft = 5 + (notif->timeout != 0 ? notif->timeout : LOC_NI_NO_RESPONSE_TIME);
+ LOC_LOGI("Automatically sends 'no response' in %d seconds (to clear status)\n", pSession->respTimeLeft);
+
+ int rc = 0;
+ rc = pthread_create(&pSession->thread, NULL, ni_thread_proc, pSession);
+ if (rc)
+ {
+ LOC_LOGE("Loc NI thread is not created.\n");
+ }
+ rc = pthread_detach(pSession->thread);
+ if (rc)
+ {
+ LOC_LOGE("Loc NI thread is not detached.\n");
+ }
+
+ CALLBACK_LOG_CALLFLOW("ni_notify_cb - id", %d, notif->notification_id);
+ loc_eng_data.ni_notify_cb((GpsNiNotification*)notif);
+ }
+ EXIT_LOG(%s, VOID_RET);
+}
+
+/*===========================================================================
+
+FUNCTION ni_thread_proc
+
+===========================================================================*/
+static void* ni_thread_proc(void *args)
+{
+ ENTRY_LOG();
+
+ loc_eng_ni_session_s_type* pSession = (loc_eng_ni_session_s_type*)args;
+ int rc = 0; /* return code from pthread calls */
+
+ struct timeval present_time;
+ struct timespec expire_time;
+
+ LOC_LOGD("Starting Loc NI thread...\n");
+ pthread_mutex_lock(&pSession->tLock);
+ /* Calculate absolute expire time */
+ gettimeofday(&present_time, NULL);
+ expire_time.tv_sec = present_time.tv_sec + pSession->respTimeLeft;
+ expire_time.tv_nsec = present_time.tv_usec * 1000;
+ LOC_LOGD("ni_thread_proc-Time out set for abs time %ld with delay %d sec\n",
+ (long) expire_time.tv_sec, pSession->respTimeLeft );
+
+ while (!pSession->respRecvd)
+ {
+ rc = pthread_cond_timedwait(&pSession->tCond,
+ &pSession->tLock,
+ &expire_time);
+ if (rc == ETIMEDOUT)
+ {
+ pSession->resp = GPS_NI_RESPONSE_NORESP;
+ LOC_LOGD("ni_thread_proc-Thread time out after valting for specified time. Ret Val %d\n",rc );
+ break;
+ }
+ }
+ LOC_LOGD("ni_thread_proc-Java layer has sent us a user response and return value from "
+ "pthread_cond_timedwait = %d\n",rc );
+ pSession->respRecvd = FALSE; /* Reset the user response flag for the next session*/
+
+ LOC_LOGD("pSession->resp is %d\n",pSession->resp);
+
+ // adding this check to support modem restart, in which case, we need the thread
+ // to exit without calling sending data. We made sure that rawRequest is NULL in
+ // loc_eng_ni_reset_on_engine_restart()
+ LocEngAdapter* adapter = pSession->adapter;
+ LocEngInformNiResponse *msg = NULL;
+
+ if (NULL != pSession->rawRequest) {
+ if (pSession->resp != GPS_NI_RESPONSE_IGNORE) {
+ LOC_LOGD("pSession->resp != GPS_NI_RESPONSE_IGNORE \n");
+ msg = new LocEngInformNiResponse(adapter,
+ pSession->resp,
+ pSession->rawRequest);
+ } else {
+ LOC_LOGD("this is the ignore reply for SUPL ES\n");
+ free(pSession->rawRequest);
+ }
+ pSession->rawRequest = NULL;
+ }
+ pthread_mutex_unlock(&pSession->tLock);
+
+ pSession->respTimeLeft = 0;
+ pSession->reqID = 0;
+
+ if (NULL != msg) {
+ LOC_LOGD("ni_thread_proc: adapter->sendMsg(msg)\n");
+ adapter->sendMsg(msg);
+ }
+
+ EXIT_LOG(%s, VOID_RET);
+ return NULL;
+}
+
+void loc_eng_ni_reset_on_engine_restart(loc_eng_data_s_type &loc_eng_data)
+{
+ ENTRY_LOG();
+ loc_eng_ni_data_s_type* loc_eng_ni_data_p = &loc_eng_data.loc_eng_ni_data;
+
+ if (NULL == loc_eng_data.ni_notify_cb) {
+ EXIT_LOG(%s, "loc_eng_ni_init hasn't happened yet.");
+ return;
+ }
+
+ // only if modem has requested but then died.
+ if (NULL != loc_eng_ni_data_p->sessionEs.rawRequest) {
+ free(loc_eng_ni_data_p->sessionEs.rawRequest);
+ loc_eng_ni_data_p->sessionEs.rawRequest = NULL;
+
+ pthread_mutex_lock(&loc_eng_ni_data_p->sessionEs.tLock);
+ // the goal is to wake up ni_thread_proc
+ // and let it exit.
+ loc_eng_ni_data_p->sessionEs.respRecvd = TRUE;
+ pthread_cond_signal(&loc_eng_ni_data_p->sessionEs.tCond);
+ pthread_mutex_unlock(&loc_eng_ni_data_p->sessionEs.tLock);
+ }
+
+ if (NULL != loc_eng_ni_data_p->session.rawRequest) {
+ free(loc_eng_ni_data_p->session.rawRequest);
+ loc_eng_ni_data_p->session.rawRequest = NULL;
+
+ pthread_mutex_lock(&loc_eng_ni_data_p->session.tLock);
+ // the goal is to wake up ni_thread_proc
+ // and let it exit.
+ loc_eng_ni_data_p->session.respRecvd = TRUE;
+ pthread_cond_signal(&loc_eng_ni_data_p->session.tCond);
+ pthread_mutex_unlock(&loc_eng_ni_data_p->session.tLock);
+ }
+
+ EXIT_LOG(%s, VOID_RET);
+}
+
+/*===========================================================================
+FUNCTION loc_eng_ni_init
+
+DESCRIPTION
+ This function initializes the NI interface
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ None
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+void loc_eng_ni_init(loc_eng_data_s_type &loc_eng_data, GpsNiExtCallbacks *callbacks)
+{
+ ENTRY_LOG_CALLFLOW();
+
+ if(callbacks == NULL)
+ EXIT_LOG(%s, "loc_eng_ni_init: failed, cb is NULL");
+ else if (NULL == callbacks->notify_cb) {
+ EXIT_LOG(%s, "loc_eng_ni_init: failed, no cb.");
+ } else if (NULL != loc_eng_data.ni_notify_cb) {
+ EXIT_LOG(%s, "loc_eng_ni_init: already inited.");
+ } else {
+ loc_eng_ni_data_s_type* loc_eng_ni_data_p = &loc_eng_data.loc_eng_ni_data;
+ loc_eng_ni_data_p->sessionEs.respTimeLeft = 0;
+ loc_eng_ni_data_p->sessionEs.respRecvd = FALSE;
+ loc_eng_ni_data_p->sessionEs.rawRequest = NULL;
+ loc_eng_ni_data_p->sessionEs.reqID = 0;
+ pthread_cond_init(&loc_eng_ni_data_p->sessionEs.tCond, NULL);
+ pthread_mutex_init(&loc_eng_ni_data_p->sessionEs.tLock, NULL);
+
+ loc_eng_ni_data_p->session.respTimeLeft = 0;
+ loc_eng_ni_data_p->session.respRecvd = FALSE;
+ loc_eng_ni_data_p->session.rawRequest = NULL;
+ loc_eng_ni_data_p->session.reqID = 0;
+ pthread_cond_init(&loc_eng_ni_data_p->session.tCond, NULL);
+ pthread_mutex_init(&loc_eng_ni_data_p->session.tLock, NULL);
+
+ loc_eng_data.ni_notify_cb = callbacks->notify_cb;
+ EXIT_LOG(%s, VOID_RET);
+ }
+}
+
+/*===========================================================================
+FUNCTION loc_eng_ni_respond
+
+DESCRIPTION
+ This function receives user response from upper layer framework
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ None
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+void loc_eng_ni_respond(loc_eng_data_s_type &loc_eng_data,
+ int notif_id, GpsUserResponseType user_response)
+{
+ ENTRY_LOG_CALLFLOW();
+ loc_eng_ni_data_s_type* loc_eng_ni_data_p = &loc_eng_data.loc_eng_ni_data;
+ loc_eng_ni_session_s_type* pSession = NULL;
+
+ if (NULL == loc_eng_data.ni_notify_cb) {
+ EXIT_LOG(%s, "loc_eng_ni_init hasn't happened yet.");
+ return;
+ }
+
+ if (notif_id == loc_eng_ni_data_p->sessionEs.reqID &&
+ NULL != loc_eng_ni_data_p->sessionEs.rawRequest) {
+ pSession = &loc_eng_ni_data_p->sessionEs;
+ // ignore any SUPL NI non-Es session if a SUPL NI ES is accepted
+ if (user_response == GPS_NI_RESPONSE_ACCEPT &&
+ NULL != loc_eng_ni_data_p->session.rawRequest) {
+ pthread_mutex_lock(&loc_eng_ni_data_p->session.tLock);
+ loc_eng_ni_data_p->session.resp = GPS_NI_RESPONSE_IGNORE;
+ loc_eng_ni_data_p->session.respRecvd = TRUE;
+ pthread_cond_signal(&loc_eng_ni_data_p->session.tCond);
+ pthread_mutex_unlock(&loc_eng_ni_data_p->session.tLock);
+ }
+ } else if (notif_id == loc_eng_ni_data_p->session.reqID &&
+ NULL != loc_eng_ni_data_p->session.rawRequest) {
+ pSession = &loc_eng_ni_data_p->session;
+ }
+
+ if (pSession) {
+ LOC_LOGI("loc_eng_ni_respond: send user response %d for notif %d", user_response, notif_id);
+ pthread_mutex_lock(&pSession->tLock);
+ pSession->resp = user_response;
+ pSession->respRecvd = TRUE;
+ pthread_cond_signal(&pSession->tCond);
+ pthread_mutex_unlock(&pSession->tLock);
+ }
+ else {
+ LOC_LOGE("loc_eng_ni_respond: notif_id %d not an active session", notif_id);
+ }
+
+ EXIT_LOG(%s, VOID_RET);
+}
diff --git a/gps/loc_api/libloc_api_50001/loc_eng_ni.h b/gps/loc_api/libloc_api_50001/loc_eng_ni.h
new file mode 100644
index 0000000..068f5cd
--- /dev/null
+++ b/gps/loc_api/libloc_api_50001/loc_eng_ni.h
@@ -0,0 +1,59 @@
+/* Copyright (c) 2009,2011,2014 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_NI_H
+#define LOC_ENG_NI_H
+
+#include <stdbool.h>
+#include <LocEngAdapter.h>
+
+#define LOC_NI_NO_RESPONSE_TIME 20 /* secs */
+#define LOC_NI_NOTIF_KEY_ADDRESS "Address"
+#define GPS_NI_RESPONSE_IGNORE 4
+
+typedef struct {
+ pthread_t thread; /* NI thread */
+ int respTimeLeft; /* examine time for NI response */
+ bool respRecvd; /* NI User reponse received or not from Java layer*/
+ void* rawRequest;
+ int reqID; /* ID to check against response */
+ GpsUserResponseType resp;
+ pthread_cond_t tCond;
+ pthread_mutex_t tLock;
+ LocEngAdapter* adapter;
+} loc_eng_ni_session_s_type;
+
+typedef struct {
+ loc_eng_ni_session_s_type session; /* SUPL NI Session */
+ loc_eng_ni_session_s_type sessionEs; /* Emergency SUPL NI Session */
+ int reqIDCounter;
+} loc_eng_ni_data_s_type;
+
+
+#endif /* LOC_ENG_NI_H */
diff --git a/gps/loc_api/libloc_api_50001/loc_eng_nmea.cpp b/gps/loc_api/libloc_api_50001/loc_eng_nmea.cpp
new file mode 100644
index 0000000..4c6b9a3
--- /dev/null
+++ b/gps/loc_api/libloc_api_50001/loc_eng_nmea.cpp
@@ -0,0 +1,836 @@
+/* Copyright (c) 2012, 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_eng_nmea"
+#define GPS_PRN_START 1
+#define GPS_PRN_END 32
+#define GLONASS_PRN_START 65
+#define GLONASS_PRN_END 96
+#include <loc_eng.h>
+#include <loc_eng_nmea.h>
+#include <math.h>
+#include "log_util.h"
+
+/*===========================================================================
+FUNCTION loc_eng_nmea_send
+
+DESCRIPTION
+ send out NMEA sentence
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ Total length of the nmea sentence
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+void loc_eng_nmea_send(char *pNmea, int length, loc_eng_data_s_type *loc_eng_data_p)
+{
+ struct timeval tv;
+ gettimeofday(&tv, (struct timezone *) NULL);
+ int64_t now = tv.tv_sec * 1000LL + tv.tv_usec / 1000;
+ CALLBACK_LOG_CALLFLOW("nmea_cb", %p, pNmea);
+ if (loc_eng_data_p->nmea_cb != NULL)
+ loc_eng_data_p->nmea_cb(now, pNmea, length);
+ LOC_LOGD("NMEA <%s", pNmea);
+}
+
+/*===========================================================================
+FUNCTION loc_eng_nmea_put_checksum
+
+DESCRIPTION
+ Generate NMEA sentences generated based on position report
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ Total length of the nmea sentence
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_nmea_put_checksum(char *pNmea, int maxSize)
+{
+ uint8_t checksum = 0;
+ int length = 0;
+
+ pNmea++; //skip the $
+ while (*pNmea != '\0')
+ {
+ checksum ^= *pNmea++;
+ length++;
+ }
+
+ int checksumLength = snprintf(pNmea,(maxSize-length-1),"*%02X\r\n", checksum);
+ return (length + checksumLength);
+}
+
+/*===========================================================================
+FUNCTION loc_eng_nmea_generate_pos
+
+DESCRIPTION
+ Generate NMEA sentences generated based on position report
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ 0
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+void loc_eng_nmea_generate_pos(loc_eng_data_s_type *loc_eng_data_p,
+ const UlpLocation &location,
+ const GpsLocationExtended &locationExtended,
+ unsigned char generate_nmea)
+{
+ ENTRY_LOG();
+ time_t utcTime(location.gpsLocation.timestamp/1000);
+ tm * pTm = gmtime(&utcTime);
+ if (NULL == pTm) {
+ LOC_LOGE("gmtime failed");
+ return;
+ }
+
+ char sentence[NMEA_SENTENCE_MAX_LENGTH] = {0};
+ char* pMarker = sentence;
+ int lengthRemaining = sizeof(sentence);
+ int length = 0;
+ int utcYear = pTm->tm_year % 100; // 2 digit year
+ int utcMonth = pTm->tm_mon + 1; // tm_mon starts at zero
+ int utcDay = pTm->tm_mday;
+ int utcHours = pTm->tm_hour;
+ int utcMinutes = pTm->tm_min;
+ int utcSeconds = pTm->tm_sec;
+
+ if (generate_nmea) {
+ // ------------------
+ // ------$GPGSA------
+ // ------------------
+
+ uint32_t svUsedCount = 0;
+ uint32_t svUsedList[32] = {0};
+ uint32_t mask = loc_eng_data_p->sv_used_mask;
+ for (uint8_t i = 1; mask > 0 && svUsedCount < 32; i++)
+ {
+ if (mask & 1)
+ svUsedList[svUsedCount++] = i;
+ mask = mask >> 1;
+ }
+ // clear the cache so they can't be used again
+ loc_eng_data_p->sv_used_mask = 0;
+
+ char fixType;
+ if (svUsedCount == 0)
+ fixType = '1'; // no fix
+ else if (svUsedCount <= 3)
+ fixType = '2'; // 2D fix
+ else
+ fixType = '3'; // 3D fix
+
+ length = snprintf(pMarker, lengthRemaining, "$GPGSA,A,%c,", fixType);
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ for (uint8_t i = 0; i < 12; i++) // only the first 12 sv go in sentence
+ {
+ if (i < svUsedCount)
+ length = snprintf(pMarker, lengthRemaining, "%02d,", svUsedList[i]);
+ else
+ length = snprintf(pMarker, lengthRemaining, ",");
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+ }
+
+ if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_DOP)
+ { // dop is in locationExtended, (QMI)
+ length = snprintf(pMarker, lengthRemaining, "%.1f,%.1f,%.1f",
+ locationExtended.pdop,
+ locationExtended.hdop,
+ locationExtended.vdop);
+ }
+ else if (loc_eng_data_p->pdop > 0 && loc_eng_data_p->hdop > 0 && loc_eng_data_p->vdop > 0)
+ { // dop was cached from sv report (RPC)
+ length = snprintf(pMarker, lengthRemaining, "%.1f,%.1f,%.1f",
+ loc_eng_data_p->pdop,
+ loc_eng_data_p->hdop,
+ loc_eng_data_p->vdop);
+ }
+ else
+ { // no dop
+ length = snprintf(pMarker, lengthRemaining, ",,");
+ }
+
+ length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
+ loc_eng_nmea_send(sentence, length, loc_eng_data_p);
+
+ // ------------------
+ // ------$GPVTG------
+ // ------------------
+
+ pMarker = sentence;
+ lengthRemaining = sizeof(sentence);
+
+ if (location.gpsLocation.flags & GPS_LOCATION_HAS_BEARING)
+ {
+ float magTrack = location.gpsLocation.bearing;
+ if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_MAG_DEV)
+ {
+ float magTrack = location.gpsLocation.bearing - locationExtended.magneticDeviation;
+ if (magTrack < 0.0)
+ magTrack += 360.0;
+ else if (magTrack > 360.0)
+ magTrack -= 360.0;
+ }
+
+ length = snprintf(pMarker, lengthRemaining, "$GPVTG,%.1lf,T,%.1lf,M,", location.gpsLocation.bearing, magTrack);
+ }
+ else
+ {
+ length = snprintf(pMarker, lengthRemaining, "$GPVTG,,T,,M,");
+ }
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if (location.gpsLocation.flags & GPS_LOCATION_HAS_SPEED)
+ {
+ float speedKnots = location.gpsLocation.speed * (3600.0/1852.0);
+ float speedKmPerHour = location.gpsLocation.speed * 3.6;
+
+ length = snprintf(pMarker, lengthRemaining, "%.1lf,N,%.1lf,K,", speedKnots, speedKmPerHour);
+ }
+ else
+ {
+ length = snprintf(pMarker, lengthRemaining, ",N,,K,");
+ }
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if (!(location.gpsLocation.flags & GPS_LOCATION_HAS_LAT_LONG))
+ length = snprintf(pMarker, lengthRemaining, "%c", 'N'); // N means no fix
+ else if (LOC_POSITION_MODE_STANDALONE == loc_eng_data_p->adapter->getPositionMode().mode)
+ length = snprintf(pMarker, lengthRemaining, "%c", 'A'); // A means autonomous
+ else
+ length = snprintf(pMarker, lengthRemaining, "%c", 'D'); // D means differential
+
+ length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
+ loc_eng_nmea_send(sentence, length, loc_eng_data_p);
+
+ // ------------------
+ // ------$GPRMC------
+ // ------------------
+
+ pMarker = sentence;
+ lengthRemaining = sizeof(sentence);
+
+ length = snprintf(pMarker, lengthRemaining, "$GPRMC,%02d%02d%02d,A," ,
+ utcHours, utcMinutes, utcSeconds);
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if (location.gpsLocation.flags & GPS_LOCATION_HAS_LAT_LONG)
+ {
+ double latitude = location.gpsLocation.latitude;
+ double longitude = location.gpsLocation.longitude;
+ char latHemisphere;
+ char lonHemisphere;
+ double latMinutes;
+ double lonMinutes;
+
+ if (latitude > 0)
+ {
+ latHemisphere = 'N';
+ }
+ else
+ {
+ latHemisphere = 'S';
+ latitude *= -1.0;
+ }
+
+ if (longitude < 0)
+ {
+ lonHemisphere = 'W';
+ longitude *= -1.0;
+ }
+ else
+ {
+ lonHemisphere = 'E';
+ }
+
+ latMinutes = fmod(latitude * 60.0 , 60.0);
+ lonMinutes = fmod(longitude * 60.0 , 60.0);
+
+ length = snprintf(pMarker, lengthRemaining, "%02d%09.6lf,%c,%03d%09.6lf,%c,",
+ (uint8_t)floor(latitude), latMinutes, latHemisphere,
+ (uint8_t)floor(longitude),lonMinutes, lonHemisphere);
+ }
+ else
+ {
+ length = snprintf(pMarker, lengthRemaining,",,,,");
+ }
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if (location.gpsLocation.flags & GPS_LOCATION_HAS_SPEED)
+ {
+ float speedKnots = location.gpsLocation.speed * (3600.0/1852.0);
+ length = snprintf(pMarker, lengthRemaining, "%.1lf,", speedKnots);
+ }
+ else
+ {
+ length = snprintf(pMarker, lengthRemaining, ",");
+ }
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if (location.gpsLocation.flags & GPS_LOCATION_HAS_BEARING)
+ {
+ length = snprintf(pMarker, lengthRemaining, "%.1lf,", location.gpsLocation.bearing);
+ }
+ else
+ {
+ length = snprintf(pMarker, lengthRemaining, ",");
+ }
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ length = snprintf(pMarker, lengthRemaining, "%2.2d%2.2d%2.2d,",
+ utcDay, utcMonth, utcYear);
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_MAG_DEV)
+ {
+ float magneticVariation = locationExtended.magneticDeviation;
+ char direction;
+ if (magneticVariation < 0.0)
+ {
+ direction = 'W';
+ magneticVariation *= -1.0;
+ }
+ else
+ {
+ direction = 'E';
+ }
+
+ length = snprintf(pMarker, lengthRemaining, "%.1lf,%c,",
+ magneticVariation, direction);
+ }
+ else
+ {
+ length = snprintf(pMarker, lengthRemaining, ",,");
+ }
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if (!(location.gpsLocation.flags & GPS_LOCATION_HAS_LAT_LONG))
+ length = snprintf(pMarker, lengthRemaining, "%c", 'N'); // N means no fix
+ else if (LOC_POSITION_MODE_STANDALONE == loc_eng_data_p->adapter->getPositionMode().mode)
+ length = snprintf(pMarker, lengthRemaining, "%c", 'A'); // A means autonomous
+ else
+ length = snprintf(pMarker, lengthRemaining, "%c", 'D'); // D means differential
+
+ length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
+ loc_eng_nmea_send(sentence, length, loc_eng_data_p);
+
+ // ------------------
+ // ------$GPGGA------
+ // ------------------
+
+ pMarker = sentence;
+ lengthRemaining = sizeof(sentence);
+
+ length = snprintf(pMarker, lengthRemaining, "$GPGGA,%02d%02d%02d," ,
+ utcHours, utcMinutes, utcSeconds);
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if (location.gpsLocation.flags & GPS_LOCATION_HAS_LAT_LONG)
+ {
+ double latitude = location.gpsLocation.latitude;
+ double longitude = location.gpsLocation.longitude;
+ char latHemisphere;
+ char lonHemisphere;
+ double latMinutes;
+ double lonMinutes;
+
+ if (latitude > 0)
+ {
+ latHemisphere = 'N';
+ }
+ else
+ {
+ latHemisphere = 'S';
+ latitude *= -1.0;
+ }
+
+ if (longitude < 0)
+ {
+ lonHemisphere = 'W';
+ longitude *= -1.0;
+ }
+ else
+ {
+ lonHemisphere = 'E';
+ }
+
+ latMinutes = fmod(latitude * 60.0 , 60.0);
+ lonMinutes = fmod(longitude * 60.0 , 60.0);
+
+ length = snprintf(pMarker, lengthRemaining, "%02d%09.6lf,%c,%03d%09.6lf,%c,",
+ (uint8_t)floor(latitude), latMinutes, latHemisphere,
+ (uint8_t)floor(longitude),lonMinutes, lonHemisphere);
+ }
+ else
+ {
+ length = snprintf(pMarker, lengthRemaining,",,,,");
+ }
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ char gpsQuality;
+ if (!(location.gpsLocation.flags & GPS_LOCATION_HAS_LAT_LONG))
+ gpsQuality = '0'; // 0 means no fix
+ else if (LOC_POSITION_MODE_STANDALONE == loc_eng_data_p->adapter->getPositionMode().mode)
+ gpsQuality = '1'; // 1 means GPS fix
+ else
+ gpsQuality = '2'; // 2 means DGPS fix
+
+ if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_DOP)
+ { // dop is in locationExtended, (QMI)
+ length = snprintf(pMarker, lengthRemaining, "%c,%02d,%.1f,",
+ gpsQuality, svUsedCount, locationExtended.hdop);
+ }
+ else if (loc_eng_data_p->pdop > 0 && loc_eng_data_p->hdop > 0 && loc_eng_data_p->vdop > 0)
+ { // dop was cached from sv report (RPC)
+ length = snprintf(pMarker, lengthRemaining, "%c,%02d,%.1f,",
+ gpsQuality, svUsedCount, loc_eng_data_p->hdop);
+ }
+ else
+ { // no hdop
+ length = snprintf(pMarker, lengthRemaining, "%c,%02d,,",
+ gpsQuality, svUsedCount);
+ }
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL)
+ {
+ length = snprintf(pMarker, lengthRemaining, "%.1lf,M,",
+ locationExtended.altitudeMeanSeaLevel);
+ }
+ else
+ {
+ length = snprintf(pMarker, lengthRemaining,",,");
+ }
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if ((location.gpsLocation.flags & GPS_LOCATION_HAS_ALTITUDE) &&
+ (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL))
+ {
+ length = snprintf(pMarker, lengthRemaining, "%.1lf,M,,",
+ location.gpsLocation.altitude - locationExtended.altitudeMeanSeaLevel);
+ }
+ else
+ {
+ length = snprintf(pMarker, lengthRemaining,",,,");
+ }
+
+ length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
+ loc_eng_nmea_send(sentence, length, loc_eng_data_p);
+
+ }
+ //Send blank NMEA reports for non-final fixes
+ else {
+ strlcpy(sentence, "$GPGSA,A,1,,,,,,,,,,,,,,,", sizeof(sentence));
+ length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
+ loc_eng_nmea_send(sentence, length, loc_eng_data_p);
+
+ strlcpy(sentence, "$GPVTG,,T,,M,,N,,K,N", sizeof(sentence));
+ length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
+ loc_eng_nmea_send(sentence, length, loc_eng_data_p);
+
+ strlcpy(sentence, "$GPRMC,,V,,,,,,,,,,N", sizeof(sentence));
+ length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
+ loc_eng_nmea_send(sentence, length, loc_eng_data_p);
+
+ strlcpy(sentence, "$GPGGA,,,,,,0,,,,,,,,", sizeof(sentence));
+ length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
+ loc_eng_nmea_send(sentence, length, loc_eng_data_p);
+ }
+ // clear the dop cache so they can't be used again
+ loc_eng_data_p->pdop = 0;
+ loc_eng_data_p->hdop = 0;
+ loc_eng_data_p->vdop = 0;
+
+ EXIT_LOG(%d, 0);
+}
+
+
+
+/*===========================================================================
+FUNCTION loc_eng_nmea_generate_sv
+
+DESCRIPTION
+ Generate NMEA sentences generated based on sv report
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ 0
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+void loc_eng_nmea_generate_sv(loc_eng_data_s_type *loc_eng_data_p,
+ const GpsSvStatus &svStatus, const GpsLocationExtended &locationExtended)
+{
+ ENTRY_LOG();
+
+ char sentence[NMEA_SENTENCE_MAX_LENGTH] = {0};
+ char* pMarker = sentence;
+ int lengthRemaining = sizeof(sentence);
+ int length = 0;
+ int svCount = svStatus.num_svs;
+ int sentenceCount = 0;
+ int sentenceNumber = 1;
+ int svNumber = 1;
+ int gpsCount = 0;
+ int glnCount = 0;
+
+ //Count GPS SVs for saparating GPS from GLONASS and throw others
+
+ for(svNumber=1; svNumber <= svCount; svNumber++) {
+ if( (svStatus.sv_list[svNumber-1].prn >= GPS_PRN_START)&&
+ (svStatus.sv_list[svNumber-1].prn <= GPS_PRN_END) )
+ {
+ gpsCount++;
+ }
+ else if( (svStatus.sv_list[svNumber-1].prn >= GLONASS_PRN_START) &&
+ (svStatus.sv_list[svNumber-1].prn <= GLONASS_PRN_END) )
+ {
+ glnCount++;
+ }
+ }
+
+ // ------------------
+ // ------$GPGSV------
+ // ------------------
+
+ if (gpsCount <= 0)
+ {
+ // no svs in view, so just send a blank $GPGSV sentence
+ strlcpy(sentence, "$GPGSV,1,1,0,", sizeof(sentence));
+ length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
+ loc_eng_nmea_send(sentence, length, loc_eng_data_p);
+ }
+ else
+ {
+ svNumber = 1;
+ sentenceNumber = 1;
+ sentenceCount = gpsCount/4 + (gpsCount % 4 != 0);
+
+ while (sentenceNumber <= sentenceCount)
+ {
+ pMarker = sentence;
+ lengthRemaining = sizeof(sentence);
+
+ length = snprintf(pMarker, lengthRemaining, "$GPGSV,%d,%d,%02d",
+ sentenceCount, sentenceNumber, gpsCount);
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ for (int i=0; (svNumber <= svCount) && (i < 4); svNumber++)
+ {
+ if( (svStatus.sv_list[svNumber-1].prn >= GPS_PRN_START) &&
+ (svStatus.sv_list[svNumber-1].prn <= GPS_PRN_END) )
+ {
+ length = snprintf(pMarker, lengthRemaining,",%02d,%02d,%03d,",
+ svStatus.sv_list[svNumber-1].prn,
+ (int)(0.5 + svStatus.sv_list[svNumber-1].elevation), //float to int
+ (int)(0.5 + svStatus.sv_list[svNumber-1].azimuth)); //float to int
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if (svStatus.sv_list[svNumber-1].snr > 0)
+ {
+ length = snprintf(pMarker, lengthRemaining,"%02d",
+ (int)(0.5 + svStatus.sv_list[svNumber-1].snr)); //float to int
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+ }
+
+ i++;
+ }
+
+ }
+
+ length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
+ loc_eng_nmea_send(sentence, length, loc_eng_data_p);
+ sentenceNumber++;
+
+ } //while
+
+ } //if
+
+ // ------------------
+ // ------$GLGSV------
+ // ------------------
+
+ if (glnCount <= 0)
+ {
+ // no svs in view, so just send a blank $GLGSV sentence
+ strlcpy(sentence, "$GLGSV,1,1,0,", sizeof(sentence));
+ length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
+ loc_eng_nmea_send(sentence, length, loc_eng_data_p);
+ }
+ else
+ {
+ svNumber = 1;
+ sentenceNumber = 1;
+ sentenceCount = glnCount/4 + (glnCount % 4 != 0);
+
+ while (sentenceNumber <= sentenceCount)
+ {
+ pMarker = sentence;
+ lengthRemaining = sizeof(sentence);
+
+ length = snprintf(pMarker, lengthRemaining, "$GLGSV,%d,%d,%02d",
+ sentenceCount, sentenceNumber, glnCount);
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ for (int i=0; (svNumber <= svCount) && (i < 4); svNumber++)
+ {
+ if( (svStatus.sv_list[svNumber-1].prn >= GLONASS_PRN_START) &&
+ (svStatus.sv_list[svNumber-1].prn <= GLONASS_PRN_END) ) {
+
+ length = snprintf(pMarker, lengthRemaining,",%02d,%02d,%03d,",
+ svStatus.sv_list[svNumber-1].prn,
+ (int)(0.5 + svStatus.sv_list[svNumber-1].elevation), //float to int
+ (int)(0.5 + svStatus.sv_list[svNumber-1].azimuth)); //float to int
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if (svStatus.sv_list[svNumber-1].snr > 0)
+ {
+ length = snprintf(pMarker, lengthRemaining,"%02d",
+ (int)(0.5 + svStatus.sv_list[svNumber-1].snr)); //float to int
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+ }
+
+ i++;
+ }
+
+ }
+
+ length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
+ loc_eng_nmea_send(sentence, length, loc_eng_data_p);
+ sentenceNumber++;
+
+ } //while
+
+ }//if
+
+ if (svStatus.used_in_fix_mask == 0)
+ { // No sv used, so there will be no position report, so send
+ // blank NMEA sentences
+ strlcpy(sentence, "$GPGSA,A,1,,,,,,,,,,,,,,,", sizeof(sentence));
+ length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
+ loc_eng_nmea_send(sentence, length, loc_eng_data_p);
+
+ strlcpy(sentence, "$GPVTG,,T,,M,,N,,K,N", sizeof(sentence));
+ length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
+ loc_eng_nmea_send(sentence, length, loc_eng_data_p);
+
+ strlcpy(sentence, "$GPRMC,,V,,,,,,,,,,N", sizeof(sentence));
+ length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
+ loc_eng_nmea_send(sentence, length, loc_eng_data_p);
+
+ strlcpy(sentence, "$GPGGA,,,,,,0,,,,,,,,", sizeof(sentence));
+ length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
+ loc_eng_nmea_send(sentence, length, loc_eng_data_p);
+ }
+ else
+ { // cache the used in fix mask, as it will be needed to send $GPGSA
+ // during the position report
+ loc_eng_data_p->sv_used_mask = svStatus.used_in_fix_mask;
+
+ // For RPC, the DOP are sent during sv report, so cache them
+ // now to be sent during position report.
+ // For QMI, the DOP will be in position report.
+ if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_DOP)
+ {
+ loc_eng_data_p->pdop = locationExtended.pdop;
+ loc_eng_data_p->hdop = locationExtended.hdop;
+ loc_eng_data_p->vdop = locationExtended.vdop;
+ }
+ else
+ {
+ loc_eng_data_p->pdop = 0;
+ loc_eng_data_p->hdop = 0;
+ loc_eng_data_p->vdop = 0;
+ }
+
+ }
+
+ EXIT_LOG(%d, 0);
+}
diff --git a/gps/loc_api/libloc_api_50001/loc_eng_nmea.h b/gps/loc_api/libloc_api_50001/loc_eng_nmea.h
new file mode 100644
index 0000000..c8f3b0e
--- /dev/null
+++ b/gps/loc_api/libloc_api_50001/loc_eng_nmea.h
@@ -0,0 +1,42 @@
+/* Copyright (c) 2012, 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_NMEA_H
+#define LOC_ENG_NMEA_H
+
+#include "hardware/gps.h"
+
+#define NMEA_SENTENCE_MAX_LENGTH 200
+
+void loc_eng_nmea_send(char *pNmea, int length, loc_eng_data_s_type *loc_eng_data_p);
+int loc_eng_nmea_put_checksum(char *pNmea, int maxSize);
+void loc_eng_nmea_generate_sv(loc_eng_data_s_type *loc_eng_data_p, const GpsSvStatus &svStatus, const GpsLocationExtended &locationExtended);
+void loc_eng_nmea_generate_pos(loc_eng_data_s_type *loc_eng_data_p, const UlpLocation &location, const GpsLocationExtended &locationExtended, unsigned char generate_nmea);
+
+#endif // LOC_ENG_NMEA_H
diff --git a/gps/loc_api/libloc_api_50001/loc_eng_xtra.cpp b/gps/loc_api/libloc_api_50001/loc_eng_xtra.cpp
new file mode 100644
index 0000000..7bb8083
--- /dev/null
+++ b/gps/loc_api/libloc_api_50001/loc_eng_xtra.cpp
@@ -0,0 +1,213 @@
+/* Copyright (c) 2009-2013, 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_eng"
+
+#include <loc_eng.h>
+#include <MsgTask.h>
+#include "log_util.h"
+#include "platform_lib_includes.h"
+
+using namespace loc_core;
+
+struct LocEngRequestXtraServer : public LocMsg {
+ LocEngAdapter* mAdapter;
+ inline LocEngRequestXtraServer(LocEngAdapter* adapter) :
+ LocMsg(), mAdapter(adapter)
+ {
+ locallog();
+ }
+ inline virtual void proc() const {
+ mAdapter->requestXtraServer();
+ }
+ inline void locallog() const {
+ LOC_LOGV("LocEngRequestXtraServer");
+ }
+ inline virtual void log() const {
+ locallog();
+ }
+};
+
+struct LocEngInjectXtraData : public LocMsg {
+ LocEngAdapter* mAdapter;
+ char* mData;
+ const int mLen;
+ inline LocEngInjectXtraData(LocEngAdapter* adapter,
+ char* data, int len):
+ LocMsg(), mAdapter(adapter),
+ mData(new char[len]), mLen(len)
+ {
+ memcpy((void*)mData, (void*)data, len);
+ locallog();
+ }
+ inline ~LocEngInjectXtraData()
+ {
+ delete[] mData;
+ }
+ inline virtual void proc() const {
+ mAdapter->setXtraData(mData, mLen);
+ }
+ inline void locallog() const {
+ LOC_LOGV("length: %d\n data: %p", mLen, mData);
+ }
+ inline virtual void log() const {
+ locallog();
+ }
+};
+
+struct LocEngSetXtraVersionCheck : public LocMsg {
+ LocEngAdapter *mAdapter;
+ int mCheck;
+ inline LocEngSetXtraVersionCheck(LocEngAdapter* adapter,
+ int check):
+ mAdapter(adapter), mCheck(check) {}
+ inline virtual void proc() const {
+ locallog();
+ mAdapter->setXtraVersionCheck(mCheck);
+ }
+ inline void locallog() const {
+ LOC_LOGD("%s:%d]: mCheck: %d",
+ __func__, __LINE__, mCheck);
+ }
+ inline virtual void log() const {
+ locallog();
+ }
+};
+
+/*===========================================================================
+FUNCTION loc_eng_xtra_init
+
+DESCRIPTION
+ Initialize XTRA module.
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ 0: success
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_xtra_init (loc_eng_data_s_type &loc_eng_data,
+ GpsXtraExtCallbacks* callbacks)
+{
+ int ret_val = -1;
+ loc_eng_xtra_data_s_type *xtra_module_data_ptr;
+ ENTRY_LOG();
+
+ if(callbacks == NULL) {
+ LOC_LOGE("loc_eng_xtra_init: failed, cb is NULL");
+ } else {
+ xtra_module_data_ptr = &loc_eng_data.xtra_module_data;
+ xtra_module_data_ptr->download_request_cb = callbacks->download_request_cb;
+ xtra_module_data_ptr->report_xtra_server_cb = callbacks->report_xtra_server_cb;
+
+ ret_val = 0;
+ }
+ EXIT_LOG(%d, ret_val);
+ return ret_val;
+}
+
+/*===========================================================================
+FUNCTION loc_eng_xtra_inject_data
+
+DESCRIPTION
+ Injects XTRA file into the engine but buffers the data if engine is busy.
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ 0
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_xtra_inject_data(loc_eng_data_s_type &loc_eng_data,
+ char* data, int length)
+{
+ ENTRY_LOG();
+ LocEngAdapter* adapter = loc_eng_data.adapter;
+ adapter->sendMsg(new LocEngInjectXtraData(adapter, data, length));
+ EXIT_LOG(%d, 0);
+ return 0;
+}
+/*===========================================================================
+FUNCTION loc_eng_xtra_request_server
+
+DESCRIPTION
+ Request the Xtra server url from the modem
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ 0
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_xtra_request_server(loc_eng_data_s_type &loc_eng_data)
+{
+ ENTRY_LOG();
+ LocEngAdapter* adapter = loc_eng_data.adapter;
+ adapter->sendMsg(new LocEngRequestXtraServer(adapter));
+ EXIT_LOG(%d, 0);
+ return 0;
+}
+/*===========================================================================
+FUNCTION loc_eng_xtra_version_check
+
+DESCRIPTION
+ Injects the enable/disable value for checking XTRA version
+ that is specified in gps.conf
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ none
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+void loc_eng_xtra_version_check(loc_eng_data_s_type &loc_eng_data,
+ int check)
+{
+ ENTRY_LOG();
+ LocEngAdapter *adapter = loc_eng_data.adapter;
+ adapter->sendMsg(new LocEngSetXtraVersionCheck(adapter, check));
+ EXIT_LOG(%d, 0);
+}
diff --git a/gps/loc_api/libloc_api_50001/loc_eng_xtra.h b/gps/loc_api/libloc_api_50001/loc_eng_xtra.h
new file mode 100644
index 0000000..d8f4641
--- /dev/null
+++ b/gps/loc_api/libloc_api_50001/loc_eng_xtra.h
@@ -0,0 +1,47 @@
+/* Copyright (c) 2009,2011 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_XTRA_H
+#define LOC_ENG_XTRA_H
+
+#include "hardware/gps.h"
+
+// Module data
+typedef struct
+{
+ // loc_eng_ioctl_cb_data_s_type ioctl_cb_data;
+ gps_xtra_download_request download_request_cb;
+ report_xtra_server report_xtra_server_cb;
+
+ // XTRA data buffer
+ char *xtra_data_for_injection; // NULL if no pending data
+ int xtra_data_len;
+} loc_eng_xtra_data_s_type;
+
+#endif // LOC_ENG_XTRA_H