From ab89a43630f2e9aee22b1c9b25faaca0a937edaa Mon Sep 17 00:00:00 2001 From: h2zero Date: Tue, 19 Nov 2024 14:14:14 -0700 Subject: [PATCH] [BREAKING] - Refactor NimBLEHIDDevice * General code cleanup. * All functions that return a characteristic or service have been renamed to have a `get` prefix to better represent their function. * All functions that set a value have been renamed with the prefix `set` to better represent their functionality. * Added an `bool notify` parameter to `setBatteryLevel`, which if `true`, will send a notification of the value to the peer. --- src/NimBLEHIDDevice.cpp | 396 +++++++++++++++++++++++----------------- src/NimBLEHIDDevice.h | 115 ++++++------ 2 files changed, 281 insertions(+), 230 deletions(-) diff --git a/src/NimBLEHIDDevice.cpp b/src/NimBLEHIDDevice.cpp index ad041977..163b3559 100644 --- a/src/NimBLEHIDDevice.cpp +++ b/src/NimBLEHIDDevice.cpp @@ -15,97 +15,95 @@ #include "nimconfig.h" #if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) -#include "NimBLEHIDDevice.h" -#include "NimBLE2904.h" +# include "NimBLEHIDDevice.h" +# include "NimBLEServer.h" +# include "NimBLEService.h" +# include "NimBLE2904.h" + +static constexpr uint16_t deviceInfoSvcUuid = 0x180a; +static constexpr uint16_t hidSvcUuid = 0x1812; +static constexpr uint16_t batterySvcUuid = 0x180f; + +static constexpr uint16_t pnpCharUuid = 0x2a50; +static constexpr uint16_t hidInfoCharUuid = 0x2a4a; +static constexpr uint16_t reportMapCharUuid = 0x2a4b; +static constexpr uint16_t hidControlCharUuid = 0x2a4c; +static constexpr uint16_t inputReportChrUuid = 0x2a4d; +static constexpr uint16_t protocolModeCharUuid = 0x2a4e; +static constexpr uint16_t batteryLevelCharUuid = 0x2a19; +static constexpr uint16_t batteryLevelDscUuid = 0x2904; +static constexpr uint16_t featureReportDscUuid = 0x2908; +static constexpr uint16_t m_manufacturerChrUuid = 0x2a29; +static constexpr uint16_t bootInputChrUuid = 0x2a22; +static constexpr uint16_t bootOutputChrUuid = 0x2a32; /** * @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)); - - /* - * 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; - - /* - * 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); - - /* - * 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() { -} + // Here we create mandatory services described in bluetooth specification + m_deviceInfoSvc = server->createService(deviceInfoSvcUuid); + m_hidSvc = server->createService(hidSvcUuid); + m_batterySvc = server->createService(batterySvcUuid); + + // Mandatory characteristic for device info service + m_pnpChr = m_deviceInfoSvc->createCharacteristic(pnpCharUuid, NIMBLE_PROPERTY::READ); + + // Mandatory characteristics for HID service + m_hidInfoChr = m_hidSvc->createCharacteristic(hidInfoCharUuid, NIMBLE_PROPERTY::READ); + m_reportMapChr = m_hidSvc->createCharacteristic(reportMapCharUuid, NIMBLE_PROPERTY::READ); + m_hidControlChr = m_hidSvc->createCharacteristic(hidControlCharUuid, NIMBLE_PROPERTY::WRITE_NR); + m_protocolModeChr = + m_hidSvc->createCharacteristic(protocolModeCharUuid, NIMBLE_PROPERTY::WRITE_NR | NIMBLE_PROPERTY::READ); + + // Mandatory battery level characteristic with notification and presence descriptor + m_batteryLevelChr = + m_batterySvc->createCharacteristic(batteryLevelCharUuid, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY); + NimBLE2904* batteryLevelDescriptor = m_batteryLevelChr->create2904(); + batteryLevelDescriptor->setFormat(NimBLE2904::FORMAT_UINT8); + batteryLevelDescriptor->setUnit(0x27ad); // percentage + + // This value is setup here because its default value in most usage cases, it's very rare to use boot mode + m_protocolModeChr->setValue(static_cast(0x01)); +} // NimBLEHIDDevice /** * @brief Set the report map data formatting information. * @param [in] map A pointer to an array with the values to set. * @param [in] size The number of values in the array. */ -void NimBLEHIDDevice::reportMap(uint8_t* map, uint16_t size) { - m_reportMapCharacteristic->setValue(map, size); -} +void NimBLEHIDDevice::setReportMap(uint8_t* map, uint16_t size) { + m_reportMapChr->setValue(map, size); +} // setReportMap /** - * @brief Start the HID device services.\n + * @brief Start the HID device services. * This function called when all the services have been created. */ void NimBLEHIDDevice::startServices() { - m_deviceInfoService->start(); - m_hidService->start(); - m_batteryService->start(); -} + m_deviceInfoSvc->start(); + m_hidSvc->start(); + m_batterySvc->start(); +} // startServices /** - * @brief Create a manufacturer characteristic (this characteristic is optional). + * @brief Get the manufacturer characteristic (this characteristic is optional). + * @details The characteristic will be created if not already existing. + * @returns True if the name was set and/or the characteristic created. */ -NimBLECharacteristic* NimBLEHIDDevice::manufacturer() { - if (m_manufacturerCharacteristic == nullptr) { - m_manufacturerCharacteristic = m_deviceInfoService->createCharacteristic((uint16_t)0x2a29, NIMBLE_PROPERTY::READ); - } +bool NimBLEHIDDevice::setManufacturer(const std::string& name) { + if (m_manufacturerChr == nullptr) { + m_manufacturerChr = m_deviceInfoSvc->createCharacteristic(m_manufacturerChrUuid, NIMBLE_PROPERTY::READ); + } - return m_manufacturerCharacteristic; -} + if (m_manufacturerChr) { + m_manufacturerChr->setValue(name); + return true; + } -/** - * @brief Set manufacturer name - * @param [in] name The manufacturer name of this HID device. - */ -void NimBLEHIDDevice::manufacturer(std::string name) { - manufacturer()->setValue(name); -} + return false; +} // setManufacturer /** * @brief Sets the Plug n Play characteristic value. @@ -114,152 +112,208 @@ void NimBLEHIDDevice::manufacturer(std::string name) { * @param [in] pid The product ID number. * @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)); -} +void NimBLEHIDDevice::setPnp(uint8_t sig, uint16_t vid, uint16_t pid, uint16_t version) { + uint8_t pnp[] = {sig, + static_cast(vid & 0xFF), + static_cast((vid >> 8) & 0xFF), + static_cast(pid & 0xFF), + static_cast((pid >> 8) & 0xFF), + static_cast(version & 0xFF), + static_cast((version >> 8) & 0xFF)}; + + m_pnpChr->setValue(pnp, sizeof(pnp)); +} // setPnp /** * @brief Sets the HID Information characteristic value. * @param [in] country The country code for the device. * @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)); -} +void NimBLEHIDDevice::setHidInfo(uint8_t country, uint8_t flags) { + uint8_t info[] = {0x11, 0x1, country, flags}; + m_hidInfoChr->setValue(info, sizeof(info)); +} // setHidInfo /** - * @brief Create input report characteristic - * @param [in] reportID input report ID, the same as in report map for input object related to the characteristic - * @return pointer to new input report characteristic + * @brief Set the battery level characteristic value. + * @param [in] level The battery level value. + * @param [in] notify If true sends a notification to the peer device, otherwise not. default = false */ -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); +void NimBLEHIDDevice::setBatteryLevel(uint8_t level, bool notify) { + m_batteryLevelChr->setValue(&level, 1); + if (notify) { + m_batteryLevelChr->notify(); + } +} // setBatteryLevel - uint8_t desc1_val[] = {reportID, 0x01}; - inputReportDescriptor->setValue((uint8_t*)desc1_val, 2); +/** + * @brief Get the input report characteristic. + * @param [in] reportId input report ID, the same as in report map for input object related to the characteristic. + * @return A pointer to the input report characteristic. + * @details This will create the characteristic if not already created. + */ +NimBLECharacteristic* NimBLEHIDDevice::getInputReport(uint8_t reportId) { + NimBLECharacteristic* inputReportChr = m_hidSvc->getCharacteristic(inputReportChrUuid); + if (inputReportChr == nullptr) { + inputReportChr = + m_hidSvc->createCharacteristic(inputReportChrUuid, + NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY | NIMBLE_PROPERTY::READ_ENC); + NimBLEDescriptor* inputReportDsc = + inputReportChr->createDescriptor(featureReportDscUuid, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::READ_ENC); + + uint8_t desc1_val[] = {reportId, 0x01}; + inputReportDsc->setValue(desc1_val, 2); + } + + return inputReportChr; +} // getInputReport - return inputReportCharacteristic; -} +/** + * @brief Get the output report characteristic. + * @param [in] reportId Output report ID, the same as in report map for output object related to the characteristic. + * @return A pointer to the output report characteristic. + * @details This will create the characteristic if not already created. + */ +NimBLECharacteristic* NimBLEHIDDevice::getOutputReport(uint8_t reportId) { + NimBLECharacteristic* outputReportChr = m_hidSvc->getCharacteristic(inputReportChrUuid); + if (outputReportChr == nullptr) { + outputReportChr = + m_hidSvc->createCharacteristic(inputReportChrUuid, + NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_NR | + NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::WRITE_ENC); + NimBLEDescriptor* outputReportDsc = outputReportChr->createDescriptor( + featureReportDscUuid, + NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::WRITE_ENC); + + uint8_t desc1_val[] = {reportId, 0x02}; + outputReportDsc->setValue(desc1_val, 2); + } + + return outputReportChr; +} // getOutputReport /** - * @brief Create output report characteristic - * @param [in] reportID Output report ID, the same as in report map for output object related to the characteristic - * @return Pointer to new output report characteristic + * @brief Get the feature report characteristic. + * @param [in] reportId Feature report ID, the same as in report map for feature object related to the characteristic. + * @return A pointer to feature report characteristic. + * @details This will create the characteristic if not already created. */ -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* NimBLEHIDDevice::getFeatureReport(uint8_t reportId) { + NimBLECharacteristic* featureReportChr = m_hidSvc->getCharacteristic(inputReportChrUuid); + if (featureReportChr == nullptr) { + featureReportChr = m_hidSvc->createCharacteristic( + inputReportChrUuid, + NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::WRITE_ENC); + NimBLEDescriptor* featureReportDsc = featureReportChr->createDescriptor( + featureReportDscUuid, + NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::WRITE_ENC); + + uint8_t desc1_val[] = {reportId, 0x03}; + featureReportDsc->setValue(desc1_val, 2); + } + + return featureReportChr; +} // getFeatureReport - uint8_t desc1_val[] = {reportID, 0x02}; - outputReportDescriptor->setValue((uint8_t*)desc1_val, 2); +/** + * @brief Get a keyboard boot input report characteristic. + * @returns A pointer to the boot input report characteristic, or nullptr on error. + * @details This will create the characteristic if not already created. + */ +NimBLECharacteristic* NimBLEHIDDevice::getBootInput() { + NimBLECharacteristic* bootInputChr = m_hidSvc->getCharacteristic(bootInputChrUuid); + if (bootInputChr) { + return bootInputChr; + } - return outputReportCharacteristic; -} + return m_hidSvc->createCharacteristic(bootInputChrUuid, NIMBLE_PROPERTY::NOTIFY); +} // getBootInput /** - * @brief Create feature report characteristic. - * @param [in] reportID Feature report ID, the same as in report map for feature object related to the characteristic - * @return Pointer to new feature report characteristic + * @brief Create a keyboard boot output report characteristic + * @returns A pointer to the boot output report characteristic, or nullptr on error. + * @details This will create the characteristic if not already created. */ -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); - - uint8_t desc1_val[] = {reportID, 0x03}; - featureReportDescriptor->setValue((uint8_t*)desc1_val, 2); +NimBLECharacteristic* NimBLEHIDDevice::getBootOutput() { + NimBLECharacteristic* bootOutputChr = m_hidSvc->getCharacteristic(bootOutputChrUuid); + if (bootOutputChr) { + return bootOutputChr; + } - return featureReportCharacteristic; -} + return m_hidSvc->createCharacteristic(bootOutputChrUuid, + NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_NR); +} // getBootOutput /** - * @brief Creates a keyboard boot input report characteristic + * @brief Get the HID control point characteristic. + * @returns A pointer to the HID control point characteristic. */ -NimBLECharacteristic* NimBLEHIDDevice::bootInput() { - return m_hidService->createCharacteristic((uint16_t)0x2a22, NIMBLE_PROPERTY::NOTIFY); -} +NimBLECharacteristic* NimBLEHIDDevice::getHidControl() { + return m_hidControlChr; +} // getHidControl /** - * @brief Create a keyboard boot output report characteristic + * @brief Get the HID protocol mode characteristic. + * @returns a pointer to the protocol mode characteristic. */ -NimBLECharacteristic* NimBLEHIDDevice::bootOutput() { - return m_hidService->createCharacteristic((uint16_t)0x2a32, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_NR); -} +NimBLECharacteristic* NimBLEHIDDevice::getProtocolMode() { + return m_protocolModeChr; +} // getProtocolMode /** - * @brief Returns a pointer to the HID control point characteristic. + * @brief Get the battery level characteristic + * @returns A pointer to the battery level characteristic */ -NimBLECharacteristic* NimBLEHIDDevice::hidControl() { - return m_hidControlCharacteristic; -} +NimBLECharacteristic* NimBLEHIDDevice::getBatteryLevel() { + return m_batteryLevelChr; +} // getBatteryLevel /** - * @brief Returns a pointer to the protocol mode characteristic. + * @brief Get the report map characteristic. + * @returns A pointer to the report map characteristic. */ -NimBLECharacteristic* NimBLEHIDDevice::protocolMode() { - return m_protocolModeCharacteristic; -} +NimBLECharacteristic* NimBLEHIDDevice::getReportMap() { + return m_reportMapChr; +} // getReportMap /** - * @brief Set the battery level characteristic value. - * @param [in] level The battery level value. + * @brief Get the PnP characteristic. + * @returns A pointer to the PnP characteristic. */ -void NimBLEHIDDevice::setBatteryLevel(uint8_t level) { - m_batteryLevelCharacteristic->setValue(&level, 1); -} -/* - * @brief Returns battery level characteristic - * @ return battery level characteristic - */ -NimBLECharacteristic* NimBLEHIDDevice::batteryLevel() { - return m_batteryLevelCharacteristic; -} - -NimBLECharacteristic* NimBLEHIDDevice::reportMap() { - return m_reportMapCharacteristic; -} +NimBLECharacteristic* NimBLEHIDDevice::getPnp() { + return m_pnpChr; +} // getPnp -/* - -BLECharacteristic* BLEHIDDevice::pnp() { - return m_pnpCharacteristic; -} - - -BLECharacteristic* BLEHIDDevice::hidInfo() { - return m_hidInfoCharacteristic; -} -*/ +/** + * @brief Get the HID information characteristic. + * @returns A pointer to the HID information characteristic. + */ +NimBLECharacteristic* NimBLEHIDDevice::getHidInfo() { + return m_hidInfoChr; +} // hidInfo /** - * @brief Returns a pointer to the device information service. + * @brief Get the manufacturer characteristic. + * @returns A pointer to the manufacturer characteristic. */ -NimBLEService* NimBLEHIDDevice::deviceInfo() { - return m_deviceInfoService; -} +NimBLEService* NimBLEHIDDevice::getDeviceInfoService() { + return m_deviceInfoSvc; +} // getDeviceInfoService /** - * @brief Returns a pointer to the HID service. + * @brief Get the HID service. + * @returns A pointer to the HID service. */ -NimBLEService* NimBLEHIDDevice::hidService() { - return m_hidService; -} +NimBLEService* NimBLEHIDDevice::getHidService() { + return m_hidSvc; +} // getHidService /** - * @brief @brief Returns a pointer to the battery service. + * @brief Get the battery service. + * @returns A pointer to the battery service. */ -NimBLEService* NimBLEHIDDevice::batteryService() { - return m_batteryService; -} +NimBLEService* NimBLEHIDDevice::getBatteryService() { + return m_batterySvc; +} // getBatteryService #endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL */ diff --git a/src/NimBLEHIDDevice.h b/src/NimBLEHIDDevice.h index f0da9943..e8e27330 100644 --- a/src/NimBLEHIDDevice.h +++ b/src/NimBLEHIDDevice.h @@ -12,76 +12,73 @@ * 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(); - - void reportMap(uint8_t* map, uint16_t); - void startServices(); - - NimBLEService* deviceInfo(); - NimBLEService* hidService(); - NimBLEService* batteryService(); - - 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); - + public: + NimBLEHIDDevice(NimBLEServer* server); - 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(); + void setReportMap(uint8_t* map, uint16_t); + void startServices(); + bool setManufacturer(const std::string& name); + void setPnp(uint8_t sig, uint16_t vid, uint16_t pid, uint16_t version); + void setHidInfo(uint8_t country, uint8_t flags); + void setBatteryLevel(uint8_t level, bool notify = false); + NimBLECharacteristic* getBatteryLevel(); + NimBLECharacteristic* getReportMap(); + NimBLECharacteristic* getHidControl(); + NimBLECharacteristic* getInputReport(uint8_t reportId); + NimBLECharacteristic* getOutputReport(uint8_t reportId); + NimBLECharacteristic* getFeatureReport(uint8_t reportId); + NimBLECharacteristic* getProtocolMode(); + NimBLECharacteristic* getBootInput(); + NimBLECharacteristic* getBootOutput(); + NimBLECharacteristic* getPnp(); + NimBLECharacteristic* getHidInfo(); + NimBLEService* getDeviceInfoService(); + NimBLEService* getHidService(); + NimBLEService* getBatteryService(); -private: - NimBLEService* m_deviceInfoService; //0x180a - NimBLEService* m_hidService; //0x1812 - NimBLEService* m_batteryService = 0; //0x180f + private: + NimBLEService* m_deviceInfoSvc{nullptr}; // 0x180a + NimBLEService* m_hidSvc{nullptr}; // 0x1812 + NimBLEService* m_batterySvc{nullptr}; // 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_manufacturerChr{nullptr}; // 0x2a29 + NimBLECharacteristic* m_pnpChr{nullptr}; // 0x2a50 + NimBLECharacteristic* m_hidInfoChr{nullptr}; // 0x2a4a + NimBLECharacteristic* m_reportMapChr{nullptr}; // 0x2a4b + NimBLECharacteristic* m_hidControlChr{nullptr}; // 0x2a4c + NimBLECharacteristic* m_protocolModeChr{nullptr}; // 0x2a4e + NimBLECharacteristic* m_batteryLevelChr{nullptr}; // 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_