#include "badge/ble.h" #include #include "badge/config.h" #include "badge/log.h" static NimBLEServer *server; static NimBLEAdvertising *pAdvertising; static NimBLECharacteristic *selectorCharacteristic; #define IMAGE_DATA(_, display) display const char *templates[] = { #include "./images.cfg" }; class BadgeServerCallbacks : public NimBLEServerCallbacks { void onConnect(NimBLEServer *pServer, NimBLEConnInfo &connInfo) override { NimBLEServerCallbacks::onConnect(pServer, connInfo); } void onDisconnect(NimBLEServer *pServer, NimBLEConnInfo &connInfo, int reason) override { NimBLEServerCallbacks::onDisconnect(pServer, connInfo, reason); } } badgeServerCallbacks; class BadgeSelectorCallbacks : public NimBLECharacteristicCallbacks { void onWrite(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo &connInfo) override { NimBLECharacteristicCallbacks::onWrite(pCharacteristic, connInfo); if (pCharacteristic == selectorCharacteristic) { const char *val = pCharacteristic->getValue().c_str(); char *end = NULL; long newVal = strtol(val, &end, 10); if (end == NULL || end == val) { LOG_F("Error parsing value\n"); pCharacteristic->setValue("0"); pCharacteristic->notify(BLE_HS_CONN_HANDLE_NONE); } else if (newVal >= ARRAY_SIZE(templates)) { LOG_F("Value out of range: %d\n", newVal); pCharacteristic->setValue("0"); pCharacteristic->notify(BLE_HS_CONN_HANDLE_NONE); } else { LOG_F("Value set to %d\n", newVal); } } } } badgeSelectorCallbacks; void de::uvok::badge::ble_init(void) { NimBLEDevice::init("Espadge"); server = NimBLEDevice::createServer(); server->setCallbacks(&badgeServerCallbacks); NimBLEService *service = new NimBLEService("ca260000-b4bb-46b2-bd06-b7b7a61ea990"); // read/write current selectorCharacteristic = service->createCharacteristic("ca260001-b4bb-46b2-bd06-b7b7a61ea990", NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::NOTIFY); selectorCharacteristic->setValue("0"); selectorCharacteristic->setCallbacks(&badgeSelectorCallbacks); // get pictures auto call = service->createCharacteristic("ca260002-b4bb-46b2-bd06-b7b7a61ea990", NIMBLE_PROPERTY::READ); // needs to be on heap String *s = new String(); for (int i = 0; i < ARRAY_SIZE(templates); i++) { char tmp[32]; snprintf(tmp, sizeof(tmp), "%d-%s;", i, templates[i]); s->concat(tmp); } call->setValue(s->c_str()); service->start(); server->addService(service); pAdvertising = NimBLEDevice::getAdvertising(); pAdvertising->setName("NimBLE"); } void de::uvok::badge::ble_advertise(void) { if (!pAdvertising->isAdvertising()) { Serial.println("Long press detected. Starting advertising..."); pAdvertising->start(10000); } }