-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBleFlexHID.cpp
271 lines (216 loc) · 8.71 KB
/
BleFlexHID.cpp
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
#include "nimconfig.h"
#include <NimBLEDevice.h>
#include <NimBLEUtils.h>
#include <NimBLEServer.h>
#include "NimBLEHIDDevice.h"
#include "HIDTypes.h"
#include "BleConnectionStatus.h"
#include "BleFlexHID.h"
#if defined(CONFIG_ARDUHAL_ESP_LOG)
#include "esp32-hal-log.h"
#define LOG_TAG "BleCombo"
#else
#include "esp_log.h"
static const char *LOG_TAG = "BleCombo";
#endif
#define SERVICE_UUID_DEVICE_INFORMATION "180A" // Service - Device information
#define CHARACTERISTIC_UUID_MODEL_NUMBER "2A24" // Characteristic - Model Number String - 0x2A24
#define CHARACTERISTIC_UUID_SOFTWARE_REVISION "2A28" // Characteristic - Software Revision String - 0x2A28
#define CHARACTERISTIC_UUID_SERIAL_NUMBER "2A25" // Characteristic - Serial Number String - 0x2A25
#define CHARACTERISTIC_UUID_FIRMWARE_REVISION "2A26" // Characteristic - Firmware Revision String - 0x2A26
#define CHARACTERISTIC_UUID_HARDWARE_REVISION "2A27" // Characteristic - Hardware Revision String - 0x2A27
// HID Utilities
bool BleHIDSubBase::IsConnected(void)
{
if (!pHIDMaster)
{
Serial.println("ERROR: BleFlexHID not attached. Did you call BleFlexHID.AddDevice()?");
return false;
}
return pHIDMaster->isConnected();
}
void BleHIDSubBase::SendReport(uint8_t* Message, int SizeMessage, int SubReportIndex)
{
if (IsConnected())
{
NimBLECharacteristic* pC = pHIDMaster->GetInputCharacterstics(SubDeviceIndex, SubReportIndex);
pC->setValue((uint8_t*)Message, SizeMessage);
pC->notify();
}
}
BleFlexHID::BleFlexHID(std::string _deviceName, std::string _deviceManufacturer, uint8_t _batteryLevel) : hid(0)
{
deviceName = _deviceName;
deviceManufacturer = _deviceManufacturer;
batteryLevel = _batteryLevel;
connectionStatus = new BleConnectionStatus();
MasterDescriptorSize = 0;
MasterDescriptor = 0;
NumDevices=0;
NumInputCharacteristics = 0;
NumOutputCharacteristics = 0;
}
/**
* @brief Sets the Plug n Play characteristic value.
* @param [in] VendorSourceID The vendor ID source number.
* @param [in] VendorID The vendor ID number.
* @param [in] ProductID The product ID number.
* @param [in] Version The produce version number.
*/
void BleFlexHID::SetProductID(int VendorSourceID, int _VendorID, int _ProductID, int _Version)
{
SigID = VendorSourceID;
VendorID = _VendorID;
ProductID = _ProductID;
Version = _Version;
}
bool BleFlexHID::AddDevice(BleHIDSubBase* pDevice)
{
if (NumDevices>=MAX_HIDS)
{
Serial.printf("ERROR: BleFlexHID() too many devices!\n");
return false;
}
Devices[NumDevices].SetDeviceInfo(pDevice);
Devices[NumDevices].BaseDevice->pHIDMaster = this;
Devices[NumDevices].BaseDevice->SubDeviceIndex = NumDevices;
NumDevices++;
return true;
}
NimBLECharacteristic* BleFlexHID::GetInputCharacterstics(int DeviceIdx, int CharacteristicIndex)
{
// calculate the index of the characteristic
int Index = 0;
for (int d=0; d<DeviceIdx; d++)
{
Index += Devices[d].NumInputReports;
}
Index += CharacteristicIndex;
return InputCharacterstics[Index];
}
NimBLECharacteristic* BleFlexHID::GetOutputCharacterstics(int DeviceIdx, int CharacteristicIndex)
{
// calculate the index of the characteristic
int Index = 0;
for (int d=0; d<DeviceIdx; d++)
{
Index += Devices[d].NumOutputReports;
}
Index += CharacteristicIndex;
return OutputCharacterstics[Index];
}
// Create the master report descriptor, which is just a concatenation of all the individual
// descriptors from all HID sub devices.
void BleFlexHID::BuildMasterDescriptor()
{
Serial.printf("Building master report descriptor for %d sub devices\n", NumDevices);
if (MasterDescriptorSize!=0 || MasterDescriptor!=0)
Serial.println(" ERROR: MasterDescriptor not empty! BleFlexHID::BuildMasterDescriptor() was probably called already.");
// Calculate the required size
MasterDescriptorSize = 0;
for (int d=0; d<NumDevices; d++)
MasterDescriptorSize += Devices[d].ReportDescriptorSize;
// Allocate and build the table
Serial.printf(" Allocating master report descriptor of size %d bytes\n", MasterDescriptorSize);
MasterDescriptor = new uint8_t[MasterDescriptorSize];
if (MasterDescriptor==0)
Serial.printf(" ERROR: Failed to allocate memory for master decriptor table!\n");
uint8_t* NextDescriptor = MasterDescriptor;
for (int d=0; d<NumDevices; d++)
{
Serial.printf(" Adding %d bytes to master report descriptor\n", Devices[d].ReportDescriptorSize);
memcpy(NextDescriptor, Devices[d].ReportDescriptor, Devices[d].ReportDescriptorSize);
NextDescriptor += Devices[d].ReportDescriptorSize;
}
Serial.printf(" Done with creation of master report descriptor\n");
}
void BleFlexHID::BuildCharacteristicsTable()
{
// Build table with input/output characteristics
Serial.printf("Building table with input/output characteristics of all sub devices\n");
int InputIndex=0;
int OutputIndex=0;
for (int d=0; d<NumDevices; d++)
{
for (int i=0; i<Devices[d].NumInputReports; i++)
{
Serial.printf(" Adding one input characteristic for report index %d of type %d for device %d\n", i, Devices[d].InputReportIndices[i], d);
InputCharacterstics[InputIndex++] = hid->inputReport(Devices[d].InputReportIndices[i]); // <-- input REPORTID from report map
}
for (int i=0; i<Devices[d].NumOutputReports; i++)
{
Serial.printf(" Adding one output characteristic for report index %d of type %d for device %d\n", i, Devices[d].OutputReportIndices[i], d);
OutputCharacterstics[OutputIndex] = hid->outputReport(Devices[d].OutputReportIndices[i]); // <-- output REPORTID from report map
OutputCallbacks[OutputIndex++] = Devices[d].OutputCallbacks[i];
}
}
NumInputCharacteristics = InputIndex,
NumOutputCharacteristics = OutputIndex;
Serial.printf(" Linking %d output callbacks\n", NumOutputCharacteristics);
for (int i=0; i<NumOutputCharacteristics; i++)
OutputCharacterstics[i]->setCallbacks(OutputCallbacks[i]);
Serial.printf(" Done with table creation\n");
}
void BleFlexHID::begin()
{
xTaskCreate(taskServer, "server", 20000, (void *)this, 5, NULL);
}
void BleFlexHID::end(void)
{
}
bool BleFlexHID::isConnected(void)
{
return this->connectionStatus->connected;
}
void BleFlexHID::setBatteryLevel(uint8_t level)
{
batteryLevel = level;
if (hid != 0)
{
hid->setBatteryLevel(this->batteryLevel);
if (isConnected())
{
hid->batteryLevel()->notify();
}
// if (configuration.getAutoReport())
if (0)
{
// sendReport();
}
}
}
int BleFlexHID::SigID = 0x02;
int BleFlexHID::VendorID=0xe502;
int BleFlexHID::Version=0x0210;
int BleFlexHID::ProductID=0x1234; // Dev
void BleFlexHID::taskServer(void *pvParameter)
{
BleFlexHID* bleInstance = (BleFlexHID *) pvParameter; //static_cast<BleComboKeyboard *>(pvParameter);
NimBLEDevice::init(bleInstance->deviceName);
NimBLEServer *pServer = NimBLEDevice::createServer();
pServer->setCallbacks(bleInstance->connectionStatus);
bleInstance->hid = new NimBLEHIDDevice(pServer);
bleInstance->BuildMasterDescriptor();
bleInstance->BuildCharacteristicsTable();
/**
* @brief Sets the Plug n Play characteristic value.
* @param [in] sig The vendor ID source number.
* @param [in] vid The vendor ID number.
* @param [in] pid The product ID number.
* @param [in] version The produce version number.
*/
bleInstance->hid->manufacturer()->setValue(bleInstance->deviceManufacturer);
bleInstance->hid->pnp(SigID, VendorID, ProductID, Version);
bleInstance->hid->hidInfo(0x00,0x01);
BLESecurity *pSecurity = new BLESecurity();
pSecurity->setAuthenticationMode(ESP_LE_AUTH_BOND);
bleInstance->hid->reportMap(bleInstance->MasterDescriptor, bleInstance->MasterDescriptorSize);
bleInstance->hid->startServices();
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->setAppearance(HID_KEYBOARD);
pAdvertising->addServiceUUID(bleInstance->hid->hidService()->getUUID());
pAdvertising->start();
bleInstance->hid->setBatteryLevel(bleInstance->batteryLevel);
ESP_LOGD(LOG_TAG, "Advertising started!");
vTaskDelay(portMAX_DELAY); //delay(portMAX_DELAY);
}