From b356a66bd123a1378f64ff1cab06e59ad869231b Mon Sep 17 00:00:00 2001 From: uvok Date: Sun, 3 May 2026 19:53:05 +0200 Subject: Add way to send text --- src/ble.cpp | 78 ++++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 22 deletions(-) (limited to 'src/ble.cpp') diff --git a/src/ble.cpp b/src/ble.cpp index 552055d..6fdc6bc 100644 --- a/src/ble.cpp +++ b/src/ble.cpp @@ -5,17 +5,23 @@ #include "badge/config.h" #include "badge/log.h" +#include + using de::uvok::badge::DisplayIndicator; static NimBLEServer *server; static NimBLEAdvertising *pAdvertising; -static NimBLECharacteristic *selectorCharacteristic; +static NimBLECharacteristic *selectImageCharacteristic; +static NimBLECharacteristic *selectTextCharacteristic; -static volatile struct +template struct CharacteristicPoll { - bool changed; - uint8_t value; -} value_changed; + volatile bool changed; + T value; +}; + +static CharacteristicPoll select_image_value_changed; +static CharacteristicPoll select_text_changed; static volatile DisplayIndicator ble_indicator = DisplayIndicator::Uninit; @@ -23,6 +29,7 @@ static volatile DisplayIndicator ble_indicator = DisplayIndicator::Uninit; const char *templates[] = { #include "./images.cfg" + }; class BadgeServerCallbacks : public NimBLEServerCallbacks @@ -47,7 +54,7 @@ class BadgeSelectorCallbacks : public NimBLECharacteristicCallbacks { NimBLECharacteristicCallbacks::onWrite(pCharacteristic, connInfo); - if (pCharacteristic == selectorCharacteristic) + if (pCharacteristic == selectImageCharacteristic) { LOG_F("Write!"); const char *val = pCharacteristic->getValue().c_str(); @@ -58,21 +65,34 @@ class BadgeSelectorCallbacks : public NimBLECharacteristicCallbacks { LOG_F("Error parsing value\n"); pCharacteristic->setValue(defVal); - (void) pCharacteristic->notify(defVal, BLE_HS_CONN_HANDLE_NONE); + (void)pCharacteristic->notify(defVal, BLE_HS_CONN_HANDLE_NONE); } else if (newVal >= ARRAY_SIZE(templates)) { LOG_F("Value out of range: %ld\n", newVal); pCharacteristic->setValue(defVal); - (void) pCharacteristic->notify(defVal, BLE_HS_CONN_HANDLE_NONE); + (void)pCharacteristic->notify(defVal, BLE_HS_CONN_HANDLE_NONE); } else { LOG_F("Value set to %ld\n", newVal); - value_changed.value = newVal; - value_changed.changed = true; + select_image_value_changed.value = newVal; + select_image_value_changed.changed = true; } } + else if (pCharacteristic == selectTextCharacteristic) + { + // + auto val = pCharacteristic->getValue().c_str(); + if (val == nullptr) + { + return; + } + std::string newText = val; + select_text_changed.value = newText; + select_text_changed.changed = true; + LOG_F("Received new text: %s\n", newText.c_str()); + } } } badgeSelectorCallbacks; @@ -85,11 +105,11 @@ void de::uvok::badge::ble_init() NimBLEService *service = new NimBLEService("ca260000-b4bb-46b2-bd06-b7b7a61ea990"); // read/write current - selectorCharacteristic = + selectImageCharacteristic = service->createCharacteristic("ca260001-b4bb-46b2-bd06-b7b7a61ea990", NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::NOTIFY); - selectorCharacteristic->setValue("0"); - selectorCharacteristic->setCallbacks(&badgeSelectorCallbacks); + selectImageCharacteristic->setValue("0"); + selectImageCharacteristic->setCallbacks(&badgeSelectorCallbacks); // get pictures auto call = service->createCharacteristic("ca260002-b4bb-46b2-bd06-b7b7a61ea990", NIMBLE_PROPERTY::READ); @@ -102,6 +122,14 @@ void de::uvok::badge::ble_init() s.concat(tmp); } call->setValue(s.c_str()); + + // write QR code + selectTextCharacteristic = + service->createCharacteristic("ca260003-b4bb-46b2-bd06-b7b7a61ea990", + NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::NOTIFY); + selectTextCharacteristic->setValue(""); + selectTextCharacteristic->setCallbacks(&badgeSelectorCallbacks); + const uint16_t mtuLen = max(s.length() + 16, 256); NimBLEDevice::setMTU(mtuLen); @@ -134,27 +162,33 @@ void de::uvok::badge::ble_advertise() } } -de::uvok::badge::ble_poll_result_t de::uvok::badge::ble_poll() +de::uvok::badge::BlePollResult de::uvok::badge::ble_poll() { - if (value_changed.changed) + if (select_image_value_changed.changed) + { + const uint8_t val = select_image_value_changed.value; + select_image_value_changed.changed = false; + return BlePollResult::MakeTemplate(val); + } + if (select_text_changed.changed) { - const uint8_t val = value_changed.value; - value_changed.changed = false; - return (ble_poll_result_t){.action_type = BleActionType::Template, .new_template = val}; + const std::string val = select_text_changed.value; + select_text_changed.changed = false; + return BlePollResult::MakeText(val); } if (ble_indicator != DisplayIndicator::Uninit) { DisplayIndicator ind = ble_indicator; ble_indicator = DisplayIndicator::Uninit; - return (ble_poll_result_t){.action_type = BleActionType::Indicator, .new_indicator = ind}; + return BlePollResult::MakeIndicator(ind); } - return (ble_poll_result_t){.action_type = BleActionType::None}; + return BlePollResult::MakeEmpty(); } void de::uvok::badge::ble_set_image(uint8_t image) { LOG_F("Notify BLE: set image to %d\n", image); String s(image); - selectorCharacteristic->setValue(s); - (void) selectorCharacteristic->notify(s, BLE_HS_CONN_HANDLE_NONE); + selectImageCharacteristic->setValue(s); + (void)selectImageCharacteristic->notify(s, BLE_HS_CONN_HANDLE_NONE); } \ No newline at end of file -- cgit v1.2.3