diff options
Diffstat (limited to 'location')
-rw-r--r-- | location/Component.cdef | 28 | ||||
-rw-r--r-- | location/location.c | 101 | ||||
-rw-r--r-- | location/location.h | 13 |
3 files changed, 142 insertions, 0 deletions
diff --git a/location/Component.cdef b/location/Component.cdef new file mode 100644 index 0000000..7907352 --- /dev/null +++ b/location/Component.cdef @@ -0,0 +1,28 @@ +cflags: +{ + -std=c99 + -I$BRNKL_ROOT/apps/util +} + +requires: +{ + api: + { + le_posCtrl = ${LEGATO_ROOT}/interfaces/positioning/le_posCtrl.api + le_pos = ${LEGATO_ROOT}/interfaces/positioning/le_pos.api + } +} + +provides: +{ + api: + { + $CURDIR/../brnkl_gps.api + } +} + +sources: +{ + location.c + $BRNKL_ROOT/apps/util/util.c +} diff --git a/location/location.c b/location/location.c new file mode 100644 index 0000000..69b934c --- /dev/null +++ b/location/location.c @@ -0,0 +1,101 @@ +#include "location.h" +#include "interfaces.h" +#include "legato.h" +#include "util.h" + +le_posCtrl_ActivationRef_t posCtrlRef; +double lat, lon, horizAccuracy; +// we initially set these pointers to null +// so we can tell if there has never been a reading +double *latPtr = NULL, *lonPtr = NULL, *horizAccuracyPtr = NULL; +uint64_t lastReadingDatetime = 0; +le_timer_Ref_t pollingTimer; + +bool hasReading() { + return latPtr != NULL && lonPtr != NULL && horizAccuracyPtr != NULL; +} + +bool canGetLocation() { + return hasReading() && posCtrlRef != NULL; +} + +void setLocationPtrs() { + horizAccuracyPtr = &horizAccuracy; + latPtr = ⪫ + lonPtr = &lon; +} + +le_result_t brnkl_gps_getCurrentLocation(double* latitude, + double* longitude, + double* horizontalAccuracy, + uint64_t* lastReading) { + if (!canGetLocation()) { + return LE_UNAVAILABLE; + } + *latitude = *latPtr; + *longitude = *lonPtr; + *horizontalAccuracy = *horizAccuracyPtr; + *lastReading = lastReadingDatetime; + return LE_OK; +} + +/** + * Attempts to use the GPS to find the current latitude, longitude and + * horizontal accuracy within + * the given timeout constraints. + * + * @return + * - LE_OK on success + * - LE_UNAVAILABLE if positioning services are unavailable + * - LE_TIMEOUT if the timeout expires before successfully acquiring the + * location + * + * @note + * Blocks until the location has been identified or the timeout has + * occurred. + */ +void getLocation(le_timer_Ref_t timerRef) { + le_timer_Stop(timerRef); + LE_DEBUG("Checking GPS position"); + int32_t rawLat, rawLon, rawHoriz; + le_result_t result = le_pos_Get2DLocation(&rawLat, &rawLon, &rawHoriz); + bool isAccurate = rawHoriz <= MIN_REQUIRED_HORIZ_ACCURACY_METRES; + bool resOk = result == LE_OK; + if (resOk && isAccurate) { + double denom = powf(10, GPS_DECIMAL_SHIFT); // divide by this + lat = ((double)rawLat) / denom; + lon = ((double)rawLon) / denom; + // no conversion required for horizontal accuracy + horizAccuracy = (double)rawHoriz; + // set these so we know there is a reading + lastReadingDatetime = GetCurrentTimestamp(); + if (!hasReading()) { + setLocationPtrs(); + } + LE_INFO("Got reading..."); + LE_INFO("lat: %f, long: %f, horiz: %f", lat, lon, horizAccuracy); + le_timer_SetMsInterval(timerRef, POLL_PERIOD_SEC * 1000); + } else { + if (!isAccurate && resOk) { + LE_INFO("Rejected for accuracy (%d m)", rawHoriz); + } + LE_INFO("Failed to get reading... retrying in %d seconds", + RETRY_PERIOD_SEC); + le_timer_SetMsInterval(timerRef, RETRY_PERIOD_SEC * 1000); + } + le_timer_Start(timerRef); +} + +le_result_t gps_init() { + pollingTimer = le_timer_Create("GPS polling timer"); + le_timer_SetHandler(pollingTimer, getLocation); + le_timer_SetRepeat(pollingTimer, 1); + le_timer_SetMsInterval(pollingTimer, 0); + posCtrlRef = le_posCtrl_Request(); + le_timer_Start(pollingTimer); + return posCtrlRef != NULL ? LE_OK : LE_UNAVAILABLE; +} + +COMPONENT_INIT { + gps_init(); +} diff --git a/location/location.h b/location/location.h new file mode 100644 index 0000000..8ffa3ed --- /dev/null +++ b/location/location.h @@ -0,0 +1,13 @@ +#ifndef LOCATION_H +#define LOCATION_H + +#include "legato.h" + +// Used to convert GPS int to double +#define GPS_DECIMAL_SHIFT 6 +// Used for distance calculations +#define MIN_REQUIRED_HORIZ_ACCURACY_METRES 10 // TODO validate this +#define POLL_PERIOD_SEC 2 * 60 +#define RETRY_PERIOD_SEC 1 + +#endif // LOCATION_H |