summaryrefslogtreecommitdiff
path: root/gps/utils
diff options
context:
space:
mode:
authorIsaac Chen <isaacchen@isaacchen.cn>2018-07-13 10:12:35 +0800
committerIsaac Chen <isaacchen@isaacchen.cn>2018-07-13 00:03:17 +0000
commit6a15b2379f90ba4f9222fea0a5f8c12e8cecbae5 (patch)
tree6b1789235069c986567127aa57a51bbe4122e5ee /gps/utils
parent71ad0c9e5399aba0ac3cd20f1df41c9757cd6ca5 (diff)
wayne: Import GPS
* QC Tag: LA.UM.6.2.r1-06100-sdm660.0 Change-Id: I26da3b90caa473ed5f88408627463ec7f7655f23 Signed-off-by: Isaac Chen <isaacchen@isaacchen.cn>
Diffstat (limited to 'gps/utils')
-rw-r--r--gps/utils/Android.mk65
-rw-r--r--gps/utils/LocHeap.cpp354
-rw-r--r--gps/utils/LocHeap.h96
-rw-r--r--gps/utils/LocSharedLock.h59
-rw-r--r--gps/utils/LocThread.cpp266
-rw-r--r--gps/utils/LocThread.h92
-rw-r--r--gps/utils/LocTimer.cpp751
-rw-r--r--gps/utils/LocTimer.h74
-rw-r--r--gps/utils/Makefile.am64
-rw-r--r--gps/utils/MsgTask.cpp104
-rw-r--r--gps/utils/MsgTask.h67
-rw-r--r--gps/utils/configure.ac59
-rw-r--r--gps/utils/gps-utils.pc.in10
-rw-r--r--gps/utils/gps_extended.h106
-rw-r--r--gps/utils/gps_extended_c.h1290
-rw-r--r--gps/utils/linked_list.c324
-rw-r--r--gps/utils/linked_list.h217
-rw-r--r--gps/utils/loc_cfg.cpp400
-rw-r--r--gps/utils/loc_cfg.h91
-rw-r--r--gps/utils/loc_gps.h2209
-rw-r--r--gps/utils/loc_log.cpp237
-rw-r--r--gps/utils/loc_log.h71
-rw-r--r--gps/utils/loc_misc_utils.cpp114
-rw-r--r--gps/utils/loc_misc_utils.h99
-rw-r--r--gps/utils/loc_nmea.cpp1106
-rw-r--r--gps/utils/loc_nmea.h54
-rw-r--r--gps/utils/loc_target.cpp221
-rw-r--r--gps/utils/loc_target.h84
-rw-r--r--gps/utils/loc_timer.h73
-rw-r--r--gps/utils/log_util.h173
-rw-r--r--gps/utils/msg_q.c333
-rw-r--r--gps/utils/msg_q.h207
-rw-r--r--gps/utils/platform_lib_abstractions/Android.mk5
-rw-r--r--gps/utils/platform_lib_abstractions/elapsed_millis_since_boot.cpp46
-rw-r--r--gps/utils/platform_lib_abstractions/loc_pla/Android.mk5
-rw-r--r--gps/utils/platform_lib_abstractions/loc_pla/Makefile.am10
-rw-r--r--gps/utils/platform_lib_abstractions/loc_pla/configure.ac61
-rw-r--r--gps/utils/platform_lib_abstractions/loc_pla/include/platform_lib_gettid.h45
-rw-r--r--gps/utils/platform_lib_abstractions/loc_pla/include/platform_lib_includes.h39
-rw-r--r--gps/utils/platform_lib_abstractions/loc_pla/include/platform_lib_log_util.h174
-rw-r--r--gps/utils/platform_lib_abstractions/loc_pla/include/platform_lib_macros.h85
-rw-r--r--gps/utils/platform_lib_abstractions/loc_pla/include/platform_lib_property_service.h44
-rw-r--r--gps/utils/platform_lib_abstractions/loc_pla/include/platform_lib_sched_policy.h46
-rw-r--r--gps/utils/platform_lib_abstractions/loc_pla/include/platform_lib_time.h36
-rw-r--r--gps/utils/platform_lib_abstractions/loc_pla/loc-pla.pc.in10
-rw-r--r--gps/utils/platform_lib_abstractions/loc_pla/src/Android.mk68
-rw-r--r--gps/utils/platform_lib_abstractions/loc_pla/src/Makefile.am39
-rw-r--r--gps/utils/platform_lib_abstractions/loc_pla/src/platform_lib_gettid.cpp46
-rw-r--r--gps/utils/platform_lib_abstractions/loc_pla/src/platform_lib_log_util.cpp78
-rw-r--r--gps/utils/platform_lib_abstractions/loc_pla/src/platform_lib_property_service.cpp39
-rw-r--r--gps/utils/platform_lib_abstractions/loc_pla/src/platform_lib_sched_policy.cpp41
-rw-r--r--gps/utils/platform_lib_abstractions/loc_pla/src/platform_lib_time.cpp59
-rw-r--r--gps/utils/platform_lib_abstractions/loc_stub/Android.mk5
-rw-r--r--gps/utils/platform_lib_abstractions/loc_stub/Makefile.am9
-rw-r--r--gps/utils/platform_lib_abstractions/loc_stub/configure.ac67
-rw-r--r--gps/utils/platform_lib_abstractions/loc_stub/include/loc_stub_android_runtime.h45
-rw-r--r--gps/utils/platform_lib_abstractions/loc_stub/include/loc_stub_gettid.h44
-rw-r--r--gps/utils/platform_lib_abstractions/loc_stub/include/loc_stub_property_service.h42
-rw-r--r--gps/utils/platform_lib_abstractions/loc_stub/include/loc_stub_sched_policy.h64
-rw-r--r--gps/utils/platform_lib_abstractions/loc_stub/include/loc_stub_time.h46
-rw-r--r--gps/utils/platform_lib_abstractions/loc_stub/loc-stub.pc.in10
-rw-r--r--gps/utils/platform_lib_abstractions/loc_stub/src/Android.mk49
-rw-r--r--gps/utils/platform_lib_abstractions/loc_stub/src/Makefile.am40
-rw-r--r--gps/utils/platform_lib_abstractions/loc_stub/src/loc_stub_android_runtime.cpp41
-rw-r--r--gps/utils/platform_lib_abstractions/loc_stub/src/loc_stub_gettid.cpp37
-rw-r--r--gps/utils/platform_lib_abstractions/loc_stub/src/loc_stub_property_service.cpp42
-rw-r--r--gps/utils/platform_lib_abstractions/loc_stub/src/loc_stub_sched_policy.cpp50
-rw-r--r--gps/utils/platform_lib_abstractions/loc_stub/src/loc_stub_time.cpp55
68 files changed, 11092 insertions, 0 deletions
diff --git a/gps/utils/Android.mk b/gps/utils/Android.mk
new file mode 100644
index 0000000..3f3b83a
--- /dev/null
+++ b/gps/utils/Android.mk
@@ -0,0 +1,65 @@
+ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)
+ifneq ($(BUILD_TINY_ANDROID),true)
+#Compile this library only for builds with the latest modem image
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+
+## Libs
+LOCAL_SHARED_LIBRARIES := \
+ libutils \
+ libcutils \
+ liblog \
+ libloc_pla
+
+LOCAL_SRC_FILES += \
+ loc_log.cpp \
+ loc_cfg.cpp \
+ msg_q.c \
+ linked_list.c \
+ loc_target.cpp \
+ platform_lib_abstractions/elapsed_millis_since_boot.cpp \
+ LocHeap.cpp \
+ LocTimer.cpp \
+ LocThread.cpp \
+ MsgTask.cpp \
+ loc_misc_utils.cpp \
+ loc_nmea.cpp
+
+# Flag -std=c++11 is not accepted by compiler when LOCAL_CLANG is set to true
+LOCAL_CFLAGS += \
+ -fno-short-enums \
+ -D_ANDROID_
+
+ifeq ($(TARGET_BUILD_VARIANT),user)
+ LOCAL_CFLAGS += -DTARGET_BUILD_VARIANT_USER
+endif
+
+LOCAL_LDFLAGS += -Wl,--export-dynamic
+
+## Includes
+LOCAL_HEADER_LIBRARIES := \
+ libloc_pla_headers \
+ liblocation_api_headers
+
+LOCAL_MODULE := libgps.utils
+LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib
+LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_PRELINK_MODULE := false
+
+LOCAL_CFLAGS += $(GNSS_CFLAGS)
+
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libgps.utils_headers
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
+include $(BUILD_HEADER_LIBRARY)
+
+include $(addsuffix /Android.mk, $(addprefix $(LOCAL_PATH)/, platform_lib_abstractions))
+endif # not BUILD_TINY_ANDROID
+endif # BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE
diff --git a/gps/utils/LocHeap.cpp b/gps/utils/LocHeap.cpp
new file mode 100644
index 0000000..d667f14
--- /dev/null
+++ b/gps/utils/LocHeap.cpp
@@ -0,0 +1,354 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation, nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include <LocHeap.h>
+
+class LocHeapNode {
+ friend class LocHeap;
+
+ // size of of the subtree, excluding self, 1 if no subtree
+ int mSize;
+ LocHeapNode* mLeft;
+ LocHeapNode* mRight;
+ LocRankable* mData;
+public:
+ inline LocHeapNode(LocRankable& data) :
+ mSize(1), mLeft(NULL), mRight(NULL), mData(&data) {}
+ ~LocHeapNode();
+
+ // this only swaps the data of the two nodes, so no
+ // detach / re-attached is necessary
+ void swap(LocHeapNode& node);
+
+ LocRankable* detachData();
+
+ // push a node into the tree stucture, keeping sorted by rank
+ void push(LocHeapNode& node);
+
+ // pop the head node out of the tree stucture. keeping sorted by rank
+ static LocHeapNode* pop(LocHeapNode*& top);
+
+ // remove a specific node from the tree
+ // returns the pointer to the node removed, which would be either the
+ // same as input (if successfully removed); or NULL (if failed).
+ static LocHeapNode* remove(LocHeapNode*& top, LocRankable& data);
+
+ // convenience method to compare data ranking
+ inline bool outRanks(LocHeapNode& node) { return mData->outRanks(*node.mData); }
+ inline bool outRanks(LocRankable& data) { return mData->outRanks(data); }
+
+ // checks if mSize is correct, AND this node is the highest ranking
+ // of the entire subtree
+ bool checkNodes();
+
+ inline int getSize() { return mSize; }
+};
+
+inline
+LocHeapNode::~LocHeapNode() {
+ if (mLeft) {
+ delete mLeft;
+ mLeft = NULL;
+ }
+ if (mRight) {
+ delete mRight;
+ mRight = NULL;
+ }
+ if (mData) {
+ mData = NULL;
+ }
+}
+
+inline
+void LocHeapNode::swap(LocHeapNode& node) {
+ LocRankable* tmpData = node.mData;
+ node.mData = mData;
+ mData = tmpData;
+}
+
+inline
+LocRankable* LocHeapNode::detachData() {
+ LocRankable* data = mData;
+ mData = NULL;
+ return data;
+}
+
+// push keeps the tree sorted by rank, it also tries to balance the
+// tree by adding the new node to the smaller of the subtrees.
+// The pointer to the tree and internal links never change. If the
+// mData of tree top ranks lower than that of the incoming node,
+// mData will be swapped with that of the incoming node to ensure
+// ranking, no restructuring the container nodes.
+void LocHeapNode::push(LocHeapNode& node) {
+ // ensure the current node ranks higher than in the incoming one
+ if (node.outRanks(*this)) {
+ swap(node);
+ }
+
+ // now drop the new node (ensured lower than *this) into a subtree
+ if (NULL == mLeft) {
+ mLeft = &node;
+ } else if (NULL == mRight) {
+ mRight = &node;
+ } else if (mLeft->mSize <= mRight->mSize) {
+ mLeft->push(node);
+ } else {
+ mRight->push(node);
+ }
+ mSize++;
+}
+
+// pop keeps the tree sorted by rank, but it does not try to balance
+// the tree. It recursively swaps with the higher ranked top of the
+// subtrees.
+// The return is a popped out node from leaf level, that has the data
+// swapped all the way down from the top. The pinter to the tree and
+// internal links will not be changed or restructured, except for the
+// node that is popped out.
+// If the return pointer == this, this the last node in the tree.
+LocHeapNode* LocHeapNode::pop(LocHeapNode*& top) {
+ // we know the top has the highest ranking at this point, else
+ // the tree is broken. This top will be popped out. But we need
+ // a node from the left or right child, whichever ranks higher,
+ // to replace the current top. This then will need to be done
+ // recursively to the leaf level. So we swap the mData of the
+ // current top node all the way down to the leaf level.
+ LocHeapNode* poppedNode = top;
+ // top is losing a node in its subtree
+ top->mSize--;
+ if (top->mLeft || top->mRight) {
+ // if mLeft is NULL, mRight for sure is NOT NULL, take that;
+ // else if mRight is NULL, mLeft for sure is NOT, take that;
+ // else we take the address of whatever has higher ranking mData
+ LocHeapNode*& subTop = (NULL == top->mLeft) ? top->mRight :
+ ((NULL == top->mRight) ? top->mLeft :
+ (top->mLeft->outRanks(*(top->mRight)) ? top->mLeft : top->mRight));
+ // swap mData, the tree top gets updated with the new data.
+ top->swap(*subTop);
+ // pop out from the subtree
+ poppedNode = pop(subTop);
+ } else {
+ // if the top has only single node
+ // detach the poppedNode from the tree
+ // subTop is the reference of ether mLeft or mRight
+ // NOT a local stack pointer. so it MUST be NULL'ed here.
+ top = NULL;
+ }
+
+ return poppedNode;
+}
+
+// navigating through the tree and find the node that hass the input
+// data. Since this is a heap, we do recursive linear search.
+// returns the pointer to the node removed, which would be either the
+// same as input (if successfully removed); or NULL (if failed).
+LocHeapNode* LocHeapNode::remove(LocHeapNode*& top, LocRankable& data) {
+ LocHeapNode* removedNode = NULL;
+ // this is the node, by address
+ if (&data == (LocRankable*)(top->mData)) {
+ // pop this node out
+ removedNode = pop(top);
+ } else if (!data.outRanks(*top->mData)) {
+ // subtrees might have this node
+ if (top->mLeft) {
+ removedNode = remove(top->mLeft, data);
+ }
+ // if we did not find in mLeft, and mRight is not empty
+ if (!removedNode && top->mRight) {
+ removedNode = remove(top->mRight, data);
+ }
+
+ // top lost a node in its subtree
+ if (removedNode) {
+ top->mSize--;
+ }
+ }
+
+ return removedNode;
+}
+
+// checks if mSize is correct, AND this node is the highest ranking
+// of the entire subtree
+bool LocHeapNode::checkNodes() {
+ // size of the current subtree
+ int totalSize = mSize;
+ if (mLeft) {
+ // check the consistency of left subtree
+ if (mLeft->outRanks(*this) || !mLeft->checkNodes()) {
+ return false;
+ }
+ // subtract the size of left subtree (with subtree head)
+ totalSize -= mLeft->mSize;
+ }
+
+ if (mRight) {
+ // check the consistency of right subtree
+ if (mRight->outRanks(*this) || !mRight->checkNodes()) {
+ return false;
+ }
+ // subtract the size of right subtree (with subtree head)
+ totalSize -= mRight->mSize;
+ }
+
+ // for the tree nodes to consistent, totalSize must be 1 now
+ return totalSize == 1;
+}
+
+LocHeap::~LocHeap() {
+ if (mTree) {
+ delete mTree;
+ }
+}
+
+void LocHeap::push(LocRankable& node) {
+ LocHeapNode* heapNode = new LocHeapNode(node);
+ if (!mTree) {
+ mTree = heapNode;
+ } else {
+ mTree->push(*heapNode);
+ }
+}
+
+LocRankable* LocHeap::peek() {
+ LocRankable* top = NULL;
+ if (mTree) {
+ top = mTree->mData;
+ }
+ return top;
+}
+
+LocRankable* LocHeap::pop() {
+ LocRankable* locNode = NULL;
+ if (mTree) {
+ // mTree may become NULL after this call
+ LocHeapNode* heapNode = LocHeapNode::pop(mTree);
+ locNode = heapNode->detachData();
+ delete heapNode;
+ }
+ return locNode;
+}
+
+LocRankable* LocHeap::remove(LocRankable& rankable) {
+ LocRankable* locNode = NULL;
+ if (mTree) {
+ // mTree may become NULL after this call
+ LocHeapNode* heapNode = LocHeapNode::remove(mTree, rankable);
+ if (heapNode) {
+ locNode = heapNode->detachData();
+ delete heapNode;
+ }
+ }
+ return locNode;
+}
+
+#ifdef __LOC_UNIT_TEST__
+bool LocHeap::checkTree() {
+ return ((NULL == mTree) || mTree->checkNodes());
+}
+uint32_t LocHeap::getTreeSize() {
+ return (NULL == mTree) ? 0 : mTree->getSize();
+}
+#endif
+
+#ifdef __LOC_DEBUG__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+class LocHeapDebug : public LocHeap {
+public:
+ bool checkTree() {
+ return ((NULL == mTree) || mTree->checkNodes());
+ }
+
+ uint32_t getTreeSize() {
+ return (NULL == mTree) ? 0 : (mTree->getSize());
+ }
+};
+
+class LocHeapDebugData : public LocRankable {
+ const int mID;
+public:
+ LocHeapDebugData(int id) : mID(id) {}
+ inline virtual int ranks(LocRankable& rankable) {
+ LocHeapDebugData* testData = dynamic_cast<LocHeapDebugData*>(&rankable);
+ return testData->mID - mID;
+ }
+};
+
+// For Linux command line testing:
+// compilation: g++ -D__LOC_HOST_DEBUG__ -D__LOC_DEBUG__ -g -I. -I../../../../vendor/qcom/proprietary/gps-internal/unit-tests/fakes_for_host -I../../../../system/core/include LocHeap.cpp
+// test: valgrind --leak-check=full ./a.out 100
+int main(int argc, char** argv) {
+ srand(time(NULL));
+ int tries = atoi(argv[1]);
+ int checks = tries >> 3;
+ LocHeapDebug heap;
+ int treeSize = 0;
+
+ for (int i = 0; i < tries; i++) {
+ if (i % checks == 0 && !heap.checkTree()) {
+ printf("tree check failed before %dth op\n", i);
+ }
+ int r = rand();
+
+ if (r & 1) {
+ LocHeapDebugData* data = new LocHeapDebugData(r >> 1);
+ heap.push(dynamic_cast<LocRankable&>(*data));
+ treeSize++;
+ } else {
+ LocRankable* rankable = heap.pop();
+ if (rankable) {
+ delete rankable;
+ }
+ treeSize ? treeSize-- : 0;
+ }
+
+ printf("%s: %d == %d\n", (r&1)?"push":"pop", treeSize, heap.getTreeSize());
+ if (treeSize != heap.getTreeSize()) {
+ printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
+ tries = i+1;
+ break;
+ }
+ }
+
+ if (!heap.checkTree()) {
+ printf("!!!!!!!!!!tree check failed at the end after %d ops!!!!!!!\n", tries);
+ } else {
+ printf("success!\n");
+ }
+
+ for (LocRankable* data = heap.pop(); NULL != data; data = heap.pop()) {
+ delete data;
+ }
+
+ return 0;
+}
+
+#endif
diff --git a/gps/utils/LocHeap.h b/gps/utils/LocHeap.h
new file mode 100644
index 0000000..b491948
--- /dev/null
+++ b/gps/utils/LocHeap.h
@@ -0,0 +1,96 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation, nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef __LOC_HEAP__
+#define __LOC_HEAP__
+
+#include <stddef.h>
+#include <string.h>
+
+// abstract class to be implemented by client to provide a rankable class
+class LocRankable {
+public:
+ virtual inline ~LocRankable() {}
+
+ // method to rank objects of such type for sorting purposes.
+ // The pointer of the input node would be stored in the heap.
+ // >0 if ranks higher than the input;
+ // ==0 if equally ranks with the input;
+ // <0 if ranks lower than the input
+ virtual int ranks(LocRankable& rankable) = 0;
+
+ // convenient method to rank objects of such type for sorting purposes.
+ inline bool outRanks(LocRankable& rankable) { return ranks(rankable) > 0; }
+};
+
+// opaque class to provide service implementation.
+class LocHeapNode;
+
+// a heap whose left and right children are not sorted. It is sorted only vertically,
+// i.e. parent always ranks higher than children, if they exist. Ranking algorithm is
+// implemented in Rankable. The reason that there is no sort between children is to
+// help beter balance the tree with lower cost. When a node is pushed to the tree,
+// it is guaranteed that the subtree that is smaller gets to have the new node.
+class LocHeap {
+protected:
+ LocHeapNode* mTree;
+public:
+ inline LocHeap() : mTree(NULL) {}
+ ~LocHeap();
+
+ // push keeps the tree sorted by rank, it also tries to balance the
+ // tree by adding the new node to the smaller of the subtrees.
+ // node is reference to an obj that is managed by client, that client
+ // creates and destroyes. The destroy should happen after the
+ // node is popped out from the heap.
+ void push(LocRankable& node);
+
+ // Peeks the node data on tree top, which has currently the highest ranking
+ // There is no change the tree structure with this operation
+ // Returns NULL if the tree is empty, otherwise pointer to the node data of
+ // the tree top.
+ LocRankable* peek();
+
+ // pop keeps the tree sorted by rank, but it does not try to balance
+ // the tree.
+ // Return - pointer to the node popped out, or NULL if heap is already empty
+ LocRankable* pop();
+
+ // navigating through the tree and find the node that ranks the same
+ // as the input data, then remove it from the tree. Rank is implemented
+ // by rankable obj.
+ // returns the pointer to the node removed; or NULL (if failed).
+ LocRankable* remove(LocRankable& rankable);
+
+#ifdef __LOC_UNIT_TEST__
+ bool checkTree();
+ uint32_t getTreeSize();
+#endif
+};
+
+#endif //__LOC_HEAP__
diff --git a/gps/utils/LocSharedLock.h b/gps/utils/LocSharedLock.h
new file mode 100644
index 0000000..7fe6237
--- /dev/null
+++ b/gps/utils/LocSharedLock.h
@@ -0,0 +1,59 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation, nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef __LOC_SHARED_LOCK__
+#define __LOC_SHARED_LOCK__
+
+#include <stddef.h>
+#include <cutils/atomic.h>
+#include <pthread.h>
+
+// This is a utility created for use cases such that there are more than
+// one client who need to share the same lock, but it is not predictable
+// which of these clients is to last to go away. This shared lock deletes
+// itself when the last client calls its drop() method. To add a cient,
+// this share lock's share() method has to be called, so that the obj
+// can maintain an accurate client count.
+class LocSharedLock {
+ volatile int32_t mRef;
+ pthread_mutex_t mMutex;
+ inline ~LocSharedLock() { pthread_mutex_destroy(&mMutex); }
+public:
+ // first client to create this LockSharedLock
+ inline LocSharedLock() : mRef(1) { pthread_mutex_init(&mMutex, NULL); }
+ // following client(s) are to *share()* this lock created by the first client
+ inline LocSharedLock* share() { android_atomic_inc(&mRef); return this; }
+ // whe a client no longer needs this shared lock, drop() shall be called.
+ inline void drop() { if (1 == android_atomic_dec(&mRef)) delete this; }
+ // locking the lock to enter critical section
+ inline void lock() { pthread_mutex_lock(&mMutex); }
+ // unlocking the lock to leave the critical section
+ inline void unlock() { pthread_mutex_unlock(&mMutex); }
+};
+
+#endif //__LOC_SHARED_LOCK__
diff --git a/gps/utils/LocThread.cpp b/gps/utils/LocThread.cpp
new file mode 100644
index 0000000..d112f61
--- /dev/null
+++ b/gps/utils/LocThread.cpp
@@ -0,0 +1,266 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation, nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include <LocThread.h>
+#include <string.h>
+#include <pthread.h>
+#include <platform_lib_macros.h>
+
+class LocThreadDelegate {
+ LocRunnable* mRunnable;
+ bool mJoinable;
+ pthread_t mThandle;
+ pthread_mutex_t mMutex;
+ int mRefCount;
+ ~LocThreadDelegate();
+ LocThreadDelegate(LocThread::tCreate creator, const char* threadName,
+ LocRunnable* runnable, bool joinable);
+ void destroy();
+public:
+ static LocThreadDelegate* create(LocThread::tCreate creator,
+ const char* threadName, LocRunnable* runnable, bool joinable);
+ void stop();
+ // bye() is for the parent thread to go away. if joinable,
+ // parent must stop the spawned thread, join, and then
+ // destroy(); if detached, the parent can go straight
+ // ahead to destroy()
+ inline void bye() { mJoinable ? stop() : destroy(); }
+ inline bool isRunning() { return (NULL != mRunnable); }
+ static void* threadMain(void* arg);
+};
+
+// it is important to note that internal members must be
+// initialized to values as if pthread_create succeeds.
+// This is to avoid the race condition between the threads,
+// once the thread is created, some of these values will
+// be check in the spawned thread, and must set correctly
+// then and there.
+// However, upon pthread_create failure, the data members
+// must be set to indicate failure, e.g. mRunnable, and
+// threashold approprietly for destroy(), e.g. mRefCount.
+LocThreadDelegate::LocThreadDelegate(LocThread::tCreate creator,
+ const char* threadName, LocRunnable* runnable, bool joinable) :
+ mRunnable(runnable), mJoinable(joinable), mThandle((pthread_t)NULL),
+ mMutex(PTHREAD_MUTEX_INITIALIZER), mRefCount(2) {
+
+ // set up thread name, if nothing is passed in
+ if (!threadName) {
+ threadName = "LocThread";
+ }
+
+ // create the thread here, then if successful
+ // and a name is given, we set the thread name
+ if (creator) {
+ mThandle = creator(threadName, threadMain, this);
+ } else if (pthread_create(&mThandle, NULL, threadMain, this)) {
+ // pthread_create() failed
+ mThandle = (pthread_t)NULL;
+ }
+
+ if (mThandle) {
+ // set thread name
+ char lname[16];
+ int len = (sizeof(lname)>sizeof(threadName)) ?
+ (sizeof(threadName) -1):(sizeof(lname) - 1);
+ memcpy(lname, threadName, len);
+ lname[len] = 0;
+ // set the thread name here
+ pthread_setname_np(mThandle, lname);
+
+ // detach, if not joinable
+ if (!joinable) {
+ pthread_detach(mThandle);
+ }
+ } else {
+ // must set these values upon failure
+ mRunnable = NULL;
+ mJoinable = false;
+ mRefCount = 1;
+ }
+}
+
+inline
+LocThreadDelegate::~LocThreadDelegate() {
+ // at this point nothing should need done any more
+}
+
+// factory method so that we could return NULL upon failure
+LocThreadDelegate* LocThreadDelegate::create(LocThread::tCreate creator,
+ const char* threadName, LocRunnable* runnable, bool joinable) {
+ LocThreadDelegate* thread = NULL;
+ if (runnable) {
+ thread = new LocThreadDelegate(creator, threadName, runnable, joinable);
+ if (thread && !thread->isRunning()) {
+ thread->destroy();
+ thread = NULL;
+ }
+ }
+
+ return thread;
+}
+
+// The order is importang
+// NULLing mRunnalbe stops the while loop in threadMain()
+// join() if mJoinble must come before destroy() call, as
+// the obj must remain alive at this time so that mThandle
+// remains valud.
+void LocThreadDelegate::stop() {
+ // mRunnable and mJoinable are reset on different triggers.
+ // mRunnable may get nulled on the spawned thread's way out;
+ // or here.
+ // mJouinable (if ever been true) gets falsed when client
+ // thread triggers stop, with either a stop()
+ // call or the client releases thread obj handle.
+ if (mRunnable) {
+ mRunnable = NULL;
+ }
+ if (mJoinable) {
+ mJoinable = false;
+ pthread_join(mThandle, NULL);
+ }
+ // call destroy() to possibly delete the obj
+ destroy();
+}
+
+// method for clients to call to release the obj
+// when it is a detached thread, the client thread
+// and the spawned thread can both try to destroy()
+// asynchronously. And we delete this obj when
+// mRefCount becomes 0.
+void LocThreadDelegate::destroy() {
+ // else case shouldn't happen, unless there is a
+ // leaking obj. But only our code here has such
+ // obj, so if we test our code well, else case
+ // will never happen
+ if (mRefCount > 0) {
+ // we need a flag on the stack
+ bool callDelete = false;
+
+ // critical section between threads
+ pthread_mutex_lock(&mMutex);
+ // last destroy() call
+ callDelete = (1 == mRefCount--);
+ pthread_mutex_unlock(&mMutex);
+
+ // upon last destroy() call we delete this obj
+ if (callDelete) {
+ delete this;
+ }
+ }
+}
+
+void* LocThreadDelegate::threadMain(void* arg) {
+ LocThreadDelegate* locThread = (LocThreadDelegate*)(arg);
+
+ if (locThread) {
+ LocRunnable* runnable = locThread->mRunnable;
+
+ if (runnable) {
+ if (locThread->isRunning()) {
+ runnable->prerun();
+ }
+
+ while (locThread->isRunning() && runnable->run());
+
+ if (locThread->isRunning()) {
+ runnable->postrun();
+ }
+
+ // at this time, locThread->mRunnable may or may not be NULL
+ // NULL it just to be safe and clean, as we want the field
+ // in the released memory slot to be NULL.
+ locThread->mRunnable = NULL;
+ delete runnable;
+ }
+ locThread->destroy();
+ }
+
+ return NULL;
+}
+
+LocThread::~LocThread() {
+ if (mThread) {
+ mThread->bye();
+ mThread = NULL;
+ }
+}
+
+bool LocThread::start(tCreate creator, const char* threadName, LocRunnable* runnable, bool joinable) {
+ bool success = false;
+ if (!mThread) {
+ mThread = LocThreadDelegate::create(creator, threadName, runnable, joinable);
+ // true only if thread is created successfully
+ success = (NULL != mThread);
+ }
+ return success;
+}
+
+void LocThread::stop() {
+ if (mThread) {
+ mThread->stop();
+ mThread = NULL;
+ }
+}
+
+#ifdef __LOC_DEBUG__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+class LocRunnableTest1 : public LocRunnable {
+ int mID;
+public:
+ LocRunnableTest1(int id) : LocRunnable(), mID(id) {}
+ virtual bool run() {
+ printf("LocRunnableTest1: %d\n", mID++);
+ sleep(1);
+ return true;
+ }
+};
+
+// on linux command line:
+// compile: g++ -D__LOC_HOST_DEBUG__ -D__LOC_DEBUG__ -g -std=c++0x -I. -I../../../../vendor/qcom/proprietary/gps-internal/unit-tests/fakes_for_host -I../../../../system/core/include -lpthread LocThread.cpp
+// test detached thread: valgrind ./a.out 0
+// test joinable thread: valgrind ./a.out 1
+int main(int argc, char** argv) {
+ LocRunnableTest1 test(10);
+
+ LocThread thread;
+ thread.start("LocThreadTest", test, atoi(argv[1]));
+
+ sleep(10);
+
+ thread.stop();
+
+ sleep(5);
+
+ return 0;
+}
+
+#endif
diff --git a/gps/utils/LocThread.h b/gps/utils/LocThread.h
new file mode 100644
index 0000000..2a65d8f
--- /dev/null
+++ b/gps/utils/LocThread.h
@@ -0,0 +1,92 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation, nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef __LOC_THREAD__
+#define __LOC_THREAD__
+
+#include <stddef.h>
+#include <pthread.h>
+
+// abstract class to be implemented by client to provide a runnable class
+// which gets scheduled by LocThread
+class LocRunnable {
+public:
+ inline LocRunnable() {}
+ inline virtual ~LocRunnable() {}
+
+ // The method to be implemented by thread clients
+ // and be scheduled by LocThread
+ // This method will be repeated called until it returns false; or
+ // until thread is stopped.
+ virtual bool run() = 0;
+
+ // The method to be run before thread loop (conditionally repeatedly)
+ // calls run()
+ inline virtual void prerun() {}
+
+ // The method to be run after thread loop (conditionally repeatedly)
+ // calls run()
+ inline virtual void postrun() {}
+};
+
+// opaque class to provide service implementation.
+class LocThreadDelegate;
+
+// A utility class to create a thread and run LocRunnable
+// caller passes in.
+class LocThread {
+ LocThreadDelegate* mThread;
+public:
+ inline LocThread() : mThread(NULL) {}
+ virtual ~LocThread();
+
+ typedef pthread_t (*tCreate)(const char* name, void* (*start)(void*), void* arg);
+ // client starts thread with a runnable, which implements
+ // the logics to fun in the created thread context.
+ // The thread could be either joinable or detached.
+ // runnable is an obj managed by client. Client creates and
+ // frees it (but must be after stop() is called, or
+ // this LocThread obj is deleted).
+ // The obj will be deleted by LocThread if start()
+ // returns true. Else it is client's responsibility
+ // to delete the object
+ // Returns 0 if success; false if failure.
+ bool start(tCreate creator, const char* threadName, LocRunnable* runnable, bool joinable = true);
+ inline bool start(const char* threadName, LocRunnable* runnable, bool joinable = true) {
+ return start(NULL, threadName, runnable, joinable);
+ }
+
+ // NOTE: if this is a joinable thread, this stop may block
+ // for a while until the thread is joined.
+ void stop();
+
+ // thread status check
+ inline bool isRunning() { return NULL != mThread; }
+};
+
+#endif //__LOC_THREAD__
diff --git a/gps/utils/LocTimer.cpp b/gps/utils/LocTimer.cpp
new file mode 100644
index 0000000..5b653eb
--- /dev/null
+++ b/gps/utils/LocTimer.cpp
@@ -0,0 +1,751 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation, nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <errno.h>
+#include <loc_timer.h>
+#include <sys/timerfd.h>
+#include <sys/epoll.h>
+#include <LocTimer.h>
+#include <LocHeap.h>
+#include <LocThread.h>
+#include <LocSharedLock.h>
+#include <MsgTask.h>
+
+#ifdef __HOST_UNIT_TEST__
+#define EPOLLWAKEUP 0
+#define CLOCK_BOOTTIME CLOCK_MONOTONIC
+#define CLOCK_BOOTTIME_ALARM CLOCK_MONOTONIC
+#endif
+
+/*
+There are implementations of 5 classes in this file:
+LocTimer, LocTimerDelegate, LocTimerContainer, LocTimerPollTask, LocTimerWrapper
+
+LocTimer - client front end, interface for client to start / stop timers, also
+ to provide a callback.
+LocTimerDelegate - an internal timer entity, which also is a LocRankable obj.
+ Its life cycle is different than that of LocTimer. It gets
+ created when LocTimer::start() is called, and gets deleted
+ when it expires or clients calls the hosting LocTimer obj's
+ stop() method. When a LocTimerDelegate obj is ticking, it
+ stays in the corresponding LocTimerContainer. When expired
+ or stopped, the obj is removed from the container. Since it
+ is also a LocRankable obj, and LocTimerContainer also is a
+ heap, its ranks() implementation decides where it is placed
+ in the heap.
+LocTimerContainer - core of the timer service. It is a container (derived from
+ LocHeap) for LocTimerDelegate (implements LocRankable) objs.
+ There are 2 of such containers, one for sw timers (or Linux
+ timers) one for hw timers (or Linux alarms). It adds one of
+ each (those that expire the soonest) to kernel via services
+ provided by LocTimerPollTask. All the heap management on the
+ LocTimerDelegate objs are done in the MsgTask context, such
+ that synchronization is ensured.
+LocTimerPollTask - is a class that wraps timerfd and epoll POXIS APIs. It also
+ both implements LocRunnalbe with epoll_wait() in the run()
+ method. It is also a LocThread client, so as to loop the run
+ method.
+LocTimerWrapper - a LocTimer client itself, to implement the existing C API with
+ APIs, loc_timer_start() and loc_timer_stop().
+
+*/
+
+class LocTimerPollTask;
+
+// This is a multi-functaional class that:
+// * extends the LocHeap class for the detection of head update upon add / remove
+// events. When that happens, soonest time out changes, so timerfd needs update.
+// * contains the timers, and add / remove them into the heap
+// * provides and maps 2 of such containers, one for timers (or mSwTimers), one
+// for alarms (or mHwTimers);
+// * provides a polling thread;
+// * provides a MsgTask thread for synchronized add / remove / timer client callback.
+class LocTimerContainer : public LocHeap {
+ // mutex to synchronize getters of static members
+ static pthread_mutex_t mMutex;
+ // Container of timers
+ static LocTimerContainer* mSwTimers;
+ // Container of alarms
+ static LocTimerContainer* mHwTimers;
+ // Msg task to provider msg Q, sender and reader.
+ static MsgTask* mMsgTask;
+ // Poll task to provide epoll call and threading to poll.
+ static LocTimerPollTask* mPollTask;
+ // timer / alarm fd
+ int mDevFd;
+ // ctor
+ LocTimerContainer(bool wakeOnExpire);
+ // dtor
+ ~LocTimerContainer();
+ static MsgTask* getMsgTaskLocked();
+ static LocTimerPollTask* getPollTaskLocked();
+ // extend LocHeap and pop if the top outRanks input
+ LocTimerDelegate* popIfOutRanks(LocTimerDelegate& timer);
+ // update the timer POSIX calls with updated soonest timer spec
+ void updateSoonestTime(LocTimerDelegate* priorTop);
+
+public:
+ // factory method to control the creation of mSwTimers / mHwTimers
+ static LocTimerContainer* get(bool wakeOnExpire);
+
+ LocTimerDelegate* getSoonestTimer();
+ int getTimerFd();
+ // add a timer / alarm obj into the container
+ void add(LocTimerDelegate& timer);
+ // remove a timer / alarm obj from the container
+ void remove(LocTimerDelegate& timer);
+ // handling of timer / alarm expiration
+ void expire();
+};
+
+// This class implements the polling thread that epolls imer / alarm fds.
+// The LocRunnable::run() contains the actual polling. The other methods
+// will be run in the caller's thread context to add / remove timer / alarm
+// fds the kernel, while the polling is blocked on epoll_wait() call.
+// Since the design is that we have maximally 2 polls, one for all the
+// timers; one for all the alarms, we will poll at most on 2 fds. But it
+// is possile that all we have are only timers or alarms at one time, so we
+// allow dynamically add / remove fds we poll on. The design decision of
+// having 1 fd per container of timer / alarm is such that, we may not need
+// to make a system call each time a timer / alarm is added / removed, unless
+// that changes the "soonest" time out of that of all the timers / alarms.
+class LocTimerPollTask : public LocRunnable {
+ // the epoll fd
+ const int mFd;
+ // the thread that calls run() method
+ LocThread* mThread;
+ friend class LocThreadDelegate;
+ // dtor
+ ~LocTimerPollTask();
+public:
+ // ctor
+ LocTimerPollTask();
+ // this obj will be deleted once thread is deleted
+ void destroy();
+ // add a container of timers. Each contain has a unique device fd, i.e.
+ // either timer or alarm fd, and a heap of timers / alarms. It is expected
+ // that container would have written to the device fd with the soonest
+ // time out value in the heap at the time of calling this method. So all
+ // this method does is to add the fd of the input container to the poll
+ // and also add the pointer of the container to the event data ptr, such
+ // when poll_wait wakes up on events, we know who is the owner of the fd.
+ void addPoll(LocTimerContainer& timerContainer);
+ // remove a fd that is assciated with a container. The expectation is that
+ // the atual timer would have been removed from the container.
+ void removePoll(LocTimerContainer& timerContainer);
+ // The polling thread context will call this method. This is where
+ // epoll_wait() is blocking and waiting for events..
+ virtual bool run();
+};
+
+// Internal class of timer obj. It gets born when client calls LocTimer::start();
+// and gets deleted when client calls LocTimer::stop() or when the it expire()'s.
+// This class implements LocRankable::ranks() so that when an obj is added into
+// the container (of LocHeap), it gets placed in sorted order.
+class LocTimerDelegate : public LocRankable {
+ friend class LocTimerContainer;
+ friend class LocTimer;
+ LocTimer* mClient;
+ LocSharedLock* mLock;
+ struct timespec mFutureTime;
+ LocTimerContainer* mContainer;
+ // not a complete obj, just ctor for LocRankable comparisons
+ inline LocTimerDelegate(struct timespec& delay)
+ : mClient(NULL), mLock(NULL), mFutureTime(delay), mContainer(NULL) {}
+ inline ~LocTimerDelegate() { if (mLock) { mLock->drop(); mLock = NULL; } }
+public:
+ LocTimerDelegate(LocTimer& client, struct timespec& futureTime, LocTimerContainer* container);
+ void destroyLocked();
+ // LocRankable virtual method
+ virtual int ranks(LocRankable& rankable);
+ void expire();
+ inline struct timespec getFutureTime() { return mFutureTime; }
+};
+
+/***************************LocTimerContainer methods***************************/
+
+// Most of these static recources are created on demand. They however are never
+// destoyed. The theory is that there are processes that link to this util lib
+// but never use timer, then these resources would never need to be created.
+// For those processes that do use timer, it will likely also need to every
+// once in a while. It might be cheaper keeping them around.
+pthread_mutex_t LocTimerContainer::mMutex = PTHREAD_MUTEX_INITIALIZER;
+LocTimerContainer* LocTimerContainer::mSwTimers = NULL;
+LocTimerContainer* LocTimerContainer::mHwTimers = NULL;
+MsgTask* LocTimerContainer::mMsgTask = NULL;
+LocTimerPollTask* LocTimerContainer::mPollTask = NULL;
+
+// ctor - initialize timer heaps
+// A container for swTimer (timer) is created, when wakeOnExpire is true; or
+// HwTimer (alarm), when wakeOnExpire is false.
+LocTimerContainer::LocTimerContainer(bool wakeOnExpire) :
+ mDevFd(timerfd_create(wakeOnExpire ? CLOCK_BOOTTIME_ALARM : CLOCK_BOOTTIME, 0)) {
+
+ if ((-1 == mDevFd) && (errno == EINVAL)) {
+ LOC_LOGW("%s: timerfd_create failure, fallback to CLOCK_MONOTONIC - %s",
+ __FUNCTION__, strerror(errno));
+ mDevFd = timerfd_create(CLOCK_MONOTONIC, 0);
+ }
+
+ if (-1 != mDevFd) {
+ // ensure we have the necessary resources created
+ LocTimerContainer::getPollTaskLocked();
+ LocTimerContainer::getMsgTaskLocked();
+ } else {
+ LOC_LOGE("%s: timerfd_create failure - %s", __FUNCTION__, strerror(errno));
+ }
+}
+
+// dtor
+// we do not ever destroy the static resources.
+inline
+LocTimerContainer::~LocTimerContainer() {
+ close(mDevFd);
+}
+
+LocTimerContainer* LocTimerContainer::get(bool wakeOnExpire) {
+ // get the reference of either mHwTimer or mSwTimers per wakeOnExpire
+ LocTimerContainer*& container = wakeOnExpire ? mHwTimers : mSwTimers;
+ // it is cheap to check pointer first than locking mutext unconditionally
+ if (!container) {
+ pthread_mutex_lock(&mMutex);
+ // let's check one more time to be safe
+ if (!container) {
+ container = new LocTimerContainer(wakeOnExpire);
+ // timerfd_create failure
+ if (-1 == container->getTimerFd()) {
+ delete container;
+ container = NULL;
+ }
+ }
+ pthread_mutex_unlock(&mMutex);
+ }
+ return container;
+}
+
+MsgTask* LocTimerContainer::getMsgTaskLocked() {
+ // it is cheap to check pointer first than locking mutext unconditionally
+ if (!mMsgTask) {
+ mMsgTask = new MsgTask("LocTimerMsgTask", false);
+ }
+ return mMsgTask;
+}
+
+LocTimerPollTask* LocTimerContainer::getPollTaskLocked() {
+ // it is cheap to check pointer first than locking mutext unconditionally
+ if (!mPollTask) {
+ mPollTask = new LocTimerPollTask();
+ }
+ return mPollTask;
+}
+
+inline
+LocTimerDelegate* LocTimerContainer::getSoonestTimer() {
+ return (LocTimerDelegate*)(peek());
+}
+
+inline
+int LocTimerContainer::getTimerFd() {
+ return mDevFd;
+}
+
+void LocTimerContainer::updateSoonestTime(LocTimerDelegate* priorTop) {
+ LocTimerDelegate* curTop = getSoonestTimer();
+
+ // check if top has changed
+ if (curTop != priorTop) {
+ struct itimerspec delay;
+ memset(&delay, 0, sizeof(struct itimerspec));
+ bool toSetTime = false;
+ // if tree is empty now, we remove poll and disarm timer
+ if (!curTop) {
+ mPollTask->removePoll(*this);
+ // setting the values to disarm timer
+ delay.it_value.tv_sec = 0;
+ delay.it_value.tv_nsec = 0;
+ toSetTime = true;
+ } else if (!priorTop || curTop->outRanks(*priorTop)) {
+ // do this first to avoid race condition, in case settime is called
+ // with too small an interval
+ mPollTask->addPoll(*this);
+ delay.it_value = curTop->getFutureTime();
+ toSetTime = true;
+ }
+ if (toSetTime) {
+ timerfd_settime(getTimerFd(), TFD_TIMER_ABSTIME, &delay, NULL);
+ }
+ }
+}
+
+// all the heap management is done in the MsgTask context.
+inline
+void LocTimerContainer::add(LocTimerDelegate& timer) {
+ struct MsgTimerPush : public LocMsg {
+ LocTimerContainer* mTimerContainer;
+ LocHeapNode* mTree;
+ LocTimerDelegate* mTimer;
+ inline MsgTimerPush(LocTimerContainer& container, LocTimerDelegate& timer) :
+ LocMsg(), mTimerContainer(&container), mTimer(&timer) {}
+ inline virtual void proc() const {
+ LocTimerDelegate* priorTop = mTimerContainer->getSoonestTimer();
+ mTimerContainer->push((LocRankable&)(*mTimer));
+ mTimerContainer->updateSoonestTime(priorTop);
+ }
+ };
+
+ mMsgTask->sendMsg(new MsgTimerPush(*this, timer));
+}
+
+// all the heap management is done in the MsgTask context.
+void LocTimerContainer::remove(LocTimerDelegate& timer) {
+ struct MsgTimerRemove : public LocMsg {
+ LocTimerContainer* mTimerContainer;
+ LocTimerDelegate* mTimer;
+ inline MsgTimerRemove(LocTimerContainer& container, LocTimerDelegate& timer) :
+ LocMsg(), mTimerContainer(&container), mTimer(&timer) {}
+ inline virtual void proc() const {
+ LocTimerDelegate* priorTop = mTimerContainer->getSoonestTimer();
+
+ // update soonest timer only if mTimer is actually removed from
+ // mTimerContainer AND mTimer is not priorTop.
+ if (priorTop == ((LocHeap*)mTimerContainer)->remove((LocRankable&)*mTimer)) {
+ // if passing in NULL, we tell updateSoonestTime to update
+ // kernel with the current top timer interval.
+ mTimerContainer->updateSoonestTime(NULL);
+ }
+ // all timers are deleted here, and only here.
+ delete mTimer;
+ }
+ };
+
+ mMsgTask->sendMsg(new MsgTimerRemove(*this, timer));
+}
+
+// all the heap management is done in the MsgTask context.
+// Upon expire, we check and continuously pop the heap until
+// the top node's timeout is in the future.
+void LocTimerContainer::expire() {
+ struct MsgTimerExpire : public LocMsg {
+ LocTimerContainer* mTimerContainer;
+ inline MsgTimerExpire(LocTimerContainer& container) :
+ LocMsg(), mTimerContainer(&container) {}
+ inline virtual void proc() const {
+ struct timespec now;
+ // get time spec of now
+ clock_gettime(CLOCK_BOOTTIME, &now);
+ LocTimerDelegate timerOfNow(now);
+ // pop everything in the heap that outRanks now, i.e. has time older than now
+ // and then call expire() on that timer.
+ for (LocTimerDelegate* timer = (LocTimerDelegate*)mTimerContainer->pop();
+ NULL != timer;
+ timer = mTimerContainer->popIfOutRanks(timerOfNow)) {
+ // the timer delegate obj will be deleted before the return of this call
+ timer->expire();
+ }
+ mTimerContainer->updateSoonestTime(NULL);
+ }
+ };
+
+ struct itimerspec delay;
+ memset(&delay, 0, sizeof(struct itimerspec));
+ timerfd_settime(getTimerFd(), TFD_TIMER_ABSTIME, &delay, NULL);
+ mPollTask->removePoll(*this);
+ mMsgTask->sendMsg(new MsgTimerExpire(*this));
+}
+
+LocTimerDelegate* LocTimerContainer::popIfOutRanks(LocTimerDelegate& timer) {
+ LocTimerDelegate* poppedNode = NULL;
+ if (mTree && !timer.outRanks(*peek())) {
+ poppedNode = (LocTimerDelegate*)(pop());
+ }
+
+ return poppedNode;
+}
+
+
+/***************************LocTimerPollTask methods***************************/
+
+inline
+LocTimerPollTask::LocTimerPollTask()
+ : mFd(epoll_create(2)), mThread(new LocThread()) {
+ // before a next call returens, a thread will be created. The run() method
+ // could already be running in parallel. Also, since each of the objs
+ // creates a thread, the container will make sure that there will be only
+ // one of such obj for our timer implementation.
+ if (!mThread->start("LocTimerPollTask", this)) {
+ delete mThread;
+ mThread = NULL;
+ }
+}
+
+inline
+LocTimerPollTask::~LocTimerPollTask() {
+ // when fs is closed, epoll_wait() should fail run() should return false
+ // and the spawned thread should exit.
+ close(mFd);
+}
+
+void LocTimerPollTask::destroy() {
+ if (mThread) {
+ LocThread* thread = mThread;
+ mThread = NULL;
+ delete thread;
+ } else {
+ delete this;
+ }
+}
+
+void LocTimerPollTask::addPoll(LocTimerContainer& timerContainer) {
+ struct epoll_event ev;
+ memset(&ev, 0, sizeof(ev));
+
+ ev.events = EPOLLIN | EPOLLWAKEUP;
+ ev.data.fd = timerContainer.getTimerFd();
+ // it is important that we set this context pointer with the input
+ // timer container this is how we know which container should handle
+ // which expiration.
+ ev.data.ptr = &timerContainer;
+
+ epoll_ctl(mFd, EPOLL_CTL_ADD, timerContainer.getTimerFd(), &ev);
+}
+
+inline
+void LocTimerPollTask::removePoll(LocTimerContainer& timerContainer) {
+ epoll_ctl(mFd, EPOLL_CTL_DEL, timerContainer.getTimerFd(), NULL);
+}
+
+// The polling thread context will call this method. If run() method needs to
+// be repetitvely called, it must return true from the previous call.
+bool LocTimerPollTask::run() {
+ struct epoll_event ev[2];
+
+ // we have max 2 descriptors to poll from
+ int fds = epoll_wait(mFd, ev, 2, -1);
+
+ // we pretty much want to continually poll until the fd is closed
+ bool rerun = (fds > 0) || (errno == EINTR);
+
+ if (fds > 0) {
+ // we may have 2 events
+ for (int i = 0; i < fds; i++) {
+ // each fd has a context pointer associated with the right timer container
+ LocTimerContainer* container = (LocTimerContainer*)(ev[i].data.ptr);
+ if (container) {
+ container->expire();
+ } else {
+ epoll_ctl(mFd, EPOLL_CTL_DEL, ev[i].data.fd, NULL);
+ }
+ }
+ }
+
+ // if rerun is true, we are requesting to be scheduled again
+ return rerun;
+}
+
+/***************************LocTimerDelegate methods***************************/
+
+inline
+LocTimerDelegate::LocTimerDelegate(LocTimer& client,
+ struct timespec& futureTime,
+ LocTimerContainer* container)
+ : mClient(&client),
+ mLock(mClient->mLock->share()),
+ mFutureTime(futureTime),
+ mContainer(container) {
+ // adding the timer into the container
+ mContainer->add(*this);
+}
+
+inline
+void LocTimerDelegate::destroyLocked() {
+ // client handle will likely be deleted soon after this
+ // method returns. Nulling this handle so that expire()
+ // won't call the callback on the dead handle any more.
+ mClient = NULL;
+
+ if (mContainer) {
+ LocTimerContainer* container = mContainer;
+ mContainer = NULL;
+ if (container) {
+ container->remove(*this);
+ }
+ } // else we do not do anything. No such *this* can be
+ // created and reached here with mContainer ever been
+ // a non NULL. So *this* must have reached the if clause
+ // once, and we want it reach there only once.
+}
+
+int LocTimerDelegate::ranks(LocRankable& rankable) {
+ int rank = -1;
+ LocTimerDelegate* timer = (LocTimerDelegate*)(&rankable);
+ if (timer) {
+ // larger time ranks lower!!!
+ // IOW, if input obj has bigger tv_sec/tv_nsec, this obj outRanks higher
+ rank = timer->mFutureTime.tv_sec - mFutureTime.tv_sec;
+ if(0 == rank)
+ {
+ //rank against tv_nsec for msec accuracy
+ rank = (int)(timer->mFutureTime.tv_nsec - mFutureTime.tv_nsec);
+ }
+ }
+ return rank;
+}
+
+inline
+void LocTimerDelegate::expire() {
+ // keeping a copy of client pointer to be safe
+ // when timeOutCallback() is called at the end of this
+ // method, *this* obj may be already deleted.
+ LocTimer* client = mClient;
+ // force a stop, which will lead to delete of this obj
+ if (client && client->stop()) {
+ // calling client callback with a pointer save on the stack
+ // only if stop() returns true, i.e. it hasn't been stopped
+ // already.
+ client->timeOutCallback();
+ }
+}
+
+
+/***************************LocTimer methods***************************/
+LocTimer::LocTimer() : mTimer(NULL), mLock(new LocSharedLock()) {
+}
+
+LocTimer::~LocTimer() {
+ stop();
+ if (mLock) {
+ mLock->drop();
+ mLock = NULL;
+ }
+}
+
+bool LocTimer::start(unsigned int timeOutInMs, bool wakeOnExpire) {
+ bool success = false;
+ mLock->lock();
+ if (!mTimer) {
+ struct timespec futureTime;
+ clock_gettime(CLOCK_BOOTTIME, &futureTime);
+ futureTime.tv_sec += timeOutInMs / 1000;
+ futureTime.tv_nsec += (timeOutInMs % 1000) * 1000000;
+ if (futureTime.tv_nsec >= 1000000000) {
+ futureTime.tv_sec += futureTime.tv_nsec / 1000000000;
+ futureTime.tv_nsec %= 1000000000;
+ }
+
+ LocTimerContainer* container;
+ container = LocTimerContainer::get(wakeOnExpire);
+ if (NULL != container) {
+ mTimer = new LocTimerDelegate(*this, futureTime, container);
+ // if mTimer is non 0, success should be 0; or vice versa
+ }
+ success = (NULL != mTimer);
+ }
+ mLock->unlock();
+ return success;
+}
+
+bool LocTimer::stop() {
+ bool success = false;
+ mLock->lock();
+ if (mTimer) {
+ LocTimerDelegate* timer = mTimer;
+ mTimer = NULL;
+ if (timer) {
+ timer->destroyLocked();
+ success = true;
+ }
+ }
+ mLock->unlock();
+ return success;
+}
+
+/***************************LocTimerWrapper methods***************************/
+//////////////////////////////////////////////////////////////////////////
+// This section below wraps for the C style APIs
+//////////////////////////////////////////////////////////////////////////
+class LocTimerWrapper : public LocTimer {
+ loc_timer_callback mCb;
+ void* mCallerData;
+ LocTimerWrapper* mMe;
+ static pthread_mutex_t mMutex;
+ inline ~LocTimerWrapper() { mCb = NULL; mMe = NULL; }
+public:
+ inline LocTimerWrapper(loc_timer_callback cb, void* callerData) :
+ mCb(cb), mCallerData(callerData), mMe(this) {
+ }
+ void destroy() {
+ pthread_mutex_lock(&mMutex);
+ if (NULL != mCb && this == mMe) {
+ delete this;
+ }
+ pthread_mutex_unlock(&mMutex);
+ }
+ virtual void timeOutCallback() {
+ loc_timer_callback cb = mCb;
+ void* callerData = mCallerData;
+ if (cb) {
+ cb(callerData, 0);
+ }
+ destroy();
+ }
+};
+
+pthread_mutex_t LocTimerWrapper::mMutex = PTHREAD_MUTEX_INITIALIZER;
+
+void* loc_timer_start(uint64_t msec, loc_timer_callback cb_func,
+ void *caller_data, bool wake_on_expire)
+{
+ LocTimerWrapper* locTimerWrapper = NULL;
+
+ if (cb_func) {
+ locTimerWrapper = new LocTimerWrapper(cb_func, caller_data);
+
+ if (locTimerWrapper) {
+ locTimerWrapper->start(msec, wake_on_expire);
+ }
+ }
+
+ return locTimerWrapper;
+}
+
+void loc_timer_stop(void*& handle)
+{
+ if (handle) {
+ LocTimerWrapper* locTimerWrapper = (LocTimerWrapper*)(handle);
+ locTimerWrapper->destroy();
+ handle = NULL;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// This section above wraps for the C style APIs
+//////////////////////////////////////////////////////////////////////////
+
+#ifdef __LOC_DEBUG__
+
+double getDeltaSeconds(struct timespec from, struct timespec to) {
+ return (double)to.tv_sec + (double)to.tv_nsec / 1000000000
+ - from.tv_sec - (double)from.tv_nsec / 1000000000;
+}
+
+struct timespec getNow() {
+ struct timespec now;
+ clock_gettime(CLOCK_BOOTTIME, &now);
+ return now;
+}
+
+class LocTimerTest : public LocTimer, public LocRankable {
+ int mTimeOut;
+ const struct timespec mTimeOfBirth;
+ inline struct timespec getTimerWrapper(int timeout) {
+ struct timespec now;
+ clock_gettime(CLOCK_BOOTTIME, &now);
+ now.tv_sec += timeout;
+ return now;
+ }
+public:
+ inline LocTimerTest(int timeout) : LocTimer(), LocRankable(),
+ mTimeOut(timeout), mTimeOfBirth(getTimerWrapper(0)) {}
+ inline virtual int ranks(LocRankable& rankable) {
+ LocTimerTest* timer = dynamic_cast<LocTimerTest*>(&rankable);
+ return timer->mTimeOut - mTimeOut;
+ }
+ inline virtual void timeOutCallback() {
+ printf("timeOutCallback() - ");
+ deviation();
+ }
+ double deviation() {
+ struct timespec now = getTimerWrapper(0);
+ double delta = getDeltaSeconds(mTimeOfBirth, now);
+ printf("%lf: %lf\n", delta, delta * 100 / mTimeOut);
+ return delta / mTimeOut;
+ }
+};
+
+// For Linux command line testing:
+// compilation:
+// g++ -D__LOC_HOST_DEBUG__ -D__LOC_DEBUG__ -g -I. -I../../../../system/core/include -o LocHeap.o LocHeap.cpp
+// g++ -D__LOC_HOST_DEBUG__ -D__LOC_DEBUG__ -g -std=c++0x -I. -I../../../../system/core/include -lpthread -o LocThread.o LocThread.cpp
+// g++ -D__LOC_HOST_DEBUG__ -D__LOC_DEBUG__ -g -I. -I../../../../system/core/include -o LocTimer.o LocTimer.cpp
+int main(int argc, char** argv) {
+ struct timespec timeOfStart=getNow();
+ srand(time(NULL));
+ int tries = atoi(argv[1]);
+ int checks = tries >> 3;
+ LocTimerTest** timerArray = new LocTimerTest*[tries];
+ memset(timerArray, NULL, tries);
+
+ for (int i = 0; i < tries; i++) {
+ int r = rand() % tries;
+ LocTimerTest* timer = new LocTimerTest(r);
+ if (timerArray[r]) {
+ if (!timer->stop()) {
+ printf("%lf:\n", getDeltaSeconds(timeOfStart, getNow()));
+ printf("ERRER: %dth timer, id %d, not running when it should be\n", i, r);
+ exit(0);
+ } else {
+ printf("stop() - %d\n", r);
+ delete timer;
+ timerArray[r] = NULL;
+ }
+ } else {
+ if (!timer->start(r, false)) {
+ printf("%lf:\n", getDeltaSeconds(timeOfStart, getNow()));
+ printf("ERRER: %dth timer, id %d, running when it should not be\n", i, r);
+ exit(0);
+ } else {
+ printf("stop() - %d\n", r);
+ timerArray[r] = timer;
+ }
+ }
+ }
+
+ for (int i = 0; i < tries; i++) {
+ if (timerArray[i]) {
+ if (!timerArray[i]->stop()) {
+ printf("%lf:\n", getDeltaSeconds(timeOfStart, getNow()));
+ printf("ERRER: %dth timer, not running when it should be\n", i);
+ exit(0);
+ } else {
+ printf("stop() - %d\n", i);
+ delete timerArray[i];
+ timerArray[i] = NULL;
+ }
+ }
+ }
+
+ delete[] timerArray;
+
+ return 0;
+}
+
+#endif
diff --git a/gps/utils/LocTimer.h b/gps/utils/LocTimer.h
new file mode 100644
index 0000000..c6a6362
--- /dev/null
+++ b/gps/utils/LocTimer.h
@@ -0,0 +1,74 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation, nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __LOC_TIMER_CPP_H__
+#define __LOC_TIMER_CPP_H__
+
+#include <stddef.h>
+#include <platform_lib_includes.h>
+
+// opaque class to provide service implementation.
+class LocTimerDelegate;
+class LocSharedLock;
+
+// LocTimer client must extend this class and implementthe callback.
+// start() / stop() methods are to arm / disarm timer.
+class LocTimer
+{
+ LocTimerDelegate* mTimer;
+ LocSharedLock* mLock;
+ // don't really want mLock to be manipulated by clients, yet LocTimer
+ // has to have a reference to the lock so that the delete of LocTimer
+ // and LocTimerDelegate can work together on their share resources.
+ friend class LocTimerDelegate;
+
+public:
+ LocTimer();
+ virtual ~LocTimer();
+
+ // timeOutInMs: timeout delay in ms
+ // wakeOnExpire: true if to wake up CPU (if sleeping) upon timer
+ // expiration and notify the client.
+ // false if to wait until next time CPU wakes up (if
+ // sleeping) and then notify the client.
+ // return: true on success;
+ // false on failure, e.g. timer is already running.
+ bool start(uint32_t timeOutInMs, bool wakeOnExpire);
+
+ // return: true on success;
+ // false on failure, e.g. timer is not running.
+ bool stop();
+
+ // LocTimer client Should implement this method.
+ // This method is used for timeout calling back to client. This method
+ // should be short enough (eg: send a message to your own thread).
+ virtual void timeOutCallback() = 0;
+};
+
+#endif //__LOC_DELAY_H__
diff --git a/gps/utils/Makefile.am b/gps/utils/Makefile.am
new file mode 100644
index 0000000..33a87da
--- /dev/null
+++ b/gps/utils/Makefile.am
@@ -0,0 +1,64 @@
+AM_CFLAGS = -Wundef \
+ -I./ \
+ -std=c++11 \
+ $(LOCPLA_CFLAGS)
+
+AM_CPPFLAGS = -Wundef \
+ -I./ \
+ -std=c++11 \
+ $(LOCPLA_CFLAGS)
+
+libgps_utils_so_la_h_sources = \
+ msg_q.h \
+ linked_list.h \
+ loc_cfg.h \
+ loc_log.h \
+ loc_target.h \
+ loc_timer.h \
+ MsgTask.h \
+ LocHeap.h \
+ LocThread.h \
+ LocTimer.h \
+ loc_misc_utils.h \
+ loc_nmea.h \
+ gps_extended_c.h \
+ gps_extended.h \
+ loc_gps.h
+
+libgps_utils_so_la_c_sources = \
+ linked_list.c \
+ msg_q.c \
+ loc_cfg.cpp \
+ loc_log.cpp \
+ loc_target.cpp \
+ LocHeap.cpp \
+ LocTimer.cpp \
+ LocThread.cpp \
+ MsgTask.cpp \
+ loc_misc_utils.cpp \
+ loc_nmea.cpp
+
+
+library_include_HEADERS = $(libgps_utils_so_la_h_sources)
+
+libgps_utils_so_la_SOURCES = $(libgps_utils_so_la_c_sources)
+
+if USE_GLIB
+libgps_utils_so_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@
+libgps_utils_so_la_LDFLAGS = -lstdc++ -Wl,-z,defs -lpthread @GLIB_LIBS@ -shared -version-info 1:0:0
+libgps_utils_so_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@
+else
+libgps_utils_so_la_CFLAGS = $(AM_CFLAGS)
+libgps_utils_so_la_LDFLAGS = -Wl,-z,defs -lpthread -shared -version-info 1:0:0
+libgps_utils_so_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS)
+endif
+
+libgps_utils_so_la_LIBADD = -lcutils -lstdc++ -llog $(LOCPLA_LIBS)
+
+#Create and Install libraries
+lib_LTLIBRARIES = libgps_utils_so.la
+library_includedir = $(pkgincludedir)
+pkgconfigdir = $(libdir)/pkgconfig
+
+pkgconfig_DATA = gps-utils.pc
+EXTRA_DIST = $(pkgconfig_DATA)
diff --git a/gps/utils/MsgTask.cpp b/gps/utils/MsgTask.cpp
new file mode 100644
index 0000000..80abeec
--- /dev/null
+++ b/gps/utils/MsgTask.cpp
@@ -0,0 +1,104 @@
+/* Copyright (c) 2011-2013, 2015, 2017The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation, nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#define LOG_NDEBUG 0
+#define LOG_TAG "LocSvc_MsgTask"
+
+#include <unistd.h>
+#include <MsgTask.h>
+#include <msg_q.h>
+#include <loc_log.h>
+#include <platform_lib_includes.h>
+
+static void LocMsgDestroy(void* msg) {
+ delete (LocMsg*)msg;
+}
+
+MsgTask::MsgTask(LocThread::tCreate tCreator,
+ const char* threadName, bool joinable) :
+ mQ(msg_q_init2()), mThread(new LocThread()) {
+ if (!mThread->start(tCreator, threadName, this, joinable)) {
+ delete mThread;
+ mThread = NULL;
+ }
+}
+
+MsgTask::MsgTask(const char* threadName, bool joinable) :
+ mQ(msg_q_init2()), mThread(new LocThread()) {
+ if (!mThread->start(threadName, this, joinable)) {
+ delete mThread;
+ mThread = NULL;
+ }
+}
+
+MsgTask::~MsgTask() {
+ msg_q_flush((void*)mQ);
+ msg_q_destroy((void**)&mQ);
+}
+
+void MsgTask::destroy() {
+ LocThread* thread = mThread;
+ msg_q_unblock((void*)mQ);
+ if (thread) {
+ mThread = NULL;
+ delete thread;
+ } else {
+ delete this;
+ }
+}
+
+void MsgTask::sendMsg(const LocMsg* msg) const {
+ if (msg) {
+ msg_q_snd((void*)mQ, (void*)msg, LocMsgDestroy);
+ } else {
+ LOC_LOGE("%s: msg is NULL", __func__);
+ }
+}
+
+void MsgTask::prerun() {
+ // make sure we do not run in background scheduling group
+ platform_lib_abstraction_set_sched_policy(platform_lib_abstraction_gettid(), PLA_SP_FOREGROUND);
+}
+
+bool MsgTask::run() {
+ LocMsg* msg;
+ msq_q_err_type result = msg_q_rcv((void*)mQ, (void **)&msg);
+ if (eMSG_Q_SUCCESS != result) {
+ LOC_LOGE("%s:%d] fail receiving msg: %s\n", __func__, __LINE__,
+ loc_get_msg_q_status(result));
+ return false;
+ }
+
+ msg->log();
+ // there is where each individual msg handling is invoked
+ msg->proc();
+
+ delete msg;
+
+ return true;
+}
diff --git a/gps/utils/MsgTask.h b/gps/utils/MsgTask.h
new file mode 100644
index 0000000..9eb1f56
--- /dev/null
+++ b/gps/utils/MsgTask.h
@@ -0,0 +1,67 @@
+/* Copyright (c) 2011-2013,2015 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation, nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef __MSG_TASK__
+#define __MSG_TASK__
+
+#include <LocThread.h>
+
+struct LocMsg {
+ inline LocMsg() {}
+ inline virtual ~LocMsg() {}
+ virtual void proc() const = 0;
+ inline virtual void log() const {}
+};
+
+class MsgTask : public LocRunnable {
+ const void* mQ;
+ LocThread* mThread;
+ friend class LocThreadDelegate;
+protected:
+ virtual ~MsgTask();
+public:
+ MsgTask(LocThread::tCreate tCreator, const char* threadName = NULL, bool joinable = true);
+ MsgTask(const char* threadName = NULL, bool joinable = true);
+ // this obj will be deleted once thread is deleted
+ void destroy();
+ void sendMsg(const LocMsg* msg) const;
+ // Overrides of LocRunnable methods
+ // This method will be repeated called until it returns false; or
+ // until thread is stopped.
+ virtual bool run();
+
+ // The method to be run before thread loop (conditionally repeatedly)
+ // calls run()
+ virtual void prerun();
+
+ // The method to be run after thread loop (conditionally repeatedly)
+ // calls run()
+ inline virtual void postrun() {}
+};
+
+#endif //__MSG_TASK__
diff --git a/gps/utils/configure.ac b/gps/utils/configure.ac
new file mode 100644
index 0000000..a7ab9b4
--- /dev/null
+++ b/gps/utils/configure.ac
@@ -0,0 +1,59 @@
+# configure.ac -- Autoconf script for gps gps-utils
+#
+# Process this file with autoconf to produce a configure script
+
+# Requires autoconf tool later than 2.61
+AC_PREREQ(2.61)
+# Initialize the gps gps-utils package version 1.0.0
+AC_INIT([gps-utils],1.0.0)
+# Does not strictly follow GNU Coding standards
+AM_INIT_AUTOMAKE([foreign])
+# Disables auto rebuilding of configure, Makefile.ins
+AM_MAINTAINER_MODE
+# Verifies the --srcdir is correct by checking for the path
+AC_CONFIG_SRCDIR([Makefile.am])
+# defines some macros variable to be included by source
+AC_CONFIG_HEADERS([config.h])
+AC_CONFIG_MACRO_DIR([m4])
+
+# Checks for programs.
+AC_PROG_LIBTOOL
+AC_PROG_CXX
+AC_PROG_CC
+AM_PROG_CC_C_O
+AC_PROG_AWK
+AC_PROG_CPP
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+PKG_PROG_PKG_CONFIG
+
+PKG_CHECK_MODULES([LOCPLA], [loc-pla])
+AC_SUBST([LOCPLA_CFLAGS])
+AC_SUBST([LOCPLA_LIBS])
+
+AC_ARG_WITH([glib],
+ AC_HELP_STRING([--with-glib],
+ [enable glib, building HLOS systems which use glib]))
+
+if (test "x${with_glib}" = "xyes"); then
+ AC_DEFINE(ENABLE_USEGLIB, 1, [Define if HLOS systems uses glib])
+ PKG_CHECK_MODULES(GTHREAD, gthread-2.0 >= 2.16, dummy=yes,
+ AC_MSG_ERROR(GThread >= 2.16 is required))
+ PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.16, dummy=yes,
+ AC_MSG_ERROR(GLib >= 2.16 is required))
+ GLIB_CFLAGS="$GLIB_CFLAGS $GTHREAD_CFLAGS"
+ GLIB_LIBS="$GLIB_LIBS $GTHREAD_LIBS"
+
+ AC_SUBST(GLIB_CFLAGS)
+ AC_SUBST(GLIB_LIBS)
+fi
+
+AM_CONDITIONAL(USE_GLIB, test "x${with_glib}" = "xyes")
+
+AC_CONFIG_FILES([ \
+ Makefile \
+ gps-utils.pc
+ ])
+
+AC_OUTPUT
diff --git a/gps/utils/gps-utils.pc.in b/gps/utils/gps-utils.pc.in
new file mode 100644
index 0000000..3ed3d90
--- /dev/null
+++ b/gps/utils/gps-utils.pc.in
@@ -0,0 +1,10 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: gps-utils
+Description: QTI GPS Location utils
+Version: @VERSION
+Libs: -L${libdir} -lgps_utils_so
+Cflags: -I${includedir}/gps-utils
diff --git a/gps/utils/gps_extended.h b/gps/utils/gps_extended.h
new file mode 100644
index 0000000..dc6ad1e
--- /dev/null
+++ b/gps/utils/gps_extended.h
@@ -0,0 +1,106 @@
+/* Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GPS_EXTENDED_H
+#define GPS_EXTENDED_H
+
+/**
+ * @file
+ * @brief C++ declarations for GPS types
+ */
+
+#include <gps_extended_c.h>
+#if defined(USE_GLIB) || defined(OFF_TARGET)
+#include <string.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+
+struct LocPosMode
+{
+ LocPositionMode mode;
+ LocGpsPositionRecurrence recurrence;
+ uint32_t min_interval;
+ uint32_t preferred_accuracy;
+ uint32_t preferred_time;
+ bool share_position;
+ char credentials[14];
+ char provider[8];
+ LocPosMode(LocPositionMode m, LocGpsPositionRecurrence recr,
+ uint32_t gap, uint32_t accu, uint32_t time,
+ bool sp, const char* cred, const char* prov) :
+ mode(m), recurrence(recr),
+ min_interval(gap < GPS_MIN_POSSIBLE_FIX_INTERVAL_MS ?
+ GPS_MIN_POSSIBLE_FIX_INTERVAL_MS : gap),
+ preferred_accuracy(accu), preferred_time(time),
+ share_position(sp) {
+ 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);
+ }
+ }
+
+ inline LocPosMode() :
+ mode(LOC_POSITION_MODE_MS_BASED),
+ recurrence(LOC_GPS_POSITION_RECURRENCE_PERIODIC),
+ min_interval(GPS_DEFAULT_FIX_INTERVAL_MS),
+ preferred_accuracy(50), preferred_time(120000),
+ share_position(true) {
+ 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);
+ }
+
+ void logv() const;
+};
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GPS_EXTENDED_H */
+
diff --git a/gps/utils/gps_extended_c.h b/gps/utils/gps_extended_c.h
new file mode 100644
index 0000000..f87a942
--- /dev/null
+++ b/gps/utils/gps_extended_c.h
@@ -0,0 +1,1290 @@
+/* Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GPS_EXTENDED_C_H
+#define GPS_EXTENDED_C_H
+
+#include <ctype.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <loc_gps.h>
+#include <LocationAPI.h>
+#include <time.h>
+
+/**
+ * @file
+ * @brief C++ declarations for GPS types
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/** Location has valid source information. */
+#define LOCATION_HAS_SOURCE_INFO 0x0020
+/** LocGpsLocation has valid "is indoor?" flag */
+#define LOC_GPS_LOCATION_HAS_IS_INDOOR 0x0040
+/** LocGpsLocation has valid floor number */
+#define LOC_GPS_LOCATION_HAS_FLOOR_NUMBER 0x0080
+/** LocGpsLocation has valid map URL*/
+#define LOC_GPS_LOCATION_HAS_MAP_URL 0x0100
+/** LocGpsLocation has valid map index */
+#define LOC_GPS_LOCATION_HAS_MAP_INDEX 0x0200
+
+/** Sizes for indoor fields */
+#define GPS_LOCATION_MAP_URL_SIZE 400
+#define GPS_LOCATION_MAP_INDEX_SIZE 16
+
+/** Position source is ULP */
+#define ULP_LOCATION_IS_FROM_HYBRID 0x0001
+/** Position source is GNSS only */
+#define ULP_LOCATION_IS_FROM_GNSS 0x0002
+/** Position source is ZPP only */
+#define ULP_LOCATION_IS_FROM_ZPP 0x0004
+/** Position is from a Geofence Breach Event */
+#define ULP_LOCATION_IS_FROM_GEOFENCE 0X0008
+/** Position is from Hardware FLP */
+#define ULP_LOCATION_IS_FROM_HW_FLP 0x0010
+/** Position is from NLP */
+#define ULP_LOCATION_IS_FROM_NLP 0x0020
+/** Position is from PIP */
+#define ULP_LOCATION_IS_FROM_PIP 0x0040
+/** Position is from external DR solution*/
+#define ULP_LOCATION_IS_FROM_EXT_DR 0X0080
+/** Raw GNSS position fixes */
+#define ULP_LOCATION_IS_FROM_GNSS_RAW 0X0100
+
+typedef uint32_t LocSvInfoSource;
+/** SVinfo source is GNSS/DR */
+#define ULP_SVINFO_IS_FROM_GNSS ((LocSvInfoSource)0x0001)
+/** Raw SVinfo from GNSS */
+#define ULP_SVINFO_IS_FROM_DR ((LocSvInfoSource)0x0002)
+
+#define ULP_MIN_INTERVAL_INVALID 0xffffffff
+#define ULP_MAX_NMEA_STRING_SIZE 201
+
+/*Emergency SUPL*/
+#define LOC_GPS_NI_TYPE_EMERGENCY_SUPL 4
+
+#define LOC_AGPS_CERTIFICATE_MAX_LENGTH 2000
+#define LOC_AGPS_CERTIFICATE_MAX_SLOTS 10
+
+typedef uint32_t LocPosTechMask;
+#define LOC_POS_TECH_MASK_DEFAULT ((LocPosTechMask)0x00000000)
+#define LOC_POS_TECH_MASK_SATELLITE ((LocPosTechMask)0x00000001)
+#define LOC_POS_TECH_MASK_CELLID ((LocPosTechMask)0x00000002)
+#define LOC_POS_TECH_MASK_WIFI ((LocPosTechMask)0x00000004)
+#define LOC_POS_TECH_MASK_SENSORS ((LocPosTechMask)0x00000008)
+#define LOC_POS_TECH_MASK_REFERENCE_LOCATION ((LocPosTechMask)0x00000010)
+#define LOC_POS_TECH_MASK_INJECTED_COARSE_POSITION ((LocPosTechMask)0x00000020)
+#define LOC_POS_TECH_MASK_AFLT ((LocPosTechMask)0x00000040)
+#define LOC_POS_TECH_MASK_HYBRID ((LocPosTechMask)0x00000080)
+
+enum loc_registration_mask_status {
+ LOC_REGISTRATION_MASK_ENABLED,
+ LOC_REGISTRATION_MASK_DISABLED,
+ LOC_REGISTRATION_MASK_SET
+};
+
+typedef enum {
+ LOC_SUPPORTED_FEATURE_ODCPI_2_V02 = 0, /**< Support ODCPI version 2 feature */
+ LOC_SUPPORTED_FEATURE_WIFI_AP_DATA_INJECT_2_V02, /**< Support Wifi AP data inject version 2 feature */
+ LOC_SUPPORTED_FEATURE_DEBUG_NMEA_V02 /**< Support debug NMEA feature */
+} loc_supported_feature_enum;
+
+typedef struct {
+ /** set to sizeof(UlpLocation) */
+ size_t size;
+ LocGpsLocation gpsLocation;
+ /* Provider indicator for HYBRID or GPS */
+ uint16_t position_source;
+ LocPosTechMask tech_mask;
+ /*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];
+} UlpLocation;
+
+typedef struct {
+ /** set to sizeof(UlpNmea) */
+ size_t size;
+ char nmea_str[ULP_MAX_NMEA_STRING_SIZE];
+ unsigned int len;
+} UlpNmea;
+
+
+/** AGPS type */
+typedef int8_t AGpsExtType;
+#define LOC_AGPS_TYPE_INVALID -1
+#define LOC_AGPS_TYPE_ANY 0
+#define LOC_AGPS_TYPE_SUPL 1
+#define LOC_AGPS_TYPE_C2K 2
+#define LOC_AGPS_TYPE_WWAN_ANY 3
+#define LOC_AGPS_TYPE_WIFI 4
+#define LOC_AGPS_TYPE_SUPL_ES 5
+
+/** SSID length */
+#define SSID_BUF_SIZE (32+1)
+
+typedef int16_t AGpsBearerType;
+#define AGPS_APN_BEARER_INVALID 0
+#define AGPS_APN_BEARER_IPV4 1
+#define AGPS_APN_BEARER_IPV6 2
+#define AGPS_APN_BEARER_IPV4V6 3
+
+typedef enum {
+ AGPS_CB_PRIORITY_LOW = 1,
+ AGPS_CB_PRIORITY_MED = 2,
+ AGPS_CB_PRIORITY_HIGH = 3
+} AgpsCbPriority;
+
+typedef struct {
+ void* statusV4Cb;
+ AgpsCbPriority cbPriority;
+} AgpsCbInfo;
+
+/** GPS extended callback structure. */
+typedef struct {
+ /** set to sizeof(LocGpsCallbacks) */
+ size_t size;
+ loc_gps_set_capabilities set_capabilities_cb;
+ loc_gps_acquire_wakelock acquire_wakelock_cb;
+ loc_gps_release_wakelock release_wakelock_cb;
+ loc_gps_create_thread create_thread_cb;
+ loc_gps_request_utc_time request_utc_time_cb;
+} GpsExtCallbacks;
+
+/** Callback to report the xtra server url to the client.
+ * The client should use this url when downloading xtra unless overwritten
+ * in the gps.conf file
+ */
+typedef void (* report_xtra_server)(const char*, const char*, const char*);
+
+/** Callback structure for the XTRA interface. */
+typedef struct {
+ loc_gps_xtra_download_request download_request_cb;
+ loc_gps_create_thread create_thread_cb;
+ report_xtra_server report_xtra_server_cb;
+} GpsXtraExtCallbacks;
+
+/** Represents the status of AGPS. */
+typedef struct {
+ /** set to sizeof(AGpsExtStatus) */
+ size_t size;
+
+ AGpsExtType type;
+ LocAGpsStatusValue status;
+ uint32_t ipv4_addr;
+ struct sockaddr_storage addr;
+ char ssid[SSID_BUF_SIZE];
+ char password[SSID_BUF_SIZE];
+} AGpsExtStatus;
+
+/** Callback with AGPS status information.
+ * Can only be called from a thread created by create_thread_cb.
+ */
+typedef void (* agps_status_extended)(AGpsExtStatus* status);
+
+/** Callback structure for the AGPS interface. */
+typedef struct {
+ agps_status_extended status_cb;
+ loc_gps_create_thread create_thread_cb;
+} AGpsExtCallbacks;
+
+
+typedef void (*loc_ni_notify_callback)(LocGpsNiNotification *notification, bool esEnalbed);
+/** GPS NI callback structure. */
+typedef struct
+{
+ /**
+ * Sends the notification request from HAL to GPSLocationProvider.
+ */
+ loc_ni_notify_callback notify_cb;
+} GpsNiExtCallbacks;
+
+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_INVALID = -1,
+ LOC_POSITION_MODE_STANDALONE = 0,
+ 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,
+ LOC_POSITION_MODE_RESERVED_5
+
+} LocPositionMode;
+
+/**
+ * @brief Minimum allowed value for fix interval.
+ *
+ * This value is a sanity limit in GPS framework. The hardware has own internal
+ * limits that may not match this value
+ *
+ * @sa GPS_DEFAULT_FIX_INTERVAL_MS
+ */
+
+#define GPS_MIN_POSSIBLE_FIX_INTERVAL_MS 100
+/**
+ * @brief Default value for fix interval.
+ *
+ * This value is used by default whenever appropriate.
+ *
+ * @sa GPS_MIN_POSSIBLE_FIX_INTERVAL_MS
+ */
+#define GPS_DEFAULT_FIX_INTERVAL_MS 1000
+
+/** Flags to indicate which values are valid in a GpsLocationExtended. */
+typedef uint32_t GpsLocationExtendedFlags;
+/** GpsLocationExtended has valid pdop, hdop, vdop. */
+#define GPS_LOCATION_EXTENDED_HAS_DOP 0x0001
+/** GpsLocationExtended has valid altitude mean sea level. */
+#define GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL 0x0002
+/** UlpLocation has valid magnetic deviation. */
+#define GPS_LOCATION_EXTENDED_HAS_MAG_DEV 0x0004
+/** UlpLocation has valid mode indicator. */
+#define GPS_LOCATION_EXTENDED_HAS_MODE_IND 0x0008
+/** GpsLocationExtended has valid vertical uncertainty */
+#define GPS_LOCATION_EXTENDED_HAS_VERT_UNC 0x0010
+/** GpsLocationExtended has valid speed uncertainty */
+#define GPS_LOCATION_EXTENDED_HAS_SPEED_UNC 0x0020
+/** GpsLocationExtended has valid heading uncertainty */
+#define GPS_LOCATION_EXTENDED_HAS_BEARING_UNC 0x0040
+/** GpsLocationExtended has valid horizontal reliability */
+#define GPS_LOCATION_EXTENDED_HAS_HOR_RELIABILITY 0x0080
+/** GpsLocationExtended has valid vertical reliability */
+#define GPS_LOCATION_EXTENDED_HAS_VERT_RELIABILITY 0x0100
+/** GpsLocationExtended has valid Horizontal Elliptical Uncertainty (Semi-Major Axis) */
+#define GPS_LOCATION_EXTENDED_HAS_HOR_ELIP_UNC_MAJOR 0x0200
+/** GpsLocationExtended has valid Horizontal Elliptical Uncertainty (Semi-Minor Axis) */
+#define GPS_LOCATION_EXTENDED_HAS_HOR_ELIP_UNC_MINOR 0x0400
+/** GpsLocationExtended has valid Elliptical Horizontal Uncertainty Azimuth */
+#define GPS_LOCATION_EXTENDED_HAS_HOR_ELIP_UNC_AZIMUTH 0x0800
+/** GpsLocationExtended has valid gnss sv used in position data */
+#define GPS_LOCATION_EXTENDED_HAS_GNSS_SV_USED_DATA 0x1000
+/** GpsLocationExtended has valid navSolutionMask */
+#define GPS_LOCATION_EXTENDED_HAS_NAV_SOLUTION_MASK 0x2000
+/** GpsLocationExtended has valid LocPosTechMask */
+#define GPS_LOCATION_EXTENDED_HAS_POS_TECH_MASK 0x4000
+/** GpsLocationExtended has valid LocSvInfoSource */
+#define GPS_LOCATION_EXTENDED_HAS_SV_SOURCE_INFO 0x8000
+/** GpsLocationExtended has valid position dynamics data */
+#define GPS_LOCATION_EXTENDED_HAS_POS_DYNAMICS_DATA 0x10000
+/** GpsLocationExtended has GPS Time */
+#define GPS_LOCATION_EXTENDED_HAS_GPS_TIME 0x20000
+
+typedef uint32_t LocNavSolutionMask;
+/* Bitmask to specify whether SBAS ionospheric correction is used */
+#define LOC_NAV_MASK_SBAS_CORRECTION_IONO ((LocNavSolutionMask)0x0001)
+/* Bitmask to specify whether SBAS fast correction is used */
+#define LOC_NAV_MASK_SBAS_CORRECTION_FAST ((LocNavSolutionMask)0x0002)
+/**< Bitmask to specify whether SBAS long-tem correction is used */
+#define LOC_NAV_MASK_SBAS_CORRECTION_LONG ((LocNavSolutionMask)0x0004)
+/**< Bitmask to specify whether SBAS integrity information is used */
+#define LOC_NAV_MASK_SBAS_INTEGRITY ((LocNavSolutionMask)0x0008)
+
+typedef uint32_t LocPosDataMask;
+/* Bitmask to specify whether Navigation data has Forward Acceleration */
+#define LOC_NAV_DATA_HAS_LONG_ACCEL ((LocPosDataMask)0x0001)
+/* Bitmask to specify whether Navigation data has Sideward Acceleration */
+#define LOC_NAV_DATA_HAS_LAT_ACCEL ((LocPosDataMask)0x0002)
+/* Bitmask to specify whether Navigation data has Vertical Acceleration */
+#define LOC_NAV_DATA_HAS_VERT_ACCEL ((LocPosDataMask)0x0004)
+/* Bitmask to specify whether Navigation data has Heading Rate */
+#define LOC_NAV_DATA_HAS_YAW_RATE ((LocPosDataMask)0x0008)
+/* Bitmask to specify whether Navigation data has Body pitch */
+#define LOC_NAV_DATA_HAS_PITCH ((LocPosDataMask)0x0010)
+
+/** GPS PRN Range */
+#define GPS_SV_PRN_MIN 1
+#define GPS_SV_PRN_MAX 32
+#define GLO_SV_PRN_MIN 65
+#define GLO_SV_PRN_MAX 96
+#define QZSS_SV_PRN_MIN 193
+#define QZSS_SV_PRN_MAX 197
+#define BDS_SV_PRN_MIN 201
+#define BDS_SV_PRN_MAX 235
+#define GAL_SV_PRN_MIN 301
+#define GAL_SV_PRN_MAX 336
+
+typedef uint32_t LocPosTechMask;
+#define LOC_POS_TECH_MASK_DEFAULT ((LocPosTechMask)0x00000000)
+#define LOC_POS_TECH_MASK_SATELLITE ((LocPosTechMask)0x00000001)
+#define LOC_POS_TECH_MASK_CELLID ((LocPosTechMask)0x00000002)
+#define LOC_POS_TECH_MASK_WIFI ((LocPosTechMask)0x00000004)
+#define LOC_POS_TECH_MASK_SENSORS ((LocPosTechMask)0x00000008)
+#define LOC_POS_TECH_MASK_REFERENCE_LOCATION ((LocPosTechMask)0x00000010)
+#define LOC_POS_TECH_MASK_INJECTED_COARSE_POSITION ((LocPosTechMask)0x00000020)
+#define LOC_POS_TECH_MASK_AFLT ((LocPosTechMask)0x00000040)
+#define LOC_POS_TECH_MASK_HYBRID ((LocPosTechMask)0x00000080)
+
+typedef enum {
+ LOC_RELIABILITY_NOT_SET = 0,
+ LOC_RELIABILITY_VERY_LOW = 1,
+ LOC_RELIABILITY_LOW = 2,
+ LOC_RELIABILITY_MEDIUM = 3,
+ LOC_RELIABILITY_HIGH = 4
+}LocReliability;
+
+typedef struct {
+ struct timespec apTimeStamp;
+ /*boottime received from pps-ktimer*/
+ float apTimeStampUncertaintyMs;
+ /* timestamp uncertainty in milli seconds */
+}Gnss_ApTimeStampStructType;
+
+typedef struct {
+ uint64_t gps_sv_used_ids_mask;
+ uint64_t glo_sv_used_ids_mask;
+ uint64_t gal_sv_used_ids_mask;
+ uint64_t bds_sv_used_ids_mask;
+ uint64_t qzss_sv_used_ids_mask;
+} GnssSvUsedInPosition;
+
+/* Body Frame parameters */
+typedef struct {
+ /** Contains Body frame LocPosDataMask bits. */
+ uint32_t bodyFrameDatamask;
+ /* Forward Acceleration in body frame (m/s2)*/
+ float longAccel;
+ /* Sideward Acceleration in body frame (m/s2)*/
+ float latAccel;
+ /* Vertical Acceleration in body frame (m/s2)*/
+ float vertAccel;
+ /* Heading Rate (Radians/second) */
+ float yawRate;
+ /* Body pitch (Radians) */
+ float pitch;
+}LocPositionDynamics;
+
+/* GPS Time structure */
+typedef struct {
+
+ /**< Current GPS week as calculated from midnight, Jan. 6, 1980. \n
+ - Units: Weeks */
+ uint16_t gpsWeek;
+
+ /**< Amount of time into the current GPS week. \n
+ - Units: Milliseconds */
+ uint32_t gpsTimeOfWeekMs;
+}GPSTimeStruct;
+
+/** Represents gps location extended. */
+typedef struct {
+ /** set to sizeof(GpsLocationExtended) */
+ size_t size;
+ /** Contains GpsLocationExtendedFlags bits. */
+ uint32_t flags;
+ /** Contains the Altitude wrt mean sea level */
+ float altitudeMeanSeaLevel;
+ /** Contains Position Dilusion of Precision. */
+ float pdop;
+ /** Contains Horizontal Dilusion of Precision. */
+ float hdop;
+ /** Contains Vertical Dilusion of Precision. */
+ float vdop;
+ /** Contains Magnetic Deviation. */
+ float magneticDeviation;
+ /** vertical uncertainty in meters */
+ float vert_unc;
+ /** speed uncertainty in m/s */
+ float speed_unc;
+ /** heading uncertainty in degrees (0 to 359.999) */
+ float bearing_unc;
+ /** horizontal reliability. */
+ LocReliability horizontal_reliability;
+ /** vertical reliability. */
+ LocReliability vertical_reliability;
+ /* Horizontal Elliptical Uncertainty (Semi-Major Axis) */
+ float horUncEllipseSemiMajor;
+ /* Horizontal Elliptical Uncertainty (Semi-Minor Axis) */
+ float horUncEllipseSemiMinor;
+ /* Elliptical Horizontal Uncertainty Azimuth */
+ float horUncEllipseOrientAzimuth;
+
+ Gnss_ApTimeStampStructType timeStamp;
+ /** Gnss sv used in position data */
+ GnssSvUsedInPosition gnss_sv_used_ids;
+ /** Nav solution mask to indicate sbas corrections */
+ LocNavSolutionMask navSolutionMask;
+ /** Position technology used in computing this fix */
+ LocPosTechMask tech_mask;
+ /** SV Info source used in computing this fix */
+ LocSvInfoSource sv_source;
+ /** Body Frame Dynamics: 4wayAcceleration and pitch set with validity */
+ LocPositionDynamics bodyFrameData;
+ /** GPS Time */
+ GPSTimeStruct gpsTime;
+} GpsLocationExtended;
+
+enum loc_sess_status {
+ LOC_SESS_SUCCESS,
+ LOC_SESS_INTERMEDIATE,
+ LOC_SESS_FAILURE
+};
+
+// Nmea sentence types mask
+typedef uint32_t NmeaSentenceTypesMask;
+#define LOC_NMEA_MASK_GGA_V02 ((NmeaSentenceTypesMask)0x00000001) /**< Enable GGA type */
+#define LOC_NMEA_MASK_RMC_V02 ((NmeaSentenceTypesMask)0x00000002) /**< Enable RMC type */
+#define LOC_NMEA_MASK_GSV_V02 ((NmeaSentenceTypesMask)0x00000004) /**< Enable GSV type */
+#define LOC_NMEA_MASK_GSA_V02 ((NmeaSentenceTypesMask)0x00000008) /**< Enable GSA type */
+#define LOC_NMEA_MASK_VTG_V02 ((NmeaSentenceTypesMask)0x00000010) /**< Enable VTG type */
+#define LOC_NMEA_MASK_PQXFI_V02 ((NmeaSentenceTypesMask)0x00000020) /**< Enable PQXFI type */
+#define LOC_NMEA_MASK_PSTIS_V02 ((NmeaSentenceTypesMask)0x00000040) /**< Enable PSTIS type */
+#define LOC_NMEA_MASK_GLGSV_V02 ((NmeaSentenceTypesMask)0x00000080) /**< Enable GLGSV type */
+#define LOC_NMEA_MASK_GNGSA_V02 ((NmeaSentenceTypesMask)0x00000100) /**< Enable GNGSA type */
+#define LOC_NMEA_MASK_GNGNS_V02 ((NmeaSentenceTypesMask)0x00000200) /**< Enable GNGNS type */
+#define LOC_NMEA_MASK_GARMC_V02 ((NmeaSentenceTypesMask)0x00000400) /**< Enable GARMC type */
+#define LOC_NMEA_MASK_GAGSV_V02 ((NmeaSentenceTypesMask)0x00000800) /**< Enable GAGSV type */
+#define LOC_NMEA_MASK_GAGSA_V02 ((NmeaSentenceTypesMask)0x00001000) /**< Enable GAGSA type */
+#define LOC_NMEA_MASK_GAVTG_V02 ((NmeaSentenceTypesMask)0x00002000) /**< Enable GAVTG type */
+#define LOC_NMEA_MASK_GAGGA_V02 ((NmeaSentenceTypesMask)0x00004000) /**< Enable GAGGA type */
+#define LOC_NMEA_MASK_PQGSA_V02 ((NmeaSentenceTypesMask)0x00008000) /**< Enable PQGSA type */
+#define LOC_NMEA_MASK_PQGSV_V02 ((NmeaSentenceTypesMask)0x00010000) /**< Enable PQGSV type */
+#define LOC_NMEA_MASK_DEBUG_V02 ((NmeaSentenceTypesMask)0x00020000) /**< Enable DEBUG type */
+
+// all bitmasks of general supported NMEA sentenses - debug is not part of this
+#define LOC_NMEA_ALL_GENERAL_SUPPORTED_MASK (LOC_NMEA_MASK_GGA_V02 | LOC_NMEA_MASK_RMC_V02 | \
+ LOC_NMEA_MASK_GSV_V02 | LOC_NMEA_MASK_GSA_V02 | LOC_NMEA_MASK_VTG_V02 | \
+ LOC_NMEA_MASK_PQXFI_V02 | LOC_NMEA_MASK_PSTIS_V02 | LOC_NMEA_MASK_GLGSV_V02 | \
+ LOC_NMEA_MASK_GNGSA_V02 | LOC_NMEA_MASK_GNGNS_V02 | LOC_NMEA_MASK_GARMC_V02 | \
+ LOC_NMEA_MASK_GAGSV_V02 | LOC_NMEA_MASK_GAGSA_V02 | LOC_NMEA_MASK_GAVTG_V02 | \
+ LOC_NMEA_MASK_GAGGA_V02 | LOC_NMEA_MASK_PQGSA_V02 | LOC_NMEA_MASK_PQGSV_V02)
+
+typedef enum {
+ LOC_ENG_IF_REQUEST_SENDER_ID_QUIPC = 0,
+ LOC_ENG_IF_REQUEST_SENDER_ID_MSAPM,
+ LOC_ENG_IF_REQUEST_SENDER_ID_MSAPU,
+ 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;
+
+
+#define smaller_of(a, b) (((a) > (b)) ? (b) : (a))
+#define MAX_APN_LEN 100
+
+// This will be overridden by the individual adapters
+// if necessary.
+#define DEFAULT_IMPL(rtv) \
+{ \
+ LOC_LOGD("%s: default implementation invoked", __func__); \
+ return rtv; \
+}
+
+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_INTERNAL = 10,
+
+ /* equating engine down to phone offline, as they are the same errror */
+ LOC_API_ADAPTER_ERR_ENGINE_DOWN = LOC_API_ADAPTER_ERR_PHONE_OFFLINE,
+ LOC_API_ADAPTER_ERR_FAILURE = 101,
+ 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_REQUEST_WIFI, //
+ LOC_API_ADAPTER_SENSOR_STATUS, //
+ LOC_API_ADAPTER_REQUEST_TIME_SYNC, //
+ LOC_API_ADAPTER_REPORT_SPI, //
+ LOC_API_ADAPTER_REPORT_NI_GEOFENCE, //
+ LOC_API_ADAPTER_GEOFENCE_GEN_ALERT, //
+ LOC_API_ADAPTER_REPORT_GENFENCE_BREACH, //
+ LOC_API_ADAPTER_PEDOMETER_CTRL, //
+ LOC_API_ADAPTER_MOTION_CTRL, //
+ LOC_API_ADAPTER_REQUEST_WIFI_AP_DATA, // Wifi ap data
+ LOC_API_ADAPTER_BATCH_FULL, // Batching on full
+ LOC_API_ADAPTER_BATCHED_POSITION_REPORT, // Batching on fix
+ LOC_API_ADAPTER_BATCHED_GENFENCE_BREACH_REPORT, //
+ LOC_API_ADAPTER_GNSS_MEASUREMENT_REPORT, //GNSS Measurement Report
+ LOC_API_ADAPTER_GNSS_SV_POLYNOMIAL_REPORT, //GNSS SV Polynomial Report
+ LOC_API_ADAPTER_GDT_UPLOAD_BEGIN_REQ, // GDT upload start request
+ LOC_API_ADAPTER_GDT_UPLOAD_END_REQ, // GDT upload end request
+ LOC_API_ADAPTER_GNSS_MEASUREMENT, // GNSS Measurement report
+ LOC_API_ADAPTER_REQUEST_TIMEZONE, // Timezone injection request
+ LOC_API_ADAPTER_REPORT_GENFENCE_DWELL_REPORT, // Geofence dwell report
+ LOC_API_ADAPTER_REQUEST_SRN_DATA, // request srn data from AP
+ LOC_API_ADAPTER_REQUEST_POSITION_INJECTION, // Position injection request
+ LOC_API_ADAPTER_BATCH_STATUS, // batch status
+ 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)
+#define LOC_API_ADAPTER_BIT_REQUEST_WIFI (1<<LOC_API_ADAPTER_REQUEST_WIFI)
+#define LOC_API_ADAPTER_BIT_SENSOR_STATUS (1<<LOC_API_ADAPTER_SENSOR_STATUS)
+#define LOC_API_ADAPTER_BIT_REQUEST_TIME_SYNC (1<<LOC_API_ADAPTER_REQUEST_TIME_SYNC)
+#define LOC_API_ADAPTER_BIT_REPORT_SPI (1<<LOC_API_ADAPTER_REPORT_SPI)
+#define LOC_API_ADAPTER_BIT_REPORT_NI_GEOFENCE (1<<LOC_API_ADAPTER_REPORT_NI_GEOFENCE)
+#define LOC_API_ADAPTER_BIT_GEOFENCE_GEN_ALERT (1<<LOC_API_ADAPTER_GEOFENCE_GEN_ALERT)
+#define LOC_API_ADAPTER_BIT_REPORT_GENFENCE_BREACH (1<<LOC_API_ADAPTER_REPORT_GENFENCE_BREACH)
+#define LOC_API_ADAPTER_BIT_BATCHED_GENFENCE_BREACH_REPORT (1<<LOC_API_ADAPTER_BATCHED_GENFENCE_BREACH_REPORT)
+#define LOC_API_ADAPTER_BIT_PEDOMETER_CTRL (1<<LOC_API_ADAPTER_PEDOMETER_CTRL)
+#define LOC_API_ADAPTER_BIT_MOTION_CTRL (1<<LOC_API_ADAPTER_MOTION_CTRL)
+#define LOC_API_ADAPTER_BIT_REQUEST_WIFI_AP_DATA (1<<LOC_API_ADAPTER_REQUEST_WIFI_AP_DATA)
+#define LOC_API_ADAPTER_BIT_BATCH_FULL (1<<LOC_API_ADAPTER_BATCH_FULL)
+#define LOC_API_ADAPTER_BIT_BATCHED_POSITION_REPORT (1<<LOC_API_ADAPTER_BATCHED_POSITION_REPORT)
+#define LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT_REPORT (1<<LOC_API_ADAPTER_GNSS_MEASUREMENT_REPORT)
+#define LOC_API_ADAPTER_BIT_GNSS_SV_POLYNOMIAL_REPORT (1<<LOC_API_ADAPTER_GNSS_SV_POLYNOMIAL_REPORT)
+#define LOC_API_ADAPTER_BIT_GDT_UPLOAD_BEGIN_REQ (1<<LOC_API_ADAPTER_GDT_UPLOAD_BEGIN_REQ)
+#define LOC_API_ADAPTER_BIT_GDT_UPLOAD_END_REQ (1<<LOC_API_ADAPTER_GDT_UPLOAD_END_REQ)
+#define LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT (1<<LOC_API_ADAPTER_GNSS_MEASUREMENT)
+#define LOC_API_ADAPTER_BIT_REQUEST_TIMEZONE (1<<LOC_API_ADAPTER_REQUEST_TIMEZONE)
+#define LOC_API_ADAPTER_BIT_REPORT_GENFENCE_DWELL (1<<LOC_API_ADAPTER_REPORT_GENFENCE_DWELL_REPORT)
+#define LOC_API_ADAPTER_BIT_REQUEST_SRN_DATA (1<<LOC_API_ADAPTER_REQUEST_SRN_DATA)
+#define LOC_API_ADAPTER_BIT_POSITION_INJECTION_REQUEST (1<<LOC_API_ADAPTER_REQUEST_POSITION_INJECTION)
+#define LOC_API_ADAPTER_BIT_BATCH_STATUS (1<<LOC_API_ADAPTER_BATCH_STATUS)
+
+
+typedef unsigned int LOC_API_ADAPTER_EVENT_MASK_T;
+
+typedef enum loc_api_adapter_msg_to_check_supported {
+ LOC_API_ADAPTER_MESSAGE_LOCATION_BATCHING, // Batching 1.0
+ LOC_API_ADAPTER_MESSAGE_BATCHED_GENFENCE_BREACH, // Geofence Batched Breach
+ LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_TRACKING, // DBT 2.0
+ LOC_API_ADAPTER_MESSAGE_ADAPTIVE_LOCATION_BATCHING, // Batching 1.5
+ LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_LOCATION_BATCHING, // Batching 2.0
+ LOC_API_ADAPTER_MESSAGE_UPDATE_TBF_ON_THE_FLY, // Updating Tracking TBF On The Fly
+ LOC_API_ADAPTER_MESSAGE_OUTDOOR_TRIP_BATCHING, // Outdoor Trip Batching
+
+ LOC_API_ADAPTER_MESSAGE_MAX
+} LocCheckingMessagesID;
+
+typedef int IzatDevId_t;
+
+typedef uint32_t LOC_GPS_LOCK_MASK;
+#define isGpsLockNone(lock) ((lock) == 0)
+#define isGpsLockMO(lock) ((lock) & ((LOC_GPS_LOCK_MASK)1))
+#define isGpsLockMT(lock) ((lock) & ((LOC_GPS_LOCK_MASK)2))
+#define isGpsLockAll(lock) (((lock) & ((LOC_GPS_LOCK_MASK)3)) == 3)
+
+/*++ ***********************************************
+** Satellite Measurement and Satellite Polynomial
+** Structure definitions
+** ***********************************************
+--*/
+#define GNSS_SV_POLY_VELOCITY_COEF_MAX_SIZE 12
+#define GNSS_SV_POLY_XYZ_0_TH_ORDER_COEFF_MAX_SIZE 3
+#define GNSS_SV_POLY_XYZ_N_TH_ORDER_COEFF_MAX_SIZE 9
+#define GNSS_SV_POLY_SV_CLKBIAS_COEFF_MAX_SIZE 4
+#define GNSS_LOC_SV_MEAS_LIST_MAX_SIZE 16
+
+enum ulp_gnss_sv_measurement_valid_flags{
+
+ ULP_GNSS_SV_MEAS_GPS_TIME = 0,
+ ULP_GNSS_SV_MEAS_PSUEDO_RANGE,
+ ULP_GNSS_SV_MEAS_MS_IN_WEEK,
+ ULP_GNSS_SV_MEAS_SUB_MSEC,
+ ULP_GNSS_SV_MEAS_CARRIER_PHASE,
+ ULP_GNSS_SV_MEAS_DOPPLER_SHIFT,
+ ULP_GNSS_SV_MEAS_CNO,
+ ULP_GNSS_SV_MEAS_LOSS_OF_LOCK,
+
+ ULP_GNSS_SV_MEAS_MAX_VALID_FLAGS
+};
+
+#define ULP_GNSS_SV_MEAS_BIT_GPS_TIME (1<<ULP_GNSS_SV_MEAS_GPS_TIME)
+#define ULP_GNSS_SV_MEAS_BIT_PSUEDO_RANGE (1<<ULP_GNSS_SV_MEAS_PSUEDO_RANGE)
+#define ULP_GNSS_SV_MEAS_BIT_MS_IN_WEEK (1<<ULP_GNSS_SV_MEAS_MS_IN_WEEK)
+#define ULP_GNSS_SV_MEAS_BIT_SUB_MSEC (1<<ULP_GNSS_SV_MEAS_SUB_MSEC)
+#define ULP_GNSS_SV_MEAS_BIT_CARRIER_PHASE (1<<ULP_GNSS_SV_MEAS_CARRIER_PHASE)
+#define ULP_GNSS_SV_MEAS_BIT_DOPPLER_SHIFT (1<<ULP_GNSS_SV_MEAS_DOPPLER_SHIFT)
+#define ULP_GNSS_SV_MEAS_BIT_CNO (1<<ULP_GNSS_SV_MEAS_CNO)
+#define ULP_GNSS_SV_MEAS_BIT_LOSS_OF_LOCK (1<<ULP_GNSS_SV_MEAS_LOSS_OF_LOCK)
+
+enum ulp_gnss_sv_poly_valid_flags{
+
+ ULP_GNSS_SV_POLY_GLO_FREQ = 0,
+ ULP_GNSS_SV_POLY_T0,
+ ULP_GNSS_SV_POLY_IODE,
+ ULP_GNSS_SV_POLY_FLAG,
+ ULP_GNSS_SV_POLY_POLYCOEFF_XYZ0,
+ ULP_GNSS_SV_POLY_POLYCOEFF_XYZN,
+ ULP_GNSS_SV_POLY_POLYCOEFF_OTHER,
+ ULP_GNSS_SV_POLY_SV_POSUNC,
+ ULP_GNSS_SV_POLY_IONODELAY,
+ ULP_GNSS_SV_POLY_IONODOT,
+ ULP_GNSS_SV_POLY_SBAS_IONODELAY,
+ ULP_GNSS_SV_POLY_SBAS_IONODOT,
+ ULP_GNSS_SV_POLY_TROPODELAY,
+ ULP_GNSS_SV_POLY_ELEVATION,
+ ULP_GNSS_SV_POLY_ELEVATIONDOT,
+ ULP_GNSS_SV_POLY_ELEVATIONUNC,
+ ULP_GNSS_SV_POLY_VELO_COEFF,
+ ULP_GNSS_SV_POLY_ENHANCED_IOD,
+
+ ULP_GNSS_SV_POLY_VALID_FLAGS
+
+};
+
+#define ULP_GNSS_SV_POLY_BIT_GLO_FREQ (1<<ULP_GNSS_SV_POLY_GLO_FREQ)
+#define ULP_GNSS_SV_POLY_BIT_T0 (1<<ULP_GNSS_SV_POLY_T0)
+#define ULP_GNSS_SV_POLY_BIT_IODE (1<<ULP_GNSS_SV_POLY_IODE)
+#define ULP_GNSS_SV_POLY_BIT_FLAG (1<<ULP_GNSS_SV_POLY_FLAG)
+#define ULP_GNSS_SV_POLY_BIT_POLYCOEFF_XYZ0 (1<<ULP_GNSS_SV_POLY_POLYCOEFF_XYZ0)
+#define ULP_GNSS_SV_POLY_BIT_POLYCOEFF_XYZN (1<<ULP_GNSS_SV_POLY_POLYCOEFF_XYZN)
+#define ULP_GNSS_SV_POLY_BIT_POLYCOEFF_OTHER (1<<ULP_GNSS_SV_POLY_POLYCOEFF_OTHER)
+#define ULP_GNSS_SV_POLY_BIT_SV_POSUNC (1<<ULP_GNSS_SV_POLY_SV_POSUNC)
+#define ULP_GNSS_SV_POLY_BIT_IONODELAY (1<<ULP_GNSS_SV_POLY_IONODELAY)
+#define ULP_GNSS_SV_POLY_BIT_IONODOT (1<<ULP_GNSS_SV_POLY_IONODOT)
+#define ULP_GNSS_SV_POLY_BIT_SBAS_IONODELAY (1<<ULP_GNSS_SV_POLY_SBAS_IONODELAY)
+#define ULP_GNSS_SV_POLY_BIT_SBAS_IONODOT (1<<ULP_GNSS_SV_POLY_SBAS_IONODOT)
+#define ULP_GNSS_SV_POLY_BIT_TROPODELAY (1<<ULP_GNSS_SV_POLY_TROPODELAY)
+#define ULP_GNSS_SV_POLY_BIT_ELEVATION (1<<ULP_GNSS_SV_POLY_ELEVATION)
+#define ULP_GNSS_SV_POLY_BIT_ELEVATIONDOT (1<<ULP_GNSS_SV_POLY_ELEVATIONDOT)
+#define ULP_GNSS_SV_POLY_BIT_ELEVATIONUNC (1<<ULP_GNSS_SV_POLY_ELEVATIONUNC)
+#define ULP_GNSS_SV_POLY_BIT_VELO_COEFF (1<<ULP_GNSS_SV_POLY_VELO_COEFF)
+#define ULP_GNSS_SV_POLY_BIT_ENHANCED_IOD (1<<ULP_GNSS_SV_POLY_ENHANCED_IOD)
+
+
+typedef enum
+{
+ GNSS_LOC_SV_SYSTEM_GPS = 1,
+ /**< GPS satellite. */
+ GNSS_LOC_SV_SYSTEM_GALILEO = 2,
+ /**< GALILEO satellite. */
+ GNSS_LOC_SV_SYSTEM_SBAS = 3,
+ /**< SBAS satellite. */
+ GNSS_LOC_SV_SYSTEM_COMPASS = 4,
+ /**< COMPASS satellite. */
+ GNSS_LOC_SV_SYSTEM_GLONASS = 5,
+ /**< GLONASS satellite. */
+ GNSS_LOC_SV_SYSTEM_BDS = 6,
+ /**< BDS satellite. */
+ GNSS_LOC_SV_SYSTEM_QZSS = 7
+ /**< QZSS satellite. */
+} Gnss_LocSvSystemEnumType;
+
+typedef enum
+{
+ GNSS_LOC_FREQ_SOURCE_INVALID = 0,
+ /**< Source of the frequency is invalid */
+ GNSS_LOC_FREQ_SOURCE_EXTERNAL = 1,
+ /**< Source of the frequency is from external injection */
+ GNSS_LOC_FREQ_SOURCE_PE_CLK_REPORT = 2,
+ /**< Source of the frequency is from Navigation engine */
+ GNSS_LOC_FREQ_SOURCE_UNKNOWN = 3
+ /**< Source of the frequency is unknown */
+} Gnss_LocSourceofFreqEnumType;
+
+typedef struct
+{
+ size_t size;
+ float clockDrift;
+ /**< Receiver clock Drift \n
+ - Units: meter per sec \n
+ */
+ float clockDriftUnc;
+ /**< Receiver clock Drift uncertainty \n
+ - Units: meter per sec \n
+ */
+ Gnss_LocSourceofFreqEnumType sourceOfFreq;
+}Gnss_LocRcvrClockFrequencyInfoStructType;
+
+typedef struct
+{
+ size_t size;
+ uint8_t leapSec;
+ /**< GPS time leap second delta to UTC time \n
+ - Units: sec \n
+ */
+ uint8_t leapSecUnc;
+ /**< Uncertainty for GPS leap second \n
+ - Units: sec \n
+ */
+}Gnss_LeapSecondInfoStructType;
+
+typedef enum
+{
+ GNSS_LOC_SYS_TIME_BIAS_VALID = 0x01,
+ /**< System time bias valid */
+ GNSS_LOC_SYS_TIME_BIAS_UNC_VALID = 0x02,
+ /**< System time bias uncertainty valid */
+}Gnss_LocInterSystemBiasValidMaskType;
+
+typedef struct
+{
+ size_t size;
+ uint32_t validMask;
+ /* Validity mask as per Gnss_LocInterSystemBiasValidMaskType */
+
+ float timeBias;
+ /**< System-1 to System-2 Time Bias \n
+ - Units: msec \n
+ */
+ float timeBiasUnc;
+ /**< System-1 to System-2 Time Bias uncertainty \n
+ - Units: msec \n
+ */
+}Gnss_InterSystemBiasStructType;
+
+
+typedef struct
+{
+ size_t size;
+ uint16_t systemWeek;
+ /**< System week number for GPS, BDS and GAL satellite systems. \n
+ Set to 65535 when invalid or not available. \n
+ Not valid for GLONASS system. \n
+ */
+
+ uint32_t systemMsec;
+ /**< System time msec. Time of Week for GPS, BDS, GAL and
+ Time of Day for GLONASS.
+ - Units: msec \n
+ */
+ float systemClkTimeBias;
+ /**< System clock time bias \n
+ - Units: msec \n
+ System time = systemMsec - systemClkTimeBias \n
+ */
+ float systemClkTimeUncMs;
+ /**< Single sided maximum time bias uncertainty \n
+ - Units: msec \n
+ */
+}Gnss_LocSystemTimeStructType;
+
+typedef struct {
+
+ size_t size;
+ uint8_t gloFourYear;
+ /**< GLONASS four year number from 1996. Refer to GLONASS ICD.\n
+ Applicable only for GLONASS and shall be ignored for other constellations. \n
+ If unknown shall be set to 255
+ */
+
+ uint16_t gloDays;
+ /**< GLONASS day number in four years. Refer to GLONASS ICD.
+ Applicable only for GLONASS and shall be ignored for other constellations. \n
+ If unknown shall be set to 65535
+ */
+
+ uint32_t gloMsec;
+ /**< GLONASS time of day in msec. Refer to GLONASS ICD.
+ - Units: msec \n
+ */
+
+ float gloClkTimeBias;
+ /**< System clock time bias (sub-millisecond) \n
+ - Units: msec \n
+ System time = systemMsec - systemClkTimeBias \n
+ */
+
+ float gloClkTimeUncMs;
+ /**< Single sided maximum time bias uncertainty \n
+ - Units: msec \n
+ */
+}Gnss_LocGloTimeStructType; /* Type */
+
+typedef struct {
+
+ size_t size;
+ uint32_t refFCount;
+ /**< Receiver frame counter value at reference tick */
+
+ uint8_t systemRtc_valid;
+ /**< Validity indicator for System RTC */
+
+ uint64_t systemRtcMs;
+ /**< Platform system RTC value \n
+ - Units: msec \n
+ */
+
+ uint32_t sourceOfTime;
+ /**< Source of time information */
+
+}Gnss_LocGnssTimeExtStructType;
+
+
+
+typedef enum
+{
+ GNSS_LOC_MEAS_STATUS_NULL = 0x00000000,
+ /**< No information state */
+ GNSS_LOC_MEAS_STATUS_SM_VALID = 0x00000001,
+ /**< Code phase is known */
+ GNSS_LOC_MEAS_STATUS_SB_VALID = 0x00000002,
+ /**< Sub-bit time is known */
+ GNSS_LOC_MEAS_STATUS_MS_VALID = 0x00000004,
+ /**< Satellite time is known */
+ GNSS_LOC_MEAS_STATUS_BE_CONFIRM = 0x00000008,
+ /**< Bit edge is confirmed from signal */
+ GNSS_LOC_MEAS_STATUS_VELOCITY_VALID = 0x00000010,
+ /**< Satellite Doppler measured */
+ GNSS_LOC_MEAS_STATUS_VELOCITY_FINE = 0x00000020,
+ /**< TRUE: Fine Doppler measured, FALSE: Coarse Doppler measured */
+ GNSS_LOC_MEAS_STATUS_FROM_RNG_DIFF = 0x00000200,
+ /**< Range update from Satellite differences */
+ GNSS_LOC_MEAS_STATUS_FROM_VE_DIFF = 0x00000400,
+ /**< Doppler update from Satellite differences */
+ GNSS_LOC_MEAS_STATUS_DONT_USE_X = 0x00000800,
+ /**< Don't use measurement if bit is set */
+ GNSS_LOC_MEAS_STATUS_DONT_USE_M = 0x000001000,
+ /**< Don't use measurement if bit is set */
+ GNSS_LOC_MEAS_STATUS_DONT_USE_D = 0x000002000,
+ /**< Don't use measurement if bit is set */
+ GNSS_LOC_MEAS_STATUS_DONT_USE_S = 0x000004000,
+ /**< Don't use measurement if bit is set */
+ GNSS_LOC_MEAS_STATUS_DONT_USE_P = 0x000008000
+ /**< Don't use measurement if bit is set */
+}Gnss_LocSvMeasStatusMaskType;
+
+typedef struct
+{
+ size_t size;
+ uint32_t svMs;
+ /**< Satellite time milisecond.\n
+ For GPS, BDS, GAL range of 0 thru (604800000-1) \n
+ For GLONASS range of 0 thru (86400000-1) \n
+ Valid when PD_LOC_MEAS_STATUS_MS_VALID bit is set in measurement status \n
+ Note: All SV times in the current measurement block are alredy propagated to common reference time epoch. \n
+ - Units: msec \n
+ */
+ float svSubMs;
+ /**<Satellite time sub-millisecond. \n
+ Total SV Time = svMs + svSubMs \n
+ - Units: msec \n
+ */
+ float svTimeUncMs;
+ /**< Satellite Time uncertainty \n
+ - Units: msec \n
+ */
+ float dopplerShift;
+ /**< Satellite Doppler \n
+ - Units: meter per sec \n
+ */
+ float dopplerShiftUnc;
+ /**< Satellite Doppler uncertainty\n
+ - Units: meter per sec \n
+ */
+}Gnss_LocSVTimeSpeedStructType;
+
+typedef enum
+{
+ GNSS_SV_STATE_IDLE = 0,
+ GNSS_SV_STATE_SEARCH = 1,
+ GNSS_SV_STATE_SEARCH_VERIFY = 2,
+ GNSS_SV_STATE_BIT_EDGE = 3,
+ GNSS_SV_STATE_VERIFY_TRACK = 4,
+ GNSS_SV_STATE_TRACK = 5,
+ GNSS_SV_STATE_RESTART = 6,
+ GNSS_SV_STATE_DPO_TRACK = 7
+} Gnss_LocSVStateEnumType;
+
+typedef enum
+{
+ GNSS_LOC_SVINFO_MASK_HAS_EPHEMERIS = 0x01,
+ /**< Ephemeris is available for this SV */
+ GNSS_LOC_SVINFO_MASK_HAS_ALMANAC = 0x02
+ /**< Almanac is available for this SV */
+}Gnss_LocSvInfoMaskT;
+
+typedef enum
+{
+ GNSS_LOC_SV_SRCH_STATUS_IDLE = 1,
+ /**< SV is not being actively processed */
+ GNSS_LOC_SV_SRCH_STATUS_SEARCH = 2,
+ /**< The system is searching for this SV */
+ GNSS_LOC_SV_SRCH_STATUS_TRACK = 3
+ /**< SV is being tracked */
+}Gnss_LocSvSearchStatusEnumT;
+
+
+typedef struct
+{
+ size_t size;
+ uint16_t gnssSvId;
+ /**< GNSS SV ID.
+ \begin{itemize1}
+ \item Range: \begin{itemize1}
+ \item For GPS: 1 to 32
+ \item For GLONASS: 1 to 32
+ \item For SBAS: 120 to 151
+ \item For BDS: 201 to 237
+ \end{itemize1} \end{itemize1}
+ The GPS and GLONASS SVs can be disambiguated using the system field.
+ */
+ uint8_t gloFrequency;
+ /**< GLONASS frequency number + 7 \n
+ Valid only for GLONASS System \n
+ Shall be ignored for all other systems \n
+ - Range: 1 to 14 \n
+ */
+ Gnss_LocSvSearchStatusEnumT svStatus;
+ /**< Satellite search state \n
+ @ENUM()
+ */
+ bool healthStatus_valid;
+ /**< SV Health Status validity flag\n
+ - 0: Not valid \n
+ - 1: Valid \n
+ */
+ uint8_t healthStatus;
+ /**< Health status.
+ \begin{itemize1}
+ \item Range: 0 to 1; 0 = unhealthy, \n 1 = healthy, 2 = unknown
+ \vspace{-0.18in} \end{itemize1}
+ */
+ Gnss_LocSvInfoMaskT svInfoMask;
+ /**< Indicates whether almanac and ephemeris information is available. \n
+ @MASK()
+ */
+ uint64_t measurementStatus;
+ /**< Bitmask indicating SV measurement status.
+ Valid bitmasks: \n
+ If any MSB bit in 0xFFC0000000000000 DONT_USE is set, the measurement
+ must not be used by the client.
+ @MASK()
+ */
+ uint16_t CNo;
+ /**< Carrier to Noise ratio \n
+ - Units: 0.1 dBHz \n
+ */
+ uint16_t gloRfLoss;
+ /**< GLONASS Rf loss reference to Antenna. \n
+ - Units: dB, Scale: 0.1 \n
+ */
+ bool lossOfLock;
+ /**< Loss of signal lock indicator \n
+ - 0: Signal in continuous track \n
+ - 1: Signal not in track \n
+ */
+ int16_t measLatency;
+ /**< Age of the measurement. Positive value means measurement precedes ref time. \n
+ - Units: msec \n
+ */
+ Gnss_LocSVTimeSpeedStructType svTimeSpeed;
+ /**< Unfiltered SV Time and Speed information
+ */
+ float dopplerAccel;
+ /**< Satellite Doppler Accelertion\n
+ - Units: Hz/s \n
+ */
+ bool multipathEstValid;
+ /**< Multipath estimate validity flag\n
+ - 0: Multipath estimate not valid \n
+ - 1: Multipath estimate valid \n
+ */
+ float multipathEstimate;
+ /**< Estimate of multipath in measurement\n
+ - Units: Meters \n
+ */
+ bool fineSpeedValid;
+ /**< Fine speed validity flag\n
+ - 0: Fine speed not valid \n
+ - 1: Fine speed valid \n
+ */
+ float fineSpeed;
+ /**< Carrier phase derived speed \n
+ - Units: m/s \n
+ */
+ bool fineSpeedUncValid;
+ /**< Fine speed uncertainty validity flag\n
+ - 0: Fine speed uncertainty not valid \n
+ - 1: Fine speed uncertainty valid \n
+ */
+ float fineSpeedUnc;
+ /**< Carrier phase derived speed \n
+ - Units: m/s \n
+ */
+ bool carrierPhaseValid;
+ /**< Carrier Phase measurement validity flag\n
+ - 0: Carrier Phase not valid \n
+ - 1: Carrier Phase valid \n
+ */
+ double carrierPhase;
+ /**< Carrier phase measurement [L1 cycles] \n
+ */
+ bool cycleSlipCountValid;
+ /**< Cycle slup count validity flag\n
+ - 0: Not valid \n
+ - 1: Valid \n
+ */
+ uint8_t cycleSlipCount;
+ /**< Increments when a CSlip is detected */
+
+ bool svDirectionValid;
+ /**< Validity flag for SV direction */
+
+ float svAzimuth;
+ /**< Satellite Azimuth
+ - Units: radians \n
+ */
+ float svElevation;
+ /**< Satellite Elevation
+ - Units: radians \n
+ */
+} Gnss_SVMeasurementStructType;
+
+/**< Maximum number of satellites in measurement block for given system. */
+
+typedef struct
+{
+ size_t size;
+ Gnss_LocSvSystemEnumType system;
+ /**< Specifies the Satellite System Type
+ */
+ bool isSystemTimeValid;
+ /**< Indicates whether System Time is Valid:\n
+ - 0x01 (TRUE) -- System Time is valid \n
+ - 0x00 (FALSE) -- System Time is not valid
+ */
+ Gnss_LocSystemTimeStructType systemTime;
+ /**< System Time Information \n
+ */
+ bool isGloTime_valid;
+ Gnss_LocGloTimeStructType gloTime;
+
+ bool isSystemTimeExt_valid;
+ Gnss_LocGnssTimeExtStructType systemTimeExt;
+
+ uint8_t numSvs;
+ /* Number of SVs in this report block */
+
+ Gnss_SVMeasurementStructType svMeasurement[GNSS_LOC_SV_MEAS_LIST_MAX_SIZE];
+ /**< Satellite measurement Information \n
+ */
+} Gnss_ClockMeasurementStructType;
+
+
+typedef struct
+{
+ size_t size;
+ uint8_t seqNum;
+ /**< Current message Number */
+ uint8_t maxMessageNum;
+ /**< Maximum number of message that will be sent for present time epoch. */
+
+ bool leapSecValid;
+ Gnss_LeapSecondInfoStructType leapSec;
+
+ Gnss_InterSystemBiasStructType gpsGloInterSystemBias;
+
+ Gnss_InterSystemBiasStructType gpsBdsInterSystemBias;
+
+ Gnss_InterSystemBiasStructType gpsGalInterSystemBias;
+
+ Gnss_InterSystemBiasStructType bdsGloInterSystemBias;
+
+ Gnss_InterSystemBiasStructType galGloInterSystemBias;
+
+ Gnss_InterSystemBiasStructType galBdsInterSystemBias;
+
+ bool clockFreqValid;
+ Gnss_LocRcvrClockFrequencyInfoStructType clockFreq; /* Freq */
+ bool gnssMeasValid;
+ Gnss_ClockMeasurementStructType gnssMeas;
+ Gnss_ApTimeStampStructType timeStamp;
+
+} GnssSvMeasurementSet;
+
+typedef enum
+{
+ GNSS_SV_POLY_COEFF_VALID = 0x01,
+ /**< SV position in orbit coefficients are valid */
+ GNSS_SV_POLY_IONO_VALID = 0x02,
+ /**< Iono estimates are valid */
+
+ GNSS_SV_POLY_TROPO_VALID = 0x04,
+ /**< Tropo estimates are valid */
+
+ GNSS_SV_POLY_ELEV_VALID = 0x08,
+ /**< Elevation, rate, uncertainty are valid */
+
+ GNSS_SV_POLY_SRC_ALM_CORR = 0x10,
+ /**< Polynomials based on XTRA */
+
+ GNSS_SV_POLY_SBAS_IONO_VALID = 0x20,
+ /**< SBAS IONO and rate are valid */
+
+ GNSS_SV_POLY_GLO_STR4 = 0x40
+ /**< GLONASS String 4 has been received */
+}Gnss_SvPolyStatusMaskType;
+
+
+typedef struct
+{
+ size_t size;
+ uint16_t gnssSvId;
+ /* GPS: 1-32, GLO: 65-96, 0: Invalid,
+ SBAS: 120-151, BDS:201-237,GAL:301 to 336
+ All others are reserved
+ */
+ int8_t freqNum;
+ /* Freq index, only valid if u_SysInd is GLO */
+
+ uint8_t svPolyFlags;
+ /* Indicate the validity of the elements
+ as per Gnss_SvPolyStatusMaskType
+ */
+
+ uint32_t is_valid;
+
+ uint16_t iode;
+ /* Ephemeris reference time
+ GPS:Issue of Data Ephemeris used [unitless].
+ GLO: Tb 7-bit, refer to ICD02
+ */
+ double T0;
+ /* Reference time for polynominal calculations
+ GPS: Secs in week.
+ GLO: Full secs since Jan/01/96
+ */
+ double polyCoeffXYZ0[GNSS_SV_POLY_XYZ_0_TH_ORDER_COEFF_MAX_SIZE];
+ /* C0X, C0Y, C0Z */
+ double polyCoefXYZN[GNSS_SV_POLY_XYZ_N_TH_ORDER_COEFF_MAX_SIZE];
+ /* C1X, C2X ... C2Z, C3Z */
+ float polyCoefOther[GNSS_SV_POLY_SV_CLKBIAS_COEFF_MAX_SIZE];
+ /* C0T, C1T, C2T, C3T */
+ float svPosUnc; /* SV position uncertainty [m]. */
+ float ionoDelay; /* Ionospheric delay at d_T0 [m]. */
+ float ionoDot; /* Iono delay rate [m/s]. */
+ float sbasIonoDelay;/* SBAS Ionospheric delay at d_T0 [m]. */
+ float sbasIonoDot; /* SBAS Iono delay rate [m/s]. */
+ float tropoDelay; /* Tropospheric delay [m]. */
+ float elevation; /* Elevation [rad] at d_T0 */
+ float elevationDot; /* Elevation rate [rad/s] */
+ float elevationUnc; /* SV elevation [rad] uncertainty */
+ double velCoef[GNSS_SV_POLY_VELOCITY_COEF_MAX_SIZE];
+ /* Coefficients of velocity poly */
+ uint32_t enhancedIOD; /* Enhanced Reference Time */
+} GnssSvPolynomial;
+
+/* Various Short Range Node Technology type*/
+typedef enum {
+ SRN_AP_DATA_TECH_TYPE_NONE,
+ SRN_AP_DATA_TECH_TYPE_BT,
+ SRN_AP_DATA_TECH_TYPE_BTLE,
+ SRN_AP_DATA_TECH_TYPE_NFC,
+ SRN_AP_DATA_TECH_TYPE_MOBILE_CODE,
+ SRN_AP_DATA_TECH_TYPE_OTHER
+} Gnss_SrnTech;
+
+/* Mac Address type requested by modem */
+typedef enum {
+ SRN_AP_DATA_PUBLIC_MAC_ADDR_TYPE_INVALID, /* No valid mac address type send */
+ SRN_AP_DATA_PUBLIC_MAC_ADDR_TYPE_PUBLIC, /* SRN AP MAC Address type PUBLIC */
+ SRN_AP_DATA_PUBLIC_MAC_ADDR_TYPE_PRIVATE, /* SRN AP MAC Address type PRIVATE */
+ SRN_AP_DATA_PUBLIC_MAC_ADDR_TYPE_OTHER, /* SRN AP MAC Address type OTHER */
+}Gnss_Srn_MacAddr_Type;
+
+typedef struct
+{
+ size_t size;
+ Gnss_SrnTech srnTechType; /* SRN Technology type in request */
+ bool srnRequest; /* scan - start(true) or stop(false) */
+ bool e911Mode; /* If in E911 emergency */
+ Gnss_Srn_MacAddr_Type macAddrType; /* SRN AP MAC Address type */
+} GnssSrnDataReq;
+
+/*
+ * Represents the status of AGNSS augmented to support IPv4.
+ */
+struct AGnssExtStatusIpV4 {
+ AGpsExtType type;
+ LocAGpsStatusValue status;
+ /*
+ * 32-bit IPv4 address.
+ */
+ uint32_t ipV4Addr;
+};
+
+/*
+ * Represents the status of AGNSS augmented to support IPv6.
+ */
+struct AGnssExtStatusIpV6 {
+ AGpsExtType type;
+ LocAGpsStatusValue status;
+ /*
+ * 128-bit IPv6 address.
+ */
+ uint8_t ipV6Addr[16];
+};
+
+/*
+ * Callback with AGNSS(IpV4) status information.
+ *
+ * @param status Will be of type AGnssExtStatusIpV4.
+ */
+typedef void (*AgnssStatusIpV4Cb)(AGnssExtStatusIpV4 status);
+
+/*
+ * Callback with AGNSS(IpV6) status information.
+ *
+ * @param status Will be of type AGnssExtStatusIpV6.
+ */
+typedef void (*AgnssStatusIpV6Cb)(AGnssExtStatusIpV6 status);
+
+/* Constructs for interaction with loc_net_iface library */
+typedef void (*LocAgpsOpenResultCb)(bool isSuccess, AGpsExtType agpsType, const char* apn,
+ AGpsBearerType bearerType, void* userDataPtr);
+
+typedef void (*LocAgpsCloseResultCb)(bool isSuccess, AGpsExtType agpsType, void* userDataPtr);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GPS_EXTENDED_C_H */
diff --git a/gps/utils/linked_list.c b/gps/utils/linked_list.c
new file mode 100644
index 0000000..33185d0
--- /dev/null
+++ b/gps/utils/linked_list.c
@@ -0,0 +1,324 @@
+/* Copyright (c) 2011, 2014, 2017 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "linked_list.h"
+#include <stdio.h>
+#include <string.h>
+
+#define LOG_TAG "LocSvc_utils_ll"
+#include <platform_lib_includes.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*))
+{
+ 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)
+{
+ 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)
+{
+ 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..a85f09a
--- /dev/null
+++ b/gps/utils/linked_list.h
@@ -0,0 +1,217 @@
+/* Copyright (c) 2011, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef __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..d2364f6
--- /dev/null
+++ b/gps/utils/loc_cfg.cpp
@@ -0,0 +1,400 @@
+/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation, nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "LocSvc_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 <platform_lib_includes.h>
+#include <loc_misc_utils.h>
+#ifdef USE_GLIB
+#include <glib.h>
+#endif
+#include "platform_lib_includes.h"
+
+/*=============================================================================
+ *
+ * GLOBAL DATA DECLARATION
+ *
+ *============================================================================*/
+
+/* Parameter data */
+static uint32_t DEBUG_LEVEL = 0xff;
+static uint32_t TIMESTAMP = 0;
+
+/* Parameter spec table */
+static const loc_param_s_type loc_param_table[] =
+{
+ {"DEBUG_LEVEL", &DEBUG_LEVEL, NULL, 'n'},
+ {"TIMESTAMP", &TIMESTAMP, NULL, 'n'},
+};
+static const int loc_param_num = sizeof(loc_param_table) / sizeof(loc_param_s_type);
+
+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
+===========================================================================*/
+int loc_set_config_entry(const loc_param_s_type* config_entry, loc_param_v_type* config_value)
+{
+ int ret=-1;
+ if(NULL == config_entry || NULL == config_value)
+ {
+ LOC_LOGE("%s: INVALID config entry or parameter", __FUNCTION__);
+ return ret;
+ }
+
+ 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;
+ }
+ ret = 0;
+ 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;
+ }
+ ret = 0;
+ 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;
+ }
+ ret = 0;
+ break;
+ default:
+ LOC_LOGE("%s: PARAM %s parameter type must be n, f, or s",
+ __FUNCTION__, config_entry->param_name);
+ }
+ }
+ return ret;
+}
+
+/*===========================================================================
+FUNCTION loc_fill_conf_item
+
+DESCRIPTION
+ Takes a line of configuration item 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:
+ input_buf : buffer contanis config item
+ config_table: table definition of strings to places to store information
+ table_length: length of the configuration table
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ 0: Number of records in the config_table filled with input_buf
+
+SIDE EFFECTS
+ N/A
+===========================================================================*/
+int loc_fill_conf_item(char* input_buf,
+ const loc_param_s_type* config_table, uint32_t table_length)
+{
+ int ret = 0;
+
+ if (input_buf && config_table) {
+ char *lasts;
+ loc_param_v_type config_value;
+ memset(&config_value, 0, sizeof(config_value));
+
+ /* Separate variable and value */
+ config_value.param_name = strtok_r(input_buf, "=", &lasts);
+ /* skip lines that do not contain "=" */
+ if (config_value.param_name) {
+ config_value.param_str_value = strtok_r(NULL, "=", &lasts);
+
+ /* skip lines that do not contain two operands */
+ if (config_value.param_str_value) {
+ /* Trim leading and trailing spaces */
+ loc_util_trim_space(config_value.param_name);
+ loc_util_trim_space(config_value.param_str_value);
+
+ /* Parse numerical value */
+ if ((strlen(config_value.param_str_value) >=3) &&
+ (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(uint32_t i = 0; NULL != config_table && i < table_length; i++)
+ {
+ if(!loc_set_config_entry(&config_table[i], &config_value)) {
+ ret += 1;
+ }
+ }
+ }
+ }
+ }
+
+ return ret;
+}
+
+/*===========================================================================
+FUNCTION loc_read_conf_r (repetitive)
+
+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.
+ The difference between this and loc_read_conf is that this function returns
+ the file pointer position at the end of filling a config table. Also, it
+ reads a fixed number of parameters at a time which is equal to the length
+ of the configuration table. This functionality enables the caller to
+ repeatedly call the function to read data from the same file.
+
+PARAMETERS:
+ conf_fp : file pointer
+ config_table: table definition of strings to places to store information
+ table_length: length of the configuration table
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ 0: Table filled successfully
+ 1: No more parameters to read
+ -1: Error filling table
+
+SIDE EFFECTS
+ N/A
+===========================================================================*/
+int loc_read_conf_r(FILE *conf_fp, const loc_param_s_type* config_table, uint32_t table_length)
+{
+ int ret=0;
+
+ unsigned int num_params=table_length;
+ if(conf_fp == NULL) {
+ LOC_LOGE("%s:%d]: ERROR: File pointer is NULL\n", __func__, __LINE__);
+ ret = -1;
+ goto err;
+ }
+
+ /* Clear all validity bits */
+ for(uint32_t i = 0; NULL != config_table && i < table_length; i++)
+ {
+ if(NULL != config_table[i].param_set)
+ {
+ *(config_table[i].param_set) = 0;
+ }
+ }
+
+ char input_buf[LOC_MAX_PARAM_LINE]; /* declare a char array */
+
+ LOC_LOGD("%s:%d]: num_params: %d\n", __func__, __LINE__, num_params);
+ while(num_params)
+ {
+ if(!fgets(input_buf, LOC_MAX_PARAM_LINE, conf_fp)) {
+ LOC_LOGD("%s:%d]: fgets returned NULL\n", __func__, __LINE__);
+ break;
+ }
+
+ num_params -= loc_fill_conf_item(input_buf, config_table, table_length);
+ }
+
+err:
+ return ret;
+}
+
+/*===========================================================================
+FUNCTION loc_udpate_conf
+
+DESCRIPTION
+ Parses the passed in buffer for configuration items, and update the table
+ that is also passed in.
+
+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_data: configuration items in bufferas a string
+ length: strlen(conf_data)
+ config_table: table definition of strings to places to store information
+ table_length: length of the configuration table
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ number of the records in the table that is updated at time of return.
+
+SIDE EFFECTS
+ N/A
+===========================================================================*/
+int loc_update_conf(const char* conf_data, int32_t length,
+ const loc_param_s_type* config_table, uint32_t table_length)
+{
+ int ret = -1;
+
+ if (conf_data && length && config_table && table_length) {
+ // make a copy, so we do not tokenize the original data
+ char* conf_copy = (char*)malloc(length+1);
+
+ if (conf_copy != NULL)
+ {
+ memcpy(conf_copy, conf_data, length);
+ // we hard NULL the end of string to be safe
+ conf_copy[length] = 0;
+
+ // start with one record off
+ uint32_t num_params = table_length - 1;
+ char* saveptr = NULL;
+ char* input_buf = strtok_r(conf_copy, "\n", &saveptr);
+ ret = 0;
+
+ LOC_LOGD("%s:%d]: num_params: %d\n", __func__, __LINE__, num_params);
+ while(num_params && input_buf) {
+ ret++;
+ num_params -= loc_fill_conf_item(input_buf, config_table, table_length);
+ input_buf = strtok_r(NULL, "\n", &saveptr);
+ }
+ free(conf_copy);
+ }
+ }
+
+ return ret;
+}
+
+/*===========================================================================
+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, const loc_param_s_type* config_table,
+ uint32_t table_length)
+{
+ FILE *conf_fp = NULL;
+ char *lasts;
+ loc_param_v_type config_value;
+ uint32_t i;
+
+ if((conf_fp = fopen(conf_file_name, "r")) != NULL)
+ {
+ LOC_LOGD("%s: using %s", __FUNCTION__, conf_file_name);
+ if(table_length && config_table) {
+ loc_read_conf_r(conf_fp, config_table, table_length);
+ rewind(conf_fp);
+ }
+ loc_read_conf_r(conf_fp, loc_param_table, loc_param_num);
+ fclose(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..0a0f100
--- /dev/null
+++ b/gps/utils/loc_cfg.h
@@ -0,0 +1,91 @@
+/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation, nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef LOC_CFG_H
+#define LOC_CFG_H
+
+#include <stdio.h>
+#include <stdint.h>
+
+#define LOC_MAX_PARAM_NAME 80
+#define LOC_MAX_PARAM_STRING 80
+#define LOC_MAX_PARAM_LINE (LOC_MAX_PARAM_NAME + LOC_MAX_PARAM_STRING)
+
+#define UTIL_UPDATE_CONF(conf_data, len, config_table) \
+ loc_update_conf((conf_data), (len), (config_table), \
+ sizeof(config_table) / sizeof(config_table[0]))
+
+#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
+{
+ const char *param_name;
+ void *param_ptr;
+ uint8_t *param_set; /* indicate value set by config file */
+ char param_type; /* 'n' for number,
+ 's' for string,
+ 'f' for double */
+} loc_param_s_type;
+
+/*=============================================================================
+ *
+ * MODULE EXTERNAL DATA
+ *
+ *============================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*=============================================================================
+ *
+ * MODULE EXPORTED FUNCTIONS
+ *
+ *============================================================================*/
+void loc_read_conf(const char* conf_file_name,
+ const loc_param_s_type* config_table,
+ uint32_t table_length);
+int loc_read_conf_r(FILE *conf_fp, const loc_param_s_type* config_table,
+ uint32_t table_length);
+int loc_update_conf(const char* conf_data, int32_t length,
+ const loc_param_s_type* config_table, uint32_t table_length);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LOC_CFG_H */
diff --git a/gps/utils/loc_gps.h b/gps/utils/loc_gps.h
new file mode 100644
index 0000000..5e915a3
--- /dev/null
+++ b/gps/utils/loc_gps.h
@@ -0,0 +1,2209 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LOC_GPS_H
+#define LOC_GPS_H
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <pthread.h>
+#include <sys/socket.h>
+#include <stdbool.h>
+
+__BEGIN_DECLS
+
+#define LOC_FLP_STATUS_LOCATION_AVAILABLE 0
+#define LOC_FLP_STATUS_LOCATION_UNAVAILABLE 1
+#define LOC_CAPABILITY_GNSS (1U<<0)
+#define LOC_CAPABILITY_WIFI (1U<<1)
+#define LOC_CAPABILITY_CELL (1U<<3)
+
+/** Milliseconds since January 1, 1970 */
+typedef int64_t LocGpsUtcTime;
+
+/** Maximum number of SVs for loc_gps_sv_status_callback(). */
+#define LOC_GPS_MAX_SVS 32
+/** Maximum number of SVs for loc_gps_sv_status_callback(). */
+#define LOC_GNSS_MAX_SVS 64
+
+/** Maximum number of Measurements in loc_gps_measurement_callback(). */
+#define LOC_GPS_MAX_MEASUREMENT 32
+
+/** Maximum number of Measurements in loc_gnss_measurement_callback(). */
+#define LOC_GNSS_MAX_MEASUREMENT 64
+
+/** Requested operational mode for GPS operation. */
+typedef uint32_t LocGpsPositionMode;
+/* IMPORTANT: Note that the following values must match
+ * constants in GpsLocationProvider.java. */
+/** Mode for running GPS standalone (no assistance). */
+#define LOC_GPS_POSITION_MODE_STANDALONE 0
+/** AGPS MS-Based mode. */
+#define LOC_GPS_POSITION_MODE_MS_BASED 1
+/**
+ * AGPS MS-Assisted mode. This mode is not maintained by the platform anymore.
+ * It is strongly recommended to use LOC_GPS_POSITION_MODE_MS_BASED instead.
+ */
+#define LOC_GPS_POSITION_MODE_MS_ASSISTED 2
+
+/** Requested recurrence mode for GPS operation. */
+typedef uint32_t LocGpsPositionRecurrence;
+/* IMPORTANT: Note that the following values must match
+ * constants in GpsLocationProvider.java. */
+/** Receive GPS fixes on a recurring basis at a specified period. */
+#define LOC_GPS_POSITION_RECURRENCE_PERIODIC 0
+/** Request a single shot GPS fix. */
+#define LOC_GPS_POSITION_RECURRENCE_SINGLE 1
+
+/** GPS status event values. */
+typedef uint16_t LocGpsStatusValue;
+/* IMPORTANT: Note that the following values must match
+ * constants in GpsLocationProvider.java. */
+/** GPS status unknown. */
+#define LOC_GPS_STATUS_NONE 0
+/** GPS has begun navigating. */
+#define LOC_GPS_STATUS_SESSION_BEGIN 1
+/** GPS has stopped navigating. */
+#define LOC_GPS_STATUS_SESSION_END 2
+/** GPS has powered on but is not navigating. */
+#define LOC_GPS_STATUS_ENGINE_ON 3
+/** GPS is powered off. */
+#define LOC_GPS_STATUS_ENGINE_OFF 4
+
+/** Flags to indicate which values are valid in a LocGpsLocation. */
+typedef uint16_t LocGpsLocationFlags;
+/* IMPORTANT: Note that the following values must match
+ * constants in GpsLocationProvider.java. */
+/** LocGpsLocation has valid latitude and longitude. */
+#define LOC_GPS_LOCATION_HAS_LAT_LONG 0x0001
+/** LocGpsLocation has valid altitude. */
+#define LOC_GPS_LOCATION_HAS_ALTITUDE 0x0002
+/** LocGpsLocation has valid speed. */
+#define LOC_GPS_LOCATION_HAS_SPEED 0x0004
+/** LocGpsLocation has valid bearing. */
+#define LOC_GPS_LOCATION_HAS_BEARING 0x0008
+/** LocGpsLocation has valid accuracy. */
+#define LOC_GPS_LOCATION_HAS_ACCURACY 0x0010
+/** LocGpsLocation has valid vertical uncertainity */
+#define LOC_GPS_LOCATION_HAS_VERT_UNCERTAINITY 0x0040
+
+/** Flags for the loc_gps_set_capabilities callback. */
+
+/**
+ * GPS HAL schedules fixes for LOC_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 LOC_GPS_CAPABILITY_SCHEDULING (1 << 0)
+/** GPS supports MS-Based AGPS mode */
+#define LOC_GPS_CAPABILITY_MSB (1 << 1)
+/** GPS supports MS-Assisted AGPS mode */
+#define LOC_GPS_CAPABILITY_MSA (1 << 2)
+/** GPS supports single-shot fixes */
+#define LOC_GPS_CAPABILITY_SINGLE_SHOT (1 << 3)
+/** GPS supports on demand time injection */
+#define LOC_GPS_CAPABILITY_ON_DEMAND_TIME (1 << 4)
+/** GPS supports Geofencing */
+#define LOC_GPS_CAPABILITY_GEOFENCING (1 << 5)
+/** GPS supports Measurements. */
+#define LOC_GPS_CAPABILITY_MEASUREMENTS (1 << 6)
+/** GPS supports Navigation Messages */
+#define LOC_GPS_CAPABILITY_NAV_MESSAGES (1 << 7)
+
+/**
+ * Flags used to specify which aiding data to delete when calling
+ * delete_aiding_data().
+ */
+typedef uint16_t LocGpsAidingData;
+/* IMPORTANT: Note that the following values must match
+ * constants in GpsLocationProvider.java. */
+#define LOC_GPS_DELETE_EPHEMERIS 0x0001
+#define LOC_GPS_DELETE_ALMANAC 0x0002
+#define LOC_GPS_DELETE_POSITION 0x0004
+#define LOC_GPS_DELETE_TIME 0x0008
+#define LOC_GPS_DELETE_IONO 0x0010
+#define LOC_GPS_DELETE_UTC 0x0020
+#define LOC_GPS_DELETE_HEALTH 0x0040
+#define LOC_GPS_DELETE_SVDIR 0x0080
+#define LOC_GPS_DELETE_SVSTEER 0x0100
+#define LOC_GPS_DELETE_SADATA 0x0200
+#define LOC_GPS_DELETE_RTI 0x0400
+#define LOC_GPS_DELETE_CELLDB_INFO 0x8000
+#define LOC_GPS_DELETE_ALL 0xFFFF
+
+/** AGPS type */
+typedef uint16_t LocAGpsType;
+#define LOC_AGPS_TYPE_SUPL 1
+#define LOC_AGPS_TYPE_C2K 2
+
+typedef uint16_t LocAGpsSetIDType;
+#define LOC_AGPS_SETID_TYPE_NONE 0
+#define LOC_AGPS_SETID_TYPE_IMSI 1
+#define LOC_AGPS_SETID_TYPE_MSISDN 2
+
+typedef uint16_t LocApnIpType;
+#define LOC_APN_IP_INVALID 0
+#define LOC_APN_IP_IPV4 1
+#define LOC_APN_IP_IPV6 2
+#define LOC_APN_IP_IPV4V6 3
+
+/**
+ * String length constants
+ */
+#define LOC_GPS_NI_SHORT_STRING_MAXLEN 256
+#define LOC_GPS_NI_LONG_STRING_MAXLEN 2048
+
+/**
+ * LocGpsNiType constants
+ */
+typedef uint32_t LocGpsNiType;
+#define LOC_GPS_NI_TYPE_VOICE 1
+#define LOC_GPS_NI_TYPE_UMTS_SUPL 2
+#define LOC_GPS_NI_TYPE_UMTS_CTRL_PLANE 3
+/*Emergency SUPL*/
+#define LOC_GPS_NI_TYPE_EMERGENCY_SUPL 4
+
+/**
+ * LocGpsNiNotifyFlags constants
+ */
+typedef uint32_t LocGpsNiNotifyFlags;
+/** NI requires notification */
+#define LOC_GPS_NI_NEED_NOTIFY 0x0001
+/** NI requires verification */
+#define LOC_GPS_NI_NEED_VERIFY 0x0002
+/** NI requires privacy override, no notification/minimal trace */
+#define LOC_GPS_NI_PRIVACY_OVERRIDE 0x0004
+
+/**
+ * GPS NI responses, used to define the response in
+ * NI structures
+ */
+typedef int LocGpsUserResponseType;
+#define LOC_GPS_NI_RESPONSE_ACCEPT 1
+#define LOC_GPS_NI_RESPONSE_DENY 2
+#define LOC_GPS_NI_RESPONSE_NORESP 3
+
+/**
+ * NI data encoding scheme
+ */
+typedef int LocGpsNiEncodingType;
+#define LOC_GPS_ENC_NONE 0
+#define LOC_GPS_ENC_SUPL_GSM_DEFAULT 1
+#define LOC_GPS_ENC_SUPL_UTF8 2
+#define LOC_GPS_ENC_SUPL_UCS2 3
+#define LOC_GPS_ENC_UNKNOWN -1
+
+/** AGPS status event values. */
+typedef uint8_t LocAGpsStatusValue;
+/** GPS requests data connection for AGPS. */
+#define LOC_GPS_REQUEST_AGPS_DATA_CONN 1
+/** GPS releases the AGPS data connection. */
+#define LOC_GPS_RELEASE_AGPS_DATA_CONN 2
+/** AGPS data connection initiated */
+#define LOC_GPS_AGPS_DATA_CONNECTED 3
+/** AGPS data connection completed */
+#define LOC_GPS_AGPS_DATA_CONN_DONE 4
+/** AGPS data connection failed */
+#define LOC_GPS_AGPS_DATA_CONN_FAILED 5
+
+typedef uint16_t LocAGpsRefLocationType;
+#define LOC_AGPS_REF_LOCATION_TYPE_GSM_CELLID 1
+#define LOC_AGPS_REF_LOCATION_TYPE_UMTS_CELLID 2
+#define LOC_AGPS_REF_LOCATION_TYPE_MAC 3
+#define LOC_AGPS_REF_LOCATION_TYPE_LTE_CELLID 4
+
+/* Deprecated, to be removed in the next Android release. */
+#define LOC_AGPS_REG_LOCATION_TYPE_MAC 3
+
+/** Network types for update_network_state "type" parameter */
+#define LOC_AGPS_RIL_NETWORK_TYPE_MOBILE 0
+#define LOC_AGPS_RIL_NETWORK_TYPE_WIFI 1
+#define LOC_AGPS_RIL_NETWORK_TYPE_MOBILE_MMS 2
+#define LOC_AGPS_RIL_NETWORK_TYPE_MOBILE_SUPL 3
+#define LOC_AGPS_RIL_NETWORK_TTYPE_MOBILE_DUN 4
+#define LOC_AGPS_RIL_NETWORK_TTYPE_MOBILE_HIPRI 5
+#define LOC_AGPS_RIL_NETWORK_TTYPE_WIMAX 6
+
+/* The following typedef together with its constants below are deprecated, and
+ * will be removed in the next release. */
+typedef uint16_t LocGpsClockFlags;
+#define LOC_GPS_CLOCK_HAS_LEAP_SECOND (1<<0)
+#define LOC_GPS_CLOCK_HAS_TIME_UNCERTAINTY (1<<1)
+#define LOC_GPS_CLOCK_HAS_FULL_BIAS (1<<2)
+#define LOC_GPS_CLOCK_HAS_BIAS (1<<3)
+#define LOC_GPS_CLOCK_HAS_BIAS_UNCERTAINTY (1<<4)
+#define LOC_GPS_CLOCK_HAS_DRIFT (1<<5)
+#define LOC_GPS_CLOCK_HAS_DRIFT_UNCERTAINTY (1<<6)
+
+/**
+ * Flags to indicate what fields in LocGnssClock are valid.
+ */
+typedef uint16_t LocGnssClockFlags;
+/** A valid 'leap second' is stored in the data structure. */
+#define LOC_GNSS_CLOCK_HAS_LEAP_SECOND (1<<0)
+/** A valid 'time uncertainty' is stored in the data structure. */
+#define LOC_GNSS_CLOCK_HAS_TIME_UNCERTAINTY (1<<1)
+/** A valid 'full bias' is stored in the data structure. */
+#define LOC_GNSS_CLOCK_HAS_FULL_BIAS (1<<2)
+/** A valid 'bias' is stored in the data structure. */
+#define LOC_GNSS_CLOCK_HAS_BIAS (1<<3)
+/** A valid 'bias uncertainty' is stored in the data structure. */
+#define LOC_GNSS_CLOCK_HAS_BIAS_UNCERTAINTY (1<<4)
+/** A valid 'drift' is stored in the data structure. */
+#define LOC_GNSS_CLOCK_HAS_DRIFT (1<<5)
+/** A valid 'drift uncertainty' is stored in the data structure. */
+#define LOC_GNSS_CLOCK_HAS_DRIFT_UNCERTAINTY (1<<6)
+
+/* The following typedef together with its constants below are deprecated, and
+ * will be removed in the next release. */
+typedef uint8_t LocGpsClockType;
+#define LOC_GPS_CLOCK_TYPE_UNKNOWN 0
+#define LOC_GPS_CLOCK_TYPE_LOCAL_HW_TIME 1
+#define LOC_GPS_CLOCK_TYPE_GPS_TIME 2
+
+/* The following typedef together with its constants below are deprecated, and
+ * will be removed in the next release. */
+typedef uint32_t LocGpsMeasurementFlags;
+#define LOC_GPS_MEASUREMENT_HAS_SNR (1<<0)
+#define LOC_GPS_MEASUREMENT_HAS_ELEVATION (1<<1)
+#define LOC_GPS_MEASUREMENT_HAS_ELEVATION_UNCERTAINTY (1<<2)
+#define LOC_GPS_MEASUREMENT_HAS_AZIMUTH (1<<3)
+#define LOC_GPS_MEASUREMENT_HAS_AZIMUTH_UNCERTAINTY (1<<4)
+#define LOC_GPS_MEASUREMENT_HAS_PSEUDORANGE (1<<5)
+#define LOC_GPS_MEASUREMENT_HAS_PSEUDORANGE_UNCERTAINTY (1<<6)
+#define LOC_GPS_MEASUREMENT_HAS_CODE_PHASE (1<<7)
+#define LOC_GPS_MEASUREMENT_HAS_CODE_PHASE_UNCERTAINTY (1<<8)
+#define LOC_GPS_MEASUREMENT_HAS_CARRIER_FREQUENCY (1<<9)
+#define LOC_GPS_MEASUREMENT_HAS_CARRIER_CYCLES (1<<10)
+#define LOC_GPS_MEASUREMENT_HAS_CARRIER_PHASE (1<<11)
+#define LOC_GPS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY (1<<12)
+#define LOC_GPS_MEASUREMENT_HAS_BIT_NUMBER (1<<13)
+#define LOC_GPS_MEASUREMENT_HAS_TIME_FROM_LAST_BIT (1<<14)
+#define LOC_GPS_MEASUREMENT_HAS_DOPPLER_SHIFT (1<<15)
+#define LOC_GPS_MEASUREMENT_HAS_DOPPLER_SHIFT_UNCERTAINTY (1<<16)
+#define LOC_GPS_MEASUREMENT_HAS_USED_IN_FIX (1<<17)
+#define LOC_GPS_MEASUREMENT_HAS_UNCORRECTED_PSEUDORANGE_RATE (1<<18)
+
+/**
+ * Flags to indicate what fields in LocGnssMeasurement are valid.
+ */
+typedef uint32_t LocGnssMeasurementFlags;
+/** A valid 'snr' is stored in the data structure. */
+#define LOC_GNSS_MEASUREMENT_HAS_SNR (1<<0)
+/** A valid 'carrier frequency' is stored in the data structure. */
+#define LOC_GNSS_MEASUREMENT_HAS_CARRIER_FREQUENCY (1<<9)
+/** A valid 'carrier cycles' is stored in the data structure. */
+#define LOC_GNSS_MEASUREMENT_HAS_CARRIER_CYCLES (1<<10)
+/** A valid 'carrier phase' is stored in the data structure. */
+#define LOC_GNSS_MEASUREMENT_HAS_CARRIER_PHASE (1<<11)
+/** A valid 'carrier phase uncertainty' is stored in the data structure. */
+#define LOC_GNSS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY (1<<12)
+
+/* The following typedef together with its constants below are deprecated, and
+ * will be removed in the next release. */
+typedef uint8_t LocGpsLossOfLock;
+#define LOC_GPS_LOSS_OF_LOCK_UNKNOWN 0
+#define LOC_GPS_LOSS_OF_LOCK_OK 1
+#define LOC_GPS_LOSS_OF_LOCK_CYCLE_SLIP 2
+
+/* The following typedef together with its constants below are deprecated, and
+ * will be removed in the next release. Use LocGnssMultipathIndicator instead.
+ */
+typedef uint8_t LocGpsMultipathIndicator;
+#define LOC_GPS_MULTIPATH_INDICATOR_UNKNOWN 0
+#define LOC_GPS_MULTIPATH_INDICATOR_DETECTED 1
+#define LOC_GPS_MULTIPATH_INDICATOR_NOT_USED 2
+
+/**
+ * Enumeration of available values for the GNSS Measurement's multipath
+ * indicator.
+ */
+typedef uint8_t LocGnssMultipathIndicator;
+/** The indicator is not available or unknown. */
+#define LOC_GNSS_MULTIPATH_INDICATOR_UNKNOWN 0
+/** The measurement is indicated to be affected by multipath. */
+#define LOC_GNSS_MULTIPATH_INDICATOR_PRESENT 1
+/** The measurement is indicated to be not affected by multipath. */
+#define LOC_GNSS_MULTIPATH_INDICATOR_NOT_PRESENT 2
+
+/* The following typedef together with its constants below are deprecated, and
+ * will be removed in the next release. */
+typedef uint16_t LocGpsMeasurementState;
+#define LOC_GPS_MEASUREMENT_STATE_UNKNOWN 0
+#define LOC_GPS_MEASUREMENT_STATE_CODE_LOCK (1<<0)
+#define LOC_GPS_MEASUREMENT_STATE_BIT_SYNC (1<<1)
+#define LOC_GPS_MEASUREMENT_STATE_SUBFRAME_SYNC (1<<2)
+#define LOC_GPS_MEASUREMENT_STATE_TOW_DECODED (1<<3)
+#define LOC_GPS_MEASUREMENT_STATE_MSEC_AMBIGUOUS (1<<4)
+
+/**
+ * Flags indicating the GNSS measurement state.
+ *
+ * The expected behavior here is for GPS HAL to set all the flags that applies.
+ * For example, if the state for a satellite is only C/A code locked and bit
+ * synchronized, and there is still millisecond ambiguity, the state should be
+ * set as:
+ *
+ * LOC_GNSS_MEASUREMENT_STATE_CODE_LOCK | LOC_GNSS_MEASUREMENT_STATE_BIT_SYNC |
+ * LOC_GNSS_MEASUREMENT_STATE_MSEC_AMBIGUOUS
+ *
+ * If GNSS is still searching for a satellite, the corresponding state should be
+ * set to LOC_GNSS_MEASUREMENT_STATE_UNKNOWN(0).
+ */
+typedef uint32_t LocGnssMeasurementState;
+#define LOC_GNSS_MEASUREMENT_STATE_UNKNOWN 0
+#define LOC_GNSS_MEASUREMENT_STATE_CODE_LOCK (1<<0)
+#define LOC_GNSS_MEASUREMENT_STATE_BIT_SYNC (1<<1)
+#define LOC_GNSS_MEASUREMENT_STATE_SUBFRAME_SYNC (1<<2)
+#define LOC_GNSS_MEASUREMENT_STATE_TOW_DECODED (1<<3)
+#define LOC_GNSS_MEASUREMENT_STATE_MSEC_AMBIGUOUS (1<<4)
+#define LOC_GNSS_MEASUREMENT_STATE_SYMBOL_SYNC (1<<5)
+#define LOC_GNSS_MEASUREMENT_STATE_GLO_STRING_SYNC (1<<6)
+#define LOC_GNSS_MEASUREMENT_STATE_GLO_TOD_DECODED (1<<7)
+#define LOC_GNSS_MEASUREMENT_STATE_BDS_D2_BIT_SYNC (1<<8)
+#define LOC_GNSS_MEASUREMENT_STATE_BDS_D2_SUBFRAME_SYNC (1<<9)
+#define LOC_GNSS_MEASUREMENT_STATE_GAL_E1BC_CODE_LOCK (1<<10)
+#define LOC_GNSS_MEASUREMENT_STATE_GAL_E1C_2ND_CODE_LOCK (1<<11)
+#define LOC_GNSS_MEASUREMENT_STATE_GAL_E1B_PAGE_SYNC (1<<12)
+#define LOC_GNSS_MEASUREMENT_STATE_SBAS_SYNC (1<<13)
+
+/* The following typedef together with its constants below are deprecated, and
+ * will be removed in the next release. */
+typedef uint16_t LocGpsAccumulatedDeltaRangeState;
+#define LOC_GPS_ADR_STATE_UNKNOWN 0
+#define LOC_GPS_ADR_STATE_VALID (1<<0)
+#define LOC_GPS_ADR_STATE_RESET (1<<1)
+#define LOC_GPS_ADR_STATE_CYCLE_SLIP (1<<2)
+
+/**
+ * Flags indicating the Accumulated Delta Range's states.
+ */
+typedef uint16_t LocGnssAccumulatedDeltaRangeState;
+#define LOC_GNSS_ADR_STATE_UNKNOWN 0
+#define LOC_GNSS_ADR_STATE_VALID (1<<0)
+#define LOC_GNSS_ADR_STATE_RESET (1<<1)
+#define LOC_GNSS_ADR_STATE_CYCLE_SLIP (1<<2)
+
+#if 0
+/* The following typedef together with its constants below are deprecated, and
+ * will be removed in the next release. */
+typedef uint8_t GpsNavigationMessageType;
+#define GPS_NAVIGATION_MESSAGE_TYPE_UNKNOWN 0
+#define GPS_NAVIGATION_MESSAGE_TYPE_L1CA 1
+#define GPS_NAVIGATION_MESSAGE_TYPE_L2CNAV 2
+#define GPS_NAVIGATION_MESSAGE_TYPE_L5CNAV 3
+#define GPS_NAVIGATION_MESSAGE_TYPE_CNAV2 4
+
+/**
+ * Enumeration of available values to indicate the GNSS Navigation message
+ * types.
+ *
+ * For convenience, first byte is the LocGnssConstellationType on which that signal
+ * is typically transmitted
+ */
+typedef int16_t GnssNavigationMessageType;
+
+#define GNSS_NAVIGATION_MESSAGE_TYPE_UNKNOWN 0
+/** GPS L1 C/A message contained in the structure. */
+#define GNSS_NAVIGATION_MESSAGE_TYPE_GPS_L1CA 0x0101
+/** GPS L2-CNAV message contained in the structure. */
+#define GNSS_NAVIGATION_MESSAGE_TYPE_GPS_L2CNAV 0x0102
+/** GPS L5-CNAV message contained in the structure. */
+#define GNSS_NAVIGATION_MESSAGE_TYPE_GPS_L5CNAV 0x0103
+/** GPS CNAV-2 message contained in the structure. */
+#define GNSS_NAVIGATION_MESSAGE_TYPE_GPS_CNAV2 0x0104
+/** Glonass L1 CA message contained in the structure. */
+#define GNSS_NAVIGATION_MESSAGE_TYPE_GLO_L1CA 0x0301
+/** Beidou D1 message contained in the structure. */
+#define GNSS_NAVIGATION_MESSAGE_TYPE_BDS_D1 0x0501
+/** Beidou D2 message contained in the structure. */
+#define GNSS_NAVIGATION_MESSAGE_TYPE_BDS_D2 0x0502
+/** Galileo I/NAV message contained in the structure. */
+#define GNSS_NAVIGATION_MESSAGE_TYPE_GAL_I 0x0601
+/** Galileo F/NAV message contained in the structure. */
+#define GNSS_NAVIGATION_MESSAGE_TYPE_GAL_F 0x0602
+
+/**
+ * Status of Navigation Message
+ * When a message is received properly without any parity error in its navigation words, the
+ * status should be set to NAV_MESSAGE_STATUS_PARITY_PASSED. But if a message is received
+ * with words that failed parity check, but GPS is able to correct those words, the status
+ * should be set to NAV_MESSAGE_STATUS_PARITY_REBUILT.
+ * No need to send any navigation message that contains words with parity error and cannot be
+ * corrected.
+ */
+typedef uint16_t NavigationMessageStatus;
+#define NAV_MESSAGE_STATUS_UNKNOWN 0
+#define NAV_MESSAGE_STATUS_PARITY_PASSED (1<<0)
+#define NAV_MESSAGE_STATUS_PARITY_REBUILT (1<<1)
+
+/* This constant is deprecated, and will be removed in the next release. */
+#define NAV_MESSAGE_STATUS_UNKONW 0
+#endif
+
+/**
+ * Flags that indicate information about the satellite
+ */
+typedef uint8_t LocGnssSvFlags;
+#define LOC_GNSS_SV_FLAGS_NONE 0
+#define LOC_GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA (1 << 0)
+#define LOC_GNSS_SV_FLAGS_HAS_ALMANAC_DATA (1 << 1)
+#define LOC_GNSS_SV_FLAGS_USED_IN_FIX (1 << 2)
+
+/**
+ * Constellation type of LocGnssSvInfo
+ */
+typedef uint8_t LocGnssConstellationType;
+#define LOC_GNSS_CONSTELLATION_UNKNOWN 0
+#define LOC_GNSS_CONSTELLATION_GPS 1
+#define LOC_GNSS_CONSTELLATION_SBAS 2
+#define LOC_GNSS_CONSTELLATION_GLONASS 3
+#define LOC_GNSS_CONSTELLATION_QZSS 4
+#define LOC_GNSS_CONSTELLATION_BEIDOU 5
+#define LOC_GNSS_CONSTELLATION_GALILEO 6
+
+/**
+ * Name for the GPS XTRA interface.
+ */
+#define LOC_GPS_XTRA_INTERFACE "gps-xtra"
+
+/**
+ * Name for the GPS DEBUG interface.
+ */
+#define LOC_GPS_DEBUG_INTERFACE "gps-debug"
+
+/**
+ * Name for the AGPS interface.
+ */
+
+#define LOC_AGPS_INTERFACE "agps"
+
+/**
+ * Name of the Supl Certificate interface.
+ */
+#define LOC_SUPL_CERTIFICATE_INTERFACE "supl-certificate"
+
+/**
+ * Name for NI interface
+ */
+#define LOC_GPS_NI_INTERFACE "gps-ni"
+
+/**
+ * Name for the AGPS-RIL interface.
+ */
+#define LOC_AGPS_RIL_INTERFACE "agps_ril"
+
+/**
+ * Name for the GPS_Geofencing interface.
+ */
+#define LOC_GPS_GEOFENCING_INTERFACE "gps_geofencing"
+
+/**
+ * Name of the GPS Measurements interface.
+ */
+#define LOC_GPS_MEASUREMENT_INTERFACE "gps_measurement"
+
+/**
+ * Name of the GPS navigation message interface.
+ */
+#define LOC_GPS_NAVIGATION_MESSAGE_INTERFACE "gps_navigation_message"
+
+/**
+ * Name of the GNSS/GPS configuration interface.
+ */
+#define LOC_GNSS_CONFIGURATION_INTERFACE "gnss_configuration"
+
+/** Represents a location. */
+typedef struct {
+ /** set to sizeof(LocGpsLocation) */
+ size_t size;
+ /** Contains LocGpsLocationFlags bits. */
+ uint16_t flags;
+ /** 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 horizontal speed in meters per second. */
+ float speed;
+ /** Represents heading in degrees. */
+ float bearing;
+ /** Represents expected accuracy in meters. */
+ float accuracy;
+ /** Represents the expected vertical uncertainity in meters*/
+ float vertUncertainity;
+ /** Timestamp for the location fix. */
+ LocGpsUtcTime timestamp;
+} LocGpsLocation;
+
+/** Represents the status. */
+typedef struct {
+ /** set to sizeof(LocGpsStatus) */
+ size_t size;
+ LocGpsStatusValue status;
+} LocGpsStatus;
+
+/**
+ * Legacy struct to represents SV information.
+ * Deprecated, to be removed in the next Android release.
+ * Use LocGnssSvInfo instead.
+ */
+typedef struct {
+ /** set to sizeof(LocGpsSvInfo) */
+ 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;
+} LocGpsSvInfo;
+
+typedef struct {
+ /** set to sizeof(LocGnssSvInfo) */
+ size_t size;
+
+ /**
+ * Pseudo-random number for the SV, or FCN/OSN number for Glonass. The
+ * distinction is made by looking at constellation field. Values should be
+ * in the range of:
+ *
+ * - GPS: 1-32
+ * - SBAS: 120-151, 183-192
+ * - GLONASS: 1-24, the orbital slot number (OSN), if known. Or, if not:
+ * 93-106, the frequency channel number (FCN) (-7 to +6) offset by + 100
+ * i.e. report an FCN of -7 as 93, FCN of 0 as 100, and FCN of +6 as 106.
+ * - QZSS: 193-200
+ * - Galileo: 1-36
+ * - Beidou: 1-37
+ */
+ int16_t svid;
+
+ /**
+ * Defines the constellation of the given SV. Value should be one of those
+ * LOC_GNSS_CONSTELLATION_* constants
+ */
+ LocGnssConstellationType constellation;
+
+ /**
+ * Carrier-to-noise density in dB-Hz, typically in the range [0, 63].
+ * It contains the measured C/N0 value for the signal at the antenna port.
+ *
+ * This is a mandatory value.
+ */
+ float c_n0_dbhz;
+
+ /** Elevation of SV in degrees. */
+ float elevation;
+
+ /** Azimuth of SV in degrees. */
+ float azimuth;
+
+ /**
+ * Contains additional data about the given SV. Value should be one of those
+ * LOC_GNSS_SV_FLAGS_* constants
+ */
+ LocGnssSvFlags flags;
+
+} LocGnssSvInfo;
+
+/**
+ * Legacy struct to represents SV status.
+ * Deprecated, to be removed in the next Android release.
+ * Use LocGnssSvStatus instead.
+ */
+typedef struct {
+ /** set to sizeof(LocGpsSvStatus) */
+ size_t size;
+ int num_svs;
+ LocGpsSvInfo sv_list[LOC_GPS_MAX_SVS];
+ uint32_t ephemeris_mask;
+ uint32_t almanac_mask;
+ uint32_t used_in_fix_mask;
+} LocGpsSvStatus;
+
+/**
+ * Represents SV status.
+ */
+typedef struct {
+ /** set to sizeof(LocGnssSvStatus) */
+ size_t size;
+
+ /** Number of GPS SVs currently visible, refers to the SVs stored in sv_list */
+ int num_svs;
+ /**
+ * Pointer to an array of SVs information for all GNSS constellations,
+ * except GPS, which is reported using sv_list
+ */
+ LocGnssSvInfo gnss_sv_list[LOC_GNSS_MAX_SVS];
+
+} LocGnssSvStatus;
+
+/* CellID for 2G, 3G and LTE, used in AGPS. */
+typedef struct {
+ LocAGpsRefLocationType type;
+ /** Mobile Country Code. */
+ uint16_t mcc;
+ /** Mobile Network Code .*/
+ uint16_t mnc;
+ /** Location Area Code in 2G, 3G and LTE. In 3G lac is discarded. In LTE,
+ * lac is populated with tac, to ensure that we don't break old clients that
+ * might rely in the old (wrong) behavior.
+ */
+ uint16_t lac;
+ /** Cell id in 2G. Utran Cell id in 3G. Cell Global Id EUTRA in LTE. */
+ uint32_t cid;
+ /** Tracking Area Code in LTE. */
+ uint16_t tac;
+ /** Physical Cell id in LTE (not used in 2G and 3G) */
+ uint16_t pcid;
+} LocAGpsRefLocationCellID;
+
+typedef struct {
+ uint8_t mac[6];
+} LocAGpsRefLocationMac;
+
+/** Represents ref locations */
+typedef struct {
+ LocAGpsRefLocationType type;
+ union {
+ LocAGpsRefLocationCellID cellID;
+ LocAGpsRefLocationMac mac;
+ } u;
+} LocAGpsRefLocation;
+
+/**
+ * Callback with location information. Can only be called from a thread created
+ * by create_thread_cb.
+ */
+typedef void (* loc_gps_location_callback)(LocGpsLocation* location);
+
+/**
+ * Callback with status information. Can only be called from a thread created by
+ * create_thread_cb.
+ */
+typedef void (* loc_gps_status_callback)(LocGpsStatus* status);
+/**
+ * Legacy callback with SV status information.
+ * Can only be called from a thread created by create_thread_cb.
+ *
+ * This callback is deprecated, and will be removed in the next release. Use
+ * loc_gnss_sv_status_callback() instead.
+ */
+typedef void (* loc_gps_sv_status_callback)(LocGpsSvStatus* sv_info);
+
+/**
+ * Callback with SV status information.
+ * Can only be called from a thread created by create_thread_cb.
+ */
+typedef void (* loc_gnss_sv_status_callback)(LocGnssSvStatus* sv_info);
+
+/**
+ * Callback for reporting NMEA sentences. Can only be called from a thread
+ * created by create_thread_cb.
+ */
+typedef void (* loc_gps_nmea_callback)(LocGpsUtcTime timestamp, const char* nmea, int length);
+
+/**
+ * Callback to inform framework of the GPS engine's capabilities. Capability
+ * parameter is a bit field of LOC_GPS_CAPABILITY_* flags.
+ */
+typedef void (* loc_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 (* loc_gps_acquire_wakelock)();
+
+/** Callback utility for releasing the GPS wakelock. */
+typedef void (* loc_gps_release_wakelock)();
+
+/** Callback for requesting NTP time */
+typedef void (* loc_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 (* loc_gps_create_thread)(const char* name, void (*start)(void *), void* arg);
+
+/**
+ * Provides information about how new the underlying GPS/GNSS hardware and
+ * software is.
+ *
+ * This information will be available for Android Test Applications. If a GPS
+ * HAL does not provide this information, it will be considered "2015 or
+ * earlier".
+ *
+ * If a GPS HAL does provide this information, then newer years will need to
+ * meet newer CTS standards. E.g. if the date are 2016 or above, then N+ level
+ * LocGpsMeasurement support will be verified.
+ */
+typedef struct {
+ /** Set to sizeof(LocGnssSystemInfo) */
+ size_t size;
+ /* year in which the last update was made to the underlying hardware/firmware
+ * used to capture GNSS signals, e.g. 2016 */
+ uint16_t year_of_hw;
+} LocGnssSystemInfo;
+
+/**
+ * Callback to inform framework of the engine's hardware version information.
+ */
+typedef void (*loc_gnss_set_system_info)(const LocGnssSystemInfo* info);
+
+/** New GPS callback structure. */
+typedef struct {
+ /** set to sizeof(LocGpsCallbacks) */
+ size_t size;
+ loc_gps_location_callback location_cb;
+ loc_gps_status_callback status_cb;
+ loc_gps_sv_status_callback sv_status_cb;
+ loc_gps_nmea_callback nmea_cb;
+ loc_gps_set_capabilities set_capabilities_cb;
+ loc_gps_acquire_wakelock acquire_wakelock_cb;
+ loc_gps_release_wakelock release_wakelock_cb;
+ loc_gps_create_thread create_thread_cb;
+ loc_gps_request_utc_time request_utc_time_cb;
+
+ loc_gnss_set_system_info set_system_info_cb;
+ loc_gnss_sv_status_callback gnss_sv_status_cb;
+} LocGpsCallbacks;
+
+/** Represents the standard GPS interface. */
+typedef struct {
+ /** set to sizeof(LocGpsInterface) */
+ size_t size;
+ /**
+ * Opens the interface and provides the callback routines
+ * to the implementation of this interface.
+ */
+ int (*init)( LocGpsCallbacks* callbacks );
+
+ /** Starts navigating. */
+ int (*start)( void );
+
+ /** Stops navigating. */
+ int (*stop)( void );
+
+ /** Closes the interface. */
+ void (*cleanup)( void );
+
+ /** Injects the current time. */
+ int (*inject_time)(LocGpsUtcTime 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. LOC_GPS_DELETE_ALL is passed for
+ * a cold start.
+ */
+ void (*delete_aiding_data)(LocGpsAidingData 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.
+ *
+ * 'mode' parameter should be one of LOC_GPS_POSITION_MODE_MS_BASED
+ * or LOC_GPS_POSITION_MODE_STANDALONE.
+ * It is allowed by the platform (and it is recommended) to fallback to
+ * LOC_GPS_POSITION_MODE_MS_BASED if LOC_GPS_POSITION_MODE_MS_ASSISTED is passed in, and
+ * LOC_GPS_POSITION_MODE_MS_BASED is supported.
+ */
+ int (*set_position_mode)(LocGpsPositionMode mode, LocGpsPositionRecurrence 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);
+} LocGpsInterface;
+
+/**
+ * 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 (* loc_gps_xtra_download_request)();
+
+/** Callback structure for the XTRA interface. */
+typedef struct {
+ loc_gps_xtra_download_request download_request_cb;
+ loc_gps_create_thread create_thread_cb;
+} LocGpsXtraCallbacks;
+
+/** Extended interface for XTRA support. */
+typedef struct {
+ /** set to sizeof(LocGpsXtraInterface) */
+ size_t size;
+ /**
+ * Opens the XTRA interface and provides the callback routines
+ * to the implementation of this interface.
+ */
+ int (*init)( LocGpsXtraCallbacks* callbacks );
+ /** Injects XTRA data into the GPS. */
+ int (*inject_xtra_data)( char* data, int length );
+} LocGpsXtraInterface;
+
+#if 0
+/** Extended interface for DEBUG support. */
+typedef struct {
+ /** set to sizeof(LocGpsDebugInterface) */
+ 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);
+} LocGpsDebugInterface;
+#endif
+
+/*
+ * Represents the status of AGPS augmented to support IPv4 and IPv6.
+ */
+typedef struct {
+ /** set to sizeof(LocAGpsStatus) */
+ size_t size;
+
+ LocAGpsType type;
+ LocAGpsStatusValue status;
+
+ /**
+ * Must be set to a valid IPv4 address if the field 'addr' contains an IPv4
+ * address, or set to INADDR_NONE otherwise.
+ */
+ uint32_t ipaddr;
+
+ /**
+ * Must contain the IPv4 (AF_INET) or IPv6 (AF_INET6) address to report.
+ * Any other value of addr.ss_family will be rejected.
+ */
+ struct sockaddr_storage addr;
+} LocAGpsStatus;
+
+/**
+ * Callback with AGPS status information. Can only be called from a thread
+ * created by create_thread_cb.
+ */
+typedef void (* loc_agps_status_callback)(LocAGpsStatus* status);
+
+/** Callback structure for the AGPS interface. */
+typedef struct {
+ loc_agps_status_callback status_cb;
+ loc_gps_create_thread create_thread_cb;
+} LocAGpsCallbacks;
+
+/**
+ * Extended interface for AGPS support, it is augmented to enable to pass
+ * extra APN data.
+ */
+typedef struct {
+ /** set to sizeof(LocAGpsInterface) */
+ size_t size;
+
+ /**
+ * Opens the AGPS interface and provides the callback routines to the
+ * implementation of this interface.
+ */
+ void (*init)(LocAGpsCallbacks* callbacks);
+ /**
+ * Deprecated.
+ * If the HAL supports LocAGpsInterface_v2 this API will not be used, see
+ * data_conn_open_with_apn_ip_type for more information.
+ */
+ int (*data_conn_open)(const char* apn);
+ /**
+ * Notifies that the AGPS data connection has been closed.
+ */
+ int (*data_conn_closed)();
+ /**
+ * Notifies that a data connection is not available for AGPS.
+ */
+ int (*data_conn_failed)();
+ /**
+ * Sets the hostname and port for the AGPS server.
+ */
+ int (*set_server)(LocAGpsType type, const char* hostname, int port);
+
+ /**
+ * Notifies that a data connection is available and sets the name of the
+ * APN, and its IP type, to be used for SUPL connections.
+ */
+ int (*data_conn_open_with_apn_ip_type)(
+ const char* apn,
+ LocApnIpType apnIpType);
+} LocAGpsInterface;
+
+/** Error codes associated with certificate operations */
+#define LOC_AGPS_CERTIFICATE_OPERATION_SUCCESS 0
+#define LOC_AGPS_CERTIFICATE_ERROR_GENERIC -100
+#define LOC_AGPS_CERTIFICATE_ERROR_TOO_MANY_CERTIFICATES -101
+
+/** A data structure that represents an X.509 certificate using DER encoding */
+typedef struct {
+ size_t length;
+ u_char* data;
+} LocDerEncodedCertificate;
+
+/**
+ * A type definition for SHA1 Fingerprints used to identify X.509 Certificates
+ * The Fingerprint is a digest of the DER Certificate that uniquely identifies it.
+ */
+typedef struct {
+ u_char data[20];
+} LocSha1CertificateFingerprint;
+
+/** AGPS Interface to handle SUPL certificate operations */
+typedef struct {
+ /** set to sizeof(LocSuplCertificateInterface) */
+ size_t size;
+
+ /**
+ * Installs a set of Certificates used for SUPL connections to the AGPS server.
+ * If needed the HAL should find out internally any certificates that need to be removed to
+ * accommodate the certificates to install.
+ * The certificates installed represent a full set of valid certificates needed to connect to
+ * AGPS SUPL servers.
+ * The list of certificates is required, and all must be available at the same time, when trying
+ * to establish a connection with the AGPS Server.
+ *
+ * Parameters:
+ * certificates - A pointer to an array of DER encoded certificates that are need to be
+ * installed in the HAL.
+ * length - The number of certificates to install.
+ * Returns:
+ * LOC_AGPS_CERTIFICATE_OPERATION_SUCCESS if the operation is completed successfully
+ * LOC_AGPS_CERTIFICATE_ERROR_TOO_MANY_CERTIFICATES if the HAL cannot store the number of
+ * certificates attempted to be installed, the state of the certificates stored should
+ * remain the same as before on this error case.
+ *
+ * IMPORTANT:
+ * If needed the HAL should find out internally the set of certificates that need to be
+ * removed to accommodate the certificates to install.
+ */
+ int (*install_certificates) ( const LocDerEncodedCertificate* certificates, size_t length );
+
+ /**
+ * Notifies the HAL that a list of certificates used for SUPL connections are revoked. It is
+ * expected that the given set of certificates is removed from the internal store of the HAL.
+ *
+ * Parameters:
+ * fingerprints - A pointer to an array of SHA1 Fingerprints to identify the set of
+ * certificates to revoke.
+ * length - The number of fingerprints provided.
+ * Returns:
+ * LOC_AGPS_CERTIFICATE_OPERATION_SUCCESS if the operation is completed successfully.
+ *
+ * IMPORTANT:
+ * If any of the certificates provided (through its fingerprint) is not known by the HAL,
+ * it should be ignored and continue revoking/deleting the rest of them.
+ */
+ int (*revoke_certificates) ( const LocSha1CertificateFingerprint* fingerprints, size_t length );
+} LocSuplCertificateInterface;
+
+/** Represents an NI request */
+typedef struct {
+ /** set to sizeof(LocGpsNiNotification) */
+ 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 LOC_GPS_NI_TYPE_VOICE, LOC_GPS_NI_TYPE_UMTS_SUPL, ...
+ */
+ LocGpsNiType ni_type;
+
+ /**
+ * Notification/verification options, combinations of LocGpsNiNotifyFlags constants
+ */
+ LocGpsNiNotifyFlags notify_flags;
+
+ /**
+ * Timeout period to wait for user response.
+ * Set to 0 for no time out limit.
+ */
+ int timeout;
+
+ /**
+ * Default response when time out.
+ */
+ LocGpsUserResponseType default_response;
+
+ /**
+ * Requestor ID
+ */
+ char requestor_id[LOC_GPS_NI_SHORT_STRING_MAXLEN];
+
+ /**
+ * Notification message. It can also be used to store client_id in some cases
+ */
+ char text[LOC_GPS_NI_LONG_STRING_MAXLEN];
+
+ /**
+ * Client name decoding scheme
+ */
+ LocGpsNiEncodingType requestor_id_encoding;
+
+ /**
+ * Client name decoding scheme
+ */
+ LocGpsNiEncodingType text_encoding;
+
+ /**
+ * A pointer to extra data. Format:
+ * key_1 = value_1
+ * key_2 = value_2
+ */
+ char extras[LOC_GPS_NI_LONG_STRING_MAXLEN];
+
+} LocGpsNiNotification;
+
+/**
+ * Callback with NI notification. Can only be called from a thread created by
+ * create_thread_cb.
+ */
+typedef void (*loc_gps_ni_notify_callback)(LocGpsNiNotification *notification);
+
+/** GPS NI callback structure. */
+typedef struct
+{
+ /**
+ * Sends the notification request from HAL to GPSLocationProvider.
+ */
+ loc_gps_ni_notify_callback notify_cb;
+ loc_gps_create_thread create_thread_cb;
+} LocGpsNiCallbacks;
+
+/**
+ * Extended interface for Network-initiated (NI) support.
+ */
+typedef struct
+{
+ /** set to sizeof(LocGpsNiInterface) */
+ size_t size;
+
+ /** Registers the callbacks for HAL to use. */
+ void (*init) (LocGpsNiCallbacks *callbacks);
+
+ /** Sends a response to HAL. */
+ void (*respond) (int notif_id, LocGpsUserResponseType user_response);
+} LocGpsNiInterface;
+
+#define LOC_AGPS_RIL_REQUEST_SETID_IMSI (1<<0L)
+#define LOC_AGPS_RIL_REQUEST_SETID_MSISDN (1<<1L)
+
+#define LOC_AGPS_RIL_REQUEST_REFLOC_CELLID (1<<0L)
+#define LOC_AGPS_RIL_REQUEST_REFLOC_MAC (1<<1L)
+
+typedef void (*loc_agps_ril_request_set_id)(uint32_t flags);
+typedef void (*loc_agps_ril_request_ref_loc)(uint32_t flags);
+
+typedef struct {
+ loc_agps_ril_request_set_id request_setid;
+ loc_agps_ril_request_ref_loc request_refloc;
+ loc_gps_create_thread create_thread_cb;
+} LocAGpsRilCallbacks;
+
+/** Extended interface for AGPS_RIL support. */
+typedef struct {
+ /** set to sizeof(LocAGpsRilInterface) */
+ size_t size;
+ /**
+ * Opens the AGPS interface and provides the callback routines
+ * to the implementation of this interface.
+ */
+ void (*init)( LocAGpsRilCallbacks* callbacks );
+
+ /**
+ * Sets the reference location.
+ */
+ void (*set_ref_location) (const LocAGpsRefLocation *agps_reflocation, size_t sz_struct);
+ /**
+ * Sets the set ID.
+ */
+ void (*set_set_id) (LocAGpsSetIDType 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);
+} LocAGpsRilInterface;
+
+/**
+ * GPS Geofence.
+ * There are 3 states associated with a Geofence: Inside, Outside, Unknown.
+ * There are 3 transitions: ENTERED, EXITED, UNCERTAIN.
+ *
+ * An example state diagram with confidence level: 95% and Unknown time limit
+ * set as 30 secs is shown below. (confidence level and Unknown time limit are
+ * explained latter)
+ * ____________________________
+ * | Unknown (30 secs) |
+ * """"""""""""""""""""""""""""
+ * ^ | | ^
+ * UNCERTAIN| |ENTERED EXITED| |UNCERTAIN
+ * | v v |
+ * ________ EXITED _________
+ * | Inside | -----------> | Outside |
+ * | | <----------- | |
+ * """""""" ENTERED """""""""
+ *
+ * Inside state: We are 95% confident that the user is inside the geofence.
+ * Outside state: We are 95% confident that the user is outside the geofence
+ * Unknown state: Rest of the time.
+ *
+ * The Unknown state is better explained with an example:
+ *
+ * __________
+ * | c|
+ * | ___ | _______
+ * | |a| | | b |
+ * | """ | """""""
+ * | |
+ * """"""""""
+ * In the diagram above, "a" and "b" are 2 geofences and "c" is the accuracy
+ * circle reported by the GPS subsystem. Now with regard to "b", the system is
+ * confident that the user is outside. But with regard to "a" is not confident
+ * whether it is inside or outside the geofence. If the accuracy remains the
+ * same for a sufficient period of time, the UNCERTAIN transition would be
+ * triggered with the state set to Unknown. If the accuracy improves later, an
+ * appropriate transition should be triggered. This "sufficient period of time"
+ * is defined by the parameter in the add_geofence_area API.
+ * In other words, Unknown state can be interpreted as a state in which the
+ * GPS subsystem isn't confident enough that the user is either inside or
+ * outside the Geofence. It moves to Unknown state only after the expiry of the
+ * timeout.
+ *
+ * The geofence callback needs to be triggered for the ENTERED and EXITED
+ * transitions, when the GPS system is confident that the user has entered
+ * (Inside state) or exited (Outside state) the Geofence. An implementation
+ * which uses a value of 95% as the confidence is recommended. The callback
+ * should be triggered only for the transitions requested by the
+ * add_geofence_area call.
+ *
+ * Even though the diagram and explanation talks about states and transitions,
+ * the callee is only interested in the transistions. The states are mentioned
+ * here for illustrative purposes.
+ *
+ * Startup Scenario: When the device boots up, if an application adds geofences,
+ * and then we get an accurate GPS location fix, it needs to trigger the
+ * appropriate (ENTERED or EXITED) transition for every Geofence it knows about.
+ * By default, all the Geofences will be in the Unknown state.
+ *
+ * When the GPS system is unavailable, loc_gps_geofence_status_callback should be
+ * called to inform the upper layers of the same. Similarly, when it becomes
+ * available the callback should be called. This is a global state while the
+ * UNKNOWN transition described above is per geofence.
+ *
+ * An important aspect to note is that users of this API (framework), will use
+ * other subsystems like wifi, sensors, cell to handle Unknown case and
+ * hopefully provide a definitive state transition to the third party
+ * application. GPS Geofence will just be a signal indicating what the GPS
+ * subsystem knows about the Geofence.
+ *
+ */
+#define LOC_GPS_GEOFENCE_ENTERED (1<<0L)
+#define LOC_GPS_GEOFENCE_EXITED (1<<1L)
+#define LOC_GPS_GEOFENCE_UNCERTAIN (1<<2L)
+
+#define LOC_GPS_GEOFENCE_UNAVAILABLE (1<<0L)
+#define LOC_GPS_GEOFENCE_AVAILABLE (1<<1L)
+
+#define LOC_GPS_GEOFENCE_OPERATION_SUCCESS 0
+#define LOC_GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES -100
+#define LOC_GPS_GEOFENCE_ERROR_ID_EXISTS -101
+#define LOC_GPS_GEOFENCE_ERROR_ID_UNKNOWN -102
+#define LOC_GPS_GEOFENCE_ERROR_INVALID_TRANSITION -103
+#define LOC_GPS_GEOFENCE_ERROR_GENERIC -149
+
+/**
+ * The callback associated with the geofence.
+ * Parameters:
+ * geofence_id - The id associated with the add_geofence_area.
+ * location - The current GPS location.
+ * transition - Can be one of LOC_GPS_GEOFENCE_ENTERED, LOC_GPS_GEOFENCE_EXITED,
+ * LOC_GPS_GEOFENCE_UNCERTAIN.
+ * timestamp - Timestamp when the transition was detected.
+ *
+ * The callback should only be called when the caller is interested in that
+ * particular transition. For instance, if the caller is interested only in
+ * ENTERED transition, then the callback should NOT be called with the EXITED
+ * transition.
+ *
+ * IMPORTANT: If a transition is triggered resulting in this callback, the GPS
+ * subsystem will wake up the application processor, if its in suspend state.
+ */
+typedef void (*loc_gps_geofence_transition_callback) (int32_t geofence_id, LocGpsLocation* location,
+ int32_t transition, LocGpsUtcTime timestamp);
+
+/**
+ * The callback associated with the availability of the GPS system for geofencing
+ * monitoring. If the GPS system determines that it cannot monitor geofences
+ * because of lack of reliability or unavailability of the GPS signals, it will
+ * call this callback with LOC_GPS_GEOFENCE_UNAVAILABLE parameter.
+ *
+ * Parameters:
+ * status - LOC_GPS_GEOFENCE_UNAVAILABLE or LOC_GPS_GEOFENCE_AVAILABLE.
+ * last_location - Last known location.
+ */
+typedef void (*loc_gps_geofence_status_callback) (int32_t status, LocGpsLocation* last_location);
+
+/**
+ * The callback associated with the add_geofence call.
+ *
+ * Parameter:
+ * geofence_id - Id of the geofence.
+ * status - LOC_GPS_GEOFENCE_OPERATION_SUCCESS
+ * LOC_GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES - geofence limit has been reached.
+ * LOC_GPS_GEOFENCE_ERROR_ID_EXISTS - geofence with id already exists
+ * LOC_GPS_GEOFENCE_ERROR_INVALID_TRANSITION - the monitorTransition contains an
+ * invalid transition
+ * LOC_GPS_GEOFENCE_ERROR_GENERIC - for other errors.
+ */
+typedef void (*loc_gps_geofence_add_callback) (int32_t geofence_id, int32_t status);
+
+/**
+ * The callback associated with the remove_geofence call.
+ *
+ * Parameter:
+ * geofence_id - Id of the geofence.
+ * status - LOC_GPS_GEOFENCE_OPERATION_SUCCESS
+ * LOC_GPS_GEOFENCE_ERROR_ID_UNKNOWN - for invalid id
+ * LOC_GPS_GEOFENCE_ERROR_GENERIC for others.
+ */
+typedef void (*loc_gps_geofence_remove_callback) (int32_t geofence_id, int32_t status);
+
+
+/**
+ * The callback associated with the pause_geofence call.
+ *
+ * Parameter:
+ * geofence_id - Id of the geofence.
+ * status - LOC_GPS_GEOFENCE_OPERATION_SUCCESS
+ * LOC_GPS_GEOFENCE_ERROR_ID_UNKNOWN - for invalid id
+ * LOC_GPS_GEOFENCE_ERROR_INVALID_TRANSITION -
+ * when monitor_transitions is invalid
+ * LOC_GPS_GEOFENCE_ERROR_GENERIC for others.
+ */
+typedef void (*loc_gps_geofence_pause_callback) (int32_t geofence_id, int32_t status);
+
+/**
+ * The callback associated with the resume_geofence call.
+ *
+ * Parameter:
+ * geofence_id - Id of the geofence.
+ * status - LOC_GPS_GEOFENCE_OPERATION_SUCCESS
+ * LOC_GPS_GEOFENCE_ERROR_ID_UNKNOWN - for invalid id
+ * LOC_GPS_GEOFENCE_ERROR_GENERIC for others.
+ */
+typedef void (*loc_gps_geofence_resume_callback) (int32_t geofence_id, int32_t status);
+
+typedef struct {
+ loc_gps_geofence_transition_callback geofence_transition_callback;
+ loc_gps_geofence_status_callback geofence_status_callback;
+ loc_gps_geofence_add_callback geofence_add_callback;
+ loc_gps_geofence_remove_callback geofence_remove_callback;
+ loc_gps_geofence_pause_callback geofence_pause_callback;
+ loc_gps_geofence_resume_callback geofence_resume_callback;
+ loc_gps_create_thread create_thread_cb;
+} LocGpsGeofenceCallbacks;
+
+/** Extended interface for GPS_Geofencing support */
+typedef struct {
+ /** set to sizeof(LocGpsGeofencingInterface) */
+ size_t size;
+
+ /**
+ * Opens the geofence interface and provides the callback routines
+ * to the implementation of this interface.
+ */
+ void (*init)( LocGpsGeofenceCallbacks* callbacks );
+
+ /**
+ * Add a geofence area. This api currently supports circular geofences.
+ * Parameters:
+ * geofence_id - The id for the geofence. If a geofence with this id
+ * already exists, an error value (LOC_GPS_GEOFENCE_ERROR_ID_EXISTS)
+ * should be returned.
+ * latitude, longtitude, radius_meters - The lat, long and radius
+ * (in meters) for the geofence
+ * last_transition - The current state of the geofence. For example, if
+ * the system already knows that the user is inside the geofence,
+ * this will be set to LOC_GPS_GEOFENCE_ENTERED. In most cases, it
+ * will be LOC_GPS_GEOFENCE_UNCERTAIN.
+ * monitor_transition - Which transitions to monitor. Bitwise OR of
+ * LOC_GPS_GEOFENCE_ENTERED, LOC_GPS_GEOFENCE_EXITED and
+ * LOC_GPS_GEOFENCE_UNCERTAIN.
+ * notification_responsiveness_ms - Defines the best-effort description
+ * of how soon should the callback be called when the transition
+ * associated with the Geofence is triggered. For instance, if set
+ * to 1000 millseconds with LOC_GPS_GEOFENCE_ENTERED, the callback
+ * should be called 1000 milliseconds within entering the geofence.
+ * This parameter is defined in milliseconds.
+ * NOTE: This is not to be confused with the rate that the GPS is
+ * polled at. It is acceptable to dynamically vary the rate of
+ * sampling the GPS for power-saving reasons; thus the rate of
+ * sampling may be faster or slower than this.
+ * unknown_timer_ms - The time limit after which the UNCERTAIN transition
+ * should be triggered. This parameter is defined in milliseconds.
+ * See above for a detailed explanation.
+ */
+ void (*add_geofence_area) (int32_t geofence_id, double latitude, double longitude,
+ double radius_meters, int last_transition, int monitor_transitions,
+ int notification_responsiveness_ms, int unknown_timer_ms);
+
+ /**
+ * Pause monitoring a particular geofence.
+ * Parameters:
+ * geofence_id - The id for the geofence.
+ */
+ void (*pause_geofence) (int32_t geofence_id);
+
+ /**
+ * Resume monitoring a particular geofence.
+ * Parameters:
+ * geofence_id - The id for the geofence.
+ * monitor_transitions - Which transitions to monitor. Bitwise OR of
+ * LOC_GPS_GEOFENCE_ENTERED, LOC_GPS_GEOFENCE_EXITED and
+ * LOC_GPS_GEOFENCE_UNCERTAIN.
+ * This supersedes the value associated provided in the
+ * add_geofence_area call.
+ */
+ void (*resume_geofence) (int32_t geofence_id, int monitor_transitions);
+
+ /**
+ * Remove a geofence area. After the function returns, no notifications
+ * should be sent.
+ * Parameter:
+ * geofence_id - The id for the geofence.
+ */
+ void (*remove_geofence_area) (int32_t geofence_id);
+} LocGpsGeofencingInterface;
+
+/**
+ * Legacy struct to represent an estimate of the GPS clock time.
+ * Deprecated, to be removed in the next Android release.
+ * Use LocGnssClock instead.
+ */
+typedef struct {
+ /** set to sizeof(LocGpsClock) */
+ size_t size;
+ LocGpsClockFlags flags;
+ int16_t leap_second;
+ LocGpsClockType type;
+ int64_t time_ns;
+ double time_uncertainty_ns;
+ int64_t full_bias_ns;
+ double bias_ns;
+ double bias_uncertainty_ns;
+ double drift_nsps;
+ double drift_uncertainty_nsps;
+} LocGpsClock;
+
+/**
+ * Represents an estimate of the GPS clock time.
+ */
+typedef struct {
+ /** set to sizeof(LocGnssClock) */
+ size_t size;
+
+ /**
+ * A set of flags indicating the validity of the fields in this data
+ * structure.
+ */
+ LocGnssClockFlags flags;
+
+ /**
+ * Leap second data.
+ * The sign of the value is defined by the following equation:
+ * utc_time_ns = time_ns - (full_bias_ns + bias_ns) - leap_second *
+ * 1,000,000,000
+ *
+ * If the data is available 'flags' must contain LOC_GNSS_CLOCK_HAS_LEAP_SECOND.
+ */
+ int16_t leap_second;
+
+ /**
+ * The GNSS receiver internal clock value. This is the local hardware clock
+ * value.
+ *
+ * For local hardware clock, this value is expected to be monotonically
+ * increasing while the hardware clock remains power on. (For the case of a
+ * HW clock that is not continuously on, see the
+ * hw_clock_discontinuity_count field). The receiver's estimate of GPS time
+ * can be derived by substracting the sum of full_bias_ns and bias_ns (when
+ * available) from this value.
+ *
+ * This GPS time is expected to be the best estimate of current GPS time
+ * that GNSS receiver can achieve.
+ *
+ * Sub-nanosecond accuracy can be provided by means of the 'bias_ns' field.
+ * The value contains the 'time uncertainty' in it.
+ *
+ * This field is mandatory.
+ */
+ int64_t time_ns;
+
+ /**
+ * 1-Sigma uncertainty associated with the clock's time in nanoseconds.
+ * The uncertainty is represented as an absolute (single sided) value.
+ *
+ * If the data is available, 'flags' must contain
+ * LOC_GNSS_CLOCK_HAS_TIME_UNCERTAINTY. This value is effectively zero (it is
+ * the reference local clock, by which all other times and time
+ * uncertainties are measured.) (And thus this field can be not provided,
+ * per LOC_GNSS_CLOCK_HAS_TIME_UNCERTAINTY flag, or provided & set to 0.)
+ */
+ double time_uncertainty_ns;
+
+ /**
+ * The difference between hardware clock ('time' field) inside GPS receiver
+ * and the true GPS time since 0000Z, January 6, 1980, in nanoseconds.
+ *
+ * The sign of the value is defined by the following equation:
+ * local estimate of GPS time = time_ns - (full_bias_ns + bias_ns)
+ *
+ * This value is mandatory if the receiver has estimated GPS time. If the
+ * computed time is for a non-GPS constellation, the time offset of that
+ * constellation to GPS has to be applied to fill this value. The error
+ * estimate for the sum of this and the bias_ns is the bias_uncertainty_ns,
+ * and the caller is responsible for using this uncertainty (it can be very
+ * large before the GPS time has been solved for.) If the data is available
+ * 'flags' must contain LOC_GNSS_CLOCK_HAS_FULL_BIAS.
+ */
+ int64_t full_bias_ns;
+
+ /**
+ * Sub-nanosecond bias.
+ * The error estimate for the sum of this and the full_bias_ns is the
+ * bias_uncertainty_ns
+ *
+ * If the data is available 'flags' must contain LOC_GNSS_CLOCK_HAS_BIAS. If GPS
+ * has computed a position fix. This value is mandatory if the receiver has
+ * estimated GPS time.
+ */
+ double bias_ns;
+
+ /**
+ * 1-Sigma uncertainty associated with the local estimate of GPS time (clock
+ * bias) in nanoseconds. The uncertainty is represented as an absolute
+ * (single sided) value.
+ *
+ * If the data is available 'flags' must contain
+ * LOC_GNSS_CLOCK_HAS_BIAS_UNCERTAINTY. This value is mandatory if the receiver
+ * has estimated GPS time.
+ */
+ double bias_uncertainty_ns;
+
+ /**
+ * The clock's drift in nanoseconds (per second).
+ *
+ * A positive value means that the frequency is higher than the nominal
+ * frequency, and that the (full_bias_ns + bias_ns) is growing more positive
+ * over time.
+ *
+ * The value contains the 'drift uncertainty' in it.
+ * If the data is available 'flags' must contain LOC_GNSS_CLOCK_HAS_DRIFT.
+ *
+ * This value is mandatory if the receiver has estimated GNSS time
+ */
+ double drift_nsps;
+
+ /**
+ * 1-Sigma uncertainty associated with the clock's drift in nanoseconds (per second).
+ * The uncertainty is represented as an absolute (single sided) value.
+ *
+ * If the data is available 'flags' must contain
+ * LOC_GNSS_CLOCK_HAS_DRIFT_UNCERTAINTY. If GPS has computed a position fix this
+ * field is mandatory and must be populated.
+ */
+ double drift_uncertainty_nsps;
+
+ /**
+ * When there are any discontinuities in the HW clock, this field is
+ * mandatory.
+ *
+ * A "discontinuity" is meant to cover the case of a switch from one source
+ * of clock to another. A single free-running crystal oscillator (XO)
+ * should generally not have any discontinuities, and this can be set and
+ * left at 0.
+ *
+ * If, however, the time_ns value (HW clock) is derived from a composite of
+ * sources, that is not as smooth as a typical XO, or is otherwise stopped &
+ * restarted, then this value shall be incremented each time a discontinuity
+ * occurs. (E.g. this value may start at zero at device boot-up and
+ * increment each time there is a change in clock continuity. In the
+ * unlikely event that this value reaches full scale, rollover (not
+ * clamping) is required, such that this value continues to change, during
+ * subsequent discontinuity events.)
+ *
+ * While this number stays the same, between LocGnssClock reports, it can be
+ * safely assumed that the time_ns value has been running continuously, e.g.
+ * derived from a single, high quality clock (XO like, or better, that's
+ * typically used during continuous GNSS signal sampling.)
+ *
+ * It is expected, esp. during periods where there are few GNSS signals
+ * available, that the HW clock be discontinuity-free as long as possible,
+ * as this avoids the need to use (waste) a GNSS measurement to fully
+ * re-solve for the GPS clock bias and drift, when using the accompanying
+ * measurements, from consecutive LocGnssData reports.
+ */
+ uint32_t hw_clock_discontinuity_count;
+
+} LocGnssClock;
+
+/**
+ * Legacy struct to represent a GPS Measurement, it contains raw and computed
+ * information.
+ * Deprecated, to be removed in the next Android release.
+ * Use LocGnssMeasurement instead.
+ */
+typedef struct {
+ /** set to sizeof(LocGpsMeasurement) */
+ size_t size;
+ LocGpsMeasurementFlags flags;
+ int8_t prn;
+ double time_offset_ns;
+ LocGpsMeasurementState state;
+ int64_t received_gps_tow_ns;
+ int64_t received_gps_tow_uncertainty_ns;
+ double c_n0_dbhz;
+ double pseudorange_rate_mps;
+ double pseudorange_rate_uncertainty_mps;
+ LocGpsAccumulatedDeltaRangeState accumulated_delta_range_state;
+ double accumulated_delta_range_m;
+ double accumulated_delta_range_uncertainty_m;
+ double pseudorange_m;
+ double pseudorange_uncertainty_m;
+ double code_phase_chips;
+ double code_phase_uncertainty_chips;
+ float carrier_frequency_hz;
+ int64_t carrier_cycles;
+ double carrier_phase;
+ double carrier_phase_uncertainty;
+ LocGpsLossOfLock loss_of_lock;
+ int32_t bit_number;
+ int16_t time_from_last_bit_ms;
+ double doppler_shift_hz;
+ double doppler_shift_uncertainty_hz;
+ LocGpsMultipathIndicator multipath_indicator;
+ double snr_db;
+ double elevation_deg;
+ double elevation_uncertainty_deg;
+ double azimuth_deg;
+ double azimuth_uncertainty_deg;
+ bool used_in_fix;
+} LocGpsMeasurement;
+
+/**
+ * Represents a GNSS Measurement, it contains raw and computed information.
+ *
+ * Independence - All signal measurement information (e.g. sv_time,
+ * pseudorange_rate, multipath_indicator) reported in this struct should be
+ * based on GNSS signal measurements only. You may not synthesize measurements
+ * by calculating or reporting expected measurements based on known or estimated
+ * position, velocity, or time.
+ */
+typedef struct {
+ /** set to sizeof(LocGnssMeasurement) */
+ size_t size;
+
+ /** A set of flags indicating the validity of the fields in this data structure. */
+ LocGnssMeasurementFlags flags;
+
+ /**
+ * Satellite vehicle ID number, as defined in LocGnssSvInfo::svid
+ * This is a mandatory value.
+ */
+ int16_t svid;
+
+ /**
+ * Defines the constellation of the given SV. Value should be one of those
+ * LOC_GNSS_CONSTELLATION_* constants
+ */
+ LocGnssConstellationType constellation;
+
+ /**
+ * Time offset at which the measurement was taken in nanoseconds.
+ * The reference receiver's time is specified by LocGpsData::clock::time_ns and should be
+ * interpreted in the same way as indicated by LocGpsClock::type.
+ *
+ * The sign of time_offset_ns is given by the following equation:
+ * measurement time = LocGpsClock::time_ns + time_offset_ns
+ *
+ * It provides an individual time-stamp for the measurement, and allows sub-nanosecond accuracy.
+ * This is a mandatory value.
+ */
+ double time_offset_ns;
+
+ /**
+ * Per satellite sync state. It represents the current sync state for the associated satellite.
+ * Based on the sync state, the 'received GPS tow' field should be interpreted accordingly.
+ *
+ * This is a mandatory value.
+ */
+ LocGnssMeasurementState state;
+
+ /**
+ * The received GNSS Time-of-Week at the measurement time, in nanoseconds.
+ * Ensure that this field is independent (see comment at top of
+ * LocGnssMeasurement struct.)
+ *
+ * For GPS & QZSS, this is:
+ * Received GPS Time-of-Week at the measurement time, in nanoseconds.
+ * The value is relative to the beginning of the current GPS week.
+ *
+ * Given the highest sync state that can be achieved, per each satellite, valid range
+ * for this field can be:
+ * Searching : [ 0 ] : LOC_GNSS_MEASUREMENT_STATE_UNKNOWN
+ * C/A code lock : [ 0 1ms ] : LOC_GNSS_MEASUREMENT_STATE_CODE_LOCK is set
+ * Bit sync : [ 0 20ms ] : LOC_GNSS_MEASUREMENT_STATE_BIT_SYNC is set
+ * Subframe sync : [ 0 6s ] : LOC_GNSS_MEASUREMENT_STATE_SUBFRAME_SYNC is set
+ * TOW decoded : [ 0 1week ] : LOC_GNSS_MEASUREMENT_STATE_TOW_DECODED is set
+ *
+ * Note well: if there is any ambiguity in integer millisecond,
+ * LOC_GNSS_MEASUREMENT_STATE_MSEC_AMBIGUOUS should be set accordingly, in the 'state' field.
+ *
+ * This value must be populated if 'state' != LOC_GNSS_MEASUREMENT_STATE_UNKNOWN.
+ *
+ * For Glonass, this is:
+ * Received Glonass time of day, at the measurement time in nanoseconds.
+ *
+ * Given the highest sync state that can be achieved, per each satellite, valid range for
+ * this field can be:
+ * Searching : [ 0 ] : LOC_GNSS_MEASUREMENT_STATE_UNKNOWN
+ * C/A code lock : [ 0 1ms ] : LOC_GNSS_MEASUREMENT_STATE_CODE_LOCK is set
+ * Symbol sync : [ 0 10ms ] : LOC_GNSS_MEASUREMENT_STATE_SYMBOL_SYNC is set
+ * Bit sync : [ 0 20ms ] : LOC_GNSS_MEASUREMENT_STATE_BIT_SYNC is set
+ * String sync : [ 0 2s ] : LOC_GNSS_MEASUREMENT_STATE_GLO_STRING_SYNC is set
+ * Time of day : [ 0 1day ] : LOC_GNSS_MEASUREMENT_STATE_GLO_TOD_DECODED is set
+ *
+ * For Beidou, this is:
+ * Received Beidou time of week, at the measurement time in nanoseconds.
+ *
+ * Given the highest sync state that can be achieved, per each satellite, valid range for
+ * this field can be:
+ * Searching : [ 0 ] : LOC_GNSS_MEASUREMENT_STATE_UNKNOWN
+ * C/A code lock: [ 0 1ms ] : LOC_GNSS_MEASUREMENT_STATE_CODE_LOCK is set
+ * Bit sync (D2): [ 0 2ms ] : LOC_GNSS_MEASUREMENT_STATE_BDS_D2_BIT_SYNC is set
+ * Bit sync (D1): [ 0 20ms ] : LOC_GNSS_MEASUREMENT_STATE_BIT_SYNC is set
+ * Subframe (D2): [ 0 0.6s ] : LOC_GNSS_MEASUREMENT_STATE_BDS_D2_SUBFRAME_SYNC is set
+ * Subframe (D1): [ 0 6s ] : LOC_GNSS_MEASUREMENT_STATE_SUBFRAME_SYNC is set
+ * Time of week : [ 0 1week ] : LOC_GNSS_MEASUREMENT_STATE_TOW_DECODED is set
+ *
+ * For Galileo, this is:
+ * Received Galileo time of week, at the measurement time in nanoseconds.
+ *
+ * E1BC code lock : [ 0 4ms ] : LOC_GNSS_MEASUREMENT_STATE_GAL_E1BC_CODE_LOCK is set
+ * E1C 2nd code lock: [ 0 100ms ] :
+ * LOC_GNSS_MEASUREMENT_STATE_GAL_E1C_2ND_CODE_LOCK is set
+ *
+ * E1B page : [ 0 2s ] : LOC_GNSS_MEASUREMENT_STATE_GAL_E1B_PAGE_SYNC is set
+ * Time of week: [ 0 1week ] : LOC_GNSS_MEASUREMENT_STATE_TOW_DECODED is set
+ *
+ * For SBAS, this is:
+ * Received SBAS time, at the measurement time in nanoseconds.
+ *
+ * Given the highest sync state that can be achieved, per each satellite,
+ * valid range for this field can be:
+ * Searching : [ 0 ] : LOC_GNSS_MEASUREMENT_STATE_UNKNOWN
+ * C/A code lock: [ 0 1ms ] : LOC_GNSS_MEASUREMENT_STATE_CODE_LOCK is set
+ * Symbol sync : [ 0 2ms ] : LOC_GNSS_MEASUREMENT_STATE_SYMBOL_SYNC is set
+ * Message : [ 0 1s ] : LOC_GNSS_MEASUREMENT_STATE_SBAS_SYNC is set
+ */
+ int64_t received_sv_time_in_ns;
+
+ /**
+ * 1-Sigma uncertainty of the Received GPS Time-of-Week in nanoseconds.
+ *
+ * This value must be populated if 'state' != LOC_GPS_MEASUREMENT_STATE_UNKNOWN.
+ */
+ int64_t received_sv_time_uncertainty_in_ns;
+
+ /**
+ * Carrier-to-noise density in dB-Hz, typically in the range [0, 63].
+ * It contains the measured C/N0 value for the signal at the antenna port.
+ *
+ * This is a mandatory value.
+ */
+ double c_n0_dbhz;
+
+ /**
+ * Pseudorange rate at the timestamp in m/s. The correction of a given
+ * Pseudorange Rate value includes corrections for receiver and satellite
+ * clock frequency errors. Ensure that this field is independent (see
+ * comment at top of LocGnssMeasurement struct.)
+ *
+ * It is mandatory to provide the 'uncorrected' 'pseudorange rate', and provide LocGpsClock's
+ * 'drift' field as well (When providing the uncorrected pseudorange rate, do not apply the
+ * corrections described above.)
+ *
+ * The value includes the 'pseudorange rate uncertainty' in it.
+ * A positive 'uncorrected' value indicates that the SV is moving away from the receiver.
+ *
+ * The sign of the 'uncorrected' 'pseudorange rate' and its relation to the sign of 'doppler
+ * shift' is given by the equation:
+ * pseudorange rate = -k * doppler shift (where k is a constant)
+ *
+ * This should be the most accurate pseudorange rate available, based on
+ * fresh signal measurements from this channel.
+ *
+ * It is mandatory that this value be provided at typical carrier phase PRR
+ * quality (few cm/sec per second of uncertainty, or better) - when signals
+ * are sufficiently strong & stable, e.g. signals from a GPS simulator at >=
+ * 35 dB-Hz.
+ */
+ double pseudorange_rate_mps;
+
+ /**
+ * 1-Sigma uncertainty of the pseudorange_rate_mps.
+ * The uncertainty is represented as an absolute (single sided) value.
+ *
+ * This is a mandatory value.
+ */
+ double pseudorange_rate_uncertainty_mps;
+
+ /**
+ * Accumulated delta range's state. It indicates whether ADR is reset or there is a cycle slip
+ * (indicating loss of lock).
+ *
+ * This is a mandatory value.
+ */
+ LocGnssAccumulatedDeltaRangeState accumulated_delta_range_state;
+
+ /**
+ * Accumulated delta range since the last channel reset in meters.
+ * A positive value indicates that the SV is moving away from the receiver.
+ *
+ * The sign of the 'accumulated delta range' and its relation to the sign of 'carrier phase'
+ * is given by the equation:
+ * accumulated delta range = -k * carrier phase (where k is a constant)
+ *
+ * This value must be populated if 'accumulated delta range state' != LOC_GPS_ADR_STATE_UNKNOWN.
+ * However, it is expected that the data is only accurate when:
+ * 'accumulated delta range state' == LOC_GPS_ADR_STATE_VALID.
+ */
+ double accumulated_delta_range_m;
+
+ /**
+ * 1-Sigma uncertainty of the accumulated delta range in meters.
+ * This value must be populated if 'accumulated delta range state' != LOC_GPS_ADR_STATE_UNKNOWN.
+ */
+ double accumulated_delta_range_uncertainty_m;
+
+ /**
+ * Carrier frequency at which codes and messages are modulated, it can be L1 or L2.
+ * If the field is not set, the carrier frequency is assumed to be L1.
+ *
+ * If the data is available, 'flags' must contain
+ * LOC_GNSS_MEASUREMENT_HAS_CARRIER_FREQUENCY.
+ */
+ float carrier_frequency_hz;
+
+ /**
+ * The number of full carrier cycles between the satellite and the receiver.
+ * The reference frequency is given by the field 'carrier_frequency_hz'.
+ * Indications of possible cycle slips and resets in the accumulation of
+ * this value can be inferred from the accumulated_delta_range_state flags.
+ *
+ * If the data is available, 'flags' must contain
+ * LOC_GNSS_MEASUREMENT_HAS_CARRIER_CYCLES.
+ */
+ int64_t carrier_cycles;
+
+ /**
+ * The RF phase detected by the receiver, in the range [0.0, 1.0].
+ * This is usually the fractional part of the complete carrier phase measurement.
+ *
+ * The reference frequency is given by the field 'carrier_frequency_hz'.
+ * The value contains the 'carrier-phase uncertainty' in it.
+ *
+ * If the data is available, 'flags' must contain
+ * LOC_GNSS_MEASUREMENT_HAS_CARRIER_PHASE.
+ */
+ double carrier_phase;
+
+ /**
+ * 1-Sigma uncertainty of the carrier-phase.
+ * If the data is available, 'flags' must contain
+ * LOC_GNSS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY.
+ */
+ double carrier_phase_uncertainty;
+
+ /**
+ * An enumeration that indicates the 'multipath' state of the event.
+ *
+ * The multipath Indicator is intended to report the presence of overlapping
+ * signals that manifest as distorted correlation peaks.
+ *
+ * - if there is a distorted correlation peak shape, report that multipath
+ * is LOC_GNSS_MULTIPATH_INDICATOR_PRESENT.
+ * - if there is not a distorted correlation peak shape, report
+ * LOC_GNSS_MULTIPATH_INDICATOR_NOT_PRESENT
+ * - if signals are too weak to discern this information, report
+ * LOC_GNSS_MULTIPATH_INDICATOR_UNKNOWN
+ *
+ * Example: when doing the standardized overlapping Multipath Performance
+ * test (3GPP TS 34.171) the Multipath indicator should report
+ * LOC_GNSS_MULTIPATH_INDICATOR_PRESENT for those signals that are tracked, and
+ * contain multipath, and LOC_GNSS_MULTIPATH_INDICATOR_NOT_PRESENT for those
+ * signals that are tracked and do not contain multipath.
+ */
+ LocGnssMultipathIndicator multipath_indicator;
+
+ /**
+ * Signal-to-noise ratio at correlator output in dB.
+ * If the data is available, 'flags' must contain LOC_GNSS_MEASUREMENT_HAS_SNR.
+ * This is the power ratio of the "correlation peak height above the
+ * observed noise floor" to "the noise RMS".
+ */
+ double snr_db;
+} LocGnssMeasurement;
+
+/**
+ * Legacy struct to represents a reading of GPS measurements.
+ * Deprecated, to be removed in the next Android release.
+ * Use LocGnssData instead.
+ */
+typedef struct {
+ /** set to sizeof(LocGpsData) */
+ size_t size;
+ size_t measurement_count;
+ LocGpsMeasurement measurements[LOC_GPS_MAX_MEASUREMENT];
+
+ /** The GPS clock time reading. */
+ LocGpsClock clock;
+} LocGpsData;
+
+/**
+ * Represents a reading of GNSS measurements. For devices where LocGnssSystemInfo's
+ * year_of_hw is set to 2016+, it is mandatory that these be provided, on
+ * request, when the GNSS receiver is searching/tracking signals.
+ *
+ * - Reporting of GPS constellation measurements is mandatory.
+ * - Reporting of all tracked constellations are encouraged.
+ */
+typedef struct {
+ /** set to sizeof(LocGnssData) */
+ size_t size;
+
+ /** Number of measurements. */
+ size_t measurement_count;
+
+ /** The array of measurements. */
+ LocGnssMeasurement measurements[LOC_GNSS_MAX_MEASUREMENT];
+
+ /** The GPS clock time reading. */
+ LocGnssClock clock;
+} LocGnssData;
+
+/**
+ * The legacy callback for to report measurements from the HAL.
+ *
+ * This callback is deprecated, and will be removed in the next release. Use
+ * loc_gnss_measurement_callback() instead.
+ *
+ * Parameters:
+ * data - A data structure containing the measurements.
+ */
+typedef void (*loc_gps_measurement_callback) (LocGpsData* data);
+
+/**
+ * The callback for to report measurements from the HAL.
+ *
+ * Parameters:
+ * data - A data structure containing the measurements.
+ */
+typedef void (*loc_gnss_measurement_callback) (LocGnssData* data);
+
+typedef struct {
+ /** set to sizeof(LocGpsMeasurementCallbacks) */
+ size_t size;
+ loc_gps_measurement_callback measurement_callback;
+ loc_gnss_measurement_callback loc_gnss_measurement_callback;
+} LocGpsMeasurementCallbacks;
+
+#define LOC_GPS_MEASUREMENT_OPERATION_SUCCESS 0
+#define LOC_GPS_MEASUREMENT_ERROR_ALREADY_INIT -100
+#define LOC_GPS_MEASUREMENT_ERROR_GENERIC -101
+
+/**
+ * Extended interface for GPS Measurements support.
+ */
+typedef struct {
+ /** Set to sizeof(LocGpsMeasurementInterface) */
+ size_t size;
+
+ /**
+ * Initializes the interface and registers the callback routines with the HAL.
+ * After a successful call to 'init' the HAL must begin to provide updates at its own phase.
+ *
+ * Status:
+ * LOC_GPS_MEASUREMENT_OPERATION_SUCCESS
+ * LOC_GPS_MEASUREMENT_ERROR_ALREADY_INIT - if a callback has already been registered without a
+ * corresponding call to 'close'
+ * LOC_GPS_MEASUREMENT_ERROR_GENERIC - if any other error occurred, it is expected that the HAL
+ * will not generate any updates upon returning this error code.
+ */
+ int (*init) (LocGpsMeasurementCallbacks* callbacks);
+
+ /**
+ * Stops updates from the HAL, and unregisters the callback routines.
+ * After a call to stop, the previously registered callbacks must be considered invalid by the
+ * HAL.
+ * If stop is invoked without a previous 'init', this function should perform no work.
+ */
+ void (*close) ();
+
+} LocGpsMeasurementInterface;
+
+#if 0
+/**
+ * Legacy struct to represents a GPS navigation message (or a fragment of it).
+ * Deprecated, to be removed in the next Android release.
+ * Use GnssNavigationMessage instead.
+ */
+typedef struct {
+ /** set to sizeof(GpsNavigationMessage) */
+ size_t size;
+ int8_t prn;
+ GpsNavigationMessageType type;
+ NavigationMessageStatus status;
+ int16_t message_id;
+ int16_t submessage_id;
+ size_t data_length;
+ uint8_t* data;
+} GpsNavigationMessage;
+
+/** Represents a GPS navigation message (or a fragment of it). */
+typedef struct {
+ /** set to sizeof(GnssNavigationMessage) */
+ size_t size;
+
+ /**
+ * Satellite vehicle ID number, as defined in LocGnssSvInfo::svid
+ * This is a mandatory value.
+ */
+ int16_t svid;
+
+ /**
+ * The type of message contained in the structure.
+ * This is a mandatory value.
+ */
+ GnssNavigationMessageType type;
+
+ /**
+ * The status of the received navigation message.
+ * No need to send any navigation message that contains words with parity error and cannot be
+ * corrected.
+ */
+ NavigationMessageStatus status;
+
+ /**
+ * Message identifier. It provides an index so the complete Navigation
+ * Message can be assembled.
+ *
+ * - For GPS L1 C/A subframe 4 and 5, this value corresponds to the 'frame
+ * id' of the navigation message, in the range of 1-25 (Subframe 1, 2, 3
+ * does not contain a 'frame id' and this value can be set to -1.)
+ *
+ * - For Glonass L1 C/A, this refers to the frame ID, in the range of 1-5.
+ *
+ * - For BeiDou D1, this refers to the frame number in the range of 1-24
+ *
+ * - For Beidou D2, this refers to the frame number, in the range of 1-120
+ *
+ * - For Galileo F/NAV nominal frame structure, this refers to the subframe
+ * number, in the range of 1-12
+ *
+ * - For Galileo I/NAV nominal frame structure, this refers to the subframe
+ * number in the range of 1-24
+ */
+ int16_t message_id;
+
+ /**
+ * Sub-message identifier. If required by the message 'type', this value
+ * contains a sub-index within the current message (or frame) that is being
+ * transmitted.
+ *
+ * - For GPS L1 C/A, BeiDou D1 & BeiDou D2, the submessage id corresponds to
+ * the subframe number of the navigation message, in the range of 1-5.
+ *
+ * - For Glonass L1 C/A, this refers to the String number, in the range from
+ * 1-15
+ *
+ * - For Galileo F/NAV, this refers to the page type in the range 1-6
+ *
+ * - For Galileo I/NAV, this refers to the word type in the range 1-10+
+ */
+ int16_t submessage_id;
+
+ /**
+ * The length of the data (in bytes) contained in the current message.
+ * If this value is different from zero, 'data' must point to an array of the same size.
+ * e.g. for L1 C/A the size of the sub-frame will be 40 bytes (10 words, 30 bits/word).
+ *
+ * This is a mandatory value.
+ */
+ size_t data_length;
+
+ /**
+ * The data of the reported GPS message. The bytes (or words) specified
+ * using big endian format (MSB first).
+ *
+ * - For GPS L1 C/A, Beidou D1 & Beidou D2, each subframe contains 10 30-bit
+ * words. Each word (30 bits) should be fit into the last 30 bits in a
+ * 4-byte word (skip B31 and B32), with MSB first, for a total of 40
+ * bytes, covering a time period of 6, 6, and 0.6 seconds, respectively.
+ *
+ * - For Glonass L1 C/A, each string contains 85 data bits, including the
+ * checksum. These bits should be fit into 11 bytes, with MSB first (skip
+ * B86-B88), covering a time period of 2 seconds.
+ *
+ * - For Galileo F/NAV, each word consists of 238-bit (sync & tail symbols
+ * excluded). Each word should be fit into 30-bytes, with MSB first (skip
+ * B239, B240), covering a time period of 10 seconds.
+ *
+ * - For Galileo I/NAV, each page contains 2 page parts, even and odd, with
+ * a total of 2x114 = 228 bits, (sync & tail excluded) that should be fit
+ * into 29 bytes, with MSB first (skip B229-B232).
+ */
+ uint8_t* data;
+
+} GnssNavigationMessage;
+
+/**
+ * The legacy callback to report an available fragment of a GPS navigation
+ * messages from the HAL.
+ *
+ * This callback is deprecated, and will be removed in the next release. Use
+ * gnss_navigation_message_callback() instead.
+ *
+ * Parameters:
+ * message - The GPS navigation submessage/subframe representation.
+ */
+typedef void (*gps_navigation_message_callback) (GpsNavigationMessage* message);
+
+/**
+ * The callback to report an available fragment of a GPS navigation messages from the HAL.
+ *
+ * Parameters:
+ * message - The GPS navigation submessage/subframe representation.
+ */
+typedef void (*gnss_navigation_message_callback) (GnssNavigationMessage* message);
+
+typedef struct {
+ /** set to sizeof(GpsNavigationMessageCallbacks) */
+ size_t size;
+ gps_navigation_message_callback navigation_message_callback;
+ gnss_navigation_message_callback gnss_navigation_message_callback;
+} GpsNavigationMessageCallbacks;
+
+#define GPS_NAVIGATION_MESSAGE_OPERATION_SUCCESS 0
+#define GPS_NAVIGATION_MESSAGE_ERROR_ALREADY_INIT -100
+#define GPS_NAVIGATION_MESSAGE_ERROR_GENERIC -101
+
+/**
+ * Extended interface for GPS navigation message reporting support.
+ */
+typedef struct {
+ /** Set to sizeof(GpsNavigationMessageInterface) */
+ size_t size;
+
+ /**
+ * Initializes the interface and registers the callback routines with the HAL.
+ * After a successful call to 'init' the HAL must begin to provide updates as they become
+ * available.
+ *
+ * Status:
+ * GPS_NAVIGATION_MESSAGE_OPERATION_SUCCESS
+ * GPS_NAVIGATION_MESSAGE_ERROR_ALREADY_INIT - if a callback has already been registered
+ * without a corresponding call to 'close'.
+ * GPS_NAVIGATION_MESSAGE_ERROR_GENERIC - if any other error occurred, it is expected that
+ * the HAL will not generate any updates upon returning this error code.
+ */
+ int (*init) (GpsNavigationMessageCallbacks* callbacks);
+
+ /**
+ * Stops updates from the HAL, and unregisters the callback routines.
+ * After a call to stop, the previously registered callbacks must be considered invalid by the
+ * HAL.
+ * If stop is invoked without a previous 'init', this function should perform no work.
+ */
+ void (*close) ();
+
+} GpsNavigationMessageInterface;
+#endif
+
+/**
+ * Interface for passing GNSS configuration contents from platform to HAL.
+ */
+typedef struct {
+ /** Set to sizeof(LocGnssConfigurationInterface) */
+ size_t size;
+
+ /**
+ * Deliver GNSS configuration contents to HAL.
+ * Parameters:
+ * config_data - a pointer to a char array which holds what usually is expected from
+ file(/vendor/etc/gps.conf), i.e., a sequence of UTF8 strings separated by '\n'.
+ * length - total number of UTF8 characters in configuraiton data.
+ *
+ * IMPORTANT:
+ * GPS HAL should expect this function can be called multiple times. And it may be
+ * called even when GpsLocationProvider is already constructed and enabled. GPS HAL
+ * should maintain the existing requests for various callback regardless the change
+ * in configuration data.
+ */
+ void (*configuration_update) (const char* config_data, int32_t length);
+} LocGnssConfigurationInterface;
+
+__END_DECLS
+
+#endif /* LOC_GPS_H */
+
diff --git a/gps/utils/loc_log.cpp b/gps/utils/loc_log.cpp
new file mode 100644
index 0000000..9fad9e6
--- /dev/null
+++ b/gps/utils/loc_log.cpp
@@ -0,0 +1,237 @@
+/* Copyright (c) 2011-2012, 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation, nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#define LOG_NDEBUG 0
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include "loc_log.h"
+#include "msg_q.h"
+#include <platform_lib_includes.h>
+
+#define BUFFER_SIZE 120
+
+// 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";
+const char EXIT_ERROR_TAG[] = "Exiting with error";
+
+/* Logging Mechanism */
+loc_logger_s_type loc_logger;
+
+/* Get names from value */
+const char* loc_get_name_from_mask(const loc_name_val_s_type table[], size_t table_size, long mask)
+{
+ size_t 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(const loc_name_val_s_type table[], size_t table_size, long value)
+{
+ size_t i;
+ for (i = 0; i < table_size; i++)
+ {
+ if (table[i].val == (long) value)
+ {
+ return table[i].name;
+ }
+ }
+ return UNKNOWN_STR;
+}
+
+static const 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 const size_t loc_msg_q_status_num = LOC_TABLE_SIZE(loc_msg_q_status);
+
+/* 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";
+}
+
+//Target names
+static const loc_name_val_s_type target_name[] =
+{
+ NAME_VAL(GNSS_NONE),
+ NAME_VAL(GNSS_MSM),
+ NAME_VAL(GNSS_GSS),
+ NAME_VAL(GNSS_MDM),
+ NAME_VAL(GNSS_AUTO),
+ NAME_VAL(GNSS_UNKNOWN)
+};
+
+static const size_t target_name_num = LOC_TABLE_SIZE(target_name);
+
+/*===========================================================================
+
+FUNCTION loc_get_target_name
+
+DESCRIPTION
+ Returns pointer to a string that contains name of the target
+
+ XX:XX:XX.000\0
+
+RETURN VALUE
+ The target name string
+
+===========================================================================*/
+const char *loc_get_target_name(unsigned int target)
+{
+ int index = 0;
+ static char ret[BUFFER_SIZE];
+
+ index = getTargetGnssType(target);
+ if( index < 0 || (unsigned)index >= target_name_num )
+ index = target_name_num - 1;
+
+ if( (target & HAS_SSC) == HAS_SSC ) {
+ snprintf(ret, sizeof(ret), " %s with SSC",
+ loc_get_name_from_val(target_name, target_name_num, (long)index) );
+ }
+ else {
+ snprintf(ret, sizeof(ret), " %s without SSC",
+ loc_get_name_from_val(target_name, target_name_num, (long)index) );
+ }
+ return ret;
+}
+
+
+/*===========================================================================
+
+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, size_t 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;
+#ifdef TARGET_BUILD_VARIANT_USER
+ // force user builds to 2 or less
+ if (loc_logger.DEBUG_LEVEL > 2) {
+ loc_logger.DEBUG_LEVEL = 2;
+ }
+#endif
+ 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..be492b1
--- /dev/null
+++ b/gps/utils/loc_log.h
@@ -0,0 +1,71 @@
+/* Copyright (c) 2011-2012, 2015 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation, nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef LOC_LOG_H
+#define LOC_LOG_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <ctype.h>
+#include <stdlib.h>
+#include "loc_target.h"
+
+typedef struct
+{
+ const char *name;
+ 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))
+
+#define LOC_TABLE_SIZE(table) (sizeof(table)/sizeof((table)[0]))
+
+/* Get names from value */
+const char* loc_get_name_from_mask(const loc_name_val_s_type table[], size_t table_size, long mask);
+const char* loc_get_name_from_val(const loc_name_val_s_type table[], size_t table_size, long value);
+const char* loc_get_msg_q_status(int status);
+const char* loc_get_target_name(unsigned int target);
+
+extern const char* log_succ_fail_string(int is_succ);
+
+extern char *loc_get_time(char *time_string, size_t buf_size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LOC_LOG_H */
diff --git a/gps/utils/loc_misc_utils.cpp b/gps/utils/loc_misc_utils.cpp
new file mode 100644
index 0000000..fd3ee6b
--- /dev/null
+++ b/gps/utils/loc_misc_utils.cpp
@@ -0,0 +1,114 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation, nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#define LOG_NDEBUG 0
+#define LOG_TAG "LocSvc_misc_utils"
+#include <stdio.h>
+#include <string.h>
+#include <platform_lib_log_util.h>
+#include <loc_misc_utils.h>
+#include <ctype.h>
+
+
+int loc_util_split_string(char *raw_string, char **split_strings_ptr,
+ int max_num_substrings, char delimiter)
+{
+ int raw_string_index=0;
+ int num_split_strings=0;
+ unsigned char end_string=0;
+ int raw_string_length=0;
+
+ if(!raw_string || !split_strings_ptr) {
+ LOC_LOGE("%s:%d]: NULL parameters", __func__, __LINE__);
+ num_split_strings = -1;
+ goto err;
+ }
+ LOC_LOGD("%s:%d]: raw string: %s\n", __func__, __LINE__, raw_string);
+ raw_string_length = strlen(raw_string) + 1;
+ split_strings_ptr[num_split_strings] = &raw_string[raw_string_index];
+ for(raw_string_index=0; raw_string_index < raw_string_length; raw_string_index++) {
+ if(raw_string[raw_string_index] == '\0')
+ end_string=1;
+ if((raw_string[raw_string_index] == delimiter) || end_string) {
+ raw_string[raw_string_index] = '\0';
+ LOC_LOGD("%s:%d]: split string: %s\n",
+ __func__, __LINE__, split_strings_ptr[num_split_strings]);
+ num_split_strings++;
+ if(((raw_string_index + 1) < raw_string_length) &&
+ (num_split_strings < max_num_substrings)) {
+ split_strings_ptr[num_split_strings] = &raw_string[raw_string_index+1];
+ }
+ else {
+ break;
+ }
+ }
+ if(end_string)
+ break;
+ }
+err:
+ LOC_LOGD("%s:%d]: num_split_strings: %d\n", __func__, __LINE__, num_split_strings);
+ return num_split_strings;
+}
+
+void loc_util_trim_space(char *org_string)
+{
+ char *scan_ptr, *write_ptr;
+ char *first_nonspace = NULL, *last_nonspace = NULL;
+
+ if(org_string == NULL) {
+ LOC_LOGE("%s:%d]: NULL parameter", __func__, __LINE__);
+ goto err;
+ }
+
+ scan_ptr = write_ptr = org_string;
+
+ while (*scan_ptr) {
+ //Find the first non-space character
+ if ( !isspace(*scan_ptr) && first_nonspace == NULL) {
+ first_nonspace = scan_ptr;
+ }
+ //Once the first non-space character is found in the
+ //above check, keep shifting the characters to the left
+ //to replace the spaces
+ if (first_nonspace != NULL) {
+ *(write_ptr++) = *scan_ptr;
+ //Keep track of which was the last non-space character
+ //encountered
+ //last_nonspace will not be updated in the case where
+ //the string ends with spaces
+ if ( !isspace(*scan_ptr)) {
+ last_nonspace = write_ptr;
+ }
+ }
+ scan_ptr++;
+ }
+ //Add NULL terminator after the last non-space character
+ if (last_nonspace) { *last_nonspace = '\0'; }
+err:
+ return;
+}
diff --git a/gps/utils/loc_misc_utils.h b/gps/utils/loc_misc_utils.h
new file mode 100644
index 0000000..7d66d84
--- /dev/null
+++ b/gps/utils/loc_misc_utils.h
@@ -0,0 +1,99 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation, nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef _LOC_MISC_UTILS_H_
+#define _LOC_MISC_UTILS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*===========================================================================
+FUNCTION loc_split_string
+
+DESCRIPTION:
+ This function is used to split a delimiter separated string into
+ sub-strings. This function does not allocate new memory to store the split
+ strings. Instead, it places '\0' in places of delimiters and assings the
+ starting address of the substring within the raw string as the string address
+ The input raw_string no longer remains to be a collection of sub-strings
+ after this function is executed.
+ Please make a copy of the input string before calling this function if
+ necessary
+
+PARAMETERS:
+ char *raw_string: is the original string with delimiter separated substrings
+ char **split_strings_ptr: is the arraw of pointers which will hold the addresses
+ of individual substrings
+ int max_num_substrings: is the maximum number of substrings that are expected
+ by the caller. The array of pointers in the above parameter
+ is usually this long
+ char delimiter: is the delimiter that separates the substrings. Examples: ' ', ';'
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ int Number of split strings
+
+SIDE EFFECTS
+ The input raw_string no longer remains a delimiter separated single string.
+
+EXAMPLE
+ delimiter = ' ' //space
+ raw_string = "hello new user" //delimiter is space ' '
+ addresses = 0123456789abcd
+ split_strings_ptr[0] = &raw_string[0]; //split_strings_ptr[0] contains "hello"
+ split_strings_ptr[1] = &raw_string[6]; //split_strings_ptr[1] contains "new"
+ split_strings_ptr[2] = &raw_string[a]; //split_strings_ptr[2] contains "user"
+
+===========================================================================*/
+int loc_util_split_string(char *raw_string, char **split_strings_ptr, int max_num_substrings,
+ char delimiter);
+
+/*===========================================================================
+FUNCTION trim_space
+
+DESCRIPTION
+ Removes leading and trailing spaces of the string
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ None
+
+SIDE EFFECTS
+ N/A
+===========================================================================*/
+void loc_util_trim_space(char *org_string);
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_LOC_MISC_UTILS_H_
diff --git a/gps/utils/loc_nmea.cpp b/gps/utils/loc_nmea.cpp
new file mode 100644
index 0000000..eb193cc
--- /dev/null
+++ b/gps/utils/loc_nmea.cpp
@@ -0,0 +1,1106 @@
+/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "LocSvc_nmea"
+#include <loc_nmea.h>
+#include <math.h>
+#include <platform_lib_includes.h>
+
+#define GLONASS_SV_ID_OFFSET 64
+#define MAX_SATELLITES_IN_USE 12
+
+// GNSS system id according to NMEA spec
+#define SYSTEM_ID_GPS 1
+#define SYSTEM_ID_GLONASS 2
+#define SYSTEM_ID_GALILEO 3
+// Extended systems
+#define SYSTEM_ID_BEIDOU 4
+#define SYSTEM_ID_QZSS 5
+
+typedef struct loc_nmea_sv_meta_s
+{
+ char talker[3];
+ LocGnssConstellationType svType;
+ uint32_t mask;
+ uint32_t svCount;
+ uint32_t svIdOffset;
+ uint32_t systemId;
+} loc_nmea_sv_meta;
+
+typedef struct loc_sv_cache_info_s
+{
+ uint32_t gps_used_mask;
+ uint32_t glo_used_mask;
+ uint32_t gal_used_mask;
+ uint32_t qzss_used_mask;
+ uint32_t bds_used_mask;
+ uint32_t gps_count;
+ uint32_t glo_count;
+ uint32_t gal_count;
+ uint32_t qzss_count;
+ uint32_t bds_count;
+ float hdop;
+ float pdop;
+ float vdop;
+} loc_sv_cache_info;
+
+static loc_sv_cache_info sv_cache_info;
+
+/*===========================================================================
+FUNCTION loc_nmea_sv_meta_init
+
+DESCRIPTION
+ Init loc_nmea_sv_meta passed in
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ Pointer to loc_nmea_sv_meta
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static loc_nmea_sv_meta* loc_nmea_sv_meta_init(loc_nmea_sv_meta& sv_meta,
+ GnssSvType svType,
+ bool needCombine)
+{
+ memset(&sv_meta, 0, sizeof(sv_meta));
+ sv_meta.svType = svType;
+
+ switch (svType)
+ {
+ case GNSS_SV_TYPE_GPS:
+ sv_meta.talker[0] = 'G';
+ sv_meta.talker[1] = 'P';
+ sv_meta.mask = sv_cache_info.gps_used_mask;
+ sv_meta.svCount = sv_cache_info.gps_count;
+ sv_meta.systemId = SYSTEM_ID_GPS;
+ break;
+ case GNSS_SV_TYPE_GLONASS:
+ sv_meta.talker[0] = 'G';
+ sv_meta.talker[1] = 'L';
+ sv_meta.mask = sv_cache_info.glo_used_mask;
+ sv_meta.svCount = sv_cache_info.glo_count;
+ // GLONASS SV ids are from 65-96
+ sv_meta.svIdOffset = GLONASS_SV_ID_OFFSET;
+ sv_meta.systemId = SYSTEM_ID_GLONASS;
+ break;
+ case GNSS_SV_TYPE_GALILEO:
+ sv_meta.talker[0] = 'G';
+ sv_meta.talker[1] = 'A';
+ sv_meta.mask = sv_cache_info.gal_used_mask;
+ sv_meta.svCount = sv_cache_info.gal_count;
+ sv_meta.systemId = SYSTEM_ID_GALILEO;
+ break;
+ case GNSS_SV_TYPE_QZSS:
+ sv_meta.talker[0] = 'P';
+ sv_meta.talker[1] = 'Q';
+ sv_meta.mask = sv_cache_info.qzss_used_mask;
+ sv_meta.svCount = sv_cache_info.qzss_count;
+ // QZSS SV ids are from 193-197. So keep svIdOffset 0
+ sv_meta.systemId = SYSTEM_ID_QZSS;
+ break;
+ case GNSS_SV_TYPE_BEIDOU:
+ sv_meta.talker[0] = 'P';
+ sv_meta.talker[1] = 'Q';
+ sv_meta.mask = sv_cache_info.bds_used_mask;
+ sv_meta.svCount = sv_cache_info.bds_count;
+ // BDS SV ids are from 201-235. So keep svIdOffset 0
+ sv_meta.systemId = SYSTEM_ID_BEIDOU;
+ break;
+ default:
+ LOC_LOGE("NMEA Error unknow constellation type: %d", svType);
+ return NULL;
+ }
+ if (needCombine &&
+ (sv_cache_info.gps_used_mask ? 1 : 0) +
+ (sv_cache_info.glo_used_mask ? 1 : 0) +
+ (sv_cache_info.gal_used_mask ? 1 : 0) +
+ (sv_cache_info.qzss_used_mask ? 1 : 0) +
+ (sv_cache_info.bds_used_mask ? 1 : 0) > 1)
+ {
+ // If GPS, GLONASS, Galileo, QZSS, BDS etc. are combined
+ // to obtain the reported position solution,
+ // talker shall be set to GN, to indicate that
+ // the satellites are used in a combined solution
+ sv_meta.talker[0] = 'G';
+ sv_meta.talker[1] = 'N';
+ }
+ return &sv_meta;
+}
+
+/*===========================================================================
+FUNCTION loc_nmea_put_checksum
+
+DESCRIPTION
+ Generate NMEA sentences generated based on position report
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ Total length of the nmea sentence
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static int loc_nmea_put_checksum(char *pNmea, int maxSize)
+{
+ uint8_t checksum = 0;
+ int length = 0;
+ if(NULL == pNmea)
+ return 0;
+
+ pNmea++; //skip the $
+ while (*pNmea != '\0')
+ {
+ checksum ^= *pNmea++;
+ length++;
+ }
+
+ // length now contains nmea sentence string length not including $ sign.
+ int checksumLength = snprintf(pNmea,(maxSize-length-1),"*%02X\r\n", checksum);
+
+ // total length of nmea sentence is length of nmea sentence inc $ sign plus
+ // length of checksum (+1 is to cover the $ character in the length).
+ return (length + checksumLength + 1);
+}
+
+/*===========================================================================
+FUNCTION loc_nmea_generate_GSA
+
+DESCRIPTION
+ Generate NMEA GSA sentences generated based on position report
+ Currently below sentences are generated:
+ - $GPGSA : GPS DOP and active SVs
+ - $GLGSA : GLONASS DOP and active SVs
+ - $GAGSA : GALILEO DOP and active SVs
+ - $GNGSA : GNSS DOP and active SVs
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ Number of SVs used
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static uint32_t loc_nmea_generate_GSA(const GpsLocationExtended &locationExtended,
+ char* sentence,
+ int bufSize,
+ loc_nmea_sv_meta* sv_meta_p,
+ std::vector<std::string> &nmeaArraystr)
+{
+ if (!sentence || bufSize <= 0 || !sv_meta_p)
+ {
+ LOC_LOGE("NMEA Error invalid arguments.");
+ return 0;
+ }
+
+ char* pMarker = sentence;
+ int lengthRemaining = bufSize;
+ int length = 0;
+
+ uint32_t svUsedCount = 0;
+ uint32_t svUsedList[32] = {0};
+
+ char fixType = '\0';
+
+ const char* talker = sv_meta_p->talker;
+ uint32_t svIdOffset = sv_meta_p->svIdOffset;
+ uint32_t mask = sv_meta_p->mask;
+
+ for (uint8_t i = 1; mask > 0 && svUsedCount < 32; i++)
+ {
+ if (mask & 1)
+ svUsedList[svUsedCount++] = i + svIdOffset;
+ mask = mask >> 1;
+ }
+
+ if (svUsedCount == 0 && GNSS_SV_TYPE_GPS != sv_meta_p->svType)
+ return 0;
+
+ if (svUsedCount == 0)
+ fixType = '1'; // no fix
+ else if (svUsedCount <= 3)
+ fixType = '2'; // 2D fix
+ else
+ fixType = '3'; // 3D fix
+
+ // Start printing the sentence
+ // Format: $--GSA,a,x,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,p.p,h.h,v.v*cc
+ // a : Mode : A : Automatic, allowed to automatically switch 2D/3D
+ // x : Fixtype : 1 (no fix), 2 (2D fix), 3 (3D fix)
+ // xx : 12 SV ID
+ // p.p : Position DOP (Dilution of Precision)
+ // h.h : Horizontal DOP
+ // v.v : Vertical DOP
+ // cc : Checksum value
+ length = snprintf(pMarker, lengthRemaining, "$%sGSA,A,%c,", talker, fixType);
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return 0;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ // Add first 12 satellite IDs
+ for (uint8_t i = 0; i < 12; i++)
+ {
+ if (i < svUsedCount)
+ length = snprintf(pMarker, lengthRemaining, "%02d,", svUsedList[i]);
+ else
+ length = snprintf(pMarker, lengthRemaining, ",");
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return 0;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+ }
+
+ // Add the position/horizontal/vertical DOP values
+ if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_DOP)
+ {
+ length = snprintf(pMarker, lengthRemaining, "%.1f,%.1f,%.1f,",
+ locationExtended.pdop,
+ locationExtended.hdop,
+ locationExtended.vdop);
+ }
+ else
+ { // no dop
+ length = snprintf(pMarker, lengthRemaining, ",,,");
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ // system id
+ length = snprintf(pMarker, lengthRemaining, "%d", sv_meta_p->systemId);
+ pMarker += length;
+ lengthRemaining -= length;
+
+ /* Sentence is ready, add checksum and broadcast */
+ length = loc_nmea_put_checksum(sentence, bufSize);
+ nmeaArraystr.push_back(sentence);
+
+ return svUsedCount;
+}
+
+/*===========================================================================
+FUNCTION loc_nmea_generate_GSV
+
+DESCRIPTION
+ Generate NMEA GSV sentences generated based on sv report
+ Currently below sentences are generated:
+ - $GPGSV: GPS Satellites in View
+ - $GNGSV: GLONASS Satellites in View
+ - $GAGSV: GALILEO Satellites in View
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ NONE
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static void loc_nmea_generate_GSV(const GnssSvNotification &svNotify,
+ char* sentence,
+ int bufSize,
+ loc_nmea_sv_meta* sv_meta_p,
+ std::vector<std::string> &nmeaArraystr)
+{
+ if (!sentence || bufSize <= 0)
+ {
+ LOC_LOGE("NMEA Error invalid argument.");
+ return;
+ }
+
+ char* pMarker = sentence;
+ int lengthRemaining = bufSize;
+ int length = 0;
+ int sentenceCount = 0;
+ int sentenceNumber = 1;
+ size_t svNumber = 1;
+
+ const char* talker = sv_meta_p->talker;
+ uint32_t svIdOffset = sv_meta_p->svIdOffset;
+ int svCount = sv_meta_p->svCount;
+
+ if (svCount <= 0)
+ {
+ // no svs in view, so just send a blank $--GSV sentence
+ snprintf(sentence, lengthRemaining, "$%sGSV,1,1,0,", talker);
+ length = loc_nmea_put_checksum(sentence, bufSize);
+ nmeaArraystr.push_back(sentence);
+ return;
+ }
+
+ svNumber = 1;
+ sentenceNumber = 1;
+ sentenceCount = svCount / 4 + (svCount % 4 != 0);
+
+ while (sentenceNumber <= sentenceCount)
+ {
+ pMarker = sentence;
+ lengthRemaining = bufSize;
+
+ length = snprintf(pMarker, lengthRemaining, "$%sGSV,%d,%d,%02d",
+ talker, sentenceCount, sentenceNumber, svCount);
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ for (int i=0; (svNumber <= svNotify.count) && (i < 4); svNumber++)
+ {
+ if (sv_meta_p->svType == svNotify.gnssSvs[svNumber - 1].type)
+ {
+ length = snprintf(pMarker, lengthRemaining,",%02d,%02d,%03d,",
+ svNotify.gnssSvs[svNumber - 1].svId + svIdOffset,
+ (int)(0.5 + svNotify.gnssSvs[svNumber - 1].elevation), //float to int
+ (int)(0.5 + svNotify.gnssSvs[svNumber - 1].azimuth)); //float to int
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if (svNotify.gnssSvs[svNumber - 1].cN0Dbhz > 0)
+ {
+ length = snprintf(pMarker, lengthRemaining,"%02d",
+ (int)(0.5 + svNotify.gnssSvs[svNumber - 1].cN0Dbhz)); //float to int
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+ }
+
+ i++;
+ }
+
+ }
+
+ // The following entries are specific to QZSS and BDS
+ if ((sv_meta_p->svType == GNSS_SV_TYPE_QZSS) ||
+ (sv_meta_p->svType == GNSS_SV_TYPE_BEIDOU))
+ {
+ // last one is System id and second last is Signal Id which is always zero
+ length = snprintf(pMarker, lengthRemaining,",%d,%d",0,sv_meta_p->systemId);
+ pMarker += length;
+ lengthRemaining -= length;
+ }
+
+ length = loc_nmea_put_checksum(sentence, bufSize);
+ nmeaArraystr.push_back(sentence);
+ sentenceNumber++;
+
+ } //while
+}
+
+/*===========================================================================
+FUNCTION loc_nmea_generate_pos
+
+DESCRIPTION
+ Generate NMEA sentences generated based on position report
+ Currently below sentences are generated within this function:
+ - $GPGSA : GPS DOP and active SVs
+ - $GLGSA : GLONASS DOP and active SVs
+ - $GAGSA : GALILEO DOP and active SVs
+ - $GNGSA : GNSS DOP and active SVs
+ - $--VTG : Track made good and ground speed
+ - $--RMC : Recommended minimum navigation information
+ - $--GGA : Time, position and fix related data
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ 0
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+void loc_nmea_generate_pos(const UlpLocation &location,
+ const GpsLocationExtended &locationExtended,
+ unsigned char generate_nmea,
+ std::vector<std::string> &nmeaArraystr)
+{
+ ENTRY_LOG();
+ time_t utcTime(location.gpsLocation.timestamp/1000);
+ tm * pTm = gmtime(&utcTime);
+ if (NULL == pTm) {
+ LOC_LOGE("gmtime failed");
+ return;
+ }
+
+ char sentence[NMEA_SENTENCE_MAX_LENGTH] = {0};
+ char* pMarker = sentence;
+ int lengthRemaining = sizeof(sentence);
+ int length = 0;
+ int utcYear = pTm->tm_year % 100; // 2 digit year
+ int utcMonth = pTm->tm_mon + 1; // tm_mon starts at zero
+ int utcDay = pTm->tm_mday;
+ int utcHours = pTm->tm_hour;
+ int utcMinutes = pTm->tm_min;
+ int utcSeconds = pTm->tm_sec;
+ int utcMSeconds = (location.gpsLocation.timestamp)%1000;
+
+ if (generate_nmea) {
+ char talker[3] = {'G', 'P', '\0'};
+ uint32_t svUsedCount = 0;
+ uint32_t count = 0;
+ loc_nmea_sv_meta sv_meta;
+ // -------------------
+ // ---$GPGSA/$GNGSA---
+ // -------------------
+
+ count = loc_nmea_generate_GSA(locationExtended, sentence, sizeof(sentence),
+ loc_nmea_sv_meta_init(sv_meta, GNSS_SV_TYPE_GPS, true), nmeaArraystr);
+ if (count > 0)
+ {
+ svUsedCount += count;
+ talker[0] = sv_meta.talker[0];
+ talker[1] = sv_meta.talker[1];
+ }
+
+ // -------------------
+ // ---$GLGSA/$GNGSA---
+ // -------------------
+
+ count = loc_nmea_generate_GSA(locationExtended, sentence, sizeof(sentence),
+ loc_nmea_sv_meta_init(sv_meta, GNSS_SV_TYPE_GLONASS, true), nmeaArraystr);
+ if (count > 0)
+ {
+ svUsedCount += count;
+ talker[0] = sv_meta.talker[0];
+ talker[1] = sv_meta.talker[1];
+ }
+
+ // -------------------
+ // ---$GAGSA/$GNGSA---
+ // -------------------
+
+ count = loc_nmea_generate_GSA(locationExtended, sentence, sizeof(sentence),
+ loc_nmea_sv_meta_init(sv_meta, GNSS_SV_TYPE_GALILEO, true), nmeaArraystr);
+ if (count > 0)
+ {
+ svUsedCount += count;
+ talker[0] = sv_meta.talker[0];
+ talker[1] = sv_meta.talker[1];
+ }
+
+ // --------------------------
+ // ---$PQGSA/$GNGSA (QZSS)---
+ // --------------------------
+
+ count = loc_nmea_generate_GSA(locationExtended, sentence, sizeof(sentence),
+ loc_nmea_sv_meta_init(sv_meta, GNSS_SV_TYPE_QZSS, false), nmeaArraystr);
+ if (count > 0)
+ {
+ svUsedCount += count;
+ // talker should be default "GP". If GPS, GLO etc is used, it should be "GN"
+ }
+
+ // ----------------------------
+ // ---$PQGSA/$GNGSA (BEIDOU)---
+ // ----------------------------
+ count = loc_nmea_generate_GSA(locationExtended, sentence, sizeof(sentence),
+ loc_nmea_sv_meta_init(sv_meta, GNSS_SV_TYPE_BEIDOU, false), nmeaArraystr);
+ if (count > 0)
+ {
+ svUsedCount += count;
+ // talker should be default "GP". If GPS, GLO etc is used, it should be "GN"
+ }
+
+ // -------------------
+ // ------$--VTG-------
+ // -------------------
+
+ pMarker = sentence;
+ lengthRemaining = sizeof(sentence);
+
+ if (location.gpsLocation.flags & LOC_GPS_LOCATION_HAS_BEARING)
+ {
+ float magTrack = location.gpsLocation.bearing;
+ if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_MAG_DEV)
+ {
+ float magTrack = location.gpsLocation.bearing - locationExtended.magneticDeviation;
+ if (magTrack < 0.0)
+ magTrack += 360.0;
+ else if (magTrack > 360.0)
+ magTrack -= 360.0;
+ }
+
+ length = snprintf(pMarker, lengthRemaining, "$%sVTG,%.1lf,T,%.1lf,M,", talker, location.gpsLocation.bearing, magTrack);
+ }
+ else
+ {
+ length = snprintf(pMarker, lengthRemaining, "$%sVTG,,T,,M,", talker);
+ }
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if (location.gpsLocation.flags & LOC_GPS_LOCATION_HAS_SPEED)
+ {
+ float speedKnots = location.gpsLocation.speed * (3600.0/1852.0);
+ float speedKmPerHour = location.gpsLocation.speed * 3.6;
+
+ length = snprintf(pMarker, lengthRemaining, "%.1lf,N,%.1lf,K,", speedKnots, speedKmPerHour);
+ }
+ else
+ {
+ length = snprintf(pMarker, lengthRemaining, ",N,,K,");
+ }
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if (!(location.gpsLocation.flags & LOC_GPS_LOCATION_HAS_LAT_LONG))
+ // N means no fix
+ length = snprintf(pMarker, lengthRemaining, "%c", 'N');
+ else if (LOC_NAV_MASK_SBAS_CORRECTION_IONO & locationExtended.navSolutionMask)
+ // D means differential
+ length = snprintf(pMarker, lengthRemaining, "%c", 'D');
+ else if (LOC_POS_TECH_MASK_SENSORS == locationExtended.tech_mask)
+ // E means estimated (dead reckoning)
+ length = snprintf(pMarker, lengthRemaining, "%c", 'E');
+ else // A means autonomous
+ length = snprintf(pMarker, lengthRemaining, "%c", 'A');
+
+ length = loc_nmea_put_checksum(sentence, sizeof(sentence));
+ nmeaArraystr.push_back(sentence);
+
+ // -------------------
+ // ------$--RMC-------
+ // -------------------
+
+ pMarker = sentence;
+ lengthRemaining = sizeof(sentence);
+
+ length = snprintf(pMarker, lengthRemaining, "$%sRMC,%02d%02d%02d.%02d,A," ,
+ talker, utcHours, utcMinutes, utcSeconds,utcMSeconds/10);
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if (location.gpsLocation.flags & LOC_GPS_LOCATION_HAS_LAT_LONG)
+ {
+ double latitude = location.gpsLocation.latitude;
+ double longitude = location.gpsLocation.longitude;
+ char latHemisphere;
+ char lonHemisphere;
+ double latMinutes;
+ double lonMinutes;
+
+ if (latitude > 0)
+ {
+ latHemisphere = 'N';
+ }
+ else
+ {
+ latHemisphere = 'S';
+ latitude *= -1.0;
+ }
+
+ if (longitude < 0)
+ {
+ lonHemisphere = 'W';
+ longitude *= -1.0;
+ }
+ else
+ {
+ lonHemisphere = 'E';
+ }
+
+ latMinutes = fmod(latitude * 60.0 , 60.0);
+ lonMinutes = fmod(longitude * 60.0 , 60.0);
+
+ length = snprintf(pMarker, lengthRemaining, "%02d%09.6lf,%c,%03d%09.6lf,%c,",
+ (uint8_t)floor(latitude), latMinutes, latHemisphere,
+ (uint8_t)floor(longitude),lonMinutes, lonHemisphere);
+ }
+ else
+ {
+ length = snprintf(pMarker, lengthRemaining,",,,,");
+ }
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if (location.gpsLocation.flags & LOC_GPS_LOCATION_HAS_SPEED)
+ {
+ float speedKnots = location.gpsLocation.speed * (3600.0/1852.0);
+ length = snprintf(pMarker, lengthRemaining, "%.1lf,", speedKnots);
+ }
+ else
+ {
+ length = snprintf(pMarker, lengthRemaining, ",");
+ }
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if (location.gpsLocation.flags & LOC_GPS_LOCATION_HAS_BEARING)
+ {
+ length = snprintf(pMarker, lengthRemaining, "%.1lf,", location.gpsLocation.bearing);
+ }
+ else
+ {
+ length = snprintf(pMarker, lengthRemaining, ",");
+ }
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ length = snprintf(pMarker, lengthRemaining, "%2.2d%2.2d%2.2d,",
+ utcDay, utcMonth, utcYear);
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_MAG_DEV)
+ {
+ float magneticVariation = locationExtended.magneticDeviation;
+ char direction;
+ if (magneticVariation < 0.0)
+ {
+ direction = 'W';
+ magneticVariation *= -1.0;
+ }
+ else
+ {
+ direction = 'E';
+ }
+
+ length = snprintf(pMarker, lengthRemaining, "%.1lf,%c,",
+ magneticVariation, direction);
+ }
+ else
+ {
+ length = snprintf(pMarker, lengthRemaining, ",,");
+ }
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if (!(location.gpsLocation.flags & LOC_GPS_LOCATION_HAS_LAT_LONG))
+ // N means no fix
+ length = snprintf(pMarker, lengthRemaining, "%c", 'N');
+ else if (LOC_NAV_MASK_SBAS_CORRECTION_IONO & locationExtended.navSolutionMask)
+ // D means differential
+ length = snprintf(pMarker, lengthRemaining, "%c", 'D');
+ else if (LOC_POS_TECH_MASK_SENSORS == locationExtended.tech_mask)
+ // E means estimated (dead reckoning)
+ length = snprintf(pMarker, lengthRemaining, "%c", 'E');
+ else // A means autonomous
+ length = snprintf(pMarker, lengthRemaining, "%c", 'A');
+
+ length = loc_nmea_put_checksum(sentence, sizeof(sentence));
+ nmeaArraystr.push_back(sentence);
+
+ // -------------------
+ // ------$--GGA-------
+ // -------------------
+
+ pMarker = sentence;
+ lengthRemaining = sizeof(sentence);
+
+ length = snprintf(pMarker, lengthRemaining, "$%sGGA,%02d%02d%02d.%02d," ,
+ talker, utcHours, utcMinutes, utcSeconds, utcMSeconds/10);
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if (location.gpsLocation.flags & LOC_GPS_LOCATION_HAS_LAT_LONG)
+ {
+ double latitude = location.gpsLocation.latitude;
+ double longitude = location.gpsLocation.longitude;
+ char latHemisphere;
+ char lonHemisphere;
+ double latMinutes;
+ double lonMinutes;
+
+ if (latitude > 0)
+ {
+ latHemisphere = 'N';
+ }
+ else
+ {
+ latHemisphere = 'S';
+ latitude *= -1.0;
+ }
+
+ if (longitude < 0)
+ {
+ lonHemisphere = 'W';
+ longitude *= -1.0;
+ }
+ else
+ {
+ lonHemisphere = 'E';
+ }
+
+ latMinutes = fmod(latitude * 60.0 , 60.0);
+ lonMinutes = fmod(longitude * 60.0 , 60.0);
+
+ length = snprintf(pMarker, lengthRemaining, "%02d%09.6lf,%c,%03d%09.6lf,%c,",
+ (uint8_t)floor(latitude), latMinutes, latHemisphere,
+ (uint8_t)floor(longitude),lonMinutes, lonHemisphere);
+ }
+ else
+ {
+ length = snprintf(pMarker, lengthRemaining,",,,,");
+ }
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ char gpsQuality;
+ if (!(location.gpsLocation.flags & LOC_GPS_LOCATION_HAS_LAT_LONG))
+ gpsQuality = '0'; // 0 means no fix
+ else if (LOC_NAV_MASK_SBAS_CORRECTION_IONO & locationExtended.navSolutionMask)
+ gpsQuality = '2'; // 2 means DGPS fix
+ else if (LOC_POS_TECH_MASK_SENSORS == locationExtended.tech_mask)
+ gpsQuality = '6'; // 6 means estimated (dead reckoning)
+ else
+ gpsQuality = '1'; // 1 means GPS fix
+
+ // Number of satellites in use, 00-12
+ if (svUsedCount > MAX_SATELLITES_IN_USE)
+ svUsedCount = MAX_SATELLITES_IN_USE;
+ if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_DOP)
+ {
+ length = snprintf(pMarker, lengthRemaining, "%c,%02d,%.1f,",
+ gpsQuality, svUsedCount, locationExtended.hdop);
+ }
+ else
+ { // no hdop
+ length = snprintf(pMarker, lengthRemaining, "%c,%02d,,",
+ gpsQuality, svUsedCount);
+ }
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL)
+ {
+ length = snprintf(pMarker, lengthRemaining, "%.1lf,M,",
+ locationExtended.altitudeMeanSeaLevel);
+ }
+ else
+ {
+ length = snprintf(pMarker, lengthRemaining,",,");
+ }
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if ((location.gpsLocation.flags & LOC_GPS_LOCATION_HAS_ALTITUDE) &&
+ (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL))
+ {
+ length = snprintf(pMarker, lengthRemaining, "%.1lf,M,,",
+ location.gpsLocation.altitude - locationExtended.altitudeMeanSeaLevel);
+ }
+ else
+ {
+ length = snprintf(pMarker, lengthRemaining,",,,");
+ }
+
+ length = loc_nmea_put_checksum(sentence, sizeof(sentence));
+ nmeaArraystr.push_back(sentence);
+
+ // clear the cache so they can't be used again
+ sv_cache_info.gps_used_mask = 0;
+ sv_cache_info.glo_used_mask = 0;
+ sv_cache_info.gal_used_mask = 0;
+ sv_cache_info.qzss_used_mask = 0;
+ sv_cache_info.bds_used_mask = 0;
+ }
+ //Send blank NMEA reports for non-final fixes
+ else {
+ strlcpy(sentence, "$GPGSA,A,1,,,,,,,,,,,,,,,", sizeof(sentence));
+ length = loc_nmea_put_checksum(sentence, sizeof(sentence));
+ nmeaArraystr.push_back(sentence);
+
+ strlcpy(sentence, "$GNGSA,A,1,,,,,,,,,,,,,,,", sizeof(sentence));
+ length = loc_nmea_put_checksum(sentence, sizeof(sentence));
+ nmeaArraystr.push_back(sentence);
+
+ strlcpy(sentence, "$PQGSA,A,1,,,,,,,,,,,,,,,", sizeof(sentence));
+ length = loc_nmea_put_checksum(sentence, sizeof(sentence));
+ nmeaArraystr.push_back(sentence);
+
+ strlcpy(sentence, "$GPVTG,,T,,M,,N,,K,N", sizeof(sentence));
+ length = loc_nmea_put_checksum(sentence, sizeof(sentence));
+ nmeaArraystr.push_back(sentence);
+
+ strlcpy(sentence, "$GPRMC,,V,,,,,,,,,,N", sizeof(sentence));
+ length = loc_nmea_put_checksum(sentence, sizeof(sentence));
+ nmeaArraystr.push_back(sentence);
+
+ strlcpy(sentence, "$GPGGA,,,,,,0,,,,,,,,", sizeof(sentence));
+ length = loc_nmea_put_checksum(sentence, sizeof(sentence));
+ nmeaArraystr.push_back(sentence);
+ }
+
+ EXIT_LOG(%d, 0);
+}
+
+
+
+/*===========================================================================
+FUNCTION loc_nmea_generate_sv
+
+DESCRIPTION
+ Generate NMEA sentences generated based on sv report
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ 0
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+void loc_nmea_generate_sv(const GnssSvNotification &svNotify,
+ std::vector<std::string> &nmeaArraystr)
+{
+ ENTRY_LOG();
+
+ char sentence[NMEA_SENTENCE_MAX_LENGTH] = {0};
+ char* pMarker = sentence;
+ int lengthRemaining = sizeof(sentence);
+ int length = 0;
+ int svCount = svNotify.count;
+ int sentenceCount = 0;
+ int sentenceNumber = 1;
+ int svNumber = 1;
+
+ //Count GPS SVs for saparating GPS from GLONASS and throw others
+
+ sv_cache_info.gps_used_mask = 0;
+ sv_cache_info.glo_used_mask = 0;
+ sv_cache_info.gal_used_mask = 0;
+ sv_cache_info.qzss_used_mask = 0;
+ sv_cache_info.bds_used_mask = 0;
+
+ sv_cache_info.gps_count = 0;
+ sv_cache_info.glo_count = 0;
+ sv_cache_info.gal_count = 0;
+ sv_cache_info.qzss_count = 0;
+ sv_cache_info.bds_count = 0;
+ for(svNumber=1; svNumber <= svCount; svNumber++) {
+ if (GNSS_SV_TYPE_GPS == svNotify.gnssSvs[svNumber - 1].type)
+ {
+ // cache the used in fix mask, as it will be needed to send $GPGSA
+ // during the position report
+ if (GNSS_SV_OPTIONS_USED_IN_FIX_BIT ==
+ (svNotify.gnssSvs[svNumber - 1].gnssSvOptionsMask &
+ GNSS_SV_OPTIONS_USED_IN_FIX_BIT))
+ {
+ sv_cache_info.gps_used_mask |= (1 << (svNotify.gnssSvs[svNumber - 1].svId - 1));
+ }
+ sv_cache_info.gps_count++;
+ }
+ else if (GNSS_SV_TYPE_GLONASS == svNotify.gnssSvs[svNumber - 1].type)
+ {
+ // cache the used in fix mask, as it will be needed to send $GNGSA
+ // during the position report
+ if (GNSS_SV_OPTIONS_USED_IN_FIX_BIT ==
+ (svNotify.gnssSvs[svNumber - 1].gnssSvOptionsMask &
+ GNSS_SV_OPTIONS_USED_IN_FIX_BIT))
+ {
+ sv_cache_info.glo_used_mask |= (1 << (svNotify.gnssSvs[svNumber - 1].svId - 1));
+ }
+ sv_cache_info.glo_count++;
+ }
+ else if (GNSS_SV_TYPE_GALILEO == svNotify.gnssSvs[svNumber - 1].type)
+ {
+ // cache the used in fix mask, as it will be needed to send $GAGSA
+ // during the position report
+ if (GNSS_SV_OPTIONS_USED_IN_FIX_BIT ==
+ (svNotify.gnssSvs[svNumber - 1].gnssSvOptionsMask &
+ GNSS_SV_OPTIONS_USED_IN_FIX_BIT))
+ {
+ sv_cache_info.gal_used_mask |= (1 << (svNotify.gnssSvs[svNumber - 1].svId - 1));
+ }
+ sv_cache_info.gal_count++;
+ }
+ else if (GNSS_SV_TYPE_QZSS == svNotify.gnssSvs[svNumber - 1].type)
+ {
+ // cache the used in fix mask, as it will be needed to send $PQGSA
+ // during the position report
+ if (GNSS_SV_OPTIONS_USED_IN_FIX_BIT ==
+ (svNotify.gnssSvs[svNumber - 1].gnssSvOptionsMask &
+ GNSS_SV_OPTIONS_USED_IN_FIX_BIT))
+ {
+ sv_cache_info.qzss_used_mask |= (1 << (svNotify.gnssSvs[svNumber - 1].svId - 1));
+ }
+ sv_cache_info.qzss_count++;
+ }
+ else if (GNSS_SV_TYPE_BEIDOU == svNotify.gnssSvs[svNumber - 1].type)
+ {
+ // cache the used in fix mask, as it will be needed to send $PQGSA
+ // during the position report
+ if (GNSS_SV_OPTIONS_USED_IN_FIX_BIT ==
+ (svNotify.gnssSvs[svNumber - 1].gnssSvOptionsMask &
+ GNSS_SV_OPTIONS_USED_IN_FIX_BIT))
+ {
+ sv_cache_info.bds_used_mask |= (1 << (svNotify.gnssSvs[svNumber - 1].svId - 1));
+ }
+ sv_cache_info.bds_count++;
+ }
+ }
+
+ loc_nmea_sv_meta sv_meta;
+ // ------------------
+ // ------$GPGSV------
+ // ------------------
+
+ loc_nmea_generate_GSV(svNotify, sentence, sizeof(sentence),
+ loc_nmea_sv_meta_init(sv_meta, GNSS_SV_TYPE_GPS, false), nmeaArraystr);
+
+ // ------------------
+ // ------$GLGSV------
+ // ------------------
+
+ loc_nmea_generate_GSV(svNotify, sentence, sizeof(sentence),
+ loc_nmea_sv_meta_init(sv_meta, GNSS_SV_TYPE_GLONASS, false), nmeaArraystr);
+
+ // ------------------
+ // ------$GAGSV------
+ // ------------------
+
+ loc_nmea_generate_GSV(svNotify, sentence, sizeof(sentence),
+ loc_nmea_sv_meta_init(sv_meta, GNSS_SV_TYPE_GALILEO, false), nmeaArraystr);
+
+ // -------------------------
+ // ------$PQGSV (QZSS)------
+ // -------------------------
+
+ loc_nmea_generate_GSV(svNotify, sentence, sizeof(sentence),
+ loc_nmea_sv_meta_init(sv_meta, GNSS_SV_TYPE_QZSS, false), nmeaArraystr);
+
+ // ---------------------------
+ // ------$PQGSV (BEIDOU)------
+ // ---------------------------
+
+ loc_nmea_generate_GSV(svNotify, sentence, sizeof(sentence),
+ loc_nmea_sv_meta_init(sv_meta, GNSS_SV_TYPE_BEIDOU, false), nmeaArraystr);
+
+ EXIT_LOG(%d, 0);
+}
diff --git a/gps/utils/loc_nmea.h b/gps/utils/loc_nmea.h
new file mode 100644
index 0000000..585a9c1
--- /dev/null
+++ b/gps/utils/loc_nmea.h
@@ -0,0 +1,54 @@
+/* Copyright (c) 2012-2013, 2015-2017 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef LOC_ENG_NMEA_H
+#define LOC_ENG_NMEA_H
+
+#include <gps_extended.h>
+#include <vector>
+#include <string>
+#define NMEA_SENTENCE_MAX_LENGTH 200
+
+void loc_nmea_generate_sv(const GnssSvNotification &svNotify,
+ std::vector<std::string> &nmeaArraystr);
+
+void loc_nmea_generate_pos(const UlpLocation &location,
+ const GpsLocationExtended &locationExtended,
+ unsigned char generate_nmea,
+ std::vector<std::string> &nmeaArraystr);
+
+#define DEBUG_NMEA_MINSIZE 6
+#define DEBUG_NMEA_MAXSIZE 4096
+inline bool loc_nmea_is_debug(const char* nmea, int length) {
+ return ((nullptr != nmea) &&
+ (length >= DEBUG_NMEA_MINSIZE) && (length <= DEBUG_NMEA_MAXSIZE) &&
+ (nmea[0] == '$') && (nmea[1] == 'P') && (nmea[2] == 'Q') && (nmea[3] == 'W'));
+}
+
+#endif // LOC_ENG_NMEA_H
diff --git a/gps/utils/loc_target.cpp b/gps/utils/loc_target.cpp
new file mode 100644
index 0000000..cf42932
--- /dev/null
+++ b/gps/utils/loc_target.cpp
@@ -0,0 +1,221 @@
+/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <cutils/properties.h>
+#include "loc_target.h"
+#include "loc_log.h"
+#include <platform_lib_includes.h>
+
+#define APQ8064_ID_1 "109"
+#define APQ8064_ID_2 "153"
+#define MPQ8064_ID_1 "130"
+#define MSM8930_ID_1 "142"
+#define MSM8930_ID_2 "116"
+#define APQ8030_ID_1 "157"
+#define APQ8074_ID_1 "184"
+
+#define LINE_LEN 100
+#define STR_LIQUID "Liquid"
+#define STR_SURF "Surf"
+#define STR_MTP "MTP"
+#define STR_APQ "apq"
+#define STR_SDC "sdc" // alternative string for APQ targets
+#define STR_MSM "msm"
+#define STR_SDM "sdm" // alternative string for MSM targets
+#define STR_APQ_NO_WGR "baseband_apq_nowgr"
+#define STR_AUTO "auto"
+#define IS_STR_END(c) ((c) == '\0' || (c) == '\n' || (c) == '\r')
+#define LENGTH(s) (sizeof(s) - 1)
+#define GPS_CHECK_NO_ERROR 0
+#define GPS_CHECK_NO_GPS_HW 1
+
+static unsigned int gTarget = (unsigned int)-1;
+
+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;
+}
+
+/*The character array passed to this function should have length
+ of atleast PROPERTY_VALUE_MAX*/
+void loc_get_target_baseband(char *baseband, int array_length)
+{
+ if(baseband && (array_length >= PROPERTY_VALUE_MAX)) {
+ property_get("ro.baseband", baseband, "");
+ LOC_LOGD("%s:%d]: Baseband: %s\n", __func__, __LINE__, baseband);
+ }
+ else {
+ LOC_LOGE("%s:%d]: NULL parameter or array length less than PROPERTY_VALUE_MAX\n",
+ __func__, __LINE__);
+ }
+}
+
+/*The character array passed to this function should have length
+ of atleast PROPERTY_VALUE_MAX*/
+void loc_get_platform_name(char *platform_name, int array_length)
+{
+ if(platform_name && (array_length >= PROPERTY_VALUE_MAX)) {
+ property_get("ro.board.platform", platform_name, "");
+ LOC_LOGD("%s:%d]: Target name: %s\n", __func__, __LINE__, platform_name);
+ }
+ else {
+ LOC_LOGE("%s:%d]: Null parameter or array length less than PROPERTY_VALUE_MAX\n",
+ __func__, __LINE__);
+ }
+}
+
+/*The character array passed to this function should have length
+ of atleast PROPERTY_VALUE_MAX*/
+void loc_get_auto_platform_name(char *platform_name, int array_length)
+{
+ if(platform_name && (array_length >= PROPERTY_VALUE_MAX)) {
+ property_get("ro.hardware.type", platform_name, "");
+ LOC_LOGD("%s:%d]: Autoplatform name: %s\n", __func__, __LINE__, platform_name);
+ }
+ else {
+ LOC_LOGE("%s:%d]: Null parameter or array length less than PROPERTY_VALUE_MAX\n",
+ __func__, __LINE__);
+ }
+}
+
+unsigned int loc_get_target(void)
+{
+ if (gTarget != (unsigned int)-1)
+ return gTarget;
+
+ static const char hw_platform[] = "/sys/devices/soc0/hw_platform";
+ static const char id[] = "/sys/devices/soc0/soc_id";
+ static const char hw_platform_dep[] =
+ "/sys/devices/system/soc/soc0/hw_platform";
+ static const char id_dep[] = "/sys/devices/system/soc/soc0/id";
+ static const char mdm[] = "/target"; // mdm target we are using
+
+ char rd_hw_platform[LINE_LEN];
+ char rd_id[LINE_LEN];
+ char rd_mdm[LINE_LEN];
+ char baseband[LINE_LEN];
+ char rd_auto_platform[LINE_LEN];
+
+ loc_get_target_baseband(baseband, sizeof(baseband));
+
+ if (!access(hw_platform, F_OK)) {
+ read_a_line(hw_platform, rd_hw_platform, LINE_LEN);
+ } else {
+ read_a_line(hw_platform_dep, rd_hw_platform, LINE_LEN);
+ }
+ if (!access(id, F_OK)) {
+ read_a_line(id, rd_id, LINE_LEN);
+ } else {
+ read_a_line(id_dep, rd_id, LINE_LEN);
+ }
+
+ /*check automotive platform*/
+ loc_get_auto_platform_name(rd_auto_platform, sizeof(rd_auto_platform));
+ if( !memcmp(rd_auto_platform, STR_AUTO, LENGTH(STR_AUTO)) )
+ {
+ gTarget = TARGET_AUTO;
+ goto detected;
+ }
+
+ if( !memcmp(baseband, STR_APQ_NO_WGR, LENGTH(STR_APQ_NO_WGR)) ){
+
+ gTarget = TARGET_NO_GNSS;
+ goto detected;
+ }
+
+ if( !memcmp(baseband, STR_APQ, LENGTH(STR_APQ)) ||
+ !memcmp(baseband, STR_SDC, LENGTH(STR_SDC)) ) {
+
+ if( !memcmp(rd_id, MPQ8064_ID_1, LENGTH(MPQ8064_ID_1))
+ && IS_STR_END(rd_id[LENGTH(MPQ8064_ID_1)]) )
+ gTarget = TARGET_NO_GNSS;
+ else
+ gTarget = TARGET_APQ_SA;
+ } else if (((!memcmp(rd_hw_platform, STR_LIQUID, LENGTH(STR_LIQUID))
+ && IS_STR_END(rd_hw_platform[LENGTH(STR_LIQUID)])) ||
+ (!memcmp(rd_hw_platform, STR_SURF, LENGTH(STR_SURF))
+ && IS_STR_END(rd_hw_platform[LENGTH(STR_SURF)])) ||
+ (!memcmp(rd_hw_platform, STR_MTP, LENGTH(STR_MTP))
+ && IS_STR_END(rd_hw_platform[LENGTH(STR_MTP)]))) &&
+ !read_a_line( mdm, rd_mdm, LINE_LEN)) {
+ gTarget = TARGET_MDM;
+ } else if( (!memcmp(rd_id, MSM8930_ID_1, LENGTH(MSM8930_ID_1))
+ && IS_STR_END(rd_id[LENGTH(MSM8930_ID_1)])) ||
+ (!memcmp(rd_id, MSM8930_ID_2, LENGTH(MSM8930_ID_2))
+ && IS_STR_END(rd_id[LENGTH(MSM8930_ID_2)])) ) {
+ gTarget = TARGET_MSM_NO_SSC;
+ } else if ( !memcmp(baseband, STR_MSM, LENGTH(STR_MSM)) ||
+ !memcmp(baseband, STR_SDM, LENGTH(STR_SDM)) ) {
+ gTarget = TARGET_DEFAULT;
+ } else {
+ gTarget = TARGET_UNKNOWN;
+ }
+
+detected:
+ LOC_LOGW("HAL: %s returned %d", __FUNCTION__, gTarget);
+ return gTarget;
+}
+
+/*Reads the property ro.lean to identify if this is a lean target
+ Returns:
+ 0 if not a lean and mean target
+ 1 if this is a lean and mean target
+*/
+int loc_identify_lean_target()
+{
+ int ret = 0;
+ char lean_target[PROPERTY_VALUE_MAX];
+ property_get("ro.lean", lean_target, "");
+ LOC_LOGD("%s:%d]: lean target: %s\n", __func__, __LINE__, lean_target);
+ return !(strncmp(lean_target, "true", PROPERTY_VALUE_MAX));
+}
diff --git a/gps/utils/loc_target.h b/gps/utils/loc_target.h
new file mode 100644
index 0000000..47a67d9
--- /dev/null
+++ b/gps/utils/loc_target.h
@@ -0,0 +1,84 @@
+/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef LOC_TARGET_H
+#define LOC_TARGET_H
+#define TARGET_SET(gnss,ssc) ( (gnss<<1)|ssc )
+#define TARGET_DEFAULT TARGET_SET(GNSS_MSM, HAS_SSC)
+#define TARGET_MDM TARGET_SET(GNSS_MDM, HAS_SSC)
+#define TARGET_APQ_SA TARGET_SET(GNSS_GSS, NO_SSC)
+#define TARGET_NO_GNSS TARGET_SET(GNSS_NONE, NO_SSC)
+#define TARGET_MSM_NO_SSC TARGET_SET(GNSS_MSM, NO_SSC)
+#define TARGET_AUTO TARGET_SET(GNSS_AUTO, NO_SSC)
+#define TARGET_UNKNOWN TARGET_SET(GNSS_UNKNOWN, NO_SSC)
+#define getTargetGnssType(target) (target>>1)
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+unsigned int loc_get_target(void);
+
+/*The character array passed to this function should have length
+ of atleast PROPERTY_VALUE_MAX*/
+void loc_get_target_baseband(char *baseband, int array_length);
+/*The character array passed to this function should have length
+ of atleast PROPERTY_VALUE_MAX*/
+void loc_get_platform_name(char *platform_name, int array_length);
+/*The character array passed to this function should have length
+ of atleast PROPERTY_VALUE_MAX*/
+void loc_get_auto_platform_name(char *platform_name, int array_length);
+
+/*Reads the property ro.lean to identify if this is a lean target
+ Returns:
+ 0 if not a lean and mean target
+ 1 if this is a lean and mean target*/
+int loc_identify_lean_target();
+
+/* Please remember to update 'target_name' in loc_log.cpp,
+ if do any changes to this enum. */
+typedef enum {
+ GNSS_NONE = 0,
+ GNSS_MSM,
+ GNSS_GSS,
+ GNSS_MDM,
+ GNSS_AUTO,
+ GNSS_UNKNOWN
+}GNSS_TARGET;
+
+typedef enum {
+ NO_SSC = 0,
+ HAS_SSC
+}SSC_TYPE;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*LOC_TARGET_H*/
diff --git a/gps/utils/loc_timer.h b/gps/utils/loc_timer.h
new file mode 100644
index 0000000..25fd179
--- /dev/null
+++ b/gps/utils/loc_timer.h
@@ -0,0 +1,73 @@
+/* Copyright (c) 2013,2015 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation, nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __LOC_DELAY_H__
+#define __LOC_DELAY_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#include <stddef.h>
+#include <platform_lib_includes.h>
+/*
+ user_data: client context pointer, passthrough. Originally received
+ from calling client when loc_timer_start() is called.
+ result: 0 if timer successfully timed out; else timer failed.
+*/
+typedef void (*loc_timer_callback)(void *user_data, int32_t result);
+
+
+/*
+ delay_msec: timeout value for the timer.
+ cb_func: callback function pointer, implemented by client.
+ Can not be NULL.
+ user_data: client context pointer, passthrough. Will be
+ returned when loc_timer_callback() is called.
+ wakeOnExpire: true if to wake up CPU (if sleeping) upon timer
+ expiration and notify the client.
+ false if to wait until next time CPU wakes up (if
+ sleeping) and then notify the client.
+ Returns the handle, which can be used to stop the timer
+ NULL, if timer start fails (e.g. if cb_func is NULL).
+*/
+void* loc_timer_start(uint64_t delay_msec,
+ loc_timer_callback cb_func,
+ void *user_data,
+ bool wake_on_expire=false);
+
+/*
+ handle becomes invalid upon the return of the callback
+*/
+void loc_timer_stop(void*& handle);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif //__LOC_DELAY_H__
diff --git a/gps/utils/log_util.h b/gps/utils/log_util.h
new file mode 100644
index 0000000..7eb338a
--- /dev/null
+++ b/gps/utils/log_util.h
@@ -0,0 +1,173 @@
+/* Copyright (c) 2011-2014 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __LOG_UTIL_H__
+#define __LOG_UTIL_H__
+
+#ifndef USE_GLIB
+#include <utils/Log.h>
+#endif /* USE_GLIB */
+
+#ifdef USE_GLIB
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#ifndef LOG_TAG
+#define LOG_TAG "GPS_UTILS"
+
+#endif // LOG_TAG
+
+#endif /* USE_GLIB */
+
+#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[];
+extern const char EXIT_ERROR_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);
+
+#ifndef DEBUG_DMN_LOC_API
+
+/* LOGGING MACROS */
+/*loc_logger.DEBUG_LEVEL is initialized to 0xff in loc_cfg.cpp
+ if that value remains unchanged, it means gps.conf did not
+ provide a value and we default to the initial value to use
+ Android's logging levels*/
+#define IF_LOC_LOGE if((loc_logger.DEBUG_LEVEL >= 1) && (loc_logger.DEBUG_LEVEL <= 5))
+#define IF_LOC_LOGW if((loc_logger.DEBUG_LEVEL >= 2) && (loc_logger.DEBUG_LEVEL <= 5))
+#define IF_LOC_LOGI if((loc_logger.DEBUG_LEVEL >= 3) && (loc_logger.DEBUG_LEVEL <= 5))
+#define IF_LOC_LOGD if((loc_logger.DEBUG_LEVEL >= 4) && (loc_logger.DEBUG_LEVEL <= 5))
+#define IF_LOC_LOGV if((loc_logger.DEBUG_LEVEL >= 5) && (loc_logger.DEBUG_LEVEL <= 5))
+
+#define LOC_LOGE(...) IF_LOC_LOGE { ALOGE(__VA_ARGS__); }
+#define LOC_LOGW(...) IF_LOC_LOGW { ALOGW(__VA_ARGS__); }
+#define LOC_LOGI(...) IF_LOC_LOGI { ALOGI(__VA_ARGS__); }
+#define LOC_LOGD(...) IF_LOC_LOGD { ALOGD(__VA_ARGS__); }
+#define LOC_LOGV(...) IF_LOC_LOGV { ALOGV(__VA_ARGS__); }
+
+#else /* DEBUG_DMN_LOC_API */
+
+#define LOC_LOGE(...) ALOGE(__VA_ARGS__)
+#define LOC_LOGW(...) ALOGW(__VA_ARGS__)
+#define LOC_LOGI(...) ALOGI(__VA_ARGS__)
+#define LOC_LOGD(...) ALOGD(__VA_ARGS__)
+#define LOC_LOGV(...) ALOGV(__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 LOC_LOG_HEAD(fmt) "%s:%d] " fmt
+#define LOC_LOGv(fmt,...) LOC_LOGV(LOC_LOG_HEAD(fmt), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+#define LOC_LOGw(fmt,...) LOC_LOGW(LOC_LOG_HEAD(fmt), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+#define LOC_LOGd(fmt,...) LOC_LOGD(LOC_LOG_HEAD(fmt), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+#define LOC_LOGe(fmt,...) LOC_LOGE(LOC_LOG_HEAD(fmt), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#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 LOG_E(ID, WHAT, SPEC, VAL) LOG_(LOC_LOGE, ID, WHAT, SPEC, VAL)
+
+#define ENTRY_LOG() LOG_V(ENTRY_TAG, __FUNCTION__, %s, "")
+#define EXIT_LOG(SPEC, VAL) LOG_V(EXIT_TAG, __FUNCTION__, SPEC, VAL)
+#define EXIT_LOG_WITH_ERROR(SPEC, VAL) \
+ if (VAL != 0) { \
+ LOG_E(EXIT_ERROR_TAG, __FUNCTION__, SPEC, VAL); \
+ } else { \
+ LOG_V(EXIT_TAG, __FUNCTION__, SPEC, VAL); \
+ }
+
+
+// Used for logging callflow from Android Framework
+#define ENTRY_LOG_CALLFLOW() LOG_I(FROM_AFW, __FUNCTION__, %s, "")
+// Used for logging callflow to Modem
+#define EXIT_LOG_CALLFLOW(SPEC, VAL) LOG_I(TO_MODEM, __FUNCTION__, SPEC, VAL)
+// Used for logging callflow from Modem(TO_MODEM, __FUNCTION__, %s, "")
+#define MODEM_LOG_CALLFLOW(SPEC, VAL) LOG_I(FROM_MODEM, __FUNCTION__, SPEC, VAL)
+// Used for logging callflow to Android Framework
+#define CALLBACK_LOG_CALLFLOW(CB, SPEC, VAL) LOG_I(TO_AFW, CB, SPEC, VAL)
+
+#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..e8b4ffe
--- /dev/null
+++ b/gps/utils/msg_q.c
@@ -0,0 +1,333 @@
+/* Copyright (c) 2011-2012, 2014, 2017 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation, nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "msg_q.h"
+
+#define LOG_TAG "LocSvc_utils_q"
+#include <platform_lib_includes.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_init2
+
+ ===========================================================================*/
+const void* msg_q_init2()
+{
+ void* q = NULL;
+ if (eMSG_Q_SUCCESS != msg_q_init(&q)) {
+ q = NULL;
+ }
+ return q;
+}
+
+/*===========================================================================
+
+ 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_LOGV("%s: Sending message with handle = %p\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_LOGV("%s: Finished Sending message with handle = %p\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;
+
+ 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_LOGV("%s: Received message %p 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..453b8ce
--- /dev/null
+++ b/gps/utils/msg_q.h
@@ -0,0 +1,207 @@
+/* Copyright (c) 2011, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __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: pointer to an opaque Q handle to be returned; NULL if fails
+
+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_init2
+
+DESCRIPTION
+ Initializes internal structures for message queue.
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ opaque handle to the Q created; NULL if create fails
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+const void* msg_q_init2();
+
+/*===========================================================================
+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/gps/utils/platform_lib_abstractions/Android.mk b/gps/utils/platform_lib_abstractions/Android.mk
new file mode 100644
index 0000000..b923a4c
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/Android.mk
@@ -0,0 +1,5 @@
+ifneq ($(BUILD_TINY_ANDROID),true)
+
+include $(call all-subdir-makefiles)
+
+endif
diff --git a/gps/utils/platform_lib_abstractions/elapsed_millis_since_boot.cpp b/gps/utils/platform_lib_abstractions/elapsed_millis_since_boot.cpp
new file mode 100644
index 0000000..6c183a8
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/elapsed_millis_since_boot.cpp
@@ -0,0 +1,46 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <sys/time.h>
+#include "platform_lib_time.h"
+
+int64_t systemTime(int /*clock*/)
+{
+ struct timeval t;
+ t.tv_sec = t.tv_usec = 0;
+ gettimeofday(&t, NULL);
+ return t.tv_sec*1000000LL + t.tv_usec;
+}
+
+
+int64_t elapsedMillisSinceBoot()
+{
+ int64_t t_us = systemTime(0);
+ return (int64_t) t_us / 1000LL;
+}
diff --git a/gps/utils/platform_lib_abstractions/loc_pla/Android.mk b/gps/utils/platform_lib_abstractions/loc_pla/Android.mk
new file mode 100644
index 0000000..b923a4c
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_pla/Android.mk
@@ -0,0 +1,5 @@
+ifneq ($(BUILD_TINY_ANDROID),true)
+
+include $(call all-subdir-makefiles)
+
+endif
diff --git a/gps/utils/platform_lib_abstractions/loc_pla/Makefile.am b/gps/utils/platform_lib_abstractions/loc_pla/Makefile.am
new file mode 100644
index 0000000..8996763
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_pla/Makefile.am
@@ -0,0 +1,10 @@
+# Makefile.am for gps loc-pla
+#
+
+ACLOCAL_AMFLAGS = -I m4
+
+SUBDIRS = src
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = loc-pla.pc
+EXTRA_DIST = $(pkgconfig_DATA)
diff --git a/gps/utils/platform_lib_abstractions/loc_pla/configure.ac b/gps/utils/platform_lib_abstractions/loc_pla/configure.ac
new file mode 100644
index 0000000..a8b892b
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_pla/configure.ac
@@ -0,0 +1,61 @@
+# configure.ac -- Autoconf script for gps loc-pla
+#
+# Process this file with autoconf to produce a configure script
+
+# Requires autoconf tool later than 2.61
+AC_PREREQ(2.61)
+# Initialize the gps loc-pla package version 1.0.0
+AC_INIT([loc-pla],1.0.0)
+# Does not strictly follow GNU Coding standards
+AM_INIT_AUTOMAKE([foreign])
+# Disables auto rebuilding of configure, Makefile.ins
+AM_MAINTAINER_MODE
+# Verifies the --srcdir is correct by checking for the path
+AC_CONFIG_SRCDIR([include/platform_lib_includes.h])
+# defines some macros variable to be included by source
+AC_CONFIG_HEADERS([config.h])
+AC_CONFIG_MACRO_DIR([m4])
+
+# Checks for programs.
+AC_PROG_LIBTOOL
+AC_PROG_CXX
+AC_PROG_CC
+AM_PROG_CC_C_O
+AC_PROG_AWK
+AC_PROG_CPP
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+PKG_PROG_PKG_CONFIG
+
+# Checks for libraries.
+PKG_CHECK_MODULES([LOCSTUB], [loc-stub])
+AC_SUBST([LOCSTUB_CFLAGS])
+AC_SUBST([LOCSTUB_LIBS])
+
+AC_ARG_WITH([glib],
+ AC_HELP_STRING([--with-glib],
+ [enable glib, building HLOS systems which use glib]))
+
+if (test "x${with_glib}" = "xyes"); then
+ AC_DEFINE(ENABLE_USEGLIB, 1, [Define if HLOS systems uses glib])
+ PKG_CHECK_MODULES(GTHREAD, gthread-2.0 >= 2.16, dummy=yes,
+ AC_MSG_ERROR(GThread >= 2.16 is required))
+ PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.16, dummy=yes,
+ AC_MSG_ERROR(GLib >= 2.16 is required))
+ GLIB_CFLAGS="$GLIB_CFLAGS $GTHREAD_CFLAGS"
+ GLIB_LIBS="$GLIB_LIBS $GTHREAD_LIBS"
+
+ AC_SUBST(GLIB_CFLAGS)
+ AC_SUBST(GLIB_LIBS)
+fi
+
+AM_CONDITIONAL(USE_GLIB, test "x${with_glib}" = "xyes")
+
+AC_CONFIG_FILES([ \
+ Makefile \
+ src/Makefile \
+ loc-pla.pc \
+ ])
+
+AC_OUTPUT
diff --git a/gps/utils/platform_lib_abstractions/loc_pla/include/platform_lib_gettid.h b/gps/utils/platform_lib_abstractions/loc_pla/include/platform_lib_gettid.h
new file mode 100644
index 0000000..340c3c5
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_pla/include/platform_lib_gettid.h
@@ -0,0 +1,45 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PLATFORM_LIB_GETTID_H__
+#define __PLATFORM_LIB_GETTID_H__
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef USE_GLIB
+const char* getprogname();
+#endif /* USE_GLIB */
+
+pid_t platform_lib_abstraction_gettid();
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __PLATFORM_LIB_GETTID_H__ */
diff --git a/gps/utils/platform_lib_abstractions/loc_pla/include/platform_lib_includes.h b/gps/utils/platform_lib_abstractions/loc_pla/include/platform_lib_includes.h
new file mode 100644
index 0000000..ebb7119
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_pla/include/platform_lib_includes.h
@@ -0,0 +1,39 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PLATFORM_LIB_INCLUDES_H__
+#define __PLATFORM_LIB_INCLUDES_H__
+
+#include "platform_lib_gettid.h"
+#include "platform_lib_log_util.h"
+#include "platform_lib_macros.h"
+#include "platform_lib_property_service.h"
+#include "platform_lib_sched_policy.h"
+#include "platform_lib_time.h"
+
+#endif /* __PLATFORM_LIB_INCLUDES_H__ */
diff --git a/gps/utils/platform_lib_abstractions/loc_pla/include/platform_lib_log_util.h b/gps/utils/platform_lib_abstractions/loc_pla/include/platform_lib_log_util.h
new file mode 100644
index 0000000..26d3c29
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_pla/include/platform_lib_log_util.h
@@ -0,0 +1,174 @@
+/* Copyright (c) 2011-2014 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PLATFORM_LIB_LOG_UTIL_H__
+#define __PLATFORM_LIB_LOG_UTIL_H__
+
+#include "platform_lib_macros.h"
+
+#ifndef USE_GLIB
+#include <log_util.h>
+#else
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+
+#ifndef LOG_TAG
+#define LOG_TAG "GPS_UTILS"
+#endif /* LOG_TAG */
+
+#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[];
+extern const char EXIT_ERROR_TAG[];
+
+/*=============================================================================
+ *
+ * MODULE EXPORTED FUNCTIONS
+ *
+ *============================================================================*/
+void loc_logger_init(unsigned long debug, unsigned long timestamp);
+char* get_timestamp(char* str, unsigned long buf_size);
+
+#ifndef DEBUG_DMN_LOC_API
+
+/* LOGGING MACROS */
+/*loc_logger.DEBUG_LEVEL is initialized to 0xff in loc_cfg.cpp
+ if that value remains unchanged, it means gps.conf did not
+ provide a value and we default to the initial value to use
+ Android's logging levels*/
+#define IF_LOC_LOGE if((loc_logger.DEBUG_LEVEL >= 1) && (loc_logger.DEBUG_LEVEL <= 5))
+#define IF_LOC_LOGW if((loc_logger.DEBUG_LEVEL >= 2) && (loc_logger.DEBUG_LEVEL <= 5))
+#define IF_LOC_LOGI if((loc_logger.DEBUG_LEVEL >= 3) && (loc_logger.DEBUG_LEVEL <= 5))
+#define IF_LOC_LOGD if((loc_logger.DEBUG_LEVEL >= 4) && (loc_logger.DEBUG_LEVEL <= 5))
+#define IF_LOC_LOGV if((loc_logger.DEBUG_LEVEL >= 5) && (loc_logger.DEBUG_LEVEL <= 5))
+
+#define LOC_LOGE(...) IF_LOC_LOGE { ALOGE(__VA_ARGS__); }
+#define LOC_LOGW(...) IF_LOC_LOGW { ALOGW(__VA_ARGS__); }
+#define LOC_LOGI(...) IF_LOC_LOGI { ALOGI(__VA_ARGS__); }
+#define LOC_LOGD(...) IF_LOC_LOGD { ALOGD(__VA_ARGS__); }
+#define LOC_LOGV(...) IF_LOC_LOGV { ALOGV(__VA_ARGS__); }
+
+#else /* DEBUG_DMN_LOC_API */
+
+#define LOC_LOGE(...) ALOGE(__VA_ARGS__)
+#define LOC_LOGW(...) ALOGW(__VA_ARGS__)
+#define LOC_LOGI(...) ALOGI(__VA_ARGS__)
+#define LOC_LOGD(...) ALOGD(__VA_ARGS__)
+#define LOC_LOGV(...) ALOGV(__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 LOC_LOG_HEAD(fmt) "%s:%d] " fmt
+#define LOC_LOGv(fmt,...) LOC_LOGV(LOC_LOG_HEAD(fmt), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+#define LOC_LOGw(fmt,...) LOC_LOGW(LOC_LOG_HEAD(fmt), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+#define LOC_LOGd(fmt,...) LOC_LOGD(LOC_LOG_HEAD(fmt), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+#define LOC_LOGe(fmt,...) LOC_LOGE(LOC_LOG_HEAD(fmt), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#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 LOG_E(ID, WHAT, SPEC, VAL) LOG_(LOC_LOGE, ID, WHAT, SPEC, VAL)
+
+#define ENTRY_LOG() LOG_V(ENTRY_TAG, __FUNCTION__, %s, "")
+#define EXIT_LOG(SPEC, VAL) LOG_V(EXIT_TAG, __FUNCTION__, SPEC, VAL)
+#define EXIT_LOG_WITH_ERROR(SPEC, VAL) \
+ if (VAL != 0) { \
+ LOG_E(EXIT_ERROR_TAG, __FUNCTION__, SPEC, VAL); \
+ } else { \
+ LOG_V(EXIT_TAG, __FUNCTION__, SPEC, VAL); \
+ }
+
+
+// Used for logging callflow from Android Framework
+#define ENTRY_LOG_CALLFLOW() LOG_I(FROM_AFW, __FUNCTION__, %s, "")
+// Used for logging callflow to Modem
+#define EXIT_LOG_CALLFLOW(SPEC, VAL) LOG_I(TO_MODEM, __FUNCTION__, SPEC, VAL)
+// Used for logging callflow from Modem(TO_MODEM, __FUNCTION__, %s, "")
+#define MODEM_LOG_CALLFLOW(SPEC, VAL) LOG_I(FROM_MODEM, __FUNCTION__, SPEC, VAL)
+// Used for logging callflow to Android Framework
+#define CALLBACK_LOG_CALLFLOW(CB, SPEC, VAL) LOG_I(TO_AFW, CB, SPEC, VAL)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* USE_GLIB */
+
+#endif /* __PLATFORM_LIB_LOG_UTIL_H__ */
diff --git a/gps/utils/platform_lib_abstractions/loc_pla/include/platform_lib_macros.h b/gps/utils/platform_lib_abstractions/loc_pla/include/platform_lib_macros.h
new file mode 100644
index 0000000..d0795eb
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_pla/include/platform_lib_macros.h
@@ -0,0 +1,85 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PLATFORM_LIB_MACROS_H__
+#define __PLATFORM_LIB_MACROS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef USE_GLIB
+#include <sys/time.h>
+#include <string.h>
+#include <stdlib.h>
+#ifndef OFF_TARGET
+#include <glib.h>
+#define strlcat g_strlcat
+#define strlcpy g_strlcpy
+#else
+#define strlcat strncat
+#define strlcpy strncpy
+#endif
+
+#define TS_PRINTF(format, x...) \
+{ \
+ 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; \
+ fprintf(stdout,"%02d:%02d:%02d.%06ld]" format "\n", hh, mm, ss, tv.tv_usec,##x); \
+}
+
+#define ALOGE(format, x...) TS_PRINTF("E/%s (%d): " format , LOG_TAG, getpid(), ##x)
+#define ALOGW(format, x...) TS_PRINTF("W/%s (%d): " format , LOG_TAG, getpid(), ##x)
+#define ALOGI(format, x...) TS_PRINTF("I/%s (%d): " format , LOG_TAG, getpid(), ##x)
+#define ALOGD(format, x...) TS_PRINTF("D/%s (%d): " format , LOG_TAG, getpid(), ##x)
+#define ALOGV(format, x...) TS_PRINTF("V/%s (%d): " format , LOG_TAG, getpid(), ##x)
+
+#endif /* USE_GLIB */
+
+
+// Below are the location conf file paths
+extern const char LOC_PATH_GPS_CONF[];
+extern const char LOC_PATH_IZAT_CONF[];
+extern const char LOC_PATH_FLP_CONF[];
+extern const char LOC_PATH_LOWI_CONF[];
+extern const char LOC_PATH_SAP_CONF[];
+extern const char LOC_PATH_APDR_CONF[];
+extern const char LOC_PATH_XTWIFI_CONF[];
+extern const char LOC_PATH_QUIPC_CONF[];
+
+
+#ifdef __cplusplus
+}
+#endif /*__cplusplus */
+
+#endif /* __PLATFORM_LIB_MACROS_H__ */
diff --git a/gps/utils/platform_lib_abstractions/loc_pla/include/platform_lib_property_service.h b/gps/utils/platform_lib_abstractions/loc_pla/include/platform_lib_property_service.h
new file mode 100644
index 0000000..ed2041f
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_pla/include/platform_lib_property_service.h
@@ -0,0 +1,44 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PLATFORM_LIB_PROPERTY_SERVICE_H__
+#define __PLATFORM_LIB_PROPERTY_SERVICE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifndef PROPERTY_VALUE_MAX
+#define PROPERTY_VALUE_MAX 92
+#endif
+int platform_lib_abstraction_property_get(const char *key, char *value, const char *default_value);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __PLATFORM_LIB_PROPERTY_SERVICE_H__ */
diff --git a/gps/utils/platform_lib_abstractions/loc_pla/include/platform_lib_sched_policy.h b/gps/utils/platform_lib_abstractions/loc_pla/include/platform_lib_sched_policy.h
new file mode 100644
index 0000000..d10f151
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_pla/include/platform_lib_sched_policy.h
@@ -0,0 +1,46 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PLATFORM_LIB_SCHED_POLICY_H__
+#define __PLATFORM_LIB_SCHED_POLICY_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+typedef enum {
+ PLA_SP_BACKGROUND = 0,
+ PLA_SP_FOREGROUND = 1,
+} PLASchedPolicy;
+
+int platform_lib_abstraction_set_sched_policy(int tid, PLASchedPolicy policy);
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __PLATFORM_LIB_SCHED_POLICY_H__ */
+
diff --git a/gps/utils/platform_lib_abstractions/loc_pla/include/platform_lib_time.h b/gps/utils/platform_lib_abstractions/loc_pla/include/platform_lib_time.h
new file mode 100644
index 0000000..ae25ae6
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_pla/include/platform_lib_time.h
@@ -0,0 +1,36 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PLATFORM_LIB_TIME_H__
+#define __PLATFORM_LIB_TIME_H__
+
+#include <stdint.h>
+int64_t platform_lib_abstraction_elapsed_millis_since_boot();
+int64_t platform_lib_abstraction_elapsed_micros_since_boot();
+
+#endif /* __PLATFORM_LIB_TIME_H__ */
diff --git a/gps/utils/platform_lib_abstractions/loc_pla/loc-pla.pc.in b/gps/utils/platform_lib_abstractions/loc_pla/loc-pla.pc.in
new file mode 100644
index 0000000..1aad2f4
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_pla/loc-pla.pc.in
@@ -0,0 +1,10 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: loc-pla
+Description: QTI GPS Location Platform Library Abstractions
+Version: @VERSION@
+Libs: -L${libdir} -lloc_pla
+Cflags: -I${includedir}/loc-pla
diff --git a/gps/utils/platform_lib_abstractions/loc_pla/src/Android.mk b/gps/utils/platform_lib_abstractions/loc_pla/src/Android.mk
new file mode 100644
index 0000000..ab13717
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_pla/src/Android.mk
@@ -0,0 +1,68 @@
+GNSS_CFLAGS := \
+ -Werror \
+ -Wno-error=unused-parameter \
+ -Wno-error=format \
+ -Wno-error=macro-redefined \
+ -Wno-error=reorder \
+ -Wno-error=missing-braces \
+ -Wno-error=self-assign \
+ -Wno-error=enum-conversion \
+ -Wno-error=logical-op-parentheses \
+ -Wno-error=null-arithmetic \
+ -Wno-error=null-conversion \
+ -Wno-error=parentheses-equality \
+ -Wno-error=undefined-bool-conversion \
+ -Wno-error=tautological-compare \
+ -Wno-error=switch \
+ -Wno-error=date-time
+
+ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)
+ifneq ($(BUILD_TINY_ANDROID),true)
+#Compile this library only for builds with the latest modem image
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+## Libs
+LOCAL_SHARED_LIBRARIES := \
+ libutils \
+ libcutils \
+ liblog \
+ libloc_stub
+
+LOCAL_SRC_FILES += \
+ platform_lib_gettid.cpp \
+ platform_lib_log_util.cpp \
+ platform_lib_property_service.cpp \
+ platform_lib_sched_policy.cpp \
+ platform_lib_time.cpp
+
+LOCAL_CFLAGS += \
+ -fno-short-enums \
+ -D_ANDROID_ \
+ -std=c++11
+
+## Includes
+LOCAL_C_INCLUDES:= \
+ $(LOCAL_PATH)/../include
+LOCAL_HEADER_LIBRARIES := \
+ libgps.utils_headers \
+ libloc_stub_headers
+
+LOCAL_MODULE := libloc_pla
+LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib
+LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_CFLAGS += $(GNSS_CFLAGS)
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libloc_pla_headers
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/../include
+include $(BUILD_HEADER_LIBRARY)
+
+endif # not BUILD_TINY_ANDROID
+endif # BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE
diff --git a/gps/utils/platform_lib_abstractions/loc_pla/src/Makefile.am b/gps/utils/platform_lib_abstractions/loc_pla/src/Makefile.am
new file mode 100644
index 0000000..30c4b4c
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_pla/src/Makefile.am
@@ -0,0 +1,39 @@
+AM_CFLAGS = \
+ $(LOCSTUB_CFLAGS) \
+ -I../include \
+ -D__func__=__PRETTY_FUNCTION__ \
+ -fno-short-enums
+
+h_sources = \
+ ../include/platform_lib_gettid.h \
+ ../include/platform_lib_includes.h \
+ ../include/platform_lib_log_util.h \
+ ../include/platform_lib_macros.h \
+ ../include/platform_lib_property_service.h \
+ ../include/platform_lib_sched_policy.h \
+ ../include/platform_lib_time.h
+
+library_includedir = $(pkgincludedir)
+library_include_HEADERS = $(h_sources)
+
+libloc_pla_la_SOURCES = \
+ platform_lib_gettid.cpp \
+ platform_lib_log_util.cpp \
+ platform_lib_property_service.cpp \
+ platform_lib_sched_policy.cpp \
+ platform_lib_time.cpp
+
+if USE_GLIB
+libloc_pla_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@
+libloc_pla_la_LDFLAGS = -lstdc++ -Wl,-z,defs -lpthread @GLIB_LIBS@ -shared -version-info 1:0:0
+libloc_pla_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@
+else
+libloc_pla_la_CFLAGS = $(AM_CFLAGS)
+libloc_pla_la_LDFLAGS = -Wl,-z,defs -lpthread -shared -version-info 1:0:0
+libloc_pla_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS)
+endif
+
+libloc_pla_la_LIBADD = -lstdc++ -ldl -llog $(LOCSTUB_LIBS)
+
+#Create and Install libraries
+lib_LTLIBRARIES = libloc_pla.la
diff --git a/gps/utils/platform_lib_abstractions/loc_pla/src/platform_lib_gettid.cpp b/gps/utils/platform_lib_abstractions/loc_pla/src/platform_lib_gettid.cpp
new file mode 100644
index 0000000..1b7aa32
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_pla/src/platform_lib_gettid.cpp
@@ -0,0 +1,46 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "platform_lib_gettid.h"
+
+#ifdef USE_GLIB
+#include <loc_stub_gettid.h>
+
+#include <errno.h>
+const char* getprogname() {
+ return program_invocation_short_name;
+}
+
+#else
+#include <unistd.h>
+#endif /* USE_GLIB */
+
+pid_t platform_lib_abstraction_gettid()
+{
+ return gettid();
+}
diff --git a/gps/utils/platform_lib_abstractions/loc_pla/src/platform_lib_log_util.cpp b/gps/utils/platform_lib_abstractions/loc_pla/src/platform_lib_log_util.cpp
new file mode 100644
index 0000000..3cb51a3
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_pla/src/platform_lib_log_util.cpp
@@ -0,0 +1,78 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "platform_lib_log_util.h"
+#include "platform_lib_macros.h"
+
+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;
+}
+
+// Below are the location conf file paths
+#ifdef __ANDROID__
+
+#define LOC_PATH_GPS_CONF_STR "/vendor/etc/gps.conf"
+#define LOC_PATH_IZAT_CONF_STR "/vendor/etc/izat.conf"
+#define LOC_PATH_FLP_CONF_STR "/vendor/etc/flp.conf"
+#define LOC_PATH_LOWI_CONF_STR "/vendor/etc/lowi.conf"
+#define LOC_PATH_SAP_CONF_STR "/vendor/etc/sap.conf"
+#define LOC_PATH_APDR_CONF_STR "/vendor/etc/apdr.conf"
+#define LOC_PATH_XTWIFI_CONF_STR "/vendor/etc/xtwifi.conf"
+#define LOC_PATH_QUIPC_CONF_STR "/vendor/etc/quipc.conf"
+
+#else
+
+#define LOC_PATH_GPS_CONF_STR "/etc/gps.conf"
+#define LOC_PATH_IZAT_CONF_STR "/etc/izat.conf"
+#define LOC_PATH_FLP_CONF_STR "/etc/flp.conf"
+#define LOC_PATH_LOWI_CONF_STR "/etc/lowi.conf"
+#define LOC_PATH_SAP_CONF_STR "/etc/sap.conf"
+#define LOC_PATH_APDR_CONF_STR "/etc/apdr.conf"
+#define LOC_PATH_XTWIFI_CONF_STR "/etc/xtwifi.conf"
+#define LOC_PATH_QUIPC_CONF_STR "/etc/quipc.conf"
+
+#endif // __ANDROID__
+
+// Reference below arrays wherever needed to avoid duplicating
+// same conf path string over and again in location code.
+const char LOC_PATH_GPS_CONF[] = LOC_PATH_GPS_CONF_STR;
+const char LOC_PATH_IZAT_CONF[] = LOC_PATH_IZAT_CONF_STR;
+const char LOC_PATH_FLP_CONF[] = LOC_PATH_FLP_CONF_STR;
+const char LOC_PATH_LOWI_CONF[] = LOC_PATH_LOWI_CONF_STR;
+const char LOC_PATH_SAP_CONF[] = LOC_PATH_SAP_CONF_STR;
+const char LOC_PATH_APDR_CONF[] = LOC_PATH_APDR_CONF_STR;
+const char LOC_PATH_XTWIFI_CONF[] = LOC_PATH_XTWIFI_CONF_STR;
+const char LOC_PATH_QUIPC_CONF[] = LOC_PATH_QUIPC_CONF_STR;
diff --git a/gps/utils/platform_lib_abstractions/loc_pla/src/platform_lib_property_service.cpp b/gps/utils/platform_lib_abstractions/loc_pla/src/platform_lib_property_service.cpp
new file mode 100644
index 0000000..dccdebc
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_pla/src/platform_lib_property_service.cpp
@@ -0,0 +1,39 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifdef USE_GLIB
+#include <loc_stub_property_service.h>
+#else
+#include <cutils/properties.h>
+#endif /* USE_GLIB */
+
+#include "platform_lib_property_service.h"
+
+int platform_lib_abstraction_property_get(const char *key, char *value, const char *default_value)
+{
+ return property_get(key, value, default_value);
+}
diff --git a/gps/utils/platform_lib_abstractions/loc_pla/src/platform_lib_sched_policy.cpp b/gps/utils/platform_lib_abstractions/loc_pla/src/platform_lib_sched_policy.cpp
new file mode 100644
index 0000000..ba6b350
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_pla/src/platform_lib_sched_policy.cpp
@@ -0,0 +1,41 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "platform_lib_sched_policy.h"
+
+#ifdef USE_GLIB
+#include <loc_stub_sched_policy.h>
+#else
+#include <cutils/sched_policy.h>
+#endif /* USE_GLIB */
+
+int platform_lib_abstraction_set_sched_policy(int tid, PLASchedPolicy policy)
+{
+ return set_sched_policy(tid, (SchedPolicy)policy);
+}
+
diff --git a/gps/utils/platform_lib_abstractions/loc_pla/src/platform_lib_time.cpp b/gps/utils/platform_lib_abstractions/loc_pla/src/platform_lib_time.cpp
new file mode 100644
index 0000000..3dcd4d3
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_pla/src/platform_lib_time.cpp
@@ -0,0 +1,59 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "platform_lib_time.h"
+
+#ifdef USE_GLIB
+#include <loc_stub_time.h>
+#else
+#include <utils/SystemClock.h>
+#include <utils/Timers.h>
+
+#endif /* USE_GLIB */
+
+int64_t platform_lib_abstraction_elapsed_millis_since_boot()
+{
+#ifdef USE_GLIB
+
+ return elapsedMillisSinceBoot();
+
+#else
+
+ //return android::nanoseconds_to_microseconds(systemTime(SYSTEM_TIME_BOOTTIME))/1000;
+ return nanoseconds_to_microseconds(systemTime(SYSTEM_TIME_BOOTTIME))/1000;
+#endif
+}
+int64_t platform_lib_abstraction_elapsed_micros_since_boot()
+{
+#ifdef USE_GLIB
+ return elapsedMicrosSinceBoot();
+
+#else
+ //return android::nanoseconds_to_microseconds(systemTime(SYSTEM_TIME_BOOTTIME));
+ return nanoseconds_to_microseconds(systemTime(SYSTEM_TIME_BOOTTIME));
+#endif
+}
diff --git a/gps/utils/platform_lib_abstractions/loc_stub/Android.mk b/gps/utils/platform_lib_abstractions/loc_stub/Android.mk
new file mode 100644
index 0000000..b923a4c
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_stub/Android.mk
@@ -0,0 +1,5 @@
+ifneq ($(BUILD_TINY_ANDROID),true)
+
+include $(call all-subdir-makefiles)
+
+endif
diff --git a/gps/utils/platform_lib_abstractions/loc_stub/Makefile.am b/gps/utils/platform_lib_abstractions/loc_stub/Makefile.am
new file mode 100644
index 0000000..d81e363
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_stub/Makefile.am
@@ -0,0 +1,9 @@
+# Makefile.am for gps loc-stub
+
+ACLOCAL_AMFLAGS = -I m4
+
+SUBDIRS = src
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = loc-stub.pc
+EXTRA_DIST = $(pkgconfig_DATA)
diff --git a/gps/utils/platform_lib_abstractions/loc_stub/configure.ac b/gps/utils/platform_lib_abstractions/loc_stub/configure.ac
new file mode 100644
index 0000000..8900f04
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_stub/configure.ac
@@ -0,0 +1,67 @@
+# configure.ac -- Autoconf script for gps loc-stub
+#
+# Process this file with autoconf to produce a configure script
+
+# Requires autoconf tool later than 2.61
+AC_PREREQ(2.61)
+# Initialize the gps loc-stub package version 1.0.0
+AC_INIT([loc-stub],1.0.0)
+# Does not strictly follow GNU Coding standards
+AM_INIT_AUTOMAKE([foreign])
+# Disables auto rebuilding of configure, Makefile.ins
+AM_MAINTAINER_MODE
+# Verifies the --srcdir is correct by checking for the path
+AC_CONFIG_SRCDIR([Makefile.am])
+# defines some macros variable to be included by source
+AC_CONFIG_HEADERS([config.h])
+AC_CONFIG_MACRO_DIR([m4])
+
+# Checks for programs.
+AC_PROG_LIBTOOL
+AC_PROG_CXX
+AC_PROG_CC
+AM_PROG_CC_C_O
+AC_PROG_AWK
+AC_PROG_CPP
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+PKG_PROG_PKG_CONFIG
+
+# Checks for libraries.
+AC_ARG_WITH([hardware_include],
+ AC_HELP_STRING([--with-hardware-include=@<:@dir@:>@],
+ [Specify the location of the hardware headers]),
+ [hardware_incdir=$withval],
+ with_hardware_include=no)
+
+if test "x$with_hardware_include" != "xno"; then
+ CPPFLAGS="${CPPFLAGS} -I${hardware_incdir}"
+fi
+
+AC_ARG_WITH([glib],
+ AC_HELP_STRING([--with-glib],
+ [enable glib, building HLOS systems which use glib]))
+
+if (test "x${with_glib}" = "xyes"); then
+ AC_DEFINE(ENABLE_USEGLIB, 1, [Define if HLOS systems uses glib])
+ PKG_CHECK_MODULES(GTHREAD, gthread-2.0 >= 2.16, dummy=yes,
+ AC_MSG_ERROR(GThread >= 2.16 is required))
+ PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.16, dummy=yes,
+ AC_MSG_ERROR(GLib >= 2.16 is required))
+ GLIB_CFLAGS="$GLIB_CFLAGS $GTHREAD_CFLAGS"
+ GLIB_LIBS="$GLIB_LIBS $GTHREAD_LIBS"
+
+ AC_SUBST(GLIB_CFLAGS)
+ AC_SUBST(GLIB_LIBS)
+fi
+
+AM_CONDITIONAL(USE_GLIB, test "x${with_glib}" = "xyes")
+
+AC_CONFIG_FILES([ \
+ Makefile \
+ src/Makefile \
+ loc-stub.pc
+ ])
+
+AC_OUTPUT
diff --git a/gps/utils/platform_lib_abstractions/loc_stub/include/loc_stub_android_runtime.h b/gps/utils/platform_lib_abstractions/loc_stub/include/loc_stub_android_runtime.h
new file mode 100644
index 0000000..c8764ee
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_stub/include/loc_stub_android_runtime.h
@@ -0,0 +1,45 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __LOC_STUB_ANDROID_RUNTIME_H__
+#define __LOC_STUB_ANDROID_RUNTIME_H__
+
+#include <pthread.h>
+
+namespace android {
+
+class AndroidRuntime
+{
+public:
+ /** create a new thread that is visible from Java */
+ static pthread_t createJavaThread(const char* name, void (*start)(void *),
+ void* arg);
+};
+
+}
+#endif /* __LOC_STUB_ANDROID_RUNTIME_H__ */
diff --git a/gps/utils/platform_lib_abstractions/loc_stub/include/loc_stub_gettid.h b/gps/utils/platform_lib_abstractions/loc_stub/include/loc_stub_gettid.h
new file mode 100644
index 0000000..677bc81
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_stub/include/loc_stub_gettid.h
@@ -0,0 +1,44 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __LOC_STUB_GETTID_H__
+#define __LOC_STUB_GETTID_H__
+
+#include <pthread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+pid_t gettid(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LOC_STUB_GETTID_H__ */
diff --git a/gps/utils/platform_lib_abstractions/loc_stub/include/loc_stub_property_service.h b/gps/utils/platform_lib_abstractions/loc_stub/include/loc_stub_property_service.h
new file mode 100644
index 0000000..3677cdf
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_stub/include/loc_stub_property_service.h
@@ -0,0 +1,42 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __LOC_STUB_PROPERTY_SERVICE_H__
+#define __LOC_STUB_PROPERTY_SERVICE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int property_get(const char *key, char *value, const char *default_value);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __LOC_STUB_PROPERTY_SERVICE_H__ */
diff --git a/gps/utils/platform_lib_abstractions/loc_stub/include/loc_stub_sched_policy.h b/gps/utils/platform_lib_abstractions/loc_stub/include/loc_stub_sched_policy.h
new file mode 100644
index 0000000..a42b117
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_stub/include/loc_stub_sched_policy.h
@@ -0,0 +1,64 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __LOC_STUB_SCHED_POLICY_H__
+#define __LOC_STUB_SCHED_POLICY_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ SP_BACKGROUND = 0,
+ SP_FOREGROUND = 1,
+} SchedPolicy;
+
+/*===========================================================================
+FUNCTION set_sched_policy
+
+DESCRIPTION
+ Local copy of this function which bypasses android set_sched_policy
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int set_sched_policy(int tid, SchedPolicy policy);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __LOC_STUB_SCHED_POLICY_H__ */
+
diff --git a/gps/utils/platform_lib_abstractions/loc_stub/include/loc_stub_time.h b/gps/utils/platform_lib_abstractions/loc_stub/include/loc_stub_time.h
new file mode 100644
index 0000000..f00a49b
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_stub/include/loc_stub_time.h
@@ -0,0 +1,46 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __LOC_STUB_TIME_H__
+#define __LOC_STUB_TIME_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int64_t systemTime(int clock);
+int64_t elapsedMillisSinceBoot();
+int64_t elapsedMicrosSinceBoot();
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __LOC_STUB_TIME_H__ */
diff --git a/gps/utils/platform_lib_abstractions/loc_stub/loc-stub.pc.in b/gps/utils/platform_lib_abstractions/loc_stub/loc-stub.pc.in
new file mode 100644
index 0000000..c2ae764
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_stub/loc-stub.pc.in
@@ -0,0 +1,10 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: loc-stub
+Description: QTI GPS Location Stub
+Version: @VERSION
+Libs: -L${libdir} -lloc_stub
+Cflags: -I${includedir}/loc-stub
diff --git a/gps/utils/platform_lib_abstractions/loc_stub/src/Android.mk b/gps/utils/platform_lib_abstractions/loc_stub/src/Android.mk
new file mode 100644
index 0000000..08697cb
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_stub/src/Android.mk
@@ -0,0 +1,49 @@
+ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)
+ifneq ($(BUILD_TINY_ANDROID),true)
+#Compile this library only for builds with the latest modem image
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+## Libs
+LOCAL_SHARED_LIBRARIES := \
+ libutils \
+ libcutils \
+ liblog
+
+LOCAL_SRC_FILES += \
+ loc_stub_android_runtime.cpp \
+ loc_stub_gettid.cpp \
+ loc_stub_property_service.cpp \
+ loc_stub_sched_policy.cpp \
+ loc_stub_time.cpp
+
+LOCAL_CFLAGS += \
+ -fno-short-enums \
+ -D_ANDROID_ \
+ -std=c++11
+
+
+LOCAL_LDFLAGS += -Wl,--export-dynamic
+
+## Includes
+LOCAL_C_INCLUDES:= \
+ $(LOCAL_PATH)/../include \
+
+LOCAL_MODULE := libloc_stub
+LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib
+LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_CFLAGS += $(GNSS_CFLAGS)
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libloc_stub_headers
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/../include
+include $(BUILD_HEADER_LIBRARY)
+
+endif # not BUILD_TINY_ANDROID
+endif # BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE
diff --git a/gps/utils/platform_lib_abstractions/loc_stub/src/Makefile.am b/gps/utils/platform_lib_abstractions/loc_stub/src/Makefile.am
new file mode 100644
index 0000000..ba823a2
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_stub/src/Makefile.am
@@ -0,0 +1,40 @@
+AM_CFLAGS = \
+ -I../include \
+ -D__func__=__PRETTY_FUNCTION__ \
+ -fno-short-enums
+
+libloc_stub_la_extra_h = \
+ ../include/utils/Log.h
+
+libloc_stub_la_c_sources = \
+ loc_stub_android_runtime.cpp \
+ loc_stub_gettid.cpp \
+ loc_stub_property_service.cpp \
+ loc_stub_sched_policy.cpp \
+ loc_stub_time.cpp
+
+libloc_stub_la_SOURCES = $(libloc_stub_la_c_sources) $(libloc_stub_la_extra_h)
+
+library_include_HEADERS = \
+ ../include/loc_stub_android_runtime.h \
+ ../include/loc_stub_gettid.h \
+ ../include/loc_stub_property_service.h \
+ ../include/loc_stub_sched_policy.h \
+ ../include/loc_stub_time.h
+
+library_includedir = $(pkgincludedir)
+
+if USE_GLIB
+libloc_stub_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@
+libloc_stub_la_LDFLAGS = -lstdc++ -Wl,-z,defs -lpthread @GLIB_LIBS@ -shared -version-info 1:0:0
+libloc_stub_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@
+else
+libloc_stub_la_CFLAGS = $(AM_CFLAGS)
+libloc_stub_la_LDFLAGS = -Wl,-z,defs -lpthread -shared -version-info 1:0:0
+libloc_stub_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS)
+endif
+
+libloc_stub_la_LIBADD = -lstdc++ -ldl -llog
+
+#Create and Install libraries
+lib_LTLIBRARIES = libloc_stub.la
diff --git a/gps/utils/platform_lib_abstractions/loc_stub/src/loc_stub_android_runtime.cpp b/gps/utils/platform_lib_abstractions/loc_stub/src/loc_stub_android_runtime.cpp
new file mode 100644
index 0000000..068df4e
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_stub/src/loc_stub_android_runtime.cpp
@@ -0,0 +1,41 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "loc_stub_android_runtime.h"
+
+namespace android {
+
+pthread_t AndroidRuntime::createJavaThread(const char* /*name*/,
+ void (*start)(void *), void* arg)
+{
+ pthread_t threadId = 0;
+ pthread_create(&threadId, NULL, (void *(*)(void*))start, arg);
+ return threadId;
+}
+
+}
diff --git a/gps/utils/platform_lib_abstractions/loc_stub/src/loc_stub_gettid.cpp b/gps/utils/platform_lib_abstractions/loc_stub/src/loc_stub_gettid.cpp
new file mode 100644
index 0000000..55ef48a
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_stub/src/loc_stub_gettid.cpp
@@ -0,0 +1,37 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "loc_stub_gettid.h"
+#include <sys/syscall.h>
+#include <unistd.h>
+
+// Required for off-target environment to compile properly
+pid_t gettid(void)
+{
+ return syscall(SYS_gettid);
+}
diff --git a/gps/utils/platform_lib_abstractions/loc_stub/src/loc_stub_property_service.cpp b/gps/utils/platform_lib_abstractions/loc_stub/src/loc_stub_property_service.cpp
new file mode 100644
index 0000000..907ab02
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_stub/src/loc_stub_property_service.cpp
@@ -0,0 +1,42 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "loc_stub_property_service.h"
+#include <stdio.h>
+#include <string.h>
+
+int property_get(const char *key, char * value, const char */*default_value*/)
+{
+ /* This will disable gps interface
+ value[0] = '1';
+ */
+ if (strcmp(key, "ro.baseband") == 0) {
+ memcpy(value, "msm", 4);
+ }
+ return 0;
+}
diff --git a/gps/utils/platform_lib_abstractions/loc_stub/src/loc_stub_sched_policy.cpp b/gps/utils/platform_lib_abstractions/loc_stub/src/loc_stub_sched_policy.cpp
new file mode 100644
index 0000000..5e26245
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_stub/src/loc_stub_sched_policy.cpp
@@ -0,0 +1,50 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "loc_stub_sched_policy.h"
+
+/*===========================================================================
+FUNCTION set_sched_policy
+
+DESCRIPTION
+ Local copy of this function which bypasses android set_sched_policy
+
+DEPENDENCIES
+ None
+
+RETURN VALUE
+ 0
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+int set_sched_policy(int /*tid*/, SchedPolicy /*policy*/)
+{
+ return 0;
+}
diff --git a/gps/utils/platform_lib_abstractions/loc_stub/src/loc_stub_time.cpp b/gps/utils/platform_lib_abstractions/loc_stub/src/loc_stub_time.cpp
new file mode 100644
index 0000000..48149a6
--- /dev/null
+++ b/gps/utils/platform_lib_abstractions/loc_stub/src/loc_stub_time.cpp
@@ -0,0 +1,55 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "loc_stub_time.h"
+#include <stdlib.h>
+#include <sys/time.h>
+#include <time.h>
+
+int64_t systemTime(int /*clock*/)
+{
+ struct timeval t;
+ t.tv_sec = t.tv_usec = 0;
+ gettimeofday(&t, NULL);
+ return t.tv_sec*1000000LL + t.tv_usec;
+}
+
+int64_t elapsedMicrosSinceBoot()
+{
+ struct timespec ts;
+ int64_t time_ms = 0;
+ clock_gettime(CLOCK_BOOTTIME, &ts);
+ time_ms += (ts.tv_sec * 1000000000LL); /* Seconds to nanoseconds */
+ time_ms += ts.tv_nsec; /* Add Nanoseconds */
+ return time_ms;
+}
+
+int64_t elapsedMillisSinceBoot()
+{
+ return (int64_t) (elapsedMicrosSinceBoot() /1000000LL);
+}