summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk23
-rw-r--r--BoardCommonConfig.mk22
-rw-r--r--common.mk21
-rw-r--r--gps/Android.mk25
-rw-r--r--gps/CleanSpec.mk50
-rw-r--r--gps/NOTICE13
-rw-r--r--gps/libloc_api_50001/.loc_eng_msg_id.h.swpbin0 -> 16384 bytes
-rw-r--r--gps/libloc_api_50001/Android.mk130
-rw-r--r--gps/libloc_api_50001/LocApiAdapter.cpp238
-rw-r--r--gps/libloc_api_50001/LocApiAdapter.h242
-rw-r--r--gps/libloc_api_50001/gps.c68
-rw-r--r--gps/libloc_api_50001/loc.cpp1117
-rw-r--r--gps/libloc_api_50001/loc.h89
-rw-r--r--gps/libloc_api_50001/loc_eng.cpp2150
-rw-r--r--gps/libloc_api_50001/loc_eng.h252
-rw-r--r--gps/libloc_api_50001/loc_eng_agps.cpp737
-rw-r--r--gps/libloc_api_50001/loc_eng_agps.h324
-rw-r--r--gps/libloc_api_50001/loc_eng_dmn_conn.cpp238
-rw-r--r--gps/libloc_api_50001/loc_eng_dmn_conn.h57
-rw-r--r--gps/libloc_api_50001/loc_eng_dmn_conn_glue_msg.c223
-rw-r--r--gps/libloc_api_50001/loc_eng_dmn_conn_glue_msg.h51
-rw-r--r--gps/libloc_api_50001/loc_eng_dmn_conn_glue_pipe.c206
-rw-r--r--gps/libloc_api_50001/loc_eng_dmn_conn_glue_pipe.h50
-rw-r--r--gps/libloc_api_50001/loc_eng_dmn_conn_handler.cpp204
-rw-r--r--gps/libloc_api_50001/loc_eng_dmn_conn_handler.h101
-rw-r--r--gps/libloc_api_50001/loc_eng_dmn_conn_thread_helper.c398
-rw-r--r--gps/libloc_api_50001/loc_eng_dmn_conn_thread_helper.h74
-rw-r--r--gps/libloc_api_50001/loc_eng_log.cpp299
-rw-r--r--gps/libloc_api_50001/loc_eng_log.h60
-rw-r--r--gps/libloc_api_50001/loc_eng_msg.cpp133
-rw-r--r--gps/libloc_api_50001/loc_eng_msg.h861
-rw-r--r--gps/libloc_api_50001/loc_eng_msg_id.h133
-rw-r--r--gps/libloc_api_50001/loc_eng_ni.cpp313
-rw-r--r--gps/libloc_api_50001/loc_eng_ni.h50
-rw-r--r--gps/libloc_api_50001/loc_eng_xtra.cpp90
-rw-r--r--gps/libloc_api_50001/loc_eng_xtra.h46
-rw-r--r--gps/ulp/inc/ulp.h59
-rw-r--r--gps/utils/Android.mk45
-rw-r--r--gps/utils/linked_list.c328
-rw-r--r--gps/utils/linked_list.h217
-rw-r--r--gps/utils/loc_cfg.cpp310
-rw-r--r--gps/utils/loc_cfg.h88
-rw-r--r--gps/utils/loc_log.cpp183
-rw-r--r--gps/utils/loc_log.h66
-rw-r--r--gps/utils/log_util.h158
-rw-r--r--gps/utils/msg_q.c322
-rw-r--r--gps/utils/msg_q.h189
-rw-r--r--include/hardware/gps.h1050
48 files changed, 12103 insertions, 0 deletions
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..85d45ad
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,23 @@
+#
+# Copyright (C) 2013 The CyanogenMod Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+ifneq ($(filter i9305 t0lte i605 l900 r950,$(TARGET_DEVICE)),)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
+
+endif
diff --git a/BoardCommonConfig.mk b/BoardCommonConfig.mk
new file mode 100644
index 0000000..2796efc
--- /dev/null
+++ b/BoardCommonConfig.mk
@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2013 The CyanogenMod Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+COMMON_PATH := device/samsung/smdk4412-qcom-common
+
+TARGET_SPECIFIC_HEADER_PATH := device/samsung/smdk4412-qcom-common/include
+
+# GPS
+BOARD_HAVE_NEW_QC_GPS := true
diff --git a/common.mk b/common.mk
new file mode 100644
index 0000000..a121567
--- /dev/null
+++ b/common.mk
@@ -0,0 +1,21 @@
+#
+# Copyright (C) 2013 The CyanogenMod Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+COMMON_PATH := device/samsung/smdk4412-qcom-common
+
+# GPS
+PRODUCT_PACKAGES += \
+ gps.default
diff --git a/gps/Android.mk b/gps/Android.mk
new file mode 100644
index 0000000..a92484d
--- /dev/null
+++ b/gps/Android.mk
@@ -0,0 +1,25 @@
+#
+# Copyright (C) 2012 The Android Open-Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# WARNING: Everything listed here will be built on ALL platforms,
+# including x86, the emulator, and the SDK. Modules must be uniquely
+# named (liblights.tuna), and must build everywhere, or limit themselves
+# to only building on ARM if they include assembly. Individual makefiles
+# are responsible for having their own logic, for fine-grained control.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-subdir-makefiles,$(LOCAL_PATH))
diff --git a/gps/CleanSpec.mk b/gps/CleanSpec.mk
new file mode 100644
index 0000000..dd1849d
--- /dev/null
+++ b/gps/CleanSpec.mk
@@ -0,0 +1,50 @@
+# Copyright (C) 2007 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# If you don't need to do a full clean build but would like to touch
+# a file or delete some intermediate files, add a clean step to the end
+# of the list. These steps will only be run once, if they haven't been
+# run before.
+#
+# E.g.:
+# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
+# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
+#
+# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
+# files that are missing or have been moved.
+#
+# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
+# Use $(OUT_DIR) to refer to the "out" directory.
+#
+# If you need to re-do something that's already mentioned, just copy
+# the command and add it to the bottom of the list. E.g., if a change
+# that you made last week required touching a file and a change you
+# made today requires touching the same file, just copy the old
+# touch step and add it to the end of the list.
+#
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
+
+# For example:
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
+#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
+#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
+
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libloc_api*)
diff --git a/gps/NOTICE b/gps/NOTICE
new file mode 100644
index 0000000..85b5740
--- /dev/null
+++ b/gps/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/libloc_api_50001/.loc_eng_msg_id.h.swp b/gps/libloc_api_50001/.loc_eng_msg_id.h.swp
new file mode 100644
index 0000000..736dc2f
--- /dev/null
+++ b/gps/libloc_api_50001/.loc_eng_msg_id.h.swp
Binary files differ
diff --git a/gps/libloc_api_50001/Android.mk b/gps/libloc_api_50001/Android.mk
new file mode 100644
index 0000000..896f001
--- /dev/null
+++ b/gps/libloc_api_50001/Android.mk
@@ -0,0 +1,130 @@
+ifneq ($(BUILD_TINY_ANDROID),true)
+#Compile this library only for builds with the latest modem image
+
+BIT_ENABLED_BOARD_PLATFORM_LIST := msm7630_fusion
+BIT_ENABLED_BOARD_PLATFORM_LIST += msm8660
+BIT_ENABLED_BOARD_PLATFORM_LIST += msm8960
+ifeq ($(call is-board-platform-in-list,$(BIT_ENABLED_BOARD_PLATFORM_LIST)),true)
+FEATURE_GNSS_BIT_API := true
+endif # is-board-platform-in-list
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libloc_adapter
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SHARED_LIBRARIES := \
+ libutils \
+ libcutils \
+ libgps.utils \
+ libdl
+
+LOCAL_SRC_FILES += \
+ loc_eng_log.cpp \
+ LocApiAdapter.cpp
+
+LOCAL_CFLAGS += \
+ -fno-short-enums \
+ -D_ANDROID_ \
+ -DNEW_QC_GPS
+
+LOCAL_C_INCLUDES:= \
+ $(TARGET_OUT_HEADERS)/gps.utils
+
+LOCAL_COPY_HEADERS_TO:= libloc_eng/
+LOCAL_COPY_HEADERS:= \
+ LocApiAdapter.h \
+ loc.h \
+ loc_eng.h \
+ loc_eng_xtra.h \
+ loc_eng_ni.h \
+ loc_eng_agps.h \
+ loc_eng_msg.h \
+ loc_eng_msg_id.h \
+ loc_eng_log.h
+
+LOCAL_PRELINK_MODULE := false
+
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libloc_eng
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SHARED_LIBRARIES := \
+ libutils \
+ libcutils \
+ libloc_adapter \
+ libgps.utils
+
+LOCAL_SRC_FILES += \
+ loc_eng.cpp \
+ loc_eng_agps.cpp \
+ loc_eng_xtra.cpp \
+ loc_eng_ni.cpp \
+ loc_eng_log.cpp
+
+ifeq ($(FEATURE_GNSS_BIT_API), true)
+LOCAL_CFLAGS += -DFEATURE_GNSS_BIT_API
+endif # FEATURE_GNSS_BIT_API
+
+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_ \
+ -DNEW_QC_GPS
+
+LOCAL_C_INCLUDES:= \
+ $(TARGET_OUT_HEADERS)/gps.utils \
+ $(LOCAL_PATH)/../ulp/inc
+
+LOCAL_PRELINK_MODULE := false
+
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := gps.default
+
+LOCAL_MODULE_TAGS := optional
+
+## Libs
+
+LOCAL_SHARED_LIBRARIES := \
+ libutils \
+ libcutils \
+ libloc_eng \
+ libgps.utils \
+ libdl
+
+LOCAL_SRC_FILES += \
+ loc.cpp \
+ gps.c
+
+LOCAL_CFLAGS += \
+ -fno-short-enums \
+ -D_ANDROID_ \
+ -DNEW_QC_GPS
+
+## Includes
+LOCAL_C_INCLUDES:= \
+ $(TARGET_OUT_HEADERS)/gps.utils \
+ $(LOCAL_PATH)/../ulp/inc
+
+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/libloc_api_50001/LocApiAdapter.cpp b/gps/libloc_api_50001/LocApiAdapter.cpp
new file mode 100644
index 0000000..7689048
--- /dev/null
+++ b/gps/libloc_api_50001/LocApiAdapter.cpp
@@ -0,0 +1,238 @@
+/* Copyright (c) 2011, Code Aurora Forum. 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 Code Aurora Forum, 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 "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_adapter"
+
+#include <dlfcn.h>
+#include <LocApiAdapter.h>
+#include "loc_eng_msg.h"
+#include "loc_log.h"
+#include "loc_eng_ni.h"
+
+static void* noProc(void* data)
+{
+ return NULL;
+}
+
+LocEng::LocEng(void* caller,
+ LOC_API_ADAPTER_EVENT_MASK_T emask,
+ gps_acquire_wakelock acqwl,
+ gps_release_wakelock relwl,
+ loc_msg_sender msgSender,
+ loc_msg_sender msgUlpSender,
+ loc_ext_parser posParser,
+ loc_ext_parser svParser) :
+ owner(caller),
+ eventMask(emask), acquireWakelock(acqwl),
+ releaseWakeLock(relwl), sendMsge(msgSender), sendUlpMsg(msgUlpSender),
+ extPosInfo(NULL == posParser ? noProc : posParser),
+ extSvInfo(NULL == svParser ? noProc : svParser)
+{
+ LOC_LOGV("LocEng constructor %p, %p", posParser, svParser);
+}
+
+LocApiAdapter::LocApiAdapter(LocEng &locEng) :
+ locEngHandle(locEng), fixCriteria(), navigating(false)
+{
+ LOC_LOGD("LocApiAdapter created");
+}
+
+LocApiAdapter::~LocApiAdapter()
+{
+ LOC_LOGV("LocApiAdapter deleted");
+}
+
+LocApiAdapter* LocApiAdapter::getLocApiAdapter(LocEng &locEng)
+{
+ void* handle;
+ LocApiAdapter* adapter = NULL;
+
+ handle = dlopen ("libloc_api_v02.so", RTLD_NOW);
+
+ if (!handle) {
+ LOC_LOGI("%s: dlopen(libloc_api_v02.so) failed, trying to load libloc_api-rpc-qc.so", __FUNCTION__);
+ handle = dlopen ("libloc_api-rpc-qc.so", RTLD_NOW);
+ }
+ else
+ LOC_LOGE("%s: dlopen(libloc_api_v02.so) succeeded.", __FUNCTION__);
+
+ if (!handle) {
+ LOC_LOGI("%s: dlopen(libloc_api-rpc-qc.so) failed, constructing LocApiAdapter", __FUNCTION__);
+ adapter = new LocApiAdapter(locEng);
+ } else {
+ getLocApiAdapter_t* getHandle = (getLocApiAdapter_t*)dlsym(handle, "_Z16getLocApiAdapterR6LocEng");
+ if (!getHandle) {
+ LOC_LOGE("%s: dlsym(getLocApiAdapter) failed", __FUNCTION__);
+ return NULL;
+ }
+ adapter = (*getHandle)(locEng);
+ }
+
+ return adapter;
+}
+
+int LocApiAdapter::hexcode(char *hexstring, int string_size,
+ const char *data, int data_size)
+{
+ int i;
+ for (i = 0; i < data_size; i++)
+ {
+ char ch = data[i];
+ if (i*2 + 3 <= string_size)
+ {
+ snprintf(&hexstring[i*2], 3, "%02X", ch);
+ }
+ else {
+ break;
+ }
+ }
+ return i;
+}
+
+int LocApiAdapter::decodeAddress(char *addr_string, int string_size,
+ const char *data, int data_size)
+{
+ const char addr_prefix = 0x91;
+ int i, idxOutput = 0;
+
+ if (!data || !addr_string) { return 0; }
+
+ if (data[0] != addr_prefix)
+ {
+ LOC_LOGW("decodeAddress: address prefix is not 0x%x but 0x%x", addr_prefix, data[0]);
+ addr_string[0] = '\0';
+ return 0; // prefix not correct
+ }
+
+ for (i = 1; i < data_size; i++)
+ {
+ unsigned char ch = data[i], low = ch & 0x0F, hi = ch >> 4;
+ if (low <= 9 && idxOutput < string_size - 1) { addr_string[idxOutput++] = low + '0'; }
+ if (hi <= 9 && idxOutput < string_size - 1) { addr_string[idxOutput++] = hi + '0'; }
+ }
+
+ addr_string[idxOutput] = '\0'; // Terminates the string
+
+ return idxOutput;
+}
+
+void LocApiAdapter::reportPosition(GpsLocation &location,
+ void* locationExt,
+ enum loc_sess_status status)
+{
+ loc_eng_msg_report_position *msg(new loc_eng_msg_report_position(locEngHandle.owner,
+ location,
+ locationExt,
+ status));
+ if (locEngHandle.sendUlpMsg) {
+ locEngHandle.sendUlpMsg(locEngHandle.owner, msg);
+ } else {
+ locEngHandle.sendMsge(locEngHandle.owner, msg);
+ }
+}
+
+void LocApiAdapter::reportSv(GpsSvStatus &svStatus, void* svExt)
+{
+ loc_eng_msg_report_sv *msg(new loc_eng_msg_report_sv(locEngHandle.owner, svStatus, 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 (locEngHandle.sendUlpMsg) {
+ locEngHandle.sendUlpMsg(locEngHandle.owner, msg);
+ } else {
+ locEngHandle.sendMsge(locEngHandle.owner, msg);
+ }
+}
+
+void LocApiAdapter::reportStatus(GpsStatusValue status)
+{
+ loc_eng_msg_report_status *msg(new loc_eng_msg_report_status(locEngHandle.owner, status));
+ locEngHandle.sendMsge(locEngHandle.owner, msg);
+}
+
+void LocApiAdapter::reportNmea(const char* nmea, int length)
+{
+ loc_eng_msg_report_nmea *msg(new loc_eng_msg_report_nmea(locEngHandle.owner, nmea, length));
+ locEngHandle.sendMsge(locEngHandle.owner, msg);
+}
+
+void LocApiAdapter::requestATL(int connHandle, AGpsType agps_type)
+{
+ loc_eng_msg_request_atl *msg(new loc_eng_msg_request_atl(locEngHandle.owner, connHandle, agps_type));
+ locEngHandle.sendMsge(locEngHandle.owner, msg);
+}
+
+void LocApiAdapter::releaseATL(int connHandle)
+{
+ loc_eng_msg_release_atl *msg(new loc_eng_msg_release_atl(locEngHandle.owner, connHandle));
+ locEngHandle.sendMsge(locEngHandle.owner, msg);
+}
+
+void LocApiAdapter::requestXtraData()
+{
+ LOC_LOGD("XTRA download request");
+
+ loc_eng_msg *msg(new loc_eng_msg(locEngHandle.owner, LOC_ENG_MSG_REQUEST_XTRA_DATA));
+ locEngHandle.sendMsge(locEngHandle.owner, msg);
+}
+
+void LocApiAdapter::requestTime()
+{
+ LOC_LOGD("loc_event_cb: XTRA time download request... not supported");
+ // loc_eng_msg *msg(new loc_eng_msg(locEngHandle.owner, LOC_ENG_MSG_REQUEST_TIME));
+ // locEngHandle.sendMsge(locEngHandle.owner, msg);
+}
+
+void LocApiAdapter::requestLocation()
+{
+ LOC_LOGD("loc_event_cb: XTRA time download request... not supported");
+ // loc_eng_msg *msg(new loc_eng_msg(locEngHandle.owner, LOC_ENG_MSG_REQUEST_POSITION));
+ // locEngHandle.sendMsge(locEngHandle.owner, msg);
+}
+
+void LocApiAdapter::requestNiNotify(GpsNiNotification &notif, const void* data)
+{
+ notif.size = sizeof(notif);
+ notif.timeout = LOC_NI_NO_RESPONSE_TIME;
+
+ loc_eng_msg_request_ni *msg(new loc_eng_msg_request_ni(locEngHandle.owner, notif, data));
+ locEngHandle.sendMsge(locEngHandle.owner, msg);
+}
+
+void LocApiAdapter::handleEngineDownEvent()
+{
+ loc_eng_msg *msg(new loc_eng_msg(locEngHandle.owner, LOC_ENG_MSG_ENGINE_DOWN));
+ locEngHandle.sendMsge(locEngHandle.owner, msg);
+}
+
+void LocApiAdapter::handleEngineUpEvent()
+{
+ loc_eng_msg *msg(new loc_eng_msg(locEngHandle.owner, LOC_ENG_MSG_ENGINE_UP));
+ locEngHandle.sendMsge(locEngHandle.owner, msg);
+}
diff --git a/gps/libloc_api_50001/LocApiAdapter.h b/gps/libloc_api_50001/LocApiAdapter.h
new file mode 100644
index 0000000..0b0cf34
--- /dev/null
+++ b/gps/libloc_api_50001/LocApiAdapter.h
@@ -0,0 +1,242 @@
+/* Copyright (c) 2011, Code Aurora Forum. 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 Code Aurora Forum, 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef LOC_API_ADAPTER_H
+#define LOC_API_ADAPTER_H
+
+#include <ctype.h>
+#include <hardware/gps.h>
+#include <loc.h>
+#include <loc_eng_log.h>
+#include <log_util.h>
+#include <loc_eng_msg.h>
+
+#define MAX_APN_LEN 100
+#define MAX_URL_LEN 256
+#define smaller_of(a, b) (((a) > (b)) ? (b) : (a))
+
+enum loc_api_adapter_err {
+ LOC_API_ADAPTER_ERR_SUCCESS = 0,
+ LOC_API_ADAPTER_ERR_GENERAL_FAILURE = 1,
+ LOC_API_ADAPTER_ERR_UNSUPPORTED = 2,
+ LOC_API_ADAPTER_ERR_INVALID_HANDLE = 4,
+ LOC_API_ADAPTER_ERR_INVALID_PARAMETER = 5,
+ LOC_API_ADAPTER_ERR_ENGINE_BUSY = 6,
+ LOC_API_ADAPTER_ERR_PHONE_OFFLINE = 7,
+ LOC_API_ADAPTER_ERR_TIMEOUT = 8,
+ LOC_API_ADAPTER_ERR_SERVICE_NOT_PRESENT = 9,
+
+ LOC_API_ADAPTER_ERR_ENGINE_DOWN = 100,
+ LOC_API_ADAPTER_ERR_FAILURE,
+ LOC_API_ADAPTER_ERR_UNKNOWN
+};
+
+enum loc_api_adapter_event_index {
+ LOC_API_ADAPTER_REPORT_POSITION = 0, // Position report comes in loc_parsed_position_s_type
+ LOC_API_ADAPTER_REPORT_SATELLITE, // Satellite in view report
+ LOC_API_ADAPTER_REPORT_NMEA_1HZ, // NMEA report at 1HZ rate
+ LOC_API_ADAPTER_REPORT_NMEA_POSITION, // NMEA report at position report rate
+ LOC_API_ADAPTER_REQUEST_NI_NOTIFY_VERIFY, // NI notification/verification request
+ LOC_API_ADAPTER_REQUEST_ASSISTANCE_DATA, // Assistance data, eg: time, predicted orbits request
+ LOC_API_ADAPTER_REQUEST_LOCATION_SERVER, // Request for location server
+ LOC_API_ADAPTER_REPORT_IOCTL, // Callback report for loc_ioctl
+ LOC_API_ADAPTER_REPORT_STATUS, // Misc status report: eg, engine state
+
+ LOC_API_ADAPTER_EVENT_MAX
+};
+
+#define LOC_API_ADAPTER_BIT_PARSED_POSITION_REPORT (1<<LOC_API_ADAPTER_REPORT_POSITION)
+#define LOC_API_ADAPTER_BIT_SATELLITE_REPORT (1<<LOC_API_ADAPTER_REPORT_SATELLITE)
+#define LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT (1<<LOC_API_ADAPTER_REPORT_NMEA_1HZ)
+#define LOC_API_ADAPTER_BIT_NMEA_POSITION_REPORT (1<<LOC_API_ADAPTER_REPORT_NMEA_POSITION)
+#define LOC_API_ADAPTER_BIT_NI_NOTIFY_VERIFY_REQUEST (1<<LOC_API_ADAPTER_REQUEST_NI_NOTIFY_VERIFY)
+#define LOC_API_ADAPTER_BIT_ASSISTANCE_DATA_REQUEST (1<<LOC_API_ADAPTER_REQUEST_ASSISTANCE_DATA)
+#define LOC_API_ADAPTER_BIT_LOCATION_SERVER_REQUEST (1<<LOC_API_ADAPTER_REQUEST_LOCATION_SERVER)
+#define LOC_API_ADAPTER_BIT_IOCTL_REPORT (1<<LOC_API_ADAPTER_REPORT_IOCTL)
+#define LOC_API_ADAPTER_BIT_STATUS_REPORT (1<<LOC_API_ADAPTER_REPORT_STATUS)
+
+typedef unsigned int LOC_API_ADAPTER_EVENT_MASK_T;
+typedef void (*loc_msg_sender)(void* loc_eng_data_p, void* msgp);
+
+struct LocEng {
+ void* owner;
+ LOC_API_ADAPTER_EVENT_MASK_T eventMask;
+ const gps_acquire_wakelock acquireWakelock;
+ const gps_release_wakelock releaseWakeLock;
+ const loc_msg_sender sendMsge;
+ const loc_msg_sender sendUlpMsg;
+ const loc_ext_parser extPosInfo;
+ const loc_ext_parser extSvInfo;
+
+ LocEng(void* caller,
+ LOC_API_ADAPTER_EVENT_MASK_T emask,
+ gps_acquire_wakelock acqwl,
+ gps_release_wakelock relwl,
+ loc_msg_sender msgSender,
+ loc_msg_sender msgUlpSender,
+ loc_ext_parser posParser,
+ loc_ext_parser svParser);
+};
+
+class LocApiAdapter {
+protected:
+ const LocEng locEngHandle;
+ LocPosMode fixCriteria;
+ bool navigating;
+
+ LocApiAdapter(LocEng &locEng);
+
+public:
+ //LocApiAdapter(int q, reportCb_t[LOC_API_ADAPTER_EVENT_MAX] callbackTable);
+ virtual ~LocApiAdapter();
+
+ static LocApiAdapter* getLocApiAdapter(LocEng &locEng);
+
+ static int hexcode(char *hexstring, int string_size,
+ const char *data, int data_size);
+ static int decodeAddress(char *addr_string, int string_size,
+ const char *data, int data_size);
+
+ void reportPosition(GpsLocation &location,
+ void* locationExt,
+ enum loc_sess_status status);
+ void reportSv(GpsSvStatus &svStatus, void* svExt);
+ void reportStatus(GpsStatusValue status);
+ void reportNmea(const char* nmea, int length);
+ void reportAgpsStatus(AGpsStatus &agpsStatus);
+ void requestXtraData();
+ void requestTime();
+ void requestLocation();
+ void requestATL(int connHandle, AGpsType agps_type);
+ void releaseATL(int connHandle);
+ void requestNiNotify(GpsNiNotification &notify, const void* data);
+ void handleEngineDownEvent();
+ void handleEngineUpEvent();
+
+ // All below functions are to be defined by adapter specific modules:
+ // RPC, QMI, etc. The default implementation is empty.
+ inline virtual enum loc_api_adapter_err
+ reinit()
+ {LOC_LOGW("%s: default implementation invoked", __func__); return LOC_API_ADAPTER_ERR_SUCCESS;}
+ inline virtual enum loc_api_adapter_err
+ startFix()
+ {LOC_LOGW("%s: default implementation invoked", __func__); return LOC_API_ADAPTER_ERR_SUCCESS;}
+ inline virtual enum loc_api_adapter_err
+ stopFix()
+ {LOC_LOGW("%s: default implementation invoked", __func__); return LOC_API_ADAPTER_ERR_SUCCESS;}
+ inline virtual enum loc_api_adapter_err
+ deleteAidingData(GpsAidingData f)
+ {LOC_LOGW("%s: default implementation invoked", __func__); return LOC_API_ADAPTER_ERR_SUCCESS;}
+ inline virtual enum loc_api_adapter_err
+ enableData(int enable)
+ {LOC_LOGW("%s: default implementation invoked", __func__); return LOC_API_ADAPTER_ERR_SUCCESS;}
+ inline virtual enum loc_api_adapter_err
+ setAPN(char* apn, int len)
+ {LOC_LOGW("%s: default implementation invoked", __func__); return LOC_API_ADAPTER_ERR_SUCCESS;}
+ inline virtual enum loc_api_adapter_err
+ injectPosition(double latitude, double longitude, float accuracy)
+ {LOC_LOGW("%s: default implementation invoked", __func__); return LOC_API_ADAPTER_ERR_SUCCESS;}
+ inline virtual enum loc_api_adapter_err
+ setTime(GpsUtcTime time, int64_t timeReference, int uncertainty)
+ {LOC_LOGW("%s: default implementation invoked", __func__); return LOC_API_ADAPTER_ERR_SUCCESS;}
+ inline virtual enum loc_api_adapter_err
+ setXtraData(char* data, int length)
+ {LOC_LOGW("%s: default implementation invoked", __func__); return LOC_API_ADAPTER_ERR_SUCCESS;}
+ inline virtual enum loc_api_adapter_err
+ atlOpenStatus(int handle, int is_succ, char* apn, AGpsBearerType bear, AGpsType agpsType)
+ {LOC_LOGW("%s: default implementation invoked", __func__); return LOC_API_ADAPTER_ERR_SUCCESS;}
+ inline virtual enum loc_api_adapter_err
+ atlCloseStatus(int handle, int is_succ)
+ {LOC_LOGW("%s: default implementation invoked", __func__); return LOC_API_ADAPTER_ERR_SUCCESS;}
+ inline virtual enum loc_api_adapter_err
+ setPositionMode(const LocPosMode *posMode)
+ {LOC_LOGW("%s: default implementation invoked", __func__); return LOC_API_ADAPTER_ERR_SUCCESS;}
+ inline virtual enum loc_api_adapter_err
+ setServer(const char* url, int len)
+ {LOC_LOGW("%s: default implementation invoked", __func__); return LOC_API_ADAPTER_ERR_SUCCESS;}
+ inline virtual enum loc_api_adapter_err
+ setServer(unsigned int ip, int port,
+ LocServerType type)
+ {LOC_LOGW("%s: default implementation invoked", __func__); return LOC_API_ADAPTER_ERR_SUCCESS;}
+ inline virtual enum loc_api_adapter_err
+ informNiResponse(GpsUserResponseType userResponse, const void* passThroughData)
+ {LOC_LOGW("%s: default implementation invoked", __func__); return LOC_API_ADAPTER_ERR_SUCCESS;}
+ inline virtual enum loc_api_adapter_err
+ setSUPLVersion(uint32_t version)
+ {LOC_LOGW("%s: default implementation invoked", __func__); return LOC_API_ADAPTER_ERR_SUCCESS;}
+ inline virtual enum loc_api_adapter_err
+ setLPPConfig(uint32_t profile)
+ {LOC_LOGW("%s: default implementation invoked", __func__);
+ return LOC_API_ADAPTER_ERR_SUCCESS; }
+ inline virtual enum loc_api_adapter_err
+ setSensorControlConfig(int sensorUsage)
+ {LOC_LOGW("%s: default implementation invoked", __func__); return LOC_API_ADAPTER_ERR_SUCCESS;}
+ inline virtual enum loc_api_adapter_err
+ setSensorProperties(bool gyroBiasVarianceRandomWalk_valid, float gyroBiasVarianceRandomWalk,
+ bool accelBiasVarianceRandomWalk_valid, float accelBiasVarianceRandomWalk,
+ bool angleBiasVarianceRandomWalk_valid, float angleBiasVarianceRandomWalk,
+ bool rateBiasVarianceRandomWalk_valid, float rateBiasVarianceRandomWalk,
+ bool velocityBiasVarianceRandomWalk_valid, float velocityBiasVarianceRandomWalk)
+ {LOC_LOGW("%s: default implementation invoked", __func__); return LOC_API_ADAPTER_ERR_SUCCESS;}
+ 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)
+ {LOC_LOGW("%s: default implementation invoked", __func__); return LOC_API_ADAPTER_ERR_SUCCESS;}
+ inline virtual enum loc_api_adapter_err
+ setExtPowerConfig(int isBatteryCharging)
+ {LOC_LOGW("%s: default implementation invoked", __func__); return LOC_API_ADAPTER_ERR_SUCCESS;}
+
+ inline const LocPosMode& getPositionMode() const {return fixCriteria;}
+
+ inline bool isInSession() { return navigating; }
+ inline virtual void setInSession(bool inSession) { navigating = inSession; }
+
+private:
+ // Pad out virtual method table so that the setPrivacy entry corresponds to
+ // the same as LocApiV02Adapter.
+ inline virtual void unknownVirtualMethod24() {}
+ inline virtual void unknownVirtualMethod25() {}
+ inline virtual void unknownVirtualMethod26() {}
+ inline virtual void unknownVirtualMethod27() {}
+ inline virtual void unknownVirtualMethod28() {}
+ inline virtual void unknownVirtualMethod29() {}
+ inline virtual void unknownVirtualMethod30() {}
+
+public:
+ inline virtual enum loc_api_adapter_err
+ setPrivacy(int8_t privacy_setting)
+ {LOC_LOGW("%s: default implementation invoked", __func__); return LOC_API_ADAPTER_ERR_SUCCESS;}
+};
+
+extern "C" LocApiAdapter* getLocApiAdapter(LocEng &locEng);
+
+typedef LocApiAdapter* (getLocApiAdapter_t)(LocEng&);
+
+#endif //LOC_API_RPC_ADAPTER_H
diff --git a/gps/libloc_api_50001/gps.c b/gps/libloc_api_50001/gps.c
new file mode 100644
index 0000000..c9e4999
--- /dev/null
+++ b/gps/libloc_api_50001/gps.c
@@ -0,0 +1,68 @@
+/* Copyright (c) 2011 Code Aurora Forum. 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 Code Aurora Forum, 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 "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));
+ 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/libloc_api_50001/loc.cpp b/gps/libloc_api_50001/loc.cpp
new file mode 100644
index 0000000..c0378fd
--- /dev/null
+++ b/gps/libloc_api_50001/loc.cpp
@@ -0,0 +1,1117 @@
+/* Copyright (c) 2011 - 2012, Code Aurora Forum. 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 Code Aurora Forum, 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 "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 <loc_eng.h>
+#include <loc_log.h>
+#include <msg_q.h>
+#include <dlfcn.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+//Globals defns
+static const ulpInterface * loc_eng_ulp_inf = NULL;
+static const ulpInterface * loc_eng_get_ulp_inf(void);
+static gps_location_callback gps_loc_cb = NULL;
+static gps_sv_status_callback gps_sv_cb = NULL;
+
+static void loc_cb(GpsLocation* location, void* locExt);
+static void sv_cb(GpsSvStatus* sv_status, void* svExt);
+
+// 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);
+//ULP/Hybrid provider Function definitions
+static int loc_update_criteria(UlpLocationCriteria criteria);
+static int loc_ulp_network_init(UlpNetworkLocationCallbacks *callbacks);
+static int loc_ulp_send_network_position(UlpNetworkPositionReport *position_report);
+static int loc_ulp_phone_context_init(UlpPhoneContextCallbacks *callback);
+static int loc_ulp_phone_context_settings_update(UlpPhoneContextSettings *settings);
+
+// 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,
+ loc_update_criteria
+};
+
+// Function declarations for sLocEngAGpsInterface
+static void loc_agps_init(AGpsCallbacks* callbacks);
+static int loc_agps_open(AGpsType agpsType,
+ const char* apn, AGpsBearerType bearerType);
+static int loc_agps_closed(AGpsType agpsType);
+static int loc_agps_open_failed(AGpsType agpsType);
+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 bool loc_inject_raw_command(char* command, int length);
+
+static const InjectRawCmdInterface sLocEngInjectRawCmdInterface =
+{
+ sizeof(InjectRawCmdInterface),
+ loc_inject_raw_command
+};
+
+//ULP/Hybrid provider interfaces
+static const UlpNetworkInterface sUlpNetworkInterface =
+{
+ sizeof(UlpNetworkInterface),
+ loc_ulp_network_init,
+ loc_ulp_send_network_position
+};
+static const UlpPhoneContextInterface sLocEngUlpPhoneContextInterface =
+{
+ sizeof(UlpPhoneContextInterface),
+ loc_ulp_phone_context_init,
+ loc_ulp_phone_context_settings_update
+};
+static loc_eng_data_s_type loc_afw_data;
+static int gss_fd = 0;
+
+#define TARGET_NAME_OTHER 0
+#define TARGET_NAME_APQ8064_STANDALONE 1
+#define TARGET_NAME_APQ8064_FUSION3 2
+
+static int read_a_line(const char * file_path, char * line, int line_size)
+{
+ FILE *fp;
+ int result = 0;
+
+ * line = '\0';
+ fp = fopen(file_path, "r" );
+ if( fp == NULL ) {
+ LOC_LOGE("open failed: %s: %s\n", file_path, strerror(errno));
+ result = -1;
+ } else {
+ int len;
+ fgets(line, line_size, fp);
+ len = strlen(line);
+ len = len < line_size - 1? len : line_size - 1;
+ line[len] = '\0';
+ LOC_LOGD("cat %s: %s", file_path, line);
+ fclose(fp);
+ }
+ return result;
+}
+
+#define LINE_LEN 100
+#define STR_LIQUID "Liquid"
+#define STR_SURF "Surf"
+#define STRLEN_LIQUID (sizeof(STR_LIQUID) - 1)
+#define STRLEN_SURF (sizeof(STR_SURF) - 1)
+#define IS_STR_END(c) ((c) == '\0' || (c) == '\n' || (c) == '\r')
+
+static int get_target_name(void)
+{
+ int target_name = TARGET_NAME_OTHER;
+
+ char hw_platform[] = "/sys/devices/system/soc/soc0/hw_platform"; // "Liquid" or "Surf"
+ char id[] = "/sys/devices/system/soc/soc0/id"; //109
+ char mdm[] = "/dev/mdm"; // No such file or directory
+
+ char line[LINE_LEN];
+
+ read_a_line( hw_platform, line, LINE_LEN);
+ if(( !memcmp(line, STR_LIQUID, STRLEN_LIQUID) && IS_STR_END(line[STRLEN_LIQUID]) ) ||
+ ( !memcmp(line, STR_SURF, STRLEN_SURF) && IS_STR_END(line[STRLEN_SURF]) )
+ ) {
+ if (!read_a_line( mdm, line, LINE_LEN)) {
+ target_name = TARGET_NAME_APQ8064_FUSION3;
+ } else {
+ read_a_line( id, line, LINE_LEN);
+ if(!strncmp(line, "109", strlen("109"))) {
+ target_name = TARGET_NAME_APQ8064_STANDALONE;
+ }
+ }
+ }
+ return target_name;
+}
+
+/*===========================================================================
+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];
+
+ // 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;
+ }
+
+ EXIT_LOG(%p, ret_val);
+ return ret_val;
+}
+
+// for gps.c
+extern "C" const GpsInterface* get_gps_interface()
+{
+ loc_eng_read_config();
+ //We load up libulp module at this point itself if ULP configured to be On
+ if(gps_conf.CAPABILITIES & ULP_CAPABILITY) {
+ loc_eng_ulp_inf = loc_eng_get_ulp_inf();
+ }
+ return &sLocEngInterface;
+}
+
+static void loc_free_msg(void* msg)
+{
+ delete (loc_eng_msg*)msg;
+}
+
+
+void loc_ulp_msg_sender(void* loc_eng_data_p, void* msg)
+{
+ LocEngContext* loc_eng_context = (LocEngContext*)((loc_eng_data_s_type*)loc_eng_data_p)->context;
+ msg_q_snd((void*)loc_eng_context->ulp_q, msg, loc_free_msg);
+}
+
+/*===========================================================================
+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)
+{
+ ENTRY_LOG();
+ LOC_API_ADAPTER_EVENT_MASK_T 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;
+ LocCallbacks clientCallbacks = {loc_cb, /* location_cb */
+ callbacks->status_cb, /* status_cb */
+ 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 */};
+ gps_loc_cb = callbacks->location_cb;
+ gps_sv_cb = callbacks->sv_status_cb;
+
+ if (get_target_name() == TARGET_NAME_APQ8064_STANDALONE)
+ {
+ 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));
+ return NULL;
+ }
+ LOC_LOGD("GSS open success! CAPABILITIES %0x\n", gps_conf.CAPABILITIES);
+ }
+
+ int retVal = -1;
+ if (loc_eng_ulp_inf == NULL)
+ retVal = loc_eng_init(loc_afw_data, &clientCallbacks, event,
+ NULL);
+ else
+ retVal = loc_eng_init(loc_afw_data, &clientCallbacks, event,
+ loc_ulp_msg_sender);
+ int ret_val1 = loc_eng_ulp_init(loc_afw_data, loc_eng_ulp_inf);
+ LOC_LOGD("loc_eng_ulp_init returned %d\n",ret_val1);
+ 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 (get_target_name() == TARGET_NAME_APQ8064_STANDALONE)
+ * {
+ * close(gss_fd);
+ * 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 = 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();
+ 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);
+ int 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 = 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 = 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);
+}
+
+/*===========================================================================
+FUNCTION loc_update_criteria
+
+DESCRIPTION
+ This is used to inform the ULP module of new unique criteria that are passed
+ in by the applications
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ 0: success
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static int loc_update_criteria(UlpLocationCriteria criteria)
+{
+ ENTRY_LOG();
+ int ret_val = loc_eng_update_criteria(loc_afw_data, criteria);
+
+ EXIT_LOG(%d, ret_val);
+ return ret_val;
+}
+
+/*===========================================================================
+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
+
+===========================================================================*/
+static const void* loc_get_extension(const char* name)
+{
+ ENTRY_LOG();
+ const void* ret_val = NULL;
+
+ 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, ULP_RAW_CMD_INTERFACE) == 0)
+ {
+ ret_val = &sLocEngInjectRawCmdInterface;
+ }
+ else if(strcmp(name, ULP_PHONE_CONTEXT_INTERFACE) == 0)
+ {
+ ret_val = &sLocEngUlpPhoneContextInterface;
+ }
+ else if(strcmp(name, ULP_NETWORK_INTERFACE) == 0)
+ {
+ //Return a valid value for ULP Network Interface only if ULP
+ //turned on in gps.conf
+ if(gps_conf.CAPABILITIES & ULP_CAPABILITY)
+ ret_val = &sUlpNetworkInterface;
+ }
+ 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, 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(AGpsType agpsType,
+ const char* apn, AGpsBearerType bearerType)
+{
+ ENTRY_LOG();
+ 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(AGpsType agpsType)
+{
+ ENTRY_LOG();
+ 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(AGpsType agpsType)
+{
+ ENTRY_LOG();
+ 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;
+ }
+ int ret_val = loc_eng_set_server_proxy(loc_afw_data, serverType, hostname, port);
+
+ EXIT_LOG(%d, ret_val);
+ return ret_val;
+}
+
+/*===========================================================================
+FUNCTION 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, 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 = loc_eng_xtra_inject_data(loc_afw_data, 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, 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);
+}
+
+/*===========================================================================
+FUNCTION loc_inject_raw_command
+
+DESCRIPTION
+ This is used to send special test modem commands from the applications
+ down into the HAL
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ 0: success
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static bool loc_inject_raw_command(char* command, int length)
+{
+ ENTRY_LOG();
+ int ret_val = loc_eng_inject_raw_command(loc_afw_data, command, length);
+ EXIT_LOG(%s, loc_logger_boolStr[ret_val!=0]);
+ return ret_val;
+}
+
+
+static void loc_cb(GpsLocation* location, void* locExt)
+{
+ ENTRY_LOG();
+ if (NULL != gps_loc_cb && NULL != location) {
+ CALLBACK_LOG_CALLFLOW("location_cb - from", %d, location->position_source);
+ gps_loc_cb(location);
+ }
+ EXIT_LOG(%s, VOID_RET);
+}
+
+static void 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);
+}
+/*===========================================================================
+FUNCTION loc_eng_get_ulp_inf
+
+DESCRIPTION
+ This function checks if ULP is enabled, and loads the libulp2.so and
+ returns its interface
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ interface pointer to libulp: no error
+ NULL: errors
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+const ulpInterface * loc_eng_get_ulp_inf(void)
+{
+ ENTRY_LOG();
+ void *handle;
+ const char *error;
+ get_ulp_interface* get_ulp_inf;
+ const ulpInterface* loc_eng_ulpInf = NULL;
+
+ if (!(gps_conf.CAPABILITIES & ULP_CAPABILITY)) {
+ LOC_LOGD ("%s, ULP is not configured to be On in gps.conf\n", __func__);
+ goto exit;
+ }
+ dlerror(); /* Clear any existing error */
+
+ handle = dlopen ("libulp2.so", RTLD_NOW);
+
+ if (!handle)
+ {
+ if ((error = dlerror()) != NULL) {
+ LOC_LOGE ("%s, dlopen for libulp.so failed, error = %s\n", __func__, error);
+ }
+ goto exit;
+ }
+ dlerror(); /* Clear any existing error */
+ get_ulp_inf = (get_ulp_interface*) dlsym(handle, "ulp_get_interface");
+ if ((error = dlerror()) != NULL) {
+ LOC_LOGE ("%s, dlsym for ulpInterface failed, error = %s\n", __func__, error);
+ goto exit;
+ }
+
+ // Initialize the ULP interface
+ loc_eng_ulpInf = get_ulp_inf();
+
+exit:
+ EXIT_LOG(%d, loc_eng_ulpInf == NULL);
+ return loc_eng_ulpInf;
+}
+
+/*===========================================================================
+FUNCTION loc_ulp_network_init
+
+DESCRIPTION
+ Initialize the ULP network interface.
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ 0
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static int loc_ulp_phone_context_init(UlpPhoneContextCallbacks *callbacks)
+{
+ ENTRY_LOG();
+ int ret_val = loc_eng_ulp_phone_context_init(loc_afw_data, callbacks);
+ EXIT_LOG(%d, ret_val);
+ return ret_val;
+}
+/*===========================================================================
+FUNCTION loc_ulp_phone_context_settings_update
+
+DESCRIPTION
+ This is used to inform the ULP module of phone settings changes carried out
+ by the users
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ 0: success
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+
+static int loc_ulp_phone_context_settings_update(UlpPhoneContextSettings *settings)
+{
+ ENTRY_LOG();
+ int ret_val = -1;
+ ret_val = loc_eng_ulp_phone_context_settings_update(loc_afw_data, settings);
+ EXIT_LOG(%d, ret_val);
+ return ret_val;
+}
+
+/*===========================================================================
+FUNCTION loc_ulp_network_init
+
+DESCRIPTION
+ Initialize the ULP network interface.
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ 0
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static int loc_ulp_network_init(UlpNetworkLocationCallbacks *callbacks)
+{
+ ENTRY_LOG();
+ int ret_val = loc_eng_ulp_network_init(loc_afw_data, callbacks);
+ EXIT_LOG(%d, ret_val);
+ return ret_val;
+}
+
+/*===========================================================================
+FUNCTION loc_eng_ulp_send_network_position
+
+DESCRIPTION
+ Ulp send data
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ 0
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_ulp_send_network_position(UlpNetworkPositionReport *position_report)
+{
+ ENTRY_LOG();
+ int ret_val = -1;
+ ret_val = loc_eng_ulp_send_network_position(loc_afw_data, position_report);
+ EXIT_LOG(%d, ret_val);
+ return ret_val;
+}
diff --git a/gps/libloc_api_50001/loc.h b/gps/libloc_api_50001/loc.h
new file mode 100644
index 0000000..233b34c
--- /dev/null
+++ b/gps/libloc_api_50001/loc.h
@@ -0,0 +1,89 @@
+/* Copyright (c) 2011, Code Aurora Forum. 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 Code Aurora Forum, 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 "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>
+
+#define MIN_POSSIBLE_FIX_INTERVAL 1000 /* msec */
+
+typedef enum loc_server_type {
+ LOC_AGPS_CDMA_PDE_SERVER,
+ LOC_AGPS_CUSTOM_PDE_SERVER,
+ LOC_AGPS_MPC_SERVER,
+ LOC_AGPS_SUPL_SERVER
+} LocServerType;
+
+typedef enum loc_position_mode_type {
+ LOC_POSITION_MODE_STANDALONE,
+ LOC_POSITION_MODE_MS_BASED,
+ LOC_POSITION_MODE_MS_ASSISTED,
+ LOC_POSITION_MODE_RESERVED_1,
+ LOC_POSITION_MODE_RESERVED_2,
+ LOC_POSITION_MODE_RESERVED_3,
+ LOC_POSITION_MODE_RESERVED_4
+} LocPositionMode;
+
+typedef void (*loc_location_cb_ext) (GpsLocation* 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;
+} LocCallbacks;
+
+enum loc_sess_status {
+ LOC_SESS_SUCCESS,
+ LOC_SESS_INTERMEDIATE,
+ LOC_SESS_FAILURE
+};
+
+void loc_ulp_msg_sender(void* loc_eng_data_p, void* msg);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif //__LOC_H__
diff --git a/gps/libloc_api_50001/loc_eng.cpp b/gps/libloc_api_50001/loc_eng.cpp
new file mode 100644
index 0000000..97cd9cb
--- /dev/null
+++ b/gps/libloc_api_50001/loc_eng.cpp
@@ -0,0 +1,2150 @@
+/* Copyright (c) 2009-2012 Code Aurora Forum. 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 Code Aurora Forum, 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 "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 <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 "LocApiAdapter.h"
+
+#include <cutils/sched_policy.h>
+#include <utils/SystemClock.h>
+#include <utils/Log.h>
+#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_msg_id.h>
+#include <msg_q.h>
+#include <loc.h>
+
+#include "log_util.h"
+#include "loc_eng_log.h"
+
+#define SUCCESS TRUE
+#define FAILURE FALSE
+
+static void loc_eng_deferred_action_thread(void* context);
+static void* loc_eng_create_msg_q();
+static void loc_eng_free_msg(void* msg);
+
+pthread_mutex_t LocEngContext::lock = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t LocEngContext::cond = PTHREAD_COND_INITIALIZER;
+LocEngContext* LocEngContext::me = NULL;
+boolean gpsConfigAlreadyRead = false;
+
+loc_gps_cfg_s_type gps_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'},
+ {"ENABLE_WIPER", &gps_conf.ENABLE_WIPER, NULL, 'n'},
+ {"SUPL_VER", &gps_conf.SUPL_VER, NULL, 'n'},
+ {"CAPABILITIES", &gps_conf.CAPABILITIES, NULL, 'n'},
+ {"GYRO_BIAS_RANDOM_WALK", &gps_conf.GYRO_BIAS_RANDOM_WALK, &gps_conf.GYRO_BIAS_RANDOM_WALK_VALID, 'f'},
+ {"ACCEL_RANDOM_WALK_SPECTRAL_DENSITY", &gps_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY, &gps_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'},
+ {"ANGLE_RANDOM_WALK_SPECTRAL_DENSITY", &gps_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY, &gps_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'},
+ {"RATE_RANDOM_WALK_SPECTRAL_DENSITY", &gps_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY, &gps_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'},
+ {"VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY", &gps_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY, &gps_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'},
+ {"SENSOR_ACCEL_BATCHES_PER_SEC", &gps_conf.SENSOR_ACCEL_BATCHES_PER_SEC, NULL, 'n'},
+ {"SENSOR_ACCEL_SAMPLES_PER_BATCH", &gps_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH, NULL, 'n'},
+ {"SENSOR_GYRO_BATCHES_PER_SEC", &gps_conf.SENSOR_GYRO_BATCHES_PER_SEC, NULL, 'n'},
+ {"SENSOR_GYRO_SAMPLES_PER_BATCH", &gps_conf.SENSOR_GYRO_SAMPLES_PER_BATCH, NULL, 'n'},
+ {"SENSOR_ACCEL_BATCHES_PER_SEC_HIGH", &gps_conf.SENSOR_ACCEL_BATCHES_PER_SEC_HIGH, NULL, 'n'},
+ {"SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH", &gps_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH, NULL, 'n'},
+ {"SENSOR_GYRO_BATCHES_PER_SEC_HIGH", &gps_conf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH, NULL, 'n'},
+ {"SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH", &gps_conf.SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH, NULL, 'n'},
+ {"SENSOR_CONTROL_MODE", &gps_conf.SENSOR_CONTROL_MODE, NULL, 'n'},
+ {"SENSOR_USAGE", &gps_conf.SENSOR_USAGE, NULL, 'n'},
+ {"SENSOR_ALGORITHM_CONFIG_MASK", &gps_conf.SENSOR_ALGORITHM_CONFIG_MASK, NULL, 'n'},
+ {"QUIPC_ENABLED", &gps_conf.QUIPC_ENABLED, NULL, 'n'},
+ {"LPP_PROFILE", &gps_conf.LPP_PROFILE, NULL, 'n'},
+};
+
+static void loc_default_parameters(void)
+{
+ /* defaults */
+ gps_conf.INTERMEDIATE_POS = 0;
+ gps_conf.ACCURACY_THRES = 0;
+ gps_conf.ENABLE_WIPER = 0;
+ gps_conf.SUPL_VER = 0x10000;
+ gps_conf.CAPABILITIES = 0x7;
+
+ gps_conf.GYRO_BIAS_RANDOM_WALK = 0;
+ gps_conf.SENSOR_ACCEL_BATCHES_PER_SEC = 2;
+ gps_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH = 5;
+ gps_conf.SENSOR_GYRO_BATCHES_PER_SEC = 2;
+ gps_conf.SENSOR_GYRO_SAMPLES_PER_BATCH = 5;
+ gps_conf.SENSOR_ACCEL_BATCHES_PER_SEC_HIGH = 4;
+ gps_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH = 25;
+ gps_conf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH = 4;
+ gps_conf.SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH = 25;
+ gps_conf.SENSOR_CONTROL_MODE = 0; /* AUTO */
+ gps_conf.SENSOR_USAGE = 0; /* Enabled */
+ gps_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 */
+ gps_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY = 0;
+ gps_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY = 0;
+ gps_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY = 0;
+ gps_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY = 0;
+
+ gps_conf.GYRO_BIAS_RANDOM_WALK_VALID = 0;
+ gps_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
+ gps_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
+ gps_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
+ gps_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
+
+ /* LTE Positioning Profile configuration is disable by default*/
+ gps_conf.LPP_PROFILE = 0;
+}
+
+LocEngContext::LocEngContext(gps_create_thread threadCreator) :
+ deferred_q((const void*)loc_eng_create_msg_q()),
+ //TODO: should we conditionally create ulp msg q?
+ ulp_q((const void*)loc_eng_create_msg_q()),
+ deferred_action_thread(threadCreator("loc_eng",loc_eng_deferred_action_thread, this)),
+ counter(0)
+{
+ LOC_LOGV("LocEngContext %d : %d pthread_id %ld\n",
+ getpid(), gettid(),
+ deferred_action_thread);
+}
+
+LocEngContext* LocEngContext::get(gps_create_thread threadCreator)
+{
+ pthread_mutex_lock(&lock);
+ // gonna need mutex protection here...
+ if (NULL == me) {
+ me = new LocEngContext(threadCreator);
+ }
+ me->counter++;
+
+ pthread_mutex_unlock(&lock);
+ return me;
+}
+
+void LocEngContext::drop()
+{
+ if (deferred_action_thread != pthread_self()) {
+ pthread_mutex_lock(&lock);
+ counter--;
+ if (counter == 0) {
+ loc_eng_msg *msg(new loc_eng_msg(this, LOC_ENG_MSG_QUIT));
+ msg_q_snd((void*)deferred_q, msg, loc_eng_free_msg);
+
+ // I am not sure if this is going to be hazardous. The calling thread
+ // might be blocked for a while, if the q is loaded. I am wondering
+ // if we should just dump all the msgs in the q upon QUIT.
+ pthread_cond_wait(&cond, &lock);
+
+ msg_q_destroy((void**)&deferred_q);
+ msg_q_destroy((void**)&ulp_q);
+ delete me;
+ me = NULL;
+ }
+ pthread_mutex_unlock(&lock);
+ } else {
+ LOC_LOGE("The HAL thread cannot free itself");
+ }
+}
+
+// 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_set_privacy(loc_eng_data_s_type &loc_eng_data,
+ int8_t privacy_setting);
+
+static char extra_data[100];
+/*********************************************************************
+ * 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)
+
+void loc_eng_msg_sender(void* loc_eng_data_p, void* msg)
+{
+ LocEngContext* loc_eng_context = (LocEngContext*)((loc_eng_data_s_type*)loc_eng_data_p)->context;
+ msg_q_snd((void*)loc_eng_context->deferred_q, msg, loc_eng_free_msg);
+}
+
+static void* loc_eng_create_msg_q()
+{
+ void* q = NULL;
+ if (eMSG_Q_SUCCESS != msg_q_init(&q)) {
+ LOC_LOGE("loc_eng_create_msg_q Q init failed.");
+ q = NULL;
+ }
+ return q;
+}
+
+static void loc_eng_free_msg(void* msg)
+{
+ delete (loc_eng_msg*)msg;
+}
+
+/*===========================================================================
+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,
+ void (*loc_external_msg_sender) (void*, void*))
+
+{
+ ENTRY_LOG_CALLFLOW();
+ if (NULL == callbacks || 0 == event) {
+ LOC_LOGE("loc_eng_init: bad parameters cb %p eMask %d", callbacks, event);
+ EXIT_LOG(%d, 0);
+ return NULL;
+ }
+
+ if (NULL != loc_eng_data.context) {
+ // Current loc_eng_cleanup keeps context initialized, so must enable
+ // here too.
+ loc_eng_set_privacy(loc_eng_data, 1);
+ }
+
+ STATE_CHECK((NULL == loc_eng_data.context),
+ "instance already initialized", return 0);
+
+ memset(&loc_eng_data, 0, sizeof (loc_eng_data));
+
+ // Create context (msg q + thread) (if not yet created)
+ // This will also parse gps.conf, if not done.
+ loc_eng_data.context = (void*)LocEngContext::get(callbacks->create_thread_cb);
+ 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.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;
+
+ LocEng locEngHandle(&loc_eng_data, event, loc_eng_data.acquire_wakelock_cb,
+ loc_eng_data.release_wakelock_cb, loc_eng_msg_sender, loc_external_msg_sender,
+ callbacks->location_ext_parser, callbacks->sv_ext_parser);
+ loc_eng_data.client_handle = LocApiAdapter::getLocApiAdapter(locEngHandle);
+
+ int ret_val =-1;
+ if (NULL == loc_eng_data.client_handle) {
+ // drop the context and declare failure
+ ((LocEngContext*)(loc_eng_data.context))->drop();
+ loc_eng_data.context = NULL;
+ } else {
+ LOC_LOGD("loc_eng_init created client, id = %p\n", loc_eng_data.client_handle);
+
+ // call reinit to send initialization messages
+ int tries = 30;
+ while (tries > 0 &&
+ LOC_API_ADAPTER_ERR_SUCCESS != (ret_val = loc_eng_reinit(loc_eng_data))) {
+ tries--;
+ LOC_LOGD("loc_eng_init client open failed, %d more tries", tries);
+ sleep(1);
+ }
+
+ if (LOC_API_ADAPTER_ERR_SUCCESS == ret_val) {
+ loc_eng_set_privacy(loc_eng_data, 1);
+ }
+ }
+
+ 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_eng_data.client_handle->reinit();
+
+ if (LOC_API_ADAPTER_ERR_SUCCESS == ret_val) {
+ LOC_LOGD("loc_eng_reinit reinit() successful");
+
+ loc_eng_msg_suple_version *supl_msg(new loc_eng_msg_suple_version(&loc_eng_data,
+ gps_conf.SUPL_VER));
+ msg_q_snd((void*)((LocEngContext*)(loc_eng_data.context))->deferred_q,
+ supl_msg, loc_eng_free_msg);
+
+ loc_eng_msg_lpp_config *lpp_msg(new loc_eng_msg_lpp_config(&loc_eng_data,
+ gps_conf.LPP_PROFILE));
+ msg_q_snd((void*)((LocEngContext*)(loc_eng_data.context))->deferred_q,
+ lpp_msg, loc_eng_free_msg);
+
+ loc_eng_msg_sensor_control_config *sensor_control_config_msg(
+ new loc_eng_msg_sensor_control_config(&loc_eng_data, gps_conf.SENSOR_USAGE));
+ msg_q_snd((void*)((LocEngContext*)(loc_eng_data.context))->deferred_q,
+ sensor_control_config_msg, loc_eng_free_msg);
+
+ /* Make sure at least one of the sensor property is specified by the user in the gps.conf file. */
+ if( gps_conf.GYRO_BIAS_RANDOM_WALK_VALID ||
+ gps_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID ||
+ gps_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID ||
+ gps_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID ||
+ gps_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID )
+ {
+ loc_eng_msg_sensor_properties *sensor_properties_msg(
+ new loc_eng_msg_sensor_properties(&loc_eng_data,
+ gps_conf.GYRO_BIAS_RANDOM_WALK_VALID,
+ gps_conf.GYRO_BIAS_RANDOM_WALK,
+ gps_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
+ gps_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY,
+ gps_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
+ gps_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY,
+ gps_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
+ gps_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY,
+ gps_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
+ gps_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY));
+ msg_q_snd((void*)((LocEngContext*)(loc_eng_data.context))->deferred_q,
+ sensor_properties_msg, loc_eng_free_msg);
+ }
+
+ loc_eng_msg_sensor_perf_control_config *sensor_perf_control_conf_msg(
+ new loc_eng_msg_sensor_perf_control_config(&loc_eng_data,
+ gps_conf.SENSOR_CONTROL_MODE,
+ gps_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH,
+ gps_conf.SENSOR_ACCEL_BATCHES_PER_SEC,
+ gps_conf.SENSOR_GYRO_SAMPLES_PER_BATCH,
+ gps_conf.SENSOR_GYRO_BATCHES_PER_SEC,
+ gps_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH,
+ gps_conf.SENSOR_ACCEL_BATCHES_PER_SEC_HIGH,
+ gps_conf.SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH,
+ gps_conf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH,
+ gps_conf.SENSOR_ALGORITHM_CONFIG_MASK));
+ msg_q_snd((void*)((LocEngContext*)(loc_eng_data.context))->deferred_q,
+ sensor_perf_control_conf_msg, loc_eng_free_msg);
+ }
+
+ 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.context, 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.client_handle->isInSession())
+ {
+ LOC_LOGD("loc_eng_cleanup: fix not stopped. stop it now.");
+ loc_eng_stop(loc_eng_data);
+ }
+
+ loc_eng_set_privacy(loc_eng_data, 0);
+
+#if 0 // can't afford to actually clean up, for many reason.
+
+ ((LocEngContext*)(loc_eng_data.context))->drop();
+ loc_eng_data.context = NULL;
+
+ // De-initialize ulp
+ if (locEngUlpInf != NULL)
+ {
+ locEngUlpInf = NULL;
+ msg_q_destroy( &loc_eng_data.ulp_q);
+ }
+
+ if (loc_eng_data.client_handle != NULL)
+ {
+ LOC_LOGD("loc_eng_init: client opened. close it now.");
+ delete loc_eng_data.client_handle;
+ loc_eng_data.client_handle = NULL;
+ }
+
+#ifdef FEATURE_GNSS_BIT_API
+ {
+ char baseband[PROPERTY_VALUE_MAX];
+ property_get("ro.baseband", baseband, "msm");
+ if ((strcmp(baseband,"svlte2a") == 0))
+ {
+ loc_eng_dmn_conn_loc_api_server_unblock();
+ loc_eng_dmn_conn_loc_api_server_join();
+ }
+ }
+#endif /* FEATURE_GNSS_BIT_API */
+
+#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.context, return -1);
+
+ if((loc_eng_data.ulp_initialized == true) && (gps_conf.CAPABILITIES & ULP_CAPABILITY))
+ {
+ //Pass the start messgage to ULP if present & activated
+ loc_eng_msg *msg(new loc_eng_msg(&loc_eng_data, ULP_MSG_START_FIX));
+ msg_q_snd( (void*)((LocEngContext*)(loc_eng_data.context))->ulp_q,
+ msg, loc_eng_free_msg);
+ }else
+ {
+ loc_eng_msg *msg(new loc_eng_msg(&loc_eng_data, LOC_ENG_MSG_START_FIX));
+ msg_q_snd((void*)((LocEngContext*)(loc_eng_data.context))->deferred_q,
+ msg, loc_eng_free_msg);
+ }
+ 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.client_handle->isInSession()) {
+ ret_val = loc_eng_data.client_handle->startFix();
+
+ if (ret_val == LOC_API_ADAPTER_ERR_SUCCESS ||
+ ret_val == LOC_API_ADAPTER_ERR_ENGINE_DOWN)
+ {
+ loc_inform_gps_status(loc_eng_data, GPS_STATUS_SESSION_BEGIN);
+ loc_eng_data.client_handle->setInSession(TRUE);
+ }
+ }
+
+ 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.context, return -1);
+
+ if((loc_eng_data.ulp_initialized == true) && (gps_conf.CAPABILITIES & ULP_CAPABILITY))
+ {
+ //Pass the start messgage to ULP if present & activated
+ loc_eng_msg *msg(new loc_eng_msg(&loc_eng_data, ULP_MSG_STOP_FIX));
+ msg_q_snd( (void*)((LocEngContext*)(loc_eng_data.context))->ulp_q,
+ msg, loc_eng_free_msg);
+ }else
+ {
+ loc_eng_msg *msg(new loc_eng_msg(&loc_eng_data, LOC_ENG_MSG_STOP_FIX));
+ msg_q_snd((void*)((LocEngContext*)(loc_eng_data.context))->deferred_q,
+ msg, loc_eng_free_msg);
+ }
+
+ 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.client_handle->isInSession()) {
+
+ ret_val = loc_eng_data.client_handle->stopFix();
+ if (ret_val == LOC_API_ADAPTER_ERR_SUCCESS)
+ {
+ loc_inform_gps_status(loc_eng_data, GPS_STATUS_SESSION_END);
+ }
+
+ loc_eng_data.client_handle->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.context, return -1);
+ loc_eng_msg_position_mode *msg(
+ new loc_eng_msg_position_mode(&loc_eng_data, params));
+ msg_q_snd((void*)((LocEngContext*)(loc_eng_data.context))->deferred_q,
+ msg, loc_eng_free_msg);
+
+ 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.context, return -1);
+ loc_eng_msg_set_time *msg(
+ new loc_eng_msg_set_time(&loc_eng_data,
+ time,
+ timeReference,
+ uncertainty));
+ msg_q_snd((void*)((LocEngContext*)(loc_eng_data.context))->deferred_q,
+ msg, loc_eng_free_msg);
+
+ 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.context, return -1);
+ loc_eng_msg_inject_location *msg(
+ new loc_eng_msg_inject_location(&loc_eng_data,
+ latitude,
+ longitude,
+ accuracy));
+ msg_q_snd((void*)((LocEngContext*)(loc_eng_data.context))->deferred_q,
+ msg, loc_eng_free_msg);
+
+ 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.context, return);
+
+ loc_eng_msg_delete_aiding_data *msg(
+ new loc_eng_msg_delete_aiding_data(&loc_eng_data,
+ f));
+ msg_q_snd((void*)((LocEngContext*)(loc_eng_data.context))->deferred_q,
+ msg, loc_eng_free_msg);
+
+ 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();
+
+ static GpsStatusValue last_status = GPS_STATUS_NONE;
+
+ GpsStatus gs = { sizeof(gs),status };
+
+
+ if (loc_eng_data.status_cb)
+ {
+ CALLBACK_LOG_CALLFLOW("status_cb", %s, loc_get_gps_status_name(gs.status));
+ loc_eng_data.status_cb(&gs);
+ }
+
+ last_status = status;
+
+ EXIT_LOG(%s, VOID_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, AGpsCallbacks* callbacks)
+{
+ ENTRY_LOG_CALLFLOW();
+ INIT_CHECK(loc_eng_data.context, return);
+ STATE_CHECK((NULL == loc_eng_data.agps_status_cb),
+ "agps instance already initialized",
+ return);
+ loc_eng_data.agps_status_cb = callbacks->status_cb;
+
+ loc_eng_data.agnss_nif = new AgpsStateMachine(loc_eng_data.agps_status_cb,
+ AGPS_TYPE_SUPL,
+ false);
+ loc_eng_data.internet_nif = new AgpsStateMachine(loc_eng_data.agps_status_cb,
+ AGPS_TYPE_WWAN_ANY,
+ false);
+ loc_eng_data.wifi_nif = new AgpsStateMachine(loc_eng_data.agps_status_cb,
+ AGPS_TYPE_WIFI,
+ true);
+
+#ifdef FEATURE_GNSS_BIT_API
+ {
+ char baseband[PROPERTY_VALUE_MAX];
+ property_get("ro.baseband", baseband, "msm");
+ if ((strcmp(baseband,"svlte2a") == 0) ||
+ (strcmp(baseband,"msm") == 0))
+ {
+ loc_eng_dmn_conn_loc_api_server_launch(callbacks->create_thread_cb,
+ NULL, NULL, &loc_eng_data);
+ }
+ }
+#endif /* FEATURE_GNSS_BIT_API */
+
+ loc_eng_agps_reinit(loc_eng_data);
+ EXIT_LOG(%s, VOID_RET);
+}
+
+/*===========================================================================
+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, AGpsType agpsType,
+ const char* apn, AGpsBearerType bearerType)
+{
+ ENTRY_LOG_CALLFLOW();
+ INIT_CHECK(loc_eng_data.context && 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);
+ loc_eng_msg_atl_open_success *msg(
+ new loc_eng_msg_atl_open_success(&loc_eng_data, agpsType, apn,
+ apn_len, bearerType));
+ msg_q_snd((void*)((LocEngContext*)(loc_eng_data.context))->deferred_q,
+ msg, loc_eng_free_msg);
+
+ 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, AGpsType agpsType)
+{
+ ENTRY_LOG_CALLFLOW();
+ INIT_CHECK(loc_eng_data.context && loc_eng_data.agps_status_cb,
+ return -1);
+
+ loc_eng_msg_atl_closed *msg(new loc_eng_msg_atl_closed(&loc_eng_data, agpsType));
+ msg_q_snd((void*)((LocEngContext*)(loc_eng_data.context))->deferred_q,
+ msg, loc_eng_free_msg);
+
+ 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, AGpsType agpsType)
+{
+ ENTRY_LOG_CALLFLOW();
+ INIT_CHECK(loc_eng_data.context && loc_eng_data.agps_status_cb,
+ return -1);
+
+ loc_eng_msg_atl_open_failed *msg(new loc_eng_msg_atl_open_failed(&loc_eng_data, agpsType));
+ msg_q_snd((void*)((LocEngContext*)(loc_eng_data.context))->deferred_q,
+ msg, loc_eng_free_msg);
+
+ 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;
+
+ 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) {
+ loc_eng_msg_set_server_url *msg(new loc_eng_msg_set_server_url(&loc_eng_data,
+ url, len));
+ msg_q_snd((void*)((LocEngContext*)(loc_eng_data.context))->deferred_q,
+ msg, loc_eng_free_msg);
+ }
+ } 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);
+ loc_eng_msg_set_server_ipv4 *msg(new loc_eng_msg_set_server_ipv4(&loc_eng_data,
+ ip,
+ port,
+ type));
+ msg_q_snd((void*)((LocEngContext*)(loc_eng_data.context))->deferred_q,
+ msg, loc_eng_free_msg);
+ }
+ } 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.context)
+ {
+ 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();
+ INIT_CHECK(loc_eng_data.context, 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);
+ loc_eng_msg_set_data_enable *msg(new loc_eng_msg_set_data_enable(&loc_eng_data, apn,
+ apn_len, available));
+ msg_q_snd((void*)((LocEngContext*)(loc_eng_data.context))->deferred_q,
+ msg, loc_eng_free_msg);
+ }
+ 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.client_handle->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) {
+ loc_eng_data.agnss_nif->dropAllSubscribers();
+ 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.client_handle->isInSession()) {
+ // This sets the copy in adapter to modem
+ loc_eng_data.client_handle->setPositionMode(NULL);
+ loc_eng_data.client_handle->setInSession(false);
+ loc_eng_start_handler(loc_eng_data);
+ }
+ EXIT_LOG(%s, VOID_RET);
+}
+
+/*===========================================================================
+FUNCTION loc_eng_deferred_action_thread
+
+DESCRIPTION
+ Main routine for the thread to execute loc_eng commands.
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ None
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static void loc_eng_deferred_action_thread(void* arg)
+{
+ ENTRY_LOG();
+ loc_eng_msg *msg;
+ static int cnt = 0;
+ LocEngContext* context = (LocEngContext*)arg;
+
+ // make sure we do not run in background scheduling group
+ set_sched_policy(gettid(), SP_FOREGROUND);
+
+ while (1)
+ {
+ LOC_LOGD("%s:%d] %d listening ...\n", __func__, __LINE__, cnt++);
+
+ // we are only sending / receiving msg pointers
+ msq_q_err_type result = msg_q_rcv((void*)context->deferred_q, (void **) &msg);
+ if (eMSG_Q_SUCCESS != result) {
+ LOC_LOGE("%s:%d] fail receiving msg: %s\n", __func__, __LINE__,
+ loc_get_msg_q_status(result));
+ return;
+ }
+
+ loc_eng_data_s_type* loc_eng_data_p = (loc_eng_data_s_type*)msg->owner;
+
+ LOC_LOGD("%s:%d] received msg_id = %s context = %p\n",
+ __func__, __LINE__, loc_get_msg_name(msg->msgid), loc_eng_data_p->context);
+
+ // need to ensure the instance data is valid
+ STATE_CHECK(NULL != loc_eng_data_p->context,
+ "instance cleanup happened",
+ delete msg; return);
+
+ switch(msg->msgid) {
+ case LOC_ENG_MSG_QUIT:
+ {
+ LocEngContext* context = (LocEngContext*)loc_eng_data_p->context;
+ pthread_mutex_lock(&(context->lock));
+ pthread_cond_signal(&(context->cond));
+ pthread_mutex_unlock(&(context->lock));
+ EXIT_LOG(%s, "LOC_ENG_MSG_QUIT, signal the main thread and return");
+ }
+ return;
+
+ case LOC_ENG_MSG_REQUEST_NI:
+ {
+ loc_eng_msg_request_ni *niMsg = (loc_eng_msg_request_ni*)msg;
+ loc_eng_ni_request_handler(*loc_eng_data_p, &niMsg->notify, niMsg->passThroughData);
+ }
+ break;
+
+ case LOC_ENG_MSG_INFORM_NI_RESPONSE:
+ {
+ loc_eng_msg_inform_ni_response *nrMsg = (loc_eng_msg_inform_ni_response*)msg;
+ loc_eng_data_p->client_handle->informNiResponse(nrMsg->response,
+ nrMsg->passThroughData);
+ }
+ break;
+
+ case LOC_ENG_MSG_START_FIX:
+ loc_eng_start_handler(*loc_eng_data_p);
+ break;
+
+ case LOC_ENG_MSG_STOP_FIX:
+ if (loc_eng_data_p->agps_request_pending)
+ {
+ loc_eng_data_p->stop_request_pending = true;
+ LOC_LOGD("loc_eng_stop - deferring stop until AGPS data call is finished\n");
+ } else {
+ loc_eng_stop_handler(*loc_eng_data_p);
+ }
+ break;
+
+ case LOC_ENG_MSG_SET_POSITION_MODE:
+ {
+ loc_eng_msg_position_mode *pmMsg = (loc_eng_msg_position_mode*)msg;
+ loc_eng_data_p->client_handle->setPositionMode(&(pmMsg->pMode));
+ }
+ break;
+
+ case LOC_ENG_MSG_SET_TIME:
+ {
+ loc_eng_msg_set_time *tMsg = (loc_eng_msg_set_time*)msg;
+ loc_eng_data_p->client_handle->setTime(tMsg->time, tMsg->timeReference,
+ tMsg->uncertainty);
+ }
+ break;
+
+ case LOC_ENG_MSG_INJECT_LOCATION:
+ {
+ loc_eng_msg_inject_location *ilMsg = (loc_eng_msg_inject_location*) msg;
+ loc_eng_data_p->client_handle->injectPosition(ilMsg->latitude, ilMsg->longitude,
+ ilMsg->accuracy);
+ }
+ break;
+
+ case LOC_ENG_MSG_SET_SERVER_IPV4:
+ {
+ loc_eng_msg_set_server_ipv4 *ssiMsg = (loc_eng_msg_set_server_ipv4*)msg;
+ loc_eng_data_p->client_handle->setServer(ssiMsg->nl_addr,
+ ssiMsg->port,
+ ssiMsg->serverType);
+ }
+ break;
+
+ case LOC_ENG_MSG_SET_SERVER_URL:
+ {
+ loc_eng_msg_set_server_url *ssuMsg = (loc_eng_msg_set_server_url*)msg;
+ loc_eng_data_p->client_handle->setServer(ssuMsg->url, ssuMsg->len);
+ }
+ break;
+
+ case LOC_ENG_MSG_SUPL_VERSION:
+ {
+ loc_eng_msg_suple_version *svMsg = (loc_eng_msg_suple_version*)msg;
+ loc_eng_data_p->client_handle->setSUPLVersion(svMsg->supl_version);
+ }
+ break;
+
+ case LOC_ENG_MSG_LPP_CONFIG:
+ {
+ loc_eng_msg_lpp_config *svMsg = (loc_eng_msg_lpp_config*)msg;
+ loc_eng_data_p->client_handle->setLPPConfig(svMsg->lpp_config);
+ }
+ break;
+
+ case LOC_ENG_MSG_SET_SENSOR_CONTROL_CONFIG:
+ {
+ loc_eng_msg_sensor_control_config *sccMsg = (loc_eng_msg_sensor_control_config*)msg;
+ loc_eng_data_p->client_handle->setSensorControlConfig(sccMsg->sensorsDisabled);
+ }
+ break;
+
+ case LOC_ENG_MSG_SET_SENSOR_PROPERTIES:
+ {
+ loc_eng_msg_sensor_properties *spMsg = (loc_eng_msg_sensor_properties*)msg;
+ loc_eng_data_p->client_handle->setSensorProperties(spMsg->gyroBiasVarianceRandomWalk_valid,
+ spMsg->gyroBiasVarianceRandomWalk,
+ spMsg->accelRandomWalk_valid,
+ spMsg->accelRandomWalk,
+ spMsg->angleRandomWalk_valid,
+ spMsg->angleRandomWalk,
+ spMsg->rateRandomWalk_valid,
+ spMsg->rateRandomWalk,
+ spMsg->velocityRandomWalk_valid,
+ spMsg->velocityRandomWalk);
+ }
+ break;
+
+ case LOC_ENG_MSG_SET_SENSOR_PERF_CONTROL_CONFIG:
+ {
+ loc_eng_msg_sensor_perf_control_config *spccMsg = (loc_eng_msg_sensor_perf_control_config*)msg;
+ loc_eng_data_p->client_handle->setSensorPerfControlConfig(spccMsg->controlMode, spccMsg->accelSamplesPerBatch, spccMsg->accelBatchesPerSec,
+ spccMsg->gyroSamplesPerBatch, spccMsg->gyroBatchesPerSec,
+ spccMsg->accelSamplesPerBatchHigh, spccMsg->accelBatchesPerSecHigh,
+ spccMsg->gyroSamplesPerBatchHigh, spccMsg->gyroBatchesPerSecHigh,
+ spccMsg->algorithmConfig);
+ }
+ break;
+
+ case LOC_ENG_MSG_EXT_POWER_CONFIG:
+ {
+ loc_eng_msg_ext_power_config *pwrMsg = (loc_eng_msg_ext_power_config*)msg;
+ loc_eng_data_p->client_handle->setExtPowerConfig(pwrMsg->isBatteryCharging);
+ }
+ break;
+
+ case LOC_ENG_MSG_REPORT_POSITION:
+ if (loc_eng_data_p->mute_session_state != LOC_MUTE_SESS_IN_SESSION)
+ {
+ bool reported = false;
+ loc_eng_msg_report_position *rpMsg = (loc_eng_msg_report_position*)msg;
+ if (loc_eng_data_p->location_cb != NULL) {
+ if (LOC_SESS_FAILURE == rpMsg->status) {
+ // in case we want to handle the failure case
+ loc_eng_data_p->location_cb(NULL, NULL);
+ reported = true;
+ }
+ // what's in the else if is... (line by line)
+ // 1. this is a good fix; or
+ // 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 == rpMsg->status ||
+ (LOC_SESS_INTERMEDIATE == loc_eng_data_p->intermediateFix &&
+ !((rpMsg->location.flags & GPS_LOCATION_HAS_ACCURACY) &&
+ (gps_conf.ACCURACY_THRES != 0) &&
+ (rpMsg->location.accuracy > gps_conf.ACCURACY_THRES)))) {
+ loc_eng_data_p->location_cb((GpsLocation*)&(rpMsg->location),
+ (void*)rpMsg->locationExt);
+ reported = true;
+ }
+ }
+
+ // if we have reported this fix
+ if (reported &&
+ // and if this is a singleshot
+ GPS_POSITION_RECURRENCE_SINGLE ==
+ loc_eng_data_p->client_handle->getPositionMode().recurrence) {
+ if (LOC_SESS_INTERMEDIATE == rpMsg->status) {
+ // modem could be still working for a final fix,
+ // although we no longer need it. So stopFix().
+ loc_eng_data_p->client_handle->stopFix();
+ }
+ // turn off the session flag.
+ loc_eng_data_p->client_handle->setInSession(false);
+ }
+
+ // Free the allocated memory for rawData
+ GpsLocation* gp = (GpsLocation*)&(rpMsg->location);
+ if (gp != NULL && gp->rawData != NULL)
+ {
+ delete (char*)gp->rawData;
+ gp->rawData = NULL;
+ gp->rawDataSize = 0;
+ }
+ }
+
+ break;
+
+ case LOC_ENG_MSG_REPORT_SV:
+ if (loc_eng_data_p->mute_session_state != LOC_MUTE_SESS_IN_SESSION)
+ {
+ loc_eng_msg_report_sv *rsMsg = (loc_eng_msg_report_sv*)msg;
+ if (loc_eng_data_p->sv_status_cb != NULL) {
+ loc_eng_data_p->sv_status_cb((GpsSvStatus*)&(rsMsg->svStatus),
+ (void*)rsMsg->svExt);
+ }
+ }
+ break;
+
+ case LOC_ENG_MSG_REPORT_STATUS:
+ loc_eng_report_status(*loc_eng_data_p, ((loc_eng_msg_report_status*)msg)->status);
+ break;
+
+ case LOC_ENG_MSG_REPORT_NMEA:
+ if (NULL != loc_eng_data_p->nmea_cb) {
+ loc_eng_msg_report_nmea* nmMsg = (loc_eng_msg_report_nmea*)msg;
+ 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, nmMsg->nmea);
+ loc_eng_data_p->nmea_cb(now, nmMsg->nmea, nmMsg->length);
+ }
+ break;
+
+ case LOC_ENG_MSG_REQUEST_BIT:
+ {
+ AgpsStateMachine* stateMachine;
+ loc_eng_msg_request_bit* brqMsg = (loc_eng_msg_request_bit*)msg;
+ if (brqMsg->ifType == LOC_ENG_IF_REQUEST_TYPE_SUPL) {
+ stateMachine = loc_eng_data_p->agnss_nif;
+ } else if (brqMsg->ifType == LOC_ENG_IF_REQUEST_TYPE_ANY) {
+ stateMachine = loc_eng_data_p->internet_nif;
+ } else {
+ LOC_LOGD("%s]%d: unknown I/F request type = 0x%x\n", __func__, __LINE__, brqMsg->ifType);
+ break;
+ }
+ BITSubscriber subscriber(stateMachine, brqMsg->ipv4Addr, brqMsg->ipv6Addr);
+
+ stateMachine->subscribeRsrc((Subscriber*)&subscriber);
+ }
+ break;
+
+ case LOC_ENG_MSG_RELEASE_BIT:
+ {
+ AgpsStateMachine* stateMachine;
+ loc_eng_msg_release_bit* brlMsg = (loc_eng_msg_release_bit*)msg;
+ if (brlMsg->ifType == LOC_ENG_IF_REQUEST_TYPE_SUPL) {
+ stateMachine = loc_eng_data_p->agnss_nif;
+ } else if (brlMsg->ifType == LOC_ENG_IF_REQUEST_TYPE_ANY) {
+ stateMachine = loc_eng_data_p->internet_nif;
+ } else {
+ LOC_LOGD("%s]%d: unknown I/F request type = 0x%x\n", __func__, __LINE__, brlMsg->ifType);
+ break;
+ }
+ BITSubscriber subscriber(stateMachine, brlMsg->ipv4Addr, brlMsg->ipv6Addr);
+
+ stateMachine->unsubscribeRsrc((Subscriber*)&subscriber);
+ }
+ break;
+
+ case LOC_ENG_MSG_REQUEST_ATL:
+ {
+ loc_eng_msg_request_atl* arqMsg = (loc_eng_msg_request_atl*)msg;
+ boolean backwardCompatibleMode = AGPS_TYPE_INVALID == arqMsg->type;
+ AgpsStateMachine* stateMachine = (AGPS_TYPE_SUPL == arqMsg->type ||
+ backwardCompatibleMode) ?
+ loc_eng_data_p->agnss_nif :
+ loc_eng_data_p->internet_nif;
+ ATLSubscriber subscriber(arqMsg->handle,
+ stateMachine,
+ loc_eng_data_p->client_handle,
+ backwardCompatibleMode);
+
+ stateMachine->subscribeRsrc((Subscriber*)&subscriber);
+ }
+ break;
+
+ case LOC_ENG_MSG_RELEASE_ATL:
+ {
+ loc_eng_msg_release_atl* arlMsg = (loc_eng_msg_release_atl*)msg;
+ ATLSubscriber s1(arlMsg->handle,
+ loc_eng_data_p->agnss_nif,
+ loc_eng_data_p->client_handle,
+ false);
+ // attempt to unsubscribe from agnss_nif first
+ if (! loc_eng_data_p->agnss_nif->unsubscribeRsrc((Subscriber*)&s1)) {
+ ATLSubscriber s2(arlMsg->handle,
+ loc_eng_data_p->internet_nif,
+ loc_eng_data_p->client_handle,
+ false);
+ // if unsuccessful, try internet_nif
+ loc_eng_data_p->internet_nif->unsubscribeRsrc((Subscriber*)&s2);
+ }
+ }
+ break;
+
+ case LOC_ENG_MSG_REQUEST_WIFI:
+ {
+ loc_eng_msg_request_wifi *wrqMsg = (loc_eng_msg_request_wifi *)msg;
+ if (wrqMsg->senderId == LOC_ENG_IF_REQUEST_SENDER_ID_QUIPC ||
+ wrqMsg->senderId == LOC_ENG_IF_REQUEST_SENDER_ID_MSAPM) {
+ AgpsStateMachine* stateMachine = loc_eng_data_p->wifi_nif;
+ WIFISubscriber subscriber(stateMachine, wrqMsg->ssid, wrqMsg->password, wrqMsg->senderId);
+ stateMachine->subscribeRsrc((Subscriber*)&subscriber);
+ } else {
+ LOC_LOGE("%s]%d ERROR: unknown sender ID", __func__, __LINE__);
+ break;
+ }
+ }
+ break;
+
+ case LOC_ENG_MSG_RELEASE_WIFI:
+ {
+ AgpsStateMachine* stateMachine = loc_eng_data_p->wifi_nif;
+ loc_eng_msg_release_wifi* wrlMsg = (loc_eng_msg_release_wifi*)msg;
+ WIFISubscriber subscriber(stateMachine, wrlMsg->ssid, wrlMsg->password, wrlMsg->senderId);
+ stateMachine->unsubscribeRsrc((Subscriber*)&subscriber);
+ }
+ break;
+
+ case LOC_ENG_MSG_REQUEST_XTRA_DATA:
+ if (loc_eng_data_p->xtra_module_data.download_request_cb != NULL)
+ {
+ loc_eng_data_p->xtra_module_data.download_request_cb();
+ }
+ break;
+
+ case LOC_ENG_MSG_REQUEST_TIME:
+ break;
+
+ case LOC_ENG_MSG_REQUEST_POSITION:
+ break;
+
+ case LOC_ENG_MSG_DELETE_AIDING_DATA:
+ loc_eng_data_p->aiding_data_for_deletion |= ((loc_eng_msg_delete_aiding_data*)msg)->type;
+ break;
+
+ case LOC_ENG_MSG_ENABLE_DATA:
+ {
+ loc_eng_msg_set_data_enable *unaMsg = (loc_eng_msg_set_data_enable*)msg;
+ loc_eng_data_p->client_handle->enableData(unaMsg->enable);
+ loc_eng_data_p->client_handle->setAPN(unaMsg->apn, unaMsg->length);
+ }
+ break;
+
+ case LOC_ENG_MSG_INJECT_XTRA_DATA:
+ {
+ loc_eng_msg_inject_xtra_data *xdMsg = (loc_eng_msg_inject_xtra_data*)msg;
+ loc_eng_data_p->client_handle->setXtraData(xdMsg->data, xdMsg->length);
+ }
+ break;
+
+ case LOC_ENG_MSG_ATL_OPEN_SUCCESS:
+ {
+ loc_eng_msg_atl_open_success *aosMsg = (loc_eng_msg_atl_open_success*)msg;
+ AgpsStateMachine* stateMachine;
+ switch (aosMsg->agpsType) {
+ case AGPS_TYPE_WIFI: {
+ stateMachine = loc_eng_data_p->wifi_nif;
+ break;
+ }
+ case AGPS_TYPE_SUPL: {
+ stateMachine = loc_eng_data_p->agnss_nif;
+ break;
+ }
+ default: {
+ stateMachine = loc_eng_data_p->internet_nif;
+ }
+ }
+
+ stateMachine->setBearer(aosMsg->bearerType);
+ stateMachine->setAPN(aosMsg->apn, aosMsg->length);
+ stateMachine->onRsrcEvent(RSRC_GRANTED);
+ }
+ break;
+
+ case LOC_ENG_MSG_ATL_CLOSED:
+ {
+ loc_eng_msg_atl_closed *acsMsg = (loc_eng_msg_atl_closed*)msg;
+ AgpsStateMachine* stateMachine;
+ switch (acsMsg->agpsType) {
+ case AGPS_TYPE_WIFI: {
+ stateMachine = loc_eng_data_p->wifi_nif;
+ break;
+ }
+ case AGPS_TYPE_SUPL: {
+ stateMachine = loc_eng_data_p->agnss_nif;
+ break;
+ }
+ default: {
+ stateMachine = loc_eng_data_p->internet_nif;
+ }
+ }
+
+ stateMachine->onRsrcEvent(RSRC_RELEASED);
+ }
+ break;
+
+ case LOC_ENG_MSG_ATL_OPEN_FAILED:
+ {
+ loc_eng_msg_atl_open_failed *aofMsg = (loc_eng_msg_atl_open_failed*)msg;
+ AgpsStateMachine* stateMachine;
+ switch (aofMsg->agpsType) {
+ case AGPS_TYPE_WIFI: {
+ stateMachine = loc_eng_data_p->wifi_nif;
+ break;
+ }
+ case AGPS_TYPE_SUPL: {
+ stateMachine = loc_eng_data_p->agnss_nif;
+ break;
+ }
+ default: {
+ stateMachine = loc_eng_data_p->internet_nif;
+ }
+ }
+
+ stateMachine->onRsrcEvent(RSRC_DENIED);
+ }
+ break;
+
+ case LOC_ENG_MSG_ENGINE_DOWN:
+ loc_eng_handle_engine_down(*loc_eng_data_p);
+ break;
+
+ case LOC_ENG_MSG_ENGINE_UP:
+ loc_eng_handle_engine_up(*loc_eng_data_p);
+ break;
+
+ case LOC_ENG_MSG_REQUEST_NETWORK_POSIITON:
+ {
+ loc_eng_msg_request_network_position *nlprequestmsg = (loc_eng_msg_request_network_position*)msg;
+ //loc_eng_handle_request_network_position(nlprequestmsg );
+ LOC_LOGD("Received n/w position request from ULP.Request type %d Periodicity: %d\n",
+ nlprequestmsg->networkPosRequest.request_type,
+ nlprequestmsg->networkPosRequest.interval_ms);
+ if(loc_eng_data_p->ulp_network_callback != NULL)
+ {
+ loc_eng_data_p->ulp_network_callback((UlpNetworkRequestPos*)&(nlprequestmsg->networkPosRequest));
+ }
+ else
+ LOC_LOGE("Ulp Network call back not initialized");
+ }
+ break;
+
+ case LOC_ENG_MSG_REQUEST_PHONE_CONTEXT:
+ {
+ loc_eng_msg_request_phone_context *contextReqMsg = (loc_eng_msg_request_phone_context*)msg;
+ LOC_LOGD("Received phone context request from ULP.context_type 0x%x,request_type 0x%x ",
+ contextReqMsg->contextRequest.context_type,contextReqMsg->contextRequest.request_type)
+ if(loc_eng_data_p->ulp_phone_context_req_cb != NULL)
+ {
+ loc_eng_data_p->ulp_phone_context_req_cb((UlpPhoneContextRequest*)&(contextReqMsg->contextRequest));
+ }
+ else
+ LOC_LOGE("Ulp Phone context request call back not initialized");
+ }
+ break;
+
+ case LOC_ENG_MSG_PRIVACY:
+ {
+ loc_eng_msg_privacy *privacyMsg = (loc_eng_msg_privacy*)msg;
+ LOC_LOGE("Ignoring call to setPrivacy");
+ //loc_eng_data_p->client_handle->setPrivacy(privacyMsg->privacy_setting);
+ }
+ break;
+
+ default:
+ LOC_LOGE("unsupported msgid = %d\n", msg->msgid);
+ break;
+ }
+
+ if ( (msg->msgid == LOC_ENG_MSG_ATL_OPEN_FAILED) |
+ (msg->msgid == LOC_ENG_MSG_ATL_CLOSED) |
+ (msg->msgid == LOC_ENG_MSG_ATL_OPEN_SUCCESS) )
+ {
+ loc_eng_data_p->agps_request_pending = false;
+ if (loc_eng_data_p->stop_request_pending) {
+ loc_eng_stop_handler(*loc_eng_data_p);
+ loc_eng_data_p->stop_request_pending = false;
+ }
+ }
+ loc_eng_data_p->stop_request_pending = false;
+
+ if (loc_eng_data_p->engine_status != GPS_STATUS_ENGINE_ON &&
+ loc_eng_data_p->aiding_data_for_deletion != 0)
+ {
+ loc_eng_data_p->client_handle->deleteAidingData(loc_eng_data_p->aiding_data_for_deletion);
+ loc_eng_data_p->aiding_data_for_deletion = 0;
+ }
+
+ delete msg;
+ }
+
+ EXIT_LOG(%s, VOID_RET);
+}
+
+/*===========================================================================
+FUNCTION loc_eng_ulp_init
+
+DESCRIPTION
+ This function dynamically loads the libulp.so and calls
+ its init function to start up the ulp module
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0: no error
+ -1: errors
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_ulp_init(loc_eng_data_s_type &loc_eng_data, const ulpInterface * loc_eng_ulpInf)
+{
+ ENTRY_LOG();
+ int ret_val=-1;
+
+ if(loc_eng_ulpInf != NULL)
+ {
+ // Initialize the ULP interface
+ ((ulpInterface *)loc_eng_ulpInf)->init(loc_eng_data);
+ loc_eng_data.ulp_initialized = TRUE;
+ }
+ ret_val = 0;
+exit:
+ EXIT_LOG(%d, ret_val);
+ return ret_val;
+}
+
+/*===========================================================================
+FUNCTION loc_eng_inject_raw_command
+
+DESCRIPTION
+ This is used to send special test modem commands from the applications
+ down into the HAL
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ 0: success
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+bool loc_eng_inject_raw_command(loc_eng_data_s_type &loc_eng_data,
+ char* command, int length)
+{
+ ENTRY_LOG_CALLFLOW();
+ INIT_CHECK(loc_eng_data.context, return -1);
+ boolean ret_val;
+ LOC_LOGD("loc_eng_send_extra_command: %s\n", command);
+ ret_val = TRUE;
+
+ if((loc_eng_data.ulp_initialized == true) && (gps_conf.CAPABILITIES & ULP_CAPABILITY))
+ {
+ ulp_msg_inject_raw_command *msg(
+ new ulp_msg_inject_raw_command(&loc_eng_data,command, length));
+ msg_q_snd( (void*)((LocEngContext*)(loc_eng_data.context))->ulp_q
+ , msg, loc_eng_free_msg);
+ ret_val = 0;
+ }else
+ {
+ ret_val = -1;
+ }
+
+
+ EXIT_LOG(%s, loc_logger_boolStr[ret_val!=0]);
+ return ret_val;
+}
+/*===========================================================================
+FUNCTION loc_eng_update_criteria
+
+DESCRIPTION
+ This is used to inform the ULP module of new unique criteria that are passed
+ in by the applications
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ 0: success
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_update_criteria(loc_eng_data_s_type &loc_eng_data,
+ UlpLocationCriteria criteria)
+{
+ ENTRY_LOG_CALLFLOW();
+ INIT_CHECK(loc_eng_data.context, return -1);
+ int ret_val;
+
+ if((loc_eng_data.ulp_initialized == true) && (gps_conf.CAPABILITIES & ULP_CAPABILITY))
+ {
+ LOC_LOGD("SJ:loc_eng_update_criteria: valid 0x%x action:%d, minTime:%ld, minDistance:%f, singleShot:%d, horizontalAccuracy:%d, powerRequirement:%d \n",
+ criteria.valid_mask, criteria.action, criteria.min_interval, criteria.min_distance, criteria.recurrence_type, criteria.preferred_horizontal_accuracy,
+ criteria.preferred_power_consumption );
+ ulp_msg_update_criteria *msg(
+ new ulp_msg_update_criteria(&loc_eng_data,criteria));
+ msg_q_snd( (void*)((LocEngContext*)(loc_eng_data.context))->ulp_q
+ , msg, loc_eng_free_msg);
+ ret_val = 0;
+ }else
+ {
+ ret_val = -1;
+ }
+ EXIT_LOG(%d, ret_val);
+ return ret_val;
+}
+
+/*===========================================================================
+FUNCTION loc_eng_ulp_phone_context_settings_update
+
+DESCRIPTION
+ This is used to inform the ULP module of phone settings changes carried out
+ by the users
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ 0: success
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+
+int loc_eng_ulp_phone_context_settings_update(loc_eng_data_s_type &loc_eng_data,
+ UlpPhoneContextSettings *settings)
+{
+ ENTRY_LOG();
+ int ret_val = -1;
+
+ LOC_LOGD("loc_eng_ulp_phone_context_settings: context_type - 0x%x is_agps_enabled - %d "
+ "is_battery_charging %d ,is_gps_enabled %d, is_network_position_available %d,"
+ "is_wifi_setting_enabled %d, is_agps_setting_enabled %d, is_enh_location_services_enabled %d\n",
+ settings->context_type ,settings->is_agps_enabled,settings->is_battery_charging,
+ settings->is_gps_enabled, settings->is_network_position_available,
+ settings->is_wifi_setting_enabled, settings->is_agps_enabled,
+ settings->is_enh_location_services_enabled );
+
+ if((loc_eng_data.ulp_initialized == true) && (gps_conf.CAPABILITIES & ULP_CAPABILITY))
+ {
+ ulp_msg_inject_phone_context_settings *msg
+ (new ulp_msg_inject_phone_context_settings(&loc_eng_data, *settings));
+ msg_q_snd( (void*)((LocEngContext*)(loc_eng_data.context))->ulp_q, msg, loc_eng_free_msg);
+ ret_val = 0;
+ }
+
+ // Send battery information to modem for processing.
+ if(settings->context_type & ULP_PHONE_CONTEXT_BATTERY_CHARGING_STATE)
+ {
+ loc_eng_msg_ext_power_config *msg(new loc_eng_msg_ext_power_config(&loc_eng_data, settings->is_battery_charging));
+ msg_q_snd( (void*)((LocEngContext*)(loc_eng_data.context))->deferred_q, msg, loc_eng_free_msg);
+ }
+
+ EXIT_LOG(%d, ret_val);
+ return ret_val;
+}
+/*===========================================================================
+FUNCTION loc_eng_ulp_network_init
+
+DESCRIPTION
+ Initialize the ULP network interface.
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ 0
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_ulp_phone_context_init(loc_eng_data_s_type &loc_eng_data,UlpPhoneContextCallbacks *callback)
+{
+ ENTRY_LOG();
+ loc_eng_data.ulp_phone_context_req_cb = callback->ulp_request_phone_context_cb ;
+ int ret_val =0;
+ EXIT_LOG(%d, ret_val);
+ return ret_val;
+}
+
+/*===========================================================================
+FUNCTION loc_eng_ulp_network_init
+
+DESCRIPTION
+ Initialize the ULP network interface.
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ 0
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_ulp_network_init(loc_eng_data_s_type &loc_eng_data,
+ UlpNetworkLocationCallbacks *callbacks)
+{
+ ENTRY_LOG_CALLFLOW();
+ loc_eng_data.ulp_network_callback = callbacks->ulp_network_location_request_cb;
+ int ret_val =0;
+ EXIT_LOG(%d, ret_val);
+ return ret_val;
+}
+
+
+/*===========================================================================
+FUNCTION loc_eng_ulp_send_network_position
+
+DESCRIPTION
+ Ulp send data
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ 0
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_ulp_send_network_position(loc_eng_data_s_type &loc_eng_data,
+ UlpNetworkPositionReport *position_report)
+{
+ ENTRY_LOG();
+ int ret_val = 0;
+ if((loc_eng_data.ulp_initialized == true) && (gps_conf.CAPABILITIES & ULP_CAPABILITY))
+ {
+ ulp_msg_inject_network_position *msg
+ (new ulp_msg_inject_network_position(&loc_eng_data, *position_report));
+ msg_q_snd( (void*)((LocEngContext*)(loc_eng_data.context))->ulp_q
+ , msg, loc_eng_free_msg);
+ ret_val = 0;
+ }else
+ {
+ ret_val = -1;
+ }
+ EXIT_LOG(%d, ret_val);
+ return ret_val;
+}
+/*===========================================================================
+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(gpsConfigAlreadyRead == false)
+ {
+ // Initialize our defaults before reading of configuration file overwrites them.
+ loc_default_parameters();
+ // Ee 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);
+ gpsConfigAlreadyRead = true;
+ } else {
+ LOC_LOGV("GPS Config file has already been read\n");
+ }
+
+ EXIT_LOG(%d, 0);
+ return 0;
+}
+
+/*===========================================================================
+FUNCTION loc_eng_set_privacy
+
+DESCRIPTION
+ Sets the privacy lock setting (1. GPS on, 0. GPS off).
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0: success
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static int loc_eng_set_privacy(loc_eng_data_s_type &loc_eng_data,
+ int8_t privacy_setting)
+{
+ ENTRY_LOG();
+ INIT_CHECK(loc_eng_data.context, return -1);
+ loc_eng_msg_privacy *msg(
+ new loc_eng_msg_privacy(&loc_eng_data, privacy_setting));
+ msg_q_snd((void*)((LocEngContext*)(loc_eng_data.context))->deferred_q,
+ msg, loc_eng_free_msg);
+
+ EXIT_LOG(%d, 0);
+ return 0;
+}
diff --git a/gps/libloc_api_50001/loc_eng.h b/gps/libloc_api_50001/loc_eng.h
new file mode 100644
index 0000000..a14f5bd
--- /dev/null
+++ b/gps/libloc_api_50001/loc_eng.h
@@ -0,0 +1,252 @@
+/* Copyright (c) 2009-2012 Code Aurora Forum. 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 Code Aurora Forum, 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 "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_msg.h>
+#include <loc_eng_agps.h>
+#include <LocApiAdapter.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
+
+enum loc_mute_session_e_type {
+ LOC_MUTE_SESS_NONE = 0,
+ LOC_MUTE_SESS_WAIT,
+ LOC_MUTE_SESS_IN_SESSION
+};
+
+struct LocEngContext {
+ // Data variables used by deferred action thread
+ const void* deferred_q;
+ const void* ulp_q;
+ const pthread_t deferred_action_thread;
+ static LocEngContext* get(gps_create_thread threadCreator);
+ void drop();
+ static pthread_mutex_t lock;
+ static pthread_cond_t cond;
+private:
+ int counter;
+ static LocEngContext *me;
+ LocEngContext(gps_create_thread threadCreator);
+};
+
+// Module data
+typedef struct
+{
+ LocApiAdapter *client_handle;
+ loc_location_cb_ext location_cb;
+ gps_status_callback status_cb;
+ loc_sv_status_cb_ext sv_status_cb;
+ agps_status_callback 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;
+ ulp_network_location_request ulp_network_callback;
+ ulp_request_phone_context ulp_phone_context_req_cb;
+ boolean intermediateFix;
+ AGpsStatusValue agps_status;
+ // used to defer stopping the GPS engine until AGPS data calls are done
+ boolean agps_request_pending;
+ boolean stop_request_pending;
+ 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;
+
+ // 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;
+
+ void* context;
+
+ // For muting session broadcast
+ loc_mute_session_e_type mute_session_state;
+
+ // 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;
+ bool ulp_initialized;
+} loc_eng_data_s_type;
+
+#include "ulp.h"
+
+/* GPS.conf support */
+typedef struct loc_gps_cfg_s
+{
+ unsigned long INTERMEDIATE_POS;
+ unsigned long ACCURACY_THRES;
+ unsigned long ENABLE_WIPER;
+ unsigned long SUPL_VER;
+ unsigned long CAPABILITIES;
+ 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 QUIPC_ENABLED;
+ unsigned long LPP_PROFILE;
+ 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;
+} loc_gps_cfg_s_type;
+
+extern loc_gps_cfg_s_type gps_conf;
+
+int loc_eng_init(loc_eng_data_s_type &loc_eng_data,
+ LocCallbacks* callbacks,
+ LOC_API_ADAPTER_EVENT_MASK_T event,
+ void (*loc_external_msg_sender) (void*, void*));
+int loc_eng_ulp_init(loc_eng_data_s_type &loc_eng_data, const ulpInterface * loc_eng_ulpInf);
+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_update_criteria(loc_eng_data_s_type &loc_eng_data,
+ UlpLocationCriteria criteria);
+
+
+void loc_eng_agps_init(loc_eng_data_s_type &loc_eng_data,
+ AGpsCallbacks* callbacks);
+int loc_eng_agps_open(loc_eng_data_s_type &loc_eng_data, AGpsType agpsType,
+ const char* apn, AGpsBearerType bearerType);
+int loc_eng_agps_closed(loc_eng_data_s_type &loc_eng_data, AGpsType agpsType);
+int loc_eng_agps_open_failed(loc_eng_data_s_type &loc_eng_data, AGpsType agpsType);
+int loc_eng_set_server_proxy(loc_eng_data_s_type &loc_eng_data,
+ LocServerType type, const char *hostname, int port);
+
+
+void loc_eng_agps_ril_update_network_availability(loc_eng_data_s_type &loc_eng_data,
+ int avaiable, const char* apn);
+
+
+bool loc_eng_inject_raw_command(loc_eng_data_s_type &loc_eng_data,
+ char* command, int length);
+
+
+void loc_eng_mute_one_session(loc_eng_data_s_type &loc_eng_data);
+
+int loc_eng_xtra_init (loc_eng_data_s_type &loc_eng_data,
+ GpsXtraCallbacks* callbacks);
+
+int loc_eng_xtra_inject_data(loc_eng_data_s_type &loc_eng_data,
+ char* data, int length);
+
+extern void loc_eng_ni_init(loc_eng_data_s_type &loc_eng_data,
+ GpsNiCallbacks *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);
+int loc_eng_ulp_network_init(loc_eng_data_s_type &loc_eng_data, UlpNetworkLocationCallbacks *callbacks);
+
+int loc_eng_ulp_phone_context_settings_update(loc_eng_data_s_type &loc_eng_data,
+ UlpPhoneContextSettings *settings);
+int loc_eng_ulp_phone_context_init(loc_eng_data_s_type &loc_eng_data,
+ UlpPhoneContextCallbacks *callback);
+int loc_eng_ulp_send_network_position(loc_eng_data_s_type &loc_eng_data,
+ UlpNetworkPositionReport *position_report);
+int loc_eng_read_config(void);
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif // LOC_ENG_H
diff --git a/gps/libloc_api_50001/loc_eng_agps.cpp b/gps/libloc_api_50001/loc_eng_agps.cpp
new file mode 100644
index 0000000..e9524d5
--- /dev/null
+++ b/gps/libloc_api_50001/loc_eng_agps.cpp
@@ -0,0 +1,737 @@
+/* Copyright (c) 2011,2012, Code Aurora Forum. 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 Code Aurora Forum, 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 "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 <loc_eng_dmn_conn_handler.h>
+#include <loc_eng_dmn_conn.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;
+
+
+//======================================================================
+// 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(ipv6Addr, bitS->ipv6Addr, sizeof(ipv6Addr))));
+}
+
+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:
+ ((LocApiAdapter*)mLocAdapter)->atlCloseStatus(ID, 1);
+ break;
+ case RSRC_DENIED:
+ {
+ AGpsType type = mBackwardCompatibleMode ?
+ AGPS_TYPE_INVALID : mStateMachine->getType();
+ ((LocApiAdapter*)mLocAdapter)->atlOpenStatus(ID, 0,
+ (char*)mStateMachine->getAPN(),
+ mStateMachine->getBearer(),
+ type);
+ }
+ break;
+ case RSRC_GRANTED:
+ {
+ AGpsType type = mBackwardCompatibleMode ?
+ AGPS_TYPE_INVALID : mStateMachine->getType();
+ ((LocApiAdapter*)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;
+}
+
+
+//======================================================================
+// 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)
+{
+ 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);
+ // move the state to PENDING
+ nextState = mPendingState;
+
+ // request from connecivity service for NIF
+ mStateMachine->sendRsrcRequest(GPS_REQUEST_AGPS_DATA_CONN);
+ }
+ 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;;
+ 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;
+ 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;;
+ 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->hasSubscribers()) {
+ 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;
+}
+
+
+//======================================================================
+// AgpsStateMachine
+//======================================================================
+
+AgpsStateMachine::AgpsStateMachine(void (*servicer)(AGpsStatus* status),
+ AGpsType type,
+ bool enforceSingleSubscriber) :
+ mServicer(servicer), mType(type),
+ mStatePtr(new AgpsReleasedState(this)),
+ mAPN(NULL),
+ mAPNLen(0),
+ mEnforceSingleSubscriber(enforceSingleSubscriber)
+{
+ 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;
+ 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);
+ }
+ } 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);
+ }
+}
+
+void 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)) {
+ AGpsStatus 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)(&nifRequest);
+ }
+}
+
+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;
+}
diff --git a/gps/libloc_api_50001/loc_eng_agps.h b/gps/libloc_api_50001/loc_eng_agps.h
new file mode 100644
index 0000000..a0873d0
--- /dev/null
+++ b/gps/libloc_api_50001/loc_eng_agps.h
@@ -0,0 +1,324 @@
+/* Copyright (c) 2011,2012, Code Aurora Forum. 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 Code Aurora Forum, 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 "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 <linked_list.h>
+#include <LocApiAdapter.h>
+#include "loc_eng_msg.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;
+
+// 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;
+
+ // 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 AgpsStateMachine {
+ // 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;
+
+ // handle to whoever provides the service
+ void (* const mServicer)(AGpsStatus* status);
+ // NIF type: AGNSS or INTERNET.
+ const AGpsType mType;
+ // pointer to the current state.
+ AgpsState* mStatePtr;
+ // a linked list of subscribers.
+ void* mSubscribers;
+ // 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(void (*servicer)(AGpsStatus* status), AGpsType 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 AGpsType getType() const { return (AGpsType)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;
+
+ void onRsrcEvent(AgpsRsrcStatus event);
+
+ // put the data together and send the FW
+ void sendRsrcRequest(AGpsStatusValue action) const;
+
+ 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;
+};
+
+// 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 int ID;
+ const AgpsStateMachine* mStateMachine;
+ inline Subscriber(const int id,
+ const AgpsStateMachine* stateMachine) :
+ ID(id), mStateMachine(stateMachine) {}
+ inline virtual ~Subscriber() {}
+
+ virtual void setIPAddresses(int &v4, char* v6) = 0;
+ inline virtual void setWifiInfo(char* ssid, char* password) {}
+
+ 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 {
+ inline BITSubscriber(const AgpsStateMachine* stateMachine,
+ unsigned int ipv4, char* ipv6) :
+ Subscriber(ipv4, stateMachine)
+ {
+ if (NULL == ipv6) {
+ ipv6Addr[0] = NULL;
+ } else {
+ memcpy(ipv6Addr, ipv6, sizeof(ipv6Addr));
+ }
+ }
+
+ virtual bool notifyRsrcStatus(Notification &notification);
+
+ inline virtual void setIPAddresses(int &v4, char* v6)
+ { v4 = ID; memcpy(v6, ipv6Addr, sizeof(ipv6Addr)); }
+
+ virtual Subscriber* clone()
+ {
+ return new BITSubscriber(mStateMachine, ID, ipv6Addr);
+ }
+
+ virtual bool equals(const Subscriber *s) const;
+
+private:
+ char ipv6Addr[16];
+};
+
+// ATLSubscriber, created with requests from ATL
+struct ATLSubscriber : public Subscriber {
+ const LocApiAdapter* mLocAdapter;
+ const bool mBackwardCompatibleMode;
+ inline ATLSubscriber(const int id,
+ const AgpsStateMachine* stateMachine,
+ const LocApiAdapter* adapter,
+ const bool compatibleMode) :
+ Subscriber(id, stateMachine), mLocAdapter(adapter),
+ mBackwardCompatibleMode(compatibleMode){}
+ virtual bool notifyRsrcStatus(Notification &notification);
+
+ inline virtual void setIPAddresses(int &v4, char* v6)
+ { v4 = INADDR_NONE; v6[0] = 0; }
+
+ inline virtual Subscriber* clone()
+ {
+ return new ATLSubscriber(ID, mStateMachine, mLocAdapter,
+ mBackwardCompatibleMode);
+ }
+};
+
+// 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(int &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);
+ }
+};
+
+#endif //__LOC_ENG_AGPS_H__
diff --git a/gps/libloc_api_50001/loc_eng_dmn_conn.cpp b/gps/libloc_api_50001/loc_eng_dmn_conn.cpp
new file mode 100644
index 0000000..2bb2d81
--- /dev/null
+++ b/gps/libloc_api_50001/loc_eng_dmn_conn.cpp
@@ -0,0 +1,238 @@
+/* Copyright (c) 2011,2012, Code Aurora Forum. 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 Code Aurora Forum, 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 "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 "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 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 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, gid = %d, result = %d, error = %s\n", 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);
+ 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);
+
+ 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 0;
+ }
+
+ 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);
+ 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_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/libloc_api_50001/loc_eng_dmn_conn.h b/gps/libloc_api_50001/loc_eng_dmn_conn.h
new file mode 100644
index 0000000..f669248
--- /dev/null
+++ b/gps/libloc_api_50001/loc_eng_dmn_conn.h
@@ -0,0 +1,57 @@
+/* Copyright (c) 2011,2012, Code Aurora Forum. 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 Code Aurora Forum, 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 "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/gpsone_d/gpsone_loc_api_q"
+#define GPSONE_LOC_API_RESP_Q_PATH "/data/misc/gpsone_d/gpsone_loc_api_resp_q"
+#define QUIPC_CTRL_Q_PATH "/data/misc/gpsone_d/quipc_ctrl_q"
+#define MSAPM_CTRL_Q_PATH "/data/misc/gpsone_d/msapm_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"
+
+#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/libloc_api_50001/loc_eng_dmn_conn_glue_msg.c b/gps/libloc_api_50001/loc_eng_dmn_conn_glue_msg.c
new file mode 100644
index 0000000..9cd1922
--- /dev/null
+++ b/gps/libloc_api_50001/loc_eng_dmn_conn_glue_msg.c
@@ -0,0 +1,223 @@
+/* Copyright (c) 2011, Code Aurora Forum. 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 Code Aurora Forum, 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 "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 "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/libloc_api_50001/loc_eng_dmn_conn_glue_msg.h b/gps/libloc_api_50001/loc_eng_dmn_conn_glue_msg.h
new file mode 100644
index 0000000..8bc6f2a
--- /dev/null
+++ b/gps/libloc_api_50001/loc_eng_dmn_conn_glue_msg.h
@@ -0,0 +1,51 @@
+/* Copyright (c) 2011, Code Aurora Forum. 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 Code Aurora Forum, 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 "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/libloc_api_50001/loc_eng_dmn_conn_glue_pipe.c b/gps/libloc_api_50001/loc_eng_dmn_conn_glue_pipe.c
new file mode 100644
index 0000000..7476908
--- /dev/null
+++ b/gps/libloc_api_50001/loc_eng_dmn_conn_glue_pipe.c
@@ -0,0 +1,206 @@
+/* Copyright (c) 2011, Code Aurora Forum. 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 Code Aurora Forum, 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 "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"
+
+/*===========================================================================
+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, 0666);
+
+ if ((result == -1) && (errno != EEXIST)) {
+ LOC_LOGE("failed: %s\n", strerror(errno));
+ return result;
+ }
+
+ 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/libloc_api_50001/loc_eng_dmn_conn_glue_pipe.h b/gps/libloc_api_50001/loc_eng_dmn_conn_glue_pipe.h
new file mode 100644
index 0000000..3136e41
--- /dev/null
+++ b/gps/libloc_api_50001/loc_eng_dmn_conn_glue_pipe.h
@@ -0,0 +1,50 @@
+/* Copyright (c) 2011, Code Aurora Forum. 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 Code Aurora Forum, 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 "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/libloc_api_50001/loc_eng_dmn_conn_handler.cpp b/gps/libloc_api_50001/loc_eng_dmn_conn_handler.cpp
new file mode 100644
index 0000000..6077b72
--- /dev/null
+++ b/gps/libloc_api_50001/loc_eng_dmn_conn_handler.cpp
@@ -0,0 +1,204 @@
+/* Copyright (c) 2011,2012, Code Aurora Forum. 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 Code Aurora Forum, 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 "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 "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) {
+ loc_if_req_type_e_type type;
+ switch (pmsg->cmsg.cmsg_if_request.type) {
+ case IF_REQUEST_TYPE_SUPL:
+ {
+ LOC_LOGD("IF_REQUEST_TYPE_SUPL");
+ type = LOC_ENG_IF_REQUEST_TYPE_SUPL;
+ break;
+ }
+ case IF_REQUEST_TYPE_WIFI:
+ {
+ LOC_LOGD("IF_REQUEST_TYPE_WIFI");
+ type = LOC_ENG_IF_REQUEST_TYPE_WIFI;
+ break;
+ }
+ case IF_REQUEST_TYPE_ANY:
+ {
+ LOC_LOGD("IF_REQUEST_TYPE_ANY");
+ type = LOC_ENG_IF_REQUEST_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");
+ loc_eng_msg_request_wifi *msg(
+ new loc_eng_msg_request_wifi(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));
+ loc_eng_msg_sender(loc_api_handle, msg);
+ break;
+ }
+ case IF_REQUEST_SENDER_ID_MSAPM:
+ {
+ LOC_LOGD("IF_REQUEST_SENDER_ID_MSAPM");
+ loc_eng_msg_request_wifi *msg(
+ new loc_eng_msg_request_wifi(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));
+ loc_eng_msg_sender(loc_api_handle, msg);
+ break;
+ }
+ case IF_REQUEST_SENDER_ID_GPSONE_DAEMON:
+ {
+ LOC_LOGD("IF_REQUEST_SENDER_ID_GPSONE_DAEMON");
+ loc_eng_msg_request_bit *msg(
+ new loc_eng_msg_request_bit(loc_api_handle,
+ type,
+ pmsg->cmsg.cmsg_if_request.ipv4_addr,
+ (char*)pmsg->cmsg.cmsg_if_request.ipv6_addr));
+ loc_eng_msg_sender(loc_api_handle, msg);
+ 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
+ loc_if_req_type_e_type type;
+ switch (pmsg->cmsg.cmsg_if_request.type) {
+ case IF_REQUEST_TYPE_SUPL:
+ {
+ LOC_LOGD("IF_REQUEST_TYPE_SUPL");
+ type = LOC_ENG_IF_REQUEST_TYPE_SUPL;
+ break;
+ }
+ case IF_REQUEST_TYPE_WIFI:
+ {
+ LOC_LOGD("IF_REQUEST_TYPE_WIFI");
+ type = LOC_ENG_IF_REQUEST_TYPE_WIFI;
+ break;
+ }
+ case IF_REQUEST_TYPE_ANY:
+ {
+ LOC_LOGD("IF_REQUEST_TYPE_ANY");
+ type = LOC_ENG_IF_REQUEST_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");
+ loc_eng_msg_release_wifi *msg(
+ new loc_eng_msg_release_wifi(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));
+ loc_eng_msg_sender(loc_api_handle, msg);
+ break;
+ }
+ case IF_REQUEST_SENDER_ID_MSAPM:
+ {
+ LOC_LOGD("IF_REQUEST_SENDER_ID_MSAPM");
+ loc_eng_msg_release_wifi *msg(
+ new loc_eng_msg_release_wifi(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));
+ loc_eng_msg_sender(loc_api_handle, msg);
+ break;
+ }
+ case IF_REQUEST_SENDER_ID_GPSONE_DAEMON:
+ {
+ LOC_LOGD("IF_REQUEST_SENDER_ID_GPSONE_DAEMON");
+ loc_eng_msg_release_bit *msg(
+ new loc_eng_msg_release_bit(loc_api_handle,
+ type,
+ pmsg->cmsg.cmsg_if_request.ipv4_addr,
+ (char*)pmsg->cmsg.cmsg_if_request.ipv6_addr));
+ loc_eng_msg_sender(loc_api_handle, msg);
+ 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/libloc_api_50001/loc_eng_dmn_conn_handler.h b/gps/libloc_api_50001/loc_eng_dmn_conn_handler.h
new file mode 100644
index 0000000..7aa22bf
--- /dev/null
+++ b/gps/libloc_api_50001/loc_eng_dmn_conn_handler.h
@@ -0,0 +1,101 @@
+/* Copyright (c) 2011,2012, Code Aurora Forum. 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 Code Aurora Forum, 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 "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>
+
+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_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/libloc_api_50001/loc_eng_dmn_conn_thread_helper.c b/gps/libloc_api_50001/loc_eng_dmn_conn_thread_helper.c
new file mode 100644
index 0000000..478b686
--- /dev/null
+++ b/gps/libloc_api_50001/loc_eng_dmn_conn_thread_helper.c
@@ -0,0 +1,398 @@
+/* Copyright (c) 2011, Code Aurora Forum. 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 Code Aurora Forum, 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 "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 "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/libloc_api_50001/loc_eng_dmn_conn_thread_helper.h b/gps/libloc_api_50001/loc_eng_dmn_conn_thread_helper.h
new file mode 100644
index 0000000..07869f9
--- /dev/null
+++ b/gps/libloc_api_50001/loc_eng_dmn_conn_thread_helper.h
@@ -0,0 +1,74 @@
+/* Copyright (c) 2011, Code Aurora Forum. 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 Code Aurora Forum, 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 "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/libloc_api_50001/loc_eng_log.cpp b/gps/libloc_api_50001/loc_eng_log.cpp
new file mode 100644
index 0000000..95db6c3
--- /dev/null
+++ b/gps/libloc_api_50001/loc_eng_log.cpp
@@ -0,0 +1,299 @@
+/* Copyright (c) 2011,2012 Code Aurora Forum. 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 Code Aurora Forum, 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 "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 "hardware/gps.h"
+#include "loc_log.h"
+#include "loc_eng_log.h"
+#include "loc_eng_msg_id.h"
+
+/* GPS status names */
+static loc_name_val_s_type gps_status_name[] =
+{
+ NAME_VAL( GPS_STATUS_NONE ),
+ NAME_VAL( GPS_STATUS_SESSION_BEGIN ),
+ NAME_VAL( GPS_STATUS_SESSION_END ),
+ NAME_VAL( GPS_STATUS_ENGINE_ON ),
+ NAME_VAL( GPS_STATUS_ENGINE_OFF ),
+};
+static int gps_status_num = sizeof(gps_status_name) / sizeof(loc_name_val_s_type);
+
+/* Find Android GPS status name */
+const char* loc_get_gps_status_name(GpsStatusValue gps_status)
+{
+ return loc_get_name_from_val(gps_status_name, gps_status_num,
+ (long) gps_status);
+}
+
+
+
+static loc_name_val_s_type loc_eng_msgs[] =
+{
+ NAME_VAL( LOC_ENG_MSG_QUIT ),
+ NAME_VAL( LOC_ENG_MSG_ENGINE_DOWN ),
+ NAME_VAL( LOC_ENG_MSG_ENGINE_UP ),
+ NAME_VAL( LOC_ENG_MSG_START_FIX ),
+ NAME_VAL( LOC_ENG_MSG_STOP_FIX ),
+ NAME_VAL( LOC_ENG_MSG_SET_POSITION_MODE ),
+ NAME_VAL( LOC_ENG_MSG_SET_TIME ),
+ NAME_VAL( LOC_ENG_MSG_INJECT_XTRA_DATA ),
+ NAME_VAL( LOC_ENG_MSG_INJECT_LOCATION ),
+ NAME_VAL( LOC_ENG_MSG_DELETE_AIDING_DATA ),
+ NAME_VAL( LOC_ENG_MSG_SET_APN ),
+ NAME_VAL( LOC_ENG_MSG_SET_SERVER_URL ),
+ NAME_VAL( LOC_ENG_MSG_SET_SERVER_IPV4 ),
+ NAME_VAL( LOC_ENG_MSG_ENABLE_DATA ),
+ NAME_VAL( LOC_ENG_MSG_SUPL_VERSION ),
+ NAME_VAL( LOC_ENG_MSG_SET_SENSOR_CONTROL_CONFIG ),
+ NAME_VAL( LOC_ENG_MSG_SET_SENSOR_PROPERTIES ),
+ NAME_VAL( LOC_ENG_MSG_SET_SENSOR_PERF_CONTROL_CONFIG ),
+ NAME_VAL( LOC_ENG_MSG_MUTE_SESSION ),
+ NAME_VAL( LOC_ENG_MSG_ATL_OPEN_SUCCESS ),
+ NAME_VAL( LOC_ENG_MSG_ATL_CLOSED ),
+ NAME_VAL( LOC_ENG_MSG_ATL_OPEN_FAILED ),
+ NAME_VAL( LOC_ENG_MSG_REPORT_POSITION ),
+ NAME_VAL( LOC_ENG_MSG_REPORT_SV ),
+ NAME_VAL( LOC_ENG_MSG_REPORT_STATUS ),
+ NAME_VAL( LOC_ENG_MSG_REPORT_NMEA ),
+ NAME_VAL( LOC_ENG_MSG_REQUEST_ATL ),
+ NAME_VAL( LOC_ENG_MSG_RELEASE_ATL ),
+ NAME_VAL( LOC_ENG_MSG_REQUEST_BIT ),
+ NAME_VAL( LOC_ENG_MSG_RELEASE_BIT ),
+ NAME_VAL( LOC_ENG_MSG_REQUEST_WIFI ),
+ NAME_VAL( LOC_ENG_MSG_RELEASE_WIFI ),
+ NAME_VAL( LOC_ENG_MSG_REQUEST_NI ),
+ NAME_VAL( LOC_ENG_MSG_INFORM_NI_RESPONSE ),
+ NAME_VAL( LOC_ENG_MSG_REQUEST_XTRA_DATA ),
+ NAME_VAL( LOC_ENG_MSG_REQUEST_TIME ),
+ NAME_VAL( LOC_ENG_MSG_EXT_POWER_CONFIG ),
+ NAME_VAL( LOC_ENG_MSG_REQUEST_POSITION ),
+ NAME_VAL( LOC_ENG_MSG_REQUEST_PHONE_CONTEXT ),
+ NAME_VAL( LOC_ENG_MSG_REQUEST_NETWORK_POSIITON ),
+ NAME_VAL( ULP_MSG_UPDATE_CRITERIA ),
+ NAME_VAL( ULP_MSG_START_FIX ),
+ NAME_VAL( ULP_MSG_STOP_FIX ),
+ NAME_VAL( ULP_MSG_INJECT_PHONE_CONTEXT_SETTINGS ),
+ NAME_VAL( ULP_MSG_INJECT_NETWORK_POSITION ),
+ NAME_VAL( ULP_MSG_REPORT_QUIPC_POSITION ),
+ NAME_VAL( ULP_MSG_REQUEST_COARSE_POSITION ),
+ NAME_VAL( LOC_ENG_MSG_LPP_CONFIG ),
+ NAME_VAL( LOC_ENG_MSG_PRIVACY )
+};
+static int loc_eng_msgs_num = sizeof(loc_eng_msgs) / sizeof(loc_name_val_s_type);
+
+/* Find Android GPS status name */
+const char* loc_get_msg_name(int id)
+{
+ return loc_get_name_from_val(loc_eng_msgs, loc_eng_msgs_num, (long) id);
+}
+
+
+
+static loc_name_val_s_type loc_eng_position_modes[] =
+{
+ NAME_VAL( LOC_POSITION_MODE_STANDALONE ),
+ NAME_VAL( LOC_POSITION_MODE_MS_BASED ),
+ NAME_VAL( LOC_POSITION_MODE_MS_ASSISTED ),
+ NAME_VAL( LOC_POSITION_MODE_RESERVED_1 ),
+ NAME_VAL( LOC_POSITION_MODE_RESERVED_2 ),
+ NAME_VAL( LOC_POSITION_MODE_RESERVED_3 ),
+ NAME_VAL( LOC_POSITION_MODE_RESERVED_4 )
+};
+static int loc_eng_position_mode_num = sizeof(loc_eng_position_modes) / sizeof(loc_name_val_s_type);
+
+const char* loc_get_position_mode_name(GpsPositionMode mode)
+{
+ return loc_get_name_from_val(loc_eng_position_modes, loc_eng_position_mode_num, (long) mode);
+}
+
+
+
+static loc_name_val_s_type loc_eng_position_recurrences[] =
+{
+ NAME_VAL( GPS_POSITION_RECURRENCE_PERIODIC ),
+ NAME_VAL( GPS_POSITION_RECURRENCE_SINGLE )
+};
+static int loc_eng_position_recurrence_num = sizeof(loc_eng_position_recurrences) / sizeof(loc_name_val_s_type);
+
+const char* loc_get_position_recurrence_name(GpsPositionRecurrence recur)
+{
+ return loc_get_name_from_val(loc_eng_position_recurrences, loc_eng_position_recurrence_num, (long) recur);
+}
+
+
+
+static loc_name_val_s_type loc_eng_aiding_data_bits[] =
+{
+ NAME_VAL( GPS_DELETE_EPHEMERIS ),
+ NAME_VAL( GPS_DELETE_ALMANAC ),
+ NAME_VAL( GPS_DELETE_POSITION ),
+ NAME_VAL( GPS_DELETE_TIME ),
+ NAME_VAL( GPS_DELETE_IONO ),
+ NAME_VAL( GPS_DELETE_UTC ),
+ NAME_VAL( GPS_DELETE_HEALTH ),
+ NAME_VAL( GPS_DELETE_SVDIR ),
+ NAME_VAL( GPS_DELETE_SVSTEER ),
+ NAME_VAL( GPS_DELETE_SADATA ),
+ NAME_VAL( GPS_DELETE_RTI ),
+ NAME_VAL( GPS_DELETE_CELLDB_INFO ),
+ NAME_VAL( GPS_DELETE_ALMANAC_CORR ),
+ NAME_VAL( GPS_DELETE_FREQ_BIAS_EST ),
+ NAME_VAL( GPS_DELETE_EPHEMERIS_GLO ),
+ NAME_VAL( GPS_DELETE_ALMANAC_GLO ),
+ NAME_VAL( GPS_DELETE_SVDIR_GLO ),
+ NAME_VAL( GPS_DELETE_SVSTEER_GLO ),
+ NAME_VAL( GPS_DELETE_ALMANAC_CORR_GLO ),
+ NAME_VAL( GPS_DELETE_TIME_GPS ),
+ NAME_VAL( GPS_DELETE_TIME_GLO )
+};
+static int loc_eng_aiding_data_bit_num = sizeof(loc_eng_aiding_data_bits) / sizeof(loc_name_val_s_type);
+
+const char* loc_get_aiding_data_mask_names(GpsAidingData data)
+{
+ return NULL;
+}
+
+
+static loc_name_val_s_type loc_eng_agps_types[] =
+{
+ NAME_VAL( AGPS_TYPE_INVALID ),
+ NAME_VAL( AGPS_TYPE_ANY ),
+ NAME_VAL( AGPS_TYPE_SUPL ),
+ NAME_VAL( AGPS_TYPE_C2K ),
+ NAME_VAL( AGPS_TYPE_WWAN_ANY )
+};
+static int loc_eng_agps_type_num = sizeof(loc_eng_agps_types) / sizeof(loc_name_val_s_type);
+
+const char* loc_get_agps_type_name(AGpsType type)
+{
+ return loc_get_name_from_val(loc_eng_agps_types, loc_eng_agps_type_num, (long) type);
+}
+
+
+static loc_name_val_s_type loc_eng_ni_types[] =
+{
+ NAME_VAL( GPS_NI_TYPE_VOICE ),
+ NAME_VAL( GPS_NI_TYPE_UMTS_SUPL ),
+ NAME_VAL( GPS_NI_TYPE_UMTS_CTRL_PLANE )
+};
+static int loc_eng_ni_type_num = sizeof(loc_eng_ni_types) / sizeof(loc_name_val_s_type);
+
+const char* loc_get_ni_type_name(GpsNiType type)
+{
+ return loc_get_name_from_val(loc_eng_ni_types, loc_eng_ni_type_num, (long) type);
+}
+
+
+static loc_name_val_s_type loc_eng_ni_responses[] =
+{
+ NAME_VAL( GPS_NI_RESPONSE_ACCEPT ),
+ NAME_VAL( GPS_NI_RESPONSE_DENY ),
+ NAME_VAL( GPS_NI_RESPONSE_DENY )
+};
+static int loc_eng_ni_reponse_num = sizeof(loc_eng_ni_responses) / sizeof(loc_name_val_s_type);
+
+const char* loc_get_ni_response_name(GpsUserResponseType response)
+{
+ return loc_get_name_from_val(loc_eng_ni_responses, loc_eng_ni_reponse_num, (long) response);
+}
+
+
+static loc_name_val_s_type loc_eng_ni_encodings[] =
+{
+ NAME_VAL( GPS_ENC_NONE ),
+ NAME_VAL( GPS_ENC_SUPL_GSM_DEFAULT ),
+ NAME_VAL( GPS_ENC_SUPL_UTF8 ),
+ NAME_VAL( GPS_ENC_SUPL_UCS2 ),
+ NAME_VAL( GPS_ENC_UNKNOWN )
+};
+static int loc_eng_ni_encoding_num = sizeof(loc_eng_ni_encodings) / sizeof(loc_name_val_s_type);
+
+const char* loc_get_ni_encoding_name(GpsNiEncodingType encoding)
+{
+ return loc_get_name_from_val(loc_eng_ni_encodings, loc_eng_ni_encoding_num, (long) encoding);
+}
+
+
+static loc_name_val_s_type loc_eng_agps_bears[] =
+{
+ NAME_VAL( AGPS_APN_BEARER_INVALID ),
+ NAME_VAL( AGPS_APN_BEARER_IPV4 ),
+ NAME_VAL( AGPS_APN_BEARER_IPV4 ),
+ NAME_VAL( AGPS_APN_BEARER_IPV4V6 )
+};
+static int loc_eng_agps_bears_num = sizeof(loc_eng_agps_bears) / sizeof(loc_name_val_s_type);
+
+const char* loc_get_agps_bear_name(AGpsBearerType bearer)
+{
+ return loc_get_name_from_val(loc_eng_agps_bears, loc_eng_agps_bears_num, (long) bearer);
+}
+
+static loc_name_val_s_type loc_eng_server_types[] =
+{
+ NAME_VAL( LOC_AGPS_CDMA_PDE_SERVER ),
+ NAME_VAL( LOC_AGPS_CUSTOM_PDE_SERVER ),
+ NAME_VAL( LOC_AGPS_MPC_SERVER ),
+ NAME_VAL( LOC_AGPS_SUPL_SERVER )
+};
+static int loc_eng_server_types_num = sizeof(loc_eng_server_types) / sizeof(loc_name_val_s_type);
+
+const char* loc_get_server_type_name(LocServerType type)
+{
+ return loc_get_name_from_val(loc_eng_server_types, loc_eng_server_types_num, (long) type);
+}
+
+static loc_name_val_s_type loc_eng_position_sess_status_types[] =
+{
+ NAME_VAL( LOC_SESS_SUCCESS ),
+ NAME_VAL( LOC_SESS_INTERMEDIATE ),
+ NAME_VAL( LOC_SESS_FAILURE )
+};
+static int loc_eng_position_sess_status_num = sizeof(loc_eng_position_sess_status_types) / sizeof(loc_name_val_s_type);
+
+const char* loc_get_position_sess_status_name(enum loc_sess_status status)
+{
+ return loc_get_name_from_val(loc_eng_position_sess_status_types, loc_eng_position_sess_status_num, (long) status);
+}
+
+static loc_name_val_s_type loc_eng_agps_status_names[] =
+{
+ NAME_VAL( GPS_REQUEST_AGPS_DATA_CONN ),
+ NAME_VAL( GPS_RELEASE_AGPS_DATA_CONN ),
+ NAME_VAL( GPS_AGPS_DATA_CONNECTED ),
+ NAME_VAL( GPS_AGPS_DATA_CONN_DONE ),
+ NAME_VAL( GPS_AGPS_DATA_CONN_FAILED )
+};
+static int loc_eng_agps_status_num = sizeof(loc_eng_agps_status_names) / sizeof(loc_name_val_s_type);
+
+const char* loc_get_agps_status_name(AGpsStatusValue status)
+{
+ return loc_get_name_from_val(loc_eng_agps_status_names, loc_eng_agps_status_num, (long) status);
+}
diff --git a/gps/libloc_api_50001/loc_eng_log.h b/gps/libloc_api_50001/loc_eng_log.h
new file mode 100644
index 0000000..e8a8279
--- /dev/null
+++ b/gps/libloc_api_50001/loc_eng_log.h
@@ -0,0 +1,60 @@
+/* Copyright (c) 2011 Code Aurora Forum. 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 Code Aurora Forum, 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 "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>
+#include <hardware/gps.h>
+#include <loc.h>
+
+const char* loc_get_gps_status_name(GpsStatusValue gps_status);
+const char* loc_get_msg_name(int id);
+const char* loc_get_position_mode_name(GpsPositionMode mode);
+const char* loc_get_position_recurrence_name(GpsPositionRecurrence recur);
+const char* loc_get_aiding_data_mask_names(GpsAidingData data);
+const char* loc_get_agps_type_name(AGpsType type);
+const char* loc_get_ni_type_name(GpsNiType type);
+const char* loc_get_ni_response_name(GpsUserResponseType response);
+const char* loc_get_ni_encoding_name(GpsNiEncodingType encoding);
+const char* loc_get_agps_bear_name(AGpsBearerType bear);
+const char* loc_get_server_type_name(LocServerType type);
+const char* loc_get_position_sess_status_name(enum loc_sess_status status);
+const char* loc_get_agps_status_name(AGpsStatusValue status);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LOC_ENG_LOG_H */
diff --git a/gps/libloc_api_50001/loc_eng_msg.cpp b/gps/libloc_api_50001/loc_eng_msg.cpp
new file mode 100644
index 0000000..97c0457
--- /dev/null
+++ b/gps/libloc_api_50001/loc_eng_msg.cpp
@@ -0,0 +1,133 @@
+/* Copyright (c) 2011, Code Aurora Forum. 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 Code Aurora Forum, 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 "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 <fcntl.h>
+#include "loc_eng_msg.h"
+#include "loc_eng_dmn_conn_glue_msg.h"
+
+#ifdef _ANDROID_
+
+#define LOC_ENG_MSG_REQ_Q_PATH "/data/misc/gpsone_d/loc_eng_msg_req_q"
+
+#else
+
+#define LOC_ENG_MSG_REQ_Q_PATH "/tmp/loc_eng_msg_req_q"
+
+#endif
+
+int loc_eng_msgget(int * p_req_msgq)
+{
+ * p_req_msgq = loc_eng_dmn_conn_glue_msgget(LOC_ENG_MSG_REQ_Q_PATH, O_RDWR);
+ return 0;
+}
+
+int loc_eng_msgremove(int req_msgq)
+{
+ loc_eng_dmn_conn_glue_piperemove(LOC_ENG_MSG_REQ_Q_PATH, req_msgq);
+ return 0;
+}
+
+int loc_eng_msgsnd(int msgqid, void * msgp)
+{
+ int ret = loc_eng_dmn_conn_glue_pipewrite(msgqid, msgp, sizeof(void*));
+ return ret;
+}
+
+int loc_eng_msgsnd_raw(int msgqid, void * msgp, unsigned int msgsz)
+{
+ int result;
+
+ struct msgbuf * pmsg = (struct msgbuf *) msgp;
+
+ if (msgsz < sizeof(struct msgbuf)) {
+ LOC_LOGE("%s:%d] msgbuf is too small %d\n", __func__, __LINE__, msgsz);
+ return -1;
+ }
+
+ 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;
+}
+
+int loc_eng_msgrcv(int msgqid, void ** msgp)
+{
+ int ret = loc_eng_dmn_conn_glue_piperead(msgqid, msgp, sizeof(void*));
+ return ret;
+}
+
+int loc_eng_msgrcv_raw(int msgqid, void *msgp, unsigned int msgsz)
+{
+ int result;
+ struct msgbuf * pmsg = (struct msgbuf *) msgp;
+
+ if (msgsz < sizeof(struct msgbuf)) {
+ LOC_LOGE("%s:%d] msgbuf is too small %d\n", __func__, __LINE__, msgsz);
+ return -1;
+ }
+
+ result = loc_eng_dmn_conn_glue_piperead(msgqid, msgp, sizeof(struct msgbuf));
+ if (result != sizeof(struct msgbuf)) {
+ LOC_LOGE("%s:%d] pipe broken %d\n", __func__, __LINE__, result);
+ return -1;
+ }
+
+ if (msgsz < pmsg->msgsz) {
+ LOC_LOGE("%s:%d] msgbuf is too small %d < %d\n", __func__, __LINE__, (int) msgsz, (int) pmsg->msgsz);
+ return -1;
+ }
+
+ if (pmsg->msgsz > sizeof(struct msgbuf)) {
+ /* there is msg body */
+ msgp += sizeof(struct msgbuf);
+
+ result = loc_eng_dmn_conn_glue_piperead(msgqid, msgp, pmsg->msgsz - sizeof(struct msgbuf));
+
+ if (result != (int) (pmsg->msgsz - sizeof(struct msgbuf))) {
+ LOC_LOGE("%s:%d] pipe broken %d, msgid = %p, msgsz = %d\n", __func__, __LINE__, result,
+ (pmsg->msgid), (int) pmsg->msgsz);
+ return -1;
+ }
+ }
+
+ return pmsg->msgsz;
+}
+
+int loc_eng_msgflush(int msgqid)
+{
+ return loc_eng_dmn_conn_glue_msgflush(msgqid);
+}
+
+int loc_eng_msgunblock(int msgqid)
+{
+ return loc_eng_dmn_conn_glue_pipeunblock(msgqid);
+}
diff --git a/gps/libloc_api_50001/loc_eng_msg.h b/gps/libloc_api_50001/loc_eng_msg.h
new file mode 100644
index 0000000..d1f4011
--- /dev/null
+++ b/gps/libloc_api_50001/loc_eng_msg.h
@@ -0,0 +1,861 @@
+/* Copyright (c) 2011,2012 Code Aurora Forum. 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 Code Aurora Forum, 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 "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 <stdlib.h>
+#include <string.h>
+#include "log_util.h"
+#include "loc.h"
+#include <loc_eng_log.h>
+#include "loc_eng_msg_id.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+struct LocPosMode
+{
+ LocPositionMode mode;
+ GpsPositionRecurrence recurrence;
+ uint32_t min_interval;
+ uint32_t preferred_accuracy;
+ uint32_t preferred_time;
+ char credentials[14];
+ char provider[8];
+ LocPosMode(LocPositionMode m, GpsPositionRecurrence recr,
+ uint32_t gap, uint32_t accu, uint32_t time,
+ const char* cred, const char* prov) :
+ mode(m), recurrence(recr),
+ min_interval(gap < MIN_POSSIBLE_FIX_INTERVAL ? MIN_POSSIBLE_FIX_INTERVAL : gap),
+ preferred_accuracy(accu), preferred_time(time) {
+ memset(credentials, 0, sizeof(credentials));
+ memset(provider, 0, sizeof(provider));
+ if (NULL != cred) {
+ memcpy(credentials, cred, sizeof(credentials)-1);
+ }
+ if (NULL != prov) {
+ memcpy(provider, prov, sizeof(provider)-1);
+ }
+ }
+
+ LocPosMode() :
+ mode(LOC_POSITION_MODE_MS_BASED), recurrence(GPS_POSITION_RECURRENCE_PERIODIC),
+ min_interval(MIN_POSSIBLE_FIX_INTERVAL), preferred_accuracy(50), preferred_time(120000) {
+ memset(credentials, 0, sizeof(credentials));
+ memset(provider, 0, sizeof(provider));
+ }
+
+ inline bool equals(const LocPosMode &anotherMode) const
+ {
+ return anotherMode.mode == mode &&
+ anotherMode.recurrence == recurrence &&
+ anotherMode.min_interval == min_interval &&
+ anotherMode.preferred_accuracy == preferred_accuracy &&
+ anotherMode.preferred_time == preferred_time &&
+ !strncmp(anotherMode.credentials, credentials, sizeof(credentials)-1) &&
+ !strncmp(anotherMode.provider, provider, sizeof(provider)-1);
+ }
+
+ inline void logv() const
+ {
+ LOC_LOGV ("Position mode: %s\n Position recurrence: %s\n min interval: %d\n preferred accuracy: %d\n preferred time: %d\n credentials: %s provider: %s",
+ loc_get_position_mode_name(mode),
+ loc_get_position_recurrence_name(recurrence),
+ min_interval,
+ preferred_accuracy,
+ preferred_time,
+ credentials,
+ provider);
+ }
+};
+
+typedef enum {
+ LOC_ENG_IF_REQUEST_TYPE_SUPL = 0,
+ LOC_ENG_IF_REQUEST_TYPE_WIFI,
+ LOC_ENG_IF_REQUEST_TYPE_ANY
+} loc_if_req_type_e_type;
+
+typedef enum {
+ LOC_ENG_IF_REQUEST_SENDER_ID_QUIPC = 0,
+ LOC_ENG_IF_REQUEST_SENDER_ID_MSAPM,
+ LOC_ENG_IF_REQUEST_SENDER_ID_GPSONE_DAEMON,
+ LOC_ENG_IF_REQUEST_SENDER_ID_MODEM,
+ LOC_ENG_IF_REQUEST_SENDER_ID_UNKNOWN
+} loc_if_req_sender_id_e_type;
+
+struct loc_eng_msg {
+ const void* owner;
+ const int msgid;
+ inline loc_eng_msg(void* instance, int id) :
+ owner(instance), msgid(id)
+ {
+ LOC_LOGV("creating msg %s", loc_get_msg_name(msgid));
+ LOC_LOGV("creating msg ox%x", msgid);
+ }
+ virtual ~loc_eng_msg()
+ {
+ LOC_LOGV("deleting msg %s", loc_get_msg_name(msgid));
+ LOC_LOGV("deleting msg ox%x", msgid);
+ }
+};
+
+struct loc_eng_msg_suple_version : public loc_eng_msg {
+ const int supl_version;
+ inline loc_eng_msg_suple_version(void* instance, int version) :
+ loc_eng_msg(instance, LOC_ENG_MSG_SUPL_VERSION),
+ supl_version(version)
+ {
+ LOC_LOGV("SUPL Version: %d", version);
+ }
+};
+
+struct loc_eng_msg_lpp_config : public loc_eng_msg {
+ const int lpp_config;
+ inline loc_eng_msg_lpp_config(void *instance, int profile) :
+ loc_eng_msg(instance, LOC_ENG_MSG_LPP_CONFIG),
+ lpp_config(profile)
+ {
+ LOC_LOGV("lpp profile: %d", profile);
+ }
+};
+
+struct loc_eng_msg_ext_power_config : public loc_eng_msg {
+ const int isBatteryCharging;
+ inline loc_eng_msg_ext_power_config(void* instance, int isBattCharging) :
+ loc_eng_msg(instance, LOC_ENG_MSG_EXT_POWER_CONFIG),
+ isBatteryCharging(isBattCharging)
+ {
+ LOC_LOGV("isBatteryCharging: %d", isBatteryCharging);
+ }
+};
+
+struct loc_eng_msg_sensor_control_config : public loc_eng_msg {
+ const int sensorsDisabled;
+ inline loc_eng_msg_sensor_control_config(void* instance, int disabled) :
+ loc_eng_msg(instance, LOC_ENG_MSG_SET_SENSOR_CONTROL_CONFIG),
+ sensorsDisabled(disabled)
+ {
+ LOC_LOGV("Sensors Disabled: %d", disabled);
+ }
+};
+
+struct loc_eng_msg_sensor_properties : public loc_eng_msg {
+ const bool gyroBiasVarianceRandomWalk_valid;
+ const float gyroBiasVarianceRandomWalk;
+ const bool accelRandomWalk_valid;
+ const float accelRandomWalk;
+ const bool angleRandomWalk_valid;
+ const float angleRandomWalk;
+ const bool rateRandomWalk_valid;
+ const float rateRandomWalk;
+ const bool velocityRandomWalk_valid;
+ const float velocityRandomWalk;
+ inline loc_eng_msg_sensor_properties(void* instance, 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) :
+ loc_eng_msg(instance, LOC_ENG_MSG_SET_SENSOR_PROPERTIES),
+ gyroBiasVarianceRandomWalk_valid(gyroBiasRandomWalk_valid),
+ gyroBiasVarianceRandomWalk(gyroBiasRandomWalk),
+ accelRandomWalk_valid(accelRandomWalk_valid),
+ accelRandomWalk(accelRandomWalk),
+ angleRandomWalk_valid(angleRandomWalk_valid),
+ angleRandomWalk(angleRandomWalk),
+ rateRandomWalk_valid(rateRandomWalk_valid),
+ rateRandomWalk(rateRandomWalk),
+ velocityRandomWalk_valid(velocityRandomWalk_valid),
+ velocityRandomWalk(velocityRandomWalk)
+ {
+ 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",
+ gyroBiasRandomWalk_valid,
+ accelRandomWalk_valid,
+ angleRandomWalk_valid,
+ rateRandomWalk_valid,
+ velocityRandomWalk_valid
+ );
+ LOC_LOGV("Sensor properties, Gyro Random walk: %f Accel Random Walk: %f "
+ "Angle Random Walk: %f Rate Random Walk: %f "
+ "Velocity Random Walk: %f",
+ gyroBiasRandomWalk,
+ accelRandomWalk,
+ angleRandomWalk,
+ rateRandomWalk,
+ velocityRandomWalk
+ );
+ }
+};
+
+struct loc_eng_msg_sensor_perf_control_config : public loc_eng_msg {
+ const int controlMode;
+ const int accelSamplesPerBatch;
+ const int accelBatchesPerSec;
+ const int gyroSamplesPerBatch;
+ const int gyroBatchesPerSec;
+ const int accelSamplesPerBatchHigh;
+ const int accelBatchesPerSecHigh;
+ const int gyroSamplesPerBatchHigh;
+ const int gyroBatchesPerSecHigh;
+ const int algorithmConfig;
+ inline loc_eng_msg_sensor_perf_control_config(void* instance, int controlMode,
+ int accelSamplesPerBatch, int accelBatchesPerSec,
+ int gyroSamplesPerBatch, int gyroBatchesPerSec,
+ int accelSamplesPerBatchHigh, int accelBatchesPerSecHigh,
+ int gyroSamplesPerBatchHigh, int gyroBatchesPerSecHigh,
+ int algorithmConfig) :
+ loc_eng_msg(instance, LOC_ENG_MSG_SET_SENSOR_PERF_CONTROL_CONFIG),
+ controlMode(controlMode),
+ accelSamplesPerBatch(accelSamplesPerBatch),
+ accelBatchesPerSec(accelBatchesPerSec),
+ gyroSamplesPerBatch(gyroSamplesPerBatch),
+ gyroBatchesPerSec(gyroBatchesPerSec),
+ accelSamplesPerBatchHigh(accelSamplesPerBatchHigh),
+ accelBatchesPerSecHigh(accelBatchesPerSecHigh),
+ gyroSamplesPerBatchHigh(gyroSamplesPerBatchHigh),
+ gyroBatchesPerSecHigh(gyroBatchesPerSecHigh),
+ algorithmConfig(algorithmConfig)
+ {
+ 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",
+ controlMode,
+ accelSamplesPerBatch,
+ accelBatchesPerSec,
+ gyroSamplesPerBatch,
+ gyroBatchesPerSec,
+ accelSamplesPerBatchHigh,
+ accelBatchesPerSecHigh,
+ gyroSamplesPerBatchHigh,
+ gyroBatchesPerSecHigh,
+ algorithmConfig
+ );
+ }
+};
+
+
+struct loc_eng_msg_position_mode : public loc_eng_msg {
+ const LocPosMode pMode;
+ inline loc_eng_msg_position_mode(void* instance,
+ LocPosMode &mode) :
+ loc_eng_msg(instance, LOC_ENG_MSG_SET_POSITION_MODE),
+ pMode(mode)
+ {
+ pMode.logv();
+ }
+};
+
+struct loc_eng_msg_set_time : public loc_eng_msg {
+ const GpsUtcTime time;
+ const int64_t timeReference;
+ const int uncertainty;
+ inline loc_eng_msg_set_time(void* instance,
+ GpsUtcTime t,
+ int64_t tf,
+ int unc) :
+ loc_eng_msg(instance, LOC_ENG_MSG_SET_TIME),
+ time(t), timeReference(tf), uncertainty(unc)
+ {
+ LOC_LOGV("time: %lld\n timeReference: %lld\n uncertainty: %d",
+ time, timeReference, uncertainty);
+ }
+};
+
+struct loc_eng_msg_inject_location : public loc_eng_msg {
+ const double latitude;
+ const double longitude;
+ const float accuracy;
+ inline loc_eng_msg_inject_location(void* instance, double lat,
+ double longi, float accur) :
+ loc_eng_msg(instance, LOC_ENG_MSG_INJECT_LOCATION),
+ latitude(lat), longitude(longi), accuracy(accur)
+ {
+ LOC_LOGV("latitude: %f\n longitude: %f\n accuracy: %f",
+ latitude, longitude, accuracy);
+ }
+};
+
+struct loc_eng_msg_delete_aiding_data : public loc_eng_msg {
+ const GpsAidingData type;
+ inline loc_eng_msg_delete_aiding_data(void* instance, GpsAidingData data) :
+ loc_eng_msg(instance, LOC_ENG_MSG_DELETE_AIDING_DATA), type(data)
+ {
+ LOC_LOGV("aiding data msak %d", type);
+ }
+};
+
+struct loc_eng_msg_report_position : public loc_eng_msg {
+ const GpsLocation location;
+ const void* locationExt;
+ const enum loc_sess_status status;
+ inline loc_eng_msg_report_position(void* instance, GpsLocation &loc, void* locExt,
+ enum loc_sess_status st) :
+ loc_eng_msg(instance, LOC_ENG_MSG_REPORT_POSITION),
+ location(loc), locationExt(locExt), status(st)
+ {
+ 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",
+ location.flags, location.position_source, location.latitude, location.longitude,
+ location.altitude, location.speed, location.bearing, location.accuracy,
+ location.timestamp, location.rawDataSize, location.rawData,status);
+ }
+};
+
+struct loc_eng_msg_report_sv : public loc_eng_msg {
+ const GpsSvStatus svStatus;
+ const void* svExt;
+ inline loc_eng_msg_report_sv(void* instance, GpsSvStatus &sv, void* ext) :
+ loc_eng_msg(instance, LOC_ENG_MSG_REPORT_SV), svStatus(sv), svExt(ext)
+ {
+ LOC_LOGV("num sv: %d\n ephemeris mask: %dxn almanac mask: %x\n used in fix mask: %x\n sv: prn snr elevation azimuth",
+ svStatus.num_svs, svStatus.ephemeris_mask, svStatus.almanac_mask, svStatus.used_in_fix_mask);
+ for (int i = 0; i < svStatus.num_svs && i < GPS_MAX_SVS; i++) {
+ LOC_LOGV(" %d: %d %f %f %f\n ",
+ i,
+ svStatus.sv_list[i].prn,
+ svStatus.sv_list[i].snr,
+ svStatus.sv_list[i].elevation,
+ svStatus.sv_list[i].azimuth);
+ }
+ }
+};
+
+struct loc_eng_msg_report_status : public loc_eng_msg {
+ const GpsStatusValue status;
+ inline loc_eng_msg_report_status(void* instance, GpsStatusValue engineStatus) :
+ loc_eng_msg(instance, LOC_ENG_MSG_REPORT_STATUS), status(engineStatus)
+ {
+ LOC_LOGV("status: %s", loc_get_gps_status_name(status));
+ }
+};
+
+struct loc_eng_msg_report_nmea : public loc_eng_msg {
+ char* const nmea;
+ const int length;
+ inline loc_eng_msg_report_nmea(void* instance,
+ const char* data,
+ int len) :
+ loc_eng_msg(instance, LOC_ENG_MSG_REPORT_NMEA),
+ nmea(new char[len]), length(len)
+ {
+ memcpy((void*)nmea, (void*)data, len);
+ LOC_LOGV("length: %d\n nmea: %p - %c%c%c",
+ length, nmea, nmea[3], nmea[4], nmea[5]);
+ }
+ inline ~loc_eng_msg_report_nmea()
+ {
+ delete[] nmea;
+ }
+};
+
+struct loc_eng_msg_request_bit : public loc_eng_msg {
+ const loc_if_req_type_e_type ifType;
+ const int ipv4Addr;
+ char* const ipv6Addr;
+ inline loc_eng_msg_request_bit(void* instance,
+ loc_if_req_type_e_type type,
+ int ipv4,
+ char* ipv6) :
+ loc_eng_msg(instance, LOC_ENG_MSG_REQUEST_BIT),
+ ifType(type), ipv4Addr(ipv4),
+ ipv6Addr(NULL == ipv6 ? NULL : new char[16])
+ {
+ if (NULL != ipv6Addr)
+ memcpy(ipv6Addr, ipv6, 16);
+ LOC_LOGV("ifType: %d, ipv4: %d.%d.%d.%d, ipv6: %s", ifType,
+ (unsigned char)(ipv4>>24),
+ (unsigned char)(ipv4>>16),
+ (unsigned char)(ipv4>>8),
+ (unsigned char)ipv4,
+ NULL != ipv6Addr ? ipv6Addr : "");
+ }
+
+ inline ~loc_eng_msg_request_bit()
+ {
+ if (NULL != ipv6Addr) {
+ delete[] ipv6Addr;
+ }
+ }
+};
+
+struct loc_eng_msg_request_wifi : public loc_eng_msg {
+ const loc_if_req_type_e_type ifType;
+ const loc_if_req_sender_id_e_type senderId;
+ char* const ssid;
+ char* const password;
+ inline loc_eng_msg_request_wifi(void* instance,
+ loc_if_req_type_e_type type,
+ loc_if_req_sender_id_e_type sender_id,
+ char* s,
+ char* p) :
+ loc_eng_msg(instance, LOC_ENG_MSG_REQUEST_WIFI),
+ ifType(type), senderId(sender_id),
+ ssid(NULL == s ? NULL : new char[SSID_BUF_SIZE]),
+ password(NULL == p ? NULL : new char[SSID_BUF_SIZE])
+ {
+ if (NULL != ssid)
+ strlcpy(ssid, s, SSID_BUF_SIZE);
+ if (NULL != password)
+ strlcpy(password, p, SSID_BUF_SIZE);
+ LOC_LOGV("ifType: %d, senderId: %d, ssid: %s, password: %s",
+ ifType,
+ senderId,
+ NULL != ssid ? ssid : "",
+ NULL != password ? password : "");
+ }
+
+ inline ~loc_eng_msg_request_wifi()
+ {
+ if (NULL != ssid) {
+ delete[] ssid;
+ }
+ if (NULL != password) {
+ delete[] password;
+ }
+ }
+};
+
+struct loc_eng_msg_release_bit : public loc_eng_msg {
+ const loc_if_req_type_e_type ifType;
+ const int ipv4Addr;
+ char* const ipv6Addr;
+ inline loc_eng_msg_release_bit(void* instance,
+ loc_if_req_type_e_type type,
+ int ipv4,
+ char* ipv6) :
+ loc_eng_msg(instance, LOC_ENG_MSG_RELEASE_BIT),
+ ifType(type), ipv4Addr(ipv4),
+ ipv6Addr(NULL == ipv6 ? NULL : new char[16])
+ {
+ if (NULL != ipv6Addr)
+ memcpy(ipv6Addr, ipv6, 16);
+ LOC_LOGV("ifType: %d, ipv4: %d.%d.%d.%d, ipv6: %s", ifType,
+ (unsigned char)(ipv4>>24),
+ (unsigned char)(ipv4>>16),
+ (unsigned char)(ipv4>>8),
+ (unsigned char)ipv4,
+ NULL != ipv6Addr ? ipv6Addr : "");
+ }
+
+ inline ~loc_eng_msg_release_bit()
+ {
+ if (NULL != ipv6Addr) {
+ delete[] ipv6Addr;
+ }
+ }
+};
+
+struct loc_eng_msg_release_wifi : public loc_eng_msg {
+ const loc_if_req_type_e_type ifType;
+ const loc_if_req_sender_id_e_type senderId;
+ char* const ssid;
+ char* const password;
+ inline loc_eng_msg_release_wifi(void* instance,
+ loc_if_req_type_e_type type,
+ loc_if_req_sender_id_e_type sender_id,
+ char* s,
+ char* p) :
+ loc_eng_msg(instance, LOC_ENG_MSG_RELEASE_WIFI),
+ ifType(type), senderId(sender_id),
+ ssid(NULL == s ? NULL : new char[SSID_BUF_SIZE]),
+ password(NULL == p ? NULL : new char[SSID_BUF_SIZE])
+ {
+ if (NULL != s)
+ strlcpy(ssid, s, SSID_BUF_SIZE);
+ if (NULL != p)
+ strlcpy(password, p, SSID_BUF_SIZE);
+ LOC_LOGV("ifType: %d, senderId: %d, ssid: %s, password: %s",
+ ifType,
+ senderId,
+ NULL != ssid ? ssid : "",
+ NULL != password ? password : "");
+ }
+
+ inline ~loc_eng_msg_release_wifi()
+ {
+ if (NULL != ssid) {
+ delete[] ssid;
+ }
+ if (NULL != password) {
+ delete[] password;
+ }
+ }
+};
+
+
+struct loc_eng_msg_request_atl : public loc_eng_msg {
+ const int handle;
+ const AGpsType type;
+ inline loc_eng_msg_request_atl(void* instance, int hndl,
+ AGpsType agps_type) :
+ loc_eng_msg(instance, LOC_ENG_MSG_REQUEST_ATL),
+ handle(hndl), type(agps_type)
+ {
+ LOC_LOGV("handle: %d\n agps type: %s",
+ handle,
+ loc_get_agps_type_name(type));
+ }
+};
+
+struct loc_eng_msg_release_atl : public loc_eng_msg {
+ const int handle;
+ inline loc_eng_msg_release_atl(void* instance, int hndl) :
+ loc_eng_msg(instance, LOC_ENG_MSG_RELEASE_ATL), handle(hndl)
+ {
+ LOC_LOGV("handle: %d", handle);
+ }
+};
+
+struct loc_eng_msg_request_ni : public loc_eng_msg {
+ const GpsNiNotification notify;
+ const void *passThroughData;
+ inline loc_eng_msg_request_ni(void* instance,
+ GpsNiNotification &notif, const void* data) :
+ loc_eng_msg(instance, LOC_ENG_MSG_REQUEST_NI),
+ notify(notif), passThroughData(data)
+ {
+ 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",
+ notify.notification_id,
+ loc_get_ni_type_name(notify.ni_type),
+ notify.notify_flags,
+ notify.timeout,
+ loc_get_ni_response_name(notify.default_response),
+ loc_get_ni_encoding_name(notify.requestor_id_encoding),
+ loc_get_ni_encoding_name(notify.text_encoding),
+ passThroughData);
+ }
+};
+
+struct loc_eng_msg_inform_ni_response : public loc_eng_msg {
+ const GpsUserResponseType response;
+ const void *passThroughData;
+ inline loc_eng_msg_inform_ni_response(void* instance,
+ GpsUserResponseType resp,
+ const void* data) :
+ loc_eng_msg(instance, LOC_ENG_MSG_INFORM_NI_RESPONSE),
+ response(resp), passThroughData(data)
+ {
+ LOC_LOGV("response: %s\n passThroughData: %p",
+ loc_get_ni_response_name(response),
+ passThroughData);
+ }
+ inline ~loc_eng_msg_inform_ni_response()
+ {
+ // this is a bit weird since passThroughData is not
+ // allocated by this class. But there is no better way.
+ // passThroughData actually won't be NULL here.
+ // But better safer than sorry.
+ if (NULL != passThroughData) {
+ free((void*)passThroughData);
+ }
+ }
+};
+
+struct loc_eng_msg_set_apn : public loc_eng_msg {
+ char* const apn;
+ inline loc_eng_msg_set_apn(void* instance, const char* name, int len) :
+ loc_eng_msg(instance, LOC_ENG_MSG_SET_APN),
+ apn(new char[len+1])
+ {
+ memcpy((void*)apn, (void*)name, len);
+ apn[len] = 0;
+ LOC_LOGV("apn: %s", apn);
+ }
+ inline ~loc_eng_msg_set_apn()
+ {
+ delete[] apn;
+ }
+};
+
+
+
+struct loc_eng_msg_set_server_ipv4 : public loc_eng_msg {
+ const unsigned int nl_addr;
+ const int port;
+ const LocServerType serverType;
+ inline loc_eng_msg_set_server_ipv4(void* instance,
+ unsigned int ip,
+ int p,
+ LocServerType type) :
+ loc_eng_msg(instance, LOC_ENG_MSG_SET_SERVER_IPV4),
+ nl_addr(ip), port(p), serverType(type)
+ {
+ LOC_LOGV("addr: %x\n , port: %d\n type: %s", nl_addr, port, loc_get_server_type_name(serverType));
+ }
+};
+
+
+struct loc_eng_msg_set_server_url : public loc_eng_msg {
+ const int len;
+ char* const url;
+ inline loc_eng_msg_set_server_url(void* instance,
+ const char* urlString,
+ int url_len) :
+ loc_eng_msg(instance, LOC_ENG_MSG_SET_SERVER_URL),
+ len(url_len), url(new char[len+1])
+ {
+ memcpy((void*)url, (void*)urlString, url_len);
+ url[len] = 0;
+ LOC_LOGV("url: %s", url);
+ }
+ inline ~loc_eng_msg_set_server_url()
+ {
+ delete[] url;
+ }
+};
+
+struct loc_eng_msg_inject_xtra_data : public loc_eng_msg {
+ char* const data;
+ const int length;
+ inline loc_eng_msg_inject_xtra_data(void* instance, char* d, int l) :
+ loc_eng_msg(instance, LOC_ENG_MSG_INJECT_XTRA_DATA),
+ data(new char[l]), length(l)
+ {
+ memcpy((void*)data, (void*)d, l);
+ LOC_LOGV("length: %d\n data: %p", length, data);
+ }
+ inline ~loc_eng_msg_inject_xtra_data()
+ {
+ delete[] data;
+ }
+};
+
+struct loc_eng_msg_atl_open_success : public loc_eng_msg {
+ const AGpsStatusValue agpsType;
+ const int length;
+ char* const apn;
+ const AGpsBearerType bearerType;
+ inline loc_eng_msg_atl_open_success(void* instance,
+ AGpsStatusValue atype,
+ const char* name,
+ int len,
+ AGpsBearerType btype) :
+ loc_eng_msg(instance, LOC_ENG_MSG_ATL_OPEN_SUCCESS),
+ agpsType(atype), length(len),
+ apn(new char[len+1]), bearerType(btype)
+ {
+ memcpy((void*)apn, (void*)name, len);
+ apn[len] = 0;
+ LOC_LOGV("agps type: %s\n apn: %s\n bearer type: %s",
+ loc_get_agps_type_name(agpsType),
+ apn,
+ loc_get_agps_bear_name(bearerType));
+ }
+ inline ~loc_eng_msg_atl_open_success()
+ {
+ delete[] apn;
+ }
+};
+
+struct loc_eng_msg_atl_open_failed : public loc_eng_msg {
+ const AGpsStatusValue agpsType;
+ inline loc_eng_msg_atl_open_failed(void* instance,
+ AGpsStatusValue atype) :
+ loc_eng_msg(instance, LOC_ENG_MSG_ATL_OPEN_FAILED),
+ agpsType(atype)
+ {
+ LOC_LOGV("agps type %s",
+ loc_get_agps_type_name(agpsType));
+ }
+};
+
+struct loc_eng_msg_atl_closed : public loc_eng_msg {
+ const AGpsStatusValue agpsType;
+ inline loc_eng_msg_atl_closed(void* instance,
+ AGpsStatusValue atype) :
+ loc_eng_msg(instance, LOC_ENG_MSG_ATL_CLOSED),
+ agpsType(atype)
+ {
+ LOC_LOGV("agps type %s",
+ loc_get_agps_type_name(agpsType));
+ }
+};
+
+struct loc_eng_msg_set_data_enable : public loc_eng_msg {
+ const int enable;
+ char* const apn;
+ const int length;
+ inline loc_eng_msg_set_data_enable(void* instance,
+ const char* name,
+ int len,
+ int yes) :
+ loc_eng_msg(instance, LOC_ENG_MSG_ENABLE_DATA),
+ enable(yes), apn(new char[len+1]), length(len)
+ {
+ memcpy((void*)apn, (void*)name, len);
+ apn[len] = 0;
+ LOC_LOGV("apn: %s\n enable: %d", apn, enable);
+ }
+ inline ~loc_eng_msg_set_data_enable()
+ {
+ delete[] apn;
+ }
+};
+
+struct loc_eng_msg_request_network_position : public loc_eng_msg {
+ const UlpNetworkRequestPos networkPosRequest;
+ inline loc_eng_msg_request_network_position (void* instance, UlpNetworkRequestPos networkPosReq) :
+ loc_eng_msg(instance, LOC_ENG_MSG_REQUEST_NETWORK_POSIITON),
+ networkPosRequest(networkPosReq)
+ {
+ LOC_LOGV("network position request: desired pos source %d\n request type: %d\n interval ms: %d ",
+ networkPosReq.desired_position_source,
+ networkPosReq.request_type,
+ networkPosReq.interval_ms);
+ }
+};
+
+struct loc_eng_msg_request_phone_context : public loc_eng_msg {
+ const UlpPhoneContextRequest contextRequest;
+ inline loc_eng_msg_request_phone_context (void* instance, UlpPhoneContextRequest contextReq) :
+ loc_eng_msg(instance, LOC_ENG_MSG_REQUEST_PHONE_CONTEXT),
+ contextRequest(contextReq)
+ {
+ LOC_LOGV("phone context request: request type 0x%x context type: 0x%x ",
+ contextRequest.request_type,
+ contextRequest.context_type);
+ }
+};
+
+struct ulp_msg_update_criteria : public loc_eng_msg {
+ const UlpLocationCriteria locationCriteria;
+ inline ulp_msg_update_criteria (void* instance, UlpLocationCriteria criteria) :
+ loc_eng_msg(instance, ULP_MSG_UPDATE_CRITERIA),
+ locationCriteria(criteria)
+ {
+ LOC_LOGV("location criteria: aciton %d\n valid mask: %d\n provider source: %d\n accuracy %d\n recurrence type %d\n min interval %d\n power consumption %d\n intermediate pos %d ",
+ locationCriteria.action,
+ locationCriteria.valid_mask,
+ locationCriteria.provider_source,
+ locationCriteria.preferred_horizontal_accuracy,
+ locationCriteria.recurrence_type,
+ locationCriteria.min_interval,
+ locationCriteria.preferred_power_consumption,
+ locationCriteria.intermediate_pos_report_enabled);
+ }
+};
+
+struct ulp_msg_inject_raw_command : public loc_eng_msg {
+ const char* rawCommand;
+ const int rawCommandLength;
+ inline ulp_msg_inject_raw_command (void* instance, char* command, int length) :
+ loc_eng_msg(instance, ULP_MSG_INJECT_RAW_COMMAND),
+ rawCommand(new char[length]),
+ rawCommandLength(length)
+ {
+ memcpy((void*)rawCommand, (void*)command, length);
+ LOC_LOGV("inject raw command: command %s\n command length: %d\n ",
+ rawCommand,
+ rawCommandLength);
+ }
+
+ inline ~ulp_msg_inject_raw_command()
+ {
+ delete[] rawCommand;
+ }
+};
+
+struct ulp_msg_inject_phone_context_settings : public loc_eng_msg {
+ const UlpPhoneContextSettings phoneSetting;
+ inline ulp_msg_inject_phone_context_settings(void* instance, UlpPhoneContextSettings setting) :
+ loc_eng_msg(instance, ULP_MSG_INJECT_PHONE_CONTEXT_SETTINGS),
+ phoneSetting(setting)
+ {
+ LOC_LOGV("context type: %d\n gps enabled: %d\n network position available %d\n wifi setting enabled %d\n battery charging %d"
+ "is_agps_setting_enabled %d, is_enh_location_services_enabled %d\n",
+ phoneSetting.context_type,
+ phoneSetting.is_gps_enabled,
+ phoneSetting.is_network_position_available,
+ phoneSetting.is_wifi_setting_enabled,
+ phoneSetting.is_battery_charging,
+ phoneSetting.is_agps_enabled,
+ phoneSetting.is_enh_location_services_enabled);
+ }
+};
+
+struct ulp_msg_inject_network_position : public loc_eng_msg {
+ const UlpNetworkPositionReport networkPosition;
+ inline ulp_msg_inject_network_position(void* instance, UlpNetworkPositionReport networkPos) :
+ loc_eng_msg(instance, ULP_MSG_INJECT_NETWORK_POSITION),
+ networkPosition(networkPos)
+ {
+ LOC_LOGV("flags: %d\n source: %d\n latitude: %f\n longitude: %f\n accuracy %d",
+ networkPosition.valid_flag,
+ networkPosition.position.pos_source,
+ networkPosition.position.latitude,
+ networkPosition.position.longitude,
+ networkPosition.position.HEPE);
+ }
+};
+
+struct ulp_msg_report_quipc_position : public loc_eng_msg {
+ const GpsLocation location;
+ const int quipc_error_code;
+ inline ulp_msg_report_quipc_position(void* instance, GpsLocation &loc,
+ int quipc_err) :
+ loc_eng_msg(instance, ULP_MSG_REPORT_QUIPC_POSITION),
+ location(loc), quipc_error_code(quipc_err)
+ {
+ 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 Quipc error: %d",
+ location.flags, location.position_source, location.latitude, location.longitude,
+ location.altitude, location.speed, location.bearing, location.accuracy,
+ location.timestamp, location.rawDataSize, location.rawData,
+ quipc_error_code);
+ }
+};
+
+struct loc_eng_msg_privacy : public loc_eng_msg {
+ const int8_t privacy_setting;
+ inline loc_eng_msg_privacy(void* instance, int8_t privacy_setting) :
+ loc_eng_msg(instance, LOC_ENG_MSG_PRIVACY),
+ privacy_setting(privacy_setting)
+ {
+ LOC_LOGV("privacy_setting: %d", privacy_setting);
+ }
+};
+
+void loc_eng_msg_sender(void* loc_eng_data_p, void* msg);
+int loc_eng_msgget(int * p_req_msgq);
+int loc_eng_msgremove(int req_msgq);
+int loc_eng_msgsnd(int msgqid, void * msgp);
+int loc_eng_msgrcv(int msgqid, void ** msgp);
+int loc_eng_msgsnd_raw(int msgqid, void * msgp, unsigned int msgsz);
+int loc_eng_msgrcv_raw(int msgqid, void *msgp, unsigned int msgsz);
+int loc_eng_msgflush(int msgqid);
+int loc_eng_msgunblock(int msgqid);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LOC_ENG_MSG_H */
diff --git a/gps/libloc_api_50001/loc_eng_msg_id.h b/gps/libloc_api_50001/loc_eng_msg_id.h
new file mode 100644
index 0000000..829b632
--- /dev/null
+++ b/gps/libloc_api_50001/loc_eng_msg_id.h
@@ -0,0 +1,133 @@
+/* Copyright (c) 2011,2012 Code Aurora Forum. 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 Code Aurora Forum, 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 "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_ID_H
+#define LOC_ENG_MSG_ID_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+struct msgbuf {
+ unsigned int msgsz;
+ void* msgid;
+};
+
+enum loc_eng_msg_ids_t {
+ /* 0x 0 - 0xEF is reserved for daemon internal */
+ /* 0xF0 - 0x1FF is reserved for daemon & framework communication */
+ LOC_ENG_MSG_QUIT = 0x200,
+
+ LOC_ENG_MSG_ENGINE_DOWN,
+ LOC_ENG_MSG_ENGINE_UP,
+
+ LOC_ENG_MSG_START_FIX,
+ LOC_ENG_MSG_STOP_FIX,
+ LOC_ENG_MSG_SET_POSITION_MODE,
+ LOC_ENG_MSG_SET_TIME,
+ LOC_ENG_MSG_INJECT_XTRA_DATA,
+ LOC_ENG_MSG_INJECT_LOCATION,
+ LOC_ENG_MSG_DELETE_AIDING_DATA,
+ LOC_ENG_MSG_SET_APN,
+ LOC_ENG_MSG_SET_SERVER_URL,
+ LOC_ENG_MSG_SET_SERVER_IPV4,
+ LOC_ENG_MSG_ENABLE_DATA,
+
+ LOC_ENG_MSG_SUPL_VERSION,
+ LOC_ENG_MSG_SET_SENSOR_CONTROL_CONFIG,
+ LOC_ENG_MSG_SET_SENSOR_PROPERTIES,
+ LOC_ENG_MSG_SET_SENSOR_PERF_CONTROL_CONFIG,
+ LOC_ENG_MSG_MUTE_SESSION,
+
+ LOC_ENG_MSG_ATL_OPEN_SUCCESS,
+ LOC_ENG_MSG_ATL_CLOSED,
+ LOC_ENG_MSG_ATL_OPEN_FAILED,
+
+ LOC_ENG_MSG_REPORT_POSITION,
+ LOC_ENG_MSG_REPORT_SV,
+ LOC_ENG_MSG_REPORT_STATUS,
+ LOC_ENG_MSG_REPORT_NMEA,
+ LOC_ENG_MSG_REQUEST_BIT,
+ LOC_ENG_MSG_RELEASE_BIT,
+ LOC_ENG_MSG_REQUEST_ATL,
+ LOC_ENG_MSG_RELEASE_ATL,
+ LOC_ENG_MSG_REQUEST_WIFI,
+ LOC_ENG_MSG_RELEASE_WIFI,
+ LOC_ENG_MSG_REQUEST_NI,
+ LOC_ENG_MSG_INFORM_NI_RESPONSE,
+ LOC_ENG_MSG_REQUEST_XTRA_DATA,
+ LOC_ENG_MSG_REQUEST_TIME,
+ LOC_ENG_MSG_REQUEST_POSITION,
+ LOC_ENG_MSG_EXT_POWER_CONFIG,
+
+ // The following messages are added for ulp
+ LOC_ENG_MSG_REQUEST_PHONE_CONTEXT,
+ LOC_ENG_MSG_REQUEST_NETWORK_POSIITON,
+
+ /* Following messages are for ulp, start at index 0x600 */
+
+ // Message is sent by GPS HAL layer to add/remove unique request criteria
+ ULP_MSG_UPDATE_CRITERIA = 0x600,
+
+ // Message is sent by GPS HAL layer to request ULP to start producing position fixes
+
+ ULP_MSG_START_FIX,
+
+ // Message is sent by Android framework(GpsLocationProvider)
+ // to request ULP to stop producing position fixes
+ ULP_MSG_STOP_FIX,
+
+ // Message is sent by Android framework(GpsLocationProvider)
+ // to inject phone context setting include initial phone context setting and subsequent changes
+ ULP_MSG_INJECT_PHONE_CONTEXT_SETTINGS,
+
+ // Message is sent by network provider to INJECT the position in UlpNetworkPositionReport format
+ ULP_MSG_INJECT_NETWORK_POSITION,
+
+ // Message is sent by QUIPC provider in order to report the position in GpsPosition format with QUIPC status
+ ULP_MSG_REPORT_QUIPC_POSITION,
+
+ // Message is sent by QUIPC module in order to request some info from ULP
+ ULP_MSG_REQUEST_COARSE_POSITION,
+
+ /* Message is sent by HAL to LOC API to configure LTE Positioning
+ Profile in modem */
+ LOC_ENG_MSG_LPP_CONFIG,
+
+ // Message is sent by Android framework (GpsLocationProvider)
+ // to inject the raw command
+ ULP_MSG_INJECT_RAW_COMMAND,
+
+ LOC_ENG_MSG_PRIVACY,
+};
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LOC_ENG_MSG_ID_H */
diff --git a/gps/libloc_api_50001/loc_eng_ni.cpp b/gps/libloc_api_50001/loc_eng_ni.cpp
new file mode 100644
index 0000000..c2d78af
--- /dev/null
+++ b/gps/libloc_api_50001/loc_eng_ni.cpp
@@ -0,0 +1,313 @@
+/* Copyright (c) 2009,2011 Code Aurora Forum. 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 Code Aurora Forum, 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 "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 <loc_eng.h>
+
+#include "log_util.h"
+
+/*=============================================================================
+ *
+ * DATA DECLARATION
+ *
+ *============================================================================*/
+
+/*=============================================================================
+ *
+ * FUNCTION DECLARATIONS
+ *
+ *============================================================================*/
+static void* ni_thread_proc(void *args);
+
+/*===========================================================================
+
+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;
+
+ if (NULL == loc_eng_data.ni_notify_cb) {
+ EXIT_LOG(%s, "loc_eng_ni_init hasn't happened yet.");
+ return;
+ }
+
+ /* If busy, use default or deny */
+ if (NULL != loc_eng_ni_data_p->rawRequest)
+ {
+ /* XXX Consider sending a NO RESPONSE reply or queue the request */
+ LOC_LOGW("loc_eng_ni_request_handler, notification in progress, new NI request ignored, type: %d",
+ notif->ni_type);
+ if (NULL != passThrough) {
+ free((void*)passThrough);
+ }
+ }
+ else {
+ /* Save request */
+ loc_eng_ni_data_p->rawRequest = (void*)passThrough;
+
+ /* Fill in notification */
+ ((GpsNiNotification*)notif)->notification_id = loc_eng_ni_data_p->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.
+ **/
+ loc_eng_ni_data_p->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", loc_eng_ni_data_p->respTimeLeft);
+
+ int rc = 0;
+ rc = pthread_create(&loc_eng_ni_data_p->thread, NULL, ni_thread_proc, &loc_eng_data);
+ if (rc)
+ {
+ LOC_LOGE("Loc NI thread is not created.\n");
+ }
+ rc = pthread_detach(loc_eng_ni_data_p->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_data_s_type* loc_eng_data_p = (loc_eng_data_s_type*)args;
+ loc_eng_ni_data_s_type* loc_eng_ni_data_p = &loc_eng_data_p->loc_eng_ni_data;
+ 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(&loc_eng_ni_data_p->tLock);
+ /* Calculate absolute expire time */
+ gettimeofday(&present_time, NULL);
+ expire_time.tv_sec = present_time.tv_sec + loc_eng_ni_data_p->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, loc_eng_ni_data_p->respTimeLeft );
+
+ while (!loc_eng_ni_data_p->respRecvd)
+ {
+ rc = pthread_cond_timedwait(&loc_eng_ni_data_p->tCond,
+ &loc_eng_ni_data_p->tLock,
+ &expire_time);
+ if (rc == ETIMEDOUT)
+ {
+ loc_eng_ni_data_p->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 );
+ loc_eng_ni_data_p->respRecvd = FALSE; /* Reset the user response flag for the next session*/
+
+ // adding this check to support modem restart, in which case, we need the thread
+ // to exit without calling sending data to loc_eng_msg_q. We made sure that
+ // rawRequest is NULL in loc_eng_ni_reset_on_engine_restart()
+ loc_eng_msg_inform_ni_response *msg = NULL;
+
+ if (NULL != loc_eng_ni_data_p->rawRequest) {
+ loc_eng_data_s_type *loc_eng_data_p = (loc_eng_data_s_type*)args;
+ msg = new loc_eng_msg_inform_ni_response(loc_eng_data_p,
+ loc_eng_ni_data_p->resp,
+ loc_eng_ni_data_p->rawRequest);
+ loc_eng_ni_data_p->rawRequest = NULL;
+ }
+ pthread_mutex_unlock(&loc_eng_ni_data_p->tLock);
+
+ loc_eng_ni_data_p->respTimeLeft = 0;
+ loc_eng_ni_data_p->reqID++;
+
+ if (NULL != msg) {
+ loc_eng_msg_sender(loc_eng_data_p, 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->rawRequest) {
+ free(loc_eng_ni_data_p->rawRequest);
+ loc_eng_ni_data_p->rawRequest = NULL;
+
+ pthread_mutex_lock(&loc_eng_ni_data_p->tLock);
+ // the goal is to wake up ni_thread_proc
+ // and let it exit.
+ loc_eng_ni_data_p->respRecvd = TRUE;
+ pthread_cond_signal(&loc_eng_ni_data_p->tCond);
+ pthread_mutex_unlock(&loc_eng_ni_data_p->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, GpsNiCallbacks *callbacks)
+{
+ ENTRY_LOG_CALLFLOW();
+
+ 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->respTimeLeft = 0;
+ loc_eng_ni_data_p->respRecvd = FALSE;
+ loc_eng_ni_data_p->rawRequest = NULL;
+ loc_eng_ni_data_p->reqID = 0;
+ pthread_cond_init(&loc_eng_ni_data_p->tCond, NULL);
+ pthread_mutex_init(&loc_eng_ni_data_p->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;
+
+ 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->reqID &&
+ NULL != loc_eng_ni_data_p->rawRequest)
+ {
+ LOC_LOGI("loc_eng_ni_respond: send user response %d for notif %d", user_response, notif_id);
+ pthread_mutex_lock(&loc_eng_ni_data_p->tLock);
+ loc_eng_ni_data_p->resp = user_response;
+ loc_eng_ni_data_p->respRecvd = TRUE;
+ pthread_cond_signal(&loc_eng_ni_data_p->tCond);
+ pthread_mutex_unlock(&loc_eng_ni_data_p->tLock);
+ }
+ else {
+ LOC_LOGE("loc_eng_ni_respond: reqID %d and notif_id %d mismatch or rawRequest %p, response: %d",
+ loc_eng_ni_data_p->reqID, notif_id, loc_eng_ni_data_p->rawRequest, user_response);
+ }
+
+ EXIT_LOG(%s, VOID_RET);
+}
diff --git a/gps/libloc_api_50001/loc_eng_ni.h b/gps/libloc_api_50001/loc_eng_ni.h
new file mode 100644
index 0000000..9b1c5f3
--- /dev/null
+++ b/gps/libloc_api_50001/loc_eng_ni.h
@@ -0,0 +1,50 @@
+/* Copyright (c) 2009,2011 Code Aurora Forum. 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 Code Aurora Forum, 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 "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>
+
+#define LOC_NI_NO_RESPONSE_TIME 20 /* secs */
+#define LOC_NI_NOTIF_KEY_ADDRESS "Address"
+
+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;
+} loc_eng_ni_data_s_type;
+
+
+#endif /* LOC_ENG_NI_H */
diff --git a/gps/libloc_api_50001/loc_eng_xtra.cpp b/gps/libloc_api_50001/loc_eng_xtra.cpp
new file mode 100644
index 0000000..ebc7c6f
--- /dev/null
+++ b/gps/libloc_api_50001/loc_eng_xtra.cpp
@@ -0,0 +1,90 @@
+/* Copyright (c) 2009,2011 Code Aurora Forum. 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 Code Aurora Forum, 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 "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 <loc_eng_msg.h>
+#include "log_util.h"
+
+
+/*===========================================================================
+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,
+ GpsXtraCallbacks* callbacks)
+{
+ loc_eng_xtra_data_s_type *xtra_module_data_ptr;
+
+ xtra_module_data_ptr = &loc_eng_data.xtra_module_data;
+ xtra_module_data_ptr->download_request_cb = callbacks->download_request_cb;
+
+ return 0;
+}
+
+/*===========================================================================
+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: success
+ >0: failure
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int loc_eng_xtra_inject_data(loc_eng_data_s_type &loc_eng_data,
+ char* data, int length)
+{
+ loc_eng_msg_inject_xtra_data *msg(new loc_eng_msg_inject_xtra_data(&loc_eng_data,
+ data, length));
+ loc_eng_msg_sender(&loc_eng_data, msg);
+
+ return 0;
+}
diff --git a/gps/libloc_api_50001/loc_eng_xtra.h b/gps/libloc_api_50001/loc_eng_xtra.h
new file mode 100644
index 0000000..7e01e14
--- /dev/null
+++ b/gps/libloc_api_50001/loc_eng_xtra.h
@@ -0,0 +1,46 @@
+/* Copyright (c) 2009,2011 Code Aurora Forum. 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 Code Aurora Forum, 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 "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;
+
+ // 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
diff --git a/gps/ulp/inc/ulp.h b/gps/ulp/inc/ulp.h
new file mode 100644
index 0000000..50d6c91
--- /dev/null
+++ b/gps/ulp/inc/ulp.h
@@ -0,0 +1,59 @@
+/* Copyright (c) 2011, Code Aurora Forum. 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 Code Aurora Forum, 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef ULP_H
+#define ULP_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <hardware/gps.h>
+#include "loc_eng.h"
+
+/** Represents the standard ulp module interface. */
+typedef struct {
+ /** set to sizeof(ulpInterface) */
+ size_t size;
+
+ /**
+ * Starts the libulp module. 0: success
+ */
+ int (*init)(loc_eng_data_s_type &loc_eng_data);
+
+}ulpInterface;
+
+typedef const ulpInterface* (get_ulp_interface) (void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* ULP_H */
+
diff --git a/gps/utils/Android.mk b/gps/utils/Android.mk
new file mode 100644
index 0000000..9df5e79
--- /dev/null
+++ b/gps/utils/Android.mk
@@ -0,0 +1,45 @@
+ifneq ($(BUILD_TINY_ANDROID),true)
+#Compile this library only for builds with the latest modem image
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+## Libs
+LOCAL_SHARED_LIBRARIES := \
+ libutils \
+ libcutils
+
+LOCAL_SRC_FILES += \
+ loc_log.cpp \
+ loc_cfg.cpp \
+ msg_q.c \
+ linked_list.c
+
+LOCAL_CFLAGS += \
+ -fno-short-enums \
+ -D_ANDROID_
+
+LOCAL_LDFLAGS += -Wl,--export-dynamic
+
+## Includes
+LOCAL_C_INCLUDES:=
+
+LOCAL_COPY_HEADERS_TO:= gps.utils/
+LOCAL_COPY_HEADERS:= \
+ loc_log.h \
+ loc_cfg.h \
+ log_util.h \
+ linked_list.h \
+ msg_q.h
+
+LOCAL_MODULE := libgps.utils
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_PRELINK_MODULE := false
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)
+include $(BUILD_SHARED_LIBRARY)
+endif # not BUILD_TINY_ANDROID
+
diff --git a/gps/utils/linked_list.c b/gps/utils/linked_list.c
new file mode 100644
index 0000000..16f2aa2
--- /dev/null
+++ b/gps/utils/linked_list.c
@@ -0,0 +1,328 @@
+/* Copyright (c) 2011, Code Aurora Forum. 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 Code Aurora Forum, 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 "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 "linked_list.h"
+#include <stdio.h>
+#include <string.h>
+
+#define LOG_TAG "LocSvc_utils_ll"
+#include "log_util.h"
+
+#include <stdlib.h>
+#include <stdint.h>
+
+typedef struct list_element {
+ struct list_element* next;
+ struct list_element* prev;
+ void* data_ptr;
+ void (*dealloc_func)(void*);
+}list_element;
+
+typedef struct list_state {
+ list_element* p_head;
+ list_element* p_tail;
+} list_state;
+
+/* ----------------------- END INTERNAL FUNCTIONS ---------------------------------------- */
+
+/*===========================================================================
+
+ FUNCTION: linked_list_init
+
+ ===========================================================================*/
+linked_list_err_type linked_list_init(void** list_data)
+{
+ if( list_data == NULL )
+ {
+ LOC_LOGE("%s: Invalid list parameter!\n", __FUNCTION__);
+ return eLINKED_LIST_INVALID_PARAMETER;
+ }
+
+ list_state* tmp_list;
+ tmp_list = (list_state*)calloc(1, sizeof(list_state));
+ if( tmp_list == NULL )
+ {
+ LOC_LOGE("%s: Unable to allocate space for list!\n", __FUNCTION__);
+ return eLINKED_LIST_FAILURE_GENERAL;
+ }
+
+ tmp_list->p_head = NULL;
+ tmp_list->p_tail = NULL;
+
+ *list_data = tmp_list;
+
+ return eLINKED_LIST_SUCCESS;
+}
+
+/*===========================================================================
+
+ FUNCTION: linked_list_destroy
+
+ ===========================================================================*/
+linked_list_err_type linked_list_destroy(void** list_data)
+{
+ if( list_data == NULL )
+ {
+ LOC_LOGE("%s: Invalid list parameter!\n", __FUNCTION__);
+ return eLINKED_LIST_INVALID_HANDLE;
+ }
+
+ list_state* p_list = (list_state*)*list_data;
+
+ linked_list_flush(p_list);
+
+ free(*list_data);
+ *list_data = NULL;
+
+ return eLINKED_LIST_SUCCESS;
+}
+
+/*===========================================================================
+
+ FUNCTION: linked_list_add
+
+ ===========================================================================*/
+linked_list_err_type linked_list_add(void* list_data, void *data_obj, void (*dealloc)(void*))
+{
+ LOC_LOGD("%s: Adding to list data_obj = 0x%08X\n", __FUNCTION__, data_obj);
+ if( list_data == NULL )
+ {
+ LOC_LOGE("%s: Invalid list parameter!\n", __FUNCTION__);
+ return eLINKED_LIST_INVALID_HANDLE;
+ }
+
+ if( data_obj == NULL )
+ {
+ LOC_LOGE("%s: Invalid input parameter!\n", __FUNCTION__);
+ return eLINKED_LIST_INVALID_PARAMETER;
+ }
+
+ list_state* p_list = (list_state*)list_data;
+ list_element* elem = (list_element*)malloc(sizeof(list_element));
+ if( elem == NULL )
+ {
+ LOC_LOGE("%s: Memory allocation failed\n", __FUNCTION__);
+ return eLINKED_LIST_FAILURE_GENERAL;
+ }
+
+ /* Copy data to newly created element */
+ elem->data_ptr = data_obj;
+ elem->next = NULL;
+ elem->prev = NULL;
+ elem->dealloc_func = dealloc;
+
+ /* Replace head element */
+ list_element* tmp = p_list->p_head;
+ p_list->p_head = elem;
+ /* Point next to the previous head element */
+ p_list->p_head->next = tmp;
+
+ if( tmp != NULL )
+ {
+ tmp->prev = p_list->p_head;
+ }
+ else
+ {
+ p_list->p_tail = p_list->p_head;
+ }
+
+ return eLINKED_LIST_SUCCESS;
+}
+
+/*===========================================================================
+
+ FUNCTION: linked_list_remove
+
+ ===========================================================================*/
+linked_list_err_type linked_list_remove(void* list_data, void **data_obj)
+{
+ LOC_LOGD("%s: Removing from list\n", __FUNCTION__);
+ if( list_data == NULL )
+ {
+ LOC_LOGE("%s: Invalid list parameter!\n", __FUNCTION__);
+ return eLINKED_LIST_INVALID_HANDLE;
+ }
+
+ if( data_obj == NULL )
+ {
+ LOC_LOGE("%s: Invalid input parameter!\n", __FUNCTION__);
+ return eLINKED_LIST_INVALID_PARAMETER;
+ }
+
+ list_state* p_list = (list_state*)list_data;
+ if( p_list->p_tail == NULL )
+ {
+ return eLINKED_LIST_UNAVAILABLE_RESOURCE;
+ }
+
+ list_element* tmp = p_list->p_tail;
+
+ /* Replace tail element */
+ p_list->p_tail = tmp->prev;
+
+ if( p_list->p_tail != NULL )
+ {
+ p_list->p_tail->next = NULL;
+ }
+ else
+ {
+ p_list->p_head = p_list->p_tail;
+ }
+
+ /* Copy data to output param */
+ *data_obj = tmp->data_ptr;
+
+ /* Free allocated list element */
+ free(tmp);
+
+ return eLINKED_LIST_SUCCESS;
+}
+
+/*===========================================================================
+
+ FUNCTION: linked_list_empty
+
+ ===========================================================================*/
+int linked_list_empty(void* list_data)
+{
+ if( list_data == NULL )
+ {
+ LOC_LOGE("%s: Invalid list parameter!\n", __FUNCTION__);
+ return (int)eLINKED_LIST_INVALID_HANDLE;
+ }
+ else
+ {
+ list_state* p_list = (list_state*)list_data;
+ return p_list->p_head == NULL ? 1 : 0;
+ }
+}
+
+/*===========================================================================
+
+ FUNCTION: linked_list_flush
+
+ ===========================================================================*/
+linked_list_err_type linked_list_flush(void* list_data)
+{
+ if( list_data == NULL )
+ {
+ LOC_LOGE("%s: Invalid list parameter!\n", __FUNCTION__);
+ return eLINKED_LIST_INVALID_HANDLE;
+ }
+
+ list_state* p_list = (list_state*)list_data;
+
+ /* Remove all dynamically allocated elements */
+ while( p_list->p_head != NULL )
+ {
+ list_element* tmp = p_list->p_head->next;
+
+ /* Free data pointer if told to do so. */
+ if( p_list->p_head->dealloc_func != NULL )
+ {
+ p_list->p_head->dealloc_func(p_list->p_head->data_ptr);
+ }
+
+ /* Free list element */
+ free(p_list->p_head);
+
+ p_list->p_head = tmp;
+ }
+
+ p_list->p_tail = NULL;
+
+ return eLINKED_LIST_SUCCESS;
+}
+
+/*===========================================================================
+
+ FUNCTION: linked_list_search
+
+ ===========================================================================*/
+linked_list_err_type linked_list_search(void* list_data, void **data_p,
+ bool (*equal)(void* data_0, void* data),
+ void* data_0, bool rm_if_found)
+{
+ LOC_LOGD("%s: Search the list\n", __FUNCTION__);
+ if( list_data == NULL || NULL == equal )
+ {
+ LOC_LOGE("%s: Invalid list parameter! list_data %p equal %p\n",
+ __FUNCTION__, list_data, equal);
+ return eLINKED_LIST_INVALID_HANDLE;
+ }
+
+ list_state* p_list = (list_state*)list_data;
+ if( p_list->p_tail == NULL )
+ {
+ return eLINKED_LIST_UNAVAILABLE_RESOURCE;
+ }
+
+ list_element* tmp = p_list->p_head;
+
+ if (NULL != data_p) {
+ *data_p = NULL;
+ }
+
+ while (NULL != tmp) {
+ if ((*equal)(data_0, tmp->data_ptr)) {
+ if (NULL != data_p) {
+ *data_p = tmp->data_ptr;
+ }
+
+ if (rm_if_found) {
+ if (NULL == tmp->prev) {
+ p_list->p_head = tmp->next;
+ } else {
+ tmp->prev->next = tmp->next;
+ }
+
+ if (NULL == tmp->next) {
+ p_list->p_tail = tmp->prev;
+ } else {
+ tmp->next->prev = tmp->prev;
+ }
+
+ tmp->prev = tmp->next = NULL;
+
+ // dealloc data if it is not copied out && caller
+ // has given us a dealloc function pointer.
+ if (NULL == data_p && NULL != tmp->dealloc_func) {
+ tmp->dealloc_func(tmp->data_ptr);
+ }
+ free(tmp);
+ }
+
+ tmp = NULL;
+ } else {
+ tmp = tmp->next;
+ }
+ }
+
+ return eLINKED_LIST_SUCCESS;
+}
+
diff --git a/gps/utils/linked_list.h b/gps/utils/linked_list.h
new file mode 100644
index 0000000..cfc945a
--- /dev/null
+++ b/gps/utils/linked_list.h
@@ -0,0 +1,217 @@
+/* Copyright (c) 2011, Code Aurora Forum. 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 Code Aurora Forum, 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 "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 __LINKED_LIST_H__
+#define __LINKED_LIST_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <stdbool.h>
+#include <stdlib.h>
+
+/** Linked List Return Codes */
+typedef enum
+{
+ eLINKED_LIST_SUCCESS = 0,
+ /**< Request was successful. */
+ eLINKED_LIST_FAILURE_GENERAL = -1,
+ /**< Failed because of a general failure. */
+ eLINKED_LIST_INVALID_PARAMETER = -2,
+ /**< Failed because the request contained invalid parameters. */
+ eLINKED_LIST_INVALID_HANDLE = -3,
+ /**< Failed because an invalid handle was specified. */
+ eLINKED_LIST_UNAVAILABLE_RESOURCE = -4,
+ /**< Failed because an there were not enough resources. */
+ eLINKED_LIST_INSUFFICIENT_BUFFER = -5,
+ /**< Failed because an the supplied buffer was too small. */
+}linked_list_err_type;
+
+/*===========================================================================
+FUNCTION linked_list_init
+
+DESCRIPTION
+ Initializes internal structures for linked list.
+
+ list_data: State of list to be initialized.
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ Look at error codes above.
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+linked_list_err_type linked_list_init(void** list_data);
+
+/*===========================================================================
+FUNCTION linked_list_destroy
+
+DESCRIPTION
+ Destroys internal structures for linked list.
+
+ p_list_data: State of list to be destroyed.
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ Look at error codes above.
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+linked_list_err_type linked_list_destroy(void** list_data);
+
+/*===========================================================================
+FUNCTION linked_list_add
+
+DESCRIPTION
+ Adds an element to the head of the linked list. The passed in data pointer
+ is not modified or freed. Passed in data_obj is expected to live throughout
+ the use of the linked_list (i.e. data is not allocated internally)
+
+ p_list_data: List to add data to the head of.
+ data_obj: Pointer to data to add into list
+ dealloc: Function used to deallocate memory for this element. Pass NULL
+ if you do not want data deallocated during a flush operation
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ Look at error codes above.
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+linked_list_err_type linked_list_add(void* list_data, void *data_obj, void (*dealloc)(void*));
+
+/*===========================================================================
+FUNCTION linked_list_remove
+
+DESCRIPTION
+ Retrieves data from the list tail. data_obj is the tail element from the list
+ passed in by linked_list_add.
+
+ p_list_data: List to remove the tail from.
+ data_obj: Pointer to data removed from list
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ Look at error codes above.
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+linked_list_err_type linked_list_remove(void* list_data, void **data_obj);
+
+/*===========================================================================
+FUNCTION linked_list_empty
+
+DESCRIPTION
+ Tells whether the list currently contains any elements
+
+ p_list_data: List to check if empty.
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ 0/FALSE : List contains elements
+ 1/TRUE : List is Empty
+ Otherwise look at error codes above.
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int linked_list_empty(void* list_data);
+
+/*===========================================================================
+FUNCTION linked_list_flush
+
+DESCRIPTION
+ Removes all elements from the list and deallocates them using the provided
+ dealloc function while adding elements.
+
+ p_list_data: List to remove all elements from.
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ Look at error codes above.
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+linked_list_err_type linked_list_flush(void* list_data);
+
+/*===========================================================================
+FUNCTION linked_list_search
+
+DESCRIPTION
+ Searches for an element in the linked list.
+
+ p_list_data: List handle.
+ data_p: to be stored with the data found; NUll if no match.
+ if data_p passed in as NULL, then no write to it.
+ equal: Function ptr takes in a list element, and returns
+ indication if this the one looking for.
+ data_0: The data being compared against.
+ rm_if_found: Should data be removed if found?
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ Look at error codes above.
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+linked_list_err_type linked_list_search(void* list_data, void **data_p,
+ bool (*equal)(void* data_0, void* data),
+ void* data_0, bool rm_if_found);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __LINKED_LIST_H__ */
diff --git a/gps/utils/loc_cfg.cpp b/gps/utils/loc_cfg.cpp
new file mode 100644
index 0000000..574c958
--- /dev/null
+++ b/gps/utils/loc_cfg.cpp
@@ -0,0 +1,310 @@
+/* Copyright (c) 2011 Code Aurora Forum. 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 Code Aurora Forum, 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 "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_utils_cfg"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <time.h>
+#include <loc_cfg.h>
+#include <log_util.h>
+
+/*=============================================================================
+ *
+ * GLOBAL DATA DECLARATION
+ *
+ *============================================================================*/
+
+/* Parameter data */
+static uint8_t DEBUG_LEVEL = 3;
+static uint8_t TIMESTAMP = 0;
+
+/* Parameter spec table */
+static loc_param_s_type loc_parameter_table[] =
+{
+ {"DEBUG_LEVEL", &DEBUG_LEVEL, NULL, 'n'},
+ {"TIMESTAMP", &TIMESTAMP, NULL, 'n'},
+};
+
+int loc_param_num = sizeof(loc_parameter_table) / sizeof(loc_param_s_type);
+
+/*===========================================================================
+FUNCTION loc_default_parameters
+
+DESCRIPTION
+ Resets the parameters to default
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ None
+
+SIDE EFFECTS
+ N/A
+===========================================================================*/
+
+static void loc_default_parameters()
+{
+ /* defaults */
+ DEBUG_LEVEL = 3; /* debug level */
+ TIMESTAMP = 0;
+
+ /* reset logging mechanism */
+ loc_logger_init(DEBUG_LEVEL, TIMESTAMP);
+}
+
+/*===========================================================================
+FUNCTION trim_space
+
+DESCRIPTION
+ Removes leading and trailing spaces of the string
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ None
+
+SIDE EFFECTS
+ N/A
+===========================================================================*/
+void trim_space(char *org_string)
+{
+ char *scan_ptr, *write_ptr;
+ char *first_nonspace = NULL, *last_nonspace = NULL;
+
+ scan_ptr = write_ptr = org_string;
+
+ while (*scan_ptr)
+ {
+ if ( !isspace(*scan_ptr) && first_nonspace == NULL)
+ {
+ first_nonspace = scan_ptr;
+ }
+
+ if (first_nonspace != NULL)
+ {
+ *(write_ptr++) = *scan_ptr;
+ if ( !isspace(*scan_ptr))
+ {
+ last_nonspace = write_ptr;
+ }
+ }
+
+ scan_ptr++;
+ }
+
+ if (last_nonspace) { *last_nonspace = '\0'; }
+}
+
+typedef struct loc_param_v_type
+{
+ char* param_name;
+
+ char* param_str_value;
+ int param_int_value;
+ double param_double_value;
+}loc_param_v_type;
+
+/*===========================================================================
+FUNCTION loc_set_config_entry
+
+DESCRIPTION
+ Potentially sets a given configuration table entry based on the passed in
+ configuration value. This is done by using a string comparison of the
+ parameter names and those found in the configuration file.
+
+PARAMETERS:
+ config_entry: configuration entry in the table to possibly set
+ config_value: value to store in the entry if the parameter names match
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ None
+
+SIDE EFFECTS
+ N/A
+===========================================================================*/
+void loc_set_config_entry(loc_param_s_type* config_entry, loc_param_v_type* config_value)
+{
+ if(NULL == config_entry || NULL == config_value)
+ {
+ LOC_LOGE("%s: INVALID config entry or parameter", __FUNCTION__);
+ return;
+ }
+
+ if (strcmp(config_entry->param_name, config_value->param_name) == 0 &&
+ config_entry->param_ptr)
+ {
+ switch (config_entry->param_type)
+ {
+ case 's':
+ if (strcmp(config_value->param_str_value, "NULL") == 0)
+ {
+ *((char*)config_entry->param_ptr) = '\0';
+ }
+ else {
+ strlcpy((char*) config_entry->param_ptr,
+ config_value->param_str_value,
+ LOC_MAX_PARAM_STRING + 1);
+ }
+ /* Log INI values */
+ LOC_LOGD("%s: PARAM %s = %s", __FUNCTION__, config_entry->param_name, (char*)config_entry->param_ptr);
+
+ if(NULL != config_entry->param_set)
+ {
+ *(config_entry->param_set) = 1;
+ }
+ break;
+ case 'n':
+ *((int *)config_entry->param_ptr) = config_value->param_int_value;
+ /* Log INI values */
+ LOC_LOGD("%s: PARAM %s = %d", __FUNCTION__, config_entry->param_name, config_value->param_int_value);
+
+ if(NULL != config_entry->param_set)
+ {
+ *(config_entry->param_set) = 1;
+ }
+ break;
+ case 'f':
+ *((double *)config_entry->param_ptr) = config_value->param_double_value;
+ /* Log INI values */
+ LOC_LOGD("%s: PARAM %s = %f", __FUNCTION__, config_entry->param_name, config_value->param_double_value);
+
+ if(NULL != config_entry->param_set)
+ {
+ *(config_entry->param_set) = 1;
+ }
+ break;
+ default:
+ LOC_LOGE("%s: PARAM %s parameter type must be n, f, or s", __FUNCTION__, config_entry->param_name);
+ }
+ }
+}
+
+/*===========================================================================
+FUNCTION loc_read_conf
+
+DESCRIPTION
+ Reads the specified configuration file and sets defined values based on
+ the passed in configuration table. This table maps strings to values to
+ set along with the type of each of these values.
+
+PARAMETERS:
+ conf_file_name: configuration file to read
+ config_table: table definition of strings to places to store information
+ table_length: length of the configuration table
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ None
+
+SIDE EFFECTS
+ N/A
+===========================================================================*/
+void loc_read_conf(const char* conf_file_name, loc_param_s_type* config_table, uint32_t table_length)
+{
+ FILE *gps_conf_fp = NULL;
+ char input_buf[LOC_MAX_PARAM_LINE]; /* declare a char array */
+ char *lasts;
+ loc_param_v_type config_value;
+ uint32_t i;
+
+ loc_default_parameters();
+
+ if((gps_conf_fp = fopen(conf_file_name, "r")) != NULL)
+ {
+ LOC_LOGD("%s: using %s", __FUNCTION__, GPS_CONF_FILE);
+ }
+ else
+ {
+ LOC_LOGW("%s: no %s file found", __FUNCTION__, GPS_CONF_FILE);
+ return; /* no parameter file */
+ }
+
+ /* Clear all validity bits */
+ for(i = 0; NULL != config_table && i < table_length; i++)
+ {
+ if(NULL != config_table[i].param_set)
+ {
+ *(config_table[i].param_set) = 0;
+ }
+ }
+
+ while(fgets(input_buf, LOC_MAX_PARAM_LINE, gps_conf_fp) != NULL)
+ {
+ memset(&config_value, 0, sizeof(config_value));
+
+ /* Separate variable and value */
+ config_value.param_name = strtok_r(input_buf, "=", &lasts);
+ if (config_value.param_name == NULL) continue; /* skip lines that do not contain "=" */
+ config_value.param_str_value = strtok_r(NULL, "=", &lasts);
+ if (config_value.param_str_value == NULL) continue; /* skip lines that do not contain two operands */
+
+ /* Trim leading and trailing spaces */
+ trim_space(config_value.param_name);
+ trim_space(config_value.param_str_value);
+
+ /* Parse numerical value */
+ if (config_value.param_str_value[0] == '0' && tolower(config_value.param_str_value[1]) == 'x')
+ {
+ /* hex */
+ config_value.param_int_value = (int) strtol(&config_value.param_str_value[2], (char**) NULL, 16);
+ }
+ else {
+ config_value.param_double_value = (double) atof(config_value.param_str_value); /* float */
+ config_value.param_int_value = atoi(config_value.param_str_value); /* dec */
+ }
+
+ for(i = 0; NULL != config_table && i < table_length; i++)
+ {
+ loc_set_config_entry(&config_table[i], &config_value);
+ }
+
+ for(i = 0; i < loc_param_num; i++)
+ {
+ loc_set_config_entry(&loc_parameter_table[i], &config_value);
+ }
+ }
+
+ fclose(gps_conf_fp);
+
+ /* Initialize logging mechanism with parsed data */
+ loc_logger_init(DEBUG_LEVEL, TIMESTAMP);
+}
diff --git a/gps/utils/loc_cfg.h b/gps/utils/loc_cfg.h
new file mode 100644
index 0000000..bc3b1c3
--- /dev/null
+++ b/gps/utils/loc_cfg.h
@@ -0,0 +1,88 @@
+/* Copyright (c) 2011 Code Aurora Forum. 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 Code Aurora Forum, 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 "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_CFG_H
+#define LOC_CFG_H
+
+#include <stdint.h>
+
+#define LOC_MAX_PARAM_NAME 48
+#define LOC_MAX_PARAM_STRING 80
+#define LOC_MAX_PARAM_LINE 80
+
+// Don't want to overwrite the pre-def'ed value
+#ifndef GPS_CONF_FILE
+#define GPS_CONF_FILE "/etc/gps.conf" //??? platform independent
+#endif
+
+#define UTIL_READ_CONF_DEFAULT(filename) \
+ loc_read_conf((filename), NULL, 0);
+
+#define UTIL_READ_CONF(filename, config_table) \
+ loc_read_conf((filename), (config_table), sizeof(config_table) / sizeof(config_table[0]))
+
+/*=============================================================================
+ *
+ * MODULE TYPE DECLARATION
+ *
+ *============================================================================*/
+typedef struct
+{
+ char param_name[LOC_MAX_PARAM_NAME];
+ void *param_ptr;
+ uint8_t *param_set; /* was this value set by config file? */
+ char param_type; /* 'n' for number,
+ 's' for string,
+ 'f' for float */
+} loc_param_s_type;
+
+/*=============================================================================
+ *
+ * MODULE EXTERNAL DATA
+ *
+ *============================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*=============================================================================
+ *
+ * MODULE EXPORTED FUNCTIONS
+ *
+ *============================================================================*/
+extern void loc_read_conf(const char* conf_file_name,
+ loc_param_s_type* config_table,
+ uint32_t table_length);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LOC_CFG_H */
diff --git a/gps/utils/loc_log.cpp b/gps/utils/loc_log.cpp
new file mode 100644
index 0000000..e4fb76c
--- /dev/null
+++ b/gps/utils/loc_log.cpp
@@ -0,0 +1,183 @@
+/* Copyright (c) 2011 Code Aurora Forum. 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 Code Aurora Forum, 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 "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
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include "loc_log.h"
+#include "msg_q.h"
+
+#include "log_util.h"
+
+// Logging Improvements
+const char *loc_logger_boolStr[]={"False","True"};
+const char VOID_RET[] = "None";
+const char FROM_AFW[] = "===>";
+const char TO_MODEM[] = "--->";
+const char FROM_MODEM[] = "<---";
+const char TO_AFW[] = "<===";
+const char EXIT_TAG[] = "Exiting";
+const char ENTRY_TAG[] = "Entering";
+
+/* Logging Mechanism */
+loc_logger_s_type loc_logger;
+
+/* Get names from value */
+const char* loc_get_name_from_mask(loc_name_val_s_type table[], int table_size, long mask)
+{
+ int i;
+ for (i = 0; i < table_size; i++)
+ {
+ if (table[i].val & (long) mask)
+ {
+ return table[i].name;
+ }
+ }
+ return UNKNOWN_STR;
+}
+
+/* Get names from value */
+const char* loc_get_name_from_val(loc_name_val_s_type table[], int table_size, long value)
+{
+ int i;
+ for (i = 0; i < table_size; i++)
+ {
+ if (table[i].val == (long) value)
+ {
+ return table[i].name;
+ }
+ }
+ return UNKNOWN_STR;
+}
+
+static loc_name_val_s_type loc_msg_q_status[] =
+{
+ NAME_VAL( eMSG_Q_SUCCESS ),
+ NAME_VAL( eMSG_Q_FAILURE_GENERAL ),
+ NAME_VAL( eMSG_Q_INVALID_PARAMETER ),
+ NAME_VAL( eMSG_Q_INVALID_HANDLE ),
+ NAME_VAL( eMSG_Q_UNAVAILABLE_RESOURCE ),
+ NAME_VAL( eMSG_Q_INSUFFICIENT_BUFFER )
+};
+static int loc_msg_q_status_num = sizeof(loc_msg_q_status) / sizeof(loc_name_val_s_type);
+
+/* Find msg_q status name */
+const char* loc_get_msg_q_status(int status)
+{
+ return loc_get_name_from_val(loc_msg_q_status, loc_msg_q_status_num, (long) status);
+}
+
+const char* log_succ_fail_string(int is_succ)
+{
+ return is_succ? "successful" : "failed";
+}
+
+
+/*===========================================================================
+
+FUNCTION loc_get_time
+
+DESCRIPTION
+ Logs a callback event header.
+ The pointer time_string should point to a buffer of at least 13 bytes:
+
+ XX:XX:XX.000\0
+
+RETURN VALUE
+ The time string
+
+===========================================================================*/
+char *loc_get_time(char *time_string, unsigned long buf_size)
+{
+ struct timeval now; /* sec and usec */
+ struct tm now_tm; /* broken-down time */
+ char hms_string[80]; /* HH:MM:SS */
+
+ gettimeofday(&now, NULL);
+ localtime_r(&now.tv_sec, &now_tm);
+
+ strftime(hms_string, sizeof hms_string, "%H:%M:%S", &now_tm);
+ snprintf(time_string, buf_size, "%s.%03d", hms_string, (int) (now.tv_usec / 1000));
+
+ return time_string;
+}
+
+
+/*===========================================================================
+FUNCTION loc_logger_init
+
+DESCRIPTION
+ Initializes the state of DEBUG_LEVEL and TIMESTAMP
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ None
+
+SIDE EFFECTS
+ N/A
+===========================================================================*/
+void loc_logger_init(unsigned long debug, unsigned long timestamp)
+{
+ loc_logger.DEBUG_LEVEL = debug;
+ loc_logger.TIMESTAMP = timestamp;
+}
+
+
+/*===========================================================================
+FUNCTION get_timestamp
+
+DESCRIPTION
+ Generates a timestamp using the current system time
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ Char pointer to the parameter str
+
+SIDE EFFECTS
+ N/A
+===========================================================================*/
+char * get_timestamp(char *str, unsigned long buf_size)
+{
+ struct timeval tv;
+ struct timezone tz;
+ int hh, mm, ss;
+ gettimeofday(&tv, &tz);
+ hh = tv.tv_sec/3600%24;
+ mm = (tv.tv_sec%3600)/60;
+ ss = tv.tv_sec%60;
+ snprintf(str, buf_size, "%02d:%02d:%02d.%06ld", hh, mm, ss, tv.tv_usec);
+ return str;
+}
+
diff --git a/gps/utils/loc_log.h b/gps/utils/loc_log.h
new file mode 100644
index 0000000..8b071a4
--- /dev/null
+++ b/gps/utils/loc_log.h
@@ -0,0 +1,66 @@
+/* Copyright (c) 2011 Code Aurora Forum. 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 Code Aurora Forum, 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 "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_LOG_H
+#define LOC_LOG_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <ctype.h>
+
+typedef struct
+{
+ char name[128];
+ long val;
+} loc_name_val_s_type;
+
+#define NAME_VAL(x) {"" #x "", x }
+
+#define UNKNOWN_STR "UNKNOWN"
+
+#define CHECK_MASK(type, value, mask_var, mask) \
+ ((mask_var & mask) ? (type) value : (type) (-1))
+
+/* Get names from value */
+const char* loc_get_name_from_mask(loc_name_val_s_type table[], int table_size, long mask);
+const char* loc_get_name_from_val(loc_name_val_s_type table[], int table_size, long value);
+const char* loc_get_msg_q_status(int status);
+
+extern const char* log_succ_fail_string(int is_succ);
+
+extern char *loc_get_time(char *time_string, unsigned long buf_size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LOC_LOG_H */
diff --git a/gps/utils/log_util.h b/gps/utils/log_util.h
new file mode 100644
index 0000000..b3dae3c
--- /dev/null
+++ b/gps/utils/log_util.h
@@ -0,0 +1,158 @@
+/* Copyright (c) 2011 Code Aurora Forum. 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 Code Aurora Forum, 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 "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 __LOG_UTIL_H__
+#define __LOG_UTIL_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/*=============================================================================
+ *
+ * LOC LOGGER TYPE DECLARATION
+ *
+ *============================================================================*/
+/* LOC LOGGER */
+typedef struct loc_logger_s
+{
+ unsigned long DEBUG_LEVEL;
+ unsigned long TIMESTAMP;
+} loc_logger_s_type;
+
+/*=============================================================================
+ *
+ * EXTERNAL DATA
+ *
+ *============================================================================*/
+extern loc_logger_s_type loc_logger;
+
+// Logging Improvements
+extern const char *loc_logger_boolStr[];
+
+extern const char *boolStr[];
+extern const char VOID_RET[];
+extern const char FROM_AFW[];
+extern const char TO_MODEM[];
+extern const char FROM_MODEM[];
+extern const char TO_AFW[];
+extern const char EXIT_TAG[];
+extern const char ENTRY_TAG[];
+/*=============================================================================
+ *
+ * MODULE EXPORTED FUNCTIONS
+ *
+ *============================================================================*/
+extern void loc_logger_init(unsigned long debug, unsigned long timestamp);
+extern char* get_timestamp(char* str, unsigned long buf_size);
+
+
+#include <utils/Log.h>
+
+#ifndef DEBUG_DMN_LOC_API
+
+/* LOGGING MACROS */
+#define LOC_LOGE(...) ALOGE("E/"__VA_ARGS__)
+
+#define LOC_LOGW(...) \
+if (loc_logger.DEBUG_LEVEL >= 2) { ALOGE("W/"__VA_ARGS__); } \
+else if (loc_logger.DEBUG_LEVEL <= 0) { ALOGW("W/"__VA_ARGS__); }
+
+#define LOC_LOGI(...) \
+if (loc_logger.DEBUG_LEVEL >= 3) { ALOGE("I/"__VA_ARGS__); } \
+else if (loc_logger.DEBUG_LEVEL <= 0) { ALOGI("W/"__VA_ARGS__); }
+
+#define LOC_LOGD(...) \
+if (loc_logger.DEBUG_LEVEL >= 4) { ALOGE("D/"__VA_ARGS__); } \
+else if (loc_logger.DEBUG_LEVEL <= 0) { ALOGD("W/"__VA_ARGS__); }
+
+#define LOC_LOGV(...) \
+if (loc_logger.DEBUG_LEVEL >= 5) { ALOGE("V/"__VA_ARGS__); } \
+else if (loc_logger.DEBUG_LEVEL <= 0) { ALOGV("W/"__VA_ARGS__); }
+
+#else /* DEBUG_DMN_LOC_API */
+
+#define LOC_LOGE(...) ALOGE("E/"__VA_ARGS__)
+
+#define LOC_LOGW(...) ALOGW("W/"__VA_ARGS__)
+
+#define LOC_LOGI(...) ALOGI("I/"__VA_ARGS__)
+
+#define LOC_LOGD(...) ALOGD("D/"__VA_ARGS__)
+
+#define LOC_LOGV(...) ALOGV("V/"__VA_ARGS__)
+
+#endif /* DEBUG_DMN_LOC_API */
+
+/*=============================================================================
+ *
+ * LOGGING IMPROVEMENT MACROS
+ *
+ *============================================================================*/
+#define LOG_(LOC_LOG, ID, WHAT, SPEC, VAL) \
+ do { \
+ if (loc_logger.TIMESTAMP) { \
+ char ts[32]; \
+ LOC_LOG("[%s] %s %s line %d " #SPEC, \
+ get_timestamp(ts, sizeof(ts)), ID, WHAT, __LINE__, VAL); \
+ } else { \
+ LOC_LOG("%s %s line %d " #SPEC, \
+ ID, WHAT, __LINE__, VAL); \
+ } \
+ } while(0)
+
+
+#define LOG_I(ID, WHAT, SPEC, VAL) LOG_(LOC_LOGI, ID, WHAT, SPEC, VAL)
+#define LOG_V(ID, WHAT, SPEC, VAL) LOG_(LOC_LOGV, ID, WHAT, SPEC, VAL)
+
+#define ENTRY_LOG() LOG_V(ENTRY_TAG, __func__, %s, "")
+#define EXIT_LOG(SPEC, VAL) LOG_V(EXIT_TAG, __func__, SPEC, VAL)
+
+
+#ifdef DEBUG_TRACE_CALLFLOW
+// Used for logging callflow from Android Framework
+#define ENTRY_LOG_CALLFLOW() LOG_I(FROM_AFW, __func__, %s, "")
+// Used for logging callflow to Modem
+#define EXIT_LOG_CALLFLOW(SPEC, VAL) LOG_I(TO_MODEM, __func__, SPEC, VAL)
+// Used for logging callflow from Modem(TO_MODEM, __func__, %s, "")
+#define MODEM_LOG_CALLFLOW(SPEC, VAL) LOG_I(FROM_MODEM, __func__, SPEC, VAL)
+// Used for logging callflow to Android Framework
+#define CALLBACK_LOG_CALLFLOW(CB, SPEC, VAL) LOG_I(TO_AFW, CB, SPEC, VAL)
+#else
+#define ENTRY_LOG_CALLFLOW()
+#define EXIT_LOG_CALLFLOW(SPEC, VAL)
+#define MODEM_LOG_CALLFLOW(SPEC, VAL)
+#define CALLBACK_LOG_CALLFLOW(CB, SPEC, VAL)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __LOG_UTIL_H__
diff --git a/gps/utils/msg_q.c b/gps/utils/msg_q.c
new file mode 100644
index 0000000..cc024e4
--- /dev/null
+++ b/gps/utils/msg_q.c
@@ -0,0 +1,322 @@
+/* Copyright (c) 2011, Code Aurora Forum. 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 Code Aurora Forum, 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 "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 "msg_q.h"
+
+#define LOG_TAG "LocSvc_utils_q"
+#include "log_util.h"
+
+#include "linked_list.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+typedef struct msg_q {
+ void* msg_list; /* Linked list to store information */
+ pthread_cond_t list_cond; /* Condition variable for waiting on msg queue */
+ pthread_mutex_t list_mutex; /* Mutex for exclusive access to message queue */
+ int unblocked; /* Has this message queue been unblocked? */
+} msg_q;
+
+/*===========================================================================
+FUNCTION convert_linked_list_err_type
+
+DESCRIPTION
+ Converts from one set of enum values to another.
+
+ linked_list_val: Value to convert to msg_q_enum_type
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ Corresponding linked_list_enum_type in msg_q_enum_type
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static msq_q_err_type convert_linked_list_err_type(linked_list_err_type linked_list_val)
+{
+ switch( linked_list_val )
+ {
+ case eLINKED_LIST_SUCCESS:
+ return eMSG_Q_SUCCESS;
+ case eLINKED_LIST_INVALID_PARAMETER:
+ return eMSG_Q_INVALID_PARAMETER;
+ case eLINKED_LIST_INVALID_HANDLE:
+ return eMSG_Q_INVALID_HANDLE;
+ case eLINKED_LIST_UNAVAILABLE_RESOURCE:
+ return eMSG_Q_UNAVAILABLE_RESOURCE;
+ case eLINKED_LIST_INSUFFICIENT_BUFFER:
+ return eMSG_Q_INSUFFICIENT_BUFFER;
+
+ case eLINKED_LIST_FAILURE_GENERAL:
+ default:
+ return eMSG_Q_FAILURE_GENERAL;
+ }
+}
+
+/* ----------------------- END INTERNAL FUNCTIONS ---------------------------------------- */
+
+/*===========================================================================
+
+ FUNCTION: msg_q_init
+
+ ===========================================================================*/
+msq_q_err_type msg_q_init(void** msg_q_data)
+{
+ if( msg_q_data == NULL )
+ {
+ LOC_LOGE("%s: Invalid msg_q_data parameter!\n", __FUNCTION__);
+ return eMSG_Q_INVALID_PARAMETER;
+ }
+
+ msg_q* tmp_msg_q;
+ tmp_msg_q = (msg_q*)calloc(1, sizeof(msg_q));
+ if( tmp_msg_q == NULL )
+ {
+ LOC_LOGE("%s: Unable to allocate space for message queue!\n", __FUNCTION__);
+ return eMSG_Q_FAILURE_GENERAL;
+ }
+
+ if( linked_list_init(&tmp_msg_q->msg_list) != 0 )
+ {
+ LOC_LOGE("%s: Unable to initialize storage list!\n", __FUNCTION__);
+ free(tmp_msg_q);
+ return eMSG_Q_FAILURE_GENERAL;
+ }
+
+ if( pthread_mutex_init(&tmp_msg_q->list_mutex, NULL) != 0 )
+ {
+ LOC_LOGE("%s: Unable to initialize list mutex!\n", __FUNCTION__);
+ linked_list_destroy(&tmp_msg_q->msg_list);
+ free(tmp_msg_q);
+ return eMSG_Q_FAILURE_GENERAL;
+ }
+
+ if( pthread_cond_init(&tmp_msg_q->list_cond, NULL) != 0 )
+ {
+ LOC_LOGE("%s: Unable to initialize msg q cond var!\n", __FUNCTION__);
+ linked_list_destroy(&tmp_msg_q->msg_list);
+ pthread_mutex_destroy(&tmp_msg_q->list_mutex);
+ free(tmp_msg_q);
+ return eMSG_Q_FAILURE_GENERAL;
+ }
+
+ tmp_msg_q->unblocked = 0;
+
+ *msg_q_data = tmp_msg_q;
+
+ return eMSG_Q_SUCCESS;
+}
+
+/*===========================================================================
+
+ FUNCTION: msg_q_destroy
+
+ ===========================================================================*/
+msq_q_err_type msg_q_destroy(void** msg_q_data)
+{
+ if( msg_q_data == NULL )
+ {
+ LOC_LOGE("%s: Invalid msg_q_data parameter!\n", __FUNCTION__);
+ return eMSG_Q_INVALID_HANDLE;
+ }
+
+ msg_q* p_msg_q = (msg_q*)*msg_q_data;
+
+ linked_list_destroy(&p_msg_q->msg_list);
+ pthread_mutex_destroy(&p_msg_q->list_mutex);
+ pthread_cond_destroy(&p_msg_q->list_cond);
+
+ p_msg_q->unblocked = 0;
+
+ free(*msg_q_data);
+ *msg_q_data = NULL;
+
+ return eMSG_Q_SUCCESS;
+}
+
+/*===========================================================================
+
+ FUNCTION: msg_q_snd
+
+ ===========================================================================*/
+msq_q_err_type msg_q_snd(void* msg_q_data, void* msg_obj, void (*dealloc)(void*))
+{
+ msq_q_err_type rv;
+ if( msg_q_data == NULL )
+ {
+ LOC_LOGE("%s: Invalid msg_q_data parameter!\n", __FUNCTION__);
+ return eMSG_Q_INVALID_HANDLE;
+ }
+ if( msg_obj == NULL )
+ {
+ LOC_LOGE("%s: Invalid msg_obj parameter!\n", __FUNCTION__);
+ return eMSG_Q_INVALID_PARAMETER;
+ }
+
+ msg_q* p_msg_q = (msg_q*)msg_q_data;
+
+ pthread_mutex_lock(&p_msg_q->list_mutex);
+ LOC_LOGD("%s: Sending message with handle = 0x%08X\n", __FUNCTION__, msg_obj);
+
+ if( p_msg_q->unblocked )
+ {
+ LOC_LOGE("%s: Message queue has been unblocked.\n", __FUNCTION__);
+ pthread_mutex_unlock(&p_msg_q->list_mutex);
+ return eMSG_Q_UNAVAILABLE_RESOURCE;
+ }
+
+ rv = convert_linked_list_err_type(linked_list_add(p_msg_q->msg_list, msg_obj, dealloc));
+
+ /* Show data is in the message queue. */
+ pthread_cond_signal(&p_msg_q->list_cond);
+
+ pthread_mutex_unlock(&p_msg_q->list_mutex);
+
+ LOC_LOGD("%s: Finished Sending message with handle = 0x%08X\n", __FUNCTION__, msg_obj);
+
+ return rv;
+}
+
+/*===========================================================================
+
+ FUNCTION: msg_q_rcv
+
+ ===========================================================================*/
+msq_q_err_type msg_q_rcv(void* msg_q_data, void** msg_obj)
+{
+ msq_q_err_type rv;
+ if( msg_q_data == NULL )
+ {
+ LOC_LOGE("%s: Invalid msg_q_data parameter!\n", __FUNCTION__);
+ return eMSG_Q_INVALID_HANDLE;
+ }
+
+ if( msg_obj == NULL )
+ {
+ LOC_LOGE("%s: Invalid msg_obj parameter!\n", __FUNCTION__);
+ return eMSG_Q_INVALID_PARAMETER;
+ }
+
+ msg_q* p_msg_q = (msg_q*)msg_q_data;
+
+ LOC_LOGD("%s: Waiting on message\n", __FUNCTION__);
+
+ pthread_mutex_lock(&p_msg_q->list_mutex);
+
+ if( p_msg_q->unblocked )
+ {
+ LOC_LOGE("%s: Message queue has been unblocked.\n", __FUNCTION__);
+ pthread_mutex_unlock(&p_msg_q->list_mutex);
+ return eMSG_Q_UNAVAILABLE_RESOURCE;
+ }
+
+ /* Wait for data in the message queue */
+ while( linked_list_empty(p_msg_q->msg_list) && !p_msg_q->unblocked )
+ {
+ pthread_cond_wait(&p_msg_q->list_cond, &p_msg_q->list_mutex);
+ }
+
+ rv = convert_linked_list_err_type(linked_list_remove(p_msg_q->msg_list, msg_obj));
+
+ pthread_mutex_unlock(&p_msg_q->list_mutex);
+
+ LOC_LOGD("%s: Received message 0x%08X rv = %d\n", __FUNCTION__, *msg_obj, rv);
+
+ return rv;
+}
+
+/*===========================================================================
+
+ FUNCTION: msg_q_flush
+
+ ===========================================================================*/
+msq_q_err_type msg_q_flush(void* msg_q_data)
+{
+ msq_q_err_type rv;
+ if ( msg_q_data == NULL )
+ {
+ LOC_LOGE("%s: Invalid msg_q_data parameter!\n", __FUNCTION__);
+ return eMSG_Q_INVALID_HANDLE;
+ }
+
+ msg_q* p_msg_q = (msg_q*)msg_q_data;
+
+ LOC_LOGD("%s: Flushing Message Queue\n", __FUNCTION__);
+
+ pthread_mutex_lock(&p_msg_q->list_mutex);
+
+ /* Remove all elements from the list */
+ rv = convert_linked_list_err_type(linked_list_flush(p_msg_q->msg_list));
+
+ pthread_mutex_unlock(&p_msg_q->list_mutex);
+
+ LOC_LOGD("%s: Message Queue flushed\n", __FUNCTION__);
+
+ return rv;
+}
+
+/*===========================================================================
+
+ FUNCTION: msg_q_unblock
+
+ ===========================================================================*/
+msq_q_err_type msg_q_unblock(void* msg_q_data)
+{
+ if ( msg_q_data == NULL )
+ {
+ LOC_LOGE("%s: Invalid msg_q_data parameter!\n", __FUNCTION__);
+ return eMSG_Q_INVALID_HANDLE;
+ }
+
+ msg_q* p_msg_q = (msg_q*)msg_q_data;
+ pthread_mutex_lock(&p_msg_q->list_mutex);
+
+ if( p_msg_q->unblocked )
+ {
+ LOC_LOGE("%s: Message queue has been unblocked.\n", __FUNCTION__);
+ pthread_mutex_unlock(&p_msg_q->list_mutex);
+ return eMSG_Q_UNAVAILABLE_RESOURCE;
+ }
+
+ LOC_LOGD("%s: Unblocking Message Queue\n", __FUNCTION__);
+ /* Unblocking message queue */
+ p_msg_q->unblocked = 1;
+
+ /* Allow all the waiters to wake up */
+ pthread_cond_broadcast(&p_msg_q->list_cond);
+
+ pthread_mutex_unlock(&p_msg_q->list_mutex);
+
+ LOC_LOGD("%s: Message Queue unblocked\n", __FUNCTION__);
+
+ return eMSG_Q_SUCCESS;
+}
diff --git a/gps/utils/msg_q.h b/gps/utils/msg_q.h
new file mode 100644
index 0000000..4171540
--- /dev/null
+++ b/gps/utils/msg_q.h
@@ -0,0 +1,189 @@
+/* Copyright (c) 2011, Code Aurora Forum. 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 Code Aurora Forum, 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 "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 __MSG_Q_H__
+#define __MSG_Q_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <stdlib.h>
+
+/** Linked List Return Codes */
+typedef enum
+{
+ eMSG_Q_SUCCESS = 0,
+ /**< Request was successful. */
+ eMSG_Q_FAILURE_GENERAL = -1,
+ /**< Failed because of a general failure. */
+ eMSG_Q_INVALID_PARAMETER = -2,
+ /**< Failed because the request contained invalid parameters. */
+ eMSG_Q_INVALID_HANDLE = -3,
+ /**< Failed because an invalid handle was specified. */
+ eMSG_Q_UNAVAILABLE_RESOURCE = -4,
+ /**< Failed because an there were not enough resources. */
+ eMSG_Q_INSUFFICIENT_BUFFER = -5,
+ /**< Failed because an the supplied buffer was too small. */
+}msq_q_err_type;
+
+/*===========================================================================
+FUNCTION msg_q_init
+
+DESCRIPTION
+ Initializes internal structures for message queue.
+
+ msg_q_data: State of message queue to be initialized.
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ Look at error codes above.
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+msq_q_err_type msg_q_init(void** msg_q_data);
+
+/*===========================================================================
+FUNCTION msg_q_destroy
+
+DESCRIPTION
+ Releases internal structures for message queue.
+
+ msg_q_data: State of message queue to be released.
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ Look at error codes above.
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+msq_q_err_type msg_q_destroy(void** msg_q_data);
+
+/*===========================================================================
+FUNCTION msg_q_snd
+
+DESCRIPTION
+ Sends data to the message queue. The passed in data pointer
+ is not modified or freed. Passed in msg_obj is expected to live throughout
+ the use of the msg_q (i.e. data is not allocated internally)
+
+ msg_q_data: Message Queue to add the element to.
+ msgp: Pointer to data to add into message queue.
+ dealloc: Function used to deallocate memory for this element. Pass NULL
+ if you do not want data deallocated during a flush operation
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ Look at error codes above.
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+msq_q_err_type msg_q_snd(void* msg_q_data, void* msg_obj, void (*dealloc)(void*));
+
+/*===========================================================================
+FUNCTION msg_q_rcv
+
+DESCRIPTION
+ Retrieves data from the message queue. msg_obj is the oldest message received
+ and pointer is simply removed from message queue.
+
+ msg_q_data: Message Queue to copy data from into msgp.
+ msg_obj: Pointer to space to copy msg_q contents to.
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ Look at error codes above.
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+msq_q_err_type msg_q_rcv(void* msg_q_data, void** msg_obj);
+
+/*===========================================================================
+FUNCTION msg_q_flush
+
+DESCRIPTION
+ Function removes all elements from the message queue.
+
+ msg_q_data: Message Queue to remove elements from.
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ Look at error codes above.
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+msq_q_err_type msg_q_flush(void* msg_q_data);
+
+/*===========================================================================
+FUNCTION msg_q_unblock
+
+DESCRIPTION
+ This function will stop use of the message queue. All waiters will wake up
+ and likely receive nothing from the queue resulting in a negative return
+ value. The message queue can no longer be used until it is destroyed
+ and initialized again after calling this function.
+
+ msg_q_data: Message queue to unblock.
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ Look at error codes above.
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+msq_q_err_type msg_q_unblock(void* msg_q_data);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __MSG_Q_H__ */
diff --git a/include/hardware/gps.h b/include/hardware/gps.h
new file mode 100644
index 0000000..9e70070
--- /dev/null
+++ b/include/hardware/gps.h
@@ -0,0 +1,1050 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (c) 2011,2012 Code Aurora Forum. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_INCLUDE_HARDWARE_GPS_H
+#define ANDROID_INCLUDE_HARDWARE_GPS_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <pthread.h>
+
+#include <hardware/hardware.h>
+
+__BEGIN_DECLS
+
+/**
+ * The id of this module
+ */
+#define GPS_HARDWARE_MODULE_ID "gps"
+#define ULP_NETWORK_INTERFACE "ulp-network-interface"
+
+/** Milliseconds since January 1, 1970 */
+typedef int64_t GpsUtcTime;
+
+/** Maximum number of SVs for gps_sv_status_callback(). */
+#define GPS_MAX_SVS 32
+
+/** Requested operational mode for GPS operation. */
+typedef uint32_t GpsPositionMode;
+// IMPORTANT: Note that the following values must match
+// constants in GpsLocationProvider.java.
+/** Mode for running GPS standalone (no assistance). */
+#define GPS_POSITION_MODE_STANDALONE 0
+/** AGPS MS-Based mode. */
+#define GPS_POSITION_MODE_MS_BASED 1
+/** AGPS MS-Assisted mode. */
+#define GPS_POSITION_MODE_MS_ASSISTED 2
+
+/** Requested recurrence mode for GPS operation. */
+typedef uint32_t GpsPositionRecurrence;
+// IMPORTANT: Note that the following values must match
+// constants in GpsLocationProvider.java.
+/** Receive GPS fixes on a recurring basis at a specified period. */
+#define GPS_POSITION_RECURRENCE_PERIODIC 0
+/** Request a single shot GPS fix. */
+#define GPS_POSITION_RECURRENCE_SINGLE 1
+
+/** GPS status event values. */
+typedef uint16_t GpsStatusValue;
+// IMPORTANT: Note that the following values must match
+// constants in GpsLocationProvider.java.
+/** GPS status unknown. */
+#define GPS_STATUS_NONE 0
+/** GPS has begun navigating. */
+#define GPS_STATUS_SESSION_BEGIN 1
+/** GPS has stopped navigating. */
+#define GPS_STATUS_SESSION_END 2
+/** GPS has powered on but is not navigating. */
+#define GPS_STATUS_ENGINE_ON 3
+/** GPS is powered off. */
+#define GPS_STATUS_ENGINE_OFF 4
+
+/** Flags to indicate which values are valid in a GpsLocation. */
+typedef uint16_t GpsLocationFlags;
+// IMPORTANT: Note that the following values must match
+// constants in GpsLocationProvider.java.
+/** GpsLocation has valid latitude and longitude. */
+#define GPS_LOCATION_HAS_LAT_LONG 0x0001
+/** GpsLocation has valid altitude. */
+#define GPS_LOCATION_HAS_ALTITUDE 0x0002
+/** GpsLocation has valid speed. */
+#define GPS_LOCATION_HAS_SPEED 0x0004
+/** GpsLocation has valid bearing. */
+#define GPS_LOCATION_HAS_BEARING 0x0008
+/** GpsLocation has valid accuracy. */
+#define GPS_LOCATION_HAS_ACCURACY 0x0010
+/** Location has valid source information. */
+#define LOCATION_HAS_SOURCE_INFO 0x0020
+/** GpsLocation has valid "is indoor?" flag */
+#define GPS_LOCATION_HAS_IS_INDOOR 0x0040
+/** GpsLocation has valid floor number */
+#define GPS_LOCATION_HAS_FLOOR_NUMBER 0x0080
+/** GpsLocation has valid map URL*/
+#define GPS_LOCATION_HAS_MAP_URL 0x0100
+/** GpsLocation has valid map index */
+#define GPS_LOCATION_HAS_MAP_INDEX 0x0200
+
+/** Sizes for indoor fields */
+#define GPS_LOCATION_MAP_URL_SIZE 400
+#define GPS_LOCATION_MAP_INDEX_SIZE 16
+
+/** Location Information Source */
+/** Position source is ULP */
+#define ULP_LOCATION_IS_FROM_HYBRID 0x0001
+/** Position source is GNSS only */
+#define ULP_LOCATION_IS_FROM_GNSS 0x0002
+
+/** Flags for the gps_set_capabilities callback. */
+
+/** GPS HAL schedules fixes for GPS_POSITION_RECURRENCE_PERIODIC mode.
+ If this is not set, then the framework will use 1000ms for min_interval
+ and will start and call start() and stop() to schedule the GPS.
+ */
+#define GPS_CAPABILITY_SCHEDULING 0x0000001
+/** GPS supports MS-Based AGPS mode */
+#define GPS_CAPABILITY_MSB 0x0000002
+/** GPS supports MS-Assisted AGPS mode */
+#define GPS_CAPABILITY_MSA 0x0000004
+/** GPS supports single-shot fixes */
+#define GPS_CAPABILITY_SINGLE_SHOT 0x0000008
+/** GPS supports on demand time injection */
+#define GPS_CAPABILITY_ON_DEMAND_TIME 0x0000010
+/* Hybrid support, the Android Framework will query to see if this capability is set before using the ulp functionalities in HAL */
+#define ULP_CAPABILITY 0x0000020
+/** Flags used to specify which aiding data to delete
+ when calling delete_aiding_data(). */
+typedef uint32_t GpsAidingData;
+// IMPORTANT: Note that the following values must match
+// constants in GpsLocationProvider.java.
+#define GPS_DELETE_EPHEMERIS 0x00000001
+#define GPS_DELETE_ALMANAC 0x00000002
+#define GPS_DELETE_POSITION 0x00000004
+#define GPS_DELETE_TIME 0x00000008
+#define GPS_DELETE_IONO 0x00000010
+#define GPS_DELETE_UTC 0x00000020
+#define GPS_DELETE_HEALTH 0x00000040
+#define GPS_DELETE_SVDIR 0x00000080
+#define GPS_DELETE_SVSTEER 0x00000100
+#define GPS_DELETE_SADATA 0x00000200
+#define GPS_DELETE_RTI 0x00000400
+#define GPS_DELETE_CELLDB_INFO 0x00000800
+#define GPS_DELETE_ALMANAC_CORR 0x00001000
+#define GPS_DELETE_FREQ_BIAS_EST 0x00002000
+#define GPS_DELETE_EPHEMERIS_GLO 0x00004000
+#define GPS_DELETE_ALMANAC_GLO 0x00008000
+#define GPS_DELETE_SVDIR_GLO 0x00010000
+#define GPS_DELETE_SVSTEER_GLO 0x00020000
+#define GPS_DELETE_ALMANAC_CORR_GLO 0x00040000
+#define GPS_DELETE_TIME_GPS 0x00080000
+#define GPS_DELETE_TIME_GLO 0x00100000
+
+#define GPS_DELETE_ALL 0xFFFFFFFF
+
+/** AGPS type */
+typedef int16_t AGpsType;
+#define AGPS_TYPE_INVALID -1
+#define AGPS_TYPE_ANY 0
+#define AGPS_TYPE_SUPL 1
+#define AGPS_TYPE_C2K 2
+#define AGPS_TYPE_WWAN_ANY 3
+#define AGPS_TYPE_WIFI 4
+
+/** SSID length */
+#define SSID_BUF_SIZE (32+1)
+
+typedef uint16_t AGpsSetIDType;
+#define AGPS_SETID_TYPE_NONE 0
+#define AGPS_SETID_TYPE_IMSI 1
+#define AGPS_SETID_TYPE_MSISDN 2
+
+typedef int16_t AGpsBearerType;
+#define AGPS_APN_BEARER_INVALID -1
+#define AGPS_APN_BEARER_IPV4 0
+#define AGPS_APN_BEARER_IPV6 1
+#define AGPS_APN_BEARER_IPV4V6 2
+
+/**
+ * String length constants
+ */
+#define GPS_NI_SHORT_STRING_MAXLEN 256
+#define GPS_NI_LONG_STRING_MAXLEN 2048
+
+/**
+ * GpsNiType constants
+ */
+typedef uint32_t GpsNiType;
+#define GPS_NI_TYPE_VOICE 1
+#define GPS_NI_TYPE_UMTS_SUPL 2
+#define GPS_NI_TYPE_UMTS_CTRL_PLANE 3
+
+/**
+ * GpsNiNotifyFlags constants
+ */
+typedef uint32_t GpsNiNotifyFlags;
+/** NI requires notification */
+#define GPS_NI_NEED_NOTIFY 0x0001
+/** NI requires verification */
+#define GPS_NI_NEED_VERIFY 0x0002
+/** NI requires privacy override, no notification/minimal trace */
+#define GPS_NI_PRIVACY_OVERRIDE 0x0004
+
+/**
+ * GPS NI responses, used to define the response in
+ * NI structures
+ */
+typedef int GpsUserResponseType;
+#define GPS_NI_RESPONSE_ACCEPT 1
+#define GPS_NI_RESPONSE_DENY 2
+#define GPS_NI_RESPONSE_NORESP 3
+
+/**
+ * NI data encoding scheme
+ */
+typedef int GpsNiEncodingType;
+#define GPS_ENC_NONE 0
+#define GPS_ENC_SUPL_GSM_DEFAULT 1
+#define GPS_ENC_SUPL_UTF8 2
+#define GPS_ENC_SUPL_UCS2 3
+#define GPS_ENC_UNKNOWN -1
+
+/** AGPS status event values. */
+typedef uint16_t AGpsStatusValue;
+/** GPS requests data connection for AGPS. */
+#define GPS_REQUEST_AGPS_DATA_CONN 1
+/** GPS releases the AGPS data connection. */
+#define GPS_RELEASE_AGPS_DATA_CONN 2
+/** AGPS data connection initiated */
+#define GPS_AGPS_DATA_CONNECTED 3
+/** AGPS data connection completed */
+#define GPS_AGPS_DATA_CONN_DONE 4
+/** AGPS data connection failed */
+#define GPS_AGPS_DATA_CONN_FAILED 5
+
+#define AGPS_REF_LOCATION_TYPE_GSM_CELLID 1
+#define AGPS_REF_LOCATION_TYPE_UMTS_CELLID 2
+#define AGPS_REG_LOCATION_TYPE_MAC 3
+
+/** Network types for update_network_state "type" parameter */
+#define AGPS_RIL_NETWORK_TYPE_MOBILE 0
+#define AGPS_RIL_NETWORK_TYPE_WIFI 1
+#define AGPS_RIL_NETWORK_TYPE_MOBILE_MMS 2
+#define AGPS_RIL_NETWORK_TYPE_MOBILE_SUPL 3
+#define AGPS_RIL_NETWORK_TTYPE_MOBILE_DUN 4
+#define AGPS_RIL_NETWORK_TTYPE_MOBILE_HIPRI 5
+#define AGPS_RIL_NETWORK_TTYPE_WIMAX 6
+
+/**
+ * Name for the EXTRA CMD interface. To pass from app to HAL
+ */
+#define ULP_RAW_CMD_INTERFACE "ulp-raw-cmd"
+
+/**
+ * Name for the GPS XTRA interface.
+ */
+#define GPS_XTRA_INTERFACE "gps-xtra"
+
+/**
+ * Name for the GPS DEBUG interface.
+ */
+#define GPS_DEBUG_INTERFACE "gps-debug"
+
+/**
+ * Name for the AGPS interface.
+ */
+#define AGPS_INTERFACE "agps"
+
+/**
+ * Name for NI interface
+ */
+#define GPS_NI_INTERFACE "gps-ni"
+
+/**
+ * Name for the AGPS-RIL interface.
+ */
+#define AGPS_RIL_INTERFACE "agps_ril"
+/**
+* Name for ULP Phone Context Interface
+*/
+#define ULP_PHONE_CONTEXT_INTERFACE "ulp-phone-context"
+
+/** Represents recurrence of location */
+typedef enum{
+ ULP_LOC_RECURRENCE_PERIODIC = 0,
+ ULP_LOC_RECURRENCE_SINGLE,
+}UlpRecurrenceCriteria;
+
+/** Represents horizontal accuracy options */
+typedef enum {
+ ULP_HORZ_ACCURACY_DONT_CARE = 0,
+ ULP_HORZ_ACCURACY_LOW,
+ ULP_HORZ_ACCURACY_MED,
+ ULP_HORZ_ACCURACY_HIGH,
+}UlpHorzAccuracyCriteria;
+
+/** Represents accuracy options (for speed, altitude, and
+ * bearing) */
+typedef enum {
+ ULP_ACCURACY_DONT_CARE = 0,
+ ULP_ACCURACY_LOW,
+ ULP_ACCURACY_HIGH,
+}UlpAccuracyCriteria;
+
+/** Represents power consumption options */
+typedef enum {
+ ULP_POWER_REQ_DONT_CARE = 0,
+ ULP_POWER_REQ_LOW,
+ ULP_POWER_REQ_HIGH,
+}UlpPowerCriteria;
+
+/** Represents data usage options */
+typedef enum {
+ ULP_DATA_REQ_DONT_CARE = 0,
+ ULP_DATA_ALLOW,
+ ULP_DATA_DENY,
+}UlpDataUsageCriteria;
+
+/** Enable the reporting of altitude in location reports */
+#define ULP_ENABLE_ALTITUDE_REPORT 0x01
+/** Enable the reporting of speed in location reports */
+#define ULP_ENABLE_SPEED_REPORT 0x02
+/** Enable the reporting of bearing in location reports */
+#define ULP_ENABLE_BEARING_REPORT 0x04
+
+#define ULP_CRITERIA_HAS_ACTION 0x00000001
+#define ULP_CRITERIA_HAS_PROVIDER_SOURCE 0x00000002
+#define ULP_CRITERIA_HAS_RECURRENCE_TYPE 0x00000004
+#define ULP_CRITERIA_HAS_PREFERRED_RESPONSE_TIME 0x00000010
+#define ULP_CRITERIA_HAS_MIN_INTERVAL 0x00000020
+#define ULP_CRITERIA_HAS_MIN_DISTANCE 0x00000040
+#define ULP_CRITERIA_HAS_MIN_DIST_SAMPLE_INTERVAL 0x00000080
+#define ULP_CRITERIA_HAS_DESIRED_OUTPUT_PARAMETER 0x00000100
+#define ULP_CRITERIA_HAS_PREFERRED_HORIZONTAL_ACCURACY 0x00000200
+#define ULP_CRITERIA_HAS_PREFERRED_POWER_CONSUMPTION 0x00000400
+#define ULP_CRITERIA_HAS_PREFERRED_ALTITUDE_ACCURACY 0x00000800
+#define ULP_CRITERIA_HAS_PREFERRED_BEARING_ACCURACY 0x00001000
+#define ULP_CRITERIA_HAS_PREFERRED_DATA_USAGE 0x00002000
+#define ULP_CRITERIA_HAS_INTERMEDIATE_POS_REPORT_ENABLED 0x00004000
+
+#define ULP_PROVIDER_SOURCE_GNSS 0x00000001
+#define ULP_PROVIDER_SOURCE_HYBRID 0x00000002
+
+
+#define ULP_ADD_CRITERIA 1
+#define ULP_REMOVE_CRITERIA 2
+
+typedef struct {
+
+ uint32_t valid_mask;
+ /* delete or add. This is a mandatory field */
+ int action;
+ /*via gps or hybrid provider*/
+ int provider_source;
+ /** PERIODIC or SINGLE */
+ UlpRecurrenceCriteria recurrence_type;
+ /** obtain position within the specified response time */
+ uint32_t preferred_response_time;
+ /** Send updates after the specified interval */
+ uint32_t min_interval;
+ /** Send updates after device moved a specified distance */
+ float min_distance;
+ uint32_t min_dist_sample_interval;
+ /** Fields specfied in the mask should be reported in the
+ * position report (altitude, bearing and speed) */
+ uint32_t desired_output_parameter;
+ /** Desired accuracy for latitude, longitude */
+ UlpHorzAccuracyCriteria preferred_horizontal_accuracy;
+ /** Desired power consumption level */
+ UlpPowerCriteria preferred_power_consumption;
+ /** Desired accuracy for altitude */
+ UlpAccuracyCriteria preferred_altitude_accuracy;
+ /** Desired accuracy for bearing */
+ UlpAccuracyCriteria preferred_bearing_accuracy;
+ UlpDataUsageCriteria preferred_data_usage;
+ bool intermediate_pos_report_enabled;
+} UlpLocationCriteria;
+
+/** Represents a location. */
+typedef struct {
+ /** set to sizeof(GpsLocation) */
+ size_t size;
+ /** Contains GpsLocationFlags bits. */
+ uint16_t flags;
+ /* Provider indicator for HYBRID or GPS */
+ uint16_t position_source;
+ /** Represents latitude in degrees. */
+ double latitude;
+ /** Represents longitude in degrees. */
+ double longitude;
+ /** Represents altitude in meters above the WGS 84 reference
+ * ellipsoid. */
+ double altitude;
+ /** Represents speed in meters per second. */
+ float speed;
+ /** Represents heading in degrees. */
+ float bearing;
+ /** Represents expected accuracy in meters. */
+ float accuracy;
+ /** Timestamp for the location fix. */
+ GpsUtcTime timestamp;
+ /*allows HAL to pass additional information related to the location */
+ int rawDataSize; /* in # of bytes */
+ void * rawData;
+ bool is_indoor;
+ float floor_number;
+ char map_url[GPS_LOCATION_MAP_URL_SIZE];
+ unsigned char map_index[GPS_LOCATION_MAP_INDEX_SIZE];
+} GpsLocation;
+
+/** Represents the status. */
+typedef struct {
+ /** set to sizeof(GpsStatus) */
+ size_t size;
+ GpsStatusValue status;
+} GpsStatus;
+
+/** Represents SV information. */
+typedef struct {
+ /** set to sizeof(GpsSvInfo) */
+ size_t size;
+ /** Pseudo-random number for the SV. */
+ int prn;
+ /** Signal to noise ratio. */
+ float snr;
+ /** Elevation of SV in degrees. */
+ float elevation;
+ /** Azimuth of SV in degrees. */
+ float azimuth;
+#if 1
+ /** Placeholder for Samsung ABI compat */
+ int unknown;
+#endif
+} GpsSvInfo;
+
+/** Represents SV status. */
+typedef struct {
+ /** set to sizeof(GpsSvStatus) */
+ size_t size;
+
+ /** Number of SVs currently visible. */
+ int num_svs;
+
+ /** Contains an array of SV information. */
+ GpsSvInfo sv_list[GPS_MAX_SVS];
+
+ /** Represents a bit mask indicating which SVs
+ * have ephemeris data.
+ */
+ uint32_t ephemeris_mask;
+
+ /** Represents a bit mask indicating which SVs
+ * have almanac data.
+ */
+ uint32_t almanac_mask;
+
+ /**
+ * Represents a bit mask indicating which SVs
+ * were used for computing the most recent position fix.
+ */
+ uint32_t used_in_fix_mask;
+} GpsSvStatus;
+
+/* 2G and 3G */
+/* In 3G lac is discarded */
+typedef struct {
+ uint16_t type;
+ uint16_t mcc;
+ uint16_t mnc;
+ uint16_t lac;
+#if 1
+ /** Placeholder for Samsung ABI compat */
+ uint16_t unknown;
+#endif
+ uint32_t cid;
+} AGpsRefLocationCellID;
+
+typedef struct {
+ uint8_t mac[6];
+} AGpsRefLocationMac;
+
+/** Represents ref locations */
+typedef struct {
+ uint16_t type;
+ union {
+ AGpsRefLocationCellID cellID;
+ AGpsRefLocationMac mac;
+ } u;
+} AGpsRefLocation;
+
+/** Callback with location information.
+ * Can only be called from a thread created by create_thread_cb.
+ */
+typedef void (* gps_location_callback)(GpsLocation* location);
+
+/** Callback with status information.
+ * Can only be called from a thread created by create_thread_cb.
+ */
+typedef void (* gps_status_callback)(GpsStatus* status);
+
+/** Callback with SV status information.
+ * Can only be called from a thread created by create_thread_cb.
+ */
+typedef void (* gps_sv_status_callback)(GpsSvStatus* sv_info);
+
+/** Callback for reporting NMEA sentences.
+ * Can only be called from a thread created by create_thread_cb.
+ */
+typedef void (* gps_nmea_callback)(GpsUtcTime timestamp, const char* nmea, int length);
+
+/** Callback to inform framework of the GPS engine's capabilities.
+ * Capability parameter is a bit field of GPS_CAPABILITY_* flags.
+ */
+typedef void (* gps_set_capabilities)(uint32_t capabilities);
+
+/** Callback utility for acquiring the GPS wakelock.
+ * This can be used to prevent the CPU from suspending while handling GPS events.
+ */
+typedef void (* gps_acquire_wakelock)();
+
+/** Callback utility for releasing the GPS wakelock. */
+typedef void (* gps_release_wakelock)();
+
+/** Callback for requesting NTP time */
+typedef void (* gps_request_utc_time)();
+
+/** Callback for creating a thread that can call into the Java framework code.
+ * This must be used to create any threads that report events up to the framework.
+ */
+typedef pthread_t (* gps_create_thread)(const char* name, void (*start)(void *), void* arg);
+
+/** GPS callback structure. */
+typedef struct {
+ /** set to sizeof(GpsCallbacks) */
+ size_t size;
+ gps_location_callback location_cb;
+ gps_status_callback status_cb;
+ gps_sv_status_callback 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;
+ gps_request_utc_time request_utc_time_cb;
+} GpsCallbacks;
+
+
+/** Represents the standard GPS interface. */
+typedef struct {
+ /** set to sizeof(GpsInterface) */
+ size_t size;
+ /**
+ * Opens the interface and provides the callback routines
+ * to the implemenation of this interface.
+ */
+ int (*init)( GpsCallbacks* callbacks );
+
+ /** Starts navigating. */
+ int (*start)( void );
+
+ /** Stops navigating. */
+ int (*stop)( void );
+
+ /** Closes the interface. */
+ void (*cleanup)( void );
+
+ /** Injects the current time. */
+ int (*inject_time)(GpsUtcTime time, int64_t timeReference,
+ int uncertainty);
+
+ /** Injects current location from another location provider
+ * (typically cell ID).
+ * latitude and longitude are measured in degrees
+ * expected accuracy is measured in meters
+ */
+ int (*inject_location)(double latitude, double longitude, float accuracy);
+
+ /**
+ * Specifies that the next call to start will not use the
+ * information defined in the flags. GPS_DELETE_ALL is passed for
+ * a cold start.
+ */
+ void (*delete_aiding_data)(GpsAidingData flags);
+
+ /**
+ * min_interval represents the time between fixes in milliseconds.
+ * preferred_accuracy represents the requested fix accuracy in meters.
+ * preferred_time represents the requested time to first fix in milliseconds.
+ */
+ int (*set_position_mode)(GpsPositionMode mode, GpsPositionRecurrence recurrence,
+ uint32_t min_interval, uint32_t preferred_accuracy, uint32_t preferred_time);
+
+ /** Get a pointer to extension information. */
+ const void* (*get_extension)(const char* name);
+
+ /* set criterias of location requests */
+ int (*update_criteria) (UlpLocationCriteria criteria );
+} GpsInterface;
+
+/** Extended interface for raw GPS command support. */
+typedef struct {
+ /** set to sizeof(ExtraCmdInterface) */
+ size_t size;
+ /** Injects Android extra cmd into the ulp. Clarify if they are blocking calls */
+ bool (*inject_raw_cmd)(char* bundle, int bundle_length );
+
+} InjectRawCmdInterface;
+
+/** ULP Network Interface */
+/** Request for network position status */
+#define ULP_NETWORK_POS_STATUS_REQUEST (0x01)
+/** Request for periodic network positions */
+#define ULP_NETWORK_POS_START_PERIODIC_REQUEST (0x02)
+/** Request last known location */
+#define ULP_NETWORK_POS_GET_LAST_KNOWN_LOCATION_REQUEST (0x03)
+/** Cancel request */
+#define ULP_NETWORK_POS_STOP_REQUEST (0x04)
+
+/** Position was obtained using Wifi Network */
+#define ULP_NETWORK_POSITION_SRC_WIFI (0x01)
+/** Position was obtained using Cell Network */
+#define ULP_NETWORK_POSITION_SRC_CELL (0x02)
+/** Position was obtained using an Unknown Network */
+#define ULP_NETWORK_POSITION_SRC_UNKNOWN (0x00)
+
+/** Represents the ULP network request */
+typedef struct {
+ /** type of request */
+ uint16_t request_type;
+ /** Desired time between network positions/measurements in ms.
+ * Shall be set to 0 if only one position is requested */
+ int interval_ms;
+ /** network position source to be used */
+ uint16_t desired_position_source;
+}UlpNetworkRequestPos;
+
+/** Callback with network position request. */
+typedef void (*ulp_network_location_request)(UlpNetworkRequestPos *req);
+
+/** ULP Network callback structure. */
+typedef struct {
+ ulp_network_location_request ulp_network_location_request_cb;
+} UlpNetworkLocationCallbacks;
+
+/** represent a network position */
+typedef struct {
+ /** source of the position (Wifi, Cell) */
+ uint16_t pos_source;
+ /** latitude in degrees */
+ double latitude;
+ /** longitude in degrees */
+ double longitude;
+ /** Horzizontal error estimate in meters */
+ uint16_t HEPE;
+} UlpNetworkPosition;
+
+/** Represents access point information */
+typedef struct {
+ /** Mac adderess */
+ char mac_addr[6];
+ /** signal strength in dbM */
+ int32_t rssi;
+ /** Beacon channel for access point */
+ uint16_t channel;
+
+ /** Bit 0 = AP is used by WiFi positioning system
+ * Bit 1 = AP doesn't broadcast SSID Bit 2 = AP has encrption
+ * turned on Bit 3 = AP is in infrastructure mode and not in
+ * ad-hoc/unknown mode */
+ uint8_t ap_qualifier;
+} UlpNetworkAccessPointInfo;
+
+/** Represents Wifi information */
+typedef struct {
+ /** Number of APs in the calculated position (-1 means
+ * unknown) */
+ uint8_t num_aps_in_pos;
+ /** Information of the scanned ap's used in the position estimation*/
+ UlpNetworkAccessPointInfo *ap_info;
+} UlpNetworkWifiInfo;
+
+
+/** Represent network landscape information */
+typedef struct {
+ /** network type Cell/Wifi */
+ uint8_t network_type;
+ /** network information */
+ union {
+ UlpNetworkWifiInfo wifi_info;
+ uint32_t cell_info;
+ } u;
+} UlpNetworkLandscape;
+
+/** network report valid flags */
+/** fix time is valid */
+#define ULP_NETWORK_POSITION_REPORT_HAS_FIX_TIME (0x01)
+/** position is valid */
+#define ULP_NETWORK_POSITION_REPORT_HAS_POSITION (0x02)
+/** landscape is valid */
+#define ULP_NETWORK_POSITION_REPORT_HAS_LANDSCAPE (0x04)
+
+/** Represents the network position report */
+typedef struct
+{
+ /** validity flags */
+ uint16_t valid_flag;
+ /** time fo network fix */
+ GpsUtcTime fix_time;
+ /** network position */
+ UlpNetworkPosition position;
+ /** network landscape */
+ UlpNetworkLandscape landscape_info;
+}UlpNetworkPositionReport;
+
+/** represents ULP network interface extension */
+typedef struct
+{
+ /** set to sizeof(UlpNetworkInterface) */
+ size_t size;
+ /** initialize network interface */
+ int ( *init)(UlpNetworkLocationCallbacks *callback);
+ /** send network position */
+ int ( *ulp_send_network_position)(UlpNetworkPositionReport *position_report);
+}UlpNetworkInterface;
+
+/** Information for the ULP Phone context interface */
+
+/** the Location settings context supports only ON_CHANGE
+ * request type */
+#define ULP_PHONE_CONTEXT_GPS_SETTING (0x01)
+#define ULP_PHONE_CONTEXT_NETWORK_POSITION_SETTING (0x02)
+#define ULP_PHONE_CONTEXT_WIFI_SETTING (0x04)
+/** The battery charging state context supports only
+ * ON_CHANGE request type */
+#define ULP_PHONE_CONTEXT_BATTERY_CHARGING_STATE (0x08)
+#define ULP_PHONE_CONTEXT_AGPS_SETTING (0x010)
+#define ULP_PHONE_CONTEXT_ENH_LOCATION_SERVICES_SETTING (0x020)
+
+/** return phone context only once */
+#define ULP_PHONE_CONTEXT_REQUEST_TYPE_SINGLE (0x01)
+/** return phone context periodcially */
+#define ULP_PHONE_CONTEXT_REQUEST_TYPE_PERIODIC (0x02)
+/** return phone context when it changes */
+#define ULP_PHONE_CONTEXT_REQUEST_TYPE_ON_CHANGE (0x03)
+
+
+/** Represents ULP phone context request */
+typedef struct {
+ /** context type requested */
+ uint16_t context_type;
+ /** request type */
+ uint16_t request_type;
+ /** interval in ms if request type is periodic */
+ int interval_ms;
+}UlpPhoneContextRequest;
+
+/** Callback for phone context request. */
+typedef void (*ulp_request_phone_context)(UlpPhoneContextRequest *req);
+
+/** ULP Phone Context callback structure. */
+typedef struct {
+ ulp_request_phone_context ulp_request_phone_context_cb;
+}UlpPhoneContextCallbacks;
+
+/** Represents the phone context settings */
+typedef struct {
+ /** Phone context information type */
+ uint16_t context_type;
+
+ /** network information */
+ /** gps setting */
+ bool is_gps_enabled;
+ /** is network positioning enabled */
+ bool is_network_position_available;
+ /** is wifi turned on */
+ bool is_wifi_setting_enabled;
+ /** is battery being currently charged */
+ bool is_battery_charging;
+ /* is agps enabled for single shot */
+ bool is_agps_enabled;
+ /* is Enhanced Location Services enabled by user*/
+ bool is_enh_location_services_enabled;
+} UlpPhoneContextSettings;
+
+/** Represent the phone contxt interface */
+typedef struct
+{
+ /** set to sizeof(UlpPhoneContextInterface) */
+ size_t size;
+ /** Initialize, register callback */
+ int (*init)(UlpPhoneContextCallbacks *callback);
+ /** send the phone context settings */
+ int (*ulp_phone_context_settings_update) (UlpPhoneContextSettings *settings );
+}UlpPhoneContextInterface;
+
+/** Callback to request the client to download XTRA data.
+ * The client should download XTRA data and inject it by calling inject_xtra_data().
+ * Can only be called from a thread created by create_thread_cb.
+ */
+typedef void (* gps_xtra_download_request)();
+
+/** Callback structure for the XTRA interface. */
+typedef struct {
+ gps_xtra_download_request download_request_cb;
+ gps_create_thread create_thread_cb;
+} GpsXtraCallbacks;
+
+/** Extended interface for XTRA support. */
+typedef struct {
+ /** set to sizeof(GpsXtraInterface) */
+ size_t size;
+ /**
+ * Opens the XTRA interface and provides the callback routines
+ * to the implemenation of this interface.
+ */
+ int (*init)( GpsXtraCallbacks* callbacks );
+ /** Injects XTRA data into the GPS. */
+ int (*inject_xtra_data)( char* data, int length );
+} GpsXtraInterface;
+
+/** Extended interface for DEBUG support. */
+typedef struct {
+ /** set to sizeof(GpsDebugInterface) */
+ size_t size;
+
+ /**
+ * This function should return any information that the native
+ * implementation wishes to include in a bugreport.
+ */
+ size_t (*get_internal_state)(char* buffer, size_t bufferSize);
+} GpsDebugInterface;
+
+/** Represents the status of AGPS. */
+typedef struct {
+ /** set to sizeof(AGpsStatus) */
+ size_t size;
+
+ AGpsType type;
+ AGpsStatusValue status;
+ int ipv4_addr;
+ char ipv6_addr[16];
+ char ssid[SSID_BUF_SIZE];
+ char password[SSID_BUF_SIZE];
+} AGpsStatus;
+
+/** Callback with AGPS status information.
+ * Can only be called from a thread created by create_thread_cb.
+ */
+typedef void (* agps_status_callback)(AGpsStatus* status);
+
+/** Callback structure for the AGPS interface. */
+typedef struct {
+ agps_status_callback status_cb;
+ gps_create_thread create_thread_cb;
+} AGpsCallbacks;
+
+
+/** Extended interface for AGPS support. */
+typedef struct {
+ /** set to sizeof(AGpsInterface) */
+ size_t size;
+
+ /**
+ * Opens the AGPS interface and provides the callback routines
+ * to the implemenation of this interface.
+ */
+ void (*init)( AGpsCallbacks* callbacks );
+ /**
+ * Notifies that a data connection is available and sets
+ * the name of the APN to be used for SUPL.
+ */
+ int (*data_conn_open)( AGpsType agpsType,
+ const char* apn, AGpsBearerType bearerType );
+ /**
+ * Notifies that the AGPS data connection has been closed.
+ */
+ int (*data_conn_closed)( AGpsType agpsType );
+ /**
+ * Notifies that a data connection is not available for AGPS.
+ */
+ int (*data_conn_failed)(AGpsType agpsType );
+ /**
+ * Sets the hostname and port for the AGPS server.
+ */
+ int (*set_server)( AGpsType type, const char* hostname, int port );
+} AGpsInterface;
+
+
+/** Represents an NI request */
+typedef struct {
+ /** set to sizeof(GpsNiNotification) */
+ size_t size;
+
+ /**
+ * An ID generated by HAL to associate NI notifications and UI
+ * responses
+ */
+ int notification_id;
+
+ /**
+ * An NI type used to distinguish different categories of NI
+ * events, such as GPS_NI_TYPE_VOICE, GPS_NI_TYPE_UMTS_SUPL, ...
+ */
+ GpsNiType ni_type;
+
+ /**
+ * Notification/verification options, combinations of GpsNiNotifyFlags constants
+ */
+ GpsNiNotifyFlags notify_flags;
+
+ /**
+ * Timeout period to wait for user response.
+ * Set to 0 for no time out limit.
+ */
+ int timeout;
+
+ /**
+ * Default response when time out.
+ */
+ GpsUserResponseType default_response;
+
+ /**
+ * Requestor ID
+ */
+ char requestor_id[GPS_NI_SHORT_STRING_MAXLEN];
+
+ /**
+ * Notification message. It can also be used to store client_id in some cases
+ */
+ char text[GPS_NI_LONG_STRING_MAXLEN];
+
+ /**
+ * Client name decoding scheme
+ */
+ GpsNiEncodingType requestor_id_encoding;
+
+ /**
+ * Client name decoding scheme
+ */
+ GpsNiEncodingType text_encoding;
+
+ /**
+ * A pointer to extra data. Format:
+ * key_1 = value_1
+ * key_2 = value_2
+ */
+ char extras[GPS_NI_LONG_STRING_MAXLEN];
+
+} GpsNiNotification;
+
+/** Callback with NI notification.
+ * Can only be called from a thread created by create_thread_cb.
+ */
+typedef void (*gps_ni_notify_callback)(GpsNiNotification *notification);
+
+/** GPS NI callback structure. */
+typedef struct
+{
+ /**
+ * Sends the notification request from HAL to GPSLocationProvider.
+ */
+ gps_ni_notify_callback notify_cb;
+ gps_create_thread create_thread_cb;
+} GpsNiCallbacks;
+
+/**
+ * Extended interface for Network-initiated (NI) support.
+ */
+typedef struct
+{
+ /** set to sizeof(GpsNiInterface) */
+ size_t size;
+
+ /** Registers the callbacks for HAL to use. */
+ void (*init) (GpsNiCallbacks *callbacks);
+
+ /** Sends a response to HAL. */
+ void (*respond) (int notif_id, GpsUserResponseType user_response);
+} GpsNiInterface;
+
+struct gps_device_t {
+ struct hw_device_t common;
+
+ /**
+ * Set the provided lights to the provided values.
+ *
+ * Returns: 0 on succes, error code on failure.
+ */
+ const GpsInterface* (*get_gps_interface)(struct gps_device_t* dev);
+};
+
+#define AGPS_RIL_REQUEST_SETID_IMSI (1<<0L)
+#define AGPS_RIL_REQUEST_SETID_MSISDN (1<<1L)
+
+#define AGPS_RIL_REQUEST_REFLOC_CELLID (1<<0L)
+#define AGPS_RIL_REQUEST_REFLOC_MAC (1<<1L)
+
+typedef void (*agps_ril_request_set_id)(uint32_t flags);
+typedef void (*agps_ril_request_ref_loc)(uint32_t flags);
+
+typedef struct {
+ agps_ril_request_set_id request_setid;
+ agps_ril_request_ref_loc request_refloc;
+ gps_create_thread create_thread_cb;
+} AGpsRilCallbacks;
+
+/** Extended interface for AGPS_RIL support. */
+typedef struct {
+ /** set to sizeof(AGpsRilInterface) */
+ size_t size;
+ /**
+ * Opens the AGPS interface and provides the callback routines
+ * to the implemenation of this interface.
+ */
+ void (*init)( AGpsRilCallbacks* callbacks );
+
+ /**
+ * Sets the reference location.
+ */
+ void (*set_ref_location) (const AGpsRefLocation *agps_reflocation, size_t sz_struct);
+ /**
+ * Sets the set ID.
+ */
+ void (*set_set_id) (AGpsSetIDType type, const char* setid);
+
+ /**
+ * Send network initiated message.
+ */
+ void (*ni_message) (uint8_t *msg, size_t len);
+
+ /**
+ * Notify GPS of network status changes.
+ * These parameters match values in the android.net.NetworkInfo class.
+ */
+ void (*update_network_state) (int connected, int type, int roaming, const char* extra_info);
+
+ /**
+ * Notify GPS of network status changes.
+ * These parameters match values in the android.net.NetworkInfo class.
+ */
+ void (*update_network_availability) (int avaiable, const char* apn);
+} AGpsRilInterface;
+
+__END_DECLS
+
+#endif /* ANDROID_INCLUDE_HARDWARE_GPS_H */
+