BLE Current Time Service
BLE Current Time Service (CTS) implementation.
supported only "Current Time" Characteristics.
https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx
I don't have a device corresponding to the CTS, I cannot check it. x)
Diff: CurrentTimeService.h
- Revision:
- 0:8c79e11bc3a1
- Child:
- 1:c4b8028471f9
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CurrentTimeService.h Sat Oct 17 16:56:39 2015 +0000 @@ -0,0 +1,193 @@ +/* + * BLE Current Time Service (subset) + * + * by ohneta/ Oct. 2015 + */ +#ifndef __BLE_CURRENT_TIME_SERVICE_H__ +#define __BLE_CURRENT_TIME_SERVICE_H__ + +//extern Serial pc; + +#include "ble/BLE.h" +//#include "app_util.h" + + +enum BLE_DayofWeek { + notknown = 0, + Monday = 1, + Tuesday, + Wednesday, + Thursday, + Friday, + Saturday, + Sunday +}; + +typedef struct { + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t hours; + uint8_t minutes; + uint8_t seconds; +} BLE_DateTime; + +typedef struct : BLE_DateTime { + BLE_DayofWeek dayOfWeek; +} BLE_DayDateTime; + +typedef struct BEL_ExactTime256 : BLE_DayDateTime { + uint8_t fractions256; +} BEL_ExactTime256; + +typedef struct BEL_CurrentTime : BEL_ExactTime256 { + uint8_t adjustReason; +} BEL_CurrentTime; + +#define BLE_CURRENT_TIME_CHAR_VALUE_SIZE 10 + +/** + * + */ +class CurrentTimeService { + +protected: + Ticker ticker; + + /** + * ticker callback. + * interval = 1sec + */ + void epochtimePeriodicCallback(void) + { + time_t tmpEpochTime = epochTimeByDateTimeBuffer(); + tmpEpochTime++; + dataTimeBufferByEpochTime(&tmpEpochTime); + } + + void dataTimeBufferByEpochTime(time_t *epochTime) + { + struct tm *tmPtr = localtime(epochTime); + + *(uint16_t *)&valueBytes[0] = tmPtr->tm_year + 1900; + valueBytes[2] = tmPtr->tm_mon + 1; + valueBytes[3] = tmPtr->tm_mday; + valueBytes[4] = tmPtr->tm_hour; + valueBytes[5] = tmPtr->tm_min; + valueBytes[6] = tmPtr->tm_sec; + valueBytes[7] = (BLE_DayofWeek)((tmPtr->tm_wday == 0) ? 7 : tmPtr->tm_wday); + valueBytes[8] = 0x00; + valueBytes[9] = 0x00; + + ble.gattServer().write(currentTimeCharacteristic.getValueHandle(), valueBytes, BLE_CURRENT_TIME_CHAR_VALUE_SIZE); + } + + time_t epochTimeByDateTimeBuffer() + { + struct tm timep; + { + timep.tm_year = *(uint16_t *)&valueBytes[0] - 1900; + timep.tm_mon = valueBytes[2] - 1; + timep.tm_mday = valueBytes[3]; + timep.tm_hour = valueBytes[4]; + timep.tm_min = valueBytes[5]; + timep.tm_sec = valueBytes[6]; + timep.tm_isdst = 0; + } + time_t epochTime = mktime(&timep); + + return epochTime; + } + +public: + //------------------------------------------------------------------------------------ + /** + * + */ + CurrentTimeService(BLE &_ble, BLE_DateTime &initialDateTime) : + ble(_ble), + currentTimeCharacteristic( GattCharacteristic::UUID_CURRENT_TIME_CHAR, + valueBytes, BLE_CURRENT_TIME_CHAR_VALUE_SIZE, BLE_CURRENT_TIME_CHAR_VALUE_SIZE, + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ + | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY + | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE + ) + { + writeDateTime(initialDateTime); + ticker.attach(this, &CurrentTimeService::epochtimePeriodicCallback, 1.0); + + GattCharacteristic *charsTable[] = {¤tTimeCharacteristic}; + GattService currentTimeService(GattService::UUID_CURRENT_TIME_SERVICE, charsTable, sizeof(charsTable) / sizeof(GattCharacteristic *) ); + + ble.addService(currentTimeService); + ble.onDataWritten(this, &CurrentTimeService::onDataWritten); + } + + /** + */ + void writeDateTime(BLE_DateTime &dateTime) + { + *(uint16_t *)&valueBytes[0] = dateTime.year; + valueBytes[2] = dateTime.month; + valueBytes[3] = dateTime.day; + valueBytes[4] = dateTime.hours; + valueBytes[5] = dateTime.minutes; + valueBytes[6] = dateTime.seconds; + + // not support + valueBytes[7] = 0x00; // day of week + valueBytes[8] = 0x00; // Fractions256 + valueBytes[9] = 0x00; // Adjust Reason + } + + /** + */ + void readDateTime(BLE_DateTime &dateTime) + { + dateTime.year = (uint16_t)valueBytes[0] << 8 | valueBytes[1]; + dateTime.month = valueBytes[2]; + dateTime.day = valueBytes[3]; + dateTime.hours = valueBytes[4]; + dateTime.minutes = valueBytes[5]; + dateTime.seconds = valueBytes[6]; + } + + + // for BLE GATT callback + // "WRITE" is optionaly + virtual void onDataWritten(const GattWriteCallbackParams *params) + { + if (params->handle == currentTimeCharacteristic.getValueHandle()) { + memcpy((void *)&valueBytes, params->data, params->len); + } + } + +protected: + BLE &ble; + uint8_t valueBytes[BLE_CURRENT_TIME_CHAR_VALUE_SIZE]; + GattCharacteristic currentTimeCharacteristic; + + + +/* + // for debug infos. + void printExactTime256Buffer() + { + BEL_CurrentTime currentTime; + currentTime.year = *((uint16_t *)&valueBytes[0]); + currentTime.month = valueBytes[2]; + currentTime.day = valueBytes[3]; + currentTime.hours = valueBytes[4]; + currentTime.minutes = valueBytes[5]; + currentTime.seconds = valueBytes[6]; + currentTime.dayOfWeek = (BLE_DayofWeek)valueBytes[7]; + + pc.printf("%04d-%02d-%02d %02d:%02d:%02d [%02d]\n", + currentTime.year, currentTime.month, currentTime.day, + currentTime.hours, currentTime.minutes, currentTime.seconds, + currentTime.dayOfWeek ); + } +*/ +}; + +#endif /* #ifndef __BLE_CURRENT_TIME_SERVICE_H__*/