From cf64169bc0d9233598d7e766c96cd57c9934efe3 Mon Sep 17 00:00:00 2001 From: h2zero Date: Sun, 17 Jan 2021 10:19:58 -0700 Subject: [PATCH] Update documentation. * Docuemnt HID device class. * Add usage tips. --- docs/Command_line_config.md | 31 ++++++----- docs/Improvements_and_updates.md | 16 +++++- docs/Usage_tips.md | 41 +++++++++++++++ docs/index.md | 6 ++- src/NimBLEHIDDevice.cpp | 88 +++++++++++++++++++------------- 5 files changed, 127 insertions(+), 55 deletions(-) create mode 100644 docs/Usage_tips.md diff --git a/docs/Command_line_config.md b/docs/Command_line_config.md index 813156f..b6ab72f 100644 --- a/docs/Command_line_config.md +++ b/docs/Command_line_config.md @@ -4,90 +4,89 @@ If defined, NimBLE Client functions will not be included. - Reduces flash size by approx. 7kB. -
+
`CONFIG_BT_NIMBLE_ROLE_OBSERVER_DISABLED` If defined, NimBLE Scan functions will not be included. - Reduces flash size by approx. 26kB. -
+
`CONFIG_BT_NIMBLE_ROLE_PERIPHERAL_DISABLED` If defined NimBLE Server functions will not be included. - Reduces flash size by approx. 16kB. -
+
`CONFIG_BT_NIMBLE_ROLE_BROADCASTER_DISABLED` If defined, NimBLE Advertising functions will not be included. - Reduces flash size by approx. 5kB. -
+
`CONFIG_BT_NIMBLE_DEBUG` If defined, enables debug log messages from the NimBLE host - Uses approx. 32kB of flash memory. -
+
`CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT` If defined, NimBLE host return codes will be printed as text in debug log messages. - Uses approx. 7kB of flash memory. -
+
`CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT` If defined, GAP event codes will be printed as text in debug log messages. - Uses approx. 1kB of flash memory. -
+
`CONFIG_NIMBLE_CPP_ENABLE_ADVERTISMENT_TYPE_TEXT` If defined, advertisment types will be printed as text while scanning in debug log messages. - Uses approx. 250 bytes of flash memory. -
+
`CONFIG_BT_NIMBLE_PINNED_TO_CORE` Sets the core the NimBLE host stack will run on - Options: 0 or 1 -
+
`CONFIG_BT_NIMBLE_TASK_STACK_SIZE` Set the task stack size for the NimBLE core. - Default is 4096 -
- +
`CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL` Sets the NimBLE stack to use external PSRAM will be loaded - Must be defined with a value of 1; Default is CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL 1 -
+
`CONFIG_BT_NIMBLE_MAX_CONNECTIONS` Sets the number of simultaneous connections (esp controller max is 9) - Default value is 3 -
+
`CONFIG_BT_NIMBLE_MAX_BONDS` Sets the number of devices allowed to store/bond with - Default value is 3 -
+
`CONFIG_BT_NIMBLE_MAX_CCCDS` Sets the maximum number of CCCD subscriptions to store - Default value is 8 -
+
`CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME` Set the default device name - Default value is "nimble" -
+
diff --git a/docs/Improvements_and_updates.md b/docs/Improvements_and_updates.md index 245defd..c3c1126 100644 --- a/docs/Improvements_and_updates.md +++ b/docs/Improvements_and_updates.md @@ -69,7 +69,9 @@ Now takes 2 optional parameters, the first is the duration to advertise for (in that is invoked when advertsing ends and takes a pointer to a `NimBLEAdvertising` object (similar to the `NimBLEScan::start` API). This provides an opportunity to update the advertisment data if desired. -
+ +Also now returns a bool value to indicate if advertising successfully started or not. +
# Client @@ -100,8 +102,18 @@ Has been **deprecated** as now the internally stored characteristic value is upd `NimBLERemoteCharacteristic::subscribe` and `NimBLERemoteCharacteristic::unsubscribe` have been implemented to replace it. A callback is no longer requred to get the most recent value unless timing is important. Instead, the application can call `NimBLERemoteCharacteristic::getValue` to get the last updated value any time. +
-In addition `NimBLERemoteCharacteristic::readValue` and `NimBLERemoteCharacteristic::getValue` take an optional timestamp parameter which will update it's value with +The `notifiy_callback` function is now defined as a `std::function` to take advantage of using `std::bind` to specifiy a class member function for the callback. + +Example: +``` +using namespace std::placeholders; +notify_callback callback = std::bind(&::, this, _1, _2, _3, _4); +->subscribe(true, callback); +``` + +`NimBLERemoteCharacteristic::readValue` and `NimBLERemoteCharacteristic::getValue` take an optional timestamp parameter which will update it's value with the time the last value was recieved. > NimBLEClient::getService diff --git a/docs/Usage_tips.md b/docs/Usage_tips.md new file mode 100644 index 0000000..b8edde2 --- /dev/null +++ b/docs/Usage_tips.md @@ -0,0 +1,41 @@ +# Usage Tips + +## Put BLE functions in a task running on the NimBLE stack core + +When commands are sent to the stack from a differnt core they can experience delays in execution. +This library detects this and invokes the esp32 IPC to reroute these commands through the correct core but this also increases overhead. +Therefore it is highly recommended to create tasks for BLE to run on the same core, the macro `CONFIG_BT_NIMBLE_PINNED_TO_CORE` can be used to set the core. +
+ +## Do not delete client instances unless necessary or unused + +When a client instance has been created and has connected to a peer device and it has retrieved service/characteristic information it will store that data for the life of the client instance. +If you are periodically connecting to the same devices and you have deleted the client instance or the services when connecting again it will cause a retrieval of that information from the peer again. +This results in significant energy drain on the battery of the devices, fragments heap, and reduces connection performance. + +Client instances in this library use approximately 20% of the original bluedroid library, deleteing them will provide much less gain than it did before. + +It is recommended to retain the client instance in cases where the time between connecting to the same device is less than 5 minutes. +
+ +## Only retrieve the services and characteriscs needed + +As a client the use of `NimBLEClient::getServices` or `NimBLERemoteService::getCharacteristics` and using `true` for the parameter should be limited to devices that are not known. +Instead `NimBLEClient::getService(NimBLEUUID)` or `NimBLERemoteService::getCharacteristic(NimBLEUUID)` should be used to access certain attributes that are useful to the application. +This reduces energy consumed, heap allocated, connection time and improves overall efficiency. +
+ +## Check return values + +Many user issues can be avoided by checking if a function returned successfully, by either testing for true/false such as when calling `NimBLEClient::connect`, +or nullptr such as when calling `NimBLEClient::getService`. The latter being a must, as calling a method on a nullptr will surely result in a crash. +Most of the functions in this library return something that should be checked before proceeding. +
+ +## There will be bugs - please report them + +No code is bug free and unit testing will not find them all on it's own. If you encounter a bug, please report it along with any logs and decoded backtrace if applicable. +Best efforts will be made to correct any errors ASAP. + +Bug reports can be made at https://github.com/h2zero/NimBLE-Arduino/issues or https://github.com/h2zero/esp-nimble-cpp/issues. +Questions and suggestions will be happily accepted there as well. diff --git a/docs/index.md b/docs/index.md index edd67ab..4bfbd24 100644 --- a/docs/index.md +++ b/docs/index.md @@ -48,7 +48,9 @@ If you have not used the original Bluedroid library please refer to the [New use If you are familiar with the original library, see: [The migration guide](Migration_guide.md) for details. -Also see [Improvements_and_updates](Improvements_and_updates.md) for information about non-breaking changes. +Also see [Improvements and updates](Improvements_and_updates.md) for information about non-breaking changes. + +For more advanced usage see [Usage tips](Usage_tips.md) for more performance and optimization. ### Arduino specific See the Refactored_original_examples in the examples folder for highlights of the differences with the original library. @@ -61,7 +63,7 @@ Change the settings in the nimconfig.h file to customize NimBLE to your project,
### Command line and platformio -See the command line configuration options available in [Command_line_config](Command_line_config.md). +See the command line configuration options available in [Command line config](Command_line_config.md).
# Acknowledgments diff --git a/src/NimBLEHIDDevice.cpp b/src/NimBLEHIDDevice.cpp index 39f07de..a06b753 100644 --- a/src/NimBLEHIDDevice.cpp +++ b/src/NimBLEHIDDevice.cpp @@ -20,6 +20,10 @@ #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 @@ -61,15 +65,18 @@ NimBLEHIDDevice::NimBLEHIDDevice(NimBLEServer* server) { NimBLEHIDDevice::~NimBLEHIDDevice() { } -/* - * @brief +/** + * @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); } -/* - * @brief This function suppose to be called at the end, when we have created all characteristics we need to build HID service +/** + * @brief Start the HID device services.\n + * This function called when all the services have been created. */ void NimBLEHIDDevice::startServices() { m_deviceInfoService->start(); @@ -77,41 +84,47 @@ void NimBLEHIDDevice::startServices() { m_batteryService->start(); } -/* - * @brief Create manufacturer characteristic (this characteristic is optional) +/** + * @brief Create a manufacturer characteristic (this characteristic is optional). */ NimBLECharacteristic* NimBLEHIDDevice::manufacturer() { m_manufacturerCharacteristic = m_deviceInfoService->createCharacteristic((uint16_t) 0x2a29, NIMBLE_PROPERTY::READ); return m_manufacturerCharacteristic; } -/* +/** * @brief Set manufacturer name - * @param [in] name manufacturer name + * @param [in] name The manufacturer name of this HID device. */ void NimBLEHIDDevice::manufacturer(std::string name) { m_manufacturerCharacteristic->setValue(name); } -/* - * @brief +/** + * @brief Sets the Plug n Play characterisc 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. */ void NimBLEHIDDevice::pnp(uint8_t sig, uint16_t vid, uint16_t pid, uint16_t version) { uint8_t pnp[] = { sig, (uint8_t) (vid >> 8), (uint8_t) vid, (uint8_t) (pid >> 8), (uint8_t) pid, (uint8_t) (version >> 8), (uint8_t) version }; m_pnpCharacteristic->setValue(pnp, sizeof(pnp)); } -/* - * @brief +/** + * @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)); } -/* - * @brief Create input report characteristic that need to be saved as new characteristic object so can be further used - * @param [in] reportID input report ID, the same as in report map for input object related to created characteristic +/** + * @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 */ NimBLECharacteristic* NimBLEHIDDevice::inputReport(uint8_t reportID) { @@ -124,9 +137,9 @@ NimBLECharacteristic* NimBLEHIDDevice::inputReport(uint8_t reportID) { return inputReportCharacteristic; } -/* - * @brief Create output report characteristic that need to be saved as new characteristic object so can be further used - * @param [in] reportID Output report ID, the same as in report map for output object related to created characteristic +/** + * @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 */ NimBLECharacteristic* NimBLEHIDDevice::outputReport(uint8_t reportID) { @@ -139,9 +152,9 @@ NimBLECharacteristic* NimBLEHIDDevice::outputReport(uint8_t reportID) { return outputReportCharacteristic; } -/* - * @brief Create feature report characteristic that need to be saved as new characteristic object so can be further used - * @param [in] reportID Feature report ID, the same as in report map for feature object related to created characteristic +/** + * @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 */ NimBLECharacteristic* NimBLEHIDDevice::featureReport(uint8_t reportID) { @@ -154,34 +167,38 @@ NimBLECharacteristic* NimBLEHIDDevice::featureReport(uint8_t reportID) { return featureReportCharacteristic; } -/* - * @brief +/** + * @brief Creates a keyboard boot input report characteristic */ NimBLECharacteristic* NimBLEHIDDevice::bootInput() { return m_hidService->createCharacteristic((uint16_t) 0x2a22, NIMBLE_PROPERTY::NOTIFY); } -/* - * @brief +/** + * @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); } -/* - * @brief +/** + * @brief Returns a pointer to the HID control point characteristic. */ NimBLECharacteristic* NimBLEHIDDevice::hidControl() { return m_hidControlCharacteristic; } -/* - * @brief +/** + * @brief Returns a pointer to the protocol mode characteristic. */ NimBLECharacteristic* NimBLEHIDDevice::protocolMode() { return m_protocolModeCharacteristic; } +/** + * @brief Set the battery level characteristic value. + * @param [in] level The battery level value. + */ void NimBLEHIDDevice::setBatteryLevel(uint8_t level) { m_batteryLevelCharacteristic->setValue(&level, 1); } @@ -208,22 +225,23 @@ BLECharacteristic* BLEHIDDevice::hidInfo() { return m_hidInfoCharacteristic; } */ -/* - * @brief + +/** + * @brief Returns a pointer to the device information service. */ NimBLEService* NimBLEHIDDevice::deviceInfo() { return m_deviceInfoService; } -/* - * @brief +/** + * @brief Returns a pointer to the HID service. */ NimBLEService* NimBLEHIDDevice::hidService() { return m_hidService; } -/* - * @brief +/** + * @brief @brief Returns a pointer to the battery service. */ NimBLEService* NimBLEHIDDevice::batteryService() { return m_batteryService;