[Breaking] Update callbacks to use NimBLEConnInfo.

Change the callback functions that receive a ble_gap_conn_desc pointer to instead receive a NimBLEConnInfo reference.

* Add a reason parameter to the server disconnect callback.

* Remove connect and disconnect callback that do not receive info parameters.

* Remove onRead and onWrite Characteristic callbacks that do not receive info parameters.

* Add info parameter to Descriptor onWrite and onRead callbacks.

* Add details to migration guide.
This commit is contained in:
h2zero 2022-08-27 08:28:15 -06:00 committed by h2zero
parent ca8a7c56ac
commit ba79a1bf72
17 changed files with 272 additions and 287 deletions

View file

@ -9,8 +9,10 @@ For more information on the improvements and additions please refer to the [clas
* [General Changes](#general-information)
* [Server](#server-api)
* [Services](#services)
* [characteristics](#characteristics)
* [descriptors](#descriptors)
* [Characteristics](#characteristics)
* [Characteristic Callbacks](#characteristic-callbacks)
* [Descriptors](#descriptors)
* [Descriptor Callbacks](#descriptor-callbacks)
* [Security](#server-security)
* [Advertising](#advertising-api)
* [Client](#client-api)
@ -29,14 +31,14 @@ For more information on the improvements and additions please refer to the [clas
### Header Files
All classes are accessible by including `NimBLEDevice.h` in your application, no further headers need to be included.
(Mainly for Arduino) You may choose to include `NimBLELog.h` in your application if you want to use the `NIMBLE_LOGx` macros for debugging. These macros are used the same way as the `ESP_LOGx` macros.
(Mainly for Arduino) You may choose to include `NimBLELog.h` in your application if you want to use the `NIMBLE_LOGx` macros for debugging. These macros are used the same way as the `ESP_LOGx` macros.
<br/>
### Class Names
Class names remain the same as the original with the addition of a "Nim" prefix.
For example `BLEDevice` is now `NimBLEDevice` and `BLEServer` is now `NimBLEServer` etc.
For convenience definitions have been added to allow applications to use either name for all classes this means **no class names need to be changed in existing code** and makes migrating easier.
For convenience definitions have been added to allow applications to use either name for all classes this means **no class names need to be changed in existing code** and makes migrating easier.
<br/>
### BLE Addresses
@ -46,8 +48,7 @@ For example `BLEAddress addr(11:22:33:44:55:66, 1)` will create the address obje
As this parameter is optional no changes to existing code are needed, it is mentioned here for information.
`BLEAddress::getNative` (`NimBLEAddress::getNative`) returns a uint8_t pointer to the native address byte array. In this library the address bytes are stored in reverse order from the original library. This is due to the way the NimBLE stack expects addresses to be presented to it. All other functions such as `toString` are
not affected as the endian change is made within them.
`BLEAddress::getNative` (`NimBLEAddress::getNative`) returns a uint8_t pointer to the native address byte array. In this library the address bytes are stored in reverse order from the original library. This is due to the way the NimBLE stack expects addresses to be presented to it. All other functions such as `toString` are not affected as the endian change is made within them.
<br/>
<a name="server-api"></a>
@ -55,14 +56,36 @@ not affected as the endian change is made within them.
Creating a `BLEServer` instance is the same as original, no changes required.
For example `BLEDevice::createServer()` will work just as it did before.
`BLEServerCallbacks` (`NimBLEServerCallbacks`) has new methods for handling security operations.
**Note:** All callback methods have default implementations which allows the application to implement only the methods applicable.
`BLEServerCallbacks` (`NimBLEServerCallbacks`) has new methods for handling security operations.
<br/>
`BLEServerCallbacks::onConnect` (`NimBLEServerCallbacks::onConnect`) only has a single callback declaration which takes an additional (required) parameter `NimBLEConnInfo & connInfo`, which has methods to get information about the connected peer.
```
void onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo)`
```
<br/>
`BLEServerCallbacks::onDisconnect` (`NimBLEServerCallbacks::onDisconnect`) only has a single callback declaration which takes 2 additional (required) parameters `NimBLEConnInfo & connInfo`, which provides information about the peer and `int reason`, which gives the reason code for disconnection.
```
void onDisconnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo, int reason)`
```
<br/>
`BLEServerCallbacks::onMtuChanged` (`NimBLEServerCallbacks::onMtuChanged`) takes the parameter `NimBLEConnInfo & connInfo` instead of `esp_ble_gatts_cb_param_t`, which has methods to get information about the connected peer.
```
onMTUChange(uint16_t MTU, NimBLEConnInfo& connInfo)
```
**Note:** All callback methods have default implementations which allows the application to implement only the methods applicable.
<br/>
<a name="services"></a>
### Services
Creating a `BLEService` (`NimBLEService`) instance is the same as original, no changes required.
For example `BLEServer::createService(SERVICE_UUID)` will work just as it did before.
For example `BLEServer::createService(SERVICE_UUID)` will work just as it did before.
<br/>
<a name="characteristics"></a>
### Characteristics
@ -71,27 +94,27 @@ For example `BLEServer::createService(SERVICE_UUID)` will work just as it did be
When creating a characteristic the properties are now set with `NIMBLE_PROPERTY::XXXX` instead of `BLECharacteristic::XXXX`.
#### Originally
> BLECharacteristic::PROPERTY_READ |
> BLECharacteristic::PROPERTY_WRITE
> BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE
#### Is Now
> NIMBLE_PROPERTY::READ |
> NIMBLE_PROPERTY::WRITE
> 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
> 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/>
@ -114,11 +137,17 @@ BLECharacteristic *pCharacteristic = pService->createCharacteristic(
```
<br/>
<a name="characteristic-callbacks"></a>
#### Characteristic callbacks
`BLECharacteristicCallbacks` (`NimBLECharacteristicCallbacks`) has a new method `NimBLECharacteristicCallbacks::onSubscribe` which is called when a client subscribes to notifications/indications.
`NimBLECharacteristicCallbacks::onStatus` (`NimBLECharacteristicCallbacks::onStatus`) has had the status parameter removed as it was unnecessary since the status code from the BLE stack was also provided. The status code for success is 0 for notifications and BLE_HS_EDONE for indications, any other value is an error.
`BLECharacteristicCallbacks::onRead` (`NimBLECharacteristicCallbacks::onRead`) only has a single callback declaration, which takes an additional (required) parameter of `NimBLEConnInfo& connInfo`, which provides connection information about the peer.
**Note:** All callback methods have default implementations which allows the application to implement only the methods applicable.
`BLECharacteristicCallbacks::onWrite` (`NimBLECharacteristicCallbacks::onWrite`) only has a single callback declaration, which takes an additional (required) parameter of `NimBLEConnInfo& connInfo`, which provides connection information about the peer.
`BLECharacteristicCallbacks::onStatus` (`NimBLECharacteristicCallbacks::onStatus`) has had the status parameter removed as it was unnecessary since the status code from the BLE stack was also provided. The status code for success is 0 for notifications and BLE_HS_EDONE for indications, any other value is an error.
**Note:** All callback methods have default implementations which allows the application to implement only the methods applicable.
<br/>
> BLECharacteristic::getData
@ -190,21 +219,30 @@ p2904 = (NimBLE2904*)pCharacteristic->createDescriptor("2904");
```
<br/>
<a name="descriptor-callbacks"></a>
#### Descriptor callbacks
> `BLEDescriptorCallbacks::onRead` (`NimBLEDescriptorCallbacks::onRead`)
`BLEDescriptorCallbacks::onwrite` (`NimBLEDescriptorCallbacks::onwrite`)
The above descriptor callbacks take an additional (required) parameter `NimBLEConnInfo& connInfo`, which contains the connection information of the peer.
<br/>
<a name="server-security"></a>
### 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
> NIMBLE_PROPERTY::READ_ENC
NIMBLE_PROPERTY::READ_AUTHEN
NIMBLE_PROPERTY::READ_AUTHOR
NIMBLE_PROPERTY::WRITE_ENC
NIMBLE_PROPERTY::WRITE_AUTHEN
NIMBLE_PROPERTY::WRITE_AUTHOR
<br/>
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 API](#security-api) for details.
This can be changed to use passkey authentication or numeric comparison. See [Security API](#security-api) for details.
<br/>
<a name="advertising-api"></a>
@ -212,13 +250,13 @@ This can be changed to use passkey authentication or numeric comparison. See [Se
Advertising works the same as the original API except:
Calling `NimBLEAdvertising::setAdvertisementData` will entirely replace any data set with `NimBLEAdvertising::addServiceUUID`, or
`NimBLEAdvertising::setAppearance` or similar methods. You should set all the data you wish to advertise within the `NimBLEAdvertisementData` instead.
`NimBLEAdvertising::setAppearance` or similar methods. You should set all the data you wish to advertise within the `NimBLEAdvertisementData` instead.
<br/>
> BLEAdvertising::start (NimBLEAdvertising::start)
Now takes 2 optional parameters, the first is the duration to advertise for (in seconds), the second is a callback that is invoked when advertising ends and takes a pointer to a `NimBLEAdvertising` object (similar to the `NimBLEScan::start` API).
This provides an opportunity to update the advertisement data if desired.
This provides an opportunity to update the advertisement data if desired.
<br/>
<a name="client-api"></a>
@ -238,18 +276,18 @@ The type parameter has been removed and a new bool parameter has been added to i
If set to false the client will use the attribute database it retrieved from the peripheral when previously connected.
This allows for faster connections and power saving if the devices dropped connection and are reconnecting.
This allows for faster connections and power saving if the devices dropped connection and are reconnecting.
<br/>
> `BLEClient::getServices` (`NimBLEClient::getServices`)
This method now takes an optional (bool) parameter to indicate if the services should be retrieved from the server (true) or the currently known database returned (false : default).
Also now returns a pointer to `std::vector` instead of `std::map`.
Also now returns a pointer to `std::vector` instead of `std::map`.
<br/>
**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 automatic functionality.
**Added:** `NimBLEClient::discoverAttributes` for the user to discover all the peripheral attributes to replace the the removed automatic functionality.
<br/>
<a name="remote-services"></a>
@ -258,14 +296,14 @@ Also now returns a pointer to `std::vector` instead of `std::map`.
> BLERemoteService::getCharacteristicsByHandle
This method has been removed.
This method has been removed.
<br/>
> `BLERemoteService::getCharacteristics` (`NimBLERemoteService::getCharacteristics`)
This method now takes an optional (bool) parameter to indicate if the characteristics should be retrieved from the server (true) or
the currently known database returned (false : default).
Also now returns a pointer to `std::vector` instead of `std::map`.
Also now returns a pointer to `std::vector` instead of `std::map`.
<br/>
<a name="remote-characteristics"></a>
@ -285,7 +323,7 @@ Has been removed.
> `NimBLERemoteCharacteristic::subscribe`
> `NimBLERemoteCharacteristic::unsubscribe`
Are the new methods added to replace it.
Are the new methods added to replace it.
<br/>
> `BLERemoteCharacteristic::readUInt8` (`NimBLERemoteCharacteristic::readUInt8`)
@ -293,7 +331,7 @@ Are the new methods added to replace it.
> `BLERemoteCharacteristic::readUInt32` (`NimBLERemoteCharacteristic::readUInt32`)
> `BLERemoteCharacteristic::readFloat` (`NimBLERemoteCharacteristic::readFloat`)
Are **deprecated** a template: `NimBLERemoteCharacteristic::readValue<type\>(time_t\*, bool)` has been added to replace them.
Are **deprecated** a template: `NimBLERemoteCharacteristic::readValue<type\>(time_t\*, bool)` has been added to replace them.
<br/>
> `BLERemoteCharacteristic::readRawData`
@ -316,7 +354,7 @@ my_struct_t myStruct = pChr->readValue<my_struct_t>();
This method now takes an optional (bool) parameter to indicate if the descriptors should be retrieved from the server (true) or
the currently known database returned (false : default).
Also now returns a pointer to `std::vector` instead of `std::map`.
Also now returns a pointer to `std::vector` instead of `std::map`.
<br/>
<a name="client-callbacks"></a>
@ -324,64 +362,63 @@ Also now returns a pointer to `std::vector` instead of `std::map`.
> `BLEClientCallbacks::onDisconnect` (`NimBLEClientCallbacks::onDisconnect`)
This now takes a second parameter `int reason` which provides the reason code for disconnection.
This now takes a second parameter `int reason` which provides the reason code for disconnection.
<br/>
<a name="client-security"></a>
### 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.
The default configuration will use "just-works" pairing with no bonding, if you wish to enable bonding see below.
<br/>
<a name="scan-api"></a>
### BLE Scan
The scan API is mostly unchanged from the original except for `NimBLEScan::start`, in which the duration parameter is now in milliseconds instead of seconds.
## BLE Scan
The scan API is mostly unchanged from the original except for `NimBLEScan::start`, in which the duration parameter is now in milliseconds instead of seconds.
<br/>
<a name="security-api"></a>
## Security API
Security operations have been moved to `BLEDevice` (`NimBLEDevice`).
Also security callback methods are now incorporated in the `NimBLEServerCallbacks` / `NimBLEClientCallbacks` classes.
However backward compatibility with the original `BLESecurity` (`NimBLESecurity`) class is retained to minimize application code changes.
Security operations have been moved to `BLEDevice` (`NimBLEDevice`).
The security callback methods are now incorporated in the `NimBLEServerCallbacks` / `NimBLEClientCallbacks` classes.
The callback methods are:
> `bool onConfirmPIN(uint32_t pin)`
Receives the pin when using numeric comparison authentication, `return true;` to accept.
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.
For client callback; return the passkey to send to the server.
<br/>
> `void onAuthenticationComplete(ble_gap_conn_desc\* desc)`
> `void onAuthenticationComplete(NimBLEConnInfo& connInfo)`
Authentication complete, success or failed information is in `desc`.
Authentication complete, success or failed information is available from the `NimBLEConnInfo` methods.
<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.
Sets the authorization mode for this device.
<br/>
> `NimBLEDevice::setSecurityIOCap(uint8_t iocap)`
Sets the Input/Output capabilities of this device.
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.
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.
Sets the keys we are willing to accept from the peer during pairing.
<br/>
<a name="arduino-configuration"></a>
@ -391,5 +428,5 @@ Unlike the original library pre-packaged in the esp32-arduino, this library has
This allows Arduino users to fully customize the build, such as increasing max connections or loading the BLE stack into external PSRAM.
For details on the options, they are fully commented in *nimconfig.h*
For details on the options, they are fully commented in *nimconfig.h*
<br/>

View file

@ -19,15 +19,9 @@ static NimBLEServer* pServer;
/** None of these are required as they will be handled by the library with defaults. **
** Remove as you see fit for your needs */
class ServerCallbacks: public NimBLEServerCallbacks {
void onConnect(NimBLEServer* pServer) {
printf("Client connected\n");
NimBLEDevice::startAdvertising();
};
/** Alternative onConnect() method to extract details of the connection.
* See: src/ble_gap.h for the details of the ble_gap_conn_desc struct.
*/
void onConnect(NimBLEServer* pServer, ble_gap_conn_desc* desc) {
printf("Client address: %s\n", NimBLEAddress(desc->peer_ota_addr).toString().c_str());
void onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo) {
printf("Client address: %s\n", connInfo.getAddress().toString().c_str());
/** We can use the connection handle here to ask for different connection parameters.
* Args: connection handle, min connection interval, max connection interval
* latency, supervision timeout.
@ -35,14 +29,17 @@ class ServerCallbacks: public NimBLEServerCallbacks {
* Latency: number of intervals allowed to skip.
* Timeout: 10 millisecond increments, try for 3x interval time for best results.
*/
pServer->updateConnParams(desc->conn_handle, 24, 48, 0, 18);
pServer->updateConnParams(connInfo.getConnHandle(), 24, 48, 0, 18);
};
void onDisconnect(NimBLEServer* pServer) {
void onDisconnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo, int reason) {
printf("Client disconnected - start advertising\n");
NimBLEDevice::startAdvertising();
};
void onMTUChange(uint16_t MTU, ble_gap_conn_desc* desc) {
printf("MTU updated: %u for connection ID: %u\n", MTU, desc->conn_handle);
void onMTUChange(uint16_t MTU, NimBLEConnInfo& connInfo) {
printf("MTU updated: %u for connection ID: %u\n", MTU, connInfo.getConnHandle());
pServer->updateConnParams(connInfo.getConnHandle(), 24, 48, 0, 60);
};
/********************* Security handled here **********************
@ -61,11 +58,10 @@ class ServerCallbacks: public NimBLEServerCallbacks {
return true;
};
void onAuthenticationComplete(ble_gap_conn_desc* desc){
void onAuthenticationComplete(NimBLEConnInfo& connInfo){
/** Check that encryption was successful, if not we disconnect the client */
if(!desc->sec_state.encrypted) {
/** NOTE: createServer returns the current server reference unless one is not already created */
NimBLEDevice::createServer()->disconnect(desc->conn_handle);
if(!connInfo.isEncrypted()) {
NimBLEDevice::getServer()->disconnect(connInfo.getConnHandle());
printf("Encrypt connection failed - disconnecting client\n");
return;
}
@ -75,25 +71,24 @@ class ServerCallbacks: public NimBLEServerCallbacks {
/** Handler class for characteristic actions */
class CharacteristicCallbacks: public NimBLECharacteristicCallbacks {
void onRead(NimBLECharacteristic* pCharacteristic){
void onRead(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) {
printf("%s : onRead(), value: %s\n",
pCharacteristic->getUUID().toString().c_str(),
pCharacteristic->getValue().c_str());
};
pCharacteristic->getUUID().toString().c_str(),
pCharacteristic->getValue().c_str());
}
void onWrite(NimBLECharacteristic* pCharacteristic) {
void onWrite(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) {
printf("%s : onWrite(), value: %s\n",
pCharacteristic->getUUID().toString().c_str(),
pCharacteristic->getValue().c_str());
};
pCharacteristic->getUUID().toString().c_str(),
pCharacteristic->getValue().c_str());
}
/** Called before notification or indication is sent,
* the value can be changed here before sending if desired.
*/
void onNotify(NimBLECharacteristic* pCharacteristic) {
printf("Sending notification to clients\n");
};
}
/**
* The value returned in code is the NimBLE host return code.
@ -101,7 +96,7 @@ class CharacteristicCallbacks: public NimBLECharacteristicCallbacks {
void onStatus(NimBLECharacteristic* pCharacteristic, int code) {
printf("Notification/Indication return code: %d, %s\n",
code, NimBLEUtils::returnCodeToString(code));
};
}
void onSubscribe(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo, uint16_t subValue) {
std::string str = "Client ID: ";
@ -120,17 +115,17 @@ class CharacteristicCallbacks: public NimBLECharacteristicCallbacks {
str += std::string(pCharacteristic->getUUID());
printf("%s\n", str.c_str());
};
}
};
/** Handler class for descriptor actions */
class DescriptorCallbacks : public NimBLEDescriptorCallbacks {
void onWrite(NimBLEDescriptor* pDescriptor) {
void onWrite(NimBLEDescriptor* pDescriptor, NimBLEConnInfo& connInfo) {
std::string dscVal = pDescriptor->getValue();
printf("Descriptor witten value: %s\n", dscVal.c_str());
};
void onRead(NimBLEDescriptor* pDescriptor) {
void onRead(NimBLEDescriptor* pDescriptor, NimBLEConnInfo& connInfo) {
printf("%s Descriptor read\n", pDescriptor->getUUID().toString().c_str());
};;
};

View file

@ -37,11 +37,11 @@ static uint8_t secondaryPhy = BLE_HCI_LE_PHY_1M;
/* Handler class for server events */
class ServerCallbacks: public NimBLEServerCallbacks {
void onConnect(NimBLEServer* pServer, ble_gap_conn_desc* desc) {
printf("Client connected: %s\n", NimBLEAddress(desc->peer_ota_addr).toString().c_str());
void onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo) {
printf("Client connected:: %s\n", connInfo.getAddress().toString().c_str());
};
void onDisconnect(NimBLEServer* pServer) {
void onDisconnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo, int reason) {
printf("Client disconnected - sleeping for %u seconds\n", sleepSeconds);
esp_deep_sleep_start();
};

View file

@ -37,11 +37,11 @@ static uint8_t secondaryPhy = BLE_HCI_LE_PHY_1M;
/* Handler class for server events */
class ServerCallbacks: public NimBLEServerCallbacks {
void onConnect(NimBLEServer* pServer, ble_gap_conn_desc* desc) {
printf("Client connected: %s\n", NimBLEAddress(desc->peer_ota_addr).toString().c_str());
void onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo) {
printf("Client connected: %s\n", connInfo.getAddress().toString().c_str());
};
void onDisconnect(NimBLEServer* pServer) {
void onDisconnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo, int reason) {
printf("Client disconnected\n");
// if still advertising we won't sleep yet.
if (!pServer->getAdvertising()->isAdvertising()) {

View file

@ -60,7 +60,7 @@ class MyClientCallback : public BLEClientCallbacks {
return true;
}
void onAuthenticationComplete(ble_gap_conn_desc desc){
void onAuthenticationComplete(BLEConnInfo& connInfo){
printf("Starting BLE work!\n");
}
/*******************************************************************/

View file

@ -48,11 +48,11 @@ uint32_t value = 0;
/** None of these are required as they will be handled by the library with defaults. **
** Remove as you see fit for your needs */
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
void onConnect(BLEServer* pServer, BLEConnInfo& connInfo) {
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) {
void onDisconnect(BLEServer* pServer, BLEConnInfo& connInfo, int reason) {
deviceConnected = false;
}
/***************** New - Security handled here ********************
@ -67,7 +67,7 @@ class MyServerCallbacks: public BLEServerCallbacks {
return true;
}
void onAuthenticationComplete(ble_gap_conn_desc desc){
void onAuthenticationComplete(BLEConnInfo& connInfo){
printf("Starting BLE work!\n");
}
/*******************************************************************/

View file

@ -50,11 +50,11 @@ uint8_t txValue = 0;
/** None of these are required as they will be handled by the library with defaults. **
** Remove as you see fit for your needs */
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
void onConnect(BLEServer* pServer, BLEConnInfo& connInfo) {
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) {
void onDisconnect(BLEServer* pServer, BLEConnInfo& connInfo, int reason) {
deviceConnected = false;
}
/***************** New - Security handled here ********************
@ -69,14 +69,14 @@ class MyServerCallbacks: public BLEServerCallbacks {
return true;
}
void onAuthenticationComplete(ble_gap_conn_desc desc){
void onAuthenticationComplete(BLEConnInfo& connInfo){
printf("Starting BLE work!\n");
}
/*******************************************************************/
};
class MyCallbacks: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
void onWrite(BLECharacteristic *pCharacteristic, BLEConnInfo& connInfo) {
std::string rxValue = pCharacteristic->getValue();
if (rxValue.length() > 0) {

View file

@ -263,7 +263,7 @@ int NimBLECharacteristic::handleGapEvent(uint16_t conn_handle, uint16_t attr_han
{
const ble_uuid_t *uuid;
int rc;
struct ble_gap_conn_desc desc;
NimBLEConnInfo peerInfo;
NimBLECharacteristic* pCharacteristic = (NimBLECharacteristic*)arg;
NIMBLE_LOGD(LOG_TAG, "Characteristic %s %s event", pCharacteristic->getUUID().toString().c_str(),
@ -273,15 +273,14 @@ int NimBLECharacteristic::handleGapEvent(uint16_t conn_handle, uint16_t attr_han
if(ble_uuid_cmp(uuid, &pCharacteristic->getUUID().getNative()->u) == 0){
switch(ctxt->op) {
case BLE_GATT_ACCESS_OP_READ_CHR: {
rc = ble_gap_conn_find(conn_handle, &desc);
rc = ble_gap_conn_find(conn_handle, &peerInfo.m_desc);
assert(rc == 0);
// If the packet header is only 8 bytes this is a follow up of a long read
// so we don't want to call the onRead() callback again.
if(ctxt->om->om_pkthdr_len > 8 ||
pCharacteristic->m_value.size() <= (ble_att_mtu(desc.conn_handle) - 3)) {
pCharacteristic->m_pCallbacks->onRead(pCharacteristic);
pCharacteristic->m_pCallbacks->onRead(pCharacteristic, &desc);
pCharacteristic->m_value.size() <= (ble_att_mtu(peerInfo.m_desc.conn_handle) - 3)) {
pCharacteristic->m_pCallbacks->onRead(pCharacteristic, peerInfo);
}
ble_npl_hw_enter_critical();
@ -311,11 +310,10 @@ int NimBLECharacteristic::handleGapEvent(uint16_t conn_handle, uint16_t attr_han
len += next->om_len;
next = SLIST_NEXT(next, om_next);
}
rc = ble_gap_conn_find(conn_handle, &desc);
rc = ble_gap_conn_find(conn_handle, &peerInfo.m_desc);
assert(rc == 0);
pCharacteristic->setValue(buf, len);
pCharacteristic->m_pCallbacks->onWrite(pCharacteristic);
pCharacteristic->m_pCallbacks->onWrite(pCharacteristic, &desc);
pCharacteristic->m_pCallbacks->onWrite(pCharacteristic, peerInfo);
return 0;
}
default:
@ -341,8 +339,8 @@ size_t NimBLECharacteristic::getSubscribedCount() {
* This will maintain a vector of subscribed clients and their indicate/notify status.
*/
void NimBLECharacteristic::setSubscribe(struct ble_gap_event *event) {
ble_gap_conn_desc desc;
if(ble_gap_conn_find(event->subscribe.conn_handle, &desc) != 0) {
NimBLEConnInfo peerInfo;
if(ble_gap_conn_find(event->subscribe.conn_handle, &peerInfo.m_desc) != 0) {
return;
}
@ -379,7 +377,7 @@ void NimBLECharacteristic::setSubscribe(struct ble_gap_event *event) {
m_subscribedVec.erase(it);
}
m_pCallbacks->onSubscribe(this, &desc, subVal);
m_pCallbacks->onSubscribe(this, peerInfo, subVal);
}
@ -529,6 +527,7 @@ void NimBLECharacteristic::setCallbacks(NimBLECharacteristicCallbacks* pCallback
}
} // setCallbacks
/**
* @brief Get the callback handlers for this characteristic.
*/
@ -584,42 +583,25 @@ std::string NimBLECharacteristic::toString() {
} // toString
NimBLECharacteristicCallbacks::~NimBLECharacteristicCallbacks() {}
/**
* @brief Callback function to support a read request.
* @param [in] pCharacteristic The characteristic that is the source of the event.
* @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info.
*/
void NimBLECharacteristicCallbacks::onRead(NimBLECharacteristic* pCharacteristic) {
void NimBLECharacteristicCallbacks::onRead(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) {
NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onRead: default");
} // onRead
/**
* @brief Callback function to support a read request.
* @param [in] pCharacteristic The characteristic that is the source of the event.
* @param [in] desc The connection description struct that is associated with the peer that performed the read.
*/
void NimBLECharacteristicCallbacks::onRead(NimBLECharacteristic* pCharacteristic, ble_gap_conn_desc* desc) {
NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onRead: default");
} // onRead
/**
* @brief Callback function to support a write request.
* @param [in] pCharacteristic The characteristic that is the source of the event.
* @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info.
*/
void NimBLECharacteristicCallbacks::onWrite(NimBLECharacteristic* pCharacteristic) {
void NimBLECharacteristicCallbacks::onWrite(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) {
NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onWrite: default");
} // onWrite
/**
* @brief Callback function to support a write request.
* @param [in] pCharacteristic The characteristic that is the source of the event.
* @param [in] desc The connection description struct that is associated with the peer that performed the write.
*/
void NimBLECharacteristicCallbacks::onWrite(NimBLECharacteristic* pCharacteristic, ble_gap_conn_desc* desc) {
NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onWrite: default");
} // onWrite
/**
* @brief Callback function to support a Notify request.
@ -645,7 +627,7 @@ void NimBLECharacteristicCallbacks::onStatus(NimBLECharacteristic* pCharacterist
/**
* @brief Callback function called when a client changes subscription status.
* @param [in] pCharacteristic The characteristic that is the source of the event.
* @param [in] desc The connection description struct that is associated with the client.
* @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info.
* @param [in] subValue The subscription status:
* * 0 = Un-Subscribed
* * 1 = Notifications
@ -653,7 +635,7 @@ void NimBLECharacteristicCallbacks::onStatus(NimBLECharacteristic* pCharacterist
* * 3 = Notifications and Indications
*/
void NimBLECharacteristicCallbacks::onSubscribe(NimBLECharacteristic* pCharacteristic,
ble_gap_conn_desc* desc,
NimBLEConnInfo& connInfo,
uint16_t subValue)
{
NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onSubscribe: default");

View file

@ -45,6 +45,7 @@ typedef enum {
#include "NimBLEService.h"
#include "NimBLEDescriptor.h"
#include "NimBLEAttValue.h"
#include "NimBLEConnInfo.h"
#include <string>
#include <vector>
@ -200,14 +201,12 @@ private:
*/
class NimBLECharacteristicCallbacks {
public:
virtual ~NimBLECharacteristicCallbacks();
virtual void onRead(NimBLECharacteristic* pCharacteristic);
virtual void onRead(NimBLECharacteristic* pCharacteristic, ble_gap_conn_desc* desc);
virtual void onWrite(NimBLECharacteristic* pCharacteristic);
virtual void onWrite(NimBLECharacteristic* pCharacteristic, ble_gap_conn_desc* desc);
virtual ~NimBLECharacteristicCallbacks(){}
virtual void onRead(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo);
virtual void onWrite(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo);
virtual void onNotify(NimBLECharacteristic* pCharacteristic);
virtual void onStatus(NimBLECharacteristic* pCharacteristic, int code);
virtual void onSubscribe(NimBLECharacteristic* pCharacteristic, ble_gap_conn_desc* desc, uint16_t subValue);
virtual void onSubscribe(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo, uint16_t subValue);
};
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL */

View file

@ -926,7 +926,7 @@ uint16_t NimBLEClient::getMTU() {
*/
/*STATIC*/
int NimBLEClient::handleGapEvent(struct ble_gap_event *event, void *arg) {
NimBLEClient* client = (NimBLEClient*)arg;
NimBLEClient* pClient = (NimBLEClient*)arg;
int rc;
NIMBLE_LOGD(LOG_TAG, "Got Client event %s", NimBLEUtils::gapEventToString(event->type));
@ -947,40 +947,40 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event *event, void *arg) {
break;
default:
// Check that the event is for this client.
if(client->m_conn_id != event->disconnect.conn.conn_handle) {
if(pClient->m_conn_id != event->disconnect.conn.conn_handle) {
return 0;
}
break;
}
// Stop the disconnect timer since we are now disconnected.
ble_npl_callout_stop(&client->m_dcTimer);
ble_npl_callout_stop(&pClient->m_dcTimer);
// Remove the device from ignore list so we will scan it again
NimBLEDevice::removeIgnored(client->m_peerAddress);
NimBLEDevice::removeIgnored(pClient->m_peerAddress);
// No longer connected, clear the connection ID.
client->m_conn_id = BLE_HS_CONN_HANDLE_NONE;
pClient->m_conn_id = BLE_HS_CONN_HANDLE_NONE;
// If we received a connected event but did not get established (no PDU)
// then a disconnect event will be sent but we should not send it to the
// app for processing. Instead we will ensure the task is released
// and report the error.
if(!client->m_connEstablished)
if(!pClient->m_connEstablished)
break;
NIMBLE_LOGI(LOG_TAG, "disconnect; reason=%d, %s",
rc, NimBLEUtils::returnCodeToString(rc));
client->m_connEstablished = false;
client->m_pClientCallbacks->onDisconnect(client, rc);
pClient->m_connEstablished = false;
pClient->m_pClientCallbacks->onDisconnect(pClient, rc);
break;
} // BLE_GAP_EVENT_DISCONNECT
case BLE_GAP_EVENT_CONNECT: {
// If we aren't waiting for this connection response
// we should drop the connection immediately.
if(client->isConnected() || client->m_pTaskData == nullptr) {
if(pClient->isConnected() || pClient->m_pTaskData == nullptr) {
ble_gap_terminate(event->connect.conn_handle, BLE_ERR_REM_USER_CONN_TERM);
return 0;
}
@ -989,20 +989,20 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event *event, void *arg) {
if (rc == 0) {
NIMBLE_LOGI(LOG_TAG, "Connected event");
client->m_conn_id = event->connect.conn_handle;
pClient->m_conn_id = event->connect.conn_handle;
rc = ble_gattc_exchange_mtu(client->m_conn_id, NULL,NULL);
rc = ble_gattc_exchange_mtu(pClient->m_conn_id, NULL,NULL);
if(rc != 0) {
NIMBLE_LOGE(LOG_TAG, "MTU exchange error; rc=%d %s",
rc, NimBLEUtils::returnCodeToString(rc));
break;
}
// In the case of a multiconnecting device we ignore this device when
// In the case of a multi-connecting device we ignore this device when
// scanning since we are already connected to it
NimBLEDevice::addIgnored(client->m_peerAddress);
NimBLEDevice::addIgnored(pClient->m_peerAddress);
} else {
client->m_conn_id = BLE_HS_CONN_HANDLE_NONE;
pClient->m_conn_id = BLE_HS_CONN_HANDLE_NONE;
break;
}
@ -1010,19 +1010,19 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event *event, void *arg) {
} // BLE_GAP_EVENT_CONNECT
case BLE_GAP_EVENT_NOTIFY_RX: {
if(client->m_conn_id != event->notify_rx.conn_handle)
if(pClient->m_conn_id != event->notify_rx.conn_handle)
return 0;
// If a notification comes before this flag is set we might
// access a vector while it is being cleared in connect()
if(!client->m_connEstablished) {
if(!pClient->m_connEstablished) {
return 0;
}
NIMBLE_LOGD(LOG_TAG, "Notify Recieved for handle: %d",
NIMBLE_LOGD(LOG_TAG, "Notify Received for handle: %d",
event->notify_rx.attr_handle);
for(auto &it: client->m_servicesVector) {
for(auto &it: pClient->m_servicesVector) {
// Dont waste cycles searching services without this handle in its range
if(it->getEndHandle() < event->notify_rx.attr_handle) {
continue;
@ -1061,7 +1061,7 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event *event, void *arg) {
case BLE_GAP_EVENT_CONN_UPDATE_REQ:
case BLE_GAP_EVENT_L2CAP_UPDATE_REQ: {
if(client->m_conn_id != event->conn_update_req.conn_handle){
if(pClient->m_conn_id != event->conn_update_req.conn_handle){
return 0;
}
NIMBLE_LOGD(LOG_TAG, "Peer requesting to update connection parameters");
@ -1071,15 +1071,15 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event *event, void *arg) {
event->conn_update_req.peer_params->latency,
event->conn_update_req.peer_params->supervision_timeout);
rc = client->m_pClientCallbacks->onConnParamsUpdateRequest(client,
rc = pClient->m_pClientCallbacks->onConnParamsUpdateRequest(pClient,
event->conn_update_req.peer_params) ? 0 : BLE_ERR_CONN_PARMS;
if(!rc && event->type == BLE_GAP_EVENT_CONN_UPDATE_REQ ) {
event->conn_update_req.self_params->itvl_min = client->m_pConnParams.itvl_min;
event->conn_update_req.self_params->itvl_max = client->m_pConnParams.itvl_max;
event->conn_update_req.self_params->latency = client->m_pConnParams.latency;
event->conn_update_req.self_params->supervision_timeout = client->m_pConnParams.supervision_timeout;
event->conn_update_req.self_params->itvl_min = pClient->m_pConnParams.itvl_min;
event->conn_update_req.self_params->itvl_max = pClient->m_pConnParams.itvl_max;
event->conn_update_req.self_params->latency = pClient->m_pConnParams.latency;
event->conn_update_req.self_params->supervision_timeout = pClient->m_pConnParams.supervision_timeout;
}
NIMBLE_LOGD(LOG_TAG, "%s peer params", (rc == 0) ? "Accepted" : "Rejected");
@ -1087,7 +1087,7 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event *event, void *arg) {
} // BLE_GAP_EVENT_CONN_UPDATE_REQ, BLE_GAP_EVENT_L2CAP_UPDATE_REQ
case BLE_GAP_EVENT_CONN_UPDATE: {
if(client->m_conn_id != event->conn_update.conn_handle){
if(pClient->m_conn_id != event->conn_update.conn_handle){
return 0;
}
if(event->conn_update.status == 0) {
@ -1099,22 +1099,22 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event *event, void *arg) {
} // BLE_GAP_EVENT_CONN_UPDATE
case BLE_GAP_EVENT_ENC_CHANGE: {
if(client->m_conn_id != event->enc_change.conn_handle){
if(pClient->m_conn_id != event->enc_change.conn_handle){
return 0;
}
if(event->enc_change.status == 0 ||
event->enc_change.status == (BLE_HS_ERR_HCI_BASE + BLE_ERR_PINKEY_MISSING))
{
struct ble_gap_conn_desc desc;
rc = ble_gap_conn_find(event->enc_change.conn_handle, &desc);
NimBLEConnInfo peerInfo;
rc = ble_gap_conn_find(event->enc_change.conn_handle, &peerInfo.m_desc);
assert(rc == 0);
if (event->enc_change.status == (BLE_HS_ERR_HCI_BASE + BLE_ERR_PINKEY_MISSING)) {
// Key is missing, try deleting.
ble_store_util_delete_peer(&desc.peer_id_addr);
ble_store_util_delete_peer(&peerInfo.m_desc.peer_id_addr);
} else {
client->m_pClientCallbacks->onAuthenticationComplete(&desc);
pClient->m_pClientCallbacks->onAuthenticationComplete(peerInfo);
}
}
@ -1123,7 +1123,7 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event *event, void *arg) {
} //BLE_GAP_EVENT_ENC_CHANGE
case BLE_GAP_EVENT_MTU: {
if(client->m_conn_id != event->mtu.conn_handle){
if(pClient->m_conn_id != event->mtu.conn_handle){
return 0;
}
NIMBLE_LOGI(LOG_TAG, "mtu update event; conn_handle=%d mtu=%d",
@ -1136,7 +1136,7 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event *event, void *arg) {
case BLE_GAP_EVENT_PASSKEY_ACTION: {
struct ble_sm_io pkey = {0,0};
if(client->m_conn_id != event->passkey.conn_handle)
if(pClient->m_conn_id != event->passkey.conn_handle)
return 0;
if (event->passkey.params.action == BLE_SM_IOACT_DISP) {
@ -1148,7 +1148,7 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event *event, void *arg) {
} else if (event->passkey.params.action == BLE_SM_IOACT_NUMCMP) {
NIMBLE_LOGD(LOG_TAG, "Passkey on device's display: %" PRIu32, event->passkey.params.numcmp);
pkey.action = event->passkey.params.action;
pkey.numcmp_accept = client->m_pClientCallbacks->onConfirmPIN(event->passkey.params.numcmp);
pkey.numcmp_accept = pClient->m_pClientCallbacks->onConfirmPIN(event->passkey.params.numcmp);
rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
NIMBLE_LOGD(LOG_TAG, "ble_sm_inject_io result: %d", rc);
@ -1166,7 +1166,7 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event *event, void *arg) {
} else if (event->passkey.params.action == BLE_SM_IOACT_INPUT) {
NIMBLE_LOGD(LOG_TAG, "Enter the passkey");
pkey.action = event->passkey.params.action;
pkey.passkey = client->m_pClientCallbacks->onPassKeyRequest();
pkey.passkey = pClient->m_pClientCallbacks->onPassKeyRequest();
rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
NIMBLE_LOGD(LOG_TAG, "ble_sm_inject_io result: %d", rc);
@ -1183,12 +1183,12 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event *event, void *arg) {
}
} // Switch
if(client->m_pTaskData != nullptr) {
client->m_pTaskData->rc = rc;
if(client->m_pTaskData->task) {
xTaskNotifyGive(client->m_pTaskData->task);
if(pClient->m_pTaskData != nullptr) {
pClient->m_pTaskData->rc = rc;
if(pClient->m_pTaskData->task) {
xTaskNotifyGive(pClient->m_pTaskData->task);
}
client->m_pTaskData = nullptr;
pClient->m_pTaskData = nullptr;
}
return 0;
@ -1262,7 +1262,7 @@ uint32_t NimBLEClientCallbacks::onPassKeyRequest(){
return 123456;
}
void NimBLEClientCallbacks::onAuthenticationComplete(ble_gap_conn_desc* desc){
void NimBLEClientCallbacks::onAuthenticationComplete(NimBLEConnInfo& peerInfo){
NIMBLE_LOGD("NimBLEClientCallbacks", "onAuthenticationComplete: default");
}
bool NimBLEClientCallbacks::onConfirmPIN(uint32_t pin){

View file

@ -152,7 +152,7 @@ public:
* @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(NimBLEConnInfo& connInfo);
/**
* @brief Called when using numeric comparision for pairing.

View file

@ -9,6 +9,9 @@
class NimBLEConnInfo {
friend class NimBLEServer;
friend class NimBLEClient;
friend class NimBLECharacteristic;
friend class NimBLEDescriptor;
ble_gap_conn_desc m_desc;
NimBLEConnInfo() { m_desc = {}; }
NimBLEConnInfo(ble_gap_conn_desc desc) { m_desc = desc; }

View file

@ -155,7 +155,7 @@ int NimBLEDescriptor::handleGapEvent(uint16_t conn_handle, uint16_t attr_handle,
const ble_uuid_t *uuid;
int rc;
struct ble_gap_conn_desc desc;
NimBLEConnInfo peerInfo;
NimBLEDescriptor* pDescriptor = (NimBLEDescriptor*)arg;
NIMBLE_LOGD(LOG_TAG, "Descriptor %s %s event", pDescriptor->getUUID().toString().c_str(),
@ -165,14 +165,14 @@ int NimBLEDescriptor::handleGapEvent(uint16_t conn_handle, uint16_t attr_handle,
if(ble_uuid_cmp(uuid, &pDescriptor->getUUID().getNative()->u) == 0){
switch(ctxt->op) {
case BLE_GATT_ACCESS_OP_READ_DSC: {
rc = ble_gap_conn_find(conn_handle, &desc);
rc = ble_gap_conn_find(conn_handle, &peerInfo.m_desc);
assert(rc == 0);
// If the packet header is only 8 bytes this is a follow up of a long read
// so we don't want to call the onRead() callback again.
if(ctxt->om->om_pkthdr_len > 8 ||
pDescriptor->m_value.size() <= (ble_att_mtu(desc.conn_handle) - 3)) {
pDescriptor->m_pCallbacks->onRead(pDescriptor);
pDescriptor->m_value.size() <= (ble_att_mtu(peerInfo.getConnHandle()) - 3)) {
pDescriptor->m_pCallbacks->onRead(pDescriptor, peerInfo);
}
ble_npl_hw_enter_critical();
@ -182,6 +182,9 @@ int NimBLEDescriptor::handleGapEvent(uint16_t conn_handle, uint16_t attr_handle,
}
case BLE_GATT_ACCESS_OP_WRITE_DSC: {
rc = ble_gap_conn_find(conn_handle, &peerInfo.m_desc);
assert(rc == 0);
uint16_t att_max_len = pDescriptor->m_value.max_size();
if (ctxt->om->om_len > att_max_len) {
@ -203,7 +206,7 @@ int NimBLEDescriptor::handleGapEvent(uint16_t conn_handle, uint16_t attr_handle,
}
pDescriptor->setValue(buf, len);
pDescriptor->m_pCallbacks->onWrite(pDescriptor);
pDescriptor->m_pCallbacks->onWrite(pDescriptor, peerInfo);
return 0;
}
default:
@ -280,13 +283,11 @@ std::string NimBLEDescriptor::toString() {
} // toString
NimBLEDescriptorCallbacks::~NimBLEDescriptorCallbacks() {}
/**
* @brief Callback function to support a read request.
* @param [in] pDescriptor The descriptor that is the source of the event.
*/
void NimBLEDescriptorCallbacks::onRead(NimBLEDescriptor* pDescriptor) {
void NimBLEDescriptorCallbacks::onRead(NimBLEDescriptor* pDescriptor, NimBLEConnInfo& connInfo) {
(void)pDescriptor;
NIMBLE_LOGD("NimBLEDescriptorCallbacks", "onRead: default");
} // onRead
@ -296,7 +297,7 @@ void NimBLEDescriptorCallbacks::onRead(NimBLEDescriptor* pDescriptor) {
* @brief Callback function to support a write request.
* @param [in] pDescriptor The descriptor that is the source of the event.
*/
void NimBLEDescriptorCallbacks::onWrite(NimBLEDescriptor* pDescriptor) {
void NimBLEDescriptorCallbacks::onWrite(NimBLEDescriptor* pDescriptor, NimBLEConnInfo& connInfo) {
(void)pDescriptor;
NIMBLE_LOGD("NimBLEDescriptorCallbacks", "onWrite: default");
} // onWrite

View file

@ -21,6 +21,7 @@
#include "NimBLECharacteristic.h"
#include "NimBLEUUID.h"
#include "NimBLEAttValue.h"
#include "NimBLEConnInfo.h"
#include <string>
@ -108,9 +109,9 @@ private:
*/
class NimBLEDescriptorCallbacks {
public:
virtual ~NimBLEDescriptorCallbacks();
virtual void onRead(NimBLEDescriptor* pDescriptor);
virtual void onWrite(NimBLEDescriptor* pDescriptor);
virtual ~NimBLEDescriptorCallbacks(){}
virtual void onRead(NimBLEDescriptor* pDescriptor, NimBLEConnInfo& connInfo);
virtual void onWrite(NimBLEDescriptor* pDescriptor, NimBLEConnInfo& connInfo);
};
#include "NimBLE2904.h"

View file

@ -78,6 +78,7 @@
#define BLEBeacon NimBLEBeacon
#define BLEEddystoneTLM NimBLEEddystoneTLM
#define BLEEddystoneURL NimBLEEddystoneURL
#define BLEConnInfo NimBLEConnInfo
#ifdef CONFIG_BT_NIMBLE_MAX_CONNECTIONS
#define NIMBLE_MAX_CONNECTIONS CONFIG_BT_NIMBLE_MAX_CONNECTIONS

View file

@ -339,11 +339,11 @@ NimBLEConnInfo NimBLEServer::getPeerIDInfo(uint16_t id) {
*/
/*STATIC*/
int NimBLEServer::handleGapEvent(struct ble_gap_event *event, void *arg) {
NimBLEServer* server = NimBLEDevice::getServer();
NIMBLE_LOGD(LOG_TAG, ">> handleGapEvent: %s",
NimBLEUtils::gapEventToString(event->type));
NIMBLE_LOGD(LOG_TAG, ">> handleGapEvent: %s", NimBLEUtils::gapEventToString(event->type));
int rc = 0;
struct ble_gap_conn_desc desc;
NimBLEConnInfo peerInfo;
NimBLEServer* pServer = NimBLEDevice::getServer();
switch(event->type) {
@ -356,15 +356,14 @@ int NimBLEServer::handleGapEvent(struct ble_gap_event *event, void *arg) {
#endif
}
else {
server->m_connectedPeersVec.push_back(event->connect.conn_handle);
pServer->m_connectedPeersVec.push_back(event->connect.conn_handle);
rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
rc = ble_gap_conn_find(event->connect.conn_handle, &peerInfo.m_desc);
if (rc != 0) {
return 0;
}
server->m_pServerCallbacks->onConnect(server);
server->m_pServerCallbacks->onConnect(server, &desc);
pServer->m_pServerCallbacks->onConnect(pServer, peerInfo);
}
return 0;
@ -386,21 +385,21 @@ int NimBLEServer::handleGapEvent(struct ble_gap_event *event, void *arg) {
break;
}
server->m_connectedPeersVec.erase(std::remove(server->m_connectedPeersVec.begin(),
server->m_connectedPeersVec.end(),
pServer->m_connectedPeersVec.erase(std::remove(pServer->m_connectedPeersVec.begin(),
pServer->m_connectedPeersVec.end(),
event->disconnect.conn.conn_handle),
server->m_connectedPeersVec.end());
pServer->m_connectedPeersVec.end());
if(server->m_svcChanged) {
server->resetGATT();
if(pServer->m_svcChanged) {
pServer->resetGATT();
}
server->m_pServerCallbacks->onDisconnect(server);
server->m_pServerCallbacks->onDisconnect(server, &event->disconnect.conn);
NimBLEConnInfo peerInfo(event->disconnect.conn);
pServer->m_pServerCallbacks->onDisconnect(pServer, peerInfo, event->disconnect.reason);
#if !CONFIG_BT_NIMBLE_EXT_ADV
if(server->m_advertiseOnDisconnect) {
server->startAdvertising();
if(pServer->m_advertiseOnDisconnect) {
pServer->startAdvertising();
}
#endif
return 0;
@ -411,18 +410,18 @@ int NimBLEServer::handleGapEvent(struct ble_gap_event *event, void *arg) {
event->subscribe.attr_handle,
(event->subscribe.cur_notify ? "true":"false"));
for(auto &it : server->m_notifyChrVec) {
for(auto &it : pServer->m_notifyChrVec) {
if(it->getHandle() == event->subscribe.attr_handle) {
if((it->getProperties() & BLE_GATT_CHR_F_READ_AUTHEN) ||
(it->getProperties() & BLE_GATT_CHR_F_READ_AUTHOR) ||
(it->getProperties() & BLE_GATT_CHR_F_READ_ENC))
{
rc = ble_gap_conn_find(event->subscribe.conn_handle, &desc);
rc = ble_gap_conn_find(event->subscribe.conn_handle, &peerInfo.m_desc);
if (rc != 0) {
break;
}
if(!desc.sec_state.encrypted) {
if(!peerInfo.isEncrypted()) {
NimBLEDevice::startSecurity(event->subscribe.conn_handle);
}
}
@ -439,19 +438,20 @@ int NimBLEServer::handleGapEvent(struct ble_gap_event *event, void *arg) {
NIMBLE_LOGI(LOG_TAG, "mtu update event; conn_handle=%d mtu=%d",
event->mtu.conn_handle,
event->mtu.value);
rc = ble_gap_conn_find(event->mtu.conn_handle, &desc);
rc = ble_gap_conn_find(event->mtu.conn_handle, &peerInfo.m_desc);
if (rc != 0) {
return 0;
}
server->m_pServerCallbacks->onMTUChange(event->mtu.value, &desc);
pServer->m_pServerCallbacks->onMTUChange(event->mtu.value, peerInfo);
return 0;
} // BLE_GAP_EVENT_MTU
case BLE_GAP_EVENT_NOTIFY_TX: {
NimBLECharacteristic *pChar = nullptr;
for(auto &it : server->m_notifyChrVec) {
for(auto &it : pServer->m_notifyChrVec) {
if(it->getHandle() == event->notify_tx.attr_handle) {
pChar = it;
}
@ -465,7 +465,7 @@ int NimBLEServer::handleGapEvent(struct ble_gap_event *event, void *arg) {
if(event->notify_tx.status == 0) {
return 0; // Indication sent but not yet acknowledged.
}
server->clearIndicateWait(event->notify_tx.conn_handle);
pServer->clearIndicateWait(event->notify_tx.conn_handle);
}
pChar->m_pCallbacks->onStatus(pChar, event->notify_tx.status);
@ -495,12 +495,12 @@ int NimBLEServer::handleGapEvent(struct ble_gap_event *event, void *arg) {
*/
/* Delete the old bond. */
rc = ble_gap_conn_find(event->repeat_pairing.conn_handle, &desc);
rc = ble_gap_conn_find(event->repeat_pairing.conn_handle, &peerInfo.m_desc);
if (rc != 0){
return BLE_GAP_REPEAT_PAIRING_IGNORE;
}
ble_store_util_delete_peer(&desc.peer_id_addr);
ble_store_util_delete_peer(&peerInfo.m_desc.peer_id_addr);
/* Return BLE_GAP_REPEAT_PAIRING_RETRY to indicate that the host should
* continue with the pairing operation.
@ -509,12 +509,12 @@ int NimBLEServer::handleGapEvent(struct ble_gap_event *event, void *arg) {
} // BLE_GAP_EVENT_REPEAT_PAIRING
case BLE_GAP_EVENT_ENC_CHANGE: {
rc = ble_gap_conn_find(event->enc_change.conn_handle, &desc);
rc = ble_gap_conn_find(event->enc_change.conn_handle, &peerInfo.m_desc);
if(rc != 0) {
return BLE_ATT_ERR_INVALID_HANDLE;
}
server->m_pServerCallbacks->onAuthenticationComplete(&desc);
pServer->m_pServerCallbacks->onAuthenticationComplete(peerInfo);
return 0;
} // BLE_GAP_EVENT_ENC_CHANGE
@ -528,7 +528,7 @@ int NimBLEServer::handleGapEvent(struct ble_gap_event *event, void *arg) {
// if the (static)passkey is the default, check the callback for custom value
// both values default to the same.
if(pkey.passkey == 123456) {
pkey.passkey = server->m_pServerCallbacks->onPassKeyRequest();
pkey.passkey = pServer->m_pServerCallbacks->onPassKeyRequest();
}
rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_DISP; ble_sm_inject_io result: %d", rc);
@ -536,7 +536,7 @@ int NimBLEServer::handleGapEvent(struct ble_gap_event *event, void *arg) {
} else if (event->passkey.params.action == BLE_SM_IOACT_NUMCMP) {
NIMBLE_LOGD(LOG_TAG, "Passkey on device's display: %" PRIu32, event->passkey.params.numcmp);
pkey.action = event->passkey.params.action;
pkey.numcmp_accept = server->m_pServerCallbacks->onConfirmPIN(event->passkey.params.numcmp);
pkey.numcmp_accept = pServer->m_pServerCallbacks->onConfirmPIN(event->passkey.params.numcmp);
rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_NUMCMP; ble_sm_inject_io result: %d", rc);
@ -554,7 +554,7 @@ int NimBLEServer::handleGapEvent(struct ble_gap_event *event, void *arg) {
} else if (event->passkey.params.action == BLE_SM_IOACT_INPUT) {
NIMBLE_LOGD(LOG_TAG, "Enter the passkey");
pkey.action = event->passkey.params.action;
pkey.passkey = server->m_pServerCallbacks->onPassKeyRequest();
pkey.passkey = pServer->m_pServerCallbacks->onPassKeyRequest();
rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_INPUT; ble_sm_inject_io result: %d", rc);
@ -838,49 +838,31 @@ void NimBLEServer::clearIndicateWait(uint16_t conn_handle) {
/** Default callback handlers */
void NimBLEServerCallbacks::onConnect(NimBLEServer* pServer) {
void NimBLEServerCallbacks::onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo) {
NIMBLE_LOGD("NimBLEServerCallbacks", "onConnect(): Default");
} // onConnect
void NimBLEServerCallbacks::onConnect(NimBLEServer* pServer, ble_gap_conn_desc* desc) {
NIMBLE_LOGD("NimBLEServerCallbacks", "onConnect(): Default");
} // onConnect
void NimBLEServerCallbacks::onDisconnect(NimBLEServer* pServer) {
void NimBLEServerCallbacks::onDisconnect(NimBLEServer* pServer,
NimBLEConnInfo& connInfo, int reason) {
NIMBLE_LOGD("NimBLEServerCallbacks", "onDisconnect(): Default");
} // onDisconnect
void NimBLEServerCallbacks::onDisconnect(NimBLEServer* pServer, ble_gap_conn_desc* desc) {
NIMBLE_LOGD("NimBLEServerCallbacks", "onDisconnect(): Default");
} // onDisconnect
void NimBLEServerCallbacks::onMTUChange(uint16_t MTU, ble_gap_conn_desc* desc) {
void NimBLEServerCallbacks::onMTUChange(uint16_t MTU, NimBLEConnInfo& connInfo) {
NIMBLE_LOGD("NimBLEServerCallbacks", "onMTUChange(): Default");
} // onMTUChange
uint32_t NimBLEServerCallbacks::onPassKeyRequest(){
NIMBLE_LOGD("NimBLEServerCallbacks", "onPassKeyRequest: default: 123456");
return 123456;
}
/*
void NimBLEServerCallbacks::onPassKeyNotify(uint32_t pass_key){
NIMBLE_LOGD("NimBLEServerCallbacks", "onPassKeyNotify: default: %d", pass_key);
}
} //onPassKeyRequest
bool NimBLEServerCallbacks::onSecurityRequest(){
NIMBLE_LOGD("NimBLEServerCallbacks", "onSecurityRequest: default: true");
return true;
}
*/
void NimBLEServerCallbacks::onAuthenticationComplete(ble_gap_conn_desc*){
void NimBLEServerCallbacks::onAuthenticationComplete(NimBLEConnInfo& connInfo){
NIMBLE_LOGD("NimBLEServerCallbacks", "onAuthenticationComplete: default");
}
} // onAuthenticationComplete
bool NimBLEServerCallbacks::onConfirmPIN(uint32_t pin){
NIMBLE_LOGD("NimBLEServerCallbacks", "onConfirmPIN: default: true");
return true;
}
} // onConfirmPIN
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL */

View file

@ -127,41 +127,28 @@ public:
* @brief Handle a client connection.
* This is called when a client connects.
* @param [in] pServer A pointer to the %BLE server that received the client connection.
* @param [in] connInfo A reference to a NimBLEConnInfo instance with information
* about the peer connection parameters.
*/
virtual void onConnect(NimBLEServer* pServer);
virtual void onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo);
/**
* @brief Handle a client connection.
* This is called when a client connects.
* @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.
*/
virtual void onDisconnect(NimBLEServer* pServer);
/**
* @brief Handle a client disconnection.
* This is called when a client discconnects.
* @param [in] pServer A pointer to the %BLE server that received the client disconnection.
* @param [in] desc A pointer to the connection description structure containing information
* about the connection.
* @param [in] connInfo A reference to a NimBLEConnInfo instance with information
* about the peer connection parameters.
* @param [in] reason The reason code for the disconnection.
*/
virtual void onDisconnect(NimBLEServer* pServer, ble_gap_conn_desc* desc);
virtual void onDisconnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo, int reason);
/**
/**
* @brief Called when the connection MTU changes.
* @param [in] MTU The new MTU value.
* @param [in] desc A pointer to the connection description structure containing information
* about the connection.
* @param [in] connInfo A reference to a NimBLEConnInfo instance with information
* about the peer connection parameters.
*/
virtual void onMTUChange(uint16_t MTU, ble_gap_conn_desc* desc);
virtual void onMTUChange(uint16_t MTU, NimBLEConnInfo& connInfo);
/**
* @brief Called when a client requests a passkey for pairing.
@ -169,15 +156,12 @@ public:
*/
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.
* @param [in] connInfo A reference to a NimBLEConnInfo instance with information
* about the peer connection parameters.
*/
virtual void onAuthenticationComplete(ble_gap_conn_desc* desc);
virtual void onAuthenticationComplete(NimBLEConnInfo& connInfo);
/**
* @brief Called when using numeric comparision for pairing.