forked from h2zero/esp-nimble-cpp
Fix comments for doxygen (#16)
* Fix comments for doxygen * Add documentation and update readme.
This commit is contained in:
222
docs/BREAKING_API_CHANGES.md
Normal file
222
docs/BREAKING_API_CHANGES.md
Normal file
@ -0,0 +1,222 @@
|
||||
# Breaking API Changes vs Original
|
||||
<br/>
|
||||
|
||||
# Server API differnces
|
||||
|
||||
### Characteristics
|
||||
When creating a characteristic the properties are now set with `NIMBLE_PROPERTY::XXXX` instead of `BLECharacteristic::XXXX`.
|
||||
|
||||
#### Originally
|
||||
> BLECharacteristic::PROPERTY_READ |
|
||||
> BLECharacteristic::PROPERTY_WRITE
|
||||
|
||||
#### Is Now
|
||||
> NIMBLE_PROPERTY::READ |
|
||||
> NIMBLE_PROPERTY::WRITE
|
||||
<br/>
|
||||
|
||||
#### The full list of properties
|
||||
> NIMBLE_PROPERTY::READ
|
||||
> NIMBLE_PROPERTY::READ_ENC
|
||||
> NIMBLE_PROPERTY::READ_AUTHEN
|
||||
> NIMBLE_PROPERTY::READ_AUTHOR
|
||||
> NIMBLE_PROPERTY::WRITE
|
||||
> NIMBLE_PROPERTY::WRITE_NR
|
||||
> NIMBLE_PROPERTY::WRITE_ENC
|
||||
> NIMBLE_PROPERTY::WRITE_AUTHEN
|
||||
> NIMBLE_PROPERTY::WRITE_AUTHOR
|
||||
> NIMBLE_PROPERTY::BROADCAST
|
||||
> NIMBLE_PROPERTY::NOTIFY
|
||||
> NIMBLE_PROPERTY::INDICATE
|
||||
<br/>
|
||||
|
||||
### Descriptors
|
||||
Descriptors are now created using the `NimBLECharacteristic::createDescriptor()` method.
|
||||
|
||||
The previous method `BLECharacteristic::addDescriptor()` is now a private function in the library.
|
||||
|
||||
This was done because the NimBLE host automatically creates a 0x2902 descriptor if a characteristic has NOTIFY or INDICATE properties applied.
|
||||
Due to this fact, the library also creates one automatically for your application.
|
||||
The only reason to manually create this descriptor now is to assign callback functions.
|
||||
If you do not require this functionality you can safely exclude the manual creation of the 0x2902 descriptor.
|
||||
|
||||
For any other descriptor, (except 0x2904, see below) it should now be created just as characteristics are
|
||||
by using the `NimBLECharacteristic::createDescriptor` method.
|
||||
Which are defined as:
|
||||
```
|
||||
NimBLEDescriptor* createDescriptor(const char* uuid,
|
||||
uint32_t properties =
|
||||
NIMBLE_PROPERTY::READ |
|
||||
NIMBLE_PROPERTY::WRITE,
|
||||
uint16_t max_len = 100);
|
||||
|
||||
NimBLEDescriptor* createDescriptor(NimBLEUUID uuid,
|
||||
uint32_t properties =
|
||||
NIMBLE_PROPERTY::READ |
|
||||
NIMBLE_PROPERTY::WRITE,
|
||||
uint16_t max_len = 100);
|
||||
```
|
||||
##### Example
|
||||
```
|
||||
pDescriptor = pCharacteristic->createDescriptor("ABCD",
|
||||
NIMBLE_PROPERTY::READ |
|
||||
NIMBLE_PROPERTY::WRITE |
|
||||
NIMBLE_PROPERTY::WRITE_ENC,
|
||||
25);
|
||||
```
|
||||
Would create a descriptor with the UUID 0xABCD, publicly readable but only writable if paired/bonded (encrypted) and has a max value length of 25 bytes.
|
||||
<br/>
|
||||
|
||||
For the 0x2904 and 0x2902 descriptor, there is a special class that is created when you call `createDescriptor("2904")`or `createDescriptor("2902")`.
|
||||
|
||||
The pointer returned is of the base class `NimBLEDescriptor` but the call will create the derived class of `NimBLE2904` or `NimBLE2902` so you must cast the returned pointer to
|
||||
`NimBLE2904` or `NimBLE2902` to access the specific class methods.
|
||||
|
||||
##### Example
|
||||
```
|
||||
p2904 = (NimBLE2904*)pCharacteristic->createDescriptor("2904");
|
||||
p2902 = (NimBLE2902*)pCharacteristic->createDescriptor("2902");
|
||||
```
|
||||
<br/>
|
||||
|
||||
### Server Security
|
||||
Security is set on the characteristic or descriptor properties by applying one of the following:
|
||||
> NIMBLE_PROPERTY::READ_ENC
|
||||
> NIMBLE_PROPERTY::READ_AUTHEN
|
||||
> NIMBLE_PROPERTY::READ_AUTHOR
|
||||
> NIMBLE_PROPERTY::WRITE_ENC
|
||||
> NIMBLE_PROPERTY::WRITE_AUTHEN
|
||||
> NIMBLE_PROPERTY::WRITE_AUTHOR
|
||||
|
||||
When a peer wants to read or write a characteristic or descriptor with any of these properties applied
|
||||
it will trigger the pairing process. By default the "just-works" pairing will be performed automatically.
|
||||
This can be changed to use passkey authentication or numeric comparison. See [Security Differences](#security-differences) for details.
|
||||
|
||||
<br/>
|
||||
|
||||
# Client API Differences
|
||||
The `NimBLEAdvertisedDeviceCallbacks::onResult()` method now receives a pointer to the
|
||||
`NimBLEAdvertisedDevice` object instead of a copy.
|
||||
|
||||
`NimBLEClient::connect()` now takes an extra parameter to indicate if the client should download the services
|
||||
database from the peripheral, default value is true.
|
||||
|
||||
Defined as:
|
||||
> NimBLEClient::connect(NimBLEAdvertisedDevice\* device, bool refreshServices = true);
|
||||
> NimBLEClient::connect(NimBLEAddress address, uint8_t type = BLE_ADDR_PUBLIC, bool refreshServices = true);
|
||||
|
||||
If set to false the client will use the services database it retrieved from the peripheral last time it connected.
|
||||
This allows for faster connections and power saving if the devices just dropped connection and want to reconnect.
|
||||
<br/>
|
||||
|
||||
> NimBLERemoteCharacteristic::writeValue();
|
||||
> NimBLERemoteCharacteristic::registerForNotify();
|
||||
|
||||
Now return true or false to indicate success or failure so you can choose to disconnect or try again.
|
||||
<br/>
|
||||
|
||||
> NimBLERemoteCharacteristic::registerForNotify();
|
||||
Is now **deprecated**.
|
||||
> NimBLERemoteCharacteristic::subscribe()
|
||||
> NimBLERemoteCharacteristic::unsubscribe()
|
||||
|
||||
Are the new methods added to replace it.
|
||||
<br/>
|
||||
|
||||
> NimBLERemoteCharacteristic::readUInt8()
|
||||
> NimBLERemoteCharacteristic::readUInt16()
|
||||
> NimBLERemoteCharacteristic::readUInt32()
|
||||
> NimBLERemoteCharacteristic::readFloat()
|
||||
|
||||
Are **deprecated** and NimBLERemoteCharacteristic::readValue(time_t\*, bool) template added to replace them.
|
||||
<br/>
|
||||
|
||||
> NimBLERemoteService::getCharacteristicsByHandle()
|
||||
|
||||
Has been removed from the API as it is no longer maintained in the library.
|
||||
<br/>
|
||||
|
||||
> NimBLERemoteCharacteristic::readRawData()
|
||||
|
||||
Has been removed from the API as it stored an unnecessary copy of the data.
|
||||
The user application should use NimBLERemoteCharacteristic::readValue or NimBLERemoteCharacteristic::getValue.
|
||||
Then cast the returned std::string to the type they wish such as:
|
||||
```
|
||||
uint8_t *val = (uint8_t*)pChr->readValue().data();
|
||||
```
|
||||
<br/>
|
||||
|
||||
> NimBLEClient::getServices(bool refresh = false)
|
||||
> NimBLERemoteCharacteristic::getDescriptors(bool refresh = false)
|
||||
> NimBLERemoteService::getCharacteristics(bool refresh = false)
|
||||
|
||||
These methods now take an optional (bool) parameter and return a pointer to `std::vector` instead of `std::map`.
|
||||
If passed true it will clear the respective vector and retrieve all the respective attributes from the peripheral.
|
||||
If false(default) it will return the respective vector with the currently stored attributes.
|
||||
|
||||
**Removed:** the automatic discovery of all peripheral attributes as they consumed time and resources for data
|
||||
the user may not be interested in.
|
||||
|
||||
**Added:** NimBLEClient::discoverAttributes() for the user to discover all the peripheral attributes
|
||||
to replace the the removed functionality.
|
||||
<br/>
|
||||
|
||||
> NimBLEClient::getService()
|
||||
> NimBLERemoteService::getCharacteristic()
|
||||
> NimBLERemoteCharacteristic::getDescriptor()
|
||||
|
||||
These methods will now check the respective vectors for the attribute object and, if not found, will retrieve (only)
|
||||
the specified attribute from the peripheral.
|
||||
|
||||
These changes allow more control for the user to manage the resources used for the attributes.
|
||||
<br/>
|
||||
|
||||
### Client Security
|
||||
The client will automatically initiate security when the peripheral responds that it's required.
|
||||
The default configuration will use "just-works" pairing with no bonding, if you wish to enable bonding see below.
|
||||
<br/>
|
||||
|
||||
# Security Differences
|
||||
Security callback functions are now incorporated in the NimBLEServerCallbacks / NimBLEClientCallbacks classes.
|
||||
However backward compatibility with the original `BLESecurity` class is retained to minimize app code changes.
|
||||
|
||||
The callback methods are:
|
||||
|
||||
> bool onConfirmPIN(uint32_t pin);
|
||||
|
||||
Receives the pin when using numeric comparison authentication, `return true;` to accept.
|
||||
<br/>
|
||||
|
||||
> uint32_t onPassKeyRequest();
|
||||
|
||||
For server callback; return the passkey expected from the client.
|
||||
For client callback; return the passkey to send to the server.
|
||||
<br/>
|
||||
|
||||
> void onAuthenticationComplete(ble_gap_conn_desc\* desc);
|
||||
|
||||
Authentication complete, success or failed information is in `desc`.
|
||||
<br/>
|
||||
|
||||
Security settings and IO capabilities are now set by the following methods of NimBLEDevice.
|
||||
> NimBLEDevice::setSecurityAuth(bool bonding, bool mitm, bool sc)
|
||||
> NimBLEDevice::setSecurityAuth(uint8_t auth_req)
|
||||
|
||||
Sets the authorization mode for this device.
|
||||
<br/>
|
||||
|
||||
> NimBLEDevice::setSecurityIOCap(uint8_t iocap)
|
||||
|
||||
Sets the Input/Output capabilities of this device.
|
||||
<br/>
|
||||
|
||||
> NimBLEDevice::setSecurityInitKey(uint8_t init_key)
|
||||
|
||||
If we are the initiator of the security procedure this sets the keys we will distribute.
|
||||
<br/>
|
||||
|
||||
> NimBLEDevice::setSecurityRespKey(uint8_t resp_key)
|
||||
|
||||
Sets the keys we are willing to accept from the peer during pairing.
|
||||
<br/>
|
||||
|
99
docs/Improvements_and_updates.md
Normal file
99
docs/Improvements_and_updates.md
Normal file
@ -0,0 +1,99 @@
|
||||
# Improvements and updates
|
||||
|
||||
# Server
|
||||
|
||||
NimBLECharacteristic::setValue(const T &s)
|
||||
NimBLEDescriptor::setValue(const T &s)
|
||||
|
||||
Now use a template to accomodate standard and custom types/values.
|
||||
|
||||
**Example**
|
||||
```
|
||||
struct my_struct{
|
||||
uint8_t one;
|
||||
uint16_t two;
|
||||
uint32_t four;
|
||||
uint64_t eight;
|
||||
float flt;
|
||||
}myStruct;
|
||||
|
||||
myStruct.one = 1;
|
||||
myStruct.two = 2;
|
||||
myStruct.four = 4;
|
||||
myStruct.eight = 8;
|
||||
myStruct.flt = 1234.56;
|
||||
|
||||
pCharacteristic->setValue(myStruct);
|
||||
```
|
||||
This will send the struct to the recieving client when read or a notification sent.
|
||||
|
||||
NimBLECharacteristic::getValue now takes an optional timestamp parameter which will update it's value with
|
||||
the time the last value was recieved. In addition an overloaded template has been added to retrieve the value
|
||||
as a type specified by the user.
|
||||
|
||||
**Example**
|
||||
```
|
||||
time_t timestamp;
|
||||
myStruct = pCharacteristic->getValue<myStruct>(×tamp); // timestamp optional
|
||||
```
|
||||
<br/>
|
||||
|
||||
**Advertising will automatically start when a client disconnects.**
|
||||
|
||||
A new method `NimBLEServer::advertiseOnDisconnect(bool)` has been implemented to control this, true(default) = enabled.
|
||||
<br/>
|
||||
|
||||
# Client
|
||||
|
||||
NimBLERemoteCharacteristic::readValue(time_t\*, bool)
|
||||
NimBLERemoteDescriptor::readValue(bool)
|
||||
|
||||
Have been added as templates to allow reading the values as any specified type.
|
||||
|
||||
**Example**
|
||||
```
|
||||
struct my_struct{
|
||||
uint8_t one;
|
||||
uint16_t two;
|
||||
uint32_t four;
|
||||
uint64_t eight;
|
||||
float flt;
|
||||
}myStruct;
|
||||
|
||||
time_t timestamp;
|
||||
myStruct = pRemoteCharacteristic->readValue<myStruct>(×tamp); // timestamp optional
|
||||
```
|
||||
<br/>
|
||||
|
||||
NimBLERemoteCharacteristic::registerForNotify
|
||||
Has been **deprecated** as now the internally stored characteristic value is updated when notification/indication is recieved.
|
||||
|
||||
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 time the last value was recieved.
|
||||
|
||||
NimBLEClient::getService will now retrieve only the service specified and not the full database, this preserves resources
|
||||
otherwise wasted retrieving and allocating attributes the user application is not interested in.
|
||||
<br/>
|
||||
|
||||
# General
|
||||
To reduce resource use all instances of std::map have been replaced with std::vector.
|
||||
|
||||
Use of FreeRTOS::Semaphore has been removed as it was consuming too much ram, the related files have been left in place to accomodate application use.
|
||||
|
||||
Operators `==`, `!=` and `std::string` have been added to NimBLEAddress and NimBLEUUID for easier comparison and logging.
|
||||
|
||||
New constructor for NimBLEUUID(uint32_t, uint16_t, uint16_t, uint64_t) added to lower memory use vs string construction. See: [#21](https://github.com/h2zero/NimBLE-Arduino/pull/21).
|
||||
|
||||
Security/pairing operations are now handled in the respective NimBLEClientCallbacks and NimBLEServerCallbacks classes, NimBLESecurity(deprecated) remains for backward compatibility.
|
||||
|
||||
Configuration options have been added to add or remove debugging information, when disabled (default) significatly reduces binary size.
|
||||
In ESP-IDF the options are in menuconfig: `Main menu -> ESP-NimBLE-cpp configuration`.
|
||||
For Arduino the options must be commented / uncommented in nimconfig.h.
|
||||
|
||||
Many more internal improvements have been made as well, this is a brief overview. Refer to the class docs for futher information on class specifics.
|
||||
<br/>
|
||||
|
67
docs/index.md
Normal file
67
docs/index.md
Normal file
@ -0,0 +1,67 @@
|
||||
# Overview
|
||||
|
||||
This is a C++ BLE library for the ESP32 that uses the NimBLE host stack instead of bluedroid.
|
||||
The aim is to maintain, as much as reasonable, the original bluedroid C++ API while adding new features
|
||||
and making improvements in performance, resource use and stability.
|
||||
|
||||
**Testing shows a nearly 50% reduction in flash use and approx. 100kB less ram consumed vs the original!**
|
||||
*Your results may vary*
|
||||
<br/>
|
||||
|
||||
### What is NimBLE?
|
||||
NimBLE is a completely open source Bluetooth Low Energy stack produced by [Apache](https://github.com/apache/mynewt-nimble).
|
||||
It is more suited to resource constrained devices than bluedroid and has now been ported to the ESP32 by Espressif.
|
||||
<br/>
|
||||
|
||||
# Arduino Installation
|
||||
Download as .zip and extract to Arduino/libraries folder, or in Arduino IDE from Sketch menu -> Include library -> Add .Zip library.
|
||||
|
||||
`#include "NimBLEDevice.h"` at the beginning of your sketch.
|
||||
|
||||
Tested and working with esp32-arduino v1.0.2 and 1.0.4 in Arduino IDE v1.8.12 and platform IO.
|
||||
<br/>
|
||||
|
||||
# ESP-IDF Installation
|
||||
### v4.0+
|
||||
Download as .zip and extract or clone into the components folder in your esp-idf project.
|
||||
|
||||
Run menuconfig, go to `Component config->Bluetooth` enable Bluetooth and in `Bluetooth host` NimBLE.
|
||||
Configure settings in `NimBLE Options`.
|
||||
`#include "NimBLEDevice.h"` in main.cpp.
|
||||
Call `NimBLEDevice::init("");` in `app_main`.
|
||||
<br/>
|
||||
|
||||
### v3.2 & v3.3
|
||||
The NimBLE component does not come with these versions of IDF.
|
||||
A backport that works in these versions has been created and is [available here](https://github.com/h2zero/esp-nimble-component).
|
||||
Download or clone that repo into your project/components folder and run menuconfig.
|
||||
Configure settings in `main menu -> NimBLE Options`.
|
||||
|
||||
`#include "NimBLEDevice.h"` in main.cpp.
|
||||
Call `NimBLEDevice::init("");` in `app_main`.
|
||||
<br/>
|
||||
|
||||
# Using
|
||||
This library is intended to be compatible with the original ESP32 BLE functions and types with minor changes.
|
||||
|
||||
See: [Breaking API Changes vs Original](docs/BREAKING_API_CHANGES.md) for details.
|
||||
|
||||
Also see [Improvements_and_updates](docs/Improvements_and_updates.md) for information about non-breaking changes.
|
||||
|
||||
### Arduino
|
||||
See the Refactored_original_examples in the examples folder for highlights of the differences with the original library.
|
||||
|
||||
More advanced examples highlighting many available features are in examples/NimBLE_Server, NimBLE_Client.
|
||||
|
||||
Beacon examples provided by [beegee-tokyo](https://github.com/beegee-tokyo) are in examples/BLE_Beacon_Scanner, BLE_EddystoneTLM_Beacon, BLE_EddystoneURL_Beacon.
|
||||
|
||||
Change the settings in the nimconfig.h file to customize NimBLE to your project, such as increasing max connections (default == 3).
|
||||
<br/>
|
||||
|
||||
# Acknowledgments
|
||||
|
||||
* [nkolban](https://github.com/nkolban) and [chegewara](https://github.com/chegewara) for the [original esp32 BLE library](https://github.com/nkolban/esp32-snippets/tree/master/cpp_utils) this project was derived from.
|
||||
* [beegee-tokyo](https://github.com/beegee-tokyo) for contributing your time to test/debug and contributing the beacon examples.
|
||||
* [Jeroen88](https://github.com/Jeroen88) for the amazing help debugging and improving the client code.
|
||||
<br/>
|
||||
|
Reference in New Issue
Block a user