Fix comments for doxygen (#16)

* Fix comments for doxygen

* Add documentation and update readme.
This commit is contained in:
h2zero
2020-07-08 19:27:26 -06:00
committed by GitHub
parent 64caf3553e
commit aae2a8f1e3
39 changed files with 1384 additions and 686 deletions

View 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/>

View 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>(&timestamp); // 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>(&timestamp); // 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
View 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/>