NimbleController : support CTS
This commit is contained in:
parent
2c9ce1cfc7
commit
a9254ee90e
3 changed files with 107 additions and 3 deletions
|
@ -1,3 +1,5 @@
|
||||||
|
#include <Components/DateTime/DateTimeController.h>
|
||||||
|
|
||||||
#include "NimbleController.h"
|
#include "NimbleController.h"
|
||||||
#include <services/gatt/ble_svc_gatt.h>
|
#include <services/gatt/ble_svc_gatt.h>
|
||||||
#include <services/gap/ble_svc_gap.h>
|
#include <services/gap/ble_svc_gap.h>
|
||||||
|
@ -5,15 +7,41 @@
|
||||||
#include <host/ble_hs_id.h>
|
#include <host/ble_hs_id.h>
|
||||||
#include <host/ble_hs.h>
|
#include <host/ble_hs.h>
|
||||||
#include <host/ble_gap.h>
|
#include <host/ble_gap.h>
|
||||||
|
#include <hal/nrf_rtc.h>
|
||||||
|
|
||||||
using namespace Pinetime::Controllers;
|
using namespace Pinetime::Controllers;
|
||||||
|
|
||||||
|
NimbleController::NimbleController(DateTime& datetimeController) : dateTimeController{datetimeController} {
|
||||||
|
ctsUuid.u.type = BLE_UUID_TYPE_16;
|
||||||
|
ctsUuid.value = BleGatServiceCts;
|
||||||
|
|
||||||
|
ctsCurrentTimeUuid.u.type = BLE_UUID_TYPE_16;
|
||||||
|
ctsCurrentTimeUuid.value = bleGattCharacteristicCurrentTime;
|
||||||
|
}
|
||||||
|
|
||||||
int GAPEventCallback(struct ble_gap_event *event, void *arg) {
|
int GAPEventCallback(struct ble_gap_event *event, void *arg) {
|
||||||
auto nimbleController = static_cast<NimbleController*>(arg);
|
auto nimbleController = static_cast<NimbleController*>(arg);
|
||||||
return nimbleController->OnGAPEvent(event);
|
return nimbleController->OnGAPEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int DiscoveryEventCallback(uint16_t conn_handle, const struct ble_gatt_error *error,
|
||||||
|
const struct ble_gatt_svc *service, void *arg) {
|
||||||
|
auto nimbleController = static_cast<NimbleController*>(arg);
|
||||||
|
return nimbleController->OnDiscoveryEvent(conn_handle, error, service);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CharacteristicDiscoveredCallback(uint16_t conn_handle, const struct ble_gatt_error *error,
|
||||||
|
const struct ble_gatt_chr *chr, void *arg) {
|
||||||
|
auto nimbleController = static_cast<NimbleController*>(arg);
|
||||||
|
return nimbleController->OnCharacteristicDiscoveryEvent(conn_handle, error, chr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CurrentTimeReadCallback(uint16_t conn_handle, const struct ble_gatt_error *error,
|
||||||
|
struct ble_gatt_attr *attr, void *arg) {
|
||||||
|
auto nimbleController = static_cast<NimbleController*>(arg);
|
||||||
|
return nimbleController->OnCurrentTimeReadResult(conn_handle, error, attr);
|
||||||
|
}
|
||||||
|
|
||||||
void NimbleController::Init() {
|
void NimbleController::Init() {
|
||||||
while (!ble_hs_synced()) {}
|
while (!ble_hs_synced()) {}
|
||||||
|
|
||||||
|
@ -87,6 +115,10 @@ int NimbleController::OnGAPEvent(ble_gap_event *event) {
|
||||||
if (event->connect.status != 0) {
|
if (event->connect.status != 0) {
|
||||||
/* Connection failed; resume advertising. */
|
/* Connection failed; resume advertising. */
|
||||||
StartAdvertising();
|
StartAdvertising();
|
||||||
|
} else {
|
||||||
|
connectionHandle = event->connect.conn_handle;
|
||||||
|
|
||||||
|
ble_gattc_disc_svc_by_uuid(connectionHandle, ((ble_uuid_t*)&ctsUuid), DiscoveryEventCallback, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -146,3 +178,48 @@ int NimbleController::OnGAPEvent(ble_gap_event *event) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int NimbleController::OnDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error *error, const ble_gatt_svc *service) {
|
||||||
|
if(service == nullptr && error->status == BLE_HS_EDONE)
|
||||||
|
NRF_LOG_INFO("Discovery complete");
|
||||||
|
|
||||||
|
if(service != nullptr && ble_uuid_cmp(((ble_uuid_t*)&ctsUuid), &service->uuid.u) == 0) {
|
||||||
|
NRF_LOG_INFO("CTS discovered : 0x%x", service->start_handle);
|
||||||
|
ble_gattc_disc_chrs_by_uuid(connectionHandle, service->start_handle, service->end_handle, ((ble_uuid_t*)&ctsCurrentTimeUuid), CharacteristicDiscoveredCallback, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int NimbleController::OnCharacteristicDiscoveryEvent(uint16_t conn_handle, const ble_gatt_error *error,
|
||||||
|
const ble_gatt_chr *characteristic) {
|
||||||
|
if(characteristic == nullptr && error->status == BLE_HS_EDONE)
|
||||||
|
NRF_LOG_INFO("Characteristic discovery complete");
|
||||||
|
|
||||||
|
if(characteristic != nullptr && ble_uuid_cmp(((ble_uuid_t*)&ctsCurrentTimeUuid), &characteristic->uuid.u) == 0) {
|
||||||
|
NRF_LOG_INFO("CTS Characteristic discovered : 0x%x", characteristic->val_handle);
|
||||||
|
|
||||||
|
ble_gattc_read(conn_handle, characteristic->val_handle, CurrentTimeReadCallback, this);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int NimbleController::OnCurrentTimeReadResult(uint16_t conn_handle, const ble_gatt_error *error, const ble_gatt_attr *attribute) {
|
||||||
|
if(error->status == 0) {
|
||||||
|
// 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));
|
||||||
|
} else {
|
||||||
|
NRF_LOG_INFO("Error retrieving current time: %d", error->status);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,15 +5,42 @@
|
||||||
|
|
||||||
namespace Pinetime {
|
namespace Pinetime {
|
||||||
namespace Controllers {
|
namespace Controllers {
|
||||||
|
class DateTime;
|
||||||
class NimbleController {
|
class NimbleController {
|
||||||
public:
|
public:
|
||||||
|
NimbleController(DateTime& dateTimeController);
|
||||||
void Init();
|
void Init();
|
||||||
void StartAdvertising();
|
void StartAdvertising();
|
||||||
int OnGAPEvent(ble_gap_event *event);
|
int OnGAPEvent(ble_gap_event *event);
|
||||||
|
int OnDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error *error, const ble_gatt_svc *service);
|
||||||
|
int
|
||||||
|
OnCharacteristicDiscoveryEvent(uint16_t conn_handle, const ble_gatt_error *error,
|
||||||
|
const ble_gatt_chr *characteristic);
|
||||||
|
int OnCurrentTimeReadResult(uint16_t conn_handle, const ble_gatt_error *error, const ble_gatt_attr *attribute);
|
||||||
private:
|
private:
|
||||||
static constexpr char* deviceName = "Pinetime-JF";
|
static constexpr char* deviceName = "Pinetime-JF";
|
||||||
|
static constexpr uint16_t BleGatServiceCts = 0x1805;
|
||||||
|
|
||||||
|
typedef struct __attribute__((packed)) {
|
||||||
|
uint16_t year;
|
||||||
|
uint8_t month;
|
||||||
|
uint8_t dayofmonth;
|
||||||
|
uint8_t hour;
|
||||||
|
uint8_t minute;
|
||||||
|
uint8_t second;
|
||||||
|
uint8_t millis;
|
||||||
|
uint8_t reason;
|
||||||
|
} CtsData;
|
||||||
|
|
||||||
|
DateTime& dateTimeController;
|
||||||
|
|
||||||
|
ble_uuid16_t ctsUuid;
|
||||||
|
|
||||||
|
static constexpr uint16_t bleGattCharacteristicCurrentTime = 0x2a2b;
|
||||||
|
ble_uuid16_t ctsCurrentTimeUuid;
|
||||||
|
|
||||||
uint8_t addrType;
|
uint8_t addrType;
|
||||||
|
uint16_t connectionHandle;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ SystemTask::SystemTask(Drivers::SpiMaster &spi, Drivers::St7789 &lcd, Drivers::C
|
||||||
Pinetime::Controllers::NotificationManager& notificationManager) :
|
Pinetime::Controllers::NotificationManager& notificationManager) :
|
||||||
spi{spi}, lcd{lcd}, touchPanel{touchPanel}, lvgl{lvgl}, batteryController{batteryController},
|
spi{spi}, lcd{lcd}, touchPanel{touchPanel}, lvgl{lvgl}, batteryController{batteryController},
|
||||||
bleController{bleController}, dateTimeController{dateTimeController},
|
bleController{bleController}, dateTimeController{dateTimeController},
|
||||||
watchdog{}, watchdogView{watchdog}, notificationManager{notificationManager} {
|
watchdog{}, watchdogView{watchdog}, notificationManager{notificationManager}, nimbleController({dateTimeController}) {
|
||||||
systemTaksMsgQueue = xQueueCreate(10, 1);
|
systemTaksMsgQueue = xQueueCreate(10, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue