1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
#include "badge/ble.h"
#include <NimBLEDevice.h>
#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);
}
}
|