ARM mbed M2X API Client: The ARM mbed client library is used to send/receive data to/from AT&T's M2X service from mbed LPC1768 microcontrollers.
Dependents: m2x-demo-all M2X_MTS_ACCEL_DEMO M2X_MTS_Accel M2X_K64F_ACCEL ... more
Diff: TimeService.cpp
- Revision:
- 22:4d895e732765
- Parent:
- 21:6878944d2ce2
diff -r 6878944d2ce2 -r 4d895e732765 TimeService.cpp --- a/TimeService.cpp Sat Jan 02 02:29:43 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,139 +0,0 @@ -#include "M2XStreamClient.h" - -static int fill_iso8601_timestamp(int32_t seconds, int32_t milli, - char* buffer, int* length); - -TimeService::TimeService(M2XStreamClient* client) : _client(client) { -} - -int TimeService::init() { - _timer.start(); - return reset(); -} - -int TimeService::reset() { - int32_t ts; - int status = _client->getTimestamp32(&ts); - - if (m2x_status_is_success(status)) { - _server_timestamp = ts; - _local_last_milli = _timer.read_ms(); - } - - return status; -} - -int TimeService::getTimestamp(char* buffer, int* length) { - uint32_t now = _timer.read_ms(); - if (now < _local_last_milli) { - // In case of a timestamp overflow(happens once every 50 days on - // Arduino), we reset the server timestamp recorded. - int status = reset(); - if (!m2x_status_is_success(status)) { return status; } - now = _timer.read_ms(); - } - if (now < _local_last_milli) { - // We have already reseted the timestamp, so this cannot happen - // (an HTTP request can take longer than 50 days to finished? You - // must be kidding here). Something else must be wrong here - return E_TIMESTAMP_ERROR; - } - uint32_t diff = now - _local_last_milli; - _local_last_milli = now; - _server_timestamp += (int32_t) (diff / 1000); // Milliseconds to seconds - return fill_iso8601_timestamp(_server_timestamp, (int32_t) (diff % 1000), - buffer, length); -} - -#define SIZE_ISO_8601 25 -static inline bool is_leap_year(int16_t y) { - return ((1970 + y) > 0) && - !((1970 + y) % 4) && - (((1970 + y) % 100) || !((1970 + y) % 400)); -} -static inline int32_t days_in_year(int16_t y) { - return is_leap_year(y) ? 366 : 365; -} -static const uint8_t MONTH_DAYS[]={31,28,31,30,31,30,31,31,30,31,30,31}; - -static int fill_iso8601_timestamp(int32_t timestamp, int32_t milli, - char* buffer, int* length) { - int16_t year; - int8_t month, month_length; - int32_t day; - int8_t hour, minute, second; - - if (*length < SIZE_ISO_8601) { - *length = SIZE_ISO_8601; - return E_BUFFER_TOO_SMALL; - } - - second = timestamp % 60; - timestamp /= 60; // now it is minutes - - minute = timestamp % 60; - timestamp /= 60; // now it is hours - - hour = timestamp % 24; - timestamp /= 24; // now it is days - - year = 0; - day = 0; - while ((day += days_in_year(year)) <= timestamp) { - year++; - } - day -= days_in_year(year); - timestamp -= day; // now it is days in this year, starting at 0 - - day = 0; - month_length = 0; - for (month = 0; month < 12; month++) { - if (month == 1) { - // February - month_length = is_leap_year(year) ? 29 : 28; - } else { - month_length = MONTH_DAYS[month]; - } - - if (timestamp >= month_length) { - timestamp -= month_length; - } else { - break; - } - } - year = 1970 + year; - month++; // offset by 1 - day = timestamp + 1; - - int i = 0, j = 0; - - // NOTE: It seems the snprintf implementation in Arduino has bugs, - // we have to manually piece the string together here. -#define INT_TO_STR(v_, width_) \ - for (j = 0; j < (width_); j++) { \ - buffer[i + (width_) - 1 - j] = '0' + ((v_) % 10); \ - (v_) /= 10; \ - } \ - i += (width_) - - INT_TO_STR(year, 4); - buffer[i++] = '-'; - INT_TO_STR(month, 2); - buffer[i++] = '-'; - INT_TO_STR(day, 2); - buffer[i++] = 'T'; - INT_TO_STR(hour, 2); - buffer[i++] = ':'; - INT_TO_STR(minute, 2); - buffer[i++] = ':'; - INT_TO_STR(second, 2); - buffer[i++] = '.'; - INT_TO_STR(milli, 3); - buffer[i++] = 'Z'; - buffer[i++] = '\0'; - -#undef INT_TO_STR - - *length = i; - return E_OK; -}