diff --git a/CMakeLists.txt b/CMakeLists.txt index edd6748..6923efa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -118,6 +118,8 @@ target_sources(infinisim PUBLIC sim/components/battery/BatteryController.cpp sim/components/ble/AlertNotificationService.h sim/components/ble/AlertNotificationService.cpp + sim/components/ble/MotionService.h + sim/components/ble/MotionService.cpp sim/components/ble/MusicService.h sim/components/ble/MusicService.cpp sim/components/ble/NavigationService.h diff --git a/InfiniTime b/InfiniTime index fc5424c..a6cd367 160000 --- a/InfiniTime +++ b/InfiniTime @@ -1 +1 @@ -Subproject commit fc5424cb72e477c5f1bbfaeddb5c50b851a965ae +Subproject commit a6cd3679eb1219865a215d0600c9703b198f9157 diff --git a/sim/components/ble/MotionService.cpp b/sim/components/ble/MotionService.cpp new file mode 100644 index 0000000..409d3b7 --- /dev/null +++ b/sim/components/ble/MotionService.cpp @@ -0,0 +1,126 @@ +#include "components/ble/MotionService.h" +#include "components/motion/MotionController.h" +#include "components/ble/NimbleController.h" +#include + +using namespace Pinetime::Controllers; + +// namespace { +// // 0003yyxx-78fc-48fe-8e23-433b3a1942d0 +// constexpr ble_uuid128_t CharUuid(uint8_t x, uint8_t y) { +// return ble_uuid128_t {.u = {.type = BLE_UUID_TYPE_128}, +// .value = {0xd0, 0x42, 0x19, 0x3a, 0x3b, 0x43, 0x23, 0x8e, 0xfe, 0x48, 0xfc, 0x78, x, y, 0x03, 0x00}}; +// } +// +// // 00030000-78fc-48fe-8e23-433b3a1942d0 +// constexpr ble_uuid128_t BaseUuid() { +// return CharUuid(0x00, 0x00); +// } +// +// constexpr ble_uuid128_t motionServiceUuid {BaseUuid()}; +// constexpr ble_uuid128_t stepCountCharUuid {CharUuid(0x01, 0x00)}; +// constexpr ble_uuid128_t motionValuesCharUuid {CharUuid(0x02, 0x00)}; +// +// int MotionServiceCallback(uint16_t /*conn_handle*/, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt, void* arg) { +// auto* motionService = static_cast(arg); +// return motionService->OnStepCountRequested(attr_handle, ctxt); +// } +// } +// +// TODO Refactoring - remove dependency to SystemTask +MotionService::MotionService(NimbleController& nimble, Controllers::MotionController& motionController) + : nimble {nimble}, + motionController {motionController}/*, + characteristicDefinition {{.uuid = &stepCountCharUuid.u, + .access_cb = MotionServiceCallback, + .arg = this, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_NOTIFY, + .val_handle = &stepCountHandle}, + {.uuid = &motionValuesCharUuid.u, + .access_cb = MotionServiceCallback, + .arg = this, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_NOTIFY, + .val_handle = &motionValuesHandle}, + {0}}, + serviceDefinition { + {.type = BLE_GATT_SVC_TYPE_PRIMARY, .uuid = &motionServiceUuid.u, .characteristics = characteristicDefinition}, + {0}, + } */{ + // TODO refactor to prevent this loop dependency (service depends on controller and controller depends on service) + motionController.SetService(this); +} +// +// void MotionService::Init() { +// int res = 0; +// res = ble_gatts_count_cfg(serviceDefinition); +// ASSERT(res == 0); +// +// res = ble_gatts_add_svcs(serviceDefinition); +// ASSERT(res == 0); +// } +// +// int MotionService::OnStepCountRequested(uint16_t attributeHandle, ble_gatt_access_ctxt* context) { +// if (attributeHandle == stepCountHandle) { +// NRF_LOG_INFO("Motion-stepcount : handle = %d", stepCountHandle); +// uint32_t buffer = motionController.NbSteps(); +// +// int res = os_mbuf_append(context->om, &buffer, 4); +// return (res == 0) ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; +// } else if (attributeHandle == motionValuesHandle) { +// int16_t buffer[3] = {motionController.X(), motionController.Y(), motionController.Z()}; +// +// int res = os_mbuf_append(context->om, buffer, 3 * sizeof(int16_t)); +// return (res == 0) ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; +// } +// return 0; +// } +// +// void MotionService::OnNewStepCountValue(uint32_t stepCount) { +// if (!stepCountNoficationEnabled) +// return; +// +// uint32_t buffer = stepCount; +// auto* om = ble_hs_mbuf_from_flat(&buffer, 4); +// +// uint16_t connectionHandle = nimble.connHandle(); +// +// if (connectionHandle == 0 || connectionHandle == BLE_HS_CONN_HANDLE_NONE) { +// return; +// } +// +// ble_gattc_notify_custom(connectionHandle, stepCountHandle, om); +// } +// +// void MotionService::OnNewMotionValues(int16_t x, int16_t y, int16_t z) { +// if (!motionValuesNoficationEnabled) +// return; +// +// int16_t buffer[3] = {x, y, z}; +// auto* om = ble_hs_mbuf_from_flat(buffer, 3 * sizeof(int16_t)); +// +// uint16_t connectionHandle = nimble.connHandle(); +// +// if (connectionHandle == 0 || connectionHandle == BLE_HS_CONN_HANDLE_NONE) { +// return; +// } +// +// ble_gattc_notify_custom(connectionHandle, motionValuesHandle, om); +// } + +void MotionService::SubscribeNotification(uint16_t attributeHandle) { + if (attributeHandle == stepCountHandle) + stepCountNoficationEnabled = true; + else if (attributeHandle == motionValuesHandle) + motionValuesNoficationEnabled = true; +} + +void MotionService::UnsubscribeNotification(uint16_t attributeHandle) { + if (attributeHandle == stepCountHandle) + stepCountNoficationEnabled = false; + else if (attributeHandle == motionValuesHandle) + motionValuesNoficationEnabled = false; +} + +bool MotionService::IsMotionNotificationSubscribed() const { + return motionValuesNoficationEnabled; +} diff --git a/sim/components/ble/MotionService.h b/sim/components/ble/MotionService.h new file mode 100644 index 0000000..a607c3e --- /dev/null +++ b/sim/components/ble/MotionService.h @@ -0,0 +1,39 @@ +#pragma once +// #define min // workaround: nimble's min/max macros conflict with libstdc++ +// #define max +// #include +#include +// #undef max +// #undef min + +namespace Pinetime { + namespace Controllers { + class NimbleController; + class MotionController; + + class MotionService { + public: + MotionService(NimbleController& nimble, Controllers::MotionController& motionController); + // void Init(); + // int OnStepCountRequested(uint16_t attributeHandle, ble_gatt_access_ctxt* context); + // void OnNewStepCountValue(uint32_t stepCount); + // void OnNewMotionValues(int16_t x, int16_t y, int16_t z); + + void SubscribeNotification(uint16_t attributeHandle); + void UnsubscribeNotification(uint16_t attributeHandle); + bool IsMotionNotificationSubscribed() const; + + private: + NimbleController& nimble; + Controllers::MotionController& motionController; + + // struct ble_gatt_chr_def characteristicDefinition[3]; + // struct ble_gatt_svc_def serviceDefinition[2]; + + uint16_t stepCountHandle; + uint16_t motionValuesHandle; + std::atomic_bool stepCountNoficationEnabled {false}; + std::atomic_bool motionValuesNoficationEnabled {false}; + }; + } +} diff --git a/sim/components/ble/NimbleController.cpp b/sim/components/ble/NimbleController.cpp index 388b8a1..44a2d9a 100644 --- a/sim/components/ble/NimbleController.cpp +++ b/sim/components/ble/NimbleController.cpp @@ -45,11 +45,11 @@ NimbleController::NimbleController(Pinetime::System::SystemTask& systemTask, // currentTimeService {dateTimeController}, musicService {systemTask}, weatherService {dateTimeController}, - navService {systemTask} { + navService {systemTask}, // batteryInformationService {batteryController}, // immediateAlertService {systemTask, notificationManager}, // heartRateService {systemTask, heartRateController}, -// motionService {systemTask, motionController}, + motionService {*this, motionController} { // fsService {systemTask, fs}, // serviceDiscovery({¤tTimeClient, &alertNotificationClient}) { } diff --git a/sim/components/ble/NimbleController.h b/sim/components/ble/NimbleController.h index c212820..9a42ea9 100644 --- a/sim/components/ble/NimbleController.h +++ b/sim/components/ble/NimbleController.h @@ -19,7 +19,7 @@ #include "components/ble/MusicService.h" #include "components/ble/NavigationService.h" //#include "components/ble/ServiceDiscovery.h" -//#include "components/ble/MotionService.h" +#include "components/ble/MotionService.h" #include "components/ble/SimpleWeatherService.h" #include "components/fs/FS.h" //#include "components/ble/FSService.h" @@ -116,7 +116,7 @@ namespace Pinetime { // BatteryInformationService batteryInformationService; // ImmediateAlertService immediateAlertService; // HeartRateService heartRateService; -// MotionService motionService; + MotionService motionService; // FSService fsService; // ServiceDiscovery serviceDiscovery; diff --git a/sim/components/motion/MotionController.h b/sim/components/motion/MotionController.h index 3908d9c..664ec8f 100644 --- a/sim/components/motion/MotionController.h +++ b/sim/components/motion/MotionController.h @@ -5,7 +5,7 @@ //#include #include "drivers/Bma421.h" -//#include "components/ble/MotionService.h" +#include "components/ble/MotionService.h" #include "utility/CircularBuffer.h" namespace Pinetime { @@ -58,9 +58,13 @@ namespace Pinetime { void Init(Pinetime::Drivers::Bma421::DeviceTypes types); -// void SetService(Pinetime::Controllers::MotionService* service) { -// this->service = service; -// } + void SetService(Pinetime::Controllers::MotionService* service) { + this->service = service; + } + + Pinetime::Controllers::MotionService* GetService() const { + return service; + } private: uint32_t nbSteps = 0; @@ -93,7 +97,7 @@ namespace Pinetime { int32_t accumulatedSpeed = 0; DeviceTypes deviceType = DeviceTypes::Unknown; -// Pinetime::Controllers::MotionService* service = nullptr; + Pinetime::Controllers::MotionService* service = nullptr; }; } }