sanders: gps: switch to LA.UM.6.6.r1-04300-89xx.0 branch
This commit is contained in:
912
gps/gnss/Agps.cpp
Normal file
912
gps/gnss/Agps.cpp
Normal file
@@ -0,0 +1,912 @@
|
||||
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation, nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#define LOG_TAG "LocSvc_Agps"
|
||||
|
||||
#include <Agps.h>
|
||||
#include <platform_lib_includes.h>
|
||||
#include <ContextBase.h>
|
||||
#include <loc_timer.h>
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* AGPS State Machine Methods
|
||||
* -------------------------------------------------------------------*/
|
||||
void AgpsStateMachine::processAgpsEvent(AgpsEvent event){
|
||||
|
||||
LOC_LOGD("processAgpsEvent(): SM %p, Event %d, State %d",
|
||||
this, event, mState);
|
||||
|
||||
switch (event) {
|
||||
|
||||
case AGPS_EVENT_SUBSCRIBE:
|
||||
processAgpsEventSubscribe();
|
||||
break;
|
||||
|
||||
case AGPS_EVENT_UNSUBSCRIBE:
|
||||
processAgpsEventUnsubscribe();
|
||||
break;
|
||||
|
||||
case AGPS_EVENT_GRANTED:
|
||||
processAgpsEventGranted();
|
||||
break;
|
||||
|
||||
case AGPS_EVENT_RELEASED:
|
||||
processAgpsEventReleased();
|
||||
break;
|
||||
|
||||
case AGPS_EVENT_DENIED:
|
||||
processAgpsEventDenied();
|
||||
break;
|
||||
|
||||
default:
|
||||
LOC_LOGE("Invalid Loc Agps Event");
|
||||
}
|
||||
}
|
||||
|
||||
void AgpsStateMachine::processAgpsEventSubscribe(){
|
||||
|
||||
switch (mState) {
|
||||
|
||||
case AGPS_STATE_RELEASED:
|
||||
/* Add subscriber to list
|
||||
* No notifications until we get RSRC_GRANTED */
|
||||
addSubscriber(mCurrentSubscriber);
|
||||
|
||||
/* Send data request
|
||||
* The if condition below is added so that if the data call setup
|
||||
* fails for DS State Machine, we want to retry in released state.
|
||||
* for Agps State Machine, sendRsrcRequest() will always return
|
||||
* success. */
|
||||
if (requestOrReleaseDataConn(true) == 0) {
|
||||
// If data request successful, move to pending state
|
||||
transitionState(AGPS_STATE_PENDING);
|
||||
}
|
||||
break;
|
||||
|
||||
case AGPS_STATE_PENDING:
|
||||
/* Already requested for data connection,
|
||||
* do nothing until we get RSRC_GRANTED event;
|
||||
* Just add this subscriber to the list, for notifications */
|
||||
addSubscriber(mCurrentSubscriber);
|
||||
break;
|
||||
|
||||
case AGPS_STATE_ACQUIRED:
|
||||
/* We already have the data connection setup,
|
||||
* Notify current subscriber with GRANTED event,
|
||||
* And add it to the subscriber list for further notifications. */
|
||||
notifyEventToSubscriber(AGPS_EVENT_GRANTED, mCurrentSubscriber, false);
|
||||
addSubscriber(mCurrentSubscriber);
|
||||
break;
|
||||
|
||||
case AGPS_STATE_RELEASING:
|
||||
addSubscriber(mCurrentSubscriber);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOC_LOGE("Invalid state: %d", mState);
|
||||
}
|
||||
}
|
||||
|
||||
void AgpsStateMachine::processAgpsEventUnsubscribe(){
|
||||
|
||||
switch (mState) {
|
||||
|
||||
case AGPS_STATE_RELEASED:
|
||||
notifyEventToSubscriber(
|
||||
AGPS_EVENT_UNSUBSCRIBE, mCurrentSubscriber, false);
|
||||
break;
|
||||
|
||||
case AGPS_STATE_PENDING:
|
||||
case AGPS_STATE_ACQUIRED:
|
||||
/* If the subscriber wishes to wait for connection close,
|
||||
* before being removed from list, move to inactive state
|
||||
* and notify */
|
||||
if (mCurrentSubscriber->mWaitForCloseComplete) {
|
||||
mCurrentSubscriber->mIsInactive = true;
|
||||
}
|
||||
else {
|
||||
/* Notify only current subscriber and then delete it from
|
||||
* subscriberList */
|
||||
notifyEventToSubscriber(
|
||||
AGPS_EVENT_UNSUBSCRIBE, mCurrentSubscriber, true);
|
||||
}
|
||||
|
||||
/* If no subscribers in list, release data connection */
|
||||
if (mSubscriberList.empty()) {
|
||||
transitionState(AGPS_STATE_RELEASED);
|
||||
requestOrReleaseDataConn(false);
|
||||
}
|
||||
/* Some subscribers in list, but all inactive;
|
||||
* Release data connection */
|
||||
else if(!anyActiveSubscribers()) {
|
||||
transitionState(AGPS_STATE_RELEASING);
|
||||
requestOrReleaseDataConn(false);
|
||||
}
|
||||
break;
|
||||
|
||||
case AGPS_STATE_RELEASING:
|
||||
/* If the subscriber wishes to wait for connection close,
|
||||
* before being removed from list, move to inactive state
|
||||
* and notify */
|
||||
if (mCurrentSubscriber->mWaitForCloseComplete) {
|
||||
mCurrentSubscriber->mIsInactive = true;
|
||||
}
|
||||
else {
|
||||
/* Notify only current subscriber and then delete it from
|
||||
* subscriberList */
|
||||
notifyEventToSubscriber(
|
||||
AGPS_EVENT_UNSUBSCRIBE, mCurrentSubscriber, true);
|
||||
}
|
||||
|
||||
/* If no subscribers in list, just move the state.
|
||||
* Request for releasing data connection should already have been
|
||||
* sent */
|
||||
if (mSubscriberList.empty()) {
|
||||
transitionState(AGPS_STATE_RELEASED);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
LOC_LOGE("Invalid state: %d", mState);
|
||||
}
|
||||
}
|
||||
|
||||
void AgpsStateMachine::processAgpsEventGranted(){
|
||||
|
||||
switch (mState) {
|
||||
|
||||
case AGPS_STATE_RELEASED:
|
||||
case AGPS_STATE_ACQUIRED:
|
||||
case AGPS_STATE_RELEASING:
|
||||
LOC_LOGE("Unexpected event GRANTED in state %d", mState);
|
||||
break;
|
||||
|
||||
case AGPS_STATE_PENDING:
|
||||
// Move to acquired state
|
||||
transitionState(AGPS_STATE_ACQUIRED);
|
||||
notifyAllSubscribers(
|
||||
AGPS_EVENT_GRANTED, false,
|
||||
AGPS_NOTIFICATION_TYPE_FOR_ACTIVE_SUBSCRIBERS);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOC_LOGE("Invalid state: %d", mState);
|
||||
}
|
||||
}
|
||||
|
||||
void AgpsStateMachine::processAgpsEventReleased(){
|
||||
|
||||
switch (mState) {
|
||||
|
||||
case AGPS_STATE_RELEASED:
|
||||
/* Subscriber list should be empty if we are in released state */
|
||||
if (!mSubscriberList.empty()) {
|
||||
LOC_LOGE("Unexpected event RELEASED in RELEASED state");
|
||||
}
|
||||
break;
|
||||
|
||||
case AGPS_STATE_ACQUIRED:
|
||||
/* Force release received */
|
||||
LOC_LOGW("Force RELEASED event in ACQUIRED state");
|
||||
transitionState(AGPS_STATE_RELEASED);
|
||||
notifyAllSubscribers(
|
||||
AGPS_EVENT_RELEASED, true,
|
||||
AGPS_NOTIFICATION_TYPE_FOR_ALL_SUBSCRIBERS);
|
||||
break;
|
||||
|
||||
case AGPS_STATE_RELEASING:
|
||||
/* Notify all inactive subscribers about the event */
|
||||
notifyAllSubscribers(
|
||||
AGPS_EVENT_RELEASED, true,
|
||||
AGPS_NOTIFICATION_TYPE_FOR_INACTIVE_SUBSCRIBERS);
|
||||
|
||||
/* If we have active subscribers now, they must be waiting for
|
||||
* data conn setup */
|
||||
if (anyActiveSubscribers()) {
|
||||
transitionState(AGPS_STATE_PENDING);
|
||||
requestOrReleaseDataConn(true);
|
||||
}
|
||||
/* No active subscribers, move to released state */
|
||||
else {
|
||||
transitionState(AGPS_STATE_RELEASED);
|
||||
}
|
||||
break;
|
||||
|
||||
case AGPS_STATE_PENDING:
|
||||
/* NOOP */
|
||||
break;
|
||||
|
||||
default:
|
||||
LOC_LOGE("Invalid state: %d", mState);
|
||||
}
|
||||
}
|
||||
|
||||
void AgpsStateMachine::processAgpsEventDenied(){
|
||||
|
||||
switch (mState) {
|
||||
|
||||
case AGPS_STATE_RELEASED:
|
||||
LOC_LOGE("Unexpected event DENIED in state %d", mState);
|
||||
break;
|
||||
|
||||
case AGPS_STATE_ACQUIRED:
|
||||
/* NOOP */
|
||||
break;
|
||||
|
||||
case AGPS_STATE_RELEASING:
|
||||
/* Notify all inactive subscribers about the event */
|
||||
notifyAllSubscribers(
|
||||
AGPS_EVENT_RELEASED, true,
|
||||
AGPS_NOTIFICATION_TYPE_FOR_INACTIVE_SUBSCRIBERS);
|
||||
|
||||
/* If we have active subscribers now, they must be waiting for
|
||||
* data conn setup */
|
||||
if (anyActiveSubscribers()) {
|
||||
transitionState(AGPS_STATE_PENDING);
|
||||
requestOrReleaseDataConn(true);
|
||||
}
|
||||
/* No active subscribers, move to released state */
|
||||
else {
|
||||
transitionState(AGPS_STATE_RELEASED);
|
||||
}
|
||||
break;
|
||||
|
||||
case AGPS_STATE_PENDING:
|
||||
transitionState(AGPS_STATE_RELEASED);
|
||||
notifyAllSubscribers(
|
||||
AGPS_EVENT_DENIED, true,
|
||||
AGPS_NOTIFICATION_TYPE_FOR_ALL_SUBSCRIBERS);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOC_LOGE("Invalid state: %d", mState);
|
||||
}
|
||||
}
|
||||
|
||||
/* Request or Release data connection
|
||||
* bool request :
|
||||
* true = Request data connection
|
||||
* false = Release data connection */
|
||||
int AgpsStateMachine::requestOrReleaseDataConn(bool request){
|
||||
|
||||
AGnssExtStatusIpV4 nifRequest;
|
||||
memset(&nifRequest, 0, sizeof(nifRequest));
|
||||
|
||||
nifRequest.type = mAgpsType;
|
||||
|
||||
if (request) {
|
||||
LOC_LOGD("AGPS Data Conn Request");
|
||||
nifRequest.status = LOC_GPS_REQUEST_AGPS_DATA_CONN;
|
||||
}
|
||||
else{
|
||||
LOC_LOGD("AGPS Data Conn Release");
|
||||
nifRequest.status = LOC_GPS_RELEASE_AGPS_DATA_CONN;
|
||||
}
|
||||
|
||||
mAgpsManager->mFrameworkStatusV4Cb(nifRequest);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AgpsStateMachine::notifyAllSubscribers(
|
||||
AgpsEvent event, bool deleteSubscriberPostNotify,
|
||||
AgpsNotificationType notificationType){
|
||||
|
||||
LOC_LOGD("notifyAllSubscribers(): "
|
||||
"SM %p, Event %d Delete %d Notification Type %d",
|
||||
this, event, deleteSubscriberPostNotify, notificationType);
|
||||
|
||||
std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
|
||||
while ( it != mSubscriberList.end() ) {
|
||||
|
||||
AgpsSubscriber* subscriber = *it;
|
||||
|
||||
if (notificationType == AGPS_NOTIFICATION_TYPE_FOR_ALL_SUBSCRIBERS ||
|
||||
(notificationType == AGPS_NOTIFICATION_TYPE_FOR_INACTIVE_SUBSCRIBERS &&
|
||||
subscriber->mIsInactive) ||
|
||||
(notificationType == AGPS_NOTIFICATION_TYPE_FOR_ACTIVE_SUBSCRIBERS &&
|
||||
!subscriber->mIsInactive)) {
|
||||
|
||||
/* Deleting via this call would require another traversal
|
||||
* through subscriber list, inefficient; hence pass in false*/
|
||||
notifyEventToSubscriber(event, subscriber, false);
|
||||
|
||||
if (deleteSubscriberPostNotify) {
|
||||
it = mSubscriberList.erase(it);
|
||||
delete subscriber;
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AgpsStateMachine::notifyEventToSubscriber(
|
||||
AgpsEvent event, AgpsSubscriber* subscriberToNotify,
|
||||
bool deleteSubscriberPostNotify) {
|
||||
|
||||
LOC_LOGD("notifyEventToSubscriber(): "
|
||||
"SM %p, Event %d Subscriber %p Delete %d",
|
||||
this, event, subscriberToNotify, deleteSubscriberPostNotify);
|
||||
|
||||
switch (event) {
|
||||
|
||||
case AGPS_EVENT_GRANTED:
|
||||
mAgpsManager->mAtlOpenStatusCb(
|
||||
subscriberToNotify->mConnHandle, 1, getAPN(),
|
||||
getBearer(), mAgpsType);
|
||||
break;
|
||||
|
||||
case AGPS_EVENT_DENIED:
|
||||
mAgpsManager->mAtlOpenStatusCb(
|
||||
subscriberToNotify->mConnHandle, 0, getAPN(),
|
||||
getBearer(), mAgpsType);
|
||||
break;
|
||||
|
||||
case AGPS_EVENT_UNSUBSCRIBE:
|
||||
case AGPS_EVENT_RELEASED:
|
||||
mAgpsManager->mAtlCloseStatusCb(subscriberToNotify->mConnHandle, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOC_LOGE("Invalid event %d", event);
|
||||
}
|
||||
|
||||
/* Search this subscriber in list and delete */
|
||||
if (deleteSubscriberPostNotify) {
|
||||
deleteSubscriber(subscriberToNotify);
|
||||
}
|
||||
}
|
||||
|
||||
void AgpsStateMachine::transitionState(AgpsState newState){
|
||||
|
||||
LOC_LOGD("transitionState(): SM %p, old %d, new %d",
|
||||
this, mState, newState);
|
||||
|
||||
mState = newState;
|
||||
|
||||
// notify state transitions to all subscribers ?
|
||||
}
|
||||
|
||||
void AgpsStateMachine::addSubscriber(AgpsSubscriber* subscriberToAdd){
|
||||
|
||||
LOC_LOGD("addSubscriber(): SM %p, Subscriber %p",
|
||||
this, subscriberToAdd);
|
||||
|
||||
// Check if subscriber is already present in the current list
|
||||
// If not, then add
|
||||
std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
|
||||
for (; it != mSubscriberList.end(); it++) {
|
||||
AgpsSubscriber* subscriber = *it;
|
||||
if (subscriber->equals(subscriberToAdd)) {
|
||||
LOC_LOGE("Subscriber already in list");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
AgpsSubscriber* cloned = subscriberToAdd->clone();
|
||||
LOC_LOGD("addSubscriber(): cloned subscriber: %p", cloned);
|
||||
mSubscriberList.push_back(cloned);
|
||||
}
|
||||
|
||||
void AgpsStateMachine::deleteSubscriber(AgpsSubscriber* subscriberToDelete){
|
||||
|
||||
LOC_LOGD("deleteSubscriber(): SM %p, Subscriber %p",
|
||||
this, subscriberToDelete);
|
||||
|
||||
std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
|
||||
while ( it != mSubscriberList.end() ) {
|
||||
|
||||
AgpsSubscriber* subscriber = *it;
|
||||
if (subscriber && subscriber->equals(subscriberToDelete)) {
|
||||
|
||||
it = mSubscriberList.erase(it);
|
||||
delete subscriber;
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool AgpsStateMachine::anyActiveSubscribers(){
|
||||
|
||||
std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
|
||||
for (; it != mSubscriberList.end(); it++) {
|
||||
AgpsSubscriber* subscriber = *it;
|
||||
if (!subscriber->mIsInactive) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void AgpsStateMachine::setAPN(char* apn, unsigned int len){
|
||||
|
||||
if (NULL != mAPN) {
|
||||
delete mAPN;
|
||||
}
|
||||
|
||||
if (apn == NULL || len <= 0) {
|
||||
LOC_LOGD("Invalid apn len (%d) or null apn", len);
|
||||
mAPN = NULL;
|
||||
mAPNLen = 0;
|
||||
}
|
||||
|
||||
if (NULL != apn) {
|
||||
mAPN = new char[len+1];
|
||||
if (NULL != mAPN) {
|
||||
memcpy(mAPN, apn, len);
|
||||
mAPN[len] = '\0';
|
||||
mAPNLen = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AgpsSubscriber* AgpsStateMachine::getSubscriber(int connHandle){
|
||||
|
||||
/* Go over the subscriber list */
|
||||
std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
|
||||
for (; it != mSubscriberList.end(); it++) {
|
||||
AgpsSubscriber* subscriber = *it;
|
||||
if (subscriber->mConnHandle == connHandle) {
|
||||
return subscriber;
|
||||
}
|
||||
}
|
||||
|
||||
/* Not found, return NULL */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AgpsSubscriber* AgpsStateMachine::getFirstSubscriber(bool isInactive){
|
||||
|
||||
/* Go over the subscriber list */
|
||||
std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
|
||||
for (; it != mSubscriberList.end(); it++) {
|
||||
AgpsSubscriber* subscriber = *it;
|
||||
if(subscriber->mIsInactive == isInactive) {
|
||||
return subscriber;
|
||||
}
|
||||
}
|
||||
|
||||
/* Not found, return NULL */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void AgpsStateMachine::dropAllSubscribers(){
|
||||
|
||||
LOC_LOGD("dropAllSubscribers(): SM %p", this);
|
||||
|
||||
/* Go over the subscriber list */
|
||||
std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
|
||||
while ( it != mSubscriberList.end() ) {
|
||||
AgpsSubscriber* subscriber = *it;
|
||||
it = mSubscriberList.erase(it);
|
||||
delete subscriber;
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* DS State Machine Methods
|
||||
* -------------------------------------------------------------------*/
|
||||
const int DSStateMachine::MAX_START_DATA_CALL_RETRIES = 4;
|
||||
const int DSStateMachine::DATA_CALL_RETRY_DELAY_MSEC = 500;
|
||||
|
||||
/* Overridden method
|
||||
* DS SM needs to handle one scenario differently */
|
||||
void DSStateMachine::processAgpsEvent(AgpsEvent event) {
|
||||
|
||||
LOC_LOGD("DSStateMachine::processAgpsEvent() %d", event);
|
||||
|
||||
/* DS Client call setup APIs don't return failure/closure separately.
|
||||
* Hence we receive RELEASED event in both cases.
|
||||
* If we are in pending, we should consider RELEASED as DENIED */
|
||||
if (event == AGPS_EVENT_RELEASED && mState == AGPS_STATE_PENDING) {
|
||||
|
||||
LOC_LOGD("Translating RELEASED to DENIED event");
|
||||
event = AGPS_EVENT_DENIED;
|
||||
}
|
||||
|
||||
/* Redirect process to base class */
|
||||
AgpsStateMachine::processAgpsEvent(event);
|
||||
}
|
||||
|
||||
/* Timer Callback
|
||||
* For the retry timer started in case of DS Client call setup failure */
|
||||
void delay_callback(void *callbackData, int result)
|
||||
{
|
||||
LOC_LOGD("delay_callback(): cbData %p", callbackData);
|
||||
|
||||
(void)result;
|
||||
|
||||
if (callbackData == NULL) {
|
||||
LOC_LOGE("delay_callback(): NULL argument received !");
|
||||
return;
|
||||
}
|
||||
DSStateMachine* dsStateMachine = (DSStateMachine *)callbackData;
|
||||
dsStateMachine->retryCallback();
|
||||
}
|
||||
|
||||
/* Invoked from Timer Callback
|
||||
* For the retry timer started in case of DS Client call setup failure */
|
||||
void DSStateMachine :: retryCallback()
|
||||
{
|
||||
LOC_LOGD("DSStateMachine::retryCallback()");
|
||||
|
||||
/* Request SUPL ES
|
||||
* There must be at least one active subscriber in list */
|
||||
AgpsSubscriber* subscriber = getFirstSubscriber(false);
|
||||
if (subscriber == NULL) {
|
||||
|
||||
LOC_LOGE("No active subscriber for DS Client call setup");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send message to retry */
|
||||
mAgpsManager->mSendMsgToAdapterQueueFn(
|
||||
new AgpsMsgRequestATL(
|
||||
mAgpsManager, subscriber->mConnHandle,
|
||||
LOC_AGPS_TYPE_SUPL_ES));
|
||||
}
|
||||
|
||||
/* Overridden method
|
||||
* Request or Release data connection
|
||||
* bool request :
|
||||
* true = Request data connection
|
||||
* false = Release data connection */
|
||||
int DSStateMachine::requestOrReleaseDataConn(bool request){
|
||||
|
||||
LOC_LOGD("DSStateMachine::requestOrReleaseDataConn(): "
|
||||
"request %d", request);
|
||||
|
||||
/* Release data connection required ? */
|
||||
if (!request && mAgpsManager->mDSClientStopDataCallFn) {
|
||||
|
||||
mAgpsManager->mDSClientStopDataCallFn();
|
||||
LOC_LOGD("DS Client release data call request sent !");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Setup data connection request
|
||||
* There must be at least one active subscriber in list */
|
||||
AgpsSubscriber* subscriber = getFirstSubscriber(false);
|
||||
if (subscriber == NULL) {
|
||||
|
||||
LOC_LOGE("No active subscriber for DS Client call setup");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* DS Client Fn registered ? */
|
||||
if (!mAgpsManager->mDSClientOpenAndStartDataCallFn) {
|
||||
|
||||
LOC_LOGE("DS Client start fn not registered, fallback to SUPL ATL");
|
||||
notifyEventToSubscriber(AGPS_EVENT_DENIED, subscriber, false);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Setup the call */
|
||||
int ret = mAgpsManager->mDSClientOpenAndStartDataCallFn();
|
||||
|
||||
/* Check if data call start failed */
|
||||
switch (ret) {
|
||||
|
||||
case LOC_API_ADAPTER_ERR_ENGINE_BUSY:
|
||||
LOC_LOGE("DS Client open call failed, err: %d", ret);
|
||||
mRetries++;
|
||||
if (mRetries > MAX_START_DATA_CALL_RETRIES) {
|
||||
|
||||
LOC_LOGE("DS Client call retries exhausted, "
|
||||
"falling back to normal SUPL ATL");
|
||||
notifyEventToSubscriber(AGPS_EVENT_DENIED, subscriber, false);
|
||||
}
|
||||
/* Retry DS Client call setup after some delay */
|
||||
else if(loc_timer_start(
|
||||
DATA_CALL_RETRY_DELAY_MSEC, delay_callback, this)) {
|
||||
LOC_LOGE("Error: Could not start delay thread\n");
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case LOC_API_ADAPTER_ERR_UNSUPPORTED:
|
||||
LOC_LOGE("No emergency profile found. Fall back to normal SUPL ATL");
|
||||
notifyEventToSubscriber(AGPS_EVENT_DENIED, subscriber, false);
|
||||
break;
|
||||
|
||||
case LOC_API_ADAPTER_ERR_SUCCESS:
|
||||
LOC_LOGD("Request to start data call sent");
|
||||
break;
|
||||
|
||||
default:
|
||||
LOC_LOGE("Unrecognized return value: %d", ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void DSStateMachine::notifyEventToSubscriber(
|
||||
AgpsEvent event, AgpsSubscriber* subscriberToNotify,
|
||||
bool deleteSubscriberPostNotify) {
|
||||
|
||||
LOC_LOGD("DSStateMachine::notifyEventToSubscriber(): "
|
||||
"SM %p, Event %d Subscriber %p Delete %d",
|
||||
this, event, subscriberToNotify, deleteSubscriberPostNotify);
|
||||
|
||||
switch (event) {
|
||||
|
||||
case AGPS_EVENT_GRANTED:
|
||||
mAgpsManager->mAtlOpenStatusCb(
|
||||
subscriberToNotify->mConnHandle, 1, NULL,
|
||||
AGPS_APN_BEARER_INVALID, LOC_AGPS_TYPE_SUPL_ES);
|
||||
break;
|
||||
|
||||
case AGPS_EVENT_DENIED:
|
||||
/* Now try with regular SUPL
|
||||
* We need to send request via message queue */
|
||||
mRetries = 0;
|
||||
mAgpsManager->mSendMsgToAdapterQueueFn(
|
||||
new AgpsMsgRequestATL(
|
||||
mAgpsManager, subscriberToNotify->mConnHandle,
|
||||
LOC_AGPS_TYPE_SUPL));
|
||||
break;
|
||||
|
||||
case AGPS_EVENT_UNSUBSCRIBE:
|
||||
mAgpsManager->mAtlCloseStatusCb(subscriberToNotify->mConnHandle, 1);
|
||||
break;
|
||||
|
||||
case AGPS_EVENT_RELEASED:
|
||||
mAgpsManager->mDSClientCloseDataCallFn();
|
||||
mAgpsManager->mAtlCloseStatusCb(subscriberToNotify->mConnHandle, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOC_LOGE("Invalid event %d", event);
|
||||
}
|
||||
|
||||
/* Search this subscriber in list and delete */
|
||||
if (deleteSubscriberPostNotify) {
|
||||
deleteSubscriber(subscriberToNotify);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Loc AGPS Manager Methods
|
||||
* -------------------------------------------------------------------*/
|
||||
|
||||
/* CREATE AGPS STATE MACHINES
|
||||
* Must be invoked in Msg Handler context */
|
||||
void AgpsManager::createAgpsStateMachines() {
|
||||
|
||||
LOC_LOGD("AgpsManager::createAgpsStateMachines");
|
||||
|
||||
bool agpsCapable =
|
||||
((loc_core::ContextBase::mGps_conf.CAPABILITIES & LOC_GPS_CAPABILITY_MSA) ||
|
||||
(loc_core::ContextBase::mGps_conf.CAPABILITIES & LOC_GPS_CAPABILITY_MSB));
|
||||
|
||||
if (NULL == mInternetNif) {
|
||||
mInternetNif = new AgpsStateMachine(this, LOC_AGPS_TYPE_WWAN_ANY);
|
||||
LOC_LOGD("Internet NIF: %p", mInternetNif);
|
||||
}
|
||||
if (agpsCapable) {
|
||||
if (NULL == mAgnssNif) {
|
||||
mAgnssNif = new AgpsStateMachine(this, LOC_AGPS_TYPE_SUPL);
|
||||
LOC_LOGD("AGNSS NIF: %p", mAgnssNif);
|
||||
}
|
||||
if (NULL == mDsNif &&
|
||||
loc_core::ContextBase::mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL) {
|
||||
|
||||
if(!mDSClientInitFn){
|
||||
|
||||
LOC_LOGE("DS Client Init Fn not registered !");
|
||||
return;
|
||||
}
|
||||
if (mDSClientInitFn(false) != 0) {
|
||||
|
||||
LOC_LOGE("Failed to init data service client");
|
||||
return;
|
||||
}
|
||||
mDsNif = new DSStateMachine(this);
|
||||
LOC_LOGD("DS NIF: %p", mDsNif);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AgpsStateMachine* AgpsManager::getAgpsStateMachine(AGpsExtType agpsType) {
|
||||
|
||||
LOC_LOGD("AgpsManager::getAgpsStateMachine(): agpsType %d", agpsType);
|
||||
|
||||
switch (agpsType) {
|
||||
|
||||
case LOC_AGPS_TYPE_INVALID:
|
||||
case LOC_AGPS_TYPE_SUPL:
|
||||
if (mAgnssNif == NULL) {
|
||||
LOC_LOGE("NULL AGNSS NIF !");
|
||||
}
|
||||
return mAgnssNif;
|
||||
|
||||
case LOC_AGPS_TYPE_SUPL_ES:
|
||||
if (loc_core::ContextBase::mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL) {
|
||||
if (mDsNif == NULL) {
|
||||
createAgpsStateMachines();
|
||||
}
|
||||
return mDsNif;
|
||||
} else {
|
||||
return mAgnssNif;
|
||||
}
|
||||
|
||||
default:
|
||||
return mInternetNif;
|
||||
}
|
||||
|
||||
LOC_LOGE("No SM found !");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void AgpsManager::requestATL(int connHandle, AGpsExtType agpsType){
|
||||
|
||||
LOC_LOGD("AgpsManager::requestATL(): connHandle %d, agpsType %d",
|
||||
connHandle, agpsType);
|
||||
|
||||
AgpsStateMachine* sm = getAgpsStateMachine(agpsType);
|
||||
|
||||
if (sm == NULL) {
|
||||
|
||||
LOC_LOGE("No AGPS State Machine for agpsType: %d", agpsType);
|
||||
mAtlOpenStatusCb(
|
||||
connHandle, 0, NULL, AGPS_APN_BEARER_INVALID, agpsType);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Invoke AGPS SM processing */
|
||||
AgpsSubscriber subscriber(connHandle, false, false);
|
||||
sm->setCurrentSubscriber(&subscriber);
|
||||
|
||||
/* If DS State Machine, wait for close complete */
|
||||
if (agpsType == LOC_AGPS_TYPE_SUPL_ES) {
|
||||
subscriber.mWaitForCloseComplete = true;
|
||||
}
|
||||
|
||||
/* Send subscriber event */
|
||||
sm->processAgpsEvent(AGPS_EVENT_SUBSCRIBE);
|
||||
}
|
||||
|
||||
void AgpsManager::releaseATL(int connHandle){
|
||||
|
||||
LOC_LOGD("AgpsManager::releaseATL(): connHandle %d", connHandle);
|
||||
|
||||
/* First find the subscriber with specified handle.
|
||||
* We need to search in all state machines. */
|
||||
AgpsStateMachine* sm = NULL;
|
||||
AgpsSubscriber* subscriber = NULL;
|
||||
|
||||
if (mAgnssNif &&
|
||||
(subscriber = mAgnssNif->getSubscriber(connHandle)) != NULL) {
|
||||
sm = mAgnssNif;
|
||||
}
|
||||
else if (mInternetNif &&
|
||||
(subscriber = mInternetNif->getSubscriber(connHandle)) != NULL) {
|
||||
sm = mInternetNif;
|
||||
}
|
||||
else if (mDsNif &&
|
||||
(subscriber = mDsNif->getSubscriber(connHandle)) != NULL) {
|
||||
sm = mDsNif;
|
||||
}
|
||||
|
||||
if (sm == NULL) {
|
||||
LOC_LOGE("Subscriber with connHandle %d not found in any SM",
|
||||
connHandle);
|
||||
mAtlCloseStatusCb(connHandle, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now send unsubscribe event */
|
||||
sm->setCurrentSubscriber(subscriber);
|
||||
sm->processAgpsEvent(AGPS_EVENT_UNSUBSCRIBE);
|
||||
}
|
||||
|
||||
void AgpsManager::reportDataCallOpened(){
|
||||
|
||||
LOC_LOGD("AgpsManager::reportDataCallOpened");
|
||||
|
||||
if (mDsNif) {
|
||||
mDsNif->processAgpsEvent(AGPS_EVENT_GRANTED);
|
||||
}
|
||||
}
|
||||
|
||||
void AgpsManager::reportDataCallClosed(){
|
||||
|
||||
LOC_LOGD("AgpsManager::reportDataCallClosed");
|
||||
|
||||
if (mDsNif) {
|
||||
mDsNif->processAgpsEvent(AGPS_EVENT_RELEASED);
|
||||
}
|
||||
}
|
||||
|
||||
void AgpsManager::reportAtlOpenSuccess(
|
||||
AGpsExtType agpsType, char* apnName, int apnLen,
|
||||
AGpsBearerType bearerType){
|
||||
|
||||
LOC_LOGD("AgpsManager::reportAtlOpenSuccess(): "
|
||||
"AgpsType %d, APN [%s], Len %d, BearerType %d",
|
||||
agpsType, apnName, apnLen, bearerType);
|
||||
|
||||
/* Find the state machine instance */
|
||||
AgpsStateMachine* sm = getAgpsStateMachine(agpsType);
|
||||
|
||||
/* Set bearer and apn info in state machine instance */
|
||||
sm->setBearer(bearerType);
|
||||
sm->setAPN(apnName, apnLen);
|
||||
|
||||
/* Send GRANTED event to state machine */
|
||||
sm->processAgpsEvent(AGPS_EVENT_GRANTED);
|
||||
}
|
||||
|
||||
void AgpsManager::reportAtlOpenFailed(AGpsExtType agpsType){
|
||||
|
||||
LOC_LOGD("AgpsManager::reportAtlOpenFailed(): AgpsType %d", agpsType);
|
||||
|
||||
/* Fetch SM and send DENIED event */
|
||||
AgpsStateMachine* sm = getAgpsStateMachine(agpsType);
|
||||
sm->processAgpsEvent(AGPS_EVENT_DENIED);
|
||||
}
|
||||
|
||||
void AgpsManager::reportAtlClosed(AGpsExtType agpsType){
|
||||
|
||||
LOC_LOGD("AgpsManager::reportAtlClosed(): AgpsType %d", agpsType);
|
||||
|
||||
/* Fetch SM and send RELEASED event */
|
||||
AgpsStateMachine* sm = getAgpsStateMachine(agpsType);
|
||||
sm->processAgpsEvent(AGPS_EVENT_RELEASED);
|
||||
}
|
||||
|
||||
void AgpsManager::handleModemSSR(){
|
||||
|
||||
LOC_LOGD("AgpsManager::handleModemSSR");
|
||||
|
||||
/* Drop subscribers from all state machines */
|
||||
if (mAgnssNif) {
|
||||
mAgnssNif->dropAllSubscribers();
|
||||
}
|
||||
if (mInternetNif) {
|
||||
mInternetNif->dropAllSubscribers();
|
||||
}
|
||||
if (mDsNif) {
|
||||
mDsNif->dropAllSubscribers();
|
||||
}
|
||||
|
||||
// reinitialize DS client in SSR mode
|
||||
if (loc_core::ContextBase::mGps_conf.
|
||||
USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL) {
|
||||
|
||||
mDSClientStopDataCallFn();
|
||||
mDSClientCloseDataCallFn();
|
||||
mDSClientReleaseFn();
|
||||
|
||||
mDSClientInitFn(true);
|
||||
}
|
||||
}
|
||||
383
gps/gnss/Agps.h
Normal file
383
gps/gnss/Agps.h
Normal file
@@ -0,0 +1,383 @@
|
||||
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation, nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef AGPS_H
|
||||
#define AGPS_H
|
||||
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <MsgTask.h>
|
||||
#include <gps_extended_c.h>
|
||||
#include <platform_lib_log_util.h>
|
||||
|
||||
/* ATL callback function pointers
|
||||
* Passed in by Adapter to AgpsManager */
|
||||
typedef std::function<void(
|
||||
int handle, int isSuccess, char* apn,
|
||||
AGpsBearerType bearerType, AGpsExtType agpsType)> AgpsAtlOpenStatusCb;
|
||||
|
||||
typedef std::function<void(int handle, int isSuccess)> AgpsAtlCloseStatusCb;
|
||||
|
||||
/* DS Client control APIs
|
||||
* Passed in by Adapter to AgpsManager */
|
||||
typedef std::function<int(bool isDueToSSR)> AgpsDSClientInitFn;
|
||||
typedef std::function<int()> AgpsDSClientOpenAndStartDataCallFn;
|
||||
typedef std::function<void()> AgpsDSClientStopDataCallFn;
|
||||
typedef std::function<void()> AgpsDSClientCloseDataCallFn;
|
||||
typedef std::function<void()> AgpsDSClientReleaseFn;
|
||||
|
||||
/* Post message to adapter's message queue */
|
||||
typedef std::function<void(LocMsg* msg)> SendMsgToAdapterMsgQueueFn;
|
||||
|
||||
/* AGPS States */
|
||||
typedef enum {
|
||||
AGPS_STATE_INVALID = 0,
|
||||
AGPS_STATE_RELEASED,
|
||||
AGPS_STATE_PENDING,
|
||||
AGPS_STATE_ACQUIRED,
|
||||
AGPS_STATE_RELEASING
|
||||
} AgpsState;
|
||||
|
||||
typedef enum {
|
||||
AGPS_EVENT_INVALID = 0,
|
||||
AGPS_EVENT_SUBSCRIBE,
|
||||
AGPS_EVENT_UNSUBSCRIBE,
|
||||
AGPS_EVENT_GRANTED,
|
||||
AGPS_EVENT_RELEASED,
|
||||
AGPS_EVENT_DENIED
|
||||
} AgpsEvent;
|
||||
|
||||
/* Notification Types sent to subscribers */
|
||||
typedef enum {
|
||||
AGPS_NOTIFICATION_TYPE_INVALID = 0,
|
||||
|
||||
/* Meant for all subscribers, either active or inactive */
|
||||
AGPS_NOTIFICATION_TYPE_FOR_ALL_SUBSCRIBERS,
|
||||
|
||||
/* Meant for only inactive subscribers */
|
||||
AGPS_NOTIFICATION_TYPE_FOR_INACTIVE_SUBSCRIBERS,
|
||||
|
||||
/* Meant for only active subscribers */
|
||||
AGPS_NOTIFICATION_TYPE_FOR_ACTIVE_SUBSCRIBERS
|
||||
} AgpsNotificationType;
|
||||
|
||||
/* Classes in this header */
|
||||
class AgpsSubscriber;
|
||||
class AgpsManager;
|
||||
class AgpsStateMachine;
|
||||
class DSStateMachine;
|
||||
|
||||
|
||||
/* SUBSCRIBER
|
||||
* Each Subscriber instance corresponds to one AGPS request,
|
||||
* received by the AGPS state machine */
|
||||
class AgpsSubscriber {
|
||||
|
||||
public:
|
||||
int mConnHandle;
|
||||
|
||||
/* Does this subscriber wait for data call close complete,
|
||||
* before being notified ATL close ?
|
||||
* While waiting for data call close, subscriber will be in
|
||||
* inactive state. */
|
||||
bool mWaitForCloseComplete;
|
||||
bool mIsInactive;
|
||||
|
||||
inline AgpsSubscriber(
|
||||
int connHandle, bool waitForCloseComplete, bool isInactive) :
|
||||
mConnHandle(connHandle),
|
||||
mWaitForCloseComplete(waitForCloseComplete),
|
||||
mIsInactive(isInactive) {}
|
||||
inline virtual ~AgpsSubscriber() {}
|
||||
|
||||
inline virtual bool equals(const AgpsSubscriber *s) const
|
||||
{ return (mConnHandle == s->mConnHandle); }
|
||||
|
||||
inline virtual AgpsSubscriber* clone()
|
||||
{ return new AgpsSubscriber(
|
||||
mConnHandle, mWaitForCloseComplete, mIsInactive); }
|
||||
};
|
||||
|
||||
/* AGPS STATE MACHINE */
|
||||
class AgpsStateMachine {
|
||||
protected:
|
||||
/* AGPS Manager instance, from where this state machine is created */
|
||||
AgpsManager* mAgpsManager;
|
||||
|
||||
/* List of all subscribers for this State Machine.
|
||||
* Once a subscriber is notified for ATL open/close status,
|
||||
* it is deleted */
|
||||
std::list<AgpsSubscriber*> mSubscriberList;
|
||||
|
||||
/* Current subscriber, whose request this State Machine is
|
||||
* currently processing */
|
||||
AgpsSubscriber* mCurrentSubscriber;
|
||||
|
||||
/* Current state for this state machine */
|
||||
AgpsState mState;
|
||||
|
||||
private:
|
||||
/* AGPS Type for this state machine
|
||||
LOC_AGPS_TYPE_ANY 0
|
||||
LOC_AGPS_TYPE_SUPL 1
|
||||
LOC_AGPS_TYPE_WWAN_ANY 3
|
||||
LOC_AGPS_TYPE_SUPL_ES 5 */
|
||||
AGpsExtType mAgpsType;
|
||||
|
||||
/* APN and IP Type info for AGPS Call */
|
||||
char* mAPN;
|
||||
unsigned int mAPNLen;
|
||||
AGpsBearerType mBearer;
|
||||
|
||||
public:
|
||||
/* CONSTRUCTOR */
|
||||
AgpsStateMachine(AgpsManager* agpsManager, AGpsExtType agpsType):
|
||||
mAgpsManager(agpsManager), mSubscriberList(),
|
||||
mCurrentSubscriber(NULL), mState(AGPS_STATE_RELEASED),
|
||||
mAgpsType(agpsType), mAPN(NULL), mAPNLen(0),
|
||||
mBearer(AGPS_APN_BEARER_INVALID) {};
|
||||
|
||||
virtual ~AgpsStateMachine() { if(NULL != mAPN) delete[] mAPN; };
|
||||
|
||||
/* Getter/Setter methods */
|
||||
void setAPN(char* apn, unsigned int len);
|
||||
inline char* getAPN() const { return (char*)mAPN; }
|
||||
inline void setBearer(AGpsBearerType bearer) { mBearer = bearer; }
|
||||
inline AGpsBearerType getBearer() const { return mBearer; }
|
||||
inline AGpsExtType getType() const { return mAgpsType; }
|
||||
inline void setCurrentSubscriber(AgpsSubscriber* subscriber)
|
||||
{ mCurrentSubscriber = subscriber; }
|
||||
|
||||
/* Fetch subscriber with specified handle */
|
||||
AgpsSubscriber* getSubscriber(int connHandle);
|
||||
|
||||
/* Fetch first active or inactive subscriber in list
|
||||
* isInactive = true : fetch first inactive subscriber
|
||||
* isInactive = false : fetch first active subscriber */
|
||||
AgpsSubscriber* getFirstSubscriber(bool isInactive);
|
||||
|
||||
/* Process LOC AGPS Event being passed in
|
||||
* onRsrcEvent */
|
||||
virtual void processAgpsEvent(AgpsEvent event);
|
||||
|
||||
/* Drop all subscribers, in case of Modem SSR */
|
||||
void dropAllSubscribers();
|
||||
|
||||
protected:
|
||||
/* Remove the specified subscriber from list if present.
|
||||
* Also delete the subscriber instance. */
|
||||
void deleteSubscriber(AgpsSubscriber* subscriber);
|
||||
|
||||
private:
|
||||
/* Send call setup request to framework
|
||||
* sendRsrcRequest(LOC_GPS_REQUEST_AGPS_DATA_CONN)
|
||||
* sendRsrcRequest(LOC_GPS_RELEASE_AGPS_DATA_CONN) */
|
||||
virtual int requestOrReleaseDataConn(bool request);
|
||||
|
||||
/* Individual event processing methods */
|
||||
void processAgpsEventSubscribe();
|
||||
void processAgpsEventUnsubscribe();
|
||||
void processAgpsEventGranted();
|
||||
void processAgpsEventReleased();
|
||||
void processAgpsEventDenied();
|
||||
|
||||
/* Clone the passed in subscriber and add to the subscriber list
|
||||
* if not already present */
|
||||
void addSubscriber(AgpsSubscriber* subscriber);
|
||||
|
||||
/* Notify subscribers about AGPS events */
|
||||
void notifyAllSubscribers(
|
||||
AgpsEvent event, bool deleteSubscriberPostNotify,
|
||||
AgpsNotificationType notificationType);
|
||||
virtual void notifyEventToSubscriber(
|
||||
AgpsEvent event, AgpsSubscriber* subscriber,
|
||||
bool deleteSubscriberPostNotify);
|
||||
|
||||
/* Do we have any subscribers in active state */
|
||||
bool anyActiveSubscribers();
|
||||
|
||||
/* Transition state */
|
||||
void transitionState(AgpsState newState);
|
||||
};
|
||||
|
||||
/* DS STATE MACHINE */
|
||||
class DSStateMachine : public AgpsStateMachine {
|
||||
|
||||
private:
|
||||
static const int MAX_START_DATA_CALL_RETRIES;
|
||||
static const int DATA_CALL_RETRY_DELAY_MSEC;
|
||||
|
||||
int mRetries;
|
||||
|
||||
public:
|
||||
/* CONSTRUCTOR */
|
||||
DSStateMachine(AgpsManager* agpsManager):
|
||||
AgpsStateMachine(agpsManager, LOC_AGPS_TYPE_SUPL_ES), mRetries(0) {}
|
||||
|
||||
/* Overridden method
|
||||
* DS SM needs to handle one event differently */
|
||||
void processAgpsEvent(AgpsEvent event);
|
||||
|
||||
/* Retry callback, used in case call failure */
|
||||
void retryCallback();
|
||||
|
||||
private:
|
||||
/* Overridden method, different functionality for DS SM
|
||||
* Send call setup request to framework
|
||||
* sendRsrcRequest(LOC_GPS_REQUEST_AGPS_DATA_CONN)
|
||||
* sendRsrcRequest(LOC_GPS_RELEASE_AGPS_DATA_CONN) */
|
||||
int requestOrReleaseDataConn(bool request);
|
||||
|
||||
/* Overridden method, different functionality for DS SM */
|
||||
void notifyEventToSubscriber(
|
||||
AgpsEvent event, AgpsSubscriber* subscriber,
|
||||
bool deleteSubscriberPostNotify);
|
||||
};
|
||||
|
||||
/* LOC AGPS MANAGER */
|
||||
class AgpsManager {
|
||||
|
||||
friend class AgpsStateMachine;
|
||||
friend class DSStateMachine;
|
||||
|
||||
public:
|
||||
/* CONSTRUCTOR */
|
||||
AgpsManager():
|
||||
mFrameworkStatusV4Cb(NULL),
|
||||
mAtlOpenStatusCb(), mAtlCloseStatusCb(),
|
||||
mDSClientInitFn(), mDSClientOpenAndStartDataCallFn(),
|
||||
mDSClientStopDataCallFn(), mDSClientCloseDataCallFn(), mDSClientReleaseFn(),
|
||||
mSendMsgToAdapterQueueFn(),
|
||||
mAgnssNif(NULL), mInternetNif(NULL), mDsNif(NULL) {}
|
||||
|
||||
/* Register callbacks */
|
||||
void registerCallbacks(
|
||||
AgnssStatusIpV4Cb frameworkStatusV4Cb,
|
||||
|
||||
AgpsAtlOpenStatusCb atlOpenStatusCb,
|
||||
AgpsAtlCloseStatusCb atlCloseStatusCb,
|
||||
|
||||
AgpsDSClientInitFn dsClientInitFn,
|
||||
AgpsDSClientOpenAndStartDataCallFn dsClientOpenAndStartDataCallFn,
|
||||
AgpsDSClientStopDataCallFn dsClientStopDataCallFn,
|
||||
AgpsDSClientCloseDataCallFn dsClientCloseDataCallFn,
|
||||
AgpsDSClientReleaseFn dsClientReleaseFn,
|
||||
|
||||
SendMsgToAdapterMsgQueueFn sendMsgToAdapterQueueFn ){
|
||||
|
||||
mFrameworkStatusV4Cb = frameworkStatusV4Cb;
|
||||
|
||||
mAtlOpenStatusCb = atlOpenStatusCb;
|
||||
mAtlCloseStatusCb = atlCloseStatusCb;
|
||||
|
||||
mDSClientInitFn = dsClientInitFn;
|
||||
mDSClientOpenAndStartDataCallFn = dsClientOpenAndStartDataCallFn;
|
||||
mDSClientStopDataCallFn = dsClientStopDataCallFn;
|
||||
mDSClientCloseDataCallFn = dsClientCloseDataCallFn;
|
||||
mDSClientReleaseFn = dsClientReleaseFn;
|
||||
|
||||
mSendMsgToAdapterQueueFn = sendMsgToAdapterQueueFn;
|
||||
}
|
||||
|
||||
/* Create all AGPS state machines */
|
||||
void createAgpsStateMachines();
|
||||
|
||||
/* Process incoming ATL requests */
|
||||
void requestATL(int connHandle, AGpsExtType agpsType);
|
||||
void releaseATL(int connHandle);
|
||||
|
||||
/* Process incoming DS Client data call events */
|
||||
void reportDataCallOpened();
|
||||
void reportDataCallClosed();
|
||||
|
||||
/* Process incoming framework data call events */
|
||||
void reportAtlOpenSuccess(AGpsExtType agpsType, char* apnName, int apnLen,
|
||||
AGpsBearerType bearerType);
|
||||
void reportAtlOpenFailed(AGpsExtType agpsType);
|
||||
void reportAtlClosed(AGpsExtType agpsType);
|
||||
|
||||
/* Handle Modem SSR */
|
||||
void handleModemSSR();
|
||||
|
||||
protected:
|
||||
AgnssStatusIpV4Cb mFrameworkStatusV4Cb;
|
||||
|
||||
AgpsAtlOpenStatusCb mAtlOpenStatusCb;
|
||||
AgpsAtlCloseStatusCb mAtlCloseStatusCb;
|
||||
|
||||
AgpsDSClientInitFn mDSClientInitFn;
|
||||
AgpsDSClientOpenAndStartDataCallFn mDSClientOpenAndStartDataCallFn;
|
||||
AgpsDSClientStopDataCallFn mDSClientStopDataCallFn;
|
||||
AgpsDSClientCloseDataCallFn mDSClientCloseDataCallFn;
|
||||
AgpsDSClientReleaseFn mDSClientReleaseFn;
|
||||
|
||||
SendMsgToAdapterMsgQueueFn mSendMsgToAdapterQueueFn;
|
||||
|
||||
AgpsStateMachine* mAgnssNif;
|
||||
AgpsStateMachine* mInternetNif;
|
||||
AgpsStateMachine* mDsNif;
|
||||
|
||||
private:
|
||||
/* Fetch state machine for handling request ATL call */
|
||||
AgpsStateMachine* getAgpsStateMachine(AGpsExtType agpsType);
|
||||
};
|
||||
|
||||
/* Request SUPL/INTERNET/SUPL_ES ATL
|
||||
* This LocMsg is defined in this header since it has to be used from more
|
||||
* than one place, other Agps LocMsg are restricted to GnssAdapter and
|
||||
* declared inline */
|
||||
struct AgpsMsgRequestATL: public LocMsg {
|
||||
|
||||
AgpsManager* mAgpsManager;
|
||||
int mConnHandle;
|
||||
AGpsExtType mAgpsType;
|
||||
|
||||
inline AgpsMsgRequestATL(AgpsManager* agpsManager, int connHandle,
|
||||
AGpsExtType agpsType) :
|
||||
LocMsg(), mAgpsManager(agpsManager), mConnHandle(connHandle), mAgpsType(
|
||||
agpsType) {
|
||||
|
||||
LOC_LOGV("AgpsMsgRequestATL");
|
||||
}
|
||||
|
||||
inline virtual void proc() const {
|
||||
|
||||
LOC_LOGV("AgpsMsgRequestATL::proc()");
|
||||
mAgpsManager->requestATL(mConnHandle, mAgpsType);
|
||||
}
|
||||
};
|
||||
|
||||
namespace AgpsUtils {
|
||||
|
||||
AGpsBearerType ipTypeToBearerType(LocApnIpType ipType);
|
||||
LocApnIpType bearerTypeToIpType(AGpsBearerType bearerType);
|
||||
|
||||
}
|
||||
|
||||
#endif /* AGPS_H */
|
||||
47
gps/gnss/Android.mk
Normal file
47
gps/gnss/Android.mk
Normal file
@@ -0,0 +1,47 @@
|
||||
ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)
|
||||
ifneq ($(BUILD_TINY_ANDROID),true)
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE := libgnss
|
||||
LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib
|
||||
LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libutils \
|
||||
libcutils \
|
||||
libdl \
|
||||
liblog \
|
||||
libloc_core \
|
||||
libgps.utils
|
||||
|
||||
LOCAL_SRC_FILES += \
|
||||
location_gnss.cpp \
|
||||
GnssAdapter.cpp \
|
||||
Agps.cpp \
|
||||
XtraSystemStatusObserver.cpp
|
||||
|
||||
LOCAL_CFLAGS += \
|
||||
-fno-short-enums \
|
||||
|
||||
ifeq ($(TARGET_BUILD_VARIANT),user)
|
||||
LOCAL_CFLAGS += -DTARGET_BUILD_VARIANT_USER
|
||||
endif
|
||||
|
||||
LOCAL_HEADER_LIBRARIES := \
|
||||
libgps.utils_headers \
|
||||
libloc_core_headers \
|
||||
libloc_pla_headers \
|
||||
liblocation_api_headers
|
||||
|
||||
LOCAL_CFLAGS += $(GNSS_CFLAGS)
|
||||
|
||||
LOCAL_PRELINK_MODULE := false
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
endif # not BUILD_TINY_ANDROID
|
||||
endif # BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE
|
||||
3131
gps/gnss/GnssAdapter.cpp
Normal file
3131
gps/gnss/GnssAdapter.cpp
Normal file
File diff suppressed because it is too large
Load Diff
287
gps/gnss/GnssAdapter.h
Normal file
287
gps/gnss/GnssAdapter.h
Normal file
@@ -0,0 +1,287 @@
|
||||
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation, nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef GNSS_ADAPTER_H
|
||||
#define GNSS_ADAPTER_H
|
||||
|
||||
#include <LocAdapterBase.h>
|
||||
#include <LocDualContext.h>
|
||||
#include <UlpProxyBase.h>
|
||||
#include <LocationAPI.h>
|
||||
#include <Agps.h>
|
||||
#include <SystemStatus.h>
|
||||
#include <XtraSystemStatusObserver.h>
|
||||
|
||||
#define MAX_URL_LEN 256
|
||||
#define NMEA_SENTENCE_MAX_LENGTH 200
|
||||
#define GLONASS_SV_ID_OFFSET 64
|
||||
#define MAX_SATELLITES_IN_USE 12
|
||||
#define LOC_NI_NO_RESPONSE_TIME 20
|
||||
#define LOC_GPS_NI_RESPONSE_IGNORE 4
|
||||
|
||||
class GnssAdapter;
|
||||
|
||||
typedef struct {
|
||||
pthread_t thread; /* NI thread */
|
||||
uint32_t respTimeLeft; /* examine time for NI response */
|
||||
bool respRecvd; /* NI User reponse received or not from Java layer*/
|
||||
void* rawRequest;
|
||||
uint32_t reqID; /* ID to check against response */
|
||||
GnssNiResponse resp;
|
||||
pthread_cond_t tCond;
|
||||
pthread_mutex_t tLock;
|
||||
GnssAdapter* adapter;
|
||||
} NiSession;
|
||||
typedef struct {
|
||||
NiSession session; /* SUPL NI Session */
|
||||
NiSession sessionEs; /* Emergency SUPL NI Session */
|
||||
uint32_t reqIDCounter;
|
||||
} NiData;
|
||||
|
||||
typedef enum {
|
||||
NMEA_PROVIDER_AP = 0, // Application Processor Provider of NMEA
|
||||
NMEA_PROVIDER_MP // Modem Processor Provider of NMEA
|
||||
} NmeaProviderType;
|
||||
typedef struct {
|
||||
GnssSvType svType;
|
||||
const char* talker;
|
||||
uint64_t mask;
|
||||
uint32_t svIdOffset;
|
||||
} NmeaSvMeta;
|
||||
|
||||
using namespace loc_core;
|
||||
|
||||
namespace loc_core {
|
||||
class SystemStatus;
|
||||
}
|
||||
|
||||
class GnssAdapter : public LocAdapterBase {
|
||||
/* ==== ULP ============================================================================ */
|
||||
UlpProxyBase* mUlpProxy;
|
||||
|
||||
/* ==== CLIENT ========================================================================= */
|
||||
typedef std::map<LocationAPI*, LocationCallbacks> ClientDataMap;
|
||||
ClientDataMap mClientData;
|
||||
|
||||
/* ==== TRACKING ======================================================================= */
|
||||
LocationSessionMap mTrackingSessions;
|
||||
LocPosMode mUlpPositionMode;
|
||||
GnssSvUsedInPosition mGnssSvIdUsedInPosition;
|
||||
bool mGnssSvIdUsedInPosAvail;
|
||||
|
||||
/* ==== CONTROL ======================================================================== */
|
||||
LocationControlCallbacks mControlCallbacks;
|
||||
uint32_t mPowerVoteId;
|
||||
uint32_t mNmeaMask;
|
||||
|
||||
/* ==== NI ============================================================================= */
|
||||
NiData mNiData;
|
||||
|
||||
/* ==== AGPS ========================================================*/
|
||||
// This must be initialized via initAgps()
|
||||
AgpsManager mAgpsManager;
|
||||
AgpsCbInfo mAgpsCbInfo;
|
||||
|
||||
/* === SystemStatus ===================================================================== */
|
||||
SystemStatus* mSystemStatus;
|
||||
std::string mServerUrl;
|
||||
XtraSystemStatusObserver mXtraObserver;
|
||||
|
||||
/*==== CONVERSION ===================================================================*/
|
||||
static void convertOptions(LocPosMode& out, const LocationOptions& options);
|
||||
static void convertLocation(Location& out, const LocGpsLocation& locGpsLocation,
|
||||
const GpsLocationExtended& locationExtended,
|
||||
const LocPosTechMask techMask);
|
||||
static void convertLocationInfo(GnssLocationInfoNotification& out,
|
||||
const GpsLocationExtended& locationExtended);
|
||||
|
||||
public:
|
||||
|
||||
GnssAdapter();
|
||||
virtual inline ~GnssAdapter() { delete mUlpProxy; }
|
||||
|
||||
/* ==== SSR ============================================================================ */
|
||||
/* ======== EVENTS ====(Called from QMI Thread)========================================= */
|
||||
virtual void handleEngineUpEvent();
|
||||
/* ======== UTILITIES ================================================================== */
|
||||
void restartSessions();
|
||||
|
||||
/* ==== ULP ============================================================================ */
|
||||
/* ======== COMMANDS ====(Called from ULP Thread)==================================== */
|
||||
virtual void setUlpProxyCommand(UlpProxyBase* ulp);
|
||||
/* ======== UTILITIES ================================================================== */
|
||||
void setUlpProxy(UlpProxyBase* ulp);
|
||||
inline UlpProxyBase* getUlpProxy() { return mUlpProxy; }
|
||||
|
||||
/* ==== CLIENT ========================================================================= */
|
||||
/* ======== COMMANDS ====(Called from Client Thread)==================================== */
|
||||
void addClientCommand(LocationAPI* client, const LocationCallbacks& callbacks);
|
||||
void removeClientCommand(LocationAPI* client);
|
||||
void requestCapabilitiesCommand(LocationAPI* client);
|
||||
/* ======== UTILITIES ================================================================== */
|
||||
void saveClient(LocationAPI* client, const LocationCallbacks& callbacks);
|
||||
void eraseClient(LocationAPI* client);
|
||||
void updateClientsEventMask();
|
||||
void stopClientSessions(LocationAPI* client);
|
||||
LocationCallbacks getClientCallbacks(LocationAPI* client);
|
||||
LocationCapabilitiesMask getCapabilities();
|
||||
void broadcastCapabilities(LocationCapabilitiesMask);
|
||||
|
||||
/* ==== TRACKING ======================================================================= */
|
||||
/* ======== COMMANDS ====(Called from Client Thread)==================================== */
|
||||
uint32_t startTrackingCommand(LocationAPI* client, LocationOptions& options);
|
||||
void updateTrackingOptionsCommand(LocationAPI* client, uint32_t id, LocationOptions& options);
|
||||
void stopTrackingCommand(LocationAPI* client, uint32_t id);
|
||||
/* ======================(Called from ULP Thread)======================================= */
|
||||
virtual void setPositionModeCommand(LocPosMode& locPosMode);
|
||||
virtual void startTrackingCommand();
|
||||
virtual void stopTrackingCommand();
|
||||
virtual void getZppCommand();
|
||||
/* ======== RESPONSES ================================================================== */
|
||||
void reportResponse(LocationAPI* client, LocationError err, uint32_t sessionId);
|
||||
/* ======== UTILITIES ================================================================== */
|
||||
bool hasTrackingCallback(LocationAPI* client);
|
||||
bool hasMeasurementsCallback(LocationAPI* client);
|
||||
bool isTrackingSession(LocationAPI* client, uint32_t sessionId);
|
||||
void saveTrackingSession(LocationAPI* client, uint32_t sessionId,
|
||||
const LocationOptions& options);
|
||||
void eraseTrackingSession(LocationAPI* client, uint32_t sessionId);
|
||||
bool setUlpPositionMode(const LocPosMode& mode);
|
||||
LocPosMode& getUlpPositionMode() { return mUlpPositionMode; }
|
||||
LocationError startTrackingMultiplex(const LocationOptions& options);
|
||||
LocationError startTracking(const LocationOptions& options);
|
||||
LocationError stopTrackingMultiplex(LocationAPI* client, uint32_t id);
|
||||
LocationError stopTracking();
|
||||
LocationError updateTrackingMultiplex(LocationAPI* client, uint32_t id,
|
||||
const LocationOptions& options);
|
||||
|
||||
/* ==== NI ============================================================================= */
|
||||
/* ======== COMMANDS ====(Called from Client Thread)==================================== */
|
||||
void gnssNiResponseCommand(LocationAPI* client, uint32_t id, GnssNiResponse response);
|
||||
/* ======================(Called from NI Thread)======================================== */
|
||||
void gnssNiResponseCommand(GnssNiResponse response, void* rawRequest);
|
||||
/* ======== UTILITIES ================================================================== */
|
||||
bool hasNiNotifyCallback(LocationAPI* client);
|
||||
NiData& getNiData() { return mNiData; }
|
||||
|
||||
/* ==== CONTROL ======================================================================== */
|
||||
/* ======== COMMANDS ====(Called from Client Thread)==================================== */
|
||||
uint32_t enableCommand(LocationTechnologyType techType);
|
||||
void disableCommand(uint32_t id);
|
||||
void setControlCallbacksCommand(LocationControlCallbacks& controlCallbacks);
|
||||
void readConfigCommand();
|
||||
void setConfigCommand();
|
||||
uint32_t* gnssUpdateConfigCommand(GnssConfig config);
|
||||
uint32_t gnssDeleteAidingDataCommand(GnssAidingData& data);
|
||||
|
||||
void initDefaultAgpsCommand();
|
||||
void initAgpsCommand(const AgpsCbInfo& cbInfo);
|
||||
void dataConnOpenCommand(AGpsExtType agpsType,
|
||||
const char* apnName, int apnLen, AGpsBearerType bearerType);
|
||||
void dataConnClosedCommand(AGpsExtType agpsType);
|
||||
void dataConnFailedCommand(AGpsExtType agpsType);
|
||||
|
||||
/* ======== RESPONSES ================================================================== */
|
||||
void reportResponse(LocationError err, uint32_t sessionId);
|
||||
void reportResponse(size_t count, LocationError* errs, uint32_t* ids);
|
||||
/* ======== UTILITIES ================================================================== */
|
||||
LocationControlCallbacks& getControlCallbacks() { return mControlCallbacks; }
|
||||
void setControlCallbacks(const LocationControlCallbacks& controlCallbacks)
|
||||
{ mControlCallbacks = controlCallbacks; }
|
||||
void setPowerVoteId(uint32_t id) { mPowerVoteId = id; }
|
||||
uint32_t getPowerVoteId() { return mPowerVoteId; }
|
||||
bool resolveInAddress(const char* hostAddress, struct in_addr* inAddress);
|
||||
virtual bool isInSession() { return !mTrackingSessions.empty(); }
|
||||
void initDefaultAgps();
|
||||
|
||||
/* ==== REPORTS ======================================================================== */
|
||||
/* ======== EVENTS ====(Called from QMI/ULP Thread)===================================== */
|
||||
virtual void reportPositionEvent(const UlpLocation& ulpLocation,
|
||||
const GpsLocationExtended& locationExtended,
|
||||
enum loc_sess_status status,
|
||||
LocPosTechMask techMask,
|
||||
bool fromUlp=false);
|
||||
virtual void reportSvEvent(const GnssSvNotification& svNotify, bool fromUlp=false);
|
||||
virtual void reportNmeaEvent(const char* nmea, size_t length, bool fromUlp=false);
|
||||
virtual bool requestNiNotifyEvent(const GnssNiNotification& notify, const void* data);
|
||||
virtual void reportGnssMeasurementDataEvent(const GnssMeasurementsNotification& measurements,
|
||||
int msInWeek);
|
||||
virtual void reportSvMeasurementEvent(GnssSvMeasurementSet &svMeasurementSet);
|
||||
virtual void reportSvPolynomialEvent(GnssSvPolynomial &svPolynomial);
|
||||
|
||||
virtual bool requestATL(int connHandle, LocAGpsType agps_type);
|
||||
virtual bool releaseATL(int connHandle);
|
||||
virtual bool requestSuplES(int connHandle);
|
||||
virtual bool reportDataCallOpened();
|
||||
virtual bool reportDataCallClosed();
|
||||
|
||||
/* ======== UTILITIES ================================================================= */
|
||||
void reportPosition(const UlpLocation &ulpLocation,
|
||||
const GpsLocationExtended &locationExtended,
|
||||
enum loc_sess_status status,
|
||||
LocPosTechMask techMask);
|
||||
void reportSv(GnssSvNotification& svNotify);
|
||||
void reportNmea(const char* nmea, size_t length);
|
||||
bool requestNiNotify(const GnssNiNotification& notify, const void* data);
|
||||
void reportGnssMeasurementData(const GnssMeasurementsNotification& measurements);
|
||||
|
||||
/*======== GNSSDEBUG ================================================================*/
|
||||
bool getDebugReport(GnssDebugReport& report);
|
||||
/* get AGC information from system status and fill it */
|
||||
void getAgcInformation(GnssMeasurementsNotification& measurements, int msInWeek);
|
||||
|
||||
/*==== SYSTEM STATUS ================================================================*/
|
||||
inline SystemStatus* getSystemStatus(void) { return mSystemStatus; }
|
||||
std::string& getServerUrl(void) { return mServerUrl; }
|
||||
void setServerUrl(const char* server) { mServerUrl.assign(server); }
|
||||
|
||||
/*==== CONVERSION ===================================================================*/
|
||||
static uint32_t convertGpsLock(const GnssConfigGpsLock gpsLock);
|
||||
static GnssConfigGpsLock convertGpsLock(const uint32_t gpsLock);
|
||||
static uint32_t convertSuplVersion(const GnssConfigSuplVersion suplVersion);
|
||||
static GnssConfigSuplVersion convertSuplVersion(const uint32_t suplVersion);
|
||||
static uint32_t convertLppProfile(const GnssConfigLppProfile lppProfile);
|
||||
static GnssConfigLppProfile convertLppProfile(const uint32_t lppProfile);
|
||||
static uint32_t convertEP4ES(const GnssConfigEmergencyPdnForEmergencySupl);
|
||||
static uint32_t convertSuplEs(const GnssConfigSuplEmergencyServices suplEmergencyServices);
|
||||
static uint32_t convertLppeCp(const GnssConfigLppeControlPlaneMask lppeControlPlaneMask);
|
||||
static GnssConfigLppeControlPlaneMask convertLppeCp(const uint32_t lppeControlPlaneMask);
|
||||
static uint32_t convertLppeUp(const GnssConfigLppeUserPlaneMask lppeUserPlaneMask);
|
||||
static GnssConfigLppeUserPlaneMask convertLppeUp(const uint32_t lppeUserPlaneMask);
|
||||
static uint32_t convertAGloProt(const GnssConfigAGlonassPositionProtocolMask);
|
||||
static uint32_t convertSuplMode(const GnssConfigSuplModeMask suplModeMask);
|
||||
static void convertSatelliteInfo(std::vector<GnssDebugSatelliteInfo>& out,
|
||||
const GnssSvType& in_constellation,
|
||||
const SystemStatusReports& in);
|
||||
|
||||
void injectLocationCommand(double latitude, double longitude, float accuracy);
|
||||
void injectTimeCommand(int64_t time, int64_t timeReference, int32_t uncertainty);
|
||||
|
||||
};
|
||||
|
||||
#endif //GNSS_ADAPTER_H
|
||||
99
gps/gnss/Makefile.am
Normal file
99
gps/gnss/Makefile.am
Normal file
@@ -0,0 +1,99 @@
|
||||
AM_CFLAGS = \
|
||||
$(LOCPLA_CFLAGS) \
|
||||
$(LOCHAL_CFLAGS) \
|
||||
-I./ \
|
||||
-I../utils \
|
||||
-I../core \
|
||||
-I../location \
|
||||
-std=c++11
|
||||
|
||||
libgnss_la_SOURCES = \
|
||||
location_gnss.cpp \
|
||||
GnssAdapter.cpp \
|
||||
Agps.cpp
|
||||
|
||||
if USE_GLIB
|
||||
libgnss_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@
|
||||
libgnss_la_LDFLAGS = -lstdc++ -lpthread @GLIB_LIBS@ -shared -avoid-version
|
||||
libgnss_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@
|
||||
else
|
||||
libgnss_la_CFLAGS = $(AM_CFLAGS)
|
||||
libgnss_la_LDFLAGS = -lpthread -shared -version-info 1:0:0
|
||||
libgnss_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS)
|
||||
endif
|
||||
|
||||
libgnss_la_LIBADD = -lstdc++ $(LOCPLA_LIBS) $(LOCHAL_LIBS)
|
||||
|
||||
|
||||
#Create and Install libraries
|
||||
#lib_LTLIBRARIES = libgnss.la
|
||||
|
||||
#library_includedir = $(pkgincludedir)
|
||||
#pkgconfigdir = $(libdir)/pkgconfig
|
||||
#pkgconfig_DATA = location-api.pc
|
||||
#EXTRA_DIST = $(pkgconfig_DATA)
|
||||
|
||||
|
||||
libloc_ds_api_CFLAGS = \
|
||||
$(QMIF_CFLAGS) \
|
||||
$(QMI_CFLAGS) \
|
||||
$(DATA_CFLAGS) \
|
||||
$(GPSUTILS_CFLAGS) \
|
||||
-I$(WORKSPACE)/qcom-opensource/location/loc_api/ds_api
|
||||
|
||||
libloc_ds_api_la_SOURCES = \
|
||||
$(WORKSPACE)/qcom-opensource/location/loc_api/ds_api/ds_client.c
|
||||
|
||||
if USE_GLIB
|
||||
libloc_ds_api_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(libloc_ds_api_CFLAGS) @GLIB_CFLAGS@
|
||||
libloc_ds_api_la_LDFLAGS = -lstdc++ -Wl,-z,defs -lpthread @GLIB_LIBS@ -shared -version-info 1:0:0
|
||||
libloc_ds_api_la_LDFLAGS += -Wl,--export-dynamic
|
||||
libloc_ds_api_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(libloc_ds_api_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@
|
||||
else
|
||||
libloc_ds_api_la_CFLAGS = $(AM_CFLAGS) $(libloc_ds_api_CFLAGS)
|
||||
libloc_ds_api_la_LDFLAGS = -lstdc++ -Wl,-z,defs -lpthread -Wl,--export-dynamic -shared -version-info 1:0:0
|
||||
libloc_ds_api_la_LDFLAGS += -Wl,--export-dynamic
|
||||
libloc_ds_api_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS) $(libloc_ds_api_CFLAGS)
|
||||
endif
|
||||
|
||||
libloc_ds_api_la_LIBADD = -lstdc++ $(QMIF_LIBS) -lqmiservices -ldsi_netctrl $(GPSUTILS_LIBS) $(LOCPLA_LIBS)
|
||||
|
||||
libloc_api_v02_CFLAGS = \
|
||||
$(QMIF_CFLAGS) \
|
||||
$(GPSUTILS_CFLAGS) \
|
||||
-I$(WORKSPACE)/qcom-opensource/location/loc_api/ds_api \
|
||||
-I$(WORKSPACE)/qcom-opensource/location/loc_api/loc_api_v02
|
||||
|
||||
libloc_api_v02_la_SOURCES = \
|
||||
$(WORKSPACE)/qcom-opensource/location/loc_api/loc_api_v02/LocApiV02.cpp \
|
||||
$(WORKSPACE)/qcom-opensource/location/loc_api/loc_api_v02/loc_api_v02_log.c \
|
||||
$(WORKSPACE)/qcom-opensource/location/loc_api/loc_api_v02/loc_api_v02_client.c \
|
||||
$(WORKSPACE)/qcom-opensource/location/loc_api/loc_api_v02/loc_api_sync_req.c \
|
||||
$(WORKSPACE)/qcom-opensource/location/loc_api/loc_api_v02/location_service_v02.c
|
||||
|
||||
if USE_GLIB
|
||||
libloc_api_v02_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(libloc_api_v02_CFLAGS) @GLIB_CFLAGS@
|
||||
libloc_api_v02_la_LDFLAGS = -lstdc++ -g -Wl,-z,defs -lpthread @GLIB_LIBS@ -shared -version-info 1:0:0
|
||||
libloc_api_v02_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(libloc_api_v02_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@
|
||||
else
|
||||
libloc_api_v02_la_CFLAGS = $(AM_CFLAGS) $(libloc_api_v02_CFLAGS)
|
||||
libloc_api_v02_la_LDFLAGS = -lstdc++ -Wl,-z,defs -lpthread -shared -version-info 1:0:0
|
||||
libloc_api_v02_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS) $(libloc_api_v02_CFLAGS)
|
||||
endif
|
||||
|
||||
libloc_api_v02_la_CXXFLAGS = -std=c++0x
|
||||
libloc_api_v02_la_LIBADD = -lstdc++ -lqmi_cci -lqmi_common_so $(QMIF_LIBS) $(GPSUTILS_LIBS) $(LOCPLA_LIBS) ../core/libloc_core.la libloc_ds_api.la
|
||||
|
||||
library_include_HEADERS = \
|
||||
$(WORKSPACE)/qcom-opensource/location/loc_api/ds_api/ds_client.h \
|
||||
$(WORKSPACE)/qcom-opensource/location/loc_api/loc_api_v02/location_service_v02.h \
|
||||
$(WORKSPACE)/qcom-opensource/location/loc_api/loc_api_v02/loc_api_v02_log.h \
|
||||
$(WORKSPACE)/qcom-opensource/location/loc_api/loc_api_v02/loc_api_v02_client.h \
|
||||
$(WORKSPACE)/qcom-opensource/location/loc_api/loc_api_v02/loc_api_sync_req.h \
|
||||
$(WORKSPACE)/qcom-opensource/location/loc_api/loc_api_v02/LocApiV02.h \
|
||||
$(WORKSPACE)/qcom-opensource/location/loc_api/loc_api_v02/loc_util_log.h
|
||||
|
||||
library_includedir = $(pkgincludedir)
|
||||
|
||||
#Create and Install libraries
|
||||
lib_LTLIBRARIES = libgnss.la libloc_ds_api.la libloc_api_v02.la
|
||||
234
gps/gnss/XtraSystemStatusObserver.cpp
Normal file
234
gps/gnss/XtraSystemStatusObserver.cpp
Normal file
@@ -0,0 +1,234 @@
|
||||
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation, nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#define LOG_TAG "LocSvc_XtraSystemStatusObs"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/un.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <cutils/properties.h>
|
||||
#include <math.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <string>
|
||||
#include <loc_log.h>
|
||||
#include <loc_nmea.h>
|
||||
#include <SystemStatus.h>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <XtraSystemStatusObserver.h>
|
||||
#include <LocAdapterBase.h>
|
||||
#include <DataItemId.h>
|
||||
#include <DataItemsFactoryProxy.h>
|
||||
|
||||
using namespace loc_core;
|
||||
|
||||
#define XTRA_HAL_SOCKET_NAME "/data/vendor/location/xtra/socket_hal_xtra"
|
||||
|
||||
bool XtraSystemStatusObserver::updateLockStatus(uint32_t lock) {
|
||||
stringstream ss;
|
||||
ss << "gpslock";
|
||||
ss << " " << lock;
|
||||
ss << "\n"; // append seperator
|
||||
return ( sendEvent(ss) );
|
||||
}
|
||||
|
||||
bool XtraSystemStatusObserver::updateConnectionStatus(bool connected, uint32_t type) {
|
||||
stringstream ss;
|
||||
ss << "connection";
|
||||
ss << " " << (connected ? "1" : "0");
|
||||
ss << " " << (int)type;
|
||||
ss << "\n"; // append seperator
|
||||
return ( sendEvent(ss) );
|
||||
}
|
||||
bool XtraSystemStatusObserver::updateTac(const string& tac) {
|
||||
stringstream ss;
|
||||
ss << "tac";
|
||||
ss << " " << tac.c_str();
|
||||
ss << "\n"; // append seperator
|
||||
return ( sendEvent(ss) );
|
||||
}
|
||||
|
||||
bool XtraSystemStatusObserver::updateMccMnc(const string& mccmnc) {
|
||||
stringstream ss;
|
||||
ss << "mncmcc";
|
||||
ss << " " << mccmnc.c_str();
|
||||
ss << "\n"; // append seperator
|
||||
return ( sendEvent(ss) );
|
||||
}
|
||||
|
||||
bool XtraSystemStatusObserver::sendEvent(const stringstream& event) {
|
||||
int socketFd = createSocket();
|
||||
if (socketFd < 0) {
|
||||
LOC_LOGe("XTRA unreachable. sending failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
const string& data = event.str();
|
||||
int remain = data.length();
|
||||
ssize_t sent = 0;
|
||||
while (remain > 0 &&
|
||||
(sent = ::send(socketFd, data.c_str() + (data.length() - remain),
|
||||
remain, MSG_NOSIGNAL)) > 0) {
|
||||
remain -= sent;
|
||||
}
|
||||
|
||||
if (sent < 0) {
|
||||
LOC_LOGe("sending error. reason:%s", strerror(errno));
|
||||
}
|
||||
|
||||
closeSocket(socketFd);
|
||||
|
||||
return (remain == 0);
|
||||
}
|
||||
|
||||
|
||||
int XtraSystemStatusObserver::createSocket() {
|
||||
int socketFd = -1;
|
||||
|
||||
if ((socketFd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
|
||||
LOC_LOGe("create socket error. reason:%s", strerror(errno));
|
||||
|
||||
} else {
|
||||
const char* socketPath = XTRA_HAL_SOCKET_NAME ;
|
||||
struct sockaddr_un addr = { .sun_family = AF_UNIX };
|
||||
snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", socketPath);
|
||||
|
||||
if (::connect(socketFd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
|
||||
LOC_LOGe("cannot connect to XTRA. reason:%s", strerror(errno));
|
||||
if (::close(socketFd)) {
|
||||
LOC_LOGe("close socket error. reason:%s", strerror(errno));
|
||||
}
|
||||
socketFd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return socketFd;
|
||||
}
|
||||
|
||||
void XtraSystemStatusObserver::closeSocket(const int socketFd) {
|
||||
if (socketFd >= 0) {
|
||||
if(::close(socketFd)) {
|
||||
LOC_LOGe("close socket error. reason:%s", strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void XtraSystemStatusObserver::subscribe(bool yes)
|
||||
{
|
||||
// Subscription data list
|
||||
list<DataItemId> subItemIdList;
|
||||
subItemIdList.push_back(NETWORKINFO_DATA_ITEM_ID);
|
||||
subItemIdList.push_back(MCCMNC_DATA_ITEM_ID);
|
||||
|
||||
if (yes) {
|
||||
mSystemStatusObsrvr->subscribe(subItemIdList, this);
|
||||
|
||||
list<DataItemId> reqItemIdList;
|
||||
reqItemIdList.push_back(TAC_DATA_ITEM_ID);
|
||||
|
||||
mSystemStatusObsrvr->requestData(reqItemIdList, this);
|
||||
|
||||
} else {
|
||||
mSystemStatusObsrvr->unsubscribe(subItemIdList, this);
|
||||
}
|
||||
}
|
||||
|
||||
// IDataItemObserver overrides
|
||||
void XtraSystemStatusObserver::getName(string& name)
|
||||
{
|
||||
name = "XtraSystemStatusObserver";
|
||||
}
|
||||
|
||||
void XtraSystemStatusObserver::notify(const list<IDataItemCore*>& dlist)
|
||||
{
|
||||
struct handleOsObserverUpdateMsg : public LocMsg {
|
||||
XtraSystemStatusObserver* mXtraSysStatObj;
|
||||
list <IDataItemCore*> mDataItemList;
|
||||
|
||||
inline handleOsObserverUpdateMsg(XtraSystemStatusObserver* xtraSysStatObs,
|
||||
const list<IDataItemCore*>& dataItemList) :
|
||||
mXtraSysStatObj(xtraSysStatObs) {
|
||||
for (auto eachItem : dataItemList) {
|
||||
IDataItemCore* dataitem = DataItemsFactoryProxy::createNewDataItem(
|
||||
eachItem->getId());
|
||||
if (NULL == dataitem) {
|
||||
break;
|
||||
}
|
||||
// Copy the contents of the data item
|
||||
dataitem->copy(eachItem);
|
||||
|
||||
mDataItemList.push_back(dataitem);
|
||||
}
|
||||
}
|
||||
|
||||
inline ~handleOsObserverUpdateMsg() {
|
||||
for (auto each : mDataItemList) {
|
||||
delete each;
|
||||
}
|
||||
}
|
||||
|
||||
inline void proc() const {
|
||||
for (auto each : mDataItemList) {
|
||||
switch (each->getId())
|
||||
{
|
||||
case NETWORKINFO_DATA_ITEM_ID:
|
||||
{
|
||||
SystemStatusNetworkInfo* networkInfo =
|
||||
reinterpret_cast<SystemStatusNetworkInfo*>(each);
|
||||
mXtraSysStatObj->updateConnectionStatus(networkInfo->mConnected,
|
||||
networkInfo->mType);
|
||||
}
|
||||
break;
|
||||
|
||||
case TAC_DATA_ITEM_ID:
|
||||
{
|
||||
SystemStatusTac* tac = reinterpret_cast<SystemStatusTac*>(each);
|
||||
mXtraSysStatObj->updateTac(tac->mValue);
|
||||
}
|
||||
break;
|
||||
|
||||
case MCCMNC_DATA_ITEM_ID:
|
||||
{
|
||||
SystemStatusMccMnc* mccmnc = reinterpret_cast<SystemStatusMccMnc*>(each);
|
||||
mXtraSysStatObj->updateMccMnc(mccmnc->mValue);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
mMsgTask->sendMsg(new (nothrow) handleOsObserverUpdateMsg(this, dlist));
|
||||
}
|
||||
|
||||
|
||||
71
gps/gnss/XtraSystemStatusObserver.h
Normal file
71
gps/gnss/XtraSystemStatusObserver.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation, nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef XTRA_SYSTEM_STATUS_OBS_H
|
||||
#define XTRA_SYSTEM_STATUS_OBS_H
|
||||
|
||||
#include <cinttypes>
|
||||
#include <MsgTask.h>
|
||||
|
||||
using namespace std;
|
||||
using loc_core::IOsObserver;
|
||||
using loc_core::IDataItemObserver;
|
||||
using loc_core::IDataItemCore;
|
||||
|
||||
|
||||
class XtraSystemStatusObserver : public IDataItemObserver {
|
||||
public :
|
||||
// constructor & destructor
|
||||
inline XtraSystemStatusObserver(IOsObserver* sysStatObs, const MsgTask* msgTask):
|
||||
mSystemStatusObsrvr(sysStatObs), mMsgTask(msgTask) {
|
||||
subscribe(true);
|
||||
}
|
||||
inline XtraSystemStatusObserver() {};
|
||||
inline virtual ~XtraSystemStatusObserver() { subscribe(false); }
|
||||
|
||||
// IDataItemObserver overrides
|
||||
inline virtual void getName(string& name);
|
||||
virtual void notify(const list<IDataItemCore*>& dlist);
|
||||
|
||||
bool updateLockStatus(uint32_t lock);
|
||||
bool updateConnectionStatus(bool connected, uint32_t type);
|
||||
bool updateTac(const string& tac);
|
||||
bool updateMccMnc(const string& mccmnc);
|
||||
inline const MsgTask* getMsgTask() { return mMsgTask; }
|
||||
void subscribe(bool yes);
|
||||
|
||||
private:
|
||||
int createSocket();
|
||||
void closeSocket(const int32_t socketFd);
|
||||
bool sendEvent(const stringstream& event);
|
||||
IOsObserver* mSystemStatusObsrvr;
|
||||
const MsgTask* mMsgTask;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
258
gps/gnss/location_gnss.cpp
Normal file
258
gps/gnss/location_gnss.cpp
Normal file
@@ -0,0 +1,258 @@
|
||||
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation, nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "GnssAdapter.h"
|
||||
#include "location_interface.h"
|
||||
|
||||
static GnssAdapter* gGnssAdapter = NULL;
|
||||
|
||||
static void initialize();
|
||||
static void deinitialize();
|
||||
|
||||
static void addClient(LocationAPI* client, const LocationCallbacks& callbacks);
|
||||
static void removeClient(LocationAPI* client);
|
||||
static void requestCapabilities(LocationAPI* client);
|
||||
|
||||
static uint32_t startTracking(LocationAPI* client, LocationOptions& options);
|
||||
static void updateTrackingOptions(LocationAPI* client, uint32_t id, LocationOptions& options);
|
||||
static void stopTracking(LocationAPI* client, uint32_t id);
|
||||
|
||||
static void gnssNiResponse(LocationAPI* client, uint32_t id, GnssNiResponse response);
|
||||
static uint32_t gnssDeleteAidingData(GnssAidingData& data);
|
||||
|
||||
static void setControlCallbacks(LocationControlCallbacks& controlCallbacks);
|
||||
static uint32_t enable(LocationTechnologyType techType);
|
||||
static void disable(uint32_t id);
|
||||
static uint32_t* gnssUpdateConfig(GnssConfig config);
|
||||
|
||||
static void injectLocation(double latitude, double longitude, float accuracy);
|
||||
static void injectTime(int64_t time, int64_t timeReference, int32_t uncertainty);
|
||||
|
||||
static void agpsInit(const AgpsCbInfo& cbInfo);
|
||||
static void agpsDataConnOpen(AGpsExtType agpsType, const char* apnName, int apnLen, int ipType);
|
||||
static void agpsDataConnClosed(AGpsExtType agpsType);
|
||||
static void agpsDataConnFailed(AGpsExtType agpsType);
|
||||
static void getDebugReport(GnssDebugReport& report);
|
||||
static void updateConnectionStatus(bool connected, uint8_t type);
|
||||
|
||||
static const GnssInterface gGnssInterface = {
|
||||
sizeof(GnssInterface),
|
||||
initialize,
|
||||
deinitialize,
|
||||
addClient,
|
||||
removeClient,
|
||||
requestCapabilities,
|
||||
startTracking,
|
||||
updateTrackingOptions,
|
||||
stopTracking,
|
||||
gnssNiResponse,
|
||||
setControlCallbacks,
|
||||
enable,
|
||||
disable,
|
||||
gnssUpdateConfig,
|
||||
gnssDeleteAidingData,
|
||||
injectLocation,
|
||||
injectTime,
|
||||
agpsInit,
|
||||
agpsDataConnOpen,
|
||||
agpsDataConnClosed,
|
||||
agpsDataConnFailed,
|
||||
getDebugReport,
|
||||
updateConnectionStatus,
|
||||
};
|
||||
|
||||
#ifndef DEBUG_X86
|
||||
extern "C" const GnssInterface* getGnssInterface()
|
||||
#else
|
||||
const GnssInterface* getGnssInterface()
|
||||
#endif // DEBUG_X86
|
||||
{
|
||||
return &gGnssInterface;
|
||||
}
|
||||
|
||||
static void initialize()
|
||||
{
|
||||
if (NULL == gGnssAdapter) {
|
||||
gGnssAdapter = new GnssAdapter();
|
||||
}
|
||||
}
|
||||
|
||||
static void deinitialize()
|
||||
{
|
||||
if (NULL != gGnssAdapter) {
|
||||
delete gGnssAdapter;
|
||||
gGnssAdapter = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void addClient(LocationAPI* client, const LocationCallbacks& callbacks)
|
||||
{
|
||||
if (NULL != gGnssAdapter) {
|
||||
gGnssAdapter->addClientCommand(client, callbacks);
|
||||
}
|
||||
}
|
||||
|
||||
static void removeClient(LocationAPI* client)
|
||||
{
|
||||
if (NULL != gGnssAdapter) {
|
||||
gGnssAdapter->removeClientCommand(client);
|
||||
}
|
||||
}
|
||||
|
||||
static void requestCapabilities(LocationAPI* client)
|
||||
{
|
||||
if (NULL != gGnssAdapter) {
|
||||
gGnssAdapter->requestCapabilitiesCommand(client);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t startTracking(LocationAPI* client, LocationOptions& options)
|
||||
{
|
||||
if (NULL != gGnssAdapter) {
|
||||
return gGnssAdapter->startTrackingCommand(client, options);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void updateTrackingOptions(LocationAPI* client, uint32_t id, LocationOptions& options)
|
||||
{
|
||||
if (NULL != gGnssAdapter) {
|
||||
gGnssAdapter->updateTrackingOptionsCommand(client, id, options);
|
||||
}
|
||||
}
|
||||
|
||||
static void stopTracking(LocationAPI* client, uint32_t id)
|
||||
{
|
||||
if (NULL != gGnssAdapter) {
|
||||
gGnssAdapter->stopTrackingCommand(client, id);
|
||||
}
|
||||
}
|
||||
|
||||
static void gnssNiResponse(LocationAPI* client, uint32_t id, GnssNiResponse response)
|
||||
{
|
||||
if (NULL != gGnssAdapter) {
|
||||
gGnssAdapter->gnssNiResponseCommand(client, id, response);
|
||||
}
|
||||
}
|
||||
|
||||
static void setControlCallbacks(LocationControlCallbacks& controlCallbacks)
|
||||
{
|
||||
if (NULL != gGnssAdapter) {
|
||||
return gGnssAdapter->setControlCallbacksCommand(controlCallbacks);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t enable(LocationTechnologyType techType)
|
||||
{
|
||||
if (NULL != gGnssAdapter) {
|
||||
return gGnssAdapter->enableCommand(techType);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void disable(uint32_t id)
|
||||
{
|
||||
if (NULL != gGnssAdapter) {
|
||||
return gGnssAdapter->disableCommand(id);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t* gnssUpdateConfig(GnssConfig config)
|
||||
{
|
||||
if (NULL != gGnssAdapter) {
|
||||
return gGnssAdapter->gnssUpdateConfigCommand(config);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t gnssDeleteAidingData(GnssAidingData& data)
|
||||
{
|
||||
if (NULL != gGnssAdapter) {
|
||||
return gGnssAdapter->gnssDeleteAidingDataCommand(data);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void injectLocation(double latitude, double longitude, float accuracy)
|
||||
{
|
||||
if (NULL != gGnssAdapter) {
|
||||
gGnssAdapter->injectLocationCommand(latitude, longitude, accuracy);
|
||||
}
|
||||
}
|
||||
|
||||
static void injectTime(int64_t time, int64_t timeReference, int32_t uncertainty)
|
||||
{
|
||||
if (NULL != gGnssAdapter) {
|
||||
gGnssAdapter->injectTimeCommand(time, timeReference, uncertainty);
|
||||
}
|
||||
}
|
||||
|
||||
static void agpsInit(const AgpsCbInfo& cbInfo) {
|
||||
|
||||
if (NULL != gGnssAdapter) {
|
||||
gGnssAdapter->initAgpsCommand(cbInfo);
|
||||
}
|
||||
}
|
||||
static void agpsDataConnOpen(
|
||||
AGpsExtType agpsType, const char* apnName, int apnLen, int ipType) {
|
||||
|
||||
if (NULL != gGnssAdapter) {
|
||||
gGnssAdapter->dataConnOpenCommand(
|
||||
agpsType, apnName, apnLen, (AGpsBearerType)ipType);
|
||||
}
|
||||
}
|
||||
static void agpsDataConnClosed(AGpsExtType agpsType) {
|
||||
|
||||
if (NULL != gGnssAdapter) {
|
||||
gGnssAdapter->dataConnClosedCommand(agpsType);
|
||||
}
|
||||
}
|
||||
static void agpsDataConnFailed(AGpsExtType agpsType) {
|
||||
|
||||
if (NULL != gGnssAdapter) {
|
||||
gGnssAdapter->dataConnFailedCommand(agpsType);
|
||||
}
|
||||
}
|
||||
|
||||
static void getDebugReport(GnssDebugReport& report) {
|
||||
|
||||
if (NULL != gGnssAdapter) {
|
||||
gGnssAdapter->getDebugReport(report);
|
||||
}
|
||||
}
|
||||
|
||||
static void updateConnectionStatus(bool connected, uint8_t type) {
|
||||
if (NULL != gGnssAdapter) {
|
||||
gGnssAdapter->getSystemStatus()->eventConnectionStatus(connected, type);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user