From 198b0453808d8a28c89559280c40e168d6b98b02 Mon Sep 17 00:00:00 2001 From: h2zero Date: Tue, 19 Nov 2024 14:14:14 -0700 Subject: [PATCH] WIP --- src/NimBLEHIDDevice.cpp | 190 +++++++++++++++++++++------------------- src/NimBLEHIDDevice.h | 114 ++++++++++++------------ 2 files changed, 155 insertions(+), 149 deletions(-) diff --git a/src/NimBLEHIDDevice.cpp b/src/NimBLEHIDDevice.cpp index ad04197..1078a02 100644 --- a/src/NimBLEHIDDevice.cpp +++ b/src/NimBLEHIDDevice.cpp @@ -15,58 +15,57 @@ #include "nimconfig.h" #if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) -#include "NimBLEHIDDevice.h" -#include "NimBLE2904.h" +# include "NimBLEHIDDevice.h" +# include "NimBLE2904.h" /** * @brief Construct a default NimBLEHIDDevice object. * @param [in] server A pointer to the server instance this HID Device will use. */ NimBLEHIDDevice::NimBLEHIDDevice(NimBLEServer* server) { - /* - * Here we create mandatory services described in bluetooth specification - */ - m_deviceInfoService = server->createService(NimBLEUUID((uint16_t)0x180a)); - m_hidService = server->createService(NimBLEUUID((uint16_t)0x1812)); - m_batteryService = server->createService(NimBLEUUID((uint16_t)0x180f)); + /* + * Here we create mandatory services described in bluetooth specification + */ + m_deviceInfoService = server->createService(NimBLEUUID((uint16_t)0x180a)); + m_hidService = server->createService(NimBLEUUID((uint16_t)0x1812)); + m_batteryService = server->createService(NimBLEUUID((uint16_t)0x180f)); - /* - * Mandatory characteristic for device info service - */ - m_pnpCharacteristic = m_deviceInfoService->createCharacteristic((uint16_t)0x2a50, NIMBLE_PROPERTY::READ); + /* + * Mandatory characteristic for device info service + */ + m_pnpCharacteristic = m_deviceInfoService->createCharacteristic((uint16_t)0x2a50, NIMBLE_PROPERTY::READ); - /* - * Non-mandatory characteristics for device info service - * Will be created on demand - */ - m_manufacturerCharacteristic = nullptr; + /* + * Non-mandatory characteristics for device info service + * Will be created on demand + */ + m_manufacturerCharacteristic = nullptr; - /* - * Mandatory characteristics for HID service - */ - m_hidInfoCharacteristic = m_hidService->createCharacteristic((uint16_t)0x2a4a, NIMBLE_PROPERTY::READ); - m_reportMapCharacteristic = m_hidService->createCharacteristic((uint16_t)0x2a4b, NIMBLE_PROPERTY::READ); - m_hidControlCharacteristic = m_hidService->createCharacteristic((uint16_t)0x2a4c, NIMBLE_PROPERTY::WRITE_NR); - m_protocolModeCharacteristic = m_hidService->createCharacteristic((uint16_t)0x2a4e, NIMBLE_PROPERTY::WRITE_NR | NIMBLE_PROPERTY::READ); + /* + * Mandatory characteristics for HID service + */ + m_hidInfoCharacteristic = m_hidService->createCharacteristic((uint16_t)0x2a4a, NIMBLE_PROPERTY::READ); + m_reportMapCharacteristic = m_hidService->createCharacteristic((uint16_t)0x2a4b, NIMBLE_PROPERTY::READ); + m_hidControlCharacteristic = m_hidService->createCharacteristic((uint16_t)0x2a4c, NIMBLE_PROPERTY::WRITE_NR); + m_protocolModeCharacteristic = + m_hidService->createCharacteristic((uint16_t)0x2a4e, NIMBLE_PROPERTY::WRITE_NR | NIMBLE_PROPERTY::READ); - /* - * Mandatory battery level characteristic with notification and presence descriptor - */ - m_batteryLevelCharacteristic = m_batteryService->createCharacteristic((uint16_t)0x2a19, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY); - NimBLE2904 *batteryLevelDescriptor = (NimBLE2904*)m_batteryLevelCharacteristic->createDescriptor((uint16_t)0x2904); - batteryLevelDescriptor->setFormat(NimBLE2904::FORMAT_UINT8); - batteryLevelDescriptor->setNamespace(1); - batteryLevelDescriptor->setUnit(0x27ad); + /* + * Mandatory battery level characteristic with notification and presence descriptor + */ + m_batteryLevelCharacteristic = + m_batteryService->createCharacteristic((uint16_t)0x2a19, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY); + NimBLE2904* batteryLevelDescriptor = (NimBLE2904*)m_batteryLevelCharacteristic->createDescriptor((uint16_t)0x2904); + batteryLevelDescriptor->setFormat(NimBLE2904::FORMAT_UINT8); + batteryLevelDescriptor->setNamespace(1); + batteryLevelDescriptor->setUnit(0x27ad); - /* - * This value is setup here because its default value in most usage cases, its very rare to use boot mode - * and we want to simplify library using as much as possible - */ - const uint8_t pMode[] = {0x01}; - protocolMode()->setValue((uint8_t*)pMode, 1); -} - -NimBLEHIDDevice::~NimBLEHIDDevice() { + /* + * This value is setup here because its default value in most usage cases, its very rare to use boot mode + * and we want to simplify library using as much as possible + */ + const uint8_t pMode{0x01}; + protocolMode()->setValue(pMode); } /** @@ -75,7 +74,7 @@ NimBLEHIDDevice::~NimBLEHIDDevice() { * @param [in] size The number of values in the array. */ void NimBLEHIDDevice::reportMap(uint8_t* map, uint16_t size) { - m_reportMapCharacteristic->setValue(map, size); + m_reportMapCharacteristic->setValue(map, size); } /** @@ -83,28 +82,28 @@ void NimBLEHIDDevice::reportMap(uint8_t* map, uint16_t size) { * This function called when all the services have been created. */ void NimBLEHIDDevice::startServices() { - m_deviceInfoService->start(); - m_hidService->start(); - m_batteryService->start(); + m_deviceInfoService->start(); + m_hidService->start(); + m_batteryService->start(); } /** * @brief Create a manufacturer characteristic (this characteristic is optional). */ NimBLECharacteristic* NimBLEHIDDevice::manufacturer() { - if (m_manufacturerCharacteristic == nullptr) { - m_manufacturerCharacteristic = m_deviceInfoService->createCharacteristic((uint16_t)0x2a29, NIMBLE_PROPERTY::READ); - } + if (m_manufacturerCharacteristic == nullptr) { + m_manufacturerCharacteristic = m_deviceInfoService->createCharacteristic((uint16_t)0x2a29, NIMBLE_PROPERTY::READ); + } - return m_manufacturerCharacteristic; + return m_manufacturerCharacteristic; } /** * @brief Set manufacturer name * @param [in] name The manufacturer name of this HID device. */ -void NimBLEHIDDevice::manufacturer(std::string name) { - manufacturer()->setValue(name); +void NimBLEHIDDevice::manufacturer(const std::string& name) { + manufacturer()->setValue(name); } /** @@ -115,16 +114,14 @@ void NimBLEHIDDevice::manufacturer(std::string name) { * @param [in] version The produce version number. */ void NimBLEHIDDevice::pnp(uint8_t sig, uint16_t vid, uint16_t pid, uint16_t version) { - uint8_t pnp[] = { - sig, - ((uint8_t*)&vid)[0], - ((uint8_t*)&vid)[1], - ((uint8_t*)&pid)[0], - ((uint8_t*)&pid)[1], - ((uint8_t*)&version)[0], - ((uint8_t*)&version)[1] - }; - m_pnpCharacteristic->setValue(pnp, sizeof(pnp)); + uint8_t pnp[] = {sig, + ((uint8_t*)&vid)[0], + ((uint8_t*)&vid)[1], + ((uint8_t*)&pid)[0], + ((uint8_t*)&pid)[1], + ((uint8_t*)&version)[0], + ((uint8_t*)&version)[1]}; + m_pnpCharacteristic->setValue(pnp, sizeof(pnp)); } /** @@ -133,8 +130,8 @@ void NimBLEHIDDevice::pnp(uint8_t sig, uint16_t vid, uint16_t pid, uint16_t vers * @param [in] flags The HID Class Specification release number to use. */ void NimBLEHIDDevice::hidInfo(uint8_t country, uint8_t flags) { - uint8_t info[] = {0x11, 0x1, country, flags}; - m_hidInfoCharacteristic->setValue(info, sizeof(info)); + uint8_t info[] = {0x11, 0x1, country, flags}; + m_hidInfoCharacteristic->setValue(info, sizeof(info)); } /** @@ -143,13 +140,16 @@ void NimBLEHIDDevice::hidInfo(uint8_t country, uint8_t flags) { * @return pointer to new input report characteristic */ NimBLECharacteristic* NimBLEHIDDevice::inputReport(uint8_t reportID) { - NimBLECharacteristic *inputReportCharacteristic = m_hidService->createCharacteristic((uint16_t)0x2a4d, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY | NIMBLE_PROPERTY::READ_ENC); - NimBLEDescriptor *inputReportDescriptor = inputReportCharacteristic->createDescriptor((uint16_t)0x2908, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::READ_ENC); + NimBLECharacteristic* inputReportCharacteristic = + m_hidService->createCharacteristic((uint16_t)0x2a4d, + NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY | NIMBLE_PROPERTY::READ_ENC); + NimBLEDescriptor* inputReportDescriptor = + inputReportCharacteristic->createDescriptor((uint16_t)0x2908, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::READ_ENC); - uint8_t desc1_val[] = {reportID, 0x01}; - inputReportDescriptor->setValue((uint8_t*)desc1_val, 2); + uint8_t desc1_val[] = {reportID, 0x01}; + inputReportDescriptor->setValue((uint8_t*)desc1_val, 2); - return inputReportCharacteristic; + return inputReportCharacteristic; } /** @@ -158,13 +158,18 @@ NimBLECharacteristic* NimBLEHIDDevice::inputReport(uint8_t reportID) { * @return Pointer to new output report characteristic */ NimBLECharacteristic* NimBLEHIDDevice::outputReport(uint8_t reportID) { - NimBLECharacteristic *outputReportCharacteristic = m_hidService->createCharacteristic((uint16_t)0x2a4d, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_NR | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::WRITE_ENC); - NimBLEDescriptor *outputReportDescriptor = outputReportCharacteristic->createDescriptor((uint16_t)0x2908, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::WRITE_ENC); + NimBLECharacteristic* outputReportCharacteristic = + m_hidService->createCharacteristic((uint16_t)0x2a4d, + NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_NR | + NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::WRITE_ENC); + NimBLEDescriptor* outputReportDescriptor = outputReportCharacteristic->createDescriptor( + (uint16_t)0x2908, + NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::WRITE_ENC); - uint8_t desc1_val[] = {reportID, 0x02}; - outputReportDescriptor->setValue((uint8_t*)desc1_val, 2); + uint8_t desc1_val[] = {reportID, 0x02}; + outputReportDescriptor->setValue((uint8_t*)desc1_val, 2); - return outputReportCharacteristic; + return outputReportCharacteristic; } /** @@ -173,41 +178,46 @@ NimBLECharacteristic* NimBLEHIDDevice::outputReport(uint8_t reportID) { * @return Pointer to new feature report characteristic */ NimBLECharacteristic* NimBLEHIDDevice::featureReport(uint8_t reportID) { - NimBLECharacteristic *featureReportCharacteristic = m_hidService->createCharacteristic((uint16_t)0x2a4d, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::WRITE_ENC); - NimBLEDescriptor *featureReportDescriptor = featureReportCharacteristic->createDescriptor((uint16_t)0x2908, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::WRITE_ENC); + NimBLECharacteristic* featureReportCharacteristic = m_hidService->createCharacteristic( + (uint16_t)0x2a4d, + NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::WRITE_ENC); + NimBLEDescriptor* featureReportDescriptor = featureReportCharacteristic->createDescriptor( + (uint16_t)0x2908, + NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::WRITE_ENC); - uint8_t desc1_val[] = {reportID, 0x03}; - featureReportDescriptor->setValue((uint8_t*)desc1_val, 2); + uint8_t desc1_val[] = {reportID, 0x03}; + featureReportDescriptor->setValue((uint8_t*)desc1_val, 2); - return featureReportCharacteristic; + return featureReportCharacteristic; } /** * @brief Creates a keyboard boot input report characteristic */ NimBLECharacteristic* NimBLEHIDDevice::bootInput() { - return m_hidService->createCharacteristic((uint16_t)0x2a22, NIMBLE_PROPERTY::NOTIFY); + return m_hidService->createCharacteristic((uint16_t)0x2a22, NIMBLE_PROPERTY::NOTIFY); } /** * @brief Create a keyboard boot output report characteristic */ NimBLECharacteristic* NimBLEHIDDevice::bootOutput() { - return m_hidService->createCharacteristic((uint16_t)0x2a32, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_NR); + return m_hidService->createCharacteristic((uint16_t)0x2a32, + NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_NR); } /** * @brief Returns a pointer to the HID control point characteristic. */ NimBLECharacteristic* NimBLEHIDDevice::hidControl() { - return m_hidControlCharacteristic; + return m_hidControlCharacteristic; } /** * @brief Returns a pointer to the protocol mode characteristic. */ NimBLECharacteristic* NimBLEHIDDevice::protocolMode() { - return m_protocolModeCharacteristic; + return m_protocolModeCharacteristic; } /** @@ -215,29 +225,29 @@ NimBLECharacteristic* NimBLEHIDDevice::protocolMode() { * @param [in] level The battery level value. */ void NimBLEHIDDevice::setBatteryLevel(uint8_t level) { - m_batteryLevelCharacteristic->setValue(&level, 1); + m_batteryLevelCharacteristic->setValue(&level, 1); } /* * @brief Returns battery level characteristic * @ return battery level characteristic */ NimBLECharacteristic* NimBLEHIDDevice::batteryLevel() { - return m_batteryLevelCharacteristic; + return m_batteryLevelCharacteristic; } NimBLECharacteristic* NimBLEHIDDevice::reportMap() { - return m_reportMapCharacteristic; + return m_reportMapCharacteristic; } /* BLECharacteristic* BLEHIDDevice::pnp() { - return m_pnpCharacteristic; + return m_pnpCharacteristic; } BLECharacteristic* BLEHIDDevice::hidInfo() { - return m_hidInfoCharacteristic; + return m_hidInfoCharacteristic; } */ @@ -245,21 +255,21 @@ BLECharacteristic* BLEHIDDevice::hidInfo() { * @brief Returns a pointer to the device information service. */ NimBLEService* NimBLEHIDDevice::deviceInfo() { - return m_deviceInfoService; + return m_deviceInfoService; } /** * @brief Returns a pointer to the HID service. */ NimBLEService* NimBLEHIDDevice::hidService() { - return m_hidService; + return m_hidService; } /** * @brief @brief Returns a pointer to the battery service. */ NimBLEService* NimBLEHIDDevice::batteryService() { - return m_batteryService; + return m_batteryService; } #endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL */ diff --git a/src/NimBLEHIDDevice.h b/src/NimBLEHIDDevice.h index f0da994..b8db877 100644 --- a/src/NimBLEHIDDevice.h +++ b/src/NimBLEHIDDevice.h @@ -12,76 +12,72 @@ * Author: chegewara */ -#ifndef _BLEHIDDEVICE_H_ -#define _BLEHIDDEVICE_H_ +#ifndef NIMBLE_CPP_HIDDEVICE_H_ +#define NIMBLE_CPP_HIDDEVICE_H_ #include "nimconfig.h" -#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) +#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) && defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) -#include "NimBLECharacteristic.h" -#include "NimBLEService.h" -#include "NimBLEDescriptor.h" -#include "HIDTypes.h" +#include +#include -#define GENERIC_HID 0x03C0 -#define HID_KEYBOARD 0x03C1 -#define HID_MOUSE 0x03C2 -#define HID_JOYSTICK 0x03C3 -#define HID_GAMEPAD 0x03C4 -#define HID_TABLET 0x03C5 -#define HID_CARD_READER 0x03C6 -#define HID_DIGITAL_PEN 0x03C7 -#define HID_BARCODE 0x03C8 +# define GENERIC_HID 0x03C0 +# define HID_KEYBOARD 0x03C1 +# define HID_MOUSE 0x03C2 +# define HID_JOYSTICK 0x03C3 +# define HID_GAMEPAD 0x03C4 +# define HID_TABLET 0x03C5 +# define HID_CARD_READER 0x03C6 +# define HID_DIGITAL_PEN 0x03C7 +# define HID_BARCODE 0x03C8 -#define PNPVersionField(MajorVersion, MinorVersion, PatchVersion) ((MajorVersion << 16) & 0xFF00) | ((MinorVersion << 8) & 0x00F0) | (PatchVersion & 0x000F) +# define PNPVersionField(MajorVersion, MinorVersion, PatchVersion) \ + ((MajorVersion << 16) & 0xFF00) | ((MinorVersion << 8) & 0x00F0) | (PatchVersion & 0x000F) + +class NimBLEServer; +class NimBLEService; +class NimBLECharacteristic; /** - * @brief A model of a %BLE Human Interface Device. + * @brief A model of a BLE Human Interface Device. */ class NimBLEHIDDevice { -public: - NimBLEHIDDevice(NimBLEServer*); - virtual ~NimBLEHIDDevice(); + public: + NimBLEHIDDevice(NimBLEServer* server); - void reportMap(uint8_t* map, uint16_t); - void startServices(); + void reportMap(uint8_t* map, uint16_t); + void startServices(); + NimBLEService* deviceInfo(); + NimBLEService* hidService(); + NimBLEService* batteryService(); + NimBLECharacteristic* manufacturer(); + void manufacturer(const std::string& name); + void pnp(uint8_t sig, uint16_t vid, uint16_t pid, uint16_t version); + void hidInfo(uint8_t country, uint8_t flags); + void setBatteryLevel(uint8_t level); + NimBLECharacteristic* batteryLevel(); + NimBLECharacteristic* reportMap(); + NimBLECharacteristic* hidControl(); + NimBLECharacteristic* inputReport(uint8_t reportID); + NimBLECharacteristic* outputReport(uint8_t reportID); + NimBLECharacteristic* featureReport(uint8_t reportID); + NimBLECharacteristic* protocolMode(); + NimBLECharacteristic* bootInput(); + NimBLECharacteristic* bootOutput(); - NimBLEService* deviceInfo(); - NimBLEService* hidService(); - NimBLEService* batteryService(); + private: + NimBLEService* m_deviceInfoService; // 0x180a + NimBLEService* m_hidService; // 0x1812 + NimBLEService* m_batteryService = 0; // 0x180f - NimBLECharacteristic* manufacturer(); - void manufacturer(std::string name); - //NimBLECharacteristic* pnp(); - void pnp(uint8_t sig, uint16_t vid, uint16_t pid, uint16_t version); - //NimBLECharacteristic* hidInfo(); - void hidInfo(uint8_t country, uint8_t flags); - NimBLECharacteristic* batteryLevel(); - void setBatteryLevel(uint8_t level); - - - NimBLECharacteristic* reportMap(); - NimBLECharacteristic* hidControl(); - NimBLECharacteristic* inputReport(uint8_t reportID); - NimBLECharacteristic* outputReport(uint8_t reportID); - NimBLECharacteristic* featureReport(uint8_t reportID); - NimBLECharacteristic* protocolMode(); - NimBLECharacteristic* bootInput(); - NimBLECharacteristic* bootOutput(); - -private: - NimBLEService* m_deviceInfoService; //0x180a - NimBLEService* m_hidService; //0x1812 - NimBLEService* m_batteryService = 0; //0x180f - - NimBLECharacteristic* m_manufacturerCharacteristic; //0x2a29 - NimBLECharacteristic* m_pnpCharacteristic; //0x2a50 - NimBLECharacteristic* m_hidInfoCharacteristic; //0x2a4a - NimBLECharacteristic* m_reportMapCharacteristic; //0x2a4b - NimBLECharacteristic* m_hidControlCharacteristic; //0x2a4c - NimBLECharacteristic* m_protocolModeCharacteristic; //0x2a4e - NimBLECharacteristic* m_batteryLevelCharacteristic; //0x2a19 + NimBLECharacteristic* m_manufacturerCharacteristic; // 0x2a29 + NimBLECharacteristic* m_pnpCharacteristic; // 0x2a50 + NimBLECharacteristic* m_hidInfoCharacteristic; // 0x2a4a + NimBLECharacteristic* m_reportMapCharacteristic; // 0x2a4b + NimBLECharacteristic* m_hidControlCharacteristic; // 0x2a4c + NimBLECharacteristic* m_protocolModeCharacteristic; // 0x2a4e + NimBLECharacteristic* m_batteryLevelCharacteristic; // 0x2a19 }; -#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_BROADCASTER */ -#endif /* _BLEHIDDEVICE_H_ */ +#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_BROADCASTER && defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) */ +#endif /* NIMBLE_CPP_HIDDEVICE_H_ */