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
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
39 changed files with 1384 additions and 686 deletions

View file

@ -1,245 +0,0 @@
# Server API differnces:
### Characteristics:
When creating a characteristic the properties are now set with `NIMBLE_PROPERTY::XXXX` instead of `BLECharacteristic::XXXX`.
#### Previous:
```
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE
```
#### Changed to:
```
NIMBLE_PROPERTY::READ |
NIMBLE_PROPERTY::WRITE
```
#### 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
```
### Descriptors:
Descriptors are now created using the NimBLEcharacteristic method `createDescriptor()`.
The previous method `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, this 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 that descriptor.
For any other descriptor, (except 0x2904, see below) it should now be created just as characteristics are
by invoking the `NimBLECharacteristic::createDescriptor` methods.
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.
For the 0x2904 descriptor, there is a special class that is created when you call `createDescriptor("2904")`.
The pointer returned is of the base class `NimBLEDescriptor` but the call will create the derived class of `NimBLE2904` so you must cast the returned pointer to `NimBLE2904*` to access the specific class methods.
##### Example:
```
p2904 = (NimBLE2904*)pCharacteristic->createDescriptor("2904");
```
#### 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 confirmation. See below for details.
# Client API Differences:
The `BLEAdvertisedDeviceCallbacks` class `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:
```
bool connect(NimBLEAdvertisedDevice* device, bool refreshServices = true);
bool 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.
```
NimBLERemoteCharacteristic::writeValue();
NimBLERemoteCharacteristic::registerForNotify();
```
Now return true or false to indicate success or failure so you can choose to disconnect or try again.
```
NimBLEClient::getServices()
NimBLERemoteService::getCharacteristics()
```
Now return a pointer to a `std::vector` of the respective object database instead of `std::map`.
`NimBLERemoteService::getCharacteristicsByHandle()`
Has been removed from the API as it is no longer maintained in the library.
The last two above changes reduce the heap usage significantly with minimal application code adjustments.
**UPDATED** on June 21, 2020
> ```
> NimBLEClient::getServices(bool refresh = false)
> NimBLERemoteService::getCharacteristics(bool refresh = false)
> NimBLERemoteCharacteristic::getDecriptors(bool refresh = false)
>```
These methods now take an optional (bool) parameter.
If 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 empty or otherwise 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::discoverAtrributes()` for the user to discover all the peripheral attributes
to replace the the former functionality.
> ```
>getService(NimBLEUUID)
>getCharacteristic(NimBLEUUID)
>getDescriptor(NimBLEUUID)
>```
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.
***
#### 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.
# Security:
Security callback functions are now incorporated in the client/server Callbacks class.
However backward compatibility with the `BLESecurity` class is retained to minimize app code changes.
The relevant server callbacks are defined as:
```
bool onConfirmPIN(uint32_t pin); // accept or reject the passkey
void onAuthenticationComplete(ble_gap_conn_desc* desc); // auth complete - details in desc
bool onPassKeyNotify(uint32_t pass_key); // receive the passkey sent by the client, accept or reject
```
The relevant client callbacks are defined as:
```
bool onConfirmPIN(uint32_t pin); // accept or reject the passkey
void onAuthenticationComplete(ble_gap_conn_desc* desc); // auth complete - details in desc
uint32_t onPassKeyRequest(); // return the passkey to send to the server
```
Security settings and IO capabilities are now set by the corresponding method of `NimBLEDevice::`.
```
static void setSecurityAuth(bool bonding, bool mitm, bool sc);
static void setSecurityAuth(uint8_t auth_req);
static void setSecurityIOCap(uint8_t iocap);
static void setSecurityInitKey(uint8_t init_key);
static void setSecurityRespKey(uint8_t init_key);
/**
* @brief Set the authorization mode for this device.
* @param bonding, if true we allow bonding, false no bonding will be performed.
* @param mitm, if true we are capable of man in the middle protection, false if not.
* @param sc, if true we will perform secure connection pairing, false we will use legacy pairing.
*/
void NimBLEDevice::setSecurityAuth(bool bonding, bool mitm, bool sc)
/**
* @brief Set the authorization mode for this device.
* @param A bitmap indicating what modes are supported.
* The bits are defined as follows:
** 0x01 BLE_SM_PAIR_AUTHREQ_BOND
** 0x04 BLE_SM_PAIR_AUTHREQ_MITM
** 0x08 BLE_SM_PAIR_AUTHREQ_SC
** 0x10 BLE_SM_PAIR_AUTHREQ_KEYPRESS - not yet supported.
** 0xe2 BLE_SM_PAIR_AUTHREQ_RESERVED - for reference only.
*/
void NimBLEDevice::setSecurityAuth(uint8_t auth_req)
/**
* @brief Set the Input/Output capabilities of this device.
* @param One of the following:
** 0x00 BLE_HS_IO_DISPLAY_ONLY DisplayOnly IO capability
** 0x01 BLE_HS_IO_DISPLAY_YESNO DisplayYesNo IO capability
** 0x02 BLE_HS_IO_KEYBOARD_ONLY KeyboardOnly IO capability
** 0x03 BLE_HS_IO_NO_INPUT_OUTPUT NoInputNoOutput IO capability
** 0x04 BLE_HS_IO_KEYBOARD_DISPLAY KeyboardDisplay Only IO capability
*/
void NimBLEDevice::setSecurityIOCap(uint8_t iocap)
/**
* @brief If we are the initiator of the security procedure this sets the keys we will distribute.
* @param A bitmap indicating which keys to distribute during pairing.
* The bits are defined as follows:
** 0x01: BLE_SM_PAIR_KEY_DIST_ENC - Distribute the encryption key.
** 0x02: BLE_SM_PAIR_KEY_DIST_ID - Distribute the ID key (IRK).
** 0x04: BLE_SM_PAIR_KEY_DIST_SIGN
** 0x08: BLE_SM_PAIR_KEY_DIST_LINK
*/
void NimBLEDevice::setSecurityInitKey(uint8_t init_key)
/**
* @brief Set the keys we are willing to accept during pairing.
* @param A bitmap indicating which keys to accept during pairing.
* The bits are defined as follows:
** 0x01: BLE_SM_PAIR_KEY_DIST_ENC - Accept the encryption key.
** 0x02: BLE_SM_PAIR_KEY_DIST_ID - Accept the ID key (IRK).
** 0x04: BLE_SM_PAIR_KEY_DIST_SIGN
** 0x08: BLE_SM_PAIR_KEY_DIST_LINK
*/
void NimBLEDevice::setSecurityRespKey(uint8_t init_key)
```
I'm sure there are more things I have forgotten but this is all the majors.
I will update this document as necessary.

View file

@ -1,29 +1,8 @@
# *** UPDATES ***
**Breaking changes:**
**NEW** on June 21, 2020
> ```
> NimBLEClient::getServices(bool refresh = false)
> NimBLERemoteService::getCharacteristics(bool refresh = false)
> NimBLERemoteCharacteristic::getDecriptors(bool refresh = false)
>```
These methods now take an optional (bool) parameter.
If 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 empty or otherwise with the currently stored attributes.
**NEW** on May 23, 2020
Client and scan now use `std::vector` instead of `std::map` for storing the remote attribute database.
This change will affect your application code if you use `NimBLEClient::getServices()` or `NimBLERemoteService::getCharacteristics()`
in your application as they now return a pointer to `std::vector` of the respective attributes.
In addition `NimBLERemoteService::getCharacteristicsByHandle()` has been removed as it is no longer maintained in the library.
These changes were necessary due to the amount of resources required to use `std::map`, it was not justifed by any benfit it provided.
It is expected that there will be minimal impact on most applications, if you need help adjusting your code please create an issue.
# esp-nimble-cpp # esp-nimble-cpp
NimBLE CPP library for use with ESP32 that attempts to maintain compatibility with the @nkolban cpp_uitls API.
NimBLE CPP library for use with ESP32 that attempts to maintain compatibility with the [nkolban cpp_uitls BLE API](https://github.com/nkolban/esp32-snippets/tree/master/cpp_utils).
**An Arduino version of this library, including NimBLE, can be [found here.](https://github.com/h2zero/NimBLE-Arduino)**
This library **significantly** reduces resource usage and improves performance for ESP32 BLE applications as compared This library **significantly** reduces resource usage and improves performance for ESP32 BLE applications as compared
with the bluedroid based library. The goal is to maintain, as much as reasonable, compatibility with the original with the bluedroid based library. The goal is to maintain, as much as reasonable, compatibility with the original
@ -31,32 +10,54 @@ library but refactored to use the NimBLE stack. In addition, this library will b
to provide improved capabilites and stability over the original. to provide improved capabilites and stability over the original.
**Testing shows a nearly 50% reduction in flash use and approx. 100kB less ram consumed vs the original!** **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/>
# Installation: # Installation
Download as .zip and extract to components folder in your esp-idf project. ### ESP-IDF 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 select NimBLE host. 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/>
### ESP-IDF 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. `#include "NimBLEDevice.h"` in main.cpp.
Call `NimBLEDevice::init("");` in `app_main`.
<br/>
# Using
# Usage:
This library is intended to be compatible with the original ESP32 BLE functions and types with minor changes. This library is intended to be compatible with the original ESP32 BLE functions and types with minor changes.
Check [API_DIFFERENCES](https://github.com/h2zero/esp-nimble-cpp/blob/master/API_DIFFERENCES.md) for details. 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.
<br/>
# Acknowledgments: # 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/>
* @nkolban and @chegewara for the [original esp32 BLE library](https://github.com/nkolban/esp32-snippets) this project was derived from. # Todo
* @beegee-tokyo for contributing your time to test/debug and contributing the beacon examples. 1. Implement random addresses.
* @Jeroen88 for the amazing help debugging and improving the client code. 2. Implement NimBLEServer::removeService
3. Implement extra fields in NimBLEAdvertisedDevice.
4. Document nimconfig.
5. Add BLE Mesh code.
<br/>
# Todo:
1. Create documentation.
2. Add BLE Mesh code.
3. Expose more NimBLE features.

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

View file

@ -114,6 +114,10 @@ bool FreeRTOS::Semaphore::timedWait(std::string owner, uint32_t timeoutMs) {
} // wait } // wait
/**
* @brief Construct a semaphore, the semaphore is given when created.
* @param [in] name A name string to provide debugging support.
*/
FreeRTOS::Semaphore::Semaphore(std::string name) { FreeRTOS::Semaphore::Semaphore(std::string name) {
m_usePthreads = false; // Are we using pThreads or FreeRTOS? m_usePthreads = false; // Are we using pThreads or FreeRTOS?
if (m_usePthreads) { if (m_usePthreads) {
@ -140,8 +144,7 @@ FreeRTOS::Semaphore::~Semaphore() {
/** /**
* @brief Give a semaphore. * @brief Give the semaphore.
* The Semaphore is given.
*/ */
void FreeRTOS::Semaphore::give() { void FreeRTOS::Semaphore::give() {
NIMBLE_LOGD(LOG_TAG, "Semaphore giving: %s", toString().c_str()); NIMBLE_LOGD(LOG_TAG, "Semaphore giving: %s", toString().c_str());

View file

@ -29,6 +29,9 @@ public:
static uint32_t getTimeSinceStart(); static uint32_t getTimeSinceStart();
/**
* @brief A binary semaphore class that operates like a mutex, it is already given when constructed.
*/
class Semaphore { class Semaphore {
public: public:
Semaphore(std::string owner = "<Unknown>"); Semaphore(std::string owner = "<Unknown>");
@ -42,6 +45,10 @@ public:
std::string toString(); std::string toString();
bool timedWait(std::string owner = "<Unknown>", uint32_t timeoutMs = portMAX_DELAY); bool timedWait(std::string owner = "<Unknown>", uint32_t timeoutMs = portMAX_DELAY);
uint32_t wait(std::string owner = "<Unknown>"); uint32_t wait(std::string owner = "<Unknown>");
/**
* @brief Get the value of the semaphore.
* @return The value stored if the semaphore was given with give(value);
*/
uint32_t value(){ return m_value; }; uint32_t value(){ return m_value; };
private: private:
@ -57,7 +64,7 @@ public:
/** /**
* @brief Ringbuffer. * @brief A wrapper class for a freeRTOS ringbuffer.
*/ */
class Ringbuffer { class Ringbuffer {
public: public:

View file

@ -23,17 +23,17 @@
static const char* LOG_TAG = "NimBLEAddress"; static const char* LOG_TAG = "NimBLEAddress";
/************************************************* /*************************************************
NOTE: NimBLE addresses are in INVERSE ORDER! * NOTE: NimBLE address bytes are in INVERSE ORDER!
We will accomodate that fact in these methods. * We will accomodate that fact in these methods.
*************************************************/ *************************************************/
/** /**
* @brief Create an address from the native ESP32 representation. * @brief Create an address from the native NimBLE representation.
* @param [in] address The native representation. * @param [in] address The native NimBLE address.
*/ */
NimBLEAddress::NimBLEAddress(ble_addr_t address) { NimBLEAddress::NimBLEAddress(ble_addr_t address) {
memcpy(m_address, address.val, 6); memcpy(m_address, address.val, 6);
} // BLEAddress } // NimBLEAddress
/** /**
@ -45,7 +45,7 @@ NimBLEAddress::NimBLEAddress(ble_addr_t address) {
* ``` * ```
* which is 17 characters in length. * which is 17 characters in length.
* *
* @param [in] stringAddress The hex representation of the address. * @param [in] stringAddress The hex string representation of the address.
*/ */
NimBLEAddress::NimBLEAddress(const std::string &stringAddress) { NimBLEAddress::NimBLEAddress(const std::string &stringAddress) {
if (stringAddress.length() == 0) { if (stringAddress.length() == 0) {
@ -72,12 +72,12 @@ NimBLEAddress::NimBLEAddress(const std::string &stringAddress) {
for(size_t index = 0; index < sizeof m_address; index++) { for(size_t index = 0; index < sizeof m_address; index++) {
m_address[index] = data[index]; m_address[index] = data[index];
} }
} // BLEAddress } // NimBLEAddress
/** /**
* @brief Constructor for compatibility with bluedroid esp library. * @brief Constructor for compatibility with bluedroid esp library using native ESP representation.
* @param [in] uint8_t[6] or esp_bd_addr_t struct containing the address. * @param [in] address A uint8_t[6] or esp_bd_addr_t containing the address.
*/ */
NimBLEAddress::NimBLEAddress(uint8_t address[6]) { NimBLEAddress::NimBLEAddress(uint8_t address[6]) {
std::reverse_copy(address, address + sizeof m_address, m_address); std::reverse_copy(address, address + sizeof m_address, m_address);
@ -85,8 +85,9 @@ NimBLEAddress::NimBLEAddress(uint8_t address[6]) {
/** /**
* @brief Constructor for address using a hex value. Use the same byte order, so use 0xa4c1385def16 for "a4:c1:38:5d:ef:16" * @brief Constructor for address using a hex value.\n
* @param [in] uint64_t containing the address. * Use the same byte order, so use 0xa4c1385def16 for "a4:c1:38:5d:ef:16"
* @param [in] address uint64_t containing the address.
*/ */
NimBLEAddress::NimBLEAddress(const uint64_t &address) { NimBLEAddress::NimBLEAddress(const uint64_t &address) {
memcpy(m_address, &address, sizeof m_address); memcpy(m_address, &address, sizeof m_address);
@ -104,8 +105,8 @@ bool NimBLEAddress::equals(const NimBLEAddress &otherAddress) const {
/** /**
* @brief Return the native representation of the address. * @brief Get the native representation of the address.
* @return The native representation of the address. * @return a pointer to the uint8_t[6] array of the address.
*/ */
const uint8_t *NimBLEAddress::getNative() const { const uint8_t *NimBLEAddress::getNative() const {
return m_address; return m_address;
@ -122,30 +123,48 @@ const uint8_t *NimBLEAddress::getNative() const {
* ``` * ```
* *
* @return The string representation of the address. * @return The string representation of the address.
* @deprecated Use std::string() operator instead.
*/ */
std::string NimBLEAddress::toString() const { std::string NimBLEAddress::toString() const {
return std::string(*this); return std::string(*this);
} // toString } // toString
/**
* @brief Convienience operator to check if this address is equal to another.
*/
bool NimBLEAddress::operator ==(const NimBLEAddress & rhs) const { bool NimBLEAddress::operator ==(const NimBLEAddress & rhs) const {
return memcmp(rhs.m_address, m_address, sizeof m_address) == 0; return memcmp(rhs.m_address, m_address, sizeof m_address) == 0;
} } // operator ==
/**
* @brief Convienience operator to check if this address is not equal to another.
*/
bool NimBLEAddress::operator !=(const NimBLEAddress & rhs) const { bool NimBLEAddress::operator !=(const NimBLEAddress & rhs) const {
return !this->operator==(rhs); return !this->operator==(rhs);
} } // operator !=
/**
* @brief Convienience operator to convert this address to string representation.
* @details This allows passing NimBLEAddress to functions
* that accept std::string and/or or it's methods as a parameter.
*/
NimBLEAddress::operator std::string() const { NimBLEAddress::operator std::string() const {
char buffer[18]; char buffer[18];
sprintf(buffer, "%02x:%02x:%02x:%02x:%02x:%02x", m_address[5], m_address[4], m_address[3], m_address[2], m_address[1], m_address[0]); sprintf(buffer, "%02x:%02x:%02x:%02x:%02x:%02x", m_address[5], m_address[4], m_address[3], m_address[2], m_address[1], m_address[0]);
return std::string(buffer); return std::string(buffer);
} } // operator std::string
/**
* @brief Convienience operator to convert the native address representation to uint_64.
*/
NimBLEAddress::operator uint64_t() const { NimBLEAddress::operator uint64_t() const {
uint64_t address = 0; uint64_t address = 0;
memcpy(&address, m_address, sizeof m_address); memcpy(&address, m_address, sizeof m_address);
return address; return address;
} } // operator uint64_t
#endif #endif

View file

@ -36,6 +36,7 @@ NimBLEAdvertisedDevice::NimBLEAdvertisedDevice() {
m_rssi = -9999; m_rssi = -9999;
m_serviceData = ""; m_serviceData = "";
m_txPower = 0; m_txPower = 0;
m_payloadLength = 0;
m_pScan = nullptr; m_pScan = nullptr;
m_payloadLength = 0; m_payloadLength = 0;
m_payload = nullptr; m_payload = nullptr;
@ -53,11 +54,7 @@ NimBLEAdvertisedDevice::NimBLEAdvertisedDevice() {
/** /**
* @brief Get the address. * @brief Get the address of the advertising device.
*
* Every %BLE device exposes an address that is used to identify it and subsequently connect to it.
* Call this function to obtain the address of the advertised device.
*
* @return The address of the advertised device. * @return The address of the advertised device.
*/ */
NimBLEAddress NimBLEAdvertisedDevice::getAddress() { NimBLEAddress NimBLEAdvertisedDevice::getAddress() {
@ -66,9 +63,13 @@ NimBLEAddress NimBLEAdvertisedDevice::getAddress() {
/** /**
* @brief Get the advertised type. * @brief Get the advertisement type.
* * @return The advertising type the device is reporting:
* @return The advertised type of the advertised device. * * BLE_HCI_ADV_TYPE_ADV_IND (0) - indirect advertising
* * BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD (1) - direct advertisng - high duty cycle
* * BLE_HCI_ADV_TYPE_ADV_SCAN_IND (2) - indirect scan response
* * BLE_HCI_ADV_TYPE_ADV_NONCONN_IND (3) - indirect advertisng - not connectable
* * BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD (4) - direct advertising - low duty cycle
*/ */
uint8_t NimBLEAdvertisedDevice::getAdvType() { uint8_t NimBLEAdvertisedDevice::getAdvType() {
return m_advType; return m_advType;
@ -98,7 +99,7 @@ std::string NimBLEAdvertisedDevice::getManufacturerData() {
/** /**
* @brief Get the name. * @brief Get the advertised name.
* @return The name of the advertised device. * @return The name of the advertised device.
*/ */
std::string NimBLEAdvertisedDevice::getName() { std::string NimBLEAdvertisedDevice::getName() {
@ -116,7 +117,7 @@ int NimBLEAdvertisedDevice::getRSSI() {
/** /**
* @brief Get the scan object that created this advertisement. * @brief Get the scan object that created this advertised device.
* @return The scan object. * @return The scan object.
*/ */
NimBLEScan* NimBLEAdvertisedDevice::getScan() { NimBLEScan* NimBLEAdvertisedDevice::getScan() {
@ -134,8 +135,8 @@ std::string NimBLEAdvertisedDevice::getServiceData() {
/** /**
* @brief Get the service data UUID. * @brief Get the advertised service UUID.
* @return The service data UUID. * @return The advertise service UUID.
*/ */
NimBLEUUID NimBLEAdvertisedDevice::getServiceDataUUID() { NimBLEUUID NimBLEAdvertisedDevice::getServiceDataUUID() {
@ -154,7 +155,7 @@ NimBLEUUID NimBLEAdvertisedDevice::getServiceUUID() { //TODO Remove it eventual
/** /**
* @brief Check advertised serviced for existence required UUID * @brief Check advertised services for existance of the required UUID
* @return Return true if service is advertised * @return Return true if service is advertised
*/ */
bool NimBLEAdvertisedDevice::isAdvertisingService(const NimBLEUUID &uuid){ bool NimBLEAdvertisedDevice::isAdvertisingService(const NimBLEUUID &uuid){
@ -163,7 +164,7 @@ bool NimBLEAdvertisedDevice::isAdvertisingService(const NimBLEUUID &uuid){
if (m_serviceUUIDs[i].equals(uuid)) return true; if (m_serviceUUIDs[i].equals(uuid)) return true;
} }
return false; return false;
} } // isAdvertisingService
/** /**
@ -335,7 +336,7 @@ bool NimBLEAdvertisedDevice::haveTXPower() {
setAppearance(fields->appearance); setAppearance(fields->appearance);
} }
/**** TODO: create storage and fucntions for these parameters /* TODO: create storage and fucntions for these parameters
if (fields->public_tgt_addr != NULL) { if (fields->public_tgt_addr != NULL) {
NIMBLE_LOGD(LOG_TAG, " public_tgt_addr="); NIMBLE_LOGD(LOG_TAG, " public_tgt_addr=");
u8p = fields->public_tgt_addr; u8p = fields->public_tgt_addr;
@ -435,7 +436,7 @@ void NimBLEAdvertisedDevice::setRSSI(int rssi) {
/** /**
* @brief Set the Scan that created this advertised device. * @brief Set the Scan that created this advertised device.
* @param pScan The Scan that created this advertised device. * @param [in] pScan The Scan that created this advertised device.
*/ */
void NimBLEAdvertisedDevice::setScan(NimBLEScan* pScan) { void NimBLEAdvertisedDevice::setScan(NimBLEScan* pScan) {
m_pScan = pScan; m_pScan = pScan;
@ -459,7 +460,7 @@ void NimBLEAdvertisedDevice::setServiceUUID(const char* serviceUUID) {
void NimBLEAdvertisedDevice::setServiceUUID(NimBLEUUID serviceUUID) { void NimBLEAdvertisedDevice::setServiceUUID(NimBLEUUID serviceUUID) {
// Don't add duplicates // Don't add duplicates
for (int i = 0; i < m_serviceUUIDs.size(); i++) { for (int i = 0; i < m_serviceUUIDs.size(); i++) {
if (m_serviceUUIDs[i].equals(serviceUUID)) { if (m_serviceUUIDs[i] == serviceUUID) {
return; return;
} }
} }
@ -539,35 +540,68 @@ std::string NimBLEAdvertisedDevice::toString() {
} // toString } // toString
/**
* @brief Get the payload advertised by the device.
* @return The advertisement payload.
*/
uint8_t* NimBLEAdvertisedDevice::getPayload() { uint8_t* NimBLEAdvertisedDevice::getPayload() {
return m_payload; return m_payload;
} } // getPayload
/**
* @brief Get the advertised device address type.
* @return The device address type:
* * BLE_ADDR_PUBLIC (0x00)
* * BLE_ADDR_RANDOM (0x01)
* * BLE_ADDR_PUBLIC_ID (0x02)
* * BLE_ADDR_RANDOM_ID (0x03)
*/
uint8_t NimBLEAdvertisedDevice::getAddressType() { uint8_t NimBLEAdvertisedDevice::getAddressType() {
return m_addressType; return m_addressType;
} } // getAddressType
/**
* @brief Get the timeStamp of when the device last advertised.
* @return The timeStamp of when the device was last seen.
*/
time_t NimBLEAdvertisedDevice::getTimestamp() { time_t NimBLEAdvertisedDevice::getTimestamp() {
return m_timestamp; return m_timestamp;
} } // getTimestamp
/**
* @brief Set the advertised device address type.
* @param [in] type The address type of the device:
* * BLE_ADDR_PUBLIC (0x00)
* * BLE_ADDR_RANDOM (0x01)
* * BLE_ADDR_PUBLIC_ID (0x02)
* * BLE_ADDR_RANDOM_ID (0x03)
*/
void NimBLEAdvertisedDevice::setAddressType(uint8_t type) { void NimBLEAdvertisedDevice::setAddressType(uint8_t type) {
m_addressType = type; m_addressType = type;
} } // setAddressType
/**
* @brief Get the length of the payload advertised by the device.
* @return The size of the payload in bytes.
*/
size_t NimBLEAdvertisedDevice::getPayloadLength() { size_t NimBLEAdvertisedDevice::getPayloadLength() {
return m_payloadLength; return m_payloadLength;
} } // getPayloadLength
/**
* @brief Set the advertisment payload data.
* @param [in] payload A pointer to the device payload data.
* @param [in] length The length of the payload data in bytes.
*/
void NimBLEAdvertisedDevice::setAdvertisementResult(uint8_t* payload, uint8_t length){ void NimBLEAdvertisedDevice::setAdvertisementResult(uint8_t* payload, uint8_t length){
m_payload = payload; m_payload = payload;
m_payloadLength = length; m_payloadLength = length;
} } // setAdvertisementResult
#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) #endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
#endif /* CONFIG_BT_ENABLED */ #endif /* CONFIG_BT_ENABLED */

View file

@ -46,6 +46,14 @@ public:
uint16_t getAppearance(); uint16_t getAppearance();
std::string getManufacturerData(); std::string getManufacturerData();
/**
* @brief A template to convert the service data to <type\>.
* @tparam T The type to convert the data to.
* @param [in] skipSizeCheck If true it will skip checking if the data size is less than <tt>sizeof(<type\>)</tt>.
* @return The data converted to <type\> or NULL if skipSizeCheck is false and the data is
* less than <tt>sizeof(<type\>)</tt>.
* @details <b>Use:</b> <tt>getManufacturerData<type>(skipSizeCheck);</tt>
*/
template<typename T> template<typename T>
T getManufacturerData(bool skipSizeCheck = false) { T getManufacturerData(bool skipSizeCheck = false) {
std::string data = getManufacturerData(); std::string data = getManufacturerData();
@ -59,6 +67,14 @@ public:
NimBLEScan* getScan(); NimBLEScan* getScan();
std::string getServiceData(); std::string getServiceData();
/**
* @brief A template to convert the service data to <tt><type\></tt>.
* @tparam T The type to convert the data to.
* @param [in] skipSizeCheck If true it will skip checking if the data size is less than <tt>sizeof(<type\>)</tt>.
* @return The data converted to <type\> or NULL if skipSizeCheck is false and the data is
* less than <tt>sizeof(<type\>)</tt>.
* @details <b>Use:</b> <tt>getServiceData<type>(skipSizeCheck);</tt>
*/
template<typename T> template<typename T>
T getServiceData(bool skipSizeCheck = false) { T getServiceData(bool skipSizeCheck = false) {
std::string data = getServiceData(); std::string data = getServiceData();
@ -123,7 +139,6 @@ private:
std::string m_name; std::string m_name;
NimBLEScan* m_pScan; NimBLEScan* m_pScan;
int m_rssi; int m_rssi;
std::vector<NimBLEUUID> m_serviceUUIDs;
int8_t m_txPower; int8_t m_txPower;
std::string m_serviceData; std::string m_serviceData;
NimBLEUUID m_serviceDataUUID; NimBLEUUID m_serviceDataUUID;
@ -132,6 +147,8 @@ private:
uint8_t m_addressType; uint8_t m_addressType;
time_t m_timestamp; time_t m_timestamp;
bool m_callbackSent; bool m_callbackSent;
std::vector<NimBLEUUID> m_serviceUUIDs;
}; };
/** /**

View file

@ -31,7 +31,6 @@ static const char* LOG_TAG = "NimBLEAdvertising";
/** /**
* @brief Construct a default advertising object. * @brief Construct a default advertising object.
*
*/ */
NimBLEAdvertising::NimBLEAdvertising() { NimBLEAdvertising::NimBLEAdvertising() {
memset(&m_advData, 0, sizeof m_advData); memset(&m_advData, 0, sizeof m_advData);
@ -78,43 +77,70 @@ void NimBLEAdvertising::addServiceUUID(const char* serviceUUID) {
/** /**
* @brief Set the device appearance in the advertising data. * @brief Set the device appearance in the advertising data.
* The appearance attribute is of type 0x19. The codes for distinct appearances can be found here: * The codes for distinct appearances can be found here:\n
* https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.gap.appearance.xml. * https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.gap.appearance.xml.
* @param [in] appearance The appearance of the device in the advertising data. * @param [in] appearance The appearance of the device in the advertising data.
* @return N/A.
*/ */
void NimBLEAdvertising::setAppearance(uint16_t appearance) { void NimBLEAdvertising::setAppearance(uint16_t appearance) {
m_advData.appearance = appearance; m_advData.appearance = appearance;
m_advData.appearance_is_present = 1; m_advData.appearance_is_present = 1;
} // setAppearance } // setAppearance
/**
* @brief Set the type of advertisment to use.
* @param [in] adv_type:
* * BLE_HCI_ADV_TYPE_ADV_IND (0) - indirect advertising
* * BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD (1) - direct advertisng - high duty cycle
* * BLE_HCI_ADV_TYPE_ADV_SCAN_IND (2) - indirect scan response
* * BLE_HCI_ADV_TYPE_ADV_NONCONN_IND (3) - indirect advertisng - not connectable
* * BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD (4) - direct advertising - low duty cycle
*/
void NimBLEAdvertising::setAdvertisementType(uint8_t adv_type){ void NimBLEAdvertising::setAdvertisementType(uint8_t adv_type){
m_advParams.conn_mode = adv_type; m_advParams.conn_mode = adv_type;
} // setAdvertisementType } // setAdvertisementType
/**
* @brief Set the minimum advertising interval.
* @param [in] mininterval Minimum value for advertising interval in 0.625ms units, 0 = use default.
*/
void NimBLEAdvertising::setMinInterval(uint16_t mininterval) { void NimBLEAdvertising::setMinInterval(uint16_t mininterval) {
m_advParams.itvl_min = mininterval; m_advParams.itvl_min = mininterval;
} // setMinInterval } // setMinInterval
/**
* @brief Set the maximum advertising interval.
* @param [in] maxinterval Maximum value for advertising interval in 0.625ms units, 0 = use default.
*/
void NimBLEAdvertising::setMaxInterval(uint16_t maxinterval) { void NimBLEAdvertising::setMaxInterval(uint16_t maxinterval) {
m_advParams.itvl_max = maxinterval; m_advParams.itvl_max = maxinterval;
} // setMaxInterval } // setMaxInterval
/* These are dummy functions for now for compatibility */ /**
* @brief NOP - Not yet implemented, dummy function for backward compatibility.
*/
void NimBLEAdvertising::setMinPreferred(uint16_t mininterval) { void NimBLEAdvertising::setMinPreferred(uint16_t mininterval) {
//m_advData.min_interval = mininterval; } // setMinPreferred
} //
/**
* @brief NOP - Not yet implemented, dummy function for backward compatibility.
*/
void NimBLEAdvertising::setMaxPreferred(uint16_t maxinterval) { void NimBLEAdvertising::setMaxPreferred(uint16_t maxinterval) {
//m_advData.max_interval = maxinterval; } // setMaxPreferred
} //
/*******************************************************/
/**
* @brief Set if scan response is available.
* @param [in] set true = scan response available.
*/
void NimBLEAdvertising::setScanResponse(bool set) { void NimBLEAdvertising::setScanResponse(bool set) {
m_scanResp = set; m_scanResp = set;
} } // setScanResponse
/** /**
* @brief Set the filtering for the scan filter. * @brief Set the filtering for the scan filter.
@ -145,6 +171,7 @@ void NimBLEAdvertising::setScanFilter(bool scanRequestWhitelistOnly, bool connec
} }
} // setScanFilter } // setScanFilter
/** /**
* @brief Set the advertisement data that is to be published in a regular advertisement. * @brief Set the advertisement data that is to be published in a regular advertisement.
* @param [in] advertisementData The data to be advertised. * @param [in] advertisementData The data to be advertised.
@ -182,8 +209,6 @@ void NimBLEAdvertising::setScanResponseData(NimBLEAdvertisementData& advertiseme
/** /**
* @brief Start advertising. * @brief Start advertising.
* Start advertising.
* @return N/A.
*/ */
void NimBLEAdvertising::start() { void NimBLEAdvertising::start() {
NIMBLE_LOGD(LOG_TAG, ">> Advertising start: customAdvData: %d, customScanResponseData: %d", m_customAdvData, m_customScanResponseData); NIMBLE_LOGD(LOG_TAG, ">> Advertising start: customAdvData: %d, customScanResponseData: %d", m_customAdvData, m_customScanResponseData);
@ -375,8 +400,6 @@ void NimBLEAdvertising::start() {
/** /**
* @brief Stop advertising. * @brief Stop advertising.
* Stop advertising.
* @return N/A.
*/ */
void NimBLEAdvertising::stop() { void NimBLEAdvertising::stop() {
NIMBLE_LOGD(LOG_TAG, ">> stop"); NIMBLE_LOGD(LOG_TAG, ">> stop");
@ -390,7 +413,7 @@ void NimBLEAdvertising::stop() {
} // stop } // stop
/** /*
* Host reset seems to clear advertising data, * Host reset seems to clear advertising data,
* we need clear the flag so it reloads it. * we need clear the flag so it reloads it.
*/ */
@ -427,8 +450,8 @@ void NimBLEAdvertisementData::setAppearance(uint16_t appearance) {
/** /**
* @brief Set the complete services. * @brief Set the complete services to advertise.
* @param [in] uuid The single service to advertise. * @param [in] uuid The UUID of the service.
*/ */
void NimBLEAdvertisementData::setCompleteServices(const NimBLEUUID &uuid) { void NimBLEAdvertisementData::setCompleteServices(const NimBLEUUID &uuid) {
char cdata[2]; char cdata[2];
@ -465,16 +488,7 @@ void NimBLEAdvertisementData::setCompleteServices(const NimBLEUUID &uuid) {
/** /**
* @brief Set the advertisement flags. * @brief Set the advertisement flags.
* @param [in] The flags to be set in the advertisement. * @param [in] flag The flags to be set in the advertisement.
* * ****DO NOT USE THESE****
* * ESP_BLE_ADV_FLAG_LIMIT_DISC
* * ESP_BLE_ADV_FLAG_GEN_DISC
* * ESP_BLE_ADV_FLAG_BREDR_NOT_SPT
* * ESP_BLE_ADV_FLAG_DMT_CONTROLLER_SPT
* * ESP_BLE_ADV_FLAG_DMT_HOST_SPT
* * ESP_BLE_ADV_FLAG_NON_LIMIT_DISC
* *
* * ****THESE ARE SUPPORTED****
* * BLE_HS_ADV_F_DISC_LTD * * BLE_HS_ADV_F_DISC_LTD
* * BLE_HS_ADV_F_DISC_GEN * * BLE_HS_ADV_F_DISC_GEN
* * BLE_HS_ADV_F_BREDR_UNSUP - must always use with NimBLE * * BLE_HS_ADV_F_BREDR_UNSUP - must always use with NimBLE
@ -490,7 +504,7 @@ void NimBLEAdvertisementData::setFlags(uint8_t flag) {
/** /**
* @brief Set manufacturer specific data. * @brief Set manufacturer specific data.
* @param [in] data Manufacturer data. * @param [in] data The manufacturer data to advertise.
*/ */
void NimBLEAdvertisementData::setManufacturerData(const std::string &data) { void NimBLEAdvertisementData::setManufacturerData(const std::string &data) {
NIMBLE_LOGD("NimBLEAdvertisementData", ">> setManufacturerData"); NIMBLE_LOGD("NimBLEAdvertisementData", ">> setManufacturerData");
@ -503,8 +517,8 @@ void NimBLEAdvertisementData::setManufacturerData(const std::string &data) {
/** /**
* @brief Set the name. * @brief Set the complete name of this device.
* @param [in] The complete name of the device. * @param [in] name The name to advertise.
*/ */
void NimBLEAdvertisementData::setName(const std::string &name) { void NimBLEAdvertisementData::setName(const std::string &name) {
NIMBLE_LOGD("NimBLEAdvertisementData", ">> setName: %s", name.c_str()); NIMBLE_LOGD("NimBLEAdvertisementData", ">> setName: %s", name.c_str());
@ -517,7 +531,7 @@ void NimBLEAdvertisementData::setName(const std::string &name) {
/** /**
* @brief Set the partial services. * @brief Set the partial services to advertise.
* @param [in] uuid The single service to advertise. * @param [in] uuid The single service to advertise.
*/ */
void NimBLEAdvertisementData::setPartialServices(const NimBLEUUID &uuid) { void NimBLEAdvertisementData::setPartialServices(const NimBLEUUID &uuid) {
@ -555,8 +569,8 @@ void NimBLEAdvertisementData::setPartialServices(const NimBLEUUID &uuid) {
/** /**
* @brief Set the service data (UUID + data) * @brief Set the service data (UUID + data)
* @param [in] uuid The UUID to set with the service data. Size of UUID will be used. * @param [in] uuid The UUID to set with the service data.
* @param [in] data The data to be associated with the service data advert. * @param [in] data The data to be associated with the service data advertised.
*/ */
void NimBLEAdvertisementData::setServiceData(const NimBLEUUID &uuid, const std::string &data) { void NimBLEAdvertisementData::setServiceData(const NimBLEUUID &uuid, const std::string &data) {
char cdata[2]; char cdata[2];
@ -593,7 +607,7 @@ void NimBLEAdvertisementData::setServiceData(const NimBLEUUID &uuid, const std::
/** /**
* @brief Set the short name. * @brief Set the short name.
* @param [in] The short name of the device. * @param [in] name The short name of the device.
*/ */
void NimBLEAdvertisementData::setShortName(const std::string &name) { void NimBLEAdvertisementData::setShortName(const std::string &name) {
NIMBLE_LOGD("NimBLEAdvertisementData", ">> setShortName: %s", name.c_str()); NIMBLE_LOGD("NimBLEAdvertisementData", ">> setShortName: %s", name.c_str());

View file

@ -84,8 +84,6 @@ public:
void setAdvertisementData(NimBLEAdvertisementData& advertisementData); void setAdvertisementData(NimBLEAdvertisementData& advertisementData);
void setScanFilter(bool scanRequertWhitelistOnly, bool connectWhitelistOnly); void setScanFilter(bool scanRequertWhitelistOnly, bool connectWhitelistOnly);
void setScanResponseData(NimBLEAdvertisementData& advertisementData); void setScanResponseData(NimBLEAdvertisementData& advertisementData);
void setPrivateAddress(uint8_t type = BLE_ADDR_RANDOM);
void setMinPreferred(uint16_t); void setMinPreferred(uint16_t);
void setMaxPreferred(uint16_t); void setMaxPreferred(uint16_t);
void setScanResponse(bool); void setScanResponse(bool);

View file

@ -22,6 +22,10 @@
static const char* LOG_TAG = "NimBLEBeacon"; static const char* LOG_TAG = "NimBLEBeacon";
/**
* @brief Construct a default beacon object.
*/
NimBLEBeacon::NimBLEBeacon() { NimBLEBeacon::NimBLEBeacon() {
m_beaconData.manufacturerId = 0x4c00; m_beaconData.manufacturerId = 0x4c00;
m_beaconData.subType = 0x02; m_beaconData.subType = 0x02;
@ -32,32 +36,64 @@ NimBLEBeacon::NimBLEBeacon() {
memset(m_beaconData.proximityUUID, 0, sizeof(m_beaconData.proximityUUID)); memset(m_beaconData.proximityUUID, 0, sizeof(m_beaconData.proximityUUID));
} // NimBLEBeacon } // NimBLEBeacon
/**
* @brief Retrieve the data that is being advertised.
* @return The advertised data.
*/
std::string NimBLEBeacon::getData() { std::string NimBLEBeacon::getData() {
return std::string((char*) &m_beaconData, sizeof(m_beaconData)); return std::string((char*) &m_beaconData, sizeof(m_beaconData));
} // getData } // getData
/**
* @brief Get the major value being advertised.
* @return The major value advertised.
*/
uint16_t NimBLEBeacon::getMajor() { uint16_t NimBLEBeacon::getMajor() {
return m_beaconData.major; return m_beaconData.major;
} }
/**
* @brief Get the manufacturer ID being advertised.
* @return The manufacturer ID value advertised.
*/
uint16_t NimBLEBeacon::getManufacturerId() { uint16_t NimBLEBeacon::getManufacturerId() {
return m_beaconData.manufacturerId; return m_beaconData.manufacturerId;
} }
/**
* @brief Get the minor value being advertised.
* @return minor value advertised.
*/
uint16_t NimBLEBeacon::getMinor() { uint16_t NimBLEBeacon::getMinor() {
return m_beaconData.minor; return m_beaconData.minor;
} }
/**
* @brief Get the proximity UUID being advertised.
* @return The UUID advertised.
*/
NimBLEUUID NimBLEBeacon::getProximityUUID() { NimBLEUUID NimBLEBeacon::getProximityUUID() {
return NimBLEUUID(m_beaconData.proximityUUID, 16, false); return NimBLEUUID(m_beaconData.proximityUUID, 16, false);
} }
/**
* @brief Get the signal power being advertised.
* @return signal power level advertised.
*/
int8_t NimBLEBeacon::getSignalPower() { int8_t NimBLEBeacon::getSignalPower() {
return m_beaconData.signalPower; return m_beaconData.signalPower;
} }
/** /**
* Set the raw data for the beacon record. * @brief Set the raw data for the beacon record.
* @param [in] data The raw beacon data.
*/ */
void NimBLEBeacon::setData(const std::string &data) { void NimBLEBeacon::setData(const std::string &data) {
if (data.length() != sizeof(m_beaconData)) { if (data.length() != sizeof(m_beaconData)) {
@ -68,24 +104,49 @@ void NimBLEBeacon::setData(const std::string &data) {
memcpy(&m_beaconData, data.data(), sizeof(m_beaconData)); memcpy(&m_beaconData, data.data(), sizeof(m_beaconData));
} // setData } // setData
/**
* @brief Set the major value.
* @param [in] major The major value.
*/
void NimBLEBeacon::setMajor(uint16_t major) { void NimBLEBeacon::setMajor(uint16_t major) {
m_beaconData.major = ENDIAN_CHANGE_U16(major); m_beaconData.major = ENDIAN_CHANGE_U16(major);
} // setMajor } // setMajor
/**
* @brief Set the manufacturer ID.
* @param [in] manufacturerId The manufacturer ID value.
*/
void NimBLEBeacon::setManufacturerId(uint16_t manufacturerId) { void NimBLEBeacon::setManufacturerId(uint16_t manufacturerId) {
m_beaconData.manufacturerId = ENDIAN_CHANGE_U16(manufacturerId); m_beaconData.manufacturerId = ENDIAN_CHANGE_U16(manufacturerId);
} // setManufacturerId } // setManufacturerId
/**
* @brief Set the minor value.
* @param [in] minor The minor value.
*/
void NimBLEBeacon::setMinor(uint16_t minor) { void NimBLEBeacon::setMinor(uint16_t minor) {
m_beaconData.minor = ENDIAN_CHANGE_U16(minor); m_beaconData.minor = ENDIAN_CHANGE_U16(minor);
} // setMinior } // setMinior
/**
* @brief Set the proximity UUID.
* @param [in] uuid The proximity UUID.
*/
void NimBLEBeacon::setProximityUUID(const NimBLEUUID &uuid) { void NimBLEBeacon::setProximityUUID(const NimBLEUUID &uuid) {
NimBLEUUID temp_uuid = uuid; NimBLEUUID temp_uuid = uuid;
temp_uuid.to128(); temp_uuid.to128();
memcpy(m_beaconData.proximityUUID, temp_uuid.getNative()->u128.value, 16); memcpy(m_beaconData.proximityUUID, temp_uuid.getNative()->u128.value, 16);
} // setProximityUUID } // setProximityUUID
/**
* @brief Set the signal power.
* @param [in] signalPower The signal power value.
*/
void NimBLEBeacon::setSignalPower(int8_t signalPower) { void NimBLEBeacon::setSignalPower(int8_t signalPower) {
m_beaconData.signalPower = signalPower; m_beaconData.signalPower = signalPower;
} // setSignalPower } // setSignalPower

View file

@ -65,6 +65,7 @@ NimBLECharacteristic::~NimBLECharacteristic() {
* @brief Create a new BLE Descriptor associated with this characteristic. * @brief Create a new BLE Descriptor associated with this characteristic.
* @param [in] uuid - The UUID of the descriptor. * @param [in] uuid - The UUID of the descriptor.
* @param [in] properties - The properties of the descriptor. * @param [in] properties - The properties of the descriptor.
* @param [in] max_len - The max length in bytes of the descriptor value.
* @return The new BLE descriptor. * @return The new BLE descriptor.
*/ */
NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const char* uuid, uint32_t properties, uint16_t max_len) { NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const char* uuid, uint32_t properties, uint16_t max_len) {
@ -76,6 +77,7 @@ NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const char* uuid, uint3
* @brief Create a new BLE Descriptor associated with this characteristic. * @brief Create a new BLE Descriptor associated with this characteristic.
* @param [in] uuid - The UUID of the descriptor. * @param [in] uuid - The UUID of the descriptor.
* @param [in] properties - The properties of the descriptor. * @param [in] properties - The properties of the descriptor.
* @param [in] max_len - The max length in bytes of the descriptor value.
* @return The new BLE descriptor. * @return The new BLE descriptor.
*/ */
NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const NimBLEUUID &uuid, uint32_t properties, uint16_t max_len) { NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const NimBLEUUID &uuid, uint32_t properties, uint16_t max_len) {
@ -106,8 +108,8 @@ NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const NimBLEUUID &uuid,
/** /**
* @brief Return the BLE Descriptor for the given UUID if associated with this characteristic. * @brief Return the BLE Descriptor for the given UUID if associated with this characteristic.
* @param [in] descriptorUUID The UUID of the descriptor that we wish to retrieve. * @param [in] uuid The UUID of the descriptor that we wish to retrieve.
* @return The BLE Descriptor. If no such descriptor is associated with the characteristic, nullptr is returned. * @return pointer to the NimBLEDescriptor. If no such descriptor is associated with the characteristic, nullptr is returned.
*/ */
NimBLEDescriptor* NimBLECharacteristic::getDescriptorByUUID(const char* uuid) { NimBLEDescriptor* NimBLECharacteristic::getDescriptorByUUID(const char* uuid) {
return getDescriptorByUUID(NimBLEUUID(uuid)); return getDescriptorByUUID(NimBLEUUID(uuid));
@ -116,8 +118,8 @@ NimBLEDescriptor* NimBLECharacteristic::getDescriptorByUUID(const char* uuid) {
/** /**
* @brief Return the BLE Descriptor for the given UUID if associated with this characteristic. * @brief Return the BLE Descriptor for the given UUID if associated with this characteristic.
* @param [in] descriptorUUID The UUID of the descriptor that we wish to retrieve. * @param [in] uuid The UUID of the descriptor that we wish to retrieve.
* @return The BLE Descriptor. If no such descriptor is associated with the characteristic, nullptr is returned. * @return pointer to the NimBLEDescriptor. If no such descriptor is associated with the characteristic, nullptr is returned.
*/ */
NimBLEDescriptor* NimBLECharacteristic::getDescriptorByUUID(const NimBLEUUID &uuid) { NimBLEDescriptor* NimBLECharacteristic::getDescriptorByUUID(const NimBLEUUID &uuid) {
for (auto &it : m_dscVec) { for (auto &it : m_dscVec) {
@ -138,6 +140,10 @@ uint16_t NimBLECharacteristic::getHandle() {
} // getHandle } // getHandle
/**
* @brief Get the properties of the characteristic.
* @return The properties of the characteristic.
*/
uint16_t NimBLECharacteristic::getProperties() { uint16_t NimBLECharacteristic::getProperties() {
return m_properties; return m_properties;
} // getProperties } // getProperties
@ -162,7 +168,7 @@ NimBLEUUID NimBLECharacteristic::getUUID() {
/** /**
* @brief Retrieve the current value of the characteristic. * @brief Retrieve the current value of the characteristic.
* @return A pointer to storage containing the current characteristic value. * @return A std::string containing the current characteristic value.
*/ */
std::string NimBLECharacteristic::getValue(time_t *timestamp) { std::string NimBLECharacteristic::getValue(time_t *timestamp) {
portENTER_CRITICAL(&m_valMux); portENTER_CRITICAL(&m_valMux);
@ -189,6 +195,9 @@ size_t NimBLECharacteristic::getDataLength() {
} }
/**
* @brief STATIC callback to handle events from the NimBLE stack.
*/
int NimBLECharacteristic::handleGapEvent(uint16_t conn_handle, uint16_t attr_handle, int NimBLECharacteristic::handleGapEvent(uint16_t conn_handle, uint16_t attr_handle,
struct ble_gatt_access_ctxt *ctxt, struct ble_gatt_access_ctxt *ctxt,
void *arg) void *arg)
@ -253,9 +262,8 @@ int NimBLECharacteristic::handleGapEvent(uint16_t conn_handle, uint16_t attr_han
/** /**
* @brief Set the subscribe status for this characteristic. * @brief Set the subscribe status for this characteristic.\n
* This will maintain a map of subscribed clients and their indicate/notify status. * This will maintain a vector of subscribed clients and their indicate/notify status.
* @return N/A
*/ */
void NimBLECharacteristic::setSubscribe(struct ble_gap_event *event) { void NimBLECharacteristic::setSubscribe(struct ble_gap_event *event) {
uint16_t subVal = 0; uint16_t subVal = 0;
@ -313,10 +321,9 @@ void NimBLECharacteristic::setSubscribe(struct ble_gap_event *event) {
/** /**
* @brief Send an indication. * @brief Send an indication.\n
* An indication is a transmission of up to the first 20 bytes of the characteristic value. An indication * An indication is a transmission of up to the first 20 bytes of the characteristic value.\n
* will block waiting a positive confirmation from the client. * An indication will block waiting for a positive confirmation from the client.
* @return N/A
*/ */
void NimBLECharacteristic::indicate() { void NimBLECharacteristic::indicate() {
NIMBLE_LOGD(LOG_TAG, ">> indicate: length: %d", getDataLength()); NIMBLE_LOGD(LOG_TAG, ">> indicate: length: %d", getDataLength());
@ -325,10 +332,10 @@ void NimBLECharacteristic::indicate() {
} // indicate } // indicate
/** /**
* @brief Send a notify. * @brief Send a notification.\n
* A notification is a transmission of up to the first 20 bytes of the characteristic value. An notification * A notification is a transmission of up to the first 20 bytes of the characteristic value.\n
* will not block; it is a fire and forget. * A notification will not block; it is a fire and forget.
* @return N/A. * @param[in] is_notification if true sends a notification, false sends an indication.
*/ */
void NimBLECharacteristic::notify(bool is_notification) { void NimBLECharacteristic::notify(bool is_notification) {
NIMBLE_LOGD(LOG_TAG, ">> notify: length: %d", getDataLength()); NIMBLE_LOGD(LOG_TAG, ">> notify: length: %d", getDataLength());
@ -435,7 +442,8 @@ void NimBLECharacteristic::notify(bool is_notification) {
/** /**
* @brief Set the callback handlers for this characteristic. * @brief Set the callback handlers for this characteristic.
* @param [in] pCallbacks An instance of a callbacks structure used to define any callbacks for the characteristic. * @param [in] pCallbacks An instance of a NimBLECharacteristicCallbacks class\n
* used to define any callbacks for the characteristic.
*/ */
void NimBLECharacteristic::setCallbacks(NimBLECharacteristicCallbacks* pCallbacks) { void NimBLECharacteristic::setCallbacks(NimBLECharacteristicCallbacks* pCallbacks) {
if (pCallbacks != nullptr){ if (pCallbacks != nullptr){
@ -473,11 +481,9 @@ void NimBLECharacteristic::setValue(const uint8_t* data, size_t length) {
/** /**
* @brief Set the value of the characteristic from string data. * @brief Set the value of the characteristic from string data.\n
* We set the value of the characteristic from the bytes contained in the * We set the value of the characteristic from the bytes contained in the string.
* string. * @param [in] value the std::string value of the characteristic.
* @param [in] Set the value of the characteristic.
* @return N/A.
*/ */
void NimBLECharacteristic::setValue(const std::string &value) { void NimBLECharacteristic::setValue(const std::string &value) {
setValue((uint8_t*)(value.data()), value.length()); setValue((uint8_t*)(value.data()), value.length());
@ -537,8 +543,8 @@ void NimBLECharacteristicCallbacks::onNotify(NimBLECharacteristic* pCharacterist
/** /**
* @brief Callback function to support a Notify/Indicate Status report. * @brief Callback function to support a Notify/Indicate Status report.
* @param [in] pCharacteristic The characteristic that is the source of the event. * @param [in] pCharacteristic The characteristic that is the source of the event.
* @param [in] s Status of the notification/indication * @param [in] s Status of the notification/indication.
* @param [in] code Additional code of underlying errors * @param [in] code Additional return code from the NimBLE stack.
*/ */
void NimBLECharacteristicCallbacks::onStatus(NimBLECharacteristic* pCharacteristic, Status s, int code) { void NimBLECharacteristicCallbacks::onStatus(NimBLECharacteristic* pCharacteristic, Status s, int code) {
NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onStatus: default"); NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onStatus: default");

View file

@ -75,6 +75,15 @@ public:
NimBLEUUID getUUID(); NimBLEUUID getUUID();
std::string getValue(time_t *timestamp = nullptr); std::string getValue(time_t *timestamp = nullptr);
/**
* @brief A template to convert the characteristic data to <type\>.
* @tparam T The type to convert the data to.
* @param [in] timestamp A pointer to a time_t struct to store the time the value was read.
* @param [in] skipSizeCheck If true it will skip checking if the data size is less than <tt>sizeof(<type\>)</tt>.
* @return The data converted to <type\> or NULL if skipSizeCheck is false and the data is
* less than <tt>sizeof(<type\>)</tt>.
* @details <b>Use:</b> <tt>getValue<type>(&timestamp, skipSizeCheck);</tt>
*/
template<typename T> template<typename T>
T getValue(time_t *timestamp = nullptr, bool skipSizeCheck = false) { T getValue(time_t *timestamp = nullptr, bool skipSizeCheck = false) {
std::string value = getValue(); std::string value = getValue();
@ -90,6 +99,10 @@ public:
void setValue(const uint8_t* data, size_t size); void setValue(const uint8_t* data, size_t size);
void setValue(const std::string &value); void setValue(const std::string &value);
/**
* @brief Convenience template to set the characteristic value to <type\>val.
* @param [in] s The value to set.
*/
template<typename T> template<typename T>
void setValue(const T &s) { void setValue(const T &s) {
setValue((uint8_t*)&s, sizeof(T)); setValue((uint8_t*)&s, sizeof(T));
@ -144,6 +157,12 @@ private:
*/ */
class NimBLECharacteristicCallbacks { class NimBLECharacteristicCallbacks {
public: public:
/**
* @brief An enum to provide the callback the status of the
* notification/indication, implemented for backward compatibility.
* @deprecated To be removed in the future as the NimBLE stack return code is also provided.
*/
typedef enum { typedef enum {
SUCCESS_INDICATE, SUCCESS_INDICATE,
SUCCESS_NOTIFY, SUCCESS_NOTIFY,

View file

@ -48,6 +48,11 @@ static NimBLEClientCallbacks defaultCallbacks;
* *
*/ */
/**
* @brief Constructor, private - only callable by NimBLEDevice::createClient
* to ensure proper handling of the list of client objects.
*/
NimBLEClient::NimBLEClient() NimBLEClient::NimBLEClient()
{ {
m_pClientCallbacks = &defaultCallbacks; m_pClientCallbacks = &defaultCallbacks;
@ -86,7 +91,7 @@ NimBLEClient::~NimBLEClient() {
/** /**
* @brief Delete any existing services. * @brief Delete all service objects created by this client and clear the vector.
*/ */
void NimBLEClient::deleteServices() { void NimBLEClient::deleteServices() {
NIMBLE_LOGD(LOG_TAG, ">> deleteServices"); NIMBLE_LOGD(LOG_TAG, ">> deleteServices");
@ -123,16 +128,11 @@ size_t NimBLEClient::deleteService(const NimBLEUUID &uuid) {
/** /**
* NOT NEEDED * @brief Connect to an advertising device.
*/ * @param [in] device The device to connect to.
/* * @param [in] refreshServices If true this will delete any attribute objects this client may already\n
void NimBLEClient::onHostReset() { * have created and clears the vectors after successful connection.
* @return True on success.
}
*/
/**
* Add overloaded function to ease connect to peer device with not public address
*/ */
bool NimBLEClient::connect(NimBLEAdvertisedDevice* device, bool refreshServices) { bool NimBLEClient::connect(NimBLEAdvertisedDevice* device, bool refreshServices) {
NimBLEAddress address(device->getAddress()); NimBLEAddress address(device->getAddress());
@ -142,8 +142,11 @@ bool NimBLEClient::connect(NimBLEAdvertisedDevice* device, bool refreshServices)
/** /**
* @brief Connect to the partner (BLE Server). * @brief Connect to the BLE Server.
* @param [in] address The address of the partner. * @param [in] address The address of the server.
* @param [in] type The address type of the server (Random/public/other)
* @param [in] refreshServices If true this will delete any attribute objects this client may already\n
* have created and clears the vectors after successful connection.
* @return True on success. * @return True on success.
*/ */
bool NimBLEClient::connect(const NimBLEAddress &address, uint8_t type, bool refreshServices) { bool NimBLEClient::connect(const NimBLEAddress &address, uint8_t type, bool refreshServices) {
@ -173,7 +176,7 @@ bool NimBLEClient::connect(const NimBLEAddress &address, uint8_t type, bool refr
ble_task_data_t taskData = {this, xTaskGetCurrentTaskHandle(), 0, nullptr}; ble_task_data_t taskData = {this, xTaskGetCurrentTaskHandle(), 0, nullptr};
m_pTaskData = &taskData; m_pTaskData = &taskData;
/** Try to connect the the advertiser. Allow 30 seconds (30000 ms) for /* Try to connect the the advertiser. Allow 30 seconds (30000 ms) for
* timeout (default value of m_connectTimeout). * timeout (default value of m_connectTimeout).
* Loop on BLE_HS_EBUSY if the scan hasn't stopped yet. * Loop on BLE_HS_EBUSY if the scan hasn't stopped yet.
*/ */
@ -218,8 +221,8 @@ bool NimBLEClient::connect(const NimBLEAddress &address, uint8_t type, bool refr
/** /**
* @brief Called when a characteristic or descriptor requires encryption or authentication to access it. * @brief Initiate a secure connection (pair/bond) with the server.\n
* This will pair with the device and bond if enabled. * Called automatically when a characteristic or descriptor requires encryption or authentication to access it.
* @return True on success. * @return True on success.
*/ */
bool NimBLEClient::secureConnection() { bool NimBLEClient::secureConnection() {
@ -239,12 +242,12 @@ bool NimBLEClient::secureConnection() {
} }
return true; return true;
} } // secureConnection
/** /**
* @brief Disconnect from the peer. * @brief Disconnect from the peer.
* @return N/A. * @return Error code from NimBLE stack, 0 = success.
*/ */
int NimBLEClient::disconnect(uint8_t reason) { int NimBLEClient::disconnect(uint8_t reason) {
NIMBLE_LOGD(LOG_TAG, ">> disconnect()"); NIMBLE_LOGD(LOG_TAG, ">> disconnect()");
@ -264,6 +267,12 @@ int NimBLEClient::disconnect(uint8_t reason) {
/** /**
* @brief Set the connection paramaters to use when connecting to a server. * @brief Set the connection paramaters to use when connecting to a server.
* @param [in] minInterval minimum connection interval in 0.625ms units.
* @param [in] maxInterval maximum connection interval in 0.625ms units.
* @param [in] latency number of packets allowed to skip (extends max interval)
* @param [in] timeout the timeout time in 10ms units before disconnecting
* @param [in] scanInterval the scan interval to use when attempting to connect in 0.625ms units.
* @param [in] scanWindow the scan window to use when attempting to connect in 0.625ms units.
*/ */
void NimBLEClient::setConnectionParams(uint16_t minInterval, uint16_t maxInterval, void NimBLEClient::setConnectionParams(uint16_t minInterval, uint16_t maxInterval,
uint16_t latency, uint16_t timeout, uint16_t latency, uint16_t timeout,
@ -271,12 +280,12 @@ void NimBLEClient::setConnectionParams(uint16_t minInterval, uint16_t maxInterva
uint16_t minConnTime, uint16_t maxConnTime)*/ uint16_t minConnTime, uint16_t maxConnTime)*/
{ {
m_pConnParams.scan_itvl = scanInterval; // Scan interval in 0.625ms units m_pConnParams.scan_itvl = scanInterval;
m_pConnParams.scan_window = scanWindow; // Scan window in 0.625ms units m_pConnParams.scan_window = scanWindow;
m_pConnParams.itvl_min = minInterval; // min_int = 0x10*1.25ms = 20ms m_pConnParams.itvl_min = minInterval;
m_pConnParams.itvl_max = maxInterval; // max_int = 0x20*1.25ms = 40ms m_pConnParams.itvl_max = maxInterval;
m_pConnParams.latency = latency; // number of packets allowed to skip (extends max interval) m_pConnParams.latency = latency;
m_pConnParams.supervision_timeout = timeout; // timeout = 400*10ms = 4000ms m_pConnParams.supervision_timeout = timeout;
// These are not used by NimBLE at this time - Must leave at defaults // These are not used by NimBLE at this time - Must leave at defaults
//m_pConnParams->min_ce_len = minConnTime; // Minimum length of connection event in 0.625ms units //m_pConnParams->min_ce_len = minConnTime; // Minimum length of connection event in 0.625ms units
@ -284,11 +293,16 @@ void NimBLEClient::setConnectionParams(uint16_t minInterval, uint16_t maxInterva
int rc = NimBLEUtils::checkConnParams(&m_pConnParams); int rc = NimBLEUtils::checkConnParams(&m_pConnParams);
assert(rc == 0 && "Invalid Connection parameters"); assert(rc == 0 && "Invalid Connection parameters");
} } // setConnectionParams
/** /**
* Update connection parameters can be called only after connection has been established * @brief Update the connection parameters:
* * Can only be used after a connection has been established.
* @param [in] minInterval minimum connection interval in 0.625ms units.
* @param [in] maxInterval maximum connection interval in 0.625ms units.
* @param [in] latency number of packets allowed to skip (extends max interval)
* @param [in] timeout the timeout time in 10ms units before disconnecting
*/ */
void NimBLEClient::updateConnParams(uint16_t minInterval, uint16_t maxInterval, void NimBLEClient::updateConnParams(uint16_t minInterval, uint16_t maxInterval,
uint16_t latency, uint16_t timeout) uint16_t latency, uint16_t timeout)
@ -308,16 +322,16 @@ void NimBLEClient::updateConnParams(uint16_t minInterval, uint16_t maxInterval,
NIMBLE_LOGE(LOG_TAG, "Update params error: %d, %s", NIMBLE_LOGE(LOG_TAG, "Update params error: %d, %s",
rc, NimBLEUtils::returnCodeToString(rc)); rc, NimBLEUtils::returnCodeToString(rc));
} }
} } // updateConnParams
/** /**
* @brief Set the timeout to wait for connection attempt to complete * @brief Set the timeout to wait for connection attempt to complete.
* @params[in] Time to wait in seconds. * @param [in] time The number of seconds before timeout.
*/ */
void NimBLEClient::setConnectTimeout(uint8_t time) { void NimBLEClient::setConnectTimeout(uint8_t time) {
m_connectTimeout = (uint32_t)(time * 1000); m_connectTimeout = (uint32_t)(time * 1000);
} } // setConnectTimeout
/** /**
@ -381,7 +395,7 @@ std::vector<NimBLERemoteService*>::iterator NimBLEClient::end() {
/** /**
* @brief Get the service BLE Remote Service instance corresponding to the uuid. * @brief Get the service BLE Remote Service instance corresponding to the uuid.
* @param [in] uuid The UUID of the service being sought. * @param [in] uuid The UUID of the service being sought.
* @return A reference to the Service or nullptr if don't know about it. * @return A pointer to the service or nullptr if not found.
*/ */
NimBLERemoteService* NimBLEClient::getService(const char* uuid) { NimBLERemoteService* NimBLEClient::getService(const char* uuid) {
return getService(NimBLEUUID(uuid)); return getService(NimBLEUUID(uuid));
@ -391,7 +405,7 @@ NimBLERemoteService* NimBLEClient::getService(const char* uuid) {
/** /**
* @brief Get the service object corresponding to the uuid. * @brief Get the service object corresponding to the uuid.
* @param [in] uuid The UUID of the service being sought. * @param [in] uuid The UUID of the service being sought.
* @return A reference to the Service or nullptr if don't know about it. * @return A pointer to the service or nullptr if not found.
*/ */
NimBLERemoteService* NimBLEClient::getService(const NimBLEUUID &uuid) { NimBLERemoteService* NimBLEClient::getService(const NimBLEUUID &uuid) {
NIMBLE_LOGD(LOG_TAG, ">> getService: uuid: %s", uuid.toString().c_str()); NIMBLE_LOGD(LOG_TAG, ">> getService: uuid: %s", uuid.toString().c_str());
@ -416,12 +430,11 @@ NimBLERemoteService* NimBLEClient::getService(const NimBLEUUID &uuid) {
/** /**
* @Get a pointer to the vector of found services. * @brief Get a pointer to the vector of found services.
* @param [in] bool value to indicate if the current vector should be cleared and * @param [in] refresh If true the current services vector will be cleared and\n
* subsequently all services retrieved from the peripheral. * all services will be retrieved from the peripheral.\n
* If false the vector will be returned with the currently stored services, * If false the vector will be returned with the currently stored services.
* If true it will retrieve all services from the peripheral and return the vector with all services * @return A pointer to the vector of available services.
* @return a pointer to the vector of available services.
*/ */
std::vector<NimBLERemoteService*>* NimBLEClient::getServices(bool refresh) { std::vector<NimBLERemoteService*>* NimBLEClient::getServices(bool refresh) {
if(refresh) { if(refresh) {
@ -435,11 +448,11 @@ std::vector<NimBLERemoteService*>* NimBLEClient::getServices(bool refresh) {
} }
} }
return &m_servicesVector; return &m_servicesVector;
} } // getServices
/** /**
* @ Retrieves the full database of attributes that the peripheral has available. * @brief Retrieves the full database of attributes that the peripheral has available.
*/ */
void NimBLEClient::discoverAttributes() { void NimBLEClient::discoverAttributes() {
for(auto svc: *getServices(true)) { for(auto svc: *getServices(true)) {
@ -447,14 +460,12 @@ void NimBLEClient::discoverAttributes() {
chr->getDescriptors(true); chr->getDescriptors(true);
} }
} }
} } // discoverAttributes
/** /**
* @brief Ask the remote %BLE server for its services. * @brief Ask the remote %BLE server for its services.\n
* A %BLE Server exposes a set of services for its partners. Here we ask the server for its set of * Here we ask the server for its set of services and wait until we have received them all.
* services and wait until we have received them all.
* We then ask for the characteristics for each service found and their desciptors.
* @return true on success otherwise false if an error occurred * @return true on success otherwise false if an error occurred
*/ */
bool NimBLEClient::retrieveServices(const NimBLEUUID *uuid_filter) { bool NimBLEClient::retrieveServices(const NimBLEUUID *uuid_filter) {
@ -502,7 +513,7 @@ bool NimBLEClient::retrieveServices(const NimBLEUUID *uuid_filter) {
/** /**
* @brief STATIC Callback for the service discovery API function. * @brief STATIC Callback for the service discovery API function.\n
* When a service is found or there is none left or there was an error * When a service is found or there is none left or there was an error
* the API will call this and report findings. * the API will call this and report findings.
*/ */
@ -574,6 +585,7 @@ std::string NimBLEClient::getValue(const NimBLEUUID &serviceUUID, const NimBLEUU
* @brief Set the value of a specific characteristic associated with a specific service. * @brief Set the value of a specific characteristic associated with a specific service.
* @param [in] serviceUUID The service that owns the characteristic. * @param [in] serviceUUID The service that owns the characteristic.
* @param [in] characteristicUUID The characteristic whose value we wish to write. * @param [in] characteristicUUID The characteristic whose value we wish to write.
* @param [in] value The value to write to the characteristic.
* @returns true if successful otherwise false * @returns true if successful otherwise false
*/ */
bool NimBLEClient::setValue(const NimBLEUUID &serviceUUID, const NimBLEUUID &characteristicUUID, bool NimBLEClient::setValue(const NimBLEUUID &serviceUUID, const NimBLEUUID &characteristicUUID,
@ -600,17 +612,17 @@ bool NimBLEClient::setValue(const NimBLEUUID &serviceUUID, const NimBLEUUID &cha
/** /**
* @brief Get the current mtu of this connection. * @brief Get the current mtu of this connection.
* @returns The MTU value.
*/ */
uint16_t NimBLEClient::getMTU() { uint16_t NimBLEClient::getMTU() {
return ble_att_mtu(m_conn_id); return ble_att_mtu(m_conn_id);
} } // getMTU
/** /**
* @brief Handle a received GAP event. * @brief Handle a received GAP event.
* * @param [in] event The event structure sent by the NimBLE stack.
* @param [in] event * @param [in] arg A pointer to the client instance that registered for this callback.
* @param [in] arg = pointer to the client instance
*/ */
/*STATIC*/ int NimBLEClient::handleGapEvent(struct ble_gap_event *event, void *arg) { /*STATIC*/ int NimBLEClient::handleGapEvent(struct ble_gap_event *event, void *arg) {
NimBLEClient* client = (NimBLEClient*)arg; NimBLEClient* client = (NimBLEClient*)arg;
@ -893,7 +905,9 @@ bool NimBLEClient::isConnected() {
/** /**
* @brief Set the callbacks that will be invoked. * @brief Set the callbacks that will be invoked when events are received.
* @param [in] pClientCallbacks A pointer to a class to receive the event callbacks.
* @param [in] deleteCallbacks If true this will delete the callback class sent when the client is destructed.
*/ */
void NimBLEClient::setClientCallbacks(NimBLEClientCallbacks* pClientCallbacks, bool deleteCallbacks) { void NimBLEClient::setClientCallbacks(NimBLEClientCallbacks* pClientCallbacks, bool deleteCallbacks) {
if (pClientCallbacks != nullptr){ if (pClientCallbacks != nullptr){
@ -938,7 +952,7 @@ uint32_t NimBLEClientCallbacks::onPassKeyRequest(){
NIMBLE_LOGD("NimBLEClientCallbacks", "onPassKeyRequest: default: 123456"); NIMBLE_LOGD("NimBLEClientCallbacks", "onPassKeyRequest: default: 123456");
return 123456; return 123456;
} }
/*
void NimBLEClientCallbacks::onPassKeyNotify(uint32_t pass_key){ void NimBLEClientCallbacks::onPassKeyNotify(uint32_t pass_key){
NIMBLE_LOGD("NimBLEClientCallbacks", "onPassKeyNotify: default: %d", pass_key); NIMBLE_LOGD("NimBLEClientCallbacks", "onPassKeyNotify: default: %d", pass_key);
} }
@ -946,7 +960,7 @@ void NimBLEClientCallbacks::onPassKeyNotify(uint32_t pass_key){
bool NimBLEClientCallbacks::onSecurityRequest(){ bool NimBLEClientCallbacks::onSecurityRequest(){
NIMBLE_LOGD("NimBLEClientCallbacks", "onSecurityRequest: default: true"); NIMBLE_LOGD("NimBLEClientCallbacks", "onSecurityRequest: default: true");
return true; return true;
} }*/
void NimBLEClientCallbacks::onAuthenticationComplete(ble_gap_conn_desc* desc){ void NimBLEClientCallbacks::onAuthenticationComplete(ble_gap_conn_desc* desc){
NIMBLE_LOGD("NimBLEClientCallbacks", "onAuthenticationComplete: default"); NIMBLE_LOGD("NimBLEClientCallbacks", "onAuthenticationComplete: default");
} }

View file

@ -107,13 +107,48 @@ private:
class NimBLEClientCallbacks { class NimBLEClientCallbacks {
public: public:
virtual ~NimBLEClientCallbacks() {}; virtual ~NimBLEClientCallbacks() {};
/**
* @brief Called after client connects.
* @param [in] pClient A pointer to the calling client object.
*/
virtual void onConnect(NimBLEClient* pClient); virtual void onConnect(NimBLEClient* pClient);
/**
* @brief Called when disconnected from the server.
* @param [in] pClient A pointer to the calling client object.
*/
virtual void onDisconnect(NimBLEClient* pClient); virtual void onDisconnect(NimBLEClient* pClient);
/**
* @brief Called when server requests to update the connection parameters.
* @param [in] pClient A pointer to the calling client object.
* @param [in] params A pointer to the struct containing the connection parameters requested.
* @return True to accept the parmeters.
*/
virtual bool onConnParamsUpdateRequest(NimBLEClient* pClient, const ble_gap_upd_params* params); virtual bool onConnParamsUpdateRequest(NimBLEClient* pClient, const ble_gap_upd_params* params);
/**
* @brief Called when server requests a passkey for pairing.
* @return The passkey to be sent to the server.
*/
virtual uint32_t onPassKeyRequest(); virtual uint32_t onPassKeyRequest();
virtual void onPassKeyNotify(uint32_t pass_key);
virtual bool onSecurityRequest(); /*virtual void onPassKeyNotify(uint32_t pass_key);
virtual bool onSecurityRequest();*/
/**
* @brief Called when the pairing procedure is complete.
* @param [in] desc A pointer to the struct containing the connection information.\n
* This can be used to check the status of the connection encryption/pairing.
*/
virtual void onAuthenticationComplete(ble_gap_conn_desc* desc); virtual void onAuthenticationComplete(ble_gap_conn_desc* desc);
/**
* @brief Called when using numeric comparision for pairing.
* @param [in] pin The pin to compare with the server.
* @return True to accept the pin.
*/
virtual bool onConfirmPIN(uint32_t pin); virtual bool onConfirmPIN(uint32_t pin);
}; };

View file

@ -52,6 +52,10 @@ public:
void setValue(const std::string &value); void setValue(const std::string &value);
std::string toString(); std::string toString();
/**
* @brief Convenience template to set the descriptor value to <type\>val.
* @param [in] s The value to set.
*/
template<typename T> template<typename T>
void setValue(const T &s) { void setValue(const T &s) {
setValue((uint8_t*)&s, sizeof(T)); setValue((uint8_t*)&s, sizeof(T));

View file

@ -90,6 +90,10 @@ NimBLESecurityCallbacks* NimBLEDevice::m_securityCallbacks = nullptr;
#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) #if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
/**
* @brief Get the instance of the advertising object.
* @return A pointer to the advertising object.
*/
NimBLEAdvertising* NimBLEDevice::getAdvertising() { NimBLEAdvertising* NimBLEDevice::getAdvertising() {
if(m_bleAdvertising == nullptr) { if(m_bleAdvertising == nullptr) {
m_bleAdvertising = new NimBLEAdvertising(); m_bleAdvertising = new NimBLEAdvertising();
@ -98,11 +102,17 @@ NimBLEAdvertising* NimBLEDevice::getAdvertising() {
} }
/**
* @brief Convenience function to begin advertising.
*/
void NimBLEDevice::startAdvertising() { void NimBLEDevice::startAdvertising() {
getAdvertising()->start(); getAdvertising()->start();
} // startAdvertising } // startAdvertising
/**
* @brief Convenience function to stop advertising.
*/
void NimBLEDevice::stopAdvertising() { void NimBLEDevice::stopAdvertising() {
getAdvertising()->stop(); getAdvertising()->stop();
} // stopAdvertising } // stopAdvertising
@ -123,6 +133,7 @@ void NimBLEDevice::stopAdvertising() {
} // getScan } // getScan
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) #endif // #if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
/** /**
* @brief Creates a new client object and maintains a list of all client objects * @brief Creates a new client object and maintains a list of all client objects
* each client can connect to 1 peripheral device. * each client can connect to 1 peripheral device.
@ -143,9 +154,9 @@ void NimBLEDevice::stopAdvertising() {
/** /**
* @brief Delete the client object and remove it from the list. * @brief Delete the client object and remove it from the list.\n
* Check if it is connected or trying to connect and close/stop it first. * Checks if it is connected or trying to connect and disconnects/stops it first.
* @param [in] Pointer to the client object. * @param [in] pClient A pointer to the client object.
*/ */
/* STATIC */ bool NimBLEDevice::deleteClient(NimBLEClient* pClient) { /* STATIC */ bool NimBLEDevice::deleteClient(NimBLEClient* pClient) {
if(pClient == nullptr) { if(pClient == nullptr) {
@ -183,8 +194,8 @@ void NimBLEDevice::stopAdvertising() {
/** /**
* @brief get the list of clients. * @brief Get the list of created client objects.
* @return a pointer to the list of clients. * @return A pointer to the list of clients.
*/ */
/* STATIC */std::list<NimBLEClient*>* NimBLEDevice::getClientList() { /* STATIC */std::list<NimBLEClient*>* NimBLEDevice::getClientList() {
return &m_cList; return &m_cList;
@ -192,8 +203,8 @@ void NimBLEDevice::stopAdvertising() {
/** /**
* @brief get the size of the list of clients. * @brief Get the number of created client objects.
* @return a pointer to the list of clients. * @return Number of client objects created.
*/ */
/* STATIC */size_t NimBLEDevice::getClientListSize() { /* STATIC */size_t NimBLEDevice::getClientListSize() {
return m_cList.size(); return m_cList.size();
@ -202,8 +213,8 @@ void NimBLEDevice::stopAdvertising() {
/** /**
* @brief Get a reference to a client by connection ID. * @brief Get a reference to a client by connection ID.
* @param [in] The client connection ID to search for. * @param [in] conn_id The client connection ID to search for.
* @return A reference pointer to the client with the spcified connection ID. * @return A pointer to the client object with the spcified connection ID.
*/ */
/* STATIC */NimBLEClient* NimBLEDevice::getClientByID(uint16_t conn_id) { /* STATIC */NimBLEClient* NimBLEDevice::getClientByID(uint16_t conn_id) {
for(auto it = m_cList.cbegin(); it != m_cList.cend(); ++it) { for(auto it = m_cList.cbegin(); it != m_cList.cend(); ++it) {
@ -218,8 +229,8 @@ void NimBLEDevice::stopAdvertising() {
/** /**
* @brief Get a reference to a client by peer address. * @brief Get a reference to a client by peer address.
* @param [in] a NimBLEAddress of the peer to search for. * @param [in] peer_addr The address of the peer to search for.
* @return A reference pointer to the client with the peer address. * @return A pointer to the client object with the peer address.
*/ */
/* STATIC */NimBLEClient* NimBLEDevice::getClientByPeerAddress(const NimBLEAddress &peer_addr) { /* STATIC */NimBLEClient* NimBLEDevice::getClientByPeerAddress(const NimBLEAddress &peer_addr) {
for(auto it = m_cList.cbegin(); it != m_cList.cend(); ++it) { for(auto it = m_cList.cbegin(); it != m_cList.cend(); ++it) {
@ -233,7 +244,7 @@ void NimBLEDevice::stopAdvertising() {
/** /**
* @brief Finds the first disconnected client in the list. * @brief Finds the first disconnected client in the list.
* @return A reference pointer to the first client that is not connected to a peer. * @return A pointer to the first client object that is not connected to a peer.
*/ */
/* STATIC */NimBLEClient* NimBLEDevice::getDisconnectedClient() { /* STATIC */NimBLEClient* NimBLEDevice::getDisconnectedClient() {
for(auto it = m_cList.cbegin(); it != m_cList.cend(); ++it) { for(auto it = m_cList.cbegin(); it != m_cList.cend(); ++it) {
@ -249,16 +260,28 @@ void NimBLEDevice::stopAdvertising() {
/** /**
* @brief Set the transmission power. * @brief Set the transmission power.
* The power level can be one of: * @param [in] powerLevel The power level to set, can be one of:
* * ESP_PWR_LVL_N12 = 0, !< Corresponding to -12dbm * * ESP_PWR_LVL_N12 = 0, Corresponding to -12dbm
* * ESP_PWR_LVL_N9 = 1, !< Corresponding to -9dbm * * ESP_PWR_LVL_N9 = 1, Corresponding to -9dbm
* * ESP_PWR_LVL_N6 = 2, !< Corresponding to -6dbm * * ESP_PWR_LVL_N6 = 2, Corresponding to -6dbm
* * ESP_PWR_LVL_N3 = 3, !< Corresponding to -3dbm * * ESP_PWR_LVL_N3 = 3, Corresponding to -3dbm
* * ESP_PWR_LVL_N0 = 4, !< Corresponding to 0dbm * * ESP_PWR_LVL_N0 = 4, Corresponding to 0dbm
* * ESP_PWR_LVL_P3 = 5, !< Corresponding to +3dbm * * ESP_PWR_LVL_P3 = 5, Corresponding to +3dbm
* * ESP_PWR_LVL_P6 = 6, !< Corresponding to +6dbm * * ESP_PWR_LVL_P6 = 6, Corresponding to +6dbm
* * ESP_PWR_LVL_P9 = 7, !< Corresponding to +9dbm * * ESP_PWR_LVL_P9 = 7, Corresponding to +9dbm
* @param [in] powerLevel. * @param [in] powerType The BLE function to set the power level for, can be one of:
* * ESP_BLE_PWR_TYPE_CONN_HDL0 = 0, For connection handle 0
* * ESP_BLE_PWR_TYPE_CONN_HDL1 = 1, For connection handle 1
* * ESP_BLE_PWR_TYPE_CONN_HDL2 = 2, For connection handle 2
* * ESP_BLE_PWR_TYPE_CONN_HDL3 = 3, For connection handle 3
* * ESP_BLE_PWR_TYPE_CONN_HDL4 = 4, For connection handle 4
* * ESP_BLE_PWR_TYPE_CONN_HDL5 = 5, For connection handle 5
* * ESP_BLE_PWR_TYPE_CONN_HDL6 = 6, For connection handle 6
* * ESP_BLE_PWR_TYPE_CONN_HDL7 = 7, For connection handle 7
* * ESP_BLE_PWR_TYPE_CONN_HDL8 = 8, For connection handle 8
* * ESP_BLE_PWR_TYPE_ADV = 9, For advertising
* * ESP_BLE_PWR_TYPE_SCAN = 10, For scan
* * ESP_BLE_PWR_TYPE_DEFAULT = 11, For default, if not set other, it will use default value
*/ */
/* STATIC */ void NimBLEDevice::setPower(esp_power_level_t powerLevel, esp_ble_power_type_t powerType) { /* STATIC */ void NimBLEDevice::setPower(esp_power_level_t powerLevel, esp_ble_power_type_t powerType) {
NIMBLE_LOGD(LOG_TAG, ">> setPower: %d (type: %d)", powerLevel, powerType); NIMBLE_LOGD(LOG_TAG, ">> setPower: %d (type: %d)", powerLevel, powerType);
@ -270,6 +293,24 @@ void NimBLEDevice::stopAdvertising() {
} // setPower } // setPower
/**
* @brief Set the transmission power.
* @param [in] powerType The power level to set, can be one of:
* * ESP_BLE_PWR_TYPE_CONN_HDL0 = 0, For connection handle 0
* * ESP_BLE_PWR_TYPE_CONN_HDL1 = 1, For connection handle 1
* * ESP_BLE_PWR_TYPE_CONN_HDL2 = 2, For connection handle 2
* * ESP_BLE_PWR_TYPE_CONN_HDL3 = 3, For connection handle 3
* * ESP_BLE_PWR_TYPE_CONN_HDL4 = 4, For connection handle 4
* * ESP_BLE_PWR_TYPE_CONN_HDL5 = 5, For connection handle 5
* * ESP_BLE_PWR_TYPE_CONN_HDL6 = 6, For connection handle 6
* * ESP_BLE_PWR_TYPE_CONN_HDL7 = 7, For connection handle 7
* * ESP_BLE_PWR_TYPE_CONN_HDL8 = 8, For connection handle 8
* * ESP_BLE_PWR_TYPE_ADV = 9, For advertising
* * ESP_BLE_PWR_TYPE_SCAN = 10, For scan
* * ESP_BLE_PWR_TYPE_DEFAULT = 11, For default, if not set other, it will use default value
* @return the power level currently used by the type specified.
*/
/* STATIC */ int NimBLEDevice::getPower(esp_ble_power_type_t powerType) { /* STATIC */ int NimBLEDevice::getPower(esp_ble_power_type_t powerType) {
switch(esp_ble_tx_power_get(powerType)) { switch(esp_ble_tx_power_get(powerType)) {
@ -302,7 +343,6 @@ void NimBLEDevice::stopAdvertising() {
*/ */
/* STATIC*/ NimBLEAddress NimBLEDevice::getAddress() { /* STATIC*/ NimBLEAddress NimBLEDevice::getAddress() {
ble_addr_t addr = {BLE_ADDR_PUBLIC, 0}; ble_addr_t addr = {BLE_ADDR_PUBLIC, 0};
//ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, addr.val, NULL)
if(BLE_HS_ENOADDR == ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, addr.val, NULL)) { if(BLE_HS_ENOADDR == ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, addr.val, NULL)) {
NIMBLE_LOGD(LOG_TAG, "Public address not found, checking random"); NIMBLE_LOGD(LOG_TAG, "Public address not found, checking random");
@ -324,9 +364,9 @@ void NimBLEDevice::stopAdvertising() {
/** /**
* @brief Setup local mtu that will be used to negotiate mtu during request from client peer * @brief Setup local mtu that will be used to negotiate mtu during request from client peer.
* @param [in] mtu Value to set local mtu, should be larger than 23 and lower or equal to * @param [in] mtu Value to set local mtu:
* BLE_ATT_MTU_MAX = 527 * * This should be larger than 23 and lower or equal to BLE_ATT_MTU_MAX = 527.
*/ */
/* STATIC */int NimBLEDevice::setMTU(uint16_t mtu) { /* STATIC */int NimBLEDevice::setMTU(uint16_t mtu) {
NIMBLE_LOGD(LOG_TAG, ">> setLocalMTU: %d", mtu); NIMBLE_LOGD(LOG_TAG, ">> setLocalMTU: %d", mtu);
@ -344,6 +384,7 @@ void NimBLEDevice::stopAdvertising() {
/** /**
* @brief Get local MTU value set. * @brief Get local MTU value set.
* @return The current preferred MTU setting.
*/ */
/* STATIC */uint16_t NimBLEDevice::getMTU() { /* STATIC */uint16_t NimBLEDevice::getMTU() {
return ble_att_preferred_mtu(); return ble_att_preferred_mtu();
@ -352,6 +393,7 @@ void NimBLEDevice::stopAdvertising() {
/** /**
* @brief Host reset, we pass the message so we don't make calls until resynced. * @brief Host reset, we pass the message so we don't make calls until resynced.
* @param [in] reason The reason code for the reset.
*/ */
/* STATIC */ void NimBLEDevice::onReset(int reason) /* STATIC */ void NimBLEDevice::onReset(int reason)
{ {
@ -389,7 +431,7 @@ void NimBLEDevice::stopAdvertising() {
/** /**
* @brief Host resynced with controller, all clear to make calls. * @brief Host resynced with controller, all clear to make calls to the stack.
*/ */
/* STATIC */ void NimBLEDevice::onSync(void) /* STATIC */ void NimBLEDevice::onSync(void)
{ {
@ -439,7 +481,7 @@ void NimBLEDevice::stopAdvertising() {
/** /**
* @brief Initialize the %BLE environment. * @brief Initialize the %BLE environment.
* @param deviceName The device name of the device. * @param [in] deviceName The device name of the device.
*/ */
/* STATIC */ void NimBLEDevice::init(const std::string &deviceName) { /* STATIC */ void NimBLEDevice::init(const std::string &deviceName) {
if(!initialized){ if(!initialized){
@ -516,6 +558,7 @@ void NimBLEDevice::stopAdvertising() {
/** /**
* @brief Check if the initialization is complete. * @brief Check if the initialization is complete.
* @return true if initialized.
*/ */
bool NimBLEDevice::getInitialized() { bool NimBLEDevice::getInitialized() {
return initialized; return initialized;
@ -524,9 +567,9 @@ bool NimBLEDevice::getInitialized() {
/** /**
* @brief Set the authorization mode for this device. * @brief Set the authorization mode for this device.
* @param bonding, if true we allow bonding, false no bonding will be performed. * @param bonding If true we allow bonding, false no bonding will be performed.
* @param mitm, if true we are capable of man in the middle protection, false if not. * @param mitm If true we are capable of man in the middle protection, false if not.
* @param sc, if true we will perform secure connection pairing, false we will use legacy pairing. * @param sc If true we will perform secure connection pairing, false we will use legacy pairing.
*/ */
/*STATIC*/ void NimBLEDevice::setSecurityAuth(bool bonding, bool mitm, bool sc) { /*STATIC*/ void NimBLEDevice::setSecurityAuth(bool bonding, bool mitm, bool sc) {
NIMBLE_LOGD(LOG_TAG, "Setting bonding: %d, mitm: %d, sc: %d",bonding,mitm,sc); NIMBLE_LOGD(LOG_TAG, "Setting bonding: %d, mitm: %d, sc: %d",bonding,mitm,sc);
@ -538,13 +581,12 @@ bool NimBLEDevice::getInitialized() {
/** /**
* @brief Set the authorization mode for this device. * @brief Set the authorization mode for this device.
* @param A bitmap indicating what modes are supported. * @param auth_req A bitmap indicating what modes are supported.\n
* The bits are defined as follows: * The available bits are defined as:
** 0x01 BLE_SM_PAIR_AUTHREQ_BOND * * 0x01 BLE_SM_PAIR_AUTHREQ_BOND
** 0x04 BLE_SM_PAIR_AUTHREQ_MITM * * 0x04 BLE_SM_PAIR_AUTHREQ_MITM
** 0x08 BLE_SM_PAIR_AUTHREQ_SC * * 0x08 BLE_SM_PAIR_AUTHREQ_SC
** 0x10 BLE_SM_PAIR_AUTHREQ_KEYPRESS - not yet supported. * * 0x10 BLE_SM_PAIR_AUTHREQ_KEYPRESS - not yet supported.
** 0xe2 BLE_SM_PAIR_AUTHREQ_RESERVED - for reference only.
*/ */
/*STATIC*/void NimBLEDevice::setSecurityAuth(uint8_t auth_req) { /*STATIC*/void NimBLEDevice::setSecurityAuth(uint8_t auth_req) {
NimBLEDevice::setSecurityAuth((auth_req & BLE_SM_PAIR_AUTHREQ_BOND)>0, NimBLEDevice::setSecurityAuth((auth_req & BLE_SM_PAIR_AUTHREQ_BOND)>0,
@ -555,12 +597,12 @@ bool NimBLEDevice::getInitialized() {
/** /**
* @brief Set the Input/Output capabilities of this device. * @brief Set the Input/Output capabilities of this device.
* @param One of the following: * @param iocap One of the following values:
** 0x00 BLE_HS_IO_DISPLAY_ONLY DisplayOnly IO capability * * 0x00 BLE_HS_IO_DISPLAY_ONLY DisplayOnly IO capability
** 0x01 BLE_HS_IO_DISPLAY_YESNO DisplayYesNo IO capability * * 0x01 BLE_HS_IO_DISPLAY_YESNO DisplayYesNo IO capability
** 0x02 BLE_HS_IO_KEYBOARD_ONLY KeyboardOnly IO capability * * 0x02 BLE_HS_IO_KEYBOARD_ONLY KeyboardOnly IO capability
** 0x03 BLE_HS_IO_NO_INPUT_OUTPUT NoInputNoOutput IO capability * * 0x03 BLE_HS_IO_NO_INPUT_OUTPUT NoInputNoOutput IO capability
** 0x04 BLE_HS_IO_KEYBOARD_DISPLAY KeyboardDisplay Only IO capability * * 0x04 BLE_HS_IO_KEYBOARD_DISPLAY KeyboardDisplay Only IO capability
*/ */
/*STATIC*/ void NimBLEDevice::setSecurityIOCap(uint8_t iocap) { /*STATIC*/ void NimBLEDevice::setSecurityIOCap(uint8_t iocap) {
ble_hs_cfg.sm_io_cap = iocap; ble_hs_cfg.sm_io_cap = iocap;
@ -569,12 +611,12 @@ bool NimBLEDevice::getInitialized() {
/** /**
* @brief If we are the initiator of the security procedure this sets the keys we will distribute. * @brief If we are the initiator of the security procedure this sets the keys we will distribute.
* @param A bitmap indicating which keys to distribute during pairing. * @param init_key A bitmap indicating which keys to distribute during pairing.\n
* The bits are defined as follows: * The available bits are defined as:
** 0x01: BLE_SM_PAIR_KEY_DIST_ENC - Distribute the encryption key. * * 0x01: BLE_SM_PAIR_KEY_DIST_ENC - Distribute the encryption key.
** 0x02: BLE_SM_PAIR_KEY_DIST_ID - Distribute the ID key (IRK). * * 0x02: BLE_SM_PAIR_KEY_DIST_ID - Distribute the ID key (IRK).
** 0x04: BLE_SM_PAIR_KEY_DIST_SIGN * * 0x04: BLE_SM_PAIR_KEY_DIST_SIGN
** 0x08: BLE_SM_PAIR_KEY_DIST_LINK * * 0x08: BLE_SM_PAIR_KEY_DIST_LINK
*/ */
/*STATIC*/void NimBLEDevice::setSecurityInitKey(uint8_t init_key) { /*STATIC*/void NimBLEDevice::setSecurityInitKey(uint8_t init_key) {
ble_hs_cfg.sm_our_key_dist = init_key; ble_hs_cfg.sm_our_key_dist = init_key;
@ -583,20 +625,21 @@ bool NimBLEDevice::getInitialized() {
/** /**
* @brief Set the keys we are willing to accept during pairing. * @brief Set the keys we are willing to accept during pairing.
* @param A bitmap indicating which keys to accept during pairing. * @param resp_key A bitmap indicating which keys to accept during pairing.
* The bits are defined as follows: * The available bits are defined as:
** 0x01: BLE_SM_PAIR_KEY_DIST_ENC - Accept the encryption key. * * 0x01: BLE_SM_PAIR_KEY_DIST_ENC - Accept the encryption key.
** 0x02: BLE_SM_PAIR_KEY_DIST_ID - Accept the ID key (IRK). * * 0x02: BLE_SM_PAIR_KEY_DIST_ID - Accept the ID key (IRK).
** 0x04: BLE_SM_PAIR_KEY_DIST_SIGN * * 0x04: BLE_SM_PAIR_KEY_DIST_SIGN
** 0x08: BLE_SM_PAIR_KEY_DIST_LINK * * 0x08: BLE_SM_PAIR_KEY_DIST_LINK
*/ */
/*STATIC*/void NimBLEDevice::setSecurityRespKey(uint8_t init_key) { /*STATIC*/void NimBLEDevice::setSecurityRespKey(uint8_t resp_key) {
ble_hs_cfg.sm_their_key_dist = init_key; ble_hs_cfg.sm_their_key_dist = resp_key;
} // setsSecurityRespKey } // setsSecurityRespKey
/** /**
* @brief Set the passkey for pairing. * @brief Set the passkey the server will ask for when pairing.
* @param [in] pin The passkey to use.
*/ */
/*STATIC*/void NimBLEDevice::setSecurityPasskey(uint32_t pin) { /*STATIC*/void NimBLEDevice::setSecurityPasskey(uint32_t pin) {
m_passkey = pin; m_passkey = pin;
@ -604,7 +647,8 @@ bool NimBLEDevice::getInitialized() {
/** /**
* @brief Get the passkey for pairing. * @brief Get the current passkey used for pairing.
* @return The current passkey.
*/ */
/*STATIC*/uint32_t NimBLEDevice::getSecurityPasskey() { /*STATIC*/uint32_t NimBLEDevice::getSecurityPasskey() {
return m_passkey; return m_passkey;
@ -613,7 +657,8 @@ bool NimBLEDevice::getInitialized() {
/** /**
* @brief Set callbacks that will be used to handle encryption negotiation events and authentication events * @brief Set callbacks that will be used to handle encryption negotiation events and authentication events
* @param [in] cllbacks Pointer to NimBLESecurityCallbacks class * @param [in] callbacks Pointer to NimBLESecurityCallbacks class
* @deprecated For backward compatibility, New code should use client/server callback methods.
*/ */
void NimBLEDevice::setSecurityCallbacks(NimBLESecurityCallbacks* callbacks) { void NimBLEDevice::setSecurityCallbacks(NimBLESecurityCallbacks* callbacks) {
NimBLEDevice::m_securityCallbacks = callbacks; NimBLEDevice::m_securityCallbacks = callbacks;
@ -622,8 +667,8 @@ void NimBLEDevice::setSecurityCallbacks(NimBLESecurityCallbacks* callbacks) {
/** /**
* @brief Start the connection securing and authorization for this connection. * @brief Start the connection securing and authorization for this connection.
* @param Connection id of the client. * @param conn_id The connection id of the peer device.
* @returns host return code 0 if success. * @returns NimBLE stack return code, 0 = success.
*/ */
/* STATIC */int NimBLEDevice::startSecurity(uint16_t conn_id) { /* STATIC */int NimBLEDevice::startSecurity(uint16_t conn_id) {
/* if(m_securityCallbacks != nullptr) { /* if(m_securityCallbacks != nullptr) {
@ -641,6 +686,7 @@ void NimBLEDevice::setSecurityCallbacks(NimBLESecurityCallbacks* callbacks) {
/** /**
* @brief Check if the device address is on our ignore list. * @brief Check if the device address is on our ignore list.
* @param [in] address The address to look for.
* @return True if ignoring. * @return True if ignoring.
*/ */
/*STATIC*/ bool NimBLEDevice::isIgnored(const NimBLEAddress &address) { /*STATIC*/ bool NimBLEDevice::isIgnored(const NimBLEAddress &address) {
@ -656,7 +702,7 @@ void NimBLEDevice::setSecurityCallbacks(NimBLESecurityCallbacks* callbacks) {
/** /**
* @brief Add a device to the ignore list. * @brief Add a device to the ignore list.
* @param Address of the device we want to ignore. * @param [in] address The address of the device we want to ignore.
*/ */
/*STATIC*/ void NimBLEDevice::addIgnored(const NimBLEAddress &address) { /*STATIC*/ void NimBLEDevice::addIgnored(const NimBLEAddress &address) {
m_ignoreList.push_back(address); m_ignoreList.push_back(address);
@ -665,7 +711,7 @@ void NimBLEDevice::setSecurityCallbacks(NimBLESecurityCallbacks* callbacks) {
/** /**
* @brief Remove a device from the ignore list. * @brief Remove a device from the ignore list.
* @param Address of the device we want to remove from the list. * @param [in] address The address of the device we want to remove from the list.
*/ */
/*STATIC*/void NimBLEDevice::removeIgnored(const NimBLEAddress &address) { /*STATIC*/void NimBLEDevice::removeIgnored(const NimBLEAddress &address) {
for(auto it = m_ignoreList.begin(); it != m_ignoreList.end(); ++it) { for(auto it = m_ignoreList.begin(); it != m_ignoreList.end(); ++it) {
@ -679,6 +725,7 @@ void NimBLEDevice::setSecurityCallbacks(NimBLESecurityCallbacks* callbacks) {
/** /**
* @brief Set a custom callback for gap events. * @brief Set a custom callback for gap events.
* @param [in] handler The function to call when gap events occur.
*/ */
void NimBLEDevice::setCustomGapHandler(gap_event_handler handler) { void NimBLEDevice::setCustomGapHandler(gap_event_handler handler) {
m_customGapHandler = handler; m_customGapHandler = handler;

View file

@ -81,13 +81,13 @@
#define NIMBLE_MAX_CONNECTIONS CONFIG_NIMBLE_MAX_CONNECTIONS #define NIMBLE_MAX_CONNECTIONS CONFIG_NIMBLE_MAX_CONNECTIONS
#endif #endif
/** typedef int (*gap_event_handler)(ble_gap_event *event, void *arg);
* @brief BLE functions.
*/
typedef int (*gap_event_handler)(ble_gap_event *event, void *arg);
extern "C" void ble_store_config_init(void); extern "C" void ble_store_config_init(void);
/**
* @brief A model of a %BLE Device from which all the BLE roles are created.
*/
class NimBLEDevice { class NimBLEDevice {
public: public:
static void init(const std::string &deviceName); static void init(const std::string &deviceName);
@ -181,8 +181,6 @@ private:
static NimBLESecurityCallbacks* m_securityCallbacks; static NimBLESecurityCallbacks* m_securityCallbacks;
static uint32_t m_passkey; static uint32_t m_passkey;
static ble_gap_event_listener m_listener; static ble_gap_event_listener m_listener;
public:
static gap_event_handler m_customGapHandler; static gap_event_handler m_customGapHandler;
}; };

View file

@ -24,7 +24,9 @@
static const char LOG_TAG[] = "NimBLEEddystoneTLM"; static const char LOG_TAG[] = "NimBLEEddystoneTLM";
/**
* @brief Construct a default EddystoneTLM beacon object.
*/
NimBLEEddystoneTLM::NimBLEEddystoneTLM() { NimBLEEddystoneTLM::NimBLEEddystoneTLM() {
beaconUUID = 0xFEAA; beaconUUID = 0xFEAA;
m_eddystoneData.frameType = EDDYSTONE_TLM_FRAME_TYPE; m_eddystoneData.frameType = EDDYSTONE_TLM_FRAME_TYPE;
@ -35,34 +37,73 @@ NimBLEEddystoneTLM::NimBLEEddystoneTLM() {
m_eddystoneData.tmil = 0; m_eddystoneData.tmil = 0;
} // NimBLEEddystoneTLM } // NimBLEEddystoneTLM
/**
* @brief Retrieve the data that is being advertised.
* @return The advertised data.
*/
std::string NimBLEEddystoneTLM::getData() { std::string NimBLEEddystoneTLM::getData() {
return std::string((char*) &m_eddystoneData, sizeof(m_eddystoneData)); return std::string((char*) &m_eddystoneData, sizeof(m_eddystoneData));
} // getData } // getData
/**
* @brief Get the UUID being advertised.
* @return The UUID advertised.
*/
NimBLEUUID NimBLEEddystoneTLM::getUUID() { NimBLEUUID NimBLEEddystoneTLM::getUUID() {
return NimBLEUUID(beaconUUID); return NimBLEUUID(beaconUUID);
} // getUUID } // getUUID
/**
* @brief Get the version being advertised.
* @return The version number.
*/
uint8_t NimBLEEddystoneTLM::getVersion() { uint8_t NimBLEEddystoneTLM::getVersion() {
return m_eddystoneData.version; return m_eddystoneData.version;
} // getVersion } // getVersion
/**
* @brief Get the battery voltage.
* @return The battery voltage.
*/
uint16_t NimBLEEddystoneTLM::getVolt() { uint16_t NimBLEEddystoneTLM::getVolt() {
return ENDIAN_CHANGE_U16(m_eddystoneData.volt); return ENDIAN_CHANGE_U16(m_eddystoneData.volt);
} // getVolt } // getVolt
/**
* @brief Get the temperature being advertised.
* @return The temperature value.
*/
float NimBLEEddystoneTLM::getTemp() { float NimBLEEddystoneTLM::getTemp() {
return ENDIAN_CHANGE_U16(m_eddystoneData.temp) / 256.0f; return ENDIAN_CHANGE_U16(m_eddystoneData.temp) / 256.0f;
} // getTemp } // getTemp
/**
* @brief Get the count of advertisments sent.
* @return The number of advertisments.
*/
uint32_t NimBLEEddystoneTLM::getCount() { uint32_t NimBLEEddystoneTLM::getCount() {
return ENDIAN_CHANGE_U32(m_eddystoneData.advCount); return ENDIAN_CHANGE_U32(m_eddystoneData.advCount);
} // getCount } // getCount
/**
* @brief Get the advertisment time.
* @return The advertisment time.
*/
uint32_t NimBLEEddystoneTLM::getTime() { uint32_t NimBLEEddystoneTLM::getTime() {
return (ENDIAN_CHANGE_U32(m_eddystoneData.tmil)) / 10; return (ENDIAN_CHANGE_U32(m_eddystoneData.tmil)) / 10;
} // getTime } // getTime
/**
* @brief Get a string representation of the beacon.
* @return The string representation.
*/
std::string NimBLEEddystoneTLM::toString() { std::string NimBLEEddystoneTLM::toString() {
std::string out = ""; std::string out = "";
uint32_t rawsec = ENDIAN_CHANGE_U32(m_eddystoneData.tmil); uint32_t rawsec = ENDIAN_CHANGE_U32(m_eddystoneData.tmil);
@ -113,8 +154,10 @@ std::string NimBLEEddystoneTLM::toString() {
return out; return out;
} // toString } // toString
/** /**
* Set the raw data for the beacon record. * @brief Set the raw data for the beacon advertisment.
* @param [in] data The raw data to advertise.
*/ */
void NimBLEEddystoneTLM::setData(const std::string &data) { void NimBLEEddystoneTLM::setData(const std::string &data) {
if (data.length() != sizeof(m_eddystoneData)) { if (data.length() != sizeof(m_eddystoneData)) {
@ -125,26 +168,56 @@ void NimBLEEddystoneTLM::setData(const std::string &data) {
memcpy(&m_eddystoneData, data.data(), data.length()); memcpy(&m_eddystoneData, data.data(), data.length());
} // setData } // setData
/**
* @brief Set the UUID to advertise.
* @param [in] l_uuid The UUID.
*/
void NimBLEEddystoneTLM::setUUID(const NimBLEUUID &l_uuid) { void NimBLEEddystoneTLM::setUUID(const NimBLEUUID &l_uuid) {
beaconUUID = l_uuid.getNative()->u16.value; beaconUUID = l_uuid.getNative()->u16.value;
} // setUUID } // setUUID
/**
* @brief Set the version to advertise.
* @param [in] version The version number.
*/
void NimBLEEddystoneTLM::setVersion(uint8_t version) { void NimBLEEddystoneTLM::setVersion(uint8_t version) {
m_eddystoneData.version = version; m_eddystoneData.version = version;
} // setVersion } // setVersion
/**
* @brief Set the battery voltage to advertise.
* @param [in] volt The voltage in millivolts.
*/
void NimBLEEddystoneTLM::setVolt(uint16_t volt) { void NimBLEEddystoneTLM::setVolt(uint16_t volt) {
m_eddystoneData.volt = volt; m_eddystoneData.volt = volt;
} // setVolt } // setVolt
/**
* @brief Set the temperature to advertise.
* @param [in] temp The temperature value.
*/
void NimBLEEddystoneTLM::setTemp(float temp) { void NimBLEEddystoneTLM::setTemp(float temp) {
m_eddystoneData.temp = (uint16_t)temp; m_eddystoneData.temp = (uint16_t)temp;
} // setTemp } // setTemp
/**
* @brief Set the advertisment count.
* @param [in] advCount The advertisment number.
*/
void NimBLEEddystoneTLM::setCount(uint32_t advCount) { void NimBLEEddystoneTLM::setCount(uint32_t advCount) {
m_eddystoneData.advCount = advCount; m_eddystoneData.advCount = advCount;
} // setCount } // setCount
/**
* @brief Set the advertisment time.
* @param [in] tmil The advertisment time in milliseconds.
*/
void NimBLEEddystoneTLM::setTime(uint32_t tmil) { void NimBLEEddystoneTLM::setTime(uint32_t tmil) {
m_eddystoneData.tmil = tmil; m_eddystoneData.tmil = tmil;
} // setTime } // setTime

View file

@ -21,6 +21,10 @@
static const char LOG_TAG[] = "NimBLEEddystoneURL"; static const char LOG_TAG[] = "NimBLEEddystoneURL";
/**
* @brief Construct a default EddystoneURL beacon object.
*/
NimBLEEddystoneURL::NimBLEEddystoneURL() { NimBLEEddystoneURL::NimBLEEddystoneURL() {
beaconUUID = 0xFEAA; beaconUUID = 0xFEAA;
lengthURL = 0; lengthURL = 0;
@ -29,22 +33,47 @@ NimBLEEddystoneURL::NimBLEEddystoneURL() {
memset(m_eddystoneData.url, 0, sizeof(m_eddystoneData.url)); memset(m_eddystoneData.url, 0, sizeof(m_eddystoneData.url));
} // BLEEddystoneURL } // BLEEddystoneURL
/**
* @brief Retrieve the data that is being advertised.
* @return The advertised data.
*/
std::string NimBLEEddystoneURL::getData() { std::string NimBLEEddystoneURL::getData() {
return std::string((char*) &m_eddystoneData, sizeof(m_eddystoneData)); return std::string((char*) &m_eddystoneData, sizeof(m_eddystoneData));
} // getData } // getData
/**
* @brief Get the UUID being advertised.
* @return The UUID advertised.
*/
NimBLEUUID NimBLEEddystoneURL::getUUID() { NimBLEUUID NimBLEEddystoneURL::getUUID() {
return NimBLEUUID(beaconUUID); return NimBLEUUID(beaconUUID);
} // getUUID } // getUUID
/**
* @brief Get the transmit power being advertised.
* @return The transmit power.
*/
int8_t NimBLEEddystoneURL::getPower() { int8_t NimBLEEddystoneURL::getPower() {
return m_eddystoneData.advertisedTxPower; return m_eddystoneData.advertisedTxPower;
} // getPower } // getPower
/**
* @brief Get the raw URL being advertised.
* @return The raw URL.
*/
std::string NimBLEEddystoneURL::getURL() { std::string NimBLEEddystoneURL::getURL() {
return std::string((char*) &m_eddystoneData.url, sizeof(m_eddystoneData.url)); return std::string((char*) &m_eddystoneData.url, sizeof(m_eddystoneData.url));
} // getURL } // getURL
/**
* @brief Get the full URL being advertised.
* @return The full URL.
*/
std::string NimBLEEddystoneURL::getDecodedURL() { std::string NimBLEEddystoneURL::getDecodedURL() {
std::string decodedURL = ""; std::string decodedURL = "";
@ -123,7 +152,8 @@ std::string NimBLEEddystoneURL::getDecodedURL() {
/** /**
* Set the raw data for the beacon record. * @brief Set the raw data for the beacon advertisment.
* @param [in] data The raw data to advertise.
*/ */
void NimBLEEddystoneURL::setData(const std::string &data) { void NimBLEEddystoneURL::setData(const std::string &data) {
if (data.length() > sizeof(m_eddystoneData)) { if (data.length() > sizeof(m_eddystoneData)) {
@ -136,14 +166,29 @@ void NimBLEEddystoneURL::setData(const std::string &data) {
lengthURL = data.length() - (sizeof(m_eddystoneData) - sizeof(m_eddystoneData.url)); lengthURL = data.length() - (sizeof(m_eddystoneData) - sizeof(m_eddystoneData.url));
} // setData } // setData
/**
* @brief Set the UUID to advertise.
* @param [in] l_uuid The UUID.
*/
void NimBLEEddystoneURL::setUUID(const NimBLEUUID &l_uuid) { void NimBLEEddystoneURL::setUUID(const NimBLEUUID &l_uuid) {
beaconUUID = l_uuid.getNative()->u16.value; beaconUUID = l_uuid.getNative()->u16.value;
} // setUUID } // setUUID
/**
* @brief Set the transmit power to advertise.
* @param [in] advertisedTxPower The transmit power level.
*/
void NimBLEEddystoneURL::setPower(int8_t advertisedTxPower) { void NimBLEEddystoneURL::setPower(int8_t advertisedTxPower) {
m_eddystoneData.advertisedTxPower = advertisedTxPower; m_eddystoneData.advertisedTxPower = advertisedTxPower;
} // setPower } // setPower
/**
* @brief Set the URL to advertise.
* @param [in] url The URL.
*/
void NimBLEEddystoneURL::setURL(const std::string &url) { void NimBLEEddystoneURL::setURL(const std::string &url) {
if (url.length() > sizeof(m_eddystoneData.url)) { if (url.length() > sizeof(m_eddystoneData.url)) {
NIMBLE_LOGE(LOG_TAG, "Unable to set the url ... length passed in was %d and max expected %d", NIMBLE_LOGE(LOG_TAG, "Unable to set the url ... length passed in was %d and max expected %d",

View file

@ -260,13 +260,12 @@ NimBLERemoteDescriptor* NimBLERemoteCharacteristic::getDescriptor(const NimBLEUU
/** /**
* @Get a pointer to the vector of found descriptors. * @brief Get a pointer to the vector of found descriptors.
* @param [in] bool value to indicate if the current vector should be cleared and * @param [in] refresh If true the current descriptor vector will be cleared and\n
* subsequently all descriptors for this characteristic retrieved from the peripheral. * all descriptors for this characteristic retrieved from the peripheral.\n
* If false the vector will be returned with the currently stored descriptors, * If false the vector will be returned with the currently stored descriptors
* if the vector is empty it will retrieve all descriptors for this characteristic * of this characteristic.
* from the peripheral. * @return A pointer to the vector of descriptors for this characteristic.
* @return a pointer to the vector of descriptors for this characteristic.
*/ */
std::vector<NimBLERemoteDescriptor*>* NimBLERemoteCharacteristic::getDescriptors(bool refresh) { std::vector<NimBLERemoteDescriptor*>* NimBLERemoteCharacteristic::getDescriptors(bool refresh) {
if(refresh) { if(refresh) {
@ -338,6 +337,7 @@ NimBLEUUID NimBLERemoteCharacteristic::getUUID() {
/** /**
* @brief Get the value of the remote characteristic. * @brief Get the value of the remote characteristic.
* @param [in] timestamp A pointer to a time_t struct to store the time the value was read.
* @return The value of the remote characteristic. * @return The value of the remote characteristic.
*/ */
std::string NimBLERemoteCharacteristic::getValue(time_t *timestamp) { std::string NimBLERemoteCharacteristic::getValue(time_t *timestamp) {
@ -355,6 +355,7 @@ std::string NimBLERemoteCharacteristic::getValue(time_t *timestamp) {
/** /**
* @brief Read an unsigned 16 bit value * @brief Read an unsigned 16 bit value
* @return The unsigned 16 bit value. * @return The unsigned 16 bit value.
* @deprecated Use readValue<uint16_t>().
*/ */
uint16_t NimBLERemoteCharacteristic::readUInt16() { uint16_t NimBLERemoteCharacteristic::readUInt16() {
return readValue<uint16_t>(); return readValue<uint16_t>();
@ -364,6 +365,7 @@ uint16_t NimBLERemoteCharacteristic::readUInt16() {
/** /**
* @brief Read an unsigned 32 bit value. * @brief Read an unsigned 32 bit value.
* @return the unsigned 32 bit value. * @return the unsigned 32 bit value.
* @deprecated Use readValue<uint32_t>().
*/ */
uint32_t NimBLERemoteCharacteristic::readUInt32() { uint32_t NimBLERemoteCharacteristic::readUInt32() {
return readValue<uint32_t>(); return readValue<uint32_t>();
@ -373,6 +375,7 @@ uint32_t NimBLERemoteCharacteristic::readUInt32() {
/** /**
* @brief Read a byte value * @brief Read a byte value
* @return The value as a byte * @return The value as a byte
* @deprecated Use readValue<uint8_t>().
*/ */
uint8_t NimBLERemoteCharacteristic::readUInt8() { uint8_t NimBLERemoteCharacteristic::readUInt8() {
return readValue<uint8_t>(); return readValue<uint8_t>();
@ -390,6 +393,7 @@ float NimBLERemoteCharacteristic::readFloat() {
/** /**
* @brief Read the value of the remote characteristic. * @brief Read the value of the remote characteristic.
* @param [in] timestamp A pointer to a time_t struct to store the time the value was read.
* @return The value of the remote characteristic. * @return The value of the remote characteristic.
*/ */
std::string NimBLERemoteCharacteristic::readValue(time_t *timestamp) { std::string NimBLERemoteCharacteristic::readValue(time_t *timestamp) {
@ -458,7 +462,7 @@ std::string NimBLERemoteCharacteristic::readValue(time_t *timestamp) {
/** /**
* @brief Callback for characteristic read operation. * @brief Callback for characteristic read operation.
* @return 0 or error code. * @return success == 0 or error code.
*/ */
int NimBLERemoteCharacteristic::onReadCB(uint16_t conn_handle, int NimBLERemoteCharacteristic::onReadCB(uint16_t conn_handle,
const struct ble_gatt_error *error, const struct ble_gatt_error *error,
@ -498,9 +502,10 @@ int NimBLERemoteCharacteristic::onReadCB(uint16_t conn_handle,
/** /**
* @brief Subscribe or unsubscribe for notifications or indications. * @brief Subscribe or unsubscribe for notifications or indications.
* @param [in] uint16_t val 0x00 to unsubscribe, 0x01 for notifications, 0x02 for indications. * @param [in] val 0x00 to unsubscribe, 0x01 for notifications, 0x02 for indications.
* @param [in] notifyCallback A callback to be invoked for a notification. If NULL is provided then no callback * @param [in] response If write response required set this to true.
* is performed for notifications. * @param [in] notifyCallback A callback to be invoked for a notification.
* If NULL is provided then no callback is performed.
* @return true if successful. * @return true if successful.
*/ */
bool NimBLERemoteCharacteristic::setNotify(uint16_t val, bool response, notify_callback notifyCallback) { bool NimBLERemoteCharacteristic::setNotify(uint16_t val, bool response, notify_callback notifyCallback) {
@ -522,10 +527,10 @@ bool NimBLERemoteCharacteristic::setNotify(uint16_t val, bool response, notify_c
/** /**
* @brief Subscribe for notifications or indications. * @brief Subscribe for notifications or indications.
* @param [in] bool if true, subscribe for notifications, false subscribe for indications. * @param [in] notifications If true, subscribe for notifications, false subscribe for indications.
* @param [in] bool if true, require a write response from the descriptor write operation. * @param [in] response If true, require a write response from the descriptor write operation.
* @param [in] notifyCallback A callback to be invoked for a notification. If NULL is provided then no callback * @param [in] notifyCallback A callback to be invoked for a notification.
* is performed for notifications. * If NULL is provided then no callback is performed.
* @return true if successful. * @return true if successful.
*/ */
bool NimBLERemoteCharacteristic::subscribe(bool notifications, bool response, notify_callback notifyCallback) { bool NimBLERemoteCharacteristic::subscribe(bool notifications, bool response, notify_callback notifyCallback) {
@ -539,7 +544,7 @@ bool NimBLERemoteCharacteristic::subscribe(bool notifications, bool response, no
/** /**
* @brief Unsubscribe for notifications or indications. * @brief Unsubscribe for notifications or indications.
* @param [in] bool if true, require a write response from the descriptor write operation. * @param [in] response bool if true, require a write response from the descriptor write operation.
* @return true if successful. * @return true if successful.
*/ */
bool NimBLERemoteCharacteristic::unsubscribe(bool response) { bool NimBLERemoteCharacteristic::unsubscribe(bool response) {
@ -549,11 +554,12 @@ bool NimBLERemoteCharacteristic::unsubscribe(bool response) {
/** /**
* @brief backward-compatibility method for subscribe/unsubscribe notifications/indications * @brief backward-compatibility method for subscribe/unsubscribe notifications/indications
* @param [in] notifyCallback A callback to be invoked for a notification. If NULL is provided then we are * @param [in] notifyCallback A callback to be invoked for a notification. If NULL is provided then we
* unregistering for notifications. * will unregister for notifications.
* @param [in] bool if true, register for notifications, false register for indications. * @param [in] notifications If true, register for notifications, false register for indications.
* @param [in] bool if true, require a write response from the descriptor write operation. * @param [in] response If true, require a write response from the descriptor write operation.
* @return true if successful. * @return true if successful.
* @deprecated Use subscribe() / unsubscribe() instead.
*/ */
bool NimBLERemoteCharacteristic::registerForNotify(notify_callback notifyCallback, bool notifications, bool response) { bool NimBLERemoteCharacteristic::registerForNotify(notify_callback notifyCallback, bool notifications, bool response) {
bool success; bool success;
@ -568,10 +574,9 @@ bool NimBLERemoteCharacteristic::registerForNotify(notify_callback notifyCallbac
/** /**
* @brief Delete the descriptors in the descriptor vector. * @brief Delete the descriptors in the descriptor vector.
* We maintain a vector called m_descriptorVector that contains pointers to BLERemoteDescriptors * @details We maintain a vector called m_descriptorVector that contains pointers to NimBLERemoteDescriptors
* object references. Since we allocated these in this class, we are also responsible for deleting * object references. Since we allocated these in this class, we are also responsible for deleting
* them. This method does just that. * them. This method does just that.
* @return N/A.
*/ */
void NimBLERemoteCharacteristic::deleteDescriptors() { void NimBLERemoteCharacteristic::deleteDescriptors() {
NIMBLE_LOGD(LOG_TAG, ">> deleteDescriptors"); NIMBLE_LOGD(LOG_TAG, ">> deleteDescriptors");
@ -587,7 +592,7 @@ void NimBLERemoteCharacteristic::deleteDescriptors() {
/** /**
* @brief Delete descriptor by UUID * @brief Delete descriptor by UUID
* @param [in] uuid The UUID of the descriptor to be deleted. * @param [in] uuid The UUID of the descriptor to be deleted.
* @return Number of services left. * @return Number of descriptors left in the vector.
*/ */
size_t NimBLERemoteCharacteristic::deleteDescriptor(const NimBLEUUID &uuid) { size_t NimBLERemoteCharacteristic::deleteDescriptor(const NimBLEUUID &uuid) {
NIMBLE_LOGD(LOG_TAG, ">> deleteDescriptor"); NIMBLE_LOGD(LOG_TAG, ">> deleteDescriptor");
@ -607,7 +612,7 @@ size_t NimBLERemoteCharacteristic::deleteDescriptor(const NimBLEUUID &uuid) {
/** /**
* @brief Convert a BLERemoteCharacteristic to a string representation; * @brief Convert a NimBLERemoteCharacteristic to a string representation;
* @return a String representation. * @return a String representation.
*/ */
std::string NimBLERemoteCharacteristic::toString() { std::string NimBLERemoteCharacteristic::toString() {
@ -725,7 +730,7 @@ bool NimBLERemoteCharacteristic::writeValue(const uint8_t* data, size_t length,
/** /**
* @brief Callback for characteristic write operation. * @brief Callback for characteristic write operation.
* @return 0 or error code. * @return success == 0 or error code.
*/ */
int NimBLERemoteCharacteristic::onWriteCB(uint16_t conn_handle, int NimBLERemoteCharacteristic::onWriteCB(uint16_t conn_handle,
const struct ble_gatt_error *error, const struct ble_gatt_error *error,

View file

@ -63,6 +63,15 @@ public:
NimBLEUUID getUUID(); NimBLEUUID getUUID();
std::string readValue(time_t *timestamp = nullptr); std::string readValue(time_t *timestamp = nullptr);
/**
* @brief A template to convert the remote characteristic data to <type\>.
* @tparam T The type to convert the data to.
* @param [in] timestamp A pointer to a time_t struct to store the time the value was read.
* @param [in] skipSizeCheck If true it will skip checking if the data size is less than <tt>sizeof(<type\>)</tt>.
* @return The data converted to <type\> or NULL if skipSizeCheck is false and the data is
* less than <tt>sizeof(<type\>)</tt>.
* @details <b>Use:</b> <tt>readValue<type>(&timestamp, skipSizeCheck);</tt>
*/
template<typename T> template<typename T>
T readValue(time_t *timestamp = nullptr, bool skipSizeCheck = false) { T readValue(time_t *timestamp = nullptr, bool skipSizeCheck = false) {
std::string value = readValue(timestamp); std::string value = readValue(timestamp);
@ -77,6 +86,15 @@ public:
float readFloat() __attribute__ ((deprecated("Use template readValue<float>()"))); float readFloat() __attribute__ ((deprecated("Use template readValue<float>()")));
std::string getValue(time_t *timestamp = nullptr); std::string getValue(time_t *timestamp = nullptr);
/**
* @brief A template to convert the remote characteristic data to <type\>.
* @tparam T The type to convert the data to.
* @param [in] timestamp A pointer to a time_t struct to store the time the value was read.
* @param [in] skipSizeCheck If true it will skip checking if the data size is less than <tt>sizeof(<type\>)</tt>.
* @return The data converted to <type\> or NULL if skipSizeCheck is false and the data is
* less than <tt>sizeof(<type\>)</tt>.
* @details <b>Use:</b> <tt>getValue<type>(&timestamp, skipSizeCheck);</tt>
*/
template<typename T> template<typename T>
T getValue(time_t *timestamp = nullptr, bool skipSizeCheck = false) { T getValue(time_t *timestamp = nullptr, bool skipSizeCheck = false) {
std::string value = getValue(timestamp); std::string value = getValue(timestamp);
@ -98,6 +116,11 @@ public:
bool response = false); bool response = false);
bool writeValue(const std::string &newValue, bool writeValue(const std::string &newValue,
bool response = false); bool response = false);
/**
* @brief Convenience template to set the remote characteristic value to <type\>val.
* @param [in] s The value to write.
* @param [in] response True == request write response.
*/
template<typename T> template<typename T>
bool writeValue(const T &s, bool response = false) { bool writeValue(const T &s, bool response = false) {
return writeValue((uint8_t*)&s, sizeof(T), response); return writeValue((uint8_t*)&s, sizeof(T), response);

View file

@ -25,8 +25,8 @@ static const char* LOG_TAG = "NimBLERemoteDescriptor";
/** /**
* @brief Remote descriptor constructor. * @brief Remote descriptor constructor.
* @param [in] Reference to the Characteristic that this belongs to. * @param [in] pRemoteCharacteristic A pointer to the Characteristic that this belongs to.
* @param [in] Reference to the struct that contains the descriptor information. * @param [in] dsc A pointer to the struct that contains the descriptor information.
*/ */
NimBLERemoteDescriptor::NimBLERemoteDescriptor(NimBLERemoteCharacteristic* pRemoteCharacteristic, NimBLERemoteDescriptor::NimBLERemoteDescriptor(NimBLERemoteCharacteristic* pRemoteCharacteristic,
const struct ble_gatt_dsc *dsc) const struct ble_gatt_dsc *dsc)
@ -78,6 +78,11 @@ NimBLEUUID NimBLERemoteDescriptor::getUUID() {
} // getUUID } // getUUID
/**
* @brief Read a byte value
* @return The value as a byte
* @deprecated Use readValue<uint8_t>().
*/
uint8_t NimBLERemoteDescriptor::readUInt8() { uint8_t NimBLERemoteDescriptor::readUInt8() {
std::string value = readValue(); std::string value = readValue();
if (value.length() >= 1) { if (value.length() >= 1) {
@ -87,6 +92,11 @@ uint8_t NimBLERemoteDescriptor::readUInt8() {
} // readUInt8 } // readUInt8
/**
* @brief Read an unsigned 16 bit value
* @return The unsigned 16 bit value.
* @deprecated Use readValue<uint16_t>().
*/
uint16_t NimBLERemoteDescriptor::readUInt16() { uint16_t NimBLERemoteDescriptor::readUInt16() {
std::string value = readValue(); std::string value = readValue();
if (value.length() >= 2) { if (value.length() >= 2) {
@ -96,6 +106,11 @@ uint16_t NimBLERemoteDescriptor::readUInt16() {
} // readUInt16 } // readUInt16
/**
* @brief Read an unsigned 32 bit value.
* @return the unsigned 32 bit value.
* @deprecated Use readValue<uint32_t>().
*/
uint32_t NimBLERemoteDescriptor::readUInt32() { uint32_t NimBLERemoteDescriptor::readUInt32() {
std::string value = readValue(); std::string value = readValue();
if (value.length() >= 4) { if (value.length() >= 4) {
@ -105,6 +120,10 @@ uint32_t NimBLERemoteDescriptor::readUInt32() {
} // readUInt32 } // readUInt32
/**
* @brief Read the value of the remote descriptor.
* @return The value of the remote descriptor.
*/
std::string NimBLERemoteDescriptor::readValue() { std::string NimBLERemoteDescriptor::readValue() {
NIMBLE_LOGD(LOG_TAG, ">> Descriptor readValue: %s", toString().c_str()); NIMBLE_LOGD(LOG_TAG, ">> Descriptor readValue: %s", toString().c_str());
@ -161,7 +180,7 @@ std::string NimBLERemoteDescriptor::readValue() {
/** /**
* @brief Callback for Descriptor read operation. * @brief Callback for Descriptor read operation.
* @return 0 or error code. * @return success == 0 or error code.
*/ */
int NimBLERemoteDescriptor::onReadCB(uint16_t conn_handle, int NimBLERemoteDescriptor::onReadCB(uint16_t conn_handle,
const struct ble_gatt_error *error, const struct ble_gatt_error *error,
@ -200,8 +219,8 @@ int NimBLERemoteDescriptor::onReadCB(uint16_t conn_handle,
/** /**
* @brief Return a string representation of this BLE Remote Descriptor. * @brief Return a string representation of this Remote Descriptor.
* @retun A string representation of this BLE Remote Descriptor. * @return A string representation of this Remote Descriptor.
*/ */
std::string NimBLERemoteDescriptor::toString() { std::string NimBLERemoteDescriptor::toString() {
std::string res = "Descriptor: uuid: " + getUUID().toString(); std::string res = "Descriptor: uuid: " + getUUID().toString();
@ -216,7 +235,7 @@ std::string NimBLERemoteDescriptor::toString() {
/** /**
* @brief Callback for descriptor write operation. * @brief Callback for descriptor write operation.
* @return 0 or error code. * @return success == 0 or error code.
*/ */
int NimBLERemoteDescriptor::onWriteCB(uint16_t conn_handle, int NimBLERemoteDescriptor::onWriteCB(uint16_t conn_handle,
const struct ble_gatt_error *error, const struct ble_gatt_error *error,
@ -242,7 +261,8 @@ int NimBLERemoteDescriptor::onWriteCB(uint16_t conn_handle,
* @brief Write data to the BLE Remote Descriptor. * @brief Write data to the BLE Remote Descriptor.
* @param [in] data The data to send to the remote descriptor. * @param [in] data The data to send to the remote descriptor.
* @param [in] length The length of the data to send. * @param [in] length The length of the data to send.
* @param [in] response True if we expect a response. * @param [in] response True if we expect a write response.
* @return True if successful
*/ */
bool NimBLERemoteDescriptor::writeValue(const uint8_t* data, size_t length, bool response) { bool NimBLERemoteDescriptor::writeValue(const uint8_t* data, size_t length, bool response) {
@ -322,11 +342,11 @@ bool NimBLERemoteDescriptor::writeValue(const uint8_t* data, size_t length, bool
* @brief Write data represented as a string to the BLE Remote Descriptor. * @brief Write data represented as a string to the BLE Remote Descriptor.
* @param [in] newValue The data to send to the remote descriptor. * @param [in] newValue The data to send to the remote descriptor.
* @param [in] response True if we expect a response. * @param [in] response True if we expect a response.
* @return True if successful
*/ */
bool NimBLERemoteDescriptor::writeValue(const std::string &newValue, bool response) { bool NimBLERemoteDescriptor::writeValue(const std::string &newValue, bool response) {
return writeValue((uint8_t*) newValue.data(), newValue.length(), response); return writeValue((uint8_t*) newValue.data(), newValue.length(), response);
} // writeValue } // writeValue
#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) #endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
#endif /* CONFIG_BT_ENABLED */ #endif /* CONFIG_BT_ENABLED */

View file

@ -33,6 +33,14 @@ public:
NimBLEUUID getUUID(); NimBLEUUID getUUID();
std::string readValue(); std::string readValue();
/**
* @brief A template to convert the remote descriptor data to <type\>.
* @tparam T The type to convert the data to.
* @param [in] skipSizeCheck If true it will skip checking if the data size is less than <tt>sizeof(<type\>)</tt>.
* @return The data converted to <type\> or NULL if skipSizeCheck is false and the data is
* less than <tt>sizeof(<type\>)</tt>.
* @details <b>Use:</b> <tt>readValue<type>(skipSizeCheck);</tt>
*/
template<typename T> template<typename T>
T readValue(bool skipSizeCheck = false) { T readValue(bool skipSizeCheck = false) {
std::string value = readValue(); std::string value = readValue();
@ -41,12 +49,18 @@ public:
return *((T *)pData); return *((T *)pData);
} }
uint8_t readUInt8() __attribute__ ((deprecated)); uint8_t readUInt8() __attribute__ ((deprecated("Use template readValue<uint8_t>()")));
uint16_t readUInt16() __attribute__ ((deprecated)); uint16_t readUInt16() __attribute__ ((deprecated("Use template readValue<uint16_t>()")));
uint32_t readUInt32() __attribute__ ((deprecated)); uint32_t readUInt32() __attribute__ ((deprecated("Use template readValue<uint32_t>()")));
std::string toString(void); std::string toString(void);
bool writeValue(const uint8_t* data, size_t length, bool response = false); bool writeValue(const uint8_t* data, size_t length, bool response = false);
bool writeValue(const std::string &newValue, bool response = false); bool writeValue(const std::string &newValue, bool response = false);
/**
* @brief Convenience template to set the remote descriptor value to <type\>val.
* @param [in] s The value to write.
* @param [in] response True == request write response.
*/
template<typename T> template<typename T>
bool writeValue(const T &s, bool response = false) { bool writeValue(const T &s, bool response = false) {
return writeValue((uint8_t*)&s, sizeof(T), response); return writeValue((uint8_t*)&s, sizeof(T), response);

View file

@ -26,8 +26,8 @@ static const char* LOG_TAG = "NimBLERemoteService";
/** /**
* @brief Remote Service constructor. * @brief Remote Service constructor.
* @param [in] Reference to the client this belongs to. * @param [in] pClient A pointer to the client this belongs to.
* @param [in] Refernce to the structure with the services' information. * @param [in] service A pointer to the structure with the service information.
*/ */
NimBLERemoteService::NimBLERemoteService(NimBLEClient* pClient, const struct ble_gatt_svc* service) { NimBLERemoteService::NimBLERemoteService(NimBLEClient* pClient, const struct ble_gatt_svc* service) {
@ -55,7 +55,6 @@ NimBLERemoteService::NimBLERemoteService(NimBLEClient* pClient, const struct ble
/** /**
* @brief When deleting the service make sure we delete all characteristics and descriptors. * @brief When deleting the service make sure we delete all characteristics and descriptors.
* Also release any semaphores they may be holding.
*/ */
NimBLERemoteService::~NimBLERemoteService() { NimBLERemoteService::~NimBLERemoteService() {
deleteCharacteristics(); deleteCharacteristics();
@ -83,7 +82,7 @@ std::vector<NimBLERemoteCharacteristic*>::iterator NimBLERemoteService::end() {
/** /**
* @brief Get the remote characteristic object for the characteristic UUID. * @brief Get the remote characteristic object for the characteristic UUID.
* @param [in] uuid Remote characteristic uuid. * @param [in] uuid Remote characteristic uuid.
* @return Reference to the remote characteristic object. * @return A pointer to the remote characteristic object.
*/ */
NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const char* uuid) { NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const char* uuid) {
return getCharacteristic(NimBLEUUID(uuid)); return getCharacteristic(NimBLEUUID(uuid));
@ -93,7 +92,7 @@ NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const char* u
/** /**
* @brief Get the characteristic object for the UUID. * @brief Get the characteristic object for the UUID.
* @param [in] uuid Characteristic uuid. * @param [in] uuid Characteristic uuid.
* @return Reference to the characteristic object, or nullptr if not found. * @return A pointer to the characteristic object, or nullptr if not found.
*/ */
NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const NimBLEUUID &uuid) { NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const NimBLEUUID &uuid) {
for(auto &it: m_characteristicVector) { for(auto &it: m_characteristicVector) {
@ -114,15 +113,12 @@ NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const NimBLEU
/** /**
* @Get a pointer to the vector of found characteristics. * @brief Get a pointer to the vector of found characteristics.
* @param [in] bool value to indicate if the current vector should be cleared and * @param [in] refresh If true the current characteristics vector will cleared and
* subsequently all characteristics for this service retrieved from the peripheral. * all characteristics for this service retrieved from the peripheral.
* If false the vector will be returned with the currently stored characteristics, * If false the vector will be returned with the currently stored characteristics of this service.
* If true it will retrieve all characteristics of this service from the peripheral * @return A pointer to the vector of descriptors for this characteristic.
* and return the vector with all characteristics for this service.
* @return a pointer to the vector of descriptors for this characteristic.
*/ */
std::vector<NimBLERemoteCharacteristic*>* NimBLERemoteService::getCharacteristics(bool refresh) { std::vector<NimBLERemoteCharacteristic*>* NimBLERemoteService::getCharacteristics(bool refresh) {
if(refresh) { if(refresh) {
deleteCharacteristics(); deleteCharacteristics();
@ -140,6 +136,7 @@ std::vector<NimBLERemoteCharacteristic*>* NimBLERemoteService::getCharacteristic
/** /**
* @brief Callback for Characterisic discovery. * @brief Callback for Characterisic discovery.
* @return success == 0 or error code.
*/ */
int NimBLERemoteService::characteristicDiscCB(uint16_t conn_handle, int NimBLERemoteService::characteristicDiscCB(uint16_t conn_handle,
const struct ble_gatt_error *error, const struct ble_gatt_error *error,
@ -182,7 +179,7 @@ int NimBLERemoteService::characteristicDiscCB(uint16_t conn_handle,
/** /**
* @brief Retrieve all the characteristics for this service. * @brief Retrieve all the characteristics for this service.
* This function will not return until we have all the characteristics. * This function will not return until we have all the characteristics.
* @return N/A * @return True if successful.
*/ */
bool NimBLERemoteService::retrieveCharacteristics(const NimBLEUUID *uuid_filter) { bool NimBLERemoteService::retrieveCharacteristics(const NimBLEUUID *uuid_filter) {
NIMBLE_LOGD(LOG_TAG, ">> retrieveCharacteristics() for service: %s", getUUID().toString().c_str()); NIMBLE_LOGD(LOG_TAG, ">> retrieveCharacteristics() for service: %s", getUUID().toString().c_str());
@ -299,10 +296,9 @@ bool NimBLERemoteService::setValue(const NimBLEUUID &characteristicUuid, const s
/** /**
* @brief Delete the characteristics in the characteristics vector. * @brief Delete the characteristics in the characteristics vector.
* We maintain a vector called m_characteristicsVector that contains pointers to BLERemoteCharacteristic * @details We maintain a vector called m_characteristicsVector that contains pointers to BLERemoteCharacteristic
* object references. Since we allocated these in this class, we are also responsible for deleting * object references. Since we allocated these in this class, we are also responsible for deleting
* them. This method does just that. * them. This method does just that.
* @return N/A.
*/ */
void NimBLERemoteService::deleteCharacteristics() { void NimBLERemoteService::deleteCharacteristics() {
NIMBLE_LOGD(LOG_TAG, ">> deleteCharacteristics"); NIMBLE_LOGD(LOG_TAG, ">> deleteCharacteristics");
@ -316,7 +312,7 @@ void NimBLERemoteService::deleteCharacteristics() {
/** /**
* @brief Delete characteristic by UUID * @brief Delete characteristic by UUID
* @param [in] uuid The UUID of the characteristic to be cleared. * @param [in] uuid The UUID of the characteristic to be removed from the local database.
* @return Number of characteristics left. * @return Number of characteristics left.
*/ */
size_t NimBLERemoteService::deleteCharacteristic(const NimBLEUUID &uuid) { size_t NimBLERemoteService::deleteCharacteristic(const NimBLEUUID &uuid) {

View file

@ -45,7 +45,7 @@ public:
void deleteCharacteristics(); void deleteCharacteristics();
size_t deleteCharacteristic(const NimBLEUUID &uuid); size_t deleteCharacteristic(const NimBLEUUID &uuid);
NimBLEClient* getClient(void); NimBLEClient* getClient(void);
uint16_t getHandle(); //uint16_t getHandle();
NimBLEUUID getUUID(void); NimBLEUUID getUUID(void);
std::string getValue(const NimBLEUUID &characteristicUuid); std::string getValue(const NimBLEUUID &characteristicUuid);
bool setValue(const NimBLEUUID &characteristicUuid, bool setValue(const NimBLEUUID &characteristicUuid,

View file

@ -151,7 +151,6 @@ NimBLEScan::NimBLEScan() {
* @brief Should we perform an active or passive scan? * @brief Should we perform an active or passive scan?
* The default is a passive scan. An active scan means that we will wish a scan response. * The default is a passive scan. An active scan means that we will wish a scan response.
* @param [in] active If true, we perform an active scan otherwise a passive scan. * @param [in] active If true, we perform an active scan otherwise a passive scan.
* @return N/A.
*/ */
void NimBLEScan::setActiveScan(bool active) { void NimBLEScan::setActiveScan(bool active) {
if (active) { if (active) {
@ -187,18 +186,18 @@ void NimBLEScan::setLimitedOnly(bool active) {
/** /**
* @brief Sets the scan filter policy. * @brief Sets the scan filter policy.
* @param [in] filter Can be one of: * @param [in] filter Can be one of:
* BLE_HCI_SCAN_FILT_NO_WL (0) * * BLE_HCI_SCAN_FILT_NO_WL (0)
* Scanner processes all advertising packets (white list not used) except * Scanner processes all advertising packets (white list not used) except\n
* directed, connectable advertising packets not sent to the scanner. * directed, connectable advertising packets not sent to the scanner.
* BLE_HCI_SCAN_FILT_USE_WL (1) * * BLE_HCI_SCAN_FILT_USE_WL (1)
* Scanner processes advertisements from white list only. A connectable, * Scanner processes advertisements from white list only. A connectable,\n
* directed advertisment is ignored unless it contains scanners address. * directed advertisment is ignored unless it contains scanners address.
* BLE_HCI_SCAN_FILT_NO_WL_INITA (2) * * BLE_HCI_SCAN_FILT_NO_WL_INITA (2)
* Scanner process all advertising packets (white list not used). A * Scanner process all advertising packets (white list not used). A\n
* connectable, directed advertisement shall not be ignored if the InitA * connectable, directed advertisement shall not be ignored if the InitA
* is a resolvable private address. * is a resolvable private address.
* BLE_HCI_SCAN_FILT_USE_WL_INITA (3) * * BLE_HCI_SCAN_FILT_USE_WL_INITA (3)
* Scanner process advertisements from white list only. A connectable, * Scanner process advertisements from white list only. A connectable,\n
* directed advertisement shall not be ignored if the InitA is a * directed advertisement shall not be ignored if the InitA is a
* resolvable private address. * resolvable private address.
*/ */
@ -221,7 +220,7 @@ void NimBLEScan::setAdvertisedDeviceCallbacks(NimBLEAdvertisedDeviceCallbacks* p
/** /**
* @brief Set the interval to scan. * @brief Set the interval to scan.
* @param [in] The interval in msecs. * @param [in] intervalMSecs The scan interval (how often) in milliseconds.
*/ */
void NimBLEScan::setInterval(uint16_t intervalMSecs) { void NimBLEScan::setInterval(uint16_t intervalMSecs) {
m_scan_params.itvl = intervalMSecs / 0.625; m_scan_params.itvl = intervalMSecs / 0.625;
@ -241,7 +240,7 @@ void NimBLEScan::setWindow(uint16_t windowMSecs) {
* @brief Start scanning. * @brief Start scanning.
* @param [in] duration The duration in seconds for which to scan. * @param [in] duration The duration in seconds for which to scan.
* @param [in] scanCompleteCB A function to be called when scanning has completed. * @param [in] scanCompleteCB A function to be called when scanning has completed.
* @param [in] are we continue scan (true) or we want to clear stored devices (false) * @param [in] is_continue Set to true to save previous scan results, false to clear them.
* @return True if scan started or false if there was an error. * @return True if scan started or false if there was an error.
*/ */
bool NimBLEScan::start(uint32_t duration, void (*scanCompleteCB)(NimBLEScanResults), bool is_continue) { bool NimBLEScan::start(uint32_t duration, void (*scanCompleteCB)(NimBLEScanResults), bool is_continue) {
@ -309,7 +308,8 @@ bool NimBLEScan::start(uint32_t duration, void (*scanCompleteCB)(NimBLEScanResul
/** /**
* @brief Start scanning and block until scanning has been completed. * @brief Start scanning and block until scanning has been completed.
* @param [in] duration The duration in seconds for which to scan. * @param [in] duration The duration in seconds for which to scan.
* @return The BLEScanResults. * @param [in] is_continue Set to true to save previous scan results, false to clear them.
* @return The NimBLEScanResults.
*/ */
NimBLEScanResults NimBLEScan::start(uint32_t duration, bool is_continue) { NimBLEScanResults NimBLEScan::start(uint32_t duration, bool is_continue) {
if(duration == 0) { if(duration == 0) {
@ -330,7 +330,7 @@ NimBLEScanResults NimBLEScan::start(uint32_t duration, bool is_continue) {
/** /**
* @brief Stop an in progress scan. * @brief Stop an in progress scan.
* @return N/A. * @return True if successful.
*/ */
bool NimBLEScan::stop() { bool NimBLEScan::stop() {
NIMBLE_LOGD(LOG_TAG, ">> stop()"); NIMBLE_LOGD(LOG_TAG, ">> stop()");
@ -356,7 +356,11 @@ bool NimBLEScan::stop() {
} // stop } // stop
// delete peer device from cache after disconnecting, it is required in case we are connecting to devices with not public address /**
* @brief Delete peer device from the scan results vector.
* @param [in] address The address of the device to delete from the results.
* @details After disconnecting, it may be required in the case we were connected to a device without a public address.
*/
void NimBLEScan::erase(const NimBLEAddress &address) { void NimBLEScan::erase(const NimBLEAddress &address) {
NIMBLE_LOGI(LOG_TAG, "erase device: %s", address.toString().c_str()); NIMBLE_LOGI(LOG_TAG, "erase device: %s", address.toString().c_str());
@ -371,8 +375,7 @@ void NimBLEScan::erase(const NimBLEAddress &address) {
/** /**
* @brief If the host reset the scan will have stopped so we should flag it and release the semaphore. * @brief If the host reset the scan will have stopped so we should set the flag as stopped.
* @return N/A.
*/ */
void NimBLEScan::onHostReset() { void NimBLEScan::onHostReset() {
m_stopped = true; m_stopped = true;
@ -411,7 +414,7 @@ void NimBLEScanResults::dump() {
/** /**
* @brief Return the count of devices found in the last scan. * @brief Get the count of devices found in the last scan.
* @return The number of devices found in the last scan. * @return The number of devices found in the last scan.
*/ */
int NimBLEScanResults::getCount() { int NimBLEScanResults::getCount() {
@ -449,7 +452,7 @@ std::vector<NimBLEAdvertisedDevice*>::iterator NimBLEScanResults::end() {
/** /**
* @brief Return a pointer to the specified device at the given address. * @brief Get a pointer to the specified device at the given address.
* If the address is not found a nullptr is returned. * If the address is not found a nullptr is returned.
* @param [in] address The address of the device. * @param [in] address The address of the device.
* @return A pointer to the device at the specified address. * @return A pointer to the device at the specified address.

View file

@ -33,9 +33,9 @@ class NimBLEAdvertisedDeviceCallbacks;
class NimBLEAddress; class NimBLEAddress;
/** /**
* @brief The result of having performed a scan. * @brief A class that contains and operates on the results of a BLE scan.
* When a scan completes, we have a set of found devices. Each device is described * @details When a scan completes, we have a set of found devices. Each device is described
* by a BLEAdvertisedDevice object. The number of items in the set is given by * by a NimBLEAdvertisedDevice object. The number of items in the set is given by
* getCount(). We can retrieve a device by calling getDevice() passing in the * getCount(). We can retrieve a device by calling getDevice() passing in the
* index (starting at 0) of the desired device. * index (starting at 0) of the desired device.
*/ */

View file

@ -18,12 +18,6 @@
#include "NimBLESecurity.h" #include "NimBLESecurity.h"
#include "NimBLEDevice.h" #include "NimBLEDevice.h"
/**
* @brief This class is for backward compatibility with the bluedroid based library.
* Use the new security functions in NimBLEDevice instead.
* New callback functions in NimBLEServer and NimBLEClient.
*/
NimBLESecurity::NimBLESecurity() { NimBLESecurity::NimBLESecurity() {
} }
@ -33,6 +27,15 @@ NimBLESecurity::~NimBLESecurity() {
/** /**
* @brief Set requested authentication mode * @brief Set requested authentication mode
* @param [in] auth_req A bitmask containing one or more of:
* * ESP_LE_AUTH_NO_BOND 0x00
* * ESP_LE_AUTH_BOND 0x01
* * ESP_LE_AUTH_REQ_MITM (1 << 2)
* * ESP_LE_AUTH_REQ_BOND_MITM (ESP_LE_AUTH_BOND | ESP_LE_AUTH_REQ_MITM)
* * ESP_LE_AUTH_REQ_SC_ONLY (1 << 3)
* * ESP_LE_AUTH_REQ_SC_BOND (ESP_LE_AUTH_BOND | ESP_LE_AUTH_REQ_SC_ONLY)
* * ESP_LE_AUTH_REQ_SC_MITM (ESP_LE_AUTH_REQ_MITM | ESP_LE_AUTH_REQ_SC_ONLY)
* * ESP_LE_AUTH_REQ_SC_MITM_BOND (ESP_LE_AUTH_REQ_MITM | ESP_LE_AUTH_REQ_SC_ONLY | ESP_LE_AUTH_BOND)
*/ */
void NimBLESecurity::setAuthenticationMode(esp_ble_auth_req_t auth_req) { void NimBLESecurity::setAuthenticationMode(esp_ble_auth_req_t auth_req) {
NimBLEDevice::setSecurityAuth((auth_req & BLE_SM_PAIR_AUTHREQ_BOND)>0, NimBLEDevice::setSecurityAuth((auth_req & BLE_SM_PAIR_AUTHREQ_BOND)>0,
@ -42,8 +45,15 @@ void NimBLESecurity::setAuthenticationMode(esp_ble_auth_req_t auth_req) {
/** /**
* @brief Set our device IO capability to let end user perform authorization * @brief Set our device IO capability to let end user perform authorization
* either by displaying or entering generated 6-digits pin code * either by displaying or entering generated 6-digit pin code or use \"just works\".
* @param [in] iocap The IO capabilites our device has.\n
* Can be set to one of:
* * ESP_IO_CAP_OUT 0
* * ESP_IO_CAP_IO 1
* * ESP_IO_CAP_IN 2
* * ESP_IO_CAP_NONE 3
* * ESP_IO_CAP_KBDISP 4
*/ */
void NimBLESecurity::setCapability(esp_ble_io_cap_t iocap) { void NimBLESecurity::setCapability(esp_ble_io_cap_t iocap) {
NimBLEDevice::setSecurityIOCap(iocap); NimBLEDevice::setSecurityIOCap(iocap);
@ -51,8 +61,13 @@ void NimBLESecurity::setCapability(esp_ble_io_cap_t iocap) {
/** /**
* @brief Init encryption key by server * @brief Sets the keys we will distibute during encryption.
* @param key_size is value between 7 and 16 * @param [in] init_key A bitmask of the keys we will distibute.\n
* Can be one or more of:
* * ESP_BLE_ENC_KEY_MASK (1 << 0)
* * ESP_BLE_ID_KEY_MASK (1 << 1)
* * ESP_BLE_CSR_KEY_MASK (1 << 2)
* * ESP_BLE_LINK_KEY_MASK (1 << 3)
*/ */
void NimBLESecurity::setInitEncryptionKey(uint8_t init_key) { void NimBLESecurity::setInitEncryptionKey(uint8_t init_key) {
NimBLEDevice::setSecurityInitKey(init_key); NimBLEDevice::setSecurityInitKey(init_key);
@ -60,8 +75,13 @@ void NimBLESecurity::setInitEncryptionKey(uint8_t init_key) {
/** /**
* @brief Init encryption key by client * @brief Sets the keys we will accept during encryption.
* @param key_size is value between 7 and 16 * @param [in] resp_key A bitmask of the keys we will accept.\n
* Can be one or more of:
* * ESP_BLE_ENC_KEY_MASK (1 << 0)
* * ESP_BLE_ID_KEY_MASK (1 << 1)
* * ESP_BLE_CSR_KEY_MASK (1 << 2)
* * ESP_BLE_LINK_KEY_MASK (1 << 3)
*/ */
void NimBLESecurity::setRespEncryptionKey(uint8_t resp_key) { void NimBLESecurity::setRespEncryptionKey(uint8_t resp_key) {
NimBLEDevice::setSecurityRespKey(resp_key); NimBLEDevice::setSecurityRespKey(resp_key);
@ -70,7 +90,6 @@ void NimBLESecurity::setRespEncryptionKey(uint8_t resp_key) {
/** /**
*@todo Requires implementation *@todo Requires implementation
*
*/ */
void NimBLESecurity::setKeySize(uint8_t key_size) { void NimBLESecurity::setKeySize(uint8_t key_size) {
@ -80,7 +99,8 @@ void NimBLESecurity::setKeySize(uint8_t key_size) {
/** /**
* Setup for static PIN connection. * @brief Sets a static PIN used to authenticate/encrypt the connection.
* @param [in] pin The 6 digit pin code to accept.
*/ */
void NimBLESecurity::setStaticPIN(uint32_t pin){ void NimBLESecurity::setStaticPIN(uint32_t pin){
//uint32_t passkey = pin; //uint32_t passkey = pin;

View file

@ -12,10 +12,6 @@
* Author: chegewara * Author: chegewara
*/ */
/** This class exists for backward compatibility - Should not be used in new code
* See the security functions in NimBLEDevice and callbacks in NimBLEServer / NimBLEClient
*/
#ifndef COMPONENTS_NIMBLESECURITY_H_ #ifndef COMPONENTS_NIMBLESECURITY_H_
#define COMPONENTS_NIMBLESECURITY_H_ #define COMPONENTS_NIMBLESECURITY_H_
#include "sdkconfig.h" #include "sdkconfig.h"
@ -56,6 +52,12 @@
typedef uint8_t esp_ble_auth_req_t; /*!< combination of the above bit pattern */ typedef uint8_t esp_ble_auth_req_t; /*!< combination of the above bit pattern */
typedef uint8_t esp_ble_io_cap_t; /*!< combination of the io capability */ typedef uint8_t esp_ble_io_cap_t; /*!< combination of the io capability */
/**
* @brief A class to handle BLE security operations.
* <b>Deprecated - provided for backward compatibility only.</b>
* @deprecated Use the security methods provided in NimBLEDevice instead.
*/
class NimBLESecurity { class NimBLESecurity {
public: public:
NimBLESecurity(); NimBLESecurity();
@ -78,8 +80,10 @@ private:
}; // BLESecurity }; // BLESecurity
/* /**
* @brief Callbacks to handle GAP events related to authorization * @brief Callbacks to handle GAP events related to authorization.
* <b>Deprecated - provided for backward compatibility only.</b>
* @deprecated Use the callbacks provided in NimBLEClientCallbacks and NimBLEServerCallbacks instead.
*/ */
class NimBLESecurityCallbacks { class NimBLESecurityCallbacks {
public: public:
@ -95,21 +99,25 @@ public:
/** /**
* @brief Provide us 6-digits code to perform authentication. * @brief Provide us 6-digits code to perform authentication.
* It requires that our device is capable to display this code to end user * It requires that our device is capable to display this code to end user
* @param * @param [in] pass_key The PIN provided by the peer.
*/ */
virtual void onPassKeyNotify(uint32_t pass_key) = 0; virtual void onPassKeyNotify(uint32_t pass_key) = 0;
/** /**
* @brief Here we can make decision if we want to let negotiate authorization with peer device or not * @brief Here we can make decision if we want to let negotiate authorization with peer device or not
* return Return true if we accept this peer device request * @return Return true if we accept this peer device request
*/ */
virtual bool onSecurityRequest() = 0 ; virtual bool onSecurityRequest() = 0 ;
/** /**
* Provide us information when authentication process is completed * @brief Provides us information when authentication process is completed
*/ */
virtual void onAuthenticationComplete(ble_gap_conn_desc*) = 0; virtual void onAuthenticationComplete(ble_gap_conn_desc*) = 0;
/**
* @brief Called when using numeric comparison for authentication.
* @param [in] pin The PIN to compare.
* @return True to accept and pair.
*/
virtual bool onConfirmPIN(uint32_t pin) = 0; virtual bool onConfirmPIN(uint32_t pin) = 0;
}; // BLESecurityCallbacks }; // BLESecurityCallbacks

View file

@ -168,8 +168,8 @@ void NimBLEServer::start() {
/** /**
* @brief Disconnect the specified client with optional reason. * @brief Disconnect the specified client with optional reason.
* @param [in] Connection Id of the client to disconnect. * @param [in] connId Connection Id of the client to disconnect.
* @param [in] Reason code for disconnecting. * @param [in] reason code for disconnecting.
* @return NimBLE host return code. * @return NimBLE host return code.
*/ */
int NimBLEServer::disconnect(uint16_t connId, uint8_t reason) { int NimBLEServer::disconnect(uint16_t connId, uint8_t reason) {
@ -188,7 +188,7 @@ int NimBLEServer::disconnect(uint16_t connId, uint8_t reason) {
/** /**
* @brief Set the server to automatically start advertising when a client disconnects. * @brief Set the server to automatically start advertising when a client disconnects.
* @param [in] bool true == advertise, false == don't advertise. * @param [in] aod true == advertise, false == don't advertise.
*/ */
void NimBLEServer::advertiseOnDisconnect(bool aod) { void NimBLEServer::advertiseOnDisconnect(bool aod) {
m_advertiseOnDisconnect = aod; m_advertiseOnDisconnect = aod;
@ -516,7 +516,7 @@ uint32_t NimBLEServerCallbacks::onPassKeyRequest(){
NIMBLE_LOGD("NimBLEServerCallbacks", "onPassKeyRequest: default: 123456"); NIMBLE_LOGD("NimBLEServerCallbacks", "onPassKeyRequest: default: 123456");
return 123456; return 123456;
} }
/*
void NimBLEServerCallbacks::onPassKeyNotify(uint32_t pass_key){ void NimBLEServerCallbacks::onPassKeyNotify(uint32_t pass_key){
NIMBLE_LOGD("NimBLEServerCallbacks", "onPassKeyNotify: default: %d", pass_key); NIMBLE_LOGD("NimBLEServerCallbacks", "onPassKeyNotify: default: %d", pass_key);
} }
@ -525,6 +525,7 @@ bool NimBLEServerCallbacks::onSecurityRequest(){
NIMBLE_LOGD("NimBLEServerCallbacks", "onSecurityRequest: default: true"); NIMBLE_LOGD("NimBLEServerCallbacks", "onSecurityRequest: default: true");
return true; return true;
} }
*/
void NimBLEServerCallbacks::onAuthenticationComplete(ble_gap_conn_desc*){ void NimBLEServerCallbacks::onAuthenticationComplete(ble_gap_conn_desc*){
NIMBLE_LOGD("NimBLEServerCallbacks", "onAuthenticationComplete: default"); NIMBLE_LOGD("NimBLEServerCallbacks", "onAuthenticationComplete: default");
} }

View file

@ -54,7 +54,7 @@ public:
uint16_t minInterval, uint16_t maxInterval, uint16_t minInterval, uint16_t maxInterval,
uint16_t latency, uint16_t timeout); uint16_t latency, uint16_t timeout);
uint16_t getPeerMTU(uint16_t conn_id); uint16_t getPeerMTU(uint16_t conn_id);
std::vector<uint16_t> getPeerDevices(); // std::vector<uint16_t> getPeerDevices();
void advertiseOnDisconnect(bool); void advertiseOnDisconnect(bool);
private: private:
@ -83,29 +83,52 @@ private:
class NimBLEServerCallbacks { class NimBLEServerCallbacks {
public: public:
virtual ~NimBLEServerCallbacks() {}; virtual ~NimBLEServerCallbacks() {};
/** /**
* @brief Handle a new client connection. * @brief Handle a client connection.
* * This is called when a client connects.
* When a new client connects, we are invoked. * @param [in] pServer A pointer to the %BLE server that received the client connection.
*
* @param [in] pServer A reference to the %BLE server that received the client connection.
*/ */
virtual void onConnect(NimBLEServer* pServer); virtual void onConnect(NimBLEServer* pServer);
virtual void onConnect(NimBLEServer* pServer, ble_gap_conn_desc* desc);
/** /**
* @brief Handle an existing client disconnection. * @brief Handle a client connection.
* * This is called when a client connects.
* When an existing client disconnects, we are invoked. * @param [in] pServer A pointer to the %BLE server that received the client connection.
* * @param [in] desc A pointer to the connection description structure containig information
* about the connection parameters.
*/
virtual void onConnect(NimBLEServer* pServer, ble_gap_conn_desc* desc);
/**
* @brief Handle a client disconnection.
* This is called when a client disconnects.
* @param [in] pServer A reference to the %BLE server that received the existing client disconnection. * @param [in] pServer A reference to the %BLE server that received the existing client disconnection.
*/ */
virtual void onDisconnect(NimBLEServer* pServer); virtual void onDisconnect(NimBLEServer* pServer);
virtual uint32_t onPassKeyRequest(); //{return 0;} /**
virtual void onPassKeyNotify(uint32_t pass_key); //{} * @brief Called when a client requests a passkey for pairing.
virtual bool onSecurityRequest(); //{return true;} * @return The passkey to be sent to the client.
virtual void onAuthenticationComplete(ble_gap_conn_desc* desc);//{}; */
virtual bool onConfirmPIN(uint32_t pin);//{return true;} virtual uint32_t onPassKeyRequest();
//virtual void onPassKeyNotify(uint32_t pass_key);
//virtual bool onSecurityRequest();
/**
* @brief Called when the pairing procedure is complete.
* @param [in] desc A pointer to the struct containing the connection information.\n
* This can be used to check the status of the connection encryption/pairing.
*/
virtual void onAuthenticationComplete(ble_gap_conn_desc* desc);
/**
* @brief Called when using numeric comparision for pairing.
* @param [in] pin The pin to compare with the client.
* @return True to accept the pin.
*/
virtual bool onConfirmPIN(uint32_t pin);
}; // NimBLEServerCallbacks }; // NimBLEServerCallbacks

View file

@ -238,11 +238,21 @@ NimBLECharacteristic* NimBLEService::createCharacteristic(const NimBLEUUID &uuid
} // createCharacteristic } // createCharacteristic
/**
* @brief Get a pointer to the characteristic object with the specified UUID.
* @param [in] uuid The UUID of the characteristic.
* @return A pointer to the characteristic object or nullptr if not found.
*/
NimBLECharacteristic* NimBLEService::getCharacteristic(const char* uuid) { NimBLECharacteristic* NimBLEService::getCharacteristic(const char* uuid) {
return getCharacteristic(NimBLEUUID(uuid)); return getCharacteristic(NimBLEUUID(uuid));
} }
/**
* @brief Get a pointer to the characteristic object with the specified UUID.
* @param [in] uuid The UUID of the characteristic.
* @return A pointer to the characteristic object or nullptr if not found.
*/
NimBLECharacteristic* NimBLEService::getCharacteristic(const NimBLEUUID &uuid) { NimBLECharacteristic* NimBLEService::getCharacteristic(const NimBLEUUID &uuid) {
for (auto &it : m_chrVec) { for (auto &it : m_chrVec) {
if (it->getUUID() == uuid) { if (it->getUUID() == uuid) {

View file

@ -73,15 +73,11 @@ static const char* LOG_TAG = "NimBLEUUID";
/** /**
* @brief Create a UUID from 16 bytes of memory. * @brief Create a UUID from 16 bytes of memory.
*
* @param [in] pData The pointer to the start of the UUID. * @param [in] pData The pointer to the start of the UUID.
* @param [in] size The size of the data. * @param [in] size The size of the data.
* @param [in] msbFirst Is the MSB first in pData memory? * @param [in] msbFirst Is the MSB first in pData memory?
*/ */
NimBLEUUID::NimBLEUUID(const uint8_t* pData, size_t size, bool msbFirst) { NimBLEUUID::NimBLEUUID(const uint8_t* pData, size_t size, bool msbFirst) {
/*** TODO: change this to use the Nimble function for various lenght UUIDs:
int ble_uuid_init_from_buf(ble_uuid_any_t *uuid, const void *buf, size_t len);
***/
if (size != 16) { if (size != 16) {
NIMBLE_LOGE(LOG_TAG,"ERROR: UUID length not 16 bytes"); NIMBLE_LOGE(LOG_TAG,"ERROR: UUID length not 16 bytes");
return; return;
@ -99,7 +95,6 @@ NimBLEUUID::NimBLEUUID(const uint8_t* pData, size_t size, bool msbFirst) {
/** /**
* @brief Create a UUID from the 16bit value. * @brief Create a UUID from the 16bit value.
*
* @param [in] uuid The 16bit short form UUID. * @param [in] uuid The 16bit short form UUID.
*/ */
NimBLEUUID::NimBLEUUID(uint16_t uuid) { NimBLEUUID::NimBLEUUID(uint16_t uuid) {
@ -111,7 +106,6 @@ NimBLEUUID::NimBLEUUID(uint16_t uuid) {
/** /**
* @brief Create a UUID from the 32bit value. * @brief Create a UUID from the 32bit value.
*
* @param [in] uuid The 32bit short form UUID. * @param [in] uuid The 32bit short form UUID.
*/ */
NimBLEUUID::NimBLEUUID(uint32_t uuid) { NimBLEUUID::NimBLEUUID(uint32_t uuid) {
@ -123,7 +117,6 @@ NimBLEUUID::NimBLEUUID(uint32_t uuid) {
/** /**
* @brief Create a UUID from the native UUID. * @brief Create a UUID from the native UUID.
*
* @param [in] uuid The native UUID. * @param [in] uuid The native UUID.
*/ */
NimBLEUUID::NimBLEUUID(const ble_uuid128_t* uuid) { NimBLEUUID::NimBLEUUID(const ble_uuid128_t* uuid) {
@ -135,8 +128,8 @@ NimBLEUUID::NimBLEUUID(const ble_uuid128_t* uuid) {
/** /**
* @brief Create a UUID from the 128bit value using hex parts instead of string, * @brief Create a UUID from the 128bit value using hex parts instead of string,
* instead of BLEUUID("ebe0ccb0-7a0a-4b0c-8a1a-6ff2997da3a6"), it becomes * instead of NimBLEUUID("ebe0ccb0-7a0a-4b0c-8a1a-6ff2997da3a6"), it becomes
* BLEUUID(0xebe0ccb0, 0x7a0a, 0x4b0c, 0x8a1a6ff2997da3a6) * NimBLEUUID(0xebe0ccb0, 0x7a0a, 0x4b0c, 0x8a1a6ff2997da3a6)
* *
* @param [in] first The first 32bit of the UUID. * @param [in] first The first 32bit of the UUID.
* @param [in] second The next 16bit of the UUID. * @param [in] second The next 16bit of the UUID.
@ -153,6 +146,9 @@ NimBLEUUID::NimBLEUUID(uint32_t first, uint16_t second, uint16_t third, uint64_t
} }
/**
* @brief Creates an empty UUID.
*/
NimBLEUUID::NimBLEUUID() { NimBLEUUID::NimBLEUUID() {
m_valueSet = false; m_valueSet = false;
} // NimBLEUUID } // NimBLEUUID
@ -180,29 +176,31 @@ bool NimBLEUUID::equals(const NimBLEUUID &uuid) const {
/** /**
* Create a BLEUUID from a string of the form: * Create a NimBLEUUID from a string of the form:
* 0xNNNN * 0xNNNN
* 0xNNNNNNNN * 0xNNNNNNNN
* 0x<UUID> * 0x<UUID>
* NNNN * NNNN
* NNNNNNNN * NNNNNNNN
* <UUID> * <UUID\>
*
* @param [in] uuid The string to create the UUID from.
*/ */
NimBLEUUID NimBLEUUID::fromString(const std::string &_uuid) { NimBLEUUID NimBLEUUID::fromString(const std::string &uuid) {
uint8_t start = 0; uint8_t start = 0;
if (strstr(_uuid.c_str(), "0x") != nullptr) { // If the string starts with 0x, skip those characters. if (strstr(uuid.c_str(), "0x") != nullptr) { // If the string starts with 0x, skip those characters.
start = 2; start = 2;
} }
uint8_t len = _uuid.length() - start; // Calculate the length of the string we are going to use. uint8_t len = uuid.length() - start; // Calculate the length of the string we are going to use.
if(len == 4) { if(len == 4) {
uint16_t x = strtoul(_uuid.substr(start, len).c_str(), NULL, 16); uint16_t x = strtoul(uuid.substr(start, len).c_str(), NULL, 16);
return NimBLEUUID(x); return NimBLEUUID(x);
} else if (len == 8) { } else if (len == 8) {
uint32_t x = strtoul(_uuid.substr(start, len).c_str(), NULL, 16); uint32_t x = strtoul(uuid.substr(start, len).c_str(), NULL, 16);
return NimBLEUUID(x); return NimBLEUUID(x);
} else if (len == 36) { } else if (len == 36) {
return NimBLEUUID(_uuid); return NimBLEUUID(uuid);
} }
return NimBLEUUID(); return NimBLEUUID();
} // fromString } // fromString
@ -210,8 +208,7 @@ NimBLEUUID NimBLEUUID::fromString(const std::string &_uuid) {
/** /**
* @brief Get the native UUID value. * @brief Get the native UUID value.
* * @return The native UUID value or nullptr if not set.
* @return The native UUID value or NULL if not set.
*/ */
const ble_uuid_any_t* NimBLEUUID::getNative() const { const ble_uuid_any_t* NimBLEUUID::getNative() const {
if (m_valueSet == false) { if (m_valueSet == false) {
@ -224,9 +221,9 @@ const ble_uuid_any_t* NimBLEUUID::getNative() const {
/** /**
* @brief Convert a UUID to its 128 bit representation. * @brief Convert a UUID to its 128 bit representation.
* * @details A UUID can be internally represented as 16bit, 32bit or the full 128bit. This method
* A UUID can be internally represented as 16bit, 32bit or the full 128bit. This method
* will convert 16 or 32 bit representations to the full 128bit. * will convert 16 or 32 bit representations to the full 128bit.
* @return The NimBLEUUID converted to 128bit.
*/ */
const NimBLEUUID &NimBLEUUID::to128() { const NimBLEUUID &NimBLEUUID::to128() {
// If we either don't have a value or are already a 128 bit UUID, nothing further to do. // If we either don't have a value or are already a 128 bit UUID, nothing further to do.
@ -248,19 +245,23 @@ const NimBLEUUID &NimBLEUUID::to128() {
/** /**
* @brief Get a string representation of the UUID. * @brief Get a string representation of the UUID.
* * @details
* The format of a string is: * The format of a string is:
* 01234567 8901 2345 6789 012345678901 * 01234567 8901 2345 6789 012345678901
* 0000180d-0000-1000-8000-00805f9b34fb * 0000180d-0000-1000-8000-00805f9b34fb
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
* *
* @return A string representation of the UUID. * @return A string representation of the UUID.
* @deprecated Use std::string() operator instead.
*/ */
std::string NimBLEUUID::toString() const { std::string NimBLEUUID::toString() const {
return std::string(*this); return std::string(*this);
} // toString } // toString
/**
* @brief Convienience operator to check if this UUID is equal to another.
*/
bool NimBLEUUID::operator ==(const NimBLEUUID & rhs) const { bool NimBLEUUID::operator ==(const NimBLEUUID & rhs) const {
if(m_valueSet && rhs.m_valueSet) { if(m_valueSet && rhs.m_valueSet) {
return ble_uuid_cmp(&m_uuid.u, &rhs.m_uuid.u) == 0; return ble_uuid_cmp(&m_uuid.u, &rhs.m_uuid.u) == 0;
@ -270,11 +271,19 @@ bool NimBLEUUID::operator ==(const NimBLEUUID & rhs) const {
} }
/**
* @brief Convienience operator to check if this UUID is not equal to another.
*/
bool NimBLEUUID::operator !=(const NimBLEUUID & rhs) const { bool NimBLEUUID::operator !=(const NimBLEUUID & rhs) const {
return !this->operator==(rhs); return !this->operator==(rhs);
} }
/**
* @brief Convienience operator to convert this UUID to string representation.
* @details This allows passing NimBLEUUID to functions
* that accept std::string and/or or it's methods as a parameter.
*/
NimBLEUUID::operator std::string() const { NimBLEUUID::operator std::string() const {
if (!m_valueSet) return std::string(); // If we have no value, nothing to format. if (!m_valueSet) return std::string(); // If we have no value, nothing to format.

View file

@ -37,20 +37,21 @@ public:
NimBLEUUID(const uint8_t* pData, size_t size, bool msbFirst); NimBLEUUID(const uint8_t* pData, size_t size, bool msbFirst);
NimBLEUUID(uint32_t first, uint16_t second, uint16_t third, uint64_t fourth); NimBLEUUID(uint32_t first, uint16_t second, uint16_t third, uint64_t fourth);
NimBLEUUID(); NimBLEUUID();
uint8_t bitSize() const; // Get the number of bits in this uuid.
bool equals(const NimBLEUUID &uuid) const; uint8_t bitSize() const;
bool equals(const NimBLEUUID &uuid) const;
const ble_uuid_any_t* getNative() const; const ble_uuid_any_t* getNative() const;
const NimBLEUUID & to128(); const NimBLEUUID & to128();
std::string toString() const; std::string toString() const;
static NimBLEUUID fromString(const std::string &uuid); // Create a NimBLEUUID from a string static NimBLEUUID fromString(const std::string &uuid);
bool operator ==(const NimBLEUUID & rhs) const; bool operator ==(const NimBLEUUID & rhs) const;
bool operator !=(const NimBLEUUID & rhs) const; bool operator !=(const NimBLEUUID & rhs) const;
operator std::string() const; operator std::string() const;
private: private:
ble_uuid_any_t m_uuid; // The underlying UUID structure that this class wraps. ble_uuid_any_t m_uuid;
bool m_valueSet = false; // Is there a value set for this instance. bool m_valueSet = false;
}; // NimBLEUUID }; // NimBLEUUID
#endif /* CONFIG_BT_ENABLED */ #endif /* CONFIG_BT_ENABLED */
#endif /* COMPONENTS_NIMBLEUUID_H_ */ #endif /* COMPONENTS_NIMBLEUUID_H_ */

View file

@ -16,6 +16,11 @@
static const char* LOG_TAG = "NimBLEUtils"; static const char* LOG_TAG = "NimBLEUtils";
/**
* @brief A function for checking validity of connection parameters.
* @param [in] params A pointer to the structure containing the parameters to check.
* @return valid == 0 or error code.
*/
int NimBLEUtils::checkConnParams(ble_gap_conn_params* params) { int NimBLEUtils::checkConnParams(ble_gap_conn_params* params) {
/* Check connection interval min */ /* Check connection interval min */
if ((params->itvl_min < BLE_HCI_CONN_ITVL_MIN) || if ((params->itvl_min < BLE_HCI_CONN_ITVL_MIN) ||
@ -49,6 +54,11 @@ int NimBLEUtils::checkConnParams(ble_gap_conn_params* params) {
} }
/**
* @brief Converts a return code from the NimBLE stack to a text string.
* @param [in] rc The return code to convert.
* @return A string representation of the return code.
*/
const char* NimBLEUtils::returnCodeToString(int rc) { const char* NimBLEUtils::returnCodeToString(int rc) {
#if defined(CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT) #if defined(CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT)
switch(rc) { switch(rc) {
@ -338,9 +348,9 @@ const char* NimBLEUtils::returnCodeToString(int rc) {
/** /**
* @brief Convert the BLE Advertising Data flags to a string. * @brief Convert the advertising type flag to a string.
* @param adFlags The flags to convert * @param advType The type to convert.
* @return std::string A string representation of the advertising flags. * @return A string representation of the advertising flags.
*/ */
const char* NimBLEUtils::advTypeToString(uint8_t advType) { const char* NimBLEUtils::advTypeToString(uint8_t advType) {
#if defined(CONFIG_NIMBLE_CPP_ENABLE_ADVERTISMENT_TYPE_TEXT) #if defined(CONFIG_NIMBLE_CPP_ENABLE_ADVERTISMENT_TYPE_TEXT)
@ -367,7 +377,7 @@ const char* NimBLEUtils::advTypeToString(uint8_t advType) {
/** /**
* @brief Create a hex representation of data. * @brief Create a hex representation of data.
* *
* @param [in] target Where to write the hex string. If this is null, we malloc storage. * @param [in] target Where to write the hex string. If this is null, we malloc storage.
* @param [in] source The start of the binary data. * @param [in] source The start of the binary data.
* @param [in] length The length of the data to convert. * @param [in] length The length of the data to convert.
* @return A pointer to the formatted buffer. * @return A pointer to the formatted buffer.
@ -400,6 +410,11 @@ char* NimBLEUtils::buildHexData(uint8_t* target, const uint8_t* source, uint8_t
} // buildHexData } // buildHexData
/**
* @brief Utility function to log the gap event info.
* @param [in] event A pointer to the gap event structure.
* @param [in] arg Unused.
*/
void NimBLEUtils::dumpGapEvent(ble_gap_event *event, void *arg){ void NimBLEUtils::dumpGapEvent(ble_gap_event *event, void *arg){
#if defined(CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT) #if defined(CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT)
NIMBLE_LOGD(LOG_TAG, "Received a GAP event: %s", gapEventToString(event->type)); NIMBLE_LOGD(LOG_TAG, "Received a GAP event: %s", gapEventToString(event->type));
@ -408,7 +423,7 @@ void NimBLEUtils::dumpGapEvent(ble_gap_event *event, void *arg){
/** /**
* @brief Convert a BT GAP event type to a string representation. * @brief Convert a GAP event type to a string representation.
* @param [in] eventType The type of event. * @param [in] eventType The type of event.
* @return A string representation of the event type. * @return A string representation of the event type.
*/ */
@ -495,22 +510,29 @@ const char* NimBLEUtils::gapEventToString(uint8_t eventType) {
/** /**
* Utility function to log an array of bytes. * @brief Utility function to log an array of bytes.
* @param [in] bytes The buffer to print.
* @param [in] len The length of the buffer.
*/ */
void print_bytes(const uint8_t *bytes, int len) void print_bytes(const uint8_t *bytes, int len)
{ {
int i; int i;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
MODLOG_DFLT(ERROR, "%s0x%02x", i != 0 ? ":" : "", bytes[i]); NIMBLE_LOGD(LOG_TAG, "%s0x%02x", i != 0 ? ":" : "", bytes[i]);
if(i % 30 == 0){ if(i % 30 == 0){
MODLOG_DFLT(ERROR, "\n"); NIMBLE_LOGD(LOG_TAG, "\n");
} }
} }
MODLOG_DFLT(ERROR, "\n"); NIMBLE_LOGD(LOG_TAG, "\n");
} }
/**
* @brief Utility function to log an os_mbuf.
* @param [in] om The buffer to print.
*/
void print_mbuf(const struct os_mbuf *om) void print_mbuf(const struct os_mbuf *om)
{ {
int colon; int colon;
@ -655,20 +677,21 @@ void print_adv_fields(const struct ble_hs_adv_fields *fields)
/** /**
* Logs information about a connection to the console. * @brief Logs information about a connection to the console.
*/ * @param [in] desc The connection description struct to print.
*/
void print_conn_desc(const struct ble_gap_conn_desc *desc) void print_conn_desc(const struct ble_gap_conn_desc *desc)
{ {
MODLOG_DFLT(DEBUG, "handle=%d our_ota_addr_type=%d our_ota_addr=%s ", NIMBLE_LOGD(LOG_TAG, "handle=%d our_ota_addr_type=%d our_ota_addr=%s ",
desc->conn_handle, desc->our_ota_addr.type, desc->conn_handle, desc->our_ota_addr.type,
addr_str(desc->our_ota_addr.val)); addr_str(desc->our_ota_addr.val));
MODLOG_DFLT(DEBUG, "our_id_addr_type=%d our_id_addr=%s ", NIMBLE_LOGD(LOG_TAG, "our_id_addr_type=%d our_id_addr=%s ",
desc->our_id_addr.type, addr_str(desc->our_id_addr.val)); desc->our_id_addr.type, addr_str(desc->our_id_addr.val));
MODLOG_DFLT(DEBUG, "peer_ota_addr_type=%d peer_ota_addr=%s ", NIMBLE_LOGD(LOG_TAG, "peer_ota_addr_type=%d peer_ota_addr=%s ",
desc->peer_ota_addr.type, addr_str(desc->peer_ota_addr.val)); desc->peer_ota_addr.type, addr_str(desc->peer_ota_addr.val));
MODLOG_DFLT(DEBUG, "peer_id_addr_type=%d peer_id_addr=%s ", NIMBLE_LOGD(LOG_TAG, "peer_id_addr_type=%d peer_id_addr=%s ",
desc->peer_id_addr.type, addr_str(desc->peer_id_addr.val)); desc->peer_id_addr.type, addr_str(desc->peer_id_addr.val));
MODLOG_DFLT(DEBUG, "conn_itvl=%d conn_latency=%d supervision_timeout=%d " NIMBLE_LOGD(LOG_TAG, "conn_itvl=%d conn_latency=%d supervision_timeout=%d "
"encrypted=%d authenticated=%d bonded=%d", "encrypted=%d authenticated=%d bonded=%d",
desc->conn_itvl, desc->conn_latency, desc->conn_itvl, desc->conn_latency,
desc->supervision_timeout, desc->supervision_timeout,

View file

@ -35,6 +35,10 @@ void print_addr(const void *addr);
void print_bytes(const uint8_t *bytes, int len); void print_bytes(const uint8_t *bytes, int len);
} }
/**
* @brief A BLE Utility class with methods for debugging and general purpose use.
*/
class NimBLEUtils { class NimBLEUtils {
public: public:
static void dumpGapEvent(ble_gap_event *event, void *arg); static void dumpGapEvent(ble_gap_event *event, void *arg);