diff options
Diffstat (limited to 'src/components/ble')
| -rw-r--r-- | src/components/ble/CurrentTimeClient.cpp | 20 | ||||
| -rw-r--r-- | src/components/ble/CurrentTimeClient.h | 10 | ||||
| -rw-r--r-- | src/components/ble/CurrentTimeService.cpp | 95 | ||||
| -rw-r--r-- | src/components/ble/CurrentTimeService.h | 27 |
4 files changed, 99 insertions, 53 deletions
diff --git a/src/components/ble/CurrentTimeClient.cpp b/src/components/ble/CurrentTimeClient.cpp index 53e98cb6..96134526 100644 --- a/src/components/ble/CurrentTimeClient.cpp +++ b/src/components/ble/CurrentTimeClient.cpp @@ -85,21 +85,11 @@ int CurrentTimeClient::OnCurrentTimeReadResult(uint16_t conn_handle, const ble_g // TODO check that attribute->handle equals the handle discovered in OnCharacteristicDiscoveryEvent CtsData result; os_mbuf_copydata(attribute->om, 0, sizeof(CtsData), &result); - NRF_LOG_INFO("Received data: %d-%d-%d %d:%d:%d", - result.year, - result.month, - result.dayofmonth, - result.hour, - result.minute, - result.second); - dateTimeController.SetTime(result.year, - result.month, - result.dayofmonth, - 0, - result.hour, - result.minute, - result.second, - nrf_rtc_counter_get(portNRF_RTC_REG)); + uint16_t year = ((uint16_t) result.year_MSO << 8) + result.year_LSO; + + NRF_LOG_INFO("Received data: %d-%d-%d %d:%d:%d", year, result.month, result.dayofmonth, result.hour, result.minute, result.second); + dateTimeController + .SetTime(year, result.month, result.dayofmonth, 0, result.hour, result.minute, result.second, nrf_rtc_counter_get(portNRF_RTC_REG)); } else { NRF_LOG_INFO("Error retrieving current time: %d", error->status); } diff --git a/src/components/ble/CurrentTimeClient.h b/src/components/ble/CurrentTimeClient.h index 9e48be79..c718d2d9 100644 --- a/src/components/ble/CurrentTimeClient.h +++ b/src/components/ble/CurrentTimeClient.h @@ -29,14 +29,16 @@ namespace Pinetime { private: typedef struct __attribute__((packed)) { - uint16_t year; + uint8_t year_LSO; // explicit byte ordering to be independent of machine order + uint8_t year_MSO; // BLE GATT is little endian uint8_t month; uint8_t dayofmonth; uint8_t hour; uint8_t minute; uint8_t second; - uint8_t millis; - uint8_t reason; + uint8_t dayofweek; + uint8_t fractions256; // currently ignored + uint8_t reason; // currently ignored, not that any host would set it anyway } CtsData; static constexpr uint16_t ctsServiceId {0x1805}; @@ -55,4 +57,4 @@ namespace Pinetime { std::function<void(uint16_t)> onServiceDiscovered; }; } -}
\ No newline at end of file +} diff --git a/src/components/ble/CurrentTimeService.cpp b/src/components/ble/CurrentTimeService.cpp index 8430d1bc..a264efba 100644 --- a/src/components/ble/CurrentTimeService.cpp +++ b/src/components/ble/CurrentTimeService.cpp @@ -5,11 +5,23 @@ using namespace Pinetime::Controllers; constexpr ble_uuid16_t CurrentTimeService::ctsUuid; -constexpr ble_uuid16_t CurrentTimeService::ctChrUuid; +constexpr ble_uuid16_t CurrentTimeService::ctsCtChrUuid; +constexpr ble_uuid16_t CurrentTimeService::ctsLtChrUuid; int CTSCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt, void* arg) { auto cts = static_cast<CurrentTimeService*>(arg); - return cts->OnTimeAccessed(conn_handle, attr_handle, ctxt); + + return cts->OnCurrentTimeServiceAccessed(conn_handle, attr_handle, ctxt); +} + +int CurrentTimeService::OnCurrentTimeServiceAccessed(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt) { + switch (ble_uuid_u16(ctxt->chr->uuid)) { + case ctsCurrentTimeCharId: + return OnCurrentTimeAccessed(conn_handle, attr_handle, ctxt); + case ctsLocalTimeCharId: + return OnLocalTimeAccessed(conn_handle, attr_handle, ctxt); + } + return -1; // Unknown characteristic } void CurrentTimeService::Init() { @@ -18,45 +30,69 @@ void CurrentTimeService::Init() { ASSERT(res == 0); res = ble_gatts_add_svcs(serviceDefinition); + ASSERT(res == 0); } -int CurrentTimeService::OnTimeAccessed(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt) { +int CurrentTimeService::OnCurrentTimeAccessed(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt) { NRF_LOG_INFO("Setting time..."); if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { - CtsData result; - os_mbuf_copydata(ctxt->om, 0, sizeof(CtsData), &result); + CtsCurrentTimeData result; + int res = os_mbuf_copydata(ctxt->om, 0, sizeof(CtsCurrentTimeData), &result); + if (res < 0) { + NRF_LOG_ERROR("Error reading BLE Data writing to CTS Current Time (too little data)") + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + + uint16_t year = ((uint16_t) result.year_MSO << 8) + result.year_LSO; - NRF_LOG_INFO("Received data: %d-%d-%d %d:%d:%d", - result.year, - result.month, - result.dayofmonth, - result.hour, - result.minute, - result.second); + NRF_LOG_INFO("Received data: %d-%d-%d %d:%d:%d", year, result.month, result.dayofmonth, result.hour, result.minute, result.second); - m_dateTimeController.SetTime(result.year, - result.month, - result.dayofmonth, - 0, - result.hour, - result.minute, - result.second, - nrf_rtc_counter_get(portNRF_RTC_REG)); + m_dateTimeController + .SetTime(year, result.month, result.dayofmonth, 0, result.hour, result.minute, result.second, nrf_rtc_counter_get(portNRF_RTC_REG)); } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { - CtsData currentDateTime; - currentDateTime.year = m_dateTimeController.Year(); + CtsCurrentTimeData currentDateTime; + currentDateTime.year_LSO = m_dateTimeController.Year() & 0xff; + currentDateTime.year_MSO = (m_dateTimeController.Year() >> 8) & 0xff; currentDateTime.month = static_cast<u_int8_t>(m_dateTimeController.Month()); currentDateTime.dayofmonth = m_dateTimeController.Day(); currentDateTime.hour = m_dateTimeController.Hours(); currentDateTime.minute = m_dateTimeController.Minutes(); currentDateTime.second = m_dateTimeController.Seconds(); - currentDateTime.millis = 0; + currentDateTime.fractions256 = 0; - int res = os_mbuf_append(ctxt->om, ¤tDateTime, sizeof(CtsData)); + int res = os_mbuf_append(ctxt->om, ¤tDateTime, sizeof(CtsCurrentTimeData)); + return (res == 0) ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + } + + return 0; +} + +int CurrentTimeService::OnLocalTimeAccessed(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt) { + NRF_LOG_INFO("Setting timezone..."); + + if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { + CtsLocalTimeData result; + int res = os_mbuf_copydata(ctxt->om, 0, sizeof(CtsLocalTimeData), &result); + + if (res < 0) { + NRF_LOG_ERROR("Error reading BLE Data writing to CTS Local Time (too little data)") + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + + NRF_LOG_INFO("Received data: %d %d", result.timezone, result.dst); + + m_dateTimeController.SetTimeZone(result.timezone, result.dst); + + } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { + CtsLocalTimeData currentTimezone; + currentTimezone.timezone = m_dateTimeController.TzOffset(); + currentTimezone.dst = m_dateTimeController.DstOffset(); + + int res = os_mbuf_append(ctxt->om, ¤tTimezone, sizeof(currentTimezone)); return (res == 0) ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; } @@ -64,12 +100,19 @@ int CurrentTimeService::OnTimeAccessed(uint16_t conn_handle, uint16_t attr_handl } CurrentTimeService::CurrentTimeService(DateTime& dateTimeController) - : characteristicDefinition {{.uuid = &ctChrUuid.u, + : characteristicDefinition { + + {.uuid = &ctsLtChrUuid.u, .access_cb = CTSCallback, + .arg = this, + .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ}, + {.uuid = &ctsCtChrUuid.u, + .access_cb = CTSCallback, .arg = this, .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ}, - {0}}, + + {0}}, serviceDefinition { {/* Device Information Service */ .type = BLE_GATT_SVC_TYPE_PRIMARY, diff --git a/src/components/ble/CurrentTimeService.h b/src/components/ble/CurrentTimeService.h index ca87d970..91544314 100644 --- a/src/components/ble/CurrentTimeService.h +++ b/src/components/ble/CurrentTimeService.h @@ -16,29 +16,40 @@ namespace Pinetime { CurrentTimeService(DateTime& dateTimeController); void Init(); - int OnTimeAccessed(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt); + int OnCurrentTimeServiceAccessed(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt); + int OnCurrentTimeAccessed(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt); + int OnLocalTimeAccessed(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt); private: static constexpr uint16_t ctsId {0x1805}; - static constexpr uint16_t ctsCharId {0x2a2b}; + static constexpr uint16_t ctsCurrentTimeCharId {0x2a2b}; + static constexpr uint16_t ctsLocalTimeCharId {0x2a0f}; static constexpr ble_uuid16_t ctsUuid {.u {.type = BLE_UUID_TYPE_16}, .value = ctsId}; - static constexpr ble_uuid16_t ctChrUuid {.u {.type = BLE_UUID_TYPE_16}, .value = ctsCharId}; + static constexpr ble_uuid16_t ctsCtChrUuid {.u {.type = BLE_UUID_TYPE_16}, .value = ctsCurrentTimeCharId}; + static constexpr ble_uuid16_t ctsLtChrUuid {.u {.type = BLE_UUID_TYPE_16}, .value = ctsLocalTimeCharId}; - struct ble_gatt_chr_def characteristicDefinition[2]; + struct ble_gatt_chr_def characteristicDefinition[3]; struct ble_gatt_svc_def serviceDefinition[2]; typedef struct __attribute__((packed)) { - uint16_t year; + uint8_t year_LSO; // BLE GATT is little endian + uint8_t year_MSO; uint8_t month; uint8_t dayofmonth; uint8_t hour; uint8_t minute; uint8_t second; - uint8_t millis; - uint8_t reason; - } CtsData; + uint8_t dayofweek; + uint8_t fractions256; // currently ignored + uint8_t reason; // currently ignored, not that any host would set it anyway + } CtsCurrentTimeData; + + typedef struct __attribute__((packed)) { + uint8_t timezone; + uint8_t dst; + } CtsLocalTimeData; DateTime& m_dateTimeController; }; |
