sm6150-common: gps: Update to LA.UM.9.1.r1-11200-SMxxx0.0

Change-Id: I6ef1b531da58204047a0e269131bf3876eb788b4
This commit is contained in:
Arian
2022-06-27 19:22:12 +02:00
parent 8165447971
commit 54a9eac768
63 changed files with 2598 additions and 1275 deletions

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015, 2020 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -28,6 +28,8 @@
*/
#include <LocHeap.h>
namespace loc_util {
class LocHeapNode {
friend class LocHeap;
@@ -266,6 +268,8 @@ LocRankable* LocHeap::remove(LocRankable& rankable) {
return locNode;
}
} // namespace loc_util
#ifdef __LOC_UNIT_TEST__
bool LocHeap::checkTree() {
return ((NULL == mTree) || mTree->checkNodes());
@@ -274,81 +278,3 @@ 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

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015, 2020 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -32,6 +32,8 @@
#include <stddef.h>
#include <string.h>
namespace loc_util {
// abstract class to be implemented by client to provide a rankable class
class LocRankable {
public:
@@ -93,4 +95,6 @@ public:
#endif
};
} // namespace loc_util
#endif //__LOC_HEAP__

View File

@@ -313,7 +313,7 @@ public:
mAbortCalled(false),
mLocIpc(locIpc),
mIpcRecver(move(ipcRecver)) {}
inline bool run() override {
inline virtual bool run() override {
if (mIpcRecver != nullptr) {
mLocIpc.startBlockingListening(*(mIpcRecver.get()));
if (!mAbortCalled) {
@@ -323,7 +323,7 @@ public:
// return false so the calling thread exits while loop
return false;
}
inline void abort() {
inline virtual void interrupt() override {
mAbortCalled = true;
if (mIpcRecver != nullptr) {
mIpcRecver->abort();
@@ -335,8 +335,7 @@ bool LocIpc::startNonBlockingListening(unique_ptr<LocIpcRecver>& ipcRecver) {
if (ipcRecver != nullptr && ipcRecver->isRecvable()) {
std::string threadName("LocIpc-");
threadName.append(ipcRecver->getName());
mRunnable = new LocIpcRunnable(*this, ipcRecver);
return mThread.start(threadName.c_str(), mRunnable);
return mThread.start(threadName.c_str(), make_shared<LocIpcRunnable>(*this, ipcRecver));
} else {
LOC_LOGe("ipcRecver is null OR ipcRecver->recvable() is fasle");
return false;
@@ -356,10 +355,6 @@ bool LocIpc::startBlockingListening(LocIpcRecver& ipcRecver) {
}
void LocIpc::stopNonBlockingListening() {
if (mRunnable) {
mRunnable->abort();
mRunnable = nullptr;
}
mThread.stop();
}

View File

@@ -45,7 +45,6 @@ namespace loc_util {
class LocIpcRecver;
class LocIpcSender;
class LocIpcRunnable;
class ILocIpcListener {
protected:
@@ -89,7 +88,7 @@ public:
class LocIpc {
public:
inline LocIpc() : mRunnable(nullptr) {}
inline LocIpc() = default;
inline virtual ~LocIpc() {
stopNonBlockingListening();
}
@@ -151,7 +150,6 @@ public:
private:
LocThread mThread;
LocIpcRunnable *mRunnable;
};
/* this is only when client needs to implement Sender / Recver that are not already provided by

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015, 2020 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -49,9 +49,11 @@ inline int32_t android_atomic_dec(volatile int32_t *addr)
volatile std::atomic_int_least32_t* a = (volatile std::atomic_int_least32_t*)addr;
return std::atomic_fetch_sub_explicit(a, 1, std::memory_order_release);
}
#endif /* FEATURE_EXTERNAL_AP */
// This is a utility created for use cases such that there are more than
namespace loc_util {
// 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,
@@ -74,4 +76,6 @@ public:
inline void unlock() { pthread_mutex_unlock(&mMutex); }
};
} //namespace loc_util
#endif //__LOC_SHARED_LOCK__

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015, 2020 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -26,194 +26,75 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <sys/prctl.h>
#include <LocThread.h>
#include <string.h>
#include <pthread.h>
#include <string>
#include <thread>
#include <loc_pla.h>
using std::weak_ptr;
using std::shared_ptr;
using std::thread;
using std::string;
namespace loc_util {
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();
static const char defaultThreadName[];
weak_ptr<LocRunnable> mRunnable;
thread mThread;
LocThreadDelegate(const string tName, shared_ptr<LocRunnable> r);
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);
~LocThreadDelegate() {
shared_ptr<LocRunnable> runnable = mRunnable.lock();
if (nullptr != runnable) {
runnable->interrupt();
}
}
inline static LocThreadDelegate* create(const char* tName, shared_ptr<LocRunnable> runnable);
};
// 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) {
const char LocThreadDelegate::defaultThreadName[] = "LocThread";
// set up thread name, if nothing is passed in
if (!threadName) {
threadName = "LocThread";
}
LocThreadDelegate* LocThreadDelegate::create(const char* tName, shared_ptr<LocRunnable> runnable) {
LocThreadDelegate* threadDelegate = nullptr;
// 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 (nullptr != runnable) {
if (!tName) {
tName = defaultThreadName;
}
if (mThandle) {
// set thread name
char lname[16];
int len = (sizeof(lname) > (strlen(threadName) + 1)) ?
(strlen(threadName)):(sizeof(lname) - 1);
memcpy(lname, threadName, len);
auto nameSize = strlen(tName) + 1;
int len = std::min(sizeof(lname), nameSize) - 1;
memcpy(lname, tName, 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;
}
threadDelegate = new LocThreadDelegate(lname, runnable);
}
return thread;
return threadDelegate;
}
// 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()) {
LocThreadDelegate::LocThreadDelegate(const string tName, shared_ptr<LocRunnable> runnable) :
mRunnable(runnable),
mThread([tName, runnable] {
prctl(PR_SET_NAME, tName.c_str(), 0, 0, 0);
runnable->prerun();
}
while (locThread->isRunning() && runnable->run());
if (locThread->isRunning()) {
while (runnable->run());
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;
mThread.detach();
}
LocThread::~LocThread() {
if (mThread) {
mThread->bye();
mThread = NULL;
}
}
bool LocThread::start(tCreate creator, const char* threadName, LocRunnable* runnable, bool joinable) {
bool LocThread::start(const char* tName, shared_ptr<LocRunnable> runnable) {
bool success = false;
if (!mThread) {
mThread = LocThreadDelegate::create(creator, threadName, runnable, joinable);
mThread = LocThreadDelegate::create(tName, runnable);
// true only if thread is created successfully
success = (NULL != mThread);
}
@@ -221,46 +102,10 @@ bool LocThread::start(tCreate creator, const char* threadName, LocRunnable* runn
}
void LocThread::stop() {
if (mThread) {
mThread->stop();
mThread = NULL;
if (nullptr != mThread) {
delete mThread;
mThread = nullptr;
}
}
#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
} // loc_util

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015, 2020 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -30,14 +30,18 @@
#define __LOC_THREAD__
#include <stddef.h>
#include <pthread.h>
#include <memory>
using std::shared_ptr;
namespace loc_util {
// 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() {}
inline LocRunnable() = default;
inline virtual ~LocRunnable() = default;
// The method to be implemented by thread clients
// and be scheduled by LocThread
@@ -52,6 +56,10 @@ public:
// The method to be run after thread loop (conditionally repeatedly)
// calls run()
inline virtual void postrun() {}
// The method to wake up the potential blocking thread
// no op if not applicable
inline virtual void interrupt() = 0;
};
// opaque class to provide service implementation.
@@ -63,12 +71,11 @@ class LocThread {
LocThreadDelegate* mThread;
public:
inline LocThread() : mThread(NULL) {}
virtual ~LocThread();
inline virtual ~LocThread() { stop(); }
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.
// The thread is always 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).
@@ -76,17 +83,13 @@ public:
// 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);
}
bool start(const char* threadName, shared_ptr<LocRunnable> runnable);
// 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; }
};
} // loc_util
#endif //__LOC_THREAD__

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015, 2020 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -48,6 +48,8 @@
#define CLOCK_BOOTTIME_ALARM CLOCK_MONOTONIC
#endif
namespace loc_util {
/*
There are implementations of 5 classes in this file:
LocTimer, LocTimerDelegate, LocTimerContainer, LocTimerPollTask, LocTimerWrapper
@@ -129,6 +131,21 @@ public:
void expire();
};
class TimerRunnable : public LocRunnable {
const int mFd;
public:
inline TimerRunnable(const int fd) : mFd(fd) {}
// 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() override;
// The method to wake up the potential blocking thread
// no op if not applicable
inline virtual void interrupt() { close(mFd); }
};
// 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
@@ -140,19 +157,17 @@ public:
// 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 {
class LocTimerPollTask {
// the epoll fd
const int mFd;
// the thread that calls run() method
LocThread* mThread;
friend class LocThreadDelegate;
// dtor
~LocTimerPollTask();
// the thread that calls TimerRunnable::run() method, where
// epoll_wait() is blocking and waiting for events..
LocThread mThread;
public:
// ctor
LocTimerPollTask();
// this obj will be deleted once thread is deleted
void destroy();
// dtor
~LocTimerPollTask() = default;
// 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
@@ -164,9 +179,6 @@ public:
// 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();
@@ -257,7 +269,7 @@ LocTimerContainer* LocTimerContainer::get(bool wakeOnExpire) {
MsgTask* LocTimerContainer::getMsgTaskLocked() {
// it is cheap to check pointer first than locking mutext unconditionally
if (!mMsgTask) {
mMsgTask = new MsgTask("LocTimerMsgTask", false);
mMsgTask = new MsgTask("LocTimerMsgTask");
}
return mMsgTask;
}
@@ -313,7 +325,6 @@ 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) {}
@@ -398,32 +409,12 @@ LocTimerDelegate* LocTimerContainer::popIfOutRanks(LocTimerDelegate& timer) {
inline
LocTimerPollTask::LocTimerPollTask()
: mFd(epoll_create(2)), mThread(new LocThread()) {
: mFd(epoll_create(2)), mThread() {
// 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;
}
mThread.start("LocTimerPollTask", std::make_shared<TimerRunnable>(mFd));
}
void LocTimerPollTask::addPoll(LocTimerContainer& timerContainer) {
@@ -447,7 +438,7 @@ void LocTimerPollTask::removePoll(LocTimerContainer& timerContainer) {
// 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() {
bool TimerRunnable::run() {
struct epoll_event ev[2];
// we have max 2 descriptors to poll from
@@ -621,6 +612,14 @@ public:
}
};
} // namespace loc_util
//////////////////////////////////////////////////////////////////////////
// This section below wraps for the C style APIs
//////////////////////////////////////////////////////////////////////////
using loc_util::LocTimerWrapper;
pthread_mutex_t LocTimerWrapper::mMutex = PTHREAD_MUTEX_INITIALIZER;
void* loc_timer_start(uint64_t msec, loc_timer_callback cb_func,
@@ -647,107 +646,3 @@ void loc_timer_stop(void*& handle)
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

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015, 2020 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -33,6 +33,8 @@
#include <stddef.h>
#include <loc_pla.h>
namespace loc_util {
// opaque class to provide service implementation.
class LocTimerDelegate;
class LocSharedLock;
@@ -71,4 +73,6 @@ public:
virtual void timeOutCallback() = 0;
};
} // namespace loc_util
#endif //__LOC_DELAY_H__

View File

@@ -36,41 +36,33 @@
#include <loc_log.h>
#include <loc_pla.h>
namespace loc_util {
class MTRunnable : public LocRunnable {
const void* mQ;
public:
inline MTRunnable(const void* q) : mQ(q) {}
virtual ~MTRunnable();
// Overrides of LocRunnable methods
// This method will be repeated called until it returns false; or
// until thread is stopped.
virtual bool run() override;
// The method to be run before thread loop (conditionally repeatedly)
// calls run()
virtual void prerun() override;
// to interrupt the run() method and come out of that
virtual void interrupt() override;
};
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;
}
MsgTask::MsgTask(const char* threadName) :
mQ(msg_q_init2()), mThread() {
mThread.start(threadName, std::make_shared<MTRunnable>(mQ));
}
void MsgTask::sendMsg(const LocMsg* msg) const {
@@ -82,12 +74,27 @@ void MsgTask::sendMsg(const LocMsg* msg) const {
}
}
void MsgTask::prerun() {
void MsgTask::sendMsg(const std::function<void()> runnable) const {
struct RunMsg : public LocMsg {
const std::function<void()> mRunnable;
public:
inline RunMsg(const std::function<void()> runnable) : mRunnable(runnable) {}
~RunMsg() = default;
inline virtual void proc() const override { mRunnable(); }
};
sendMsg(new RunMsg(runnable));
}
void MTRunnable::interrupt() {
msg_q_unblock((void*)mQ);
}
void MTRunnable::prerun() {
// make sure we do not run in background scheduling group
set_sched_policy(gettid(), SP_FOREGROUND);
}
bool MsgTask::run() {
bool MTRunnable::run() {
LocMsg* msg;
msq_q_err_type result = msg_q_rcv((void*)mQ, (void **)&msg);
if (eMSG_Q_SUCCESS != result) {
@@ -104,3 +111,10 @@ bool MsgTask::run() {
return true;
}
MTRunnable::~MTRunnable() {
msg_q_flush((void*)mQ);
msg_q_destroy((void**)&mQ);
}
} // namespace loc_util

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2011-2013,2015 The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-2013, 2015, 2020 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -29,8 +29,11 @@
#ifndef __MSG_TASK__
#define __MSG_TASK__
#include <functional>
#include <LocThread.h>
namespace loc_util {
struct LocMsg {
inline LocMsg() {}
inline virtual ~LocMsg() {}
@@ -38,30 +41,16 @@ struct LocMsg {
inline virtual void log() const {}
};
class MsgTask : public LocRunnable {
class MsgTask {
const void* mQ;
LocThread* mThread;
friend class LocThreadDelegate;
protected:
virtual ~MsgTask();
LocThread mThread;
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();
~MsgTask() = default;
MsgTask(const char* threadName = NULL);
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() {}
void sendMsg(const std::function<void()> runnable) const;
};
} //
#endif //__MSG_TASK__

View File

@@ -115,6 +115,9 @@ typedef uint32_t LocPosTechMask;
#define LOC_POS_TECH_MASK_AFLT ((LocPosTechMask)0x00000040)
#define LOC_POS_TECH_MASK_HYBRID ((LocPosTechMask)0x00000080)
#define LOC_POS_TECH_MASK_PPE ((LocPosTechMask)0x00000100)
#define LOC_POS_TECH_MASK_VEH ((LocPosTechMask)0x00000200)
#define LOC_POS_TECH_MASK_VIS ((LocPosTechMask)0x00000400)
enum loc_registration_mask_status {
LOC_REGISTRATION_MASK_ENABLED,
@@ -412,8 +415,12 @@ typedef uint64_t GpsLocationExtendedFlags;
#define GPS_LOCATION_EXTENDED_HAS_LLA_VRP_BASED 0x200000000000
/** GpsLocationExtended has the velocityVRPased. */
#define GPS_LOCATION_EXTENDED_HAS_ENU_VELOCITY_LLA_VRP_BASED 0x400000000000
/** GpsLocationExtended has upperTriangleFullCovMatrix. */
#define GPS_LOCATION_EXTENDED_HAS_UPPER_TRIANGLE_FULL_COV_MATRIX 0x800000000000
/** GpsLocationExtended has drSolutionStatusMask. */
#define GPS_LOCATION_EXTENDED_HAS_DR_SOLUTION_STATUS_MASK 0x1000000000000
/** GpsLocationExtended has altitudeAssumed. */
#define GPS_LOCATION_EXTENDED_HAS_ALTITUDE_ASSUMED 0x2000000000000
typedef uint32_t LocNavSolutionMask;
/* Bitmask to specify whether SBAS ionospheric correction is used */
@@ -479,6 +486,7 @@ typedef uint32_t GnssAdditionalSystemInfoMask;
#define GAL_SV_PRN_MAX 336
#define NAVIC_SV_PRN_MIN 401
#define NAVIC_SV_PRN_MAX 414
#define GLO_SV_PRN_SLOT_UNKNOWN 255
/* Checking svIdOneBase can be set to the corresponding bit in mask */
#define svFitsMask(mask, svIdOneBase) \
@@ -488,6 +496,7 @@ typedef uint32_t GnssAdditionalSystemInfoMask;
if (svFitsMask(mask, svIdOneBase)) mask |= (1ULL << ((svIdOneBase) - 1))
#define isValInRangeInclusive(val, min, max) ((val) >= (min) && (val) <= (max))
#define isGloSlotUnknown(val) ((val) == GLO_SV_PRN_SLOT_UNKNOWN)
typedef enum {
LOC_RELIABILITY_NOT_SET = 0,
@@ -864,14 +873,14 @@ typedef struct {
*/
float upperTriangleFullCovMatrix[COV_MATRIX_SIZE];
DrSolutionStatusMask drSolutionStatusMask;
/** When this field is valid, it will indicates whether altitude
* is assumed or calculated.
* false: Altitude is calculated.
* true: Altitude is assumed; there may not be enough
* satellites to determine the precise altitude. */
bool altitudeAssumed;
} GpsLocationExtended;
enum loc_sess_status {
LOC_SESS_SUCCESS,
LOC_SESS_INTERMEDIATE,
LOC_SESS_FAILURE
};
// struct that contains complete position info from engine
typedef struct {
UlpLocation location;
@@ -912,6 +921,7 @@ typedef uint32_t NmeaSentenceTypesMask;
#define LOC_NMEA_MASK_GQGSV_V02 ((NmeaSentenceTypesMask)0x10000000) /**< Enable GQGSV type */
#define LOC_NMEA_MASK_GIGSV_V02 ((NmeaSentenceTypesMask)0x20000000) /**< Enable GIGSV type */
#define LOC_NMEA_MASK_GNDTM_V02 ((NmeaSentenceTypesMask)0x40000000) /**< Enable GNDTM type */
#define LOC_NMEA_MASK_TAGBLOCK_V02 ((NmeaSentenceTypesMask)0x80000000) /**< Enable TAGBLOCK type */
// all bitmasks of general supported NMEA sentenses - debug is not part of this
@@ -1006,41 +1016,42 @@ enum loc_api_adapter_event_index {
LOC_API_ADAPTER_LOC_SYSTEM_INFO, // Location system info event
LOC_API_ADAPTER_GNSS_NHZ_MEASUREMENT_REPORT, // GNSS SV nHz measurement report
LOC_API_ADAPTER_EVENT_REPORT_INFO, // Event report info
LOC_API_ADAPTER_LATENCY_INFORMATION_REPORT, // Latency information report
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)
#define LOC_API_ADAPTER_BIT_PARSED_POSITION_REPORT (1ULL<<LOC_API_ADAPTER_REPORT_POSITION)
#define LOC_API_ADAPTER_BIT_SATELLITE_REPORT (1ULL<<LOC_API_ADAPTER_REPORT_SATELLITE)
#define LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT (1ULL<<LOC_API_ADAPTER_REPORT_NMEA_1HZ)
#define LOC_API_ADAPTER_BIT_NMEA_POSITION_REPORT (1ULL<<LOC_API_ADAPTER_REPORT_NMEA_POSITION)
#define LOC_API_ADAPTER_BIT_NI_NOTIFY_VERIFY_REQUEST (1ULL<<LOC_API_ADAPTER_REQUEST_NI_NOTIFY_VERIFY)
#define LOC_API_ADAPTER_BIT_ASSISTANCE_DATA_REQUEST (1ULL<<LOC_API_ADAPTER_REQUEST_ASSISTANCE_DATA)
#define LOC_API_ADAPTER_BIT_LOCATION_SERVER_REQUEST (1ULL<<LOC_API_ADAPTER_REQUEST_LOCATION_SERVER)
#define LOC_API_ADAPTER_BIT_IOCTL_REPORT (1ULL<<LOC_API_ADAPTER_REPORT_IOCTL)
#define LOC_API_ADAPTER_BIT_STATUS_REPORT (1ULL<<LOC_API_ADAPTER_REPORT_STATUS)
#define LOC_API_ADAPTER_BIT_REQUEST_WIFI (1ULL<<LOC_API_ADAPTER_REQUEST_WIFI)
#define LOC_API_ADAPTER_BIT_SENSOR_STATUS (1ULL<<LOC_API_ADAPTER_SENSOR_STATUS)
#define LOC_API_ADAPTER_BIT_REQUEST_TIME_SYNC (1ULL<<LOC_API_ADAPTER_REQUEST_TIME_SYNC)
#define LOC_API_ADAPTER_BIT_REPORT_SPI (1ULL<<LOC_API_ADAPTER_REPORT_SPI)
#define LOC_API_ADAPTER_BIT_REPORT_NI_GEOFENCE (1ULL<<LOC_API_ADAPTER_REPORT_NI_GEOFENCE)
#define LOC_API_ADAPTER_BIT_GEOFENCE_GEN_ALERT (1ULL<<LOC_API_ADAPTER_GEOFENCE_GEN_ALERT)
#define LOC_API_ADAPTER_BIT_REPORT_GENFENCE_BREACH (1ULL<<LOC_API_ADAPTER_REPORT_GENFENCE_BREACH)
#define LOC_API_ADAPTER_BIT_BATCHED_GENFENCE_BREACH_REPORT (1ULL<<LOC_API_ADAPTER_BATCHED_GENFENCE_BREACH_REPORT)
#define LOC_API_ADAPTER_BIT_PEDOMETER_CTRL (1ULL<<LOC_API_ADAPTER_PEDOMETER_CTRL)
#define LOC_API_ADAPTER_BIT_MOTION_CTRL (1ULL<<LOC_API_ADAPTER_MOTION_CTRL)
#define LOC_API_ADAPTER_BIT_REQUEST_WIFI_AP_DATA (1ULL<<LOC_API_ADAPTER_REQUEST_WIFI_AP_DATA)
#define LOC_API_ADAPTER_BIT_BATCH_FULL (1ULL<<LOC_API_ADAPTER_BATCH_FULL)
#define LOC_API_ADAPTER_BIT_BATCHED_POSITION_REPORT (1ULL<<LOC_API_ADAPTER_BATCHED_POSITION_REPORT)
#define LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT_REPORT (1ULL<<LOC_API_ADAPTER_GNSS_MEASUREMENT_REPORT)
#define LOC_API_ADAPTER_BIT_GNSS_SV_POLYNOMIAL_REPORT (1ULL<<LOC_API_ADAPTER_GNSS_SV_POLYNOMIAL_REPORT)
#define LOC_API_ADAPTER_BIT_GDT_UPLOAD_BEGIN_REQ (1ULL<<LOC_API_ADAPTER_GDT_UPLOAD_BEGIN_REQ)
#define LOC_API_ADAPTER_BIT_GDT_UPLOAD_END_REQ (1ULL<<LOC_API_ADAPTER_GDT_UPLOAD_END_REQ)
#define LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT (1ULL<<LOC_API_ADAPTER_GNSS_MEASUREMENT)
#define LOC_API_ADAPTER_BIT_REQUEST_TIMEZONE (1ULL<<LOC_API_ADAPTER_REQUEST_TIMEZONE)
#define LOC_API_ADAPTER_BIT_REPORT_GENFENCE_DWELL (1ULL<<LOC_API_ADAPTER_REPORT_GENFENCE_DWELL_REPORT)
#define LOC_API_ADAPTER_BIT_REQUEST_SRN_DATA (1ULL<<LOC_API_ADAPTER_REQUEST_SRN_DATA)
#define LOC_API_ADAPTER_BIT_POSITION_INJECTION_REQUEST (1ULL<<LOC_API_ADAPTER_REQUEST_POSITION_INJECTION)
#define LOC_API_ADAPTER_BIT_BATCH_STATUS (1ULL<<LOC_API_ADAPTER_BATCH_STATUS)
#define LOC_API_ADAPTER_BIT_FDCL_SERVICE_REQ (1ULL<<LOC_API_ADAPTER_FDCL_SERVICE_REQ)
#define LOC_API_ADAPTER_BIT_PARSED_UNPROPAGATED_POSITION_REPORT (1ULL<<LOC_API_ADAPTER_REPORT_UNPROPAGATED_POSITION)
#define LOC_API_ADAPTER_BIT_BS_OBS_DATA_SERVICE_REQ (1ULL<<LOC_API_ADAPTER_BS_OBS_DATA_SERVICE_REQ)
@@ -1048,6 +1059,7 @@ enum loc_api_adapter_event_index {
#define LOC_API_ADAPTER_BIT_LOC_SYSTEM_INFO (1ULL<<LOC_API_ADAPTER_LOC_SYSTEM_INFO)
#define LOC_API_ADAPTER_BIT_GNSS_NHZ_MEASUREMENT (1ULL<<LOC_API_ADAPTER_GNSS_NHZ_MEASUREMENT_REPORT)
#define LOC_API_ADAPTER_BIT_EVENT_REPORT_INFO (1ULL<<LOC_API_ADAPTER_EVENT_REPORT_INFO)
#define LOC_API_ADAPTER_BIT_LATENCY_INFORMATION (1ULL<<LOC_API_ADAPTER_LATENCY_INFORMATION_REPORT)
typedef uint64_t LOC_API_ADAPTER_EVENT_MASK_T;
@@ -1539,6 +1551,10 @@ typedef uint64_t GpsSvMeasHeaderFlags;
#define GNSS_SV_MEAS_HEADER_HAS_DGNSS_CORRECTION_SOURCE_ID 0x020000000
#define GNSS_SV_MEAS_HEADER_HAS_DGNSS_REF_STATION_ID 0x040000000
#define GNSS_SV_MEAS_HEADER_HAS_REF_COUNT_TICKS 0x080000000
#define GNSS_SV_MEAS_HEADER_HAS_GPSL1L2C_TIME_BIAS 0x100000000
#define GNSS_SV_MEAS_HEADER_HAS_GLOG1G2_TIME_BIAS 0x200000000
#define GNSS_SV_MEAS_HEADER_HAS_BDSB1IB1C_TIME_BIAS 0x400000000
#define GNSS_SV_MEAS_HEADER_HAS_GALE1E5B_TIME_BIAS 0x800000000
typedef struct
{
@@ -1565,6 +1581,10 @@ typedef struct
Gnss_InterSystemBiasStructType gpsL1L5TimeBias;
Gnss_InterSystemBiasStructType galE1E5aTimeBias;
Gnss_InterSystemBiasStructType bdsB1iB2aTimeBias;
Gnss_InterSystemBiasStructType gpsL1L2cTimeBias;
Gnss_InterSystemBiasStructType gloG1G2TimeBias;
Gnss_InterSystemBiasStructType bdsB1iB1cTimeBias;
Gnss_InterSystemBiasStructType galE1E5bTimeBias;
GnssSystemTimeStructType gpsSystemTime;
GnssSystemTimeStructType galSystemTime;

View File

@@ -144,7 +144,9 @@ RETURN VALUE
SIDE EFFECTS
N/A
===========================================================================*/
int loc_set_config_entry(const loc_param_s_type* config_entry, loc_param_v_type* config_value)
int loc_set_config_entry(const loc_param_s_type* config_entry,
loc_param_v_type* config_value,
uint16_t string_len = LOC_MAX_PARAM_STRING)
{
int ret=-1;
if(NULL == config_entry || NULL == config_value)
@@ -166,7 +168,7 @@ int loc_set_config_entry(const loc_param_s_type* config_entry, loc_param_v_type*
else {
strlcpy((char*) config_entry->param_ptr,
config_value->param_str_value,
LOC_MAX_PARAM_STRING);
string_len);
}
/* Log INI values */
LOC_LOGD("%s: PARAM %s = %s", __FUNCTION__,
@@ -233,7 +235,8 @@ SIDE EFFECTS
N/A
===========================================================================*/
int loc_fill_conf_item(char* input_buf,
const loc_param_s_type* config_table, uint32_t table_length)
const loc_param_s_type* config_table,
uint32_t table_length, uint16_t string_len = LOC_MAX_PARAM_STRING)
{
int ret = 0;
@@ -270,7 +273,7 @@ int loc_fill_conf_item(char* input_buf,
for(uint32_t i = 0; NULL != config_table && i < table_length; i++)
{
if(!loc_set_config_entry(&config_table[i], &config_value)) {
if(!loc_set_config_entry(&config_table[i], &config_value, string_len)) {
ret += 1;
}
}
@@ -282,7 +285,7 @@ int loc_fill_conf_item(char* input_buf,
}
/*===========================================================================
FUNCTION loc_read_conf_r (repetitive)
FUNCTION loc_read_conf_r_long (repetitive)
DESCRIPTION
Reads the specified configuration file and sets defined values based on
@@ -310,11 +313,13 @@ RETURN VALUE
SIDE EFFECTS
N/A
===========================================================================*/
int loc_read_conf_r(FILE *conf_fp, const loc_param_s_type* config_table, uint32_t table_length)
int loc_read_conf_r_long(FILE *conf_fp, const loc_param_s_type* config_table,
uint32_t table_length, uint16_t string_len)
{
int ret=0;
char input_buf[string_len]; /* declare a char array */
unsigned int num_params=table_length;
if(conf_fp == NULL) {
LOC_LOGE("%s:%d]: ERROR: File pointer is NULL\n", __func__, __LINE__);
ret = -1;
@@ -330,17 +335,15 @@ int loc_read_conf_r(FILE *conf_fp, const loc_param_s_type* config_table, uint32_
}
}
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)) {
if(!fgets(input_buf, string_len, 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);
num_params -= loc_fill_conf_item(input_buf, config_table, table_length, string_len);
}
err:
@@ -348,7 +351,7 @@ err:
}
/*===========================================================================
FUNCTION loc_udpate_conf
FUNCTION loc_udpate_conf_long
DESCRIPTION
Parses the passed in buffer for configuration items, and update the table
@@ -373,8 +376,9 @@ RETURN VALUE
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 loc_update_conf_long(const char* conf_data, int32_t length,
const loc_param_s_type* config_table,
uint32_t table_length, uint16_t string_len)
{
int ret = -1;
@@ -397,7 +401,8 @@ int loc_update_conf(const char* conf_data, int32_t length,
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);
num_params -=
loc_fill_conf_item(input_buf, config_table, table_length, string_len);
input_buf = strtok_r(NULL, "\n", &saveptr);
}
free(conf_copy);
@@ -408,7 +413,7 @@ int loc_update_conf(const char* conf_data, int32_t length,
}
/*===========================================================================
FUNCTION loc_read_conf
FUNCTION loc_read_conf_long
DESCRIPTION
Reads the specified configuration file and sets defined values based on
@@ -429,8 +434,8 @@ RETURN VALUE
SIDE EFFECTS
N/A
===========================================================================*/
void loc_read_conf(const char* conf_file_name, const loc_param_s_type* config_table,
uint32_t table_length)
void loc_read_conf_long(const char* conf_file_name, const loc_param_s_type* config_table,
uint32_t table_length, uint16_t string_len)
{
FILE *conf_fp = NULL;
@@ -439,15 +444,16 @@ void loc_read_conf(const char* conf_file_name, const loc_param_s_type* config_ta
{
LOC_LOGD("%s: using %s", __FUNCTION__, conf_file_name);
if(table_length && config_table) {
loc_read_conf_r(conf_fp, config_table, table_length);
loc_read_conf_r_long(conf_fp, config_table, table_length, string_len);
rewind(conf_fp);
}
loc_read_conf_r(conf_fp, loc_param_table, loc_param_num);
loc_read_conf_r_long(conf_fp, loc_param_table, loc_param_num, string_len);
fclose(conf_fp);
}
/* Initialize logging mechanism with parsed data */
loc_logger_init(DEBUG_LEVEL, TIMESTAMP);
log_buffer_init(sLogBufferEnabled);
log_tag_level_map_init();
}
/*=============================================================================

View File

@@ -65,6 +65,10 @@
#define UTIL_READ_CONF(filename, config_table) \
loc_read_conf((filename), (&config_table[0]), sizeof(config_table) / sizeof(config_table[0]))
#define UTIL_READ_CONF_LONG(filename, config_table, rec_len) \
loc_read_conf_long((filename), (&config_table[0]), \
sizeof(config_table) / sizeof(config_table[0]), (rec_len))
/*=============================================================================
*
* MODULE TYPE DECLARATION
@@ -115,13 +119,30 @@ extern "C" {
*============================================================================*/
bool isVendorEnhanced();
void setVendorEnhanced(bool vendorEnhanced);
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);
void loc_read_conf_long(const char* conf_file_name,
const loc_param_s_type* config_table,
uint32_t table_length, uint16_t string_len);
int loc_read_conf_r_long(FILE *conf_fp, const loc_param_s_type* config_table,
uint32_t table_length, uint16_t string_len);
int loc_update_conf_long(const char* conf_data, int32_t length,
const loc_param_s_type* config_table, uint32_t table_length,
uint16_t string_len);
inline void loc_read_conf(const char* conf_file_name,
const loc_param_s_type* config_table, uint32_t table_length) {
loc_read_conf_long(conf_file_name, config_table, table_length, LOC_MAX_PARAM_STRING);
}
inline int loc_read_conf_r(FILE *conf_fp, const loc_param_s_type* config_table,
uint32_t table_length) {
return (loc_read_conf_r_long(conf_fp, config_table, table_length, LOC_MAX_PARAM_STRING));
}
inline int loc_update_conf(const char* conf_data, int32_t length,
const loc_param_s_type* config_table, uint32_t table_length) {
return (loc_update_conf_long(
conf_data, length, config_table, table_length, LOC_MAX_PARAM_STRING));
}
// Below are the location conf file paths
extern const char LOC_PATH_GPS_CONF[];

View File

@@ -38,8 +38,13 @@
#include "msg_q.h"
#include <loc_pla.h>
#include "LogBuffer.h"
#include <unordered_map>
#include <fstream>
#include <algorithm>
#include <string>
#include <cctype>
#define BUFFER_SIZE 120
#define LOG_TAG_LEVEL_CONF_FILE_PATH "/data/vendor/location/gps.prop"
// Logging Improvements
const char *loc_logger_boolStr[]={"False","True"};
@@ -59,6 +64,10 @@ const string gUnknownStr = "UNKNOWN";
/* Logging Mechanism */
loc_logger_s_type loc_logger;
/* tag base logging control map*/
static std::unordered_map<std::string, uint8_t> tag_level_map;
static bool tag_map_inited = false;
/* returns the least signification bit that is set in the mask
Param
mask - bit mask.
@@ -219,3 +228,55 @@ void log_buffer_insert(char *str, unsigned long buf_size, int level)
string ss = str;
loc_util::LogBuffer::getInstance()->append(ss, level, elapsedTime);
}
void log_tag_level_map_init()
{
if (tag_map_inited) {
return;
}
std::string filename = LOG_TAG_LEVEL_CONF_FILE_PATH;
std::ifstream s(filename);
if (!s.is_open()) {
ALOGE("cannot open file:%s", LOG_TAG_LEVEL_CONF_FILE_PATH);
} else {
std::string line;
while (std::getline(s, line)) {
line.erase(std::remove(line.begin(), line.end(), ' '), line.end());
int pos = line.find('=');
if (pos <= 0 || pos >= (line.size() - 1)) {
ALOGE("wrong format in gps.prop");
continue;
}
std::string tag = line.substr(0, pos);
std::string level = line.substr(pos+1, 1);
if (!std::isdigit(*(level.begin()))) {
ALOGE("wrong format in gps.prop");
continue;
}
tag_level_map[tag] = (uint8_t)std::stoul(level);
}
}
tag_map_inited = true;
}
int get_tag_log_level(const char* tag)
{
if (!tag_map_inited) {
return -1;
}
// in case LOG_TAG isn't defined in a source file, use the global log level
if (tag == NULL) {
return loc_logger.DEBUG_LEVEL;
}
int log_level;
auto search = tag_level_map.find(std::string(tag));
if (tag_level_map.end() != search) {
log_level = search->second;
} else {
log_level = loc_logger.DEBUG_LEVEL;
}
return log_level;
}

View File

@@ -32,6 +32,7 @@
#include <string.h>
#include <inttypes.h>
#include <dlfcn.h>
#include <math.h>
#include <log_util.h>
#include <loc_misc_utils.h>
#include <ctype.h>
@@ -232,3 +233,119 @@ uint64_t getBootTimeMilliSec()
clock_gettime(CLOCK_BOOTTIME, &curTs);
return (uint64_t)GET_MSEC_FROM_TS(curTs);
}
// Used for convert position/velocity from GSNS antenna based to VRP based
void Matrix_MxV(float a[3][3], float b[3], float c[3]) {
int i, j;
for (i=0; i<3; i++) {
c[i] = 0.0f;
for (j=0; j<3; j++)
c[i] += a[i][j] * b[j];
}
}
// Used for convert position/velocity from GNSS antenna based to VRP based
void Matrix_Skew(float a[3], float c[3][3]) {
c[0][0] = 0.0f;
c[0][1] = -a[2];
c[0][2] = a[1];
c[1][0] = a[2];
c[1][1] = 0.0f;
c[1][2] = -a[0];
c[2][0] = -a[1];
c[2][1] = a[0];
c[2][2] = 0.0f;
}
// Used for convert position/velocity from GNSS antenna based to VRP based
void Euler2Dcm(float euler[3], float dcm[3][3]) {
float cr = 0.0, sr = 0.0, cp = 0.0, sp = 0.0, ch = 0.0, sh = 0.0;
cr = cosf(euler[0]);
sr = sinf(euler[0]);
cp = cosf(euler[1]);
sp = sinf(euler[1]);
ch = cosf(euler[2]);
sh = sinf(euler[2]);
dcm[0][0] = cp * ch;
dcm[0][1] = (sp*sr*ch) - (cr*sh);
dcm[0][2] = (cr*sp*ch) + (sh*sr);
dcm[1][0] = cp * sh;
dcm[1][1] = (sr*sp*sh) + (cr*ch);
dcm[1][2] = (cr*sp*sh) - (sr*ch);
dcm[2][0] = -sp;
dcm[2][1] = sr * cp;
dcm[2][2] = cr * cp;
}
// Used for convert position from GSNS based to VRP based
// The converted position will be stored in the llaInfo parameter.
#define A6DOF_WGS_A (6378137.0f)
#define A6DOF_WGS_B (6335439.0f)
#define A6DOF_WGS_E2 (0.00669437999014f)
void loc_convert_lla_gnss_to_vrp(double lla[3], float rollPitchYaw[3],
float leverArm[3]) {
LOC_LOGv("lla: %f, %f, %f, lever arm: %f %f %f, "
"rollpitchyaw: %f %f %f",
lla[0], lla[1], lla[2],
leverArm[0], leverArm[1], leverArm[2],
rollPitchYaw[0], rollPitchYaw[1], rollPitchYaw[2]);
float cnb[3][3];
memset(cnb, 0, sizeof(cnb));
Euler2Dcm(rollPitchYaw, cnb);
float sl = sin(lla[0]);
float cl = cos(lla[0]);
float sf = 1.0f / (1.0f - A6DOF_WGS_E2 * sl* sl);
float sfr = sqrtf(sf);
float rn = A6DOF_WGS_B * sf * sfr + lla[2];
float re = A6DOF_WGS_A * sfr + lla[2];
float deltaNEU[3];
// gps_pos_lla = imu_pos_lla + Cbn*la_b .* [1/geo.Rn; 1/(geo.Re*geo.cL); -1];
Matrix_MxV(cnb, leverArm, deltaNEU);
// NED to lla conversion
lla[0] = lla[0] + deltaNEU[0] / rn;
lla[1] = lla[1] + deltaNEU[1] / (re * cl);
lla[2] = lla[2] + deltaNEU[2];
}
// Used for convert velocity from GSNS based to VRP based
// The converted velocity will be stored in the enuVelocity parameter.
void loc_convert_velocity_gnss_to_vrp(float enuVelocity[3], float rollPitchYaw[3],
float rollPitchYawRate[3], float leverArm[3]) {
LOC_LOGv("enu velocity: %f, %f, %f, lever arm: %f %f %f, roll pitch yaw: %f %f %f,"
"rollpitchyawRate: %f %f %f",
enuVelocity[0], enuVelocity[1], enuVelocity[2],
leverArm[0], leverArm[1], leverArm[2],
rollPitchYaw[0], rollPitchYaw[1], rollPitchYaw[2],
rollPitchYawRate[0], rollPitchYawRate[1], rollPitchYawRate[2]);
float cnb[3][3];
memset(cnb, 0, sizeof(cnb));
Euler2Dcm(rollPitchYaw, cnb);
float skewLA[3][3];
memset(skewLA, 0, sizeof(skewLA));
Matrix_Skew(leverArm, skewLA);
float tmp[3];
float deltaEnuVelocity[3];
memset(tmp, 0, sizeof(tmp));
memset(deltaEnuVelocity, 0, sizeof(deltaEnuVelocity));
Matrix_MxV(skewLA, rollPitchYawRate, tmp);
Matrix_MxV(cnb, tmp, deltaEnuVelocity);
enuVelocity[0] = enuVelocity[0] - deltaEnuVelocity[0];
enuVelocity[1] = enuVelocity[1] - deltaEnuVelocity[1];
enuVelocity[2] = enuVelocity[2] - deltaEnuVelocity[2];
}

View File

@@ -279,4 +279,43 @@ inline uint64_t qTimerTicksToNanos(double qTimer) {
return (uint64_t((qTimer * double(10000ull)) / (double)192ull));
}
/*===========================================================================
FUNCTION loc_convert_lla_gnss_to_vrp
DESCRIPTION
This function converts lat/long/altitude from GNSS antenna based
to vehicle reference point based.
DEPENDENCIES
N/A
RETURN VALUE
The converted lat/long/altitude will be stored in the parameter of llaInfo.
SIDE EFFECTS
N/A
===========================================================================*/
void loc_convert_lla_gnss_to_vrp(double lla[3], float rollPitchYaw[3],
float leverArm[3]);
/*===========================================================================
FUNCTION loc_convert_velocity_gnss_to_vrp
DESCRIPTION
This function converts east/north/up velocity from GNSS antenna based
to vehicle reference point based.
DEPENDENCIES
N/A
RETURN VALUE
The converted east/north/up velocity will be stored in the parameter of
enuVelocity.
SIDE EFFECTS
N/A
===========================================================================*/
void loc_convert_velocity_gnss_to_vrp(float enuVelocity[3], float rollPitchYaw[3],
float rollPitchYawRate[3], float leverArm[3]);
#endif //_LOC_MISC_UTILS_H_

View File

@@ -36,6 +36,7 @@
#include <loc_cfg.h>
#define GLONASS_SV_ID_OFFSET 64
#define SBAS_SV_ID_OFFSET (87)
#define QZSS_SV_ID_OFFSET (192)
#define BDS_SV_ID_OFFSET (200)
#define GALILEO_SV_ID_OFFSET (300)
@@ -44,6 +45,7 @@
#define MAX_SATELLITES_IN_USE 12
#define MSEC_IN_ONE_WEEK 604800000ULL
#define UTC_GPS_OFFSET_MSECS 315964800000ULL
#define MAX_TAG_BLOCK_GROUP_CODE (99999)
// GNSS system id according to NMEA spec
#define SYSTEM_ID_GPS 1
@@ -113,7 +115,7 @@
typedef struct loc_nmea_sv_meta_s
{
char talker[3];
LocGnssConstellationType svType;
uint32_t svTypeMask;
uint64_t mask;
uint32_t svCount;
uint32_t totalSvUsedCount;
@@ -139,6 +141,7 @@ typedef struct loc_sv_cache_info_s
uint32_t gal_e5_count;
uint32_t gal_e5b_count;
uint32_t qzss_l1_count;
uint32_t qzss_l2_count;
uint32_t qzss_l5_count;
uint32_t bds_b1i_count;
uint32_t bds_b1c_count;
@@ -291,6 +294,7 @@ static uint32_t convert_signalType_to_signalId(GnssSignalTypeMask signalType)
switch (signalType) {
case GNSS_SIGNAL_GPS_L1CA:
case GNSS_SIGNAL_SBAS_L1:
signalId = SIGNAL_ID_GPS_L1CA;
break;
case GNSS_SIGNAL_GPS_L2:
@@ -403,7 +407,7 @@ static loc_nmea_sv_meta* loc_nmea_sv_meta_init(loc_nmea_sv_meta& sv_meta,
bool needCombine)
{
memset(&sv_meta, 0, sizeof(sv_meta));
sv_meta.svType = svType;
sv_meta.svTypeMask = (1 << svType);
switch (svType)
{
@@ -412,12 +416,17 @@ static loc_nmea_sv_meta* loc_nmea_sv_meta_init(loc_nmea_sv_meta& sv_meta,
sv_meta.talker[1] = 'P';
sv_meta.mask = sv_cache_info.gps_used_mask;
sv_meta.systemId = SYSTEM_ID_GPS;
if (GNSS_SIGNAL_GPS_L1CA == signalType) {
sv_meta.svCount = sv_cache_info.gps_l1_count;
} else if (GNSS_SIGNAL_GPS_L5 == signalType) {
sv_meta.svCount = sv_cache_info.gps_l5_count;
} else if (GNSS_SIGNAL_GPS_L2 == signalType) {
sv_meta.svCount = sv_cache_info.gps_l2_count;
sv_meta.svTypeMask |= (1 << GNSS_SV_TYPE_SBAS);
switch (signalType) {
case GNSS_SIGNAL_GPS_L1CA:
sv_meta.svCount = sv_cache_info.gps_l1_count;
break;
case GNSS_SIGNAL_GPS_L5:
sv_meta.svCount = sv_cache_info.gps_l5_count;
break;
case GNSS_SIGNAL_GPS_L2:
sv_meta.svCount = sv_cache_info.gps_l2_count;
break;
}
break;
case GNSS_SV_TYPE_GLONASS:
@@ -427,10 +436,13 @@ static loc_nmea_sv_meta* loc_nmea_sv_meta_init(loc_nmea_sv_meta& sv_meta,
// GLONASS SV ids are from 65-96
sv_meta.svIdOffset = GLONASS_SV_ID_OFFSET;
sv_meta.systemId = SYSTEM_ID_GLONASS;
if (GNSS_SIGNAL_GLONASS_G1 == signalType) {
sv_meta.svCount = sv_cache_info.glo_g1_count;
} else if (GNSS_SIGNAL_GLONASS_G2 == signalType) {
sv_meta.svCount = sv_cache_info.glo_g2_count;
switch (signalType) {
case GNSS_SIGNAL_GLONASS_G1:
sv_meta.svCount = sv_cache_info.glo_g1_count;
break;
case GNSS_SIGNAL_GLONASS_G2:
sv_meta.svCount = sv_cache_info.glo_g2_count;
break;
}
break;
case GNSS_SV_TYPE_GALILEO:
@@ -440,12 +452,16 @@ static loc_nmea_sv_meta* loc_nmea_sv_meta_init(loc_nmea_sv_meta& sv_meta,
// GALILEO SV ids are from 301-336, So keep svIdOffset 300
sv_meta.svIdOffset = GALILEO_SV_ID_OFFSET;
sv_meta.systemId = SYSTEM_ID_GALILEO;
if (GNSS_SIGNAL_GALILEO_E1 == signalType) {
sv_meta.svCount = sv_cache_info.gal_e1_count;
} else if (GNSS_SIGNAL_GALILEO_E5A == signalType) {
sv_meta.svCount = sv_cache_info.gal_e5_count;
} else if (GNSS_SIGNAL_GALILEO_E5B == signalType) {
sv_meta.svCount == sv_cache_info.gal_e5b_count;
switch (signalType) {
case GNSS_SIGNAL_GALILEO_E1:
sv_meta.svCount = sv_cache_info.gal_e1_count;
break;
case GNSS_SIGNAL_GALILEO_E5A:
sv_meta.svCount = sv_cache_info.gal_e5_count;
break;
case GNSS_SIGNAL_GALILEO_E5B:
sv_meta.svCount = sv_cache_info.gal_e5b_count;
break;
}
break;
case GNSS_SV_TYPE_QZSS:
@@ -455,10 +471,16 @@ static loc_nmea_sv_meta* loc_nmea_sv_meta_init(loc_nmea_sv_meta& sv_meta,
// QZSS SV ids are from 193-199. So keep svIdOffset 192
sv_meta.svIdOffset = QZSS_SV_ID_OFFSET;
sv_meta.systemId = SYSTEM_ID_QZSS;
if (GNSS_SIGNAL_QZSS_L1CA == signalType) {
sv_meta.svCount = sv_cache_info.qzss_l1_count;
} else if (GNSS_SIGNAL_QZSS_L5 == signalType) {
sv_meta.svCount = sv_cache_info.qzss_l5_count;
switch (signalType) {
case GNSS_SIGNAL_QZSS_L1CA:
sv_meta.svCount = sv_cache_info.qzss_l1_count;
break;
case GNSS_SIGNAL_QZSS_L2:
sv_meta.svCount = sv_cache_info.qzss_l2_count;
break;
case GNSS_SIGNAL_QZSS_L5:
sv_meta.svCount = sv_cache_info.qzss_l5_count;
break;
}
break;
case GNSS_SV_TYPE_BEIDOU:
@@ -468,12 +490,16 @@ static loc_nmea_sv_meta* loc_nmea_sv_meta_init(loc_nmea_sv_meta& sv_meta,
// BDS SV ids are from 201-237. So keep svIdOffset 200
sv_meta.svIdOffset = BDS_SV_ID_OFFSET;
sv_meta.systemId = SYSTEM_ID_BDS;
if (GNSS_SIGNAL_BEIDOU_B1I == signalType) {
sv_meta.svCount = sv_cache_info.bds_b1i_count;
} else if (GNSS_SIGNAL_BEIDOU_B1C == signalType) {
sv_meta.svCount = sv_cache_info.bds_b1c_count;
} else if (GNSS_SIGNAL_BEIDOU_B2AI == signalType) {
sv_meta.svCount = sv_cache_info.bds_b2_count;
switch (signalType) {
case GNSS_SIGNAL_BEIDOU_B1I:
sv_meta.svCount = sv_cache_info.bds_b1i_count;
break;
case GNSS_SIGNAL_BEIDOU_B1C:
sv_meta.svCount = sv_cache_info.bds_b1c_count;
break;
case GNSS_SIGNAL_BEIDOU_B2AI:
sv_meta.svCount = sv_cache_info.bds_b2_count;
break;
}
break;
case GNSS_SV_TYPE_NAVIC:
@@ -483,8 +509,10 @@ static loc_nmea_sv_meta* loc_nmea_sv_meta_init(loc_nmea_sv_meta& sv_meta,
// NAVIC SV ids are from 401-414. So keep svIdOffset 400
sv_meta.svIdOffset = NAVIC_SV_ID_OFFSET;
sv_meta.systemId = SYSTEM_ID_NAVIC;
if (GNSS_SIGNAL_NAVIC_L5 == signalType) {
sv_meta.svCount = sv_cache_info.navic_l5_count;
switch (signalType) {
case GNSS_SIGNAL_NAVIC_L5:
sv_meta.svCount = sv_cache_info.navic_l5_count;
break;
}
break;
default:
@@ -539,23 +567,28 @@ SIDE EFFECTS
N/A
===========================================================================*/
static int loc_nmea_put_checksum(char *pNmea, int maxSize)
static int loc_nmea_put_checksum(char *pNmea, int maxSize, bool isTagBlock)
{
uint8_t checksum = 0;
int length = 0;
int checksumLength = 0;
if(NULL == pNmea)
return 0;
pNmea++; //skip the $
pNmea++; //skip the $ or / for Tag Block
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);
if (isTagBlock) {
// length now contains tag block sentence string length not including / sign.
checksumLength = snprintf(pNmea, (maxSize-length-1), "*%02X\\", checksum);
} else {
// length now contains nmea sentence string length not including $ sign.
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);
@@ -586,7 +619,8 @@ static uint32_t loc_nmea_generate_GSA(const GpsLocationExtended &locationExtende
char* sentence,
int bufSize,
loc_nmea_sv_meta* sv_meta_p,
std::vector<std::string> &nmeaArraystr)
std::vector<std::string> &nmeaArraystr,
bool isTagBlockGroupingEnabled)
{
if (!sentence || bufSize <= 0 || !sv_meta_p)
{
@@ -597,9 +631,14 @@ static uint32_t loc_nmea_generate_GSA(const GpsLocationExtended &locationExtende
char* pMarker = sentence;
int lengthRemaining = bufSize;
int length = 0;
int lengthTagBlock = 0;
uint32_t svUsedCount = 0;
uint32_t svUsedList[64] = {0};
uint32_t sentenceCount = 0;
uint32_t sentenceNumber = 1;
size_t svNumber = 1;
static uint32_t code = 1;
char fixType = '\0';
@@ -607,7 +646,7 @@ static uint32_t loc_nmea_generate_GSA(const GpsLocationExtended &locationExtende
uint32_t svIdOffset = sv_meta_p->svIdOffset;
uint64_t mask = sv_meta_p->mask;
if(sv_meta_p->svType != GNSS_SV_TYPE_GLONASS) {
if (!(sv_meta_p->svTypeMask & (1 << GNSS_SV_TYPE_GLONASS))) {
svIdOffset = 0;
}
@@ -618,77 +657,98 @@ static uint32_t loc_nmea_generate_GSA(const GpsLocationExtended &locationExtende
mask = mask >> 1;
}
if (svUsedCount == 0)
return 0;
if (sv_meta_p->totalSvUsedCount == 0)
fixType = '1'; // no fix
else if (sv_meta_p->totalSvUsedCount <= 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,s*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
// s : GNSS System Id
// cc : Checksum value
length = snprintf(pMarker, lengthRemaining, "$%sGSA,A,%c,", talker, fixType);
if (length < 0 || length >= lengthRemaining)
{
LOC_LOGE("NMEA Error in string formatting");
if (svUsedCount == 0) {
return 0;
} else {
sentenceNumber = 1;
sentenceCount = svUsedCount / 12 + (svUsedCount % 12 != 0);
svNumber = 1;
}
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]);
while (sentenceNumber <= sentenceCount) {
pMarker = sentence;
lengthRemaining = bufSize;
if (svUsedCount > 12 && isTagBlockGroupingEnabled) {
lengthTagBlock = snprintf(pMarker, lengthRemaining, "\\g:%d-%d-%d", sentenceNumber,
sentenceCount, code);
if (MAX_TAG_BLOCK_GROUP_CODE == code) {
code = 1;
}
lengthTagBlock = loc_nmea_put_checksum(sentence, bufSize, true);
pMarker += lengthTagBlock;
lengthRemaining -= lengthTagBlock;
}
if (sv_meta_p->totalSvUsedCount == 0)
fixType = '1'; // no fix
else if (sv_meta_p->totalSvUsedCount <= 3)
fixType = '2'; // 2D fix
else
length = snprintf(pMarker, lengthRemaining, ",");
fixType = '3'; // 3D fix
if (length < 0 || length >= lengthRemaining)
{
// 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,s*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
// s : GNSS System Id
// 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 12 satellite IDs
for (uint8_t i = 0; i < 12; i++, svNumber++)
{
if (svNumber <= svUsedCount)
length = snprintf(pMarker, lengthRemaining, "%02d,", svUsedList[svNumber - 1]);
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 + lengthTagBlock, bufSize - lengthTagBlock, false);
nmeaArraystr.push_back(sentence);
sentenceNumber++;
if (!isTagBlockGroupingEnabled) {
break;
}
}
// 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);
if (svUsedCount > 12 && isTagBlockGroupingEnabled) {
code++;
}
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;
}
@@ -740,7 +800,7 @@ static void loc_nmea_generate_GSV(const GnssSvNotification &svNotify,
return;
}
if (GNSS_SV_TYPE_GLONASS == sv_meta_p->svType) {
if ((1 << GNSS_SV_TYPE_GLONASS) & sv_meta_p->svTypeMask) {
svIdOffset = 0;
}
svNumber = 1;
@@ -798,14 +858,23 @@ static void loc_nmea_generate_GSV(const GnssSvNotification &svNotify,
}
}
if (sv_meta_p->svType == svNotify.gnssSvs[svNumber - 1].type &&
if ((sv_meta_p->svTypeMask & (1 << svNotify.gnssSvs[svNumber - 1].type)) &&
sv_meta_p->signalId == convert_signalType_to_signalId(signalType))
{
length = snprintf(pMarker, lengthRemaining,",%02d,%02d,%03d,",
if (GNSS_SV_TYPE_SBAS == svNotify.gnssSvs[svNumber - 1].type) {
svIdOffset = SBAS_SV_ID_OFFSET;
}
if (GNSS_SV_TYPE_GLONASS == svNotify.gnssSvs[svNumber - 1].type &&
GLO_SV_PRN_SLOT_UNKNOWN == svNotify.gnssSvs[svNumber - 1].svId) {
length = snprintf(pMarker, lengthRemaining, ",,%02d,%03d,",
(int)(0.5 + svNotify.gnssSvs[svNumber - 1].elevation), //float to int
(int)(0.5 + svNotify.gnssSvs[svNumber - 1].azimuth)); //float to int
} else {
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");
@@ -838,7 +907,7 @@ static void loc_nmea_generate_GSV(const GnssSvNotification &svNotify,
pMarker += length;
lengthRemaining -= length;
length = loc_nmea_put_checksum(sentence, bufSize);
length = loc_nmea_put_checksum(sentence, bufSize, false);
nmeaArraystr.push_back(sentence);
sentenceNumber++;
@@ -947,7 +1016,7 @@ static void loc_nmea_generate_DTM(const LocLla &ref_lla,
pMarker += length;
lengthRemaining -= length;
length = loc_nmea_put_checksum(sentence, bufSize);
length = loc_nmea_put_checksum(sentence, bufSize, false);
}
/*===========================================================================
@@ -1059,17 +1128,6 @@ static void loc_nmea_get_fix_quality(const UlpLocation & location,
memset(gnsModeIndicator, 'N', 6); // N means no fix
gnsModeIndicator[6] = '\0';
do {
// GGA fix quality is defined in NMEA spec as below:
// https://www.trimble.com/OEM_ReceiverHelp/V4.44/en/NMEA-0183messages_GGA.html
// Fix quality: 0 = invalid
// 1 = GPS fix (SPS)
// 2 = DGPS fix
// 3 = PPS fix
// 4 = Real Time Kinematic
// 5 = Float RTK
// 6 = estimated (dead reckoning) (2.3 feature)
// 7 = Manual input mode
// 8 = Simulation mode
if (!(location.gpsLocation.flags & LOC_GPS_LOCATION_HAS_LAT_LONG)){
break;
}
@@ -1274,7 +1332,8 @@ void loc_nmea_generate_pos(const UlpLocation &location,
unsigned char generate_nmea,
bool custom_gga_fix_quality,
std::vector<std::string> &nmeaArraystr,
int& indexOfGGA)
int& indexOfGGA,
bool isTagBlockGroupingEnabled)
{
ENTRY_LOG();
@@ -1355,7 +1414,7 @@ void loc_nmea_generate_pos(const UlpLocation &location,
count = loc_nmea_generate_GSA(locationExtended, sentence, sizeof(sentence),
loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_GPS,
GNSS_SIGNAL_GPS_L1CA, true), nmeaArraystr);
GNSS_SIGNAL_GPS_L1CA, true), nmeaArraystr, isTagBlockGroupingEnabled);
if (count > 0)
{
svUsedCount += count;
@@ -1369,7 +1428,7 @@ void loc_nmea_generate_pos(const UlpLocation &location,
count = loc_nmea_generate_GSA(locationExtended, sentence, sizeof(sentence),
loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_GLONASS,
GNSS_SIGNAL_GLONASS_G1, true), nmeaArraystr);
GNSS_SIGNAL_GLONASS_G1, true), nmeaArraystr, isTagBlockGroupingEnabled);
if (count > 0)
{
svUsedCount += count;
@@ -1383,7 +1442,7 @@ void loc_nmea_generate_pos(const UlpLocation &location,
count = loc_nmea_generate_GSA(locationExtended, sentence, sizeof(sentence),
loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_GALILEO,
GNSS_SIGNAL_GALILEO_E1, true), nmeaArraystr);
GNSS_SIGNAL_GALILEO_E1, true), nmeaArraystr, isTagBlockGroupingEnabled);
if (count > 0)
{
svUsedCount += count;
@@ -1396,7 +1455,7 @@ void loc_nmea_generate_pos(const UlpLocation &location,
// ----------------------------
count = loc_nmea_generate_GSA(locationExtended, sentence, sizeof(sentence),
loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_BEIDOU,
GNSS_SIGNAL_BEIDOU_B1I, true), nmeaArraystr);
GNSS_SIGNAL_BEIDOU_B1I, true), nmeaArraystr, isTagBlockGroupingEnabled);
if (count > 0)
{
svUsedCount += count;
@@ -1410,7 +1469,7 @@ void loc_nmea_generate_pos(const UlpLocation &location,
count = loc_nmea_generate_GSA(locationExtended, sentence, sizeof(sentence),
loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_QZSS,
GNSS_SIGNAL_QZSS_L1CA, true), nmeaArraystr);
GNSS_SIGNAL_QZSS_L1CA, true), nmeaArraystr, isTagBlockGroupingEnabled);
if (count > 0)
{
svUsedCount += count;
@@ -1422,7 +1481,7 @@ void loc_nmea_generate_pos(const UlpLocation &location,
// in this case, generate an empty GSA sentence
if (svUsedCount == 0) {
strlcpy(sentence, "$GPGSA,A,1,,,,,,,,,,,,,,,,", sizeof(sentence));
length = loc_nmea_put_checksum(sentence, sizeof(sentence));
length = loc_nmea_put_checksum(sentence, sizeof(sentence), false);
nmeaArraystr.push_back(sentence);
}
@@ -1445,7 +1504,7 @@ void loc_nmea_generate_pos(const UlpLocation &location,
float magTrack = location.gpsLocation.bearing;
if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_MAG_DEV)
{
float magTrack = location.gpsLocation.bearing - locationExtended.magneticDeviation;
magTrack = location.gpsLocation.bearing - locationExtended.magneticDeviation;
if (magTrack < 0.0)
magTrack += 360.0;
else if (magTrack > 360.0)
@@ -1489,7 +1548,7 @@ void loc_nmea_generate_pos(const UlpLocation &location,
length = snprintf(pMarker, lengthRemaining, "%c", vtgModeIndicator);
length = loc_nmea_put_checksum(sentence, sizeof(sentence));
length = loc_nmea_put_checksum(sentence, sizeof(sentence), false);
nmeaArraystr.push_back(sentence);
memset(&ecef_w84, 0, sizeof(ecef_w84));
@@ -1693,7 +1752,7 @@ void loc_nmea_generate_pos(const UlpLocation &location,
// hardcode Navigation Status field to 'V'
length = snprintf(pMarker, lengthRemaining, ",%c", 'V');
length = loc_nmea_put_checksum(sentence_RMC, sizeof(sentence_RMC));
length = loc_nmea_put_checksum(sentence_RMC, sizeof(sentence_RMC), false);
// -------------------
// ------$--GNS-------
@@ -1855,7 +1914,7 @@ void loc_nmea_generate_pos(const UlpLocation &location,
pMarker += length;
lengthRemaining -= length;
length = loc_nmea_put_checksum(sentence_GNS, sizeof(sentence_GNS));
length = loc_nmea_put_checksum(sentence_GNS, sizeof(sentence_GNS), false);
// -------------------
// ------$--GGA-------
@@ -2012,7 +2071,7 @@ void loc_nmea_generate_pos(const UlpLocation &location,
lengthRemaining -= length;
}
length = loc_nmea_put_checksum(sentence_GGA, sizeof(sentence_GGA));
length = loc_nmea_put_checksum(sentence_GGA, sizeof(sentence_GGA), false);
// ------$--DTM-------
nmeaArraystr.push_back(sentence_DTM);
@@ -2035,27 +2094,27 @@ void loc_nmea_generate_pos(const UlpLocation &location,
//Send blank NMEA reports for non-final fixes
else {
strlcpy(sentence, "$GPGSA,A,1,,,,,,,,,,,,,,,,", sizeof(sentence));
length = loc_nmea_put_checksum(sentence, sizeof(sentence));
length = loc_nmea_put_checksum(sentence, sizeof(sentence), false);
nmeaArraystr.push_back(sentence);
strlcpy(sentence, "$GPVTG,,T,,M,,N,,K,N", sizeof(sentence));
length = loc_nmea_put_checksum(sentence, sizeof(sentence));
length = loc_nmea_put_checksum(sentence, sizeof(sentence), false);
nmeaArraystr.push_back(sentence);
strlcpy(sentence, "$GPDTM,,,,,,,,", sizeof(sentence));
length = loc_nmea_put_checksum(sentence, sizeof(sentence));
length = loc_nmea_put_checksum(sentence, sizeof(sentence), false);
nmeaArraystr.push_back(sentence);
strlcpy(sentence, "$GPRMC,,V,,,,,,,,,,N,V", sizeof(sentence));
length = loc_nmea_put_checksum(sentence, sizeof(sentence));
length = loc_nmea_put_checksum(sentence, sizeof(sentence), false);
nmeaArraystr.push_back(sentence);
strlcpy(sentence, "$GPGNS,,,,,,N,,,,,,,V", sizeof(sentence));
length = loc_nmea_put_checksum(sentence, sizeof(sentence));
length = loc_nmea_put_checksum(sentence, sizeof(sentence), false);
nmeaArraystr.push_back(sentence);
strlcpy(sentence, "$GPGGA,,,,,,0,,,,,,,,", sizeof(sentence));
length = loc_nmea_put_checksum(sentence, sizeof(sentence));
length = loc_nmea_put_checksum(sentence, sizeof(sentence), false);
nmeaArraystr.push_back(sentence);
}
@@ -2090,14 +2149,15 @@ void loc_nmea_generate_sv(const GnssSvNotification &svNotify,
//Count GPS SVs for saparating GPS from GLONASS and throw others
for (uint32_t svOffset = 0; svOffset < svNotify.count; svOffset++) {
if (GNSS_SV_TYPE_GPS == svNotify.gnssSvs[svOffset].type)
if ((GNSS_SV_TYPE_GPS == svNotify.gnssSvs[svOffset].type) ||
(GNSS_SV_TYPE_SBAS == svNotify.gnssSvs[svOffset].type))
{
if (GNSS_SIGNAL_GPS_L5 == svNotify.gnssSvs[svOffset].gnssSignalTypeMask) {
sv_cache_info.gps_l5_count++;
} else if (GNSS_SIGNAL_GPS_L2 == svNotify.gnssSvs[svOffset].gnssSignalTypeMask) {
sv_cache_info.gps_l2_count++;
} else {
// GNSS_SIGNAL_GPS_L1CA or default
// GNSS_SIGNAL_GPS_L1CA, GNSS_SIGNAL_SBAS_L1 or default
// If no signal type in report, it means default L1
sv_cache_info.gps_l1_count++;
}
@@ -2128,6 +2188,8 @@ void loc_nmea_generate_sv(const GnssSvNotification &svNotify,
{
if (GNSS_SIGNAL_QZSS_L5 == svNotify.gnssSvs[svOffset].gnssSignalTypeMask) {
sv_cache_info.qzss_l5_count++;
} else if (GNSS_SIGNAL_QZSS_L2 == svNotify.gnssSvs[svOffset].gnssSignalTypeMask) {
sv_cache_info.qzss_l2_count++;
} else {
// GNSS_SIGNAL_QZSS_L1CA or default
// If no signal type in report, it means default L1
@@ -2136,6 +2198,14 @@ void loc_nmea_generate_sv(const GnssSvNotification &svNotify,
}
else if (GNSS_SV_TYPE_BEIDOU == svNotify.gnssSvs[svOffset].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[svOffset].gnssSvOptionsMask &
GNSS_SV_OPTIONS_USED_IN_FIX_BIT))
{
setSvMask(sv_cache_info.bds_used_mask, svNotify.gnssSvs[svOffset].svId);
}
if ((GNSS_SIGNAL_BEIDOU_B2AI == svNotify.gnssSvs[svOffset].gnssSignalTypeMask) ||
(GNSS_SIGNAL_BEIDOU_B2AQ == svNotify.gnssSvs[svOffset].gnssSignalTypeMask)) {
sv_cache_info.bds_b2_count++;
@@ -2231,6 +2301,16 @@ void loc_nmea_generate_sv(const GnssSvNotification &svNotify,
loc_nmea_generate_GSV(svNotify, sentence, sizeof(sentence),
loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_QZSS,
GNSS_SIGNAL_QZSS_L5, false), nmeaArraystr);
// -----------------------------
// ------$GQGSV (QZSS):L2-------
// -----------------------------
loc_nmea_generate_GSV(svNotify, sentence, sizeof(sentence),
loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_QZSS,
GNSS_SIGNAL_QZSS_L2, false), nmeaArraystr);
// -----------------------------
// ------$GBGSV (BEIDOU:B1I)----
// -----------------------------
@@ -2242,6 +2322,7 @@ void loc_nmea_generate_sv(const GnssSvNotification &svNotify,
// -----------------------------
// ------$GBGSV (BEIDOU:B1C)----
// -----------------------------
loc_nmea_generate_GSV(svNotify, sentence, sizeof(sentence),
loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_BEIDOU,
GNSS_SIGNAL_BEIDOU_B1C, false), nmeaArraystr);

View File

@@ -81,7 +81,8 @@ void loc_nmea_generate_pos(const UlpLocation &location,
unsigned char generate_nmea,
bool custom_gga_fix_quality,
std::vector<std::string> &nmeaArraystr,
int& indexOfGGA);
int& indexOfGGA,
bool isTagBlockGroupingEnabled);
#define DEBUG_NMEA_MINSIZE 6
#define DEBUG_NMEA_MAXSIZE 4096

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2011-2014 The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-2014, 2020 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -32,7 +32,6 @@
#include <stdbool.h>
#include <loc_pla.h>
#if defined (USE_ANDROID_LOGGING) || defined (ANDROID)
// Android and LE targets with logcat support
#include <utils/Log.h>
@@ -53,7 +52,7 @@
#endif /* LOG_TAG */
// LE targets with no logcat support
#ifdef FEATURE_EXTERNAL_AP
#if defined(FEATURE_EXTERNAL_AP) || defined(USE_SYSLOG_LOGGING)
#include <syslog.h>
#define ALOGE(...) syslog(LOG_ERR, "LOC_LOGE: " __VA_ARGS__);
#define ALOGW(...) syslog(LOG_WARNING, "LOC_LOGW: " __VA_ARGS__);
@@ -160,10 +159,10 @@ inline void loc_logger_init(unsigned long debug, unsigned long timestamp)
inline void log_buffer_init(bool enabled) {
loc_logger.LOG_BUFFER_ENABLE = enabled;
}
extern void log_tag_level_map_init();
extern int get_tag_log_level(const char* tag);
extern char* get_timestamp(char* str, unsigned long buf_size);
extern void log_buffer_insert(char *str, unsigned long buf_size, int level);
/*=============================================================================
*
* LOGGING BUFFER MACROS
@@ -196,11 +195,28 @@ extern void log_buffer_insert(char *str, unsigned long buf_size, int level);
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))
/* Tag based logging control MACROS */
/* The logic is like this:
* 1, LOCAL_LOG_LEVEL is defined as a static variable in log_util.h,
* then all source files which includes log_util.h will have its own LOCAL_LOG_LEVEL variable;
* 2, For each source file,
* 2.1, First time when LOC_LOG* is invoked(its LOCAL_LOG_LEVEL == -1),
* Set the tag based log level according to the <tag, level> map;
* If this tag isn't found in map, set local debug level as global loc_logger.DEBUG_LEVEL;
* 2.2, If not the first time, use its LOCAL_LOG_LEVEL as the debug level of this tag.
*/
static int LOCAL_LOG_LEVEL = -1;
#define IF_LOC_LOG(x) \
if (((LOCAL_LOG_LEVEL == -1 && (LOCAL_LOG_LEVEL = get_tag_log_level(LOG_TAG)) >= x) ||\
LOCAL_LOG_LEVEL >= x) && LOCAL_LOG_LEVEL <= 5)
#define IF_LOC_LOGE IF_LOC_LOG(1)
#define IF_LOC_LOGW IF_LOC_LOG(2)
#define IF_LOC_LOGI IF_LOC_LOG(3)
#define IF_LOC_LOGD IF_LOC_LOG(4)
#define IF_LOC_LOGV IF_LOC_LOG(5)
#define LOC_LOGE(...) IF_LOC_LOGE { ALOGE(__VA_ARGS__); INSERT_BUFFER(LOG_NDEBUG, 0, __VA_ARGS__);}
#define LOC_LOGW(...) IF_LOC_LOGW { ALOGW(__VA_ARGS__); INSERT_BUFFER(LOG_NDEBUG, 1, __VA_ARGS__);}