diff --git a/core/LocAdapterBase.h b/core/LocAdapterBase.h index be31de6e..8222b24b 100644 --- a/core/LocAdapterBase.h +++ b/core/LocAdapterBase.h @@ -73,6 +73,7 @@ public: inline virtual void setPositionModeInt(LocPosMode& posMode) {} virtual void startFixInt() {} virtual void stopFixInt() {} + virtual void getZppInt() {} virtual void reportPosition(UlpLocation &location, GpsLocationExtended &locationExtended, void* locationExt, diff --git a/core/LocApiBase.cpp b/core/LocApiBase.cpp index 2978fb3f..80e23755 100644 --- a/core/LocApiBase.cpp +++ b/core/LocApiBase.cpp @@ -445,6 +445,10 @@ enum loc_api_adapter_err LocApiBase:: getZppFix(GpsLocation & zppLoc) DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) +enum loc_api_adapter_err LocApiBase:: + getZppFix(GpsLocation & zppLoc, LocPosTechMask & tech_mask) +DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) + int LocApiBase:: initDataServiceClient() DEFAULT_IMPL(-1) diff --git a/core/LocApiBase.h b/core/LocApiBase.h index 04afa53a..e162cfc7 100644 --- a/core/LocApiBase.h +++ b/core/LocApiBase.h @@ -187,6 +187,8 @@ public: setAGLONASSProtocol(unsigned long aGlonassProtocol); virtual enum loc_api_adapter_err getZppFix(GpsLocation & zppLoc); + virtual enum loc_api_adapter_err + getZppFix(GpsLocation & zppLoc, LocPosTechMask & tech_mask); virtual int initDataServiceClient(); virtual int openAndStartDataCall(); virtual void stopDataCall(); diff --git a/core/gps_extended_c.h b/core/gps_extended_c.h index 42df7f68..f970b644 100644 --- a/core/gps_extended_c.h +++ b/core/gps_extended_c.h @@ -56,6 +56,8 @@ extern "C" { #define ULP_LOCATION_IS_FROM_HYBRID 0x0001 /** Position source is GNSS only */ #define ULP_LOCATION_IS_FROM_GNSS 0x0002 +/** Position source is ZPP only */ +#define ULP_LOCATION_IS_FROM_ZPP 0x0004 #define ULP_MIN_INTERVAL_INVALID 0xffffffff @@ -175,6 +177,22 @@ typedef enum loc_position_mode_type { #define MIN_POSSIBLE_FIX_INTERVAL 1000 /* msec */ +/** GpsLocationExtended has valid latitude and longitude. */ +#define GPS_LOCATION_EXTENDED_HAS_LAT_LONG (1U<<0) +/** GpsLocationExtended has valid altitude. */ +#define GPS_LOCATION_EXTENDED_HAS_ALTITUDE (1U<<1) +/** GpsLocationExtended has valid speed. */ +#define GPS_LOCATION_EXTENDED_HAS_SPEED (1U<<2) +/** GpsLocationExtended has valid bearing. */ +#define GPS_LOCATION_EXTENDED_HAS_BEARING (1U<<4) +/** GpsLocationExtended has valid accuracy. */ +#define GPS_LOCATION_EXTENDED_HAS_ACCURACY (1U<<8) + +/** GPS extended supports geofencing */ +#define GPS_EXTENDED_CAPABILITY_GEOFENCE 0x0000001 +/** GPS extended supports batching */ +#define GPS_EXTENDED_CAPABILITY_BATCHING 0x0000002 + /** Flags to indicate which values are valid in a GpsLocationExtended. */ typedef uint16_t GpsLocationExtendedFlags; /** GpsLocationExtended has valid pdop, hdop, vdop. */ @@ -246,7 +264,7 @@ typedef enum { // if necessary. #define DEFAULT_IMPL(rtv) \ { \ - LOC_LOGW("%s: default implementation invoked", __func__); \ + LOC_LOGD("%s: default implementation invoked", __func__); \ return rtv; \ } @@ -286,6 +304,8 @@ enum loc_api_adapter_event_index { LOC_API_ADAPTER_PEDOMETER_CTRL, // LOC_API_ADAPTER_MOTION_CTRL, // LOC_API_ADAPTER_REQUEST_WIFI_AP_DATA, // Wifi ap data + LOC_API_ADAPTER_BATCH_FULL, // Batching on full + LOC_API_ADAPTER_BATCHED_POSITION_REPORT, // Batching on fix LOC_API_ADAPTER_EVENT_MAX }; @@ -309,6 +329,8 @@ enum loc_api_adapter_event_index { #define LOC_API_ADAPTER_BIT_PEDOMETER_CTRL (1<closeDataCall(); } + inline enum loc_api_adapter_err + getZpp(GpsLocation &zppLoc, LocPosTechMask &tech_mask) + { + return mLocApi->getZppFix(zppLoc, tech_mask); + } virtual void handleEngineDownEvent(); virtual void handleEngineUpEvent(); diff --git a/loc_api/libloc_api_50001/loc_eng.cpp b/loc_api/libloc_api_50001/loc_eng.cpp index cd4e34a3..6d6d701a 100644 --- a/loc_api/libloc_api_50001/loc_eng.cpp +++ b/loc_api/libloc_api_50001/loc_eng.cpp @@ -182,6 +182,7 @@ static void loc_eng_handle_engine_up(loc_eng_data_s_type &loc_eng_data) ; static int loc_eng_start_handler(loc_eng_data_s_type &loc_eng_data); static int loc_eng_stop_handler(loc_eng_data_s_type &loc_eng_data); +static int loc_eng_get_zpp_handler(loc_eng_data_s_type &loc_eng_data); static void deleteAidingData(loc_eng_data_s_type &logEng); static AgpsStateMachine* @@ -300,6 +301,28 @@ void LocEngPositionMode::send() const { mAdapter->sendMsg(this); } +LocEngGetZpp::LocEngGetZpp(LocEngAdapter* adapter) : + LocMsg(), mAdapter(adapter) +{ + locallog(); +} +inline void LocEngGetZpp::proc() const +{ + loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mAdapter->getOwner(); + loc_eng_get_zpp_handler(*locEng); +} +inline void LocEngGetZpp::locallog() const +{ + LOC_LOGV("LocEngGetZpp"); +} +inline void LocEngGetZpp::log() const +{ + locallog(); +} +void LocEngGetZpp::send() const { + mAdapter->sendMsg(this); +} + // case LOC_ENG_MSG_SET_TIME: struct LocEngSetTime : public LocMsg { LocEngAdapter* mAdapter; @@ -1920,6 +1943,32 @@ static void loc_inform_gps_status(loc_eng_data_s_type &loc_eng_data, GpsStatusVa EXIT_LOG(%s, VOID_RET); } +static int loc_eng_get_zpp_handler(loc_eng_data_s_type &loc_eng_data) +{ + ENTRY_LOG(); + int ret_val = LOC_API_ADAPTER_ERR_SUCCESS; + UlpLocation location; + LocPosTechMask tech_mask = LOC_POS_TECH_MASK_DEFAULT; + GpsLocationExtended locationExtended; + memset(&locationExtended, 0, sizeof (GpsLocationExtended)); + locationExtended.size = sizeof(locationExtended); + memset(&location, 0, sizeof location); + + ret_val = loc_eng_data.adapter->getZpp(location.gpsLocation, tech_mask); + //Mark the location source as from ZPP + location.gpsLocation.flags |= LOCATION_HAS_SOURCE_INFO; + location.position_source = ULP_LOCATION_IS_FROM_ZPP; + + loc_eng_data.adapter->getUlpProxy()->reportPosition(location, + locationExtended, + NULL, + LOC_SESS_SUCCESS, + tech_mask); + + EXIT_LOG(%d, ret_val); + return ret_val; +} + /* Callback function passed to Data Services State Machine This becomes part of the state machine's servicer and diff --git a/loc_api/libloc_api_50001/loc_eng_msg.h b/loc_api/libloc_api_50001/loc_eng_msg.h index 4790bbee..ae962f55 100644 --- a/loc_api/libloc_api_50001/loc_eng_msg.h +++ b/loc_api/libloc_api_50001/loc_eng_msg.h @@ -280,6 +280,14 @@ struct LocEngUp : public LocMsg { virtual void log() const; }; +struct LocEngGetZpp : public LocMsg { + LocEngAdapter* mAdapter; + LocEngGetZpp(LocEngAdapter* adapter); + virtual void proc() const; + void locallog() const; + virtual void log() const; + void send() const; +}; #ifdef __cplusplus } diff --git a/loc_api/libloc_api_50001/loc_eng_nmea.cpp b/loc_api/libloc_api_50001/loc_eng_nmea.cpp index 97ba4d58..842eda1f 100644 --- a/loc_api/libloc_api_50001/loc_eng_nmea.cpp +++ b/loc_api/libloc_api_50001/loc_eng_nmea.cpp @@ -654,7 +654,7 @@ void loc_eng_nmea_generate_sv(loc_eng_data_s_type *loc_eng_data_p, lengthRemaining = sizeof(sentence); length = snprintf(pMarker, lengthRemaining, "$GPGSV,%d,%d,%02d", - sentenceCount, sentenceNumber, svCount); + sentenceCount, sentenceNumber, gpsCount); if (length < 0 || length >= lengthRemaining) { @@ -732,7 +732,7 @@ void loc_eng_nmea_generate_sv(loc_eng_data_s_type *loc_eng_data_p, lengthRemaining = sizeof(sentence); length = snprintf(pMarker, lengthRemaining, "$GLGSV,%d,%d,%02d", - sentenceCount, sentenceNumber, svCount); + sentenceCount, sentenceNumber, glnCount); if (length < 0 || length >= lengthRemaining) { diff --git a/utils/loc_timer.c b/utils/loc_timer.c index 13f7786f..1e4008eb 100644 --- a/utils/loc_timer.c +++ b/utils/loc_timer.c @@ -34,124 +34,153 @@ #include #include -#define MAX_DELAY_RETRIES 3 +enum timer_state { + READY = 100, + WAITING, + DONE, + ABORT +}; typedef struct { loc_timer_callback callback_func; void *user_data; unsigned int time_msec; + pthread_cond_t timer_cond; + pthread_mutex_t timer_mutex; + enum timer_state state; }timer_data; static void *timer_thread(void *thread_data) { - int ret; - unsigned char retries=0; + int ret = -ETIMEDOUT; struct timespec ts; struct timeval tv; - timer_data t; - t.callback_func = ((timer_data *)thread_data)->callback_func; - t.user_data = ((timer_data *)thread_data)->user_data; - t.time_msec = ((timer_data *)thread_data)->time_msec; - pthread_cond_t timer_cond; - pthread_mutex_t timer_mutex; + timer_data* t = (timer_data*)thread_data; - LOC_LOGD("%s:%d]: Enter. Delay = %d\n", __func__, __LINE__, t.time_msec); - //Copied over all info into local variable. Do not need allocated struct - free(thread_data); + LOC_LOGD("%s:%d]: Enter. Delay = %d\n", __func__, __LINE__, t->time_msec); - if(pthread_cond_init(&timer_cond, NULL)) { - LOC_LOGE("%s:%d]: Pthread cond init failed\n", __func__, __LINE__); - ret = -1; - goto err; + gettimeofday(&tv, NULL); + clock_gettime(CLOCK_REALTIME, &ts); + if(t->time_msec >= 1000) { + ts.tv_sec += t->time_msec/1000; + t->time_msec = t->time_msec % 1000; } - if(pthread_mutex_init(&timer_mutex, NULL)) { - LOC_LOGE("%s:%d]: Pthread mutex init failed\n", __func__, __LINE__); - ret = -1; - goto mutex_err; + if(t->time_msec) + ts.tv_nsec += t->time_msec * 1000000; + if(ts.tv_nsec > 999999999) { + LOC_LOGD("%s:%d]: Large nanosecs\n", __func__, __LINE__); + ts.tv_sec += 1; + ts.tv_nsec -= 1000000000; } - while(retries < MAX_DELAY_RETRIES) { - gettimeofday(&tv, NULL); - clock_gettime(CLOCK_REALTIME, &ts); - if(t.time_msec >= 1000) { - ts.tv_sec += t.time_msec/1000; - t.time_msec = t.time_msec % 1000; - } - if(t.time_msec) - ts.tv_nsec += t.time_msec * 1000000; - if(ts.tv_nsec > 999999999) { - LOC_LOGD("%s:%d]: Large nanosecs\n", __func__, __LINE__); - ts.tv_sec += 1; - ts.tv_nsec -= 1000000000; - } - LOC_LOGD("%s:%d]: ts.tv_sec:%d; ts.tv_nsec:%d\n", - __func__, __LINE__, (int)ts.tv_sec, (int)ts.tv_nsec); - LOC_LOGD("%s:%d]: Current time: %d sec; %d nsec\n", - __func__, __LINE__, (int)tv.tv_sec, (int)tv.tv_usec*1000); - pthread_mutex_lock(&(timer_mutex)); - ret = pthread_cond_timedwait(&timer_cond, &timer_mutex, &ts); - pthread_mutex_unlock(&(timer_mutex)); - if(ret != ETIMEDOUT) { - LOC_LOGE("%s:%d]: Call to pthread timedwait failed; ret=%d\n", - __func__, __LINE__,ret); - ret = -1; - retries++; - } - else { - ret = 0; - break; - } + LOC_LOGD("%s:%d]: ts.tv_sec:%d; ts.tv_nsec:%d\n" + "\t Current time: %d sec; %d nsec", + __func__, __LINE__, (int)ts.tv_sec, (int)ts.tv_nsec, + (int)tv.tv_sec, (int)tv.tv_usec*1000); + + pthread_mutex_lock(&(t->timer_mutex)); + if (READY == t->state) { + t->state = WAITING; + ret = pthread_cond_timedwait(&t->timer_cond, &t->timer_mutex, &ts); + t->state = DONE; + } + pthread_mutex_unlock(&(t->timer_mutex)); + + switch (ret) { + case ETIMEDOUT: + LOC_LOGV("%s:%d]: loc_timer timed out", __func__, __LINE__); + break; + case 0: + LOC_LOGV("%s:%d]: loc_timer stopped", __func__, __LINE__); + break; + case -ETIMEDOUT: + LOC_LOGV("%s:%d]: loc_timer cancelled", __func__, __LINE__); + break; + default: + LOC_LOGE("%s:%d]: Call to pthread timedwait failed; ret=%d\n", + __func__, __LINE__, ret); + break; } - pthread_mutex_destroy(&timer_mutex); -mutex_err: - pthread_cond_destroy(&timer_cond); -err: - if(!ret) - t.callback_func(t.user_data, ret); + pthread_mutex_destroy(&t->timer_mutex); + pthread_cond_destroy(&t->timer_cond); + + if(ETIMEDOUT == ret) + t->callback_func(t->user_data, ret); + + free(t); LOC_LOGD("%s:%d]: Exit\n", __func__, __LINE__); return NULL; } -int loc_timer_start(unsigned int msec, loc_timer_callback cb_func, - void* caller_data) +void* loc_timer_start(unsigned int msec, loc_timer_callback cb_func, + void* caller_data) { - int ret=0; timer_data *t=NULL; pthread_attr_t tattr; pthread_t id; LOC_LOGD("%s:%d]: Enter\n", __func__, __LINE__); if(cb_func == NULL || msec == 0) { LOC_LOGE("%s:%d]: Error: Wrong parameters\n", __func__, __LINE__); - ret = -1; - goto err; + goto _err; } t = (timer_data *)calloc(1, sizeof(timer_data)); if(t == NULL) { LOC_LOGE("%s:%d]: Could not allocate memory. Failing.\n", __func__, __LINE__); - ret = -1; - goto err; + goto _err; + } + + if(pthread_cond_init(&(t->timer_cond), NULL)) { + LOC_LOGE("%s:%d]: Pthread cond init failed\n", __func__, __LINE__); + goto t_err; + } + if(pthread_mutex_init(&(t->timer_mutex), NULL)) { + LOC_LOGE("%s:%d]: Pthread mutex init failed\n", __func__, __LINE__); + goto cond_err; } t->callback_func = cb_func; t->user_data = caller_data; t->time_msec = msec; + t->state = READY; - pthread_attr_init(&tattr); + if (pthread_attr_init(&tattr)) { + LOC_LOGE("%s:%d]: Pthread mutex init failed\n", __func__, __LINE__); + goto mutex_err; + } pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); + if(pthread_create(&(id), &tattr, timer_thread, (void *)t)) { LOC_LOGE("%s:%d]: Could not create thread\n", __func__, __LINE__); - ret = -1; goto attr_err; } - else { - LOC_LOGD("%s:%d]: Created thread with id: %d\n", - __func__, __LINE__, (int)id); - } + + LOC_LOGD("%s:%d]: Created thread with id: %d\n", + __func__, __LINE__, (int)id); + goto _err; attr_err: pthread_attr_destroy(&tattr); -err: +mutex_err: + pthread_mutex_destroy(&t->timer_mutex); +cond_err: + pthread_cond_destroy(&t->timer_cond); +t_err: + free(t); +_err: LOC_LOGD("%s:%d]: Exit\n", __func__, __LINE__); - return ret; + return t; +} + +void loc_timer_stop(void* handle) { + timer_data* t = (timer_data*)handle; + + if (NULL != t && (READY == t->state || WAITING == t->state)) { + pthread_mutex_lock(&(t->timer_mutex)); + if (READY == t->state || WAITING == t->state) { + pthread_cond_signal(&t->timer_cond); + t->state = ABORT; + } + pthread_mutex_unlock(&(t->timer_mutex)); + } } diff --git a/utils/loc_timer.h b/utils/loc_timer.h index 213da209..0034d278 100644 --- a/utils/loc_timer.h +++ b/utils/loc_timer.h @@ -43,10 +43,19 @@ extern "C" { */ typedef void(*loc_timer_callback)(void *user_data, int result); -//int loc_timer_start(loc_timer_client_data *p_thread); -int loc_timer_start(unsigned int delay_msec, - loc_timer_callback, - void* user_data); + +/* + Returns the handle, which can be used to stop the timer +*/ +void* loc_timer_start(unsigned int delay_msec, + loc_timer_callback, + void* user_data); + +/* + handle becomes invalid upon the return of the callback +*/ +void loc_timer_stop(void* handle); + #ifdef __cplusplus } #endif /* __cplusplus */