mirror of https://github.com/arendst/Tasmota.git
NimBLE v1.36 (#14744)
This commit is contained in:
parent
33a779f105
commit
5a70ca1562
|
@ -2,6 +2,17 @@
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## [1.3.6] - 2022-01-18
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- When retrieving attributes from a server fails with a 128bit UUID containing the ble base UUID another attempt will be made with the 16bit version of the UUID.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Memory leak when services are changed on server devices.
|
||||||
|
- Rare crashing that occurs when BLE commands are sent from ISR context using IPC.
|
||||||
|
- Crashing caused by uninitialized disconnect timer in client.
|
||||||
|
- Potential crash due to unintialized advertising callback pointer.
|
||||||
|
|
||||||
## [1.3.5] - 2022-01-14
|
## [1.3.5] - 2022-01-14
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -6,6 +6,24 @@ Sets the number of simultaneous connections (esp controller max is 9)
|
||||||
- Default value is 3
|
- Default value is 3
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
|
`CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED`
|
||||||
|
|
||||||
|
Enable/disable storing the timestamp when an attribute value is updated
|
||||||
|
This allows for checking the last update time using getTimeStamp() or getValue(time_t*)
|
||||||
|
If disabled, the timestamp returned from these functions will be 0.
|
||||||
|
Disabling timestamps will reduce the memory used for each value.
|
||||||
|
1 = Enabled, 0 = Disabled; Default = Disabled
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
`CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH`
|
||||||
|
|
||||||
|
Set the default allocation size (bytes) for each attribute.
|
||||||
|
If not specified when the constructor is called. This is also the size used when a remote
|
||||||
|
characteristic or descriptor is constructed before a value is read/notifed.
|
||||||
|
Increasing this will reduce reallocations but increase memory footprint.
|
||||||
|
Default value is 20. Range: 1 : 512 (BLE_ATT_ATTR_MAX_LEN)
|
||||||
|
<br/>
|
||||||
|
|
||||||
`CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU`
|
`CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU`
|
||||||
|
|
||||||
Sets the default MTU size.
|
Sets the default MTU size.
|
||||||
|
@ -24,6 +42,13 @@ If defined, enables debug log messages from the NimBLE host
|
||||||
- Uses approx. 32kB of flash memory.
|
- Uses approx. 32kB of flash memory.
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
|
`CONFIG_NIMBLE_CPP_LOG_LEVEL`
|
||||||
|
|
||||||
|
Define to set the debug log message level from the NimBLE CPP Wrapper.
|
||||||
|
If not defined it will use the same value as the Arduino core debug level.
|
||||||
|
Values: 0 = NONE, 1 = ERROR, 2 = WARNING, 3 = INFO, 4+ = DEBUG
|
||||||
|
<br/>
|
||||||
|
|
||||||
`CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT`
|
`CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT`
|
||||||
|
|
||||||
If defined, NimBLE host return codes will be printed as text in debug log messages.
|
If defined, NimBLE host return codes will be printed as text in debug log messages.
|
||||||
|
|
|
@ -69,7 +69,9 @@ Now takes 2 optional parameters, the first is the duration to advertise for (in
|
||||||
that is invoked when advertsing ends and takes a pointer to a `NimBLEAdvertising` object (similar to the `NimBLEScan::start` API).
|
that is invoked when advertsing ends and takes a pointer to a `NimBLEAdvertising` object (similar to the `NimBLEScan::start` API).
|
||||||
|
|
||||||
This provides an opportunity to update the advertisment data if desired.
|
This provides an opportunity to update the advertisment data if desired.
|
||||||
<br/>
|
|
||||||
|
Also now returns a bool value to indicate if advertising successfully started or not.
|
||||||
|
<br/>
|
||||||
|
|
||||||
<a name="client"></a>
|
<a name="client"></a>
|
||||||
# Client
|
# Client
|
||||||
|
@ -100,8 +102,18 @@ Has been **deprecated** as now the internally stored characteristic value is upd
|
||||||
`NimBLERemoteCharacteristic::subscribe` and `NimBLERemoteCharacteristic::unsubscribe` have been implemented to replace it.
|
`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
|
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.
|
get the last updated value any time.
|
||||||
|
<br/>
|
||||||
|
|
||||||
In addition `NimBLERemoteCharacteristic::readValue` and `NimBLERemoteCharacteristic::getValue` take an optional timestamp parameter which will update it's value with
|
The `notifiy_callback` function is now defined as a `std::function` to take advantage of using `std::bind` to specifiy a class member function for the callback.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
using namespace std::placeholders;
|
||||||
|
notify_callback callback = std::bind(&<ClassName>::<memberFunctionCallbackName>, this, _1, _2, _3, _4);
|
||||||
|
<remoteCharacteristicInstance>->subscribe(true, callback);
|
||||||
|
```
|
||||||
|
|
||||||
|
`NimBLERemoteCharacteristic::readValue` and `NimBLERemoteCharacteristic::getValue` take an optional timestamp parameter which will update it's value with
|
||||||
the time the last value was recieved.
|
the time the last value was recieved.
|
||||||
|
|
||||||
> NimBLEClient::getService
|
> NimBLEClient::getService
|
||||||
|
|
|
@ -127,7 +127,7 @@ class CharacteristicCallbacks: public NimBLECharacteristicCallbacks {
|
||||||
/** Handler class for descriptor actions */
|
/** Handler class for descriptor actions */
|
||||||
class DescriptorCallbacks : public NimBLEDescriptorCallbacks {
|
class DescriptorCallbacks : public NimBLEDescriptorCallbacks {
|
||||||
void onWrite(NimBLEDescriptor* pDescriptor) {
|
void onWrite(NimBLEDescriptor* pDescriptor) {
|
||||||
std::string dscVal((char*)pDescriptor->getValue(), pDescriptor->getLength());
|
std::string dscVal = pDescriptor->getValue();
|
||||||
Serial.print("Descriptor witten value:");
|
Serial.print("Descriptor witten value:");
|
||||||
Serial.println(dscVal.c_str());
|
Serial.println(dscVal.c_str());
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"name": "NimBLE-Arduino",
|
"name": "NimBLE-Arduino",
|
||||||
"keywords": "esp32, bluetooth",
|
"keywords": "esp32, bluetooth",
|
||||||
"description": "Bluetooth low energy (BLE) library for arduino-esp32 based on NimBLE",
|
"description": "Bluetooth low energy (BLE) library for arduino-esp32 based on NimBLE",
|
||||||
"version": "1.3.5",
|
"version": "1.3.6",
|
||||||
"frameworks": "arduino",
|
"frameworks": "arduino",
|
||||||
"platforms": "espressif32"
|
"platforms": "espressif32"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
name=NimBLE-Arduino
|
name=NimBLE-Arduino
|
||||||
version=1.3.5
|
version=1.3.6
|
||||||
author=h2zero
|
author=h2zero
|
||||||
maintainer=h2zero <powellperalta@gmail.com>
|
maintainer=h2zero <powellperalta@gmail.com>
|
||||||
sentence=Bluetooth low energy (BLE) library for arduino-esp32 based on NimBLE.
|
sentence=Bluetooth low energy (BLE) library for arduino-esp32 based on NimBLE.
|
||||||
|
|
|
@ -45,13 +45,8 @@
|
||||||
/* of data as per HID Class standard */
|
/* of data as per HID Class standard */
|
||||||
|
|
||||||
/* Main items */
|
/* Main items */
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#define HIDINPUT(size) (0x80 | size)
|
||||||
#define HIDINPUT(size) (0x80 | size)
|
#define HIDOUTPUT(size) (0x90 | size)
|
||||||
#define HIDOUTPUT(size) (0x90 | size)
|
|
||||||
#else
|
|
||||||
#define INPUT(size) (0x80 | size)
|
|
||||||
#define OUTPUT(size) (0x90 | size)
|
|
||||||
#endif
|
|
||||||
#define FEATURE(size) (0xb0 | size)
|
#define FEATURE(size) (0xb0 | size)
|
||||||
#define COLLECTION(size) (0xa0 | size)
|
#define COLLECTION(size) (0xa0 | size)
|
||||||
#define END_COLLECTION(size) (0xc0 | size)
|
#define END_COLLECTION(size) (0xc0 | size)
|
||||||
|
|
|
@ -16,11 +16,8 @@
|
||||||
* See also:
|
* See also:
|
||||||
* https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml
|
* https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml
|
||||||
*/
|
*/
|
||||||
#include "sdkconfig.h"
|
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
|
||||||
|
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||||
|
|
||||||
#include "NimBLE2904.h"
|
#include "NimBLE2904.h"
|
||||||
|
|
||||||
|
@ -86,5 +83,4 @@ void NimBLE2904::setUnit(uint16_t unit) {
|
||||||
setValue((uint8_t*) &m_data, sizeof(m_data));
|
setValue((uint8_t*) &m_data, sizeof(m_data));
|
||||||
} // setUnit
|
} // setUnit
|
||||||
|
|
||||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL */
|
||||||
#endif
|
|
||||||
|
|
|
@ -14,11 +14,8 @@
|
||||||
|
|
||||||
#ifndef MAIN_NIMBLE2904_H_
|
#ifndef MAIN_NIMBLE2904_H_
|
||||||
#define MAIN_NIMBLE2904_H_
|
#define MAIN_NIMBLE2904_H_
|
||||||
#include "sdkconfig.h"
|
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
|
||||||
|
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||||
|
|
||||||
#include "NimBLEDescriptor.h"
|
#include "NimBLEDescriptor.h"
|
||||||
|
|
||||||
|
@ -82,6 +79,5 @@ private:
|
||||||
BLE2904_Data m_data;
|
BLE2904_Data m_data;
|
||||||
}; // BLE2904
|
}; // BLE2904
|
||||||
|
|
||||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL */
|
||||||
#endif /* CONFIG_BT_ENABLED */
|
|
||||||
#endif /* MAIN_NIMBLE2904_H_ */
|
#endif /* MAIN_NIMBLE2904_H_ */
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
* Created on: Jul 2, 2017
|
* Created on: Jul 2, 2017
|
||||||
* Author: kolban
|
* Author: kolban
|
||||||
*/
|
*/
|
||||||
#include "sdkconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
#if defined(CONFIG_BT_ENABLED)
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
|
@ -14,10 +14,15 @@
|
||||||
|
|
||||||
#ifndef COMPONENTS_NIMBLEADDRESS_H_
|
#ifndef COMPONENTS_NIMBLEADDRESS_H_
|
||||||
#define COMPONENTS_NIMBLEADDRESS_H_
|
#define COMPONENTS_NIMBLEADDRESS_H_
|
||||||
#include "sdkconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
#if defined(CONFIG_BT_ENABLED)
|
||||||
|
|
||||||
|
#if defined(CONFIG_NIMBLE_CPP_IDF)
|
||||||
#include "nimble/ble.h"
|
#include "nimble/ble.h"
|
||||||
|
#else
|
||||||
|
#include "nimble/nimble/include/nimble/ble.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/**** FIX COMPILATION ****/
|
/**** FIX COMPILATION ****/
|
||||||
#undef min
|
#undef min
|
||||||
#undef max
|
#undef max
|
||||||
|
|
|
@ -11,11 +11,9 @@
|
||||||
* Created on: Jul 3, 2017
|
* Created on: Jul 3, 2017
|
||||||
* Author: kolban
|
* Author: kolban
|
||||||
*/
|
*/
|
||||||
#include "sdkconfig.h"
|
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
|
||||||
|
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
||||||
|
|
||||||
#include "NimBLEDevice.h"
|
#include "NimBLEDevice.h"
|
||||||
#include "NimBLEAdvertisedDevice.h"
|
#include "NimBLEAdvertisedDevice.h"
|
||||||
|
@ -783,7 +781,5 @@ size_t NimBLEAdvertisedDevice::getPayloadLength() {
|
||||||
return m_payload.size();
|
return m_payload.size();
|
||||||
} // getPayloadLength
|
} // getPayloadLength
|
||||||
|
|
||||||
|
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL */
|
||||||
#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
|
||||||
#endif /* CONFIG_BT_ENABLED */
|
|
||||||
|
|
||||||
|
|
|
@ -14,20 +14,22 @@
|
||||||
|
|
||||||
#ifndef COMPONENTS_NIMBLEADVERTISEDDEVICE_H_
|
#ifndef COMPONENTS_NIMBLEADVERTISEDDEVICE_H_
|
||||||
#define COMPONENTS_NIMBLEADVERTISEDDEVICE_H_
|
#define COMPONENTS_NIMBLEADVERTISEDDEVICE_H_
|
||||||
#include "sdkconfig.h"
|
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
|
||||||
|
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
||||||
|
|
||||||
#include "NimBLEAddress.h"
|
#include "NimBLEAddress.h"
|
||||||
#include "NimBLEScan.h"
|
#include "NimBLEScan.h"
|
||||||
#include "NimBLEUUID.h"
|
#include "NimBLEUUID.h"
|
||||||
|
|
||||||
|
#if defined(CONFIG_NIMBLE_CPP_IDF)
|
||||||
#include "host/ble_hs_adv.h"
|
#include "host/ble_hs_adv.h"
|
||||||
|
#else
|
||||||
|
#include "nimble/nimble/host/include/host/ble_hs_adv.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
|
||||||
class NimBLEScan;
|
class NimBLEScan;
|
||||||
|
@ -171,6 +173,5 @@ public:
|
||||||
virtual void onResult(NimBLEAdvertisedDevice* advertisedDevice) = 0;
|
virtual void onResult(NimBLEAdvertisedDevice* advertisedDevice) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_OBSERVER */
|
||||||
#endif /* CONFIG_BT_ENABLED */
|
|
||||||
#endif /* COMPONENTS_NIMBLEADVERTISEDDEVICE_H_ */
|
#endif /* COMPONENTS_NIMBLEADVERTISEDDEVICE_H_ */
|
||||||
|
|
|
@ -13,13 +13,14 @@
|
||||||
* Author: kolban
|
* Author: kolban
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#include "sdkconfig.h"
|
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
|
||||||
|
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
|
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
|
||||||
|
|
||||||
|
#if defined(CONFIG_NIMBLE_CPP_IDF)
|
||||||
#include "services/gap/ble_svc_gap.h"
|
#include "services/gap/ble_svc_gap.h"
|
||||||
|
#else
|
||||||
|
#include "nimble/nimble/host/services/gap/include/services/gap/ble_svc_gap.h"
|
||||||
|
#endif
|
||||||
#include "NimBLEAdvertising.h"
|
#include "NimBLEAdvertising.h"
|
||||||
#include "NimBLEDevice.h"
|
#include "NimBLEDevice.h"
|
||||||
#include "NimBLEServer.h"
|
#include "NimBLEServer.h"
|
||||||
|
@ -68,6 +69,7 @@ void NimBLEAdvertising::reset() {
|
||||||
m_advDataSet = false;
|
m_advDataSet = false;
|
||||||
// Set this to non-zero to prevent auto start if host reset before started by app.
|
// Set this to non-zero to prevent auto start if host reset before started by app.
|
||||||
m_duration = BLE_HS_FOREVER;
|
m_duration = BLE_HS_FOREVER;
|
||||||
|
m_advCompCB = nullptr;
|
||||||
} // reset
|
} // reset
|
||||||
|
|
||||||
|
|
||||||
|
@ -653,12 +655,8 @@ bool NimBLEAdvertising::start(uint32_t duration, void (*advCompleteCB)(NimBLEAdv
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(rc != 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
NIMBLE_LOGD(LOG_TAG, "<< Advertising start");
|
NIMBLE_LOGD(LOG_TAG, "<< Advertising start");
|
||||||
return true;
|
return (rc == 0);
|
||||||
} // start
|
} // start
|
||||||
|
|
||||||
|
|
||||||
|
@ -1028,5 +1026,4 @@ std::string NimBLEAdvertisementData::getPayload() {
|
||||||
return m_payload;
|
return m_payload;
|
||||||
} // getPayload
|
} // getPayload
|
||||||
|
|
||||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_BROADCASTER */
|
||||||
#endif /* CONFIG_BT_ENABLED */
|
|
||||||
|
|
|
@ -14,13 +14,15 @@
|
||||||
|
|
||||||
#ifndef MAIN_BLEADVERTISING_H_
|
#ifndef MAIN_BLEADVERTISING_H_
|
||||||
#define MAIN_BLEADVERTISING_H_
|
#define MAIN_BLEADVERTISING_H_
|
||||||
#include "sdkconfig.h"
|
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
|
||||||
|
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
|
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
|
||||||
|
|
||||||
|
#if defined(CONFIG_NIMBLE_CPP_IDF)
|
||||||
#include "host/ble_gap.h"
|
#include "host/ble_gap.h"
|
||||||
|
#else
|
||||||
|
#include "nimble/nimble/host/include/host/ble_gap.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/**** FIX COMPILATION ****/
|
/**** FIX COMPILATION ****/
|
||||||
#undef min
|
#undef min
|
||||||
#undef max
|
#undef max
|
||||||
|
@ -132,6 +134,5 @@ private:
|
||||||
std::vector<uint8_t> m_uri;
|
std::vector<uint8_t> m_uri;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_BROADCASTER */
|
||||||
#endif /* CONFIG_BT_ENABLED */
|
|
||||||
#endif /* MAIN_BLEADVERTISING_H_ */
|
#endif /* MAIN_BLEADVERTISING_H_ */
|
||||||
|
|
|
@ -0,0 +1,447 @@
|
||||||
|
/*
|
||||||
|
* NimBLEAttValue.h
|
||||||
|
*
|
||||||
|
* Created: on March 18, 2021
|
||||||
|
* Author H2zero
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MAIN_NIMBLEATTVALUE_H_
|
||||||
|
#define MAIN_NIMBLEATTVALUE_H_
|
||||||
|
#include "nimconfig.h"
|
||||||
|
#if defined(CONFIG_BT_ENABLED)
|
||||||
|
|
||||||
|
#ifdef NIMBLE_CPP_ARDUINO_STRING_AVAILABLE
|
||||||
|
#include <Arduino.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "NimBLELog.h"
|
||||||
|
|
||||||
|
/**** FIX COMPILATION ****/
|
||||||
|
#undef min
|
||||||
|
#undef max
|
||||||
|
/**************************/
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#ifndef CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED
|
||||||
|
# define CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED
|
||||||
|
# include <time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH)
|
||||||
|
# define CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH 20
|
||||||
|
#elif CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH > BLE_ATT_ATTR_MAX_LEN
|
||||||
|
# error CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH cannot be larger than 512 (BLE_ATT_ATTR_MAX_LEN)
|
||||||
|
#elif CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH < 1
|
||||||
|
# error CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH cannot be less than 1; Range = 1 : 512
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Used to determine if the type passed to a template has a c_str() and length() method. */
|
||||||
|
template <typename T, typename = void, typename = void>
|
||||||
|
struct Has_c_str_len : std::false_type {};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct Has_c_str_len<T, decltype(void(std::declval<T &>().c_str())),
|
||||||
|
decltype(void(std::declval<T &>().length()))> : std::true_type {};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A specialized container class to hold BLE attribute values.
|
||||||
|
* @details This class is designed to be more memory efficient than using\n
|
||||||
|
* standard container types for value storage, while being convertable to\n
|
||||||
|
* many different container classes.
|
||||||
|
*/
|
||||||
|
class NimBLEAttValue
|
||||||
|
{
|
||||||
|
uint8_t* m_attr_value = nullptr;
|
||||||
|
uint16_t m_attr_max_len = 0;
|
||||||
|
uint16_t m_attr_len = 0;
|
||||||
|
uint16_t m_capacity = 0;
|
||||||
|
#if CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED
|
||||||
|
time_t m_timestamp = 0;
|
||||||
|
#endif
|
||||||
|
void deepCopy(const NimBLEAttValue & source);
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Default constructor.
|
||||||
|
* @param[in] init_len The initial size in bytes.
|
||||||
|
* @param[in] max_len The max size in bytes that the value can be.
|
||||||
|
*/
|
||||||
|
NimBLEAttValue(uint16_t init_len = CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH,
|
||||||
|
uint16_t max_len = BLE_ATT_ATTR_MAX_LEN);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Construct with an initial value from a buffer.
|
||||||
|
* @param value A pointer to the initial value to set.
|
||||||
|
* @param[in] len The size in bytes of the value to set.
|
||||||
|
* @param[in] max_len The max size in bytes that the value can be.
|
||||||
|
*/
|
||||||
|
NimBLEAttValue(const uint8_t *value, uint16_t len,
|
||||||
|
uint16_t max_len = BLE_ATT_ATTR_MAX_LEN);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Construct with an initializer list.
|
||||||
|
* @param list An initializer list containing the initial value to set.
|
||||||
|
* @param[in] max_len The max size in bytes that the value can be.
|
||||||
|
*/
|
||||||
|
NimBLEAttValue(std::initializer_list<uint8_t> list,
|
||||||
|
uint16_t max_len = BLE_ATT_ATTR_MAX_LEN)
|
||||||
|
:NimBLEAttValue(list.begin(), (uint16_t)list.size(), max_len){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Construct with an initial value from a const char string.
|
||||||
|
* @param value A pointer to the initial value to set.
|
||||||
|
* @param[in] max_len The max size in bytes that the value can be.
|
||||||
|
*/
|
||||||
|
NimBLEAttValue(const char *value, uint16_t max_len = BLE_ATT_ATTR_MAX_LEN)
|
||||||
|
:NimBLEAttValue((uint8_t*)value, (uint16_t)strlen(value), max_len){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Construct with an initial value from a std::string.
|
||||||
|
* @param str A std::string containing to the initial value to set.
|
||||||
|
* @param[in] max_len The max size in bytes that the value can be.
|
||||||
|
*/
|
||||||
|
NimBLEAttValue(const std::string str, uint16_t max_len = BLE_ATT_ATTR_MAX_LEN)
|
||||||
|
:NimBLEAttValue((uint8_t*)str.data(), (uint16_t)str.length(), max_len){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Construct with an initial value from a std::vector<uint8_t>.
|
||||||
|
* @param vec A std::vector<uint8_t> containing to the initial value to set.
|
||||||
|
* @param[in] max_len The max size in bytes that the value can be.
|
||||||
|
*/
|
||||||
|
NimBLEAttValue(const std::vector<uint8_t> vec, uint16_t max_len = BLE_ATT_ATTR_MAX_LEN)
|
||||||
|
:NimBLEAttValue(&vec[0], (uint16_t)vec.size(), max_len){}
|
||||||
|
|
||||||
|
#ifdef NIMBLE_CPP_ARDUINO_STRING_AVAILABLE
|
||||||
|
/**
|
||||||
|
* @brief Construct with an initial value from an Arduino String.
|
||||||
|
* @param str An Arduino String containing to the initial value to set.
|
||||||
|
* @param[in] max_len The max size in bytes that the value can be.
|
||||||
|
*/
|
||||||
|
NimBLEAttValue(const String str, uint16_t max_len = BLE_ATT_ATTR_MAX_LEN)
|
||||||
|
:NimBLEAttValue((uint8_t*)str.c_str(), str.length(), max_len){}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** @brief Copy constructor */
|
||||||
|
NimBLEAttValue(const NimBLEAttValue & source) { deepCopy(source); }
|
||||||
|
|
||||||
|
/** @brief Move constructor */
|
||||||
|
NimBLEAttValue(NimBLEAttValue && source) { *this = std::move(source); }
|
||||||
|
|
||||||
|
/** @brief Destructor */
|
||||||
|
~NimBLEAttValue();
|
||||||
|
|
||||||
|
/** @brief Returns the max size in bytes */
|
||||||
|
uint16_t max_size() const { return m_attr_max_len; }
|
||||||
|
|
||||||
|
/** @brief Returns the currently allocated capacity in bytes */
|
||||||
|
uint16_t capacity() const { return m_capacity; }
|
||||||
|
|
||||||
|
/** @brief Returns the current length of the value in bytes */
|
||||||
|
uint16_t length() const { return m_attr_len; }
|
||||||
|
|
||||||
|
/** @brief Returns the current size of the value in bytes */
|
||||||
|
uint16_t size() const { return m_attr_len; }
|
||||||
|
|
||||||
|
/** @brief Returns a pointer to the internal buffer of the value */
|
||||||
|
const uint8_t* data() const { return m_attr_value; }
|
||||||
|
|
||||||
|
/** @brief Returns a pointer to the internal buffer of the value as a const char* */
|
||||||
|
const char* c_str() const { return (const char*)m_attr_value; }
|
||||||
|
|
||||||
|
/** @brief Iterator begin */
|
||||||
|
const uint8_t* begin() const { return m_attr_value; }
|
||||||
|
|
||||||
|
/** @brief Iterator end */
|
||||||
|
const uint8_t* end() const { return m_attr_value + m_attr_len; }
|
||||||
|
|
||||||
|
#if CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED
|
||||||
|
/** @brief Returns a timestamp of when the value was last updated */
|
||||||
|
time_t getTimeStamp() const { return m_timestamp; }
|
||||||
|
|
||||||
|
/** @brief Set the timestamp to the current time */
|
||||||
|
void setTimeStamp() { m_timestamp = time(nullptr); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the timestamp to the specified time
|
||||||
|
* @param[in] t The timestamp value to set
|
||||||
|
*/
|
||||||
|
void setTimeStamp(time_t t) { m_timestamp = t; }
|
||||||
|
#else
|
||||||
|
time_t getTimeStamp() const { return 0; }
|
||||||
|
void setTimeStamp() { }
|
||||||
|
void setTimeStamp(time_t t) { }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the value from a buffer
|
||||||
|
* @param[in] value A ponter to a buffer containing the value.
|
||||||
|
* @param[in] len The length of the value in bytes.
|
||||||
|
* @returns True if successful.
|
||||||
|
*/
|
||||||
|
bool setValue(const uint8_t *value, uint16_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set value to the value of const char*.
|
||||||
|
* @param [in] s A ponter to a const char value to set.
|
||||||
|
*/
|
||||||
|
bool setValue(const char* s) {
|
||||||
|
return setValue((uint8_t*)s, (uint16_t)strlen(s)); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get a pointer to the value buffer with timestamp.
|
||||||
|
* @param[in] timestamp A ponter to a time_t variable to store the timestamp.
|
||||||
|
* @returns A pointer to the internal value buffer.
|
||||||
|
*/
|
||||||
|
const uint8_t* getValue(time_t *timestamp);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Append data to the value.
|
||||||
|
* @param[in] value A ponter to a data buffer with the value to append.
|
||||||
|
* @param[in] len The length of the value to append in bytes.
|
||||||
|
* @returns A reference to the appended NimBLEAttValue.
|
||||||
|
*/
|
||||||
|
NimBLEAttValue& append(const uint8_t *value, uint16_t len);
|
||||||
|
|
||||||
|
|
||||||
|
/*********************** Template Functions ************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Template to set value to the value of <type\>val.
|
||||||
|
* @param [in] s The <type\>value to set.
|
||||||
|
* @details Only used for types without a `c_str()` method.
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
#ifdef _DOXYGEN_
|
||||||
|
bool
|
||||||
|
#else
|
||||||
|
typename std::enable_if<!Has_c_str_len<T>::value, bool>::type
|
||||||
|
#endif
|
||||||
|
setValue(const T &s) {
|
||||||
|
return setValue((uint8_t*)&s, sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Template to set value to the value of <type\>val.
|
||||||
|
* @param [in] s The <type\>value to set.
|
||||||
|
* @details Only used if the <type\> has a `c_str()` method.
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
#ifdef _DOXYGEN_
|
||||||
|
bool
|
||||||
|
#else
|
||||||
|
typename std::enable_if<Has_c_str_len<T>::value, bool>::type
|
||||||
|
#endif
|
||||||
|
setValue(const T & s) {
|
||||||
|
return setValue((uint8_t*)s.c_str(), (uint16_t)s.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Template to return the value as a <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\n
|
||||||
|
* <tt>sizeof(<type\>)</tt>.
|
||||||
|
* @return The data converted to <type\> or NULL if skipSizeCheck is false and the data is\n
|
||||||
|
* less than <tt>sizeof(<type\>)</tt>.
|
||||||
|
* @details <b>Use:</b> <tt>getValue<type>(×tamp, skipSizeCheck);</tt>
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
T getValue(time_t *timestamp = nullptr, bool skipSizeCheck = false) {
|
||||||
|
if(!skipSizeCheck && size() < sizeof(T)) {
|
||||||
|
return T();
|
||||||
|
}
|
||||||
|
return *((T *)getValue(timestamp));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*********************** Operators ************************/
|
||||||
|
|
||||||
|
/** @brief Subscript operator */
|
||||||
|
uint8_t operator [](int pos) const {
|
||||||
|
assert(pos < m_attr_len && "out of range"); return m_attr_value[pos]; }
|
||||||
|
|
||||||
|
/** @brief Operator; Get the value as a std::vector<uint8_t>. */
|
||||||
|
operator std::vector<uint8_t>() const {
|
||||||
|
return std::vector<uint8_t>(m_attr_value, m_attr_value + m_attr_len); }
|
||||||
|
|
||||||
|
/** @brief Operator; Get the value as a std::string. */
|
||||||
|
operator std::string() const {
|
||||||
|
return std::string((char*)m_attr_value, m_attr_len); }
|
||||||
|
|
||||||
|
/** @brief Operator; Get the value as a const uint8_t*. */
|
||||||
|
operator const uint8_t*() const { return m_attr_value; }
|
||||||
|
|
||||||
|
/** @brief Operator; Append another NimBLEAttValue. */
|
||||||
|
NimBLEAttValue& operator +=(const NimBLEAttValue & source) {
|
||||||
|
return append(source.data(), source.size()); }
|
||||||
|
|
||||||
|
/** @brief Operator; Set the value from a std::string source. */
|
||||||
|
NimBLEAttValue& operator =(const std::string & source) {
|
||||||
|
setValue((uint8_t*)source.data(), (uint16_t)source.size()); return *this; }
|
||||||
|
|
||||||
|
/** @brief Move assignment operator */
|
||||||
|
NimBLEAttValue& operator =(NimBLEAttValue && source);
|
||||||
|
|
||||||
|
/** @brief Copy assignment operator */
|
||||||
|
NimBLEAttValue& operator =(const NimBLEAttValue & source);
|
||||||
|
|
||||||
|
/** @brief Equality operator */
|
||||||
|
bool operator ==(const NimBLEAttValue & source) {
|
||||||
|
return (m_attr_len == source.size()) ?
|
||||||
|
memcmp(m_attr_value, source.data(), m_attr_len) == 0 : false; }
|
||||||
|
|
||||||
|
/** @brief Inequality operator */
|
||||||
|
bool operator !=(const NimBLEAttValue & source){ return !(*this == source); }
|
||||||
|
|
||||||
|
#ifdef NIMBLE_CPP_ARDUINO_STRING_AVAILABLE
|
||||||
|
/** @brief Operator; Get the value as an Arduino String value. */
|
||||||
|
operator String() const { return String((char*)m_attr_value); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline NimBLEAttValue::NimBLEAttValue(uint16_t init_len, uint16_t max_len) {
|
||||||
|
m_attr_value = (uint8_t*)calloc(init_len + 1, 1);
|
||||||
|
assert(m_attr_value && "No Mem");
|
||||||
|
m_attr_max_len = std::min(BLE_ATT_ATTR_MAX_LEN, (int)max_len);
|
||||||
|
m_attr_len = 0;
|
||||||
|
m_capacity = init_len;
|
||||||
|
setTimeStamp(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline NimBLEAttValue::NimBLEAttValue(const uint8_t *value, uint16_t len, uint16_t max_len)
|
||||||
|
: NimBLEAttValue(len, max_len) {
|
||||||
|
memcpy(m_attr_value, value, len);
|
||||||
|
m_attr_value[len] = '\0';
|
||||||
|
m_attr_len = len;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline NimBLEAttValue::~NimBLEAttValue() {
|
||||||
|
if(m_attr_value != nullptr) {
|
||||||
|
free(m_attr_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline NimBLEAttValue& NimBLEAttValue::operator =(NimBLEAttValue && source) {
|
||||||
|
if (this != &source){
|
||||||
|
free(m_attr_value);
|
||||||
|
|
||||||
|
m_attr_value = source.m_attr_value;
|
||||||
|
m_attr_max_len = source.m_attr_max_len;
|
||||||
|
m_attr_len = source.m_attr_len;
|
||||||
|
m_capacity = source.m_capacity;
|
||||||
|
setTimeStamp(source.getTimeStamp());
|
||||||
|
source.m_attr_value = nullptr;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline NimBLEAttValue& NimBLEAttValue::operator =(const NimBLEAttValue & source) {
|
||||||
|
if (this != &source) {
|
||||||
|
deepCopy(source);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void NimBLEAttValue::deepCopy(const NimBLEAttValue & source) {
|
||||||
|
uint8_t* res = (uint8_t*)realloc( m_attr_value, source.m_capacity + 1);
|
||||||
|
assert(res && "deepCopy: realloc failed");
|
||||||
|
|
||||||
|
ble_npl_hw_enter_critical();
|
||||||
|
m_attr_value = res;
|
||||||
|
m_attr_max_len = source.m_attr_max_len;
|
||||||
|
m_attr_len = source.m_attr_len;
|
||||||
|
m_capacity = source.m_capacity;
|
||||||
|
setTimeStamp(source.getTimeStamp());
|
||||||
|
memcpy(m_attr_value, source.m_attr_value, m_attr_len + 1);
|
||||||
|
ble_npl_hw_exit_critical(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const uint8_t* NimBLEAttValue::getValue(time_t *timestamp) {
|
||||||
|
if(timestamp != nullptr) {
|
||||||
|
#if CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED
|
||||||
|
*timestamp = m_timestamp;
|
||||||
|
#else
|
||||||
|
*timestamp = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return m_attr_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool NimBLEAttValue::setValue(const uint8_t *value, uint16_t len) {
|
||||||
|
if (len > m_attr_max_len) {
|
||||||
|
NIMBLE_LOGE("NimBLEAttValue", "value exceeds max, len=%u, max=%u",
|
||||||
|
len, m_attr_max_len);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *res = m_attr_value;
|
||||||
|
if (len > m_capacity) {
|
||||||
|
res = (uint8_t*)realloc(m_attr_value, (len + 1));
|
||||||
|
m_capacity = len;
|
||||||
|
}
|
||||||
|
assert(res && "setValue: realloc failed");
|
||||||
|
|
||||||
|
#if CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED
|
||||||
|
time_t t = time(nullptr);
|
||||||
|
#else
|
||||||
|
time_t t = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ble_npl_hw_enter_critical();
|
||||||
|
m_attr_value = res;
|
||||||
|
memcpy(m_attr_value, value, len);
|
||||||
|
m_attr_value[len] = '\0';
|
||||||
|
m_attr_len = len;
|
||||||
|
setTimeStamp(t);
|
||||||
|
ble_npl_hw_exit_critical(0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline NimBLEAttValue& NimBLEAttValue::append(const uint8_t *value, uint16_t len) {
|
||||||
|
if (len < 1) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((m_attr_len + len) > m_attr_max_len) {
|
||||||
|
NIMBLE_LOGE("NimBLEAttValue", "val > max, len=%u, max=%u",
|
||||||
|
len, m_attr_max_len);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* res = m_attr_value;
|
||||||
|
uint16_t new_len = m_attr_len + len;
|
||||||
|
if (new_len > m_capacity) {
|
||||||
|
res = (uint8_t*)realloc(m_attr_value, (new_len + 1));
|
||||||
|
m_capacity = new_len;
|
||||||
|
}
|
||||||
|
assert(res && "append: realloc failed");
|
||||||
|
|
||||||
|
#if CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED
|
||||||
|
time_t t = time(nullptr);
|
||||||
|
#else
|
||||||
|
time_t t = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ble_npl_hw_enter_critical();
|
||||||
|
m_attr_value = res;
|
||||||
|
memcpy(m_attr_value + m_attr_len, value, len);
|
||||||
|
m_attr_len = new_len;
|
||||||
|
m_attr_value[m_attr_len] = '\0';
|
||||||
|
setTimeStamp(t);
|
||||||
|
ble_npl_hw_exit_critical(0);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /*(CONFIG_BT_ENABLED) */
|
||||||
|
#endif /* MAIN_NIMBLEATTVALUE_H_ */
|
|
@ -11,7 +11,7 @@
|
||||||
* Created on: Jan 4, 2018
|
* Created on: Jan 4, 2018
|
||||||
* Author: kolban
|
* Author: kolban
|
||||||
*/
|
*/
|
||||||
#include "sdkconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
#if defined(CONFIG_BT_ENABLED)
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
|
@ -9,11 +9,9 @@
|
||||||
* Created on: Jun 22, 2017
|
* Created on: Jun 22, 2017
|
||||||
* Author: kolban
|
* Author: kolban
|
||||||
*/
|
*/
|
||||||
#include "sdkconfig.h"
|
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
|
||||||
|
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||||
|
|
||||||
#include "NimBLECharacteristic.h"
|
#include "NimBLECharacteristic.h"
|
||||||
#include "NimBLE2904.h"
|
#include "NimBLE2904.h"
|
||||||
|
@ -32,27 +30,29 @@ static const char* LOG_TAG = "NimBLECharacteristic";
|
||||||
* @brief Construct a characteristic
|
* @brief Construct a characteristic
|
||||||
* @param [in] uuid - UUID (const char*) for the characteristic.
|
* @param [in] uuid - UUID (const char*) for the characteristic.
|
||||||
* @param [in] properties - Properties for the characteristic.
|
* @param [in] properties - Properties for the characteristic.
|
||||||
|
* @param [in] max_len - The maximum length in bytes that the characteristic value can hold. (Default: 512 bytes for esp32, 20 for all others).
|
||||||
* @param [in] pService - pointer to the service instance this characteristic belongs to.
|
* @param [in] pService - pointer to the service instance this characteristic belongs to.
|
||||||
*/
|
*/
|
||||||
NimBLECharacteristic::NimBLECharacteristic(const char* uuid, uint16_t properties, NimBLEService* pService)
|
NimBLECharacteristic::NimBLECharacteristic(const char* uuid, uint16_t properties,
|
||||||
: NimBLECharacteristic(NimBLEUUID(uuid), properties, pService) {
|
uint16_t max_len, NimBLEService* pService)
|
||||||
|
: NimBLECharacteristic(NimBLEUUID(uuid), properties, max_len, pService) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Construct a characteristic
|
* @brief Construct a characteristic
|
||||||
* @param [in] uuid - UUID for the characteristic.
|
* @param [in] uuid - UUID for the characteristic.
|
||||||
* @param [in] properties - Properties for the characteristic.
|
* @param [in] properties - Properties for the characteristic.
|
||||||
|
* @param [in] max_len - The maximum length in bytes that the characteristic value can hold. (Default: 512 bytes for esp32, 20 for all others).
|
||||||
* @param [in] pService - pointer to the service instance this characteristic belongs to.
|
* @param [in] pService - pointer to the service instance this characteristic belongs to.
|
||||||
*/
|
*/
|
||||||
NimBLECharacteristic::NimBLECharacteristic(const NimBLEUUID &uuid, uint16_t properties, NimBLEService* pService) {
|
NimBLECharacteristic::NimBLECharacteristic(const NimBLEUUID &uuid, uint16_t properties,
|
||||||
|
uint16_t max_len, NimBLEService* pService)
|
||||||
|
: m_value(std::min(CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH , (int)max_len), max_len) {
|
||||||
m_uuid = uuid;
|
m_uuid = uuid;
|
||||||
m_handle = NULL_HANDLE;
|
m_handle = NULL_HANDLE;
|
||||||
m_properties = properties;
|
m_properties = properties;
|
||||||
m_pCallbacks = &defaultCallback;
|
m_pCallbacks = &defaultCallback;
|
||||||
m_pService = pService;
|
m_pService = pService;
|
||||||
m_value = "";
|
|
||||||
m_valMux = portMUX_INITIALIZER_UNLOCKED;
|
|
||||||
m_timestamp = 0;
|
|
||||||
m_removed = 0;
|
m_removed = 0;
|
||||||
} // NimBLECharacteristic
|
} // NimBLECharacteristic
|
||||||
|
|
||||||
|
@ -234,17 +234,14 @@ NimBLEUUID NimBLECharacteristic::getUUID() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Retrieve the current value of the characteristic.
|
* @brief Retrieve the current value of the characteristic.
|
||||||
* @return A std::string containing the current characteristic value.
|
* @return The NimBLEAttValue containing the current characteristic value.
|
||||||
*/
|
*/
|
||||||
std::string NimBLECharacteristic::getValue(time_t *timestamp) {
|
NimBLEAttValue NimBLECharacteristic::getValue(time_t *timestamp) {
|
||||||
portENTER_CRITICAL(&m_valMux);
|
|
||||||
std::string retVal = m_value;
|
|
||||||
if(timestamp != nullptr) {
|
if(timestamp != nullptr) {
|
||||||
*timestamp = m_timestamp;
|
m_value.getValue(timestamp);
|
||||||
}
|
}
|
||||||
portEXIT_CRITICAL(&m_valMux);
|
|
||||||
|
|
||||||
return retVal;
|
return m_value;
|
||||||
} // getValue
|
} // getValue
|
||||||
|
|
||||||
|
|
||||||
|
@ -253,11 +250,7 @@ std::string NimBLECharacteristic::getValue(time_t *timestamp) {
|
||||||
* @return The length of the current characteristic data.
|
* @return The length of the current characteristic data.
|
||||||
*/
|
*/
|
||||||
size_t NimBLECharacteristic::getDataLength() {
|
size_t NimBLECharacteristic::getDataLength() {
|
||||||
portENTER_CRITICAL(&m_valMux);
|
return m_value.size();
|
||||||
size_t len = m_value.length();
|
|
||||||
portEXIT_CRITICAL(&m_valMux);
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -289,27 +282,27 @@ int NimBLECharacteristic::handleGapEvent(uint16_t conn_handle, uint16_t attr_han
|
||||||
pCharacteristic->m_pCallbacks->onRead(pCharacteristic, &desc);
|
pCharacteristic->m_pCallbacks->onRead(pCharacteristic, &desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
portENTER_CRITICAL(&pCharacteristic->m_valMux);
|
ble_npl_hw_enter_critical();
|
||||||
rc = os_mbuf_append(ctxt->om, (uint8_t*)pCharacteristic->m_value.data(),
|
rc = os_mbuf_append(ctxt->om, pCharacteristic->m_value.data(), pCharacteristic->m_value.size());
|
||||||
pCharacteristic->m_value.length());
|
ble_npl_hw_exit_critical(0);
|
||||||
portEXIT_CRITICAL(&pCharacteristic->m_valMux);
|
|
||||||
|
|
||||||
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
|
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
|
||||||
}
|
}
|
||||||
|
|
||||||
case BLE_GATT_ACCESS_OP_WRITE_CHR: {
|
case BLE_GATT_ACCESS_OP_WRITE_CHR: {
|
||||||
if (ctxt->om->om_len > BLE_ATT_ATTR_MAX_LEN) {
|
uint16_t att_max_len = pCharacteristic->m_value.max_size();
|
||||||
|
|
||||||
|
if (ctxt->om->om_len > att_max_len) {
|
||||||
return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
|
return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t buf[BLE_ATT_ATTR_MAX_LEN];
|
uint8_t buf[att_max_len];
|
||||||
size_t len = ctxt->om->om_len;
|
size_t len = ctxt->om->om_len;
|
||||||
memcpy(buf, ctxt->om->om_data,len);
|
memcpy(buf, ctxt->om->om_data,len);
|
||||||
|
|
||||||
os_mbuf *next;
|
os_mbuf *next;
|
||||||
next = SLIST_NEXT(ctxt->om, om_next);
|
next = SLIST_NEXT(ctxt->om, om_next);
|
||||||
while(next != NULL){
|
while(next != NULL){
|
||||||
if((len + next->om_len) > BLE_ATT_ATTR_MAX_LEN) {
|
if((len + next->om_len) > att_max_len) {
|
||||||
return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
|
return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
|
||||||
}
|
}
|
||||||
memcpy(&buf[len], next->om_data, next->om_len);
|
memcpy(&buf[len], next->om_data, next->om_len);
|
||||||
|
@ -389,26 +382,60 @@ void NimBLECharacteristic::setSubscribe(struct ble_gap_event *event) {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Send an indication.\n
|
* @brief Send an indication.
|
||||||
* An indication is a transmission of up to the first 20 bytes of the characteristic value.\n
|
|
||||||
* An indication will block waiting for a positive confirmation from the client.
|
|
||||||
*/
|
*/
|
||||||
void NimBLECharacteristic::indicate() {
|
void NimBLECharacteristic::indicate() {
|
||||||
NIMBLE_LOGD(LOG_TAG, ">> indicate: length: %d", getDataLength());
|
|
||||||
notify(false);
|
notify(false);
|
||||||
NIMBLE_LOGD(LOG_TAG, "<< indicate");
|
|
||||||
} // indicate
|
} // indicate
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Send a notification.\n
|
* @brief Send an indication.
|
||||||
* A notification is a transmission of up to the first 20 bytes of the characteristic value.\n
|
* @param[in] value A pointer to the data to send.
|
||||||
* A notification will not block; it is a fire and forget.
|
* @param[in] length The length of the data to send.
|
||||||
|
*/
|
||||||
|
void NimBLECharacteristic::indicate(const uint8_t* value, size_t length) {
|
||||||
|
notify(value, length, false);
|
||||||
|
} // indicate
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Send an indication.
|
||||||
|
* @param[in] value A std::vector<uint8_t> containing the value to send as the notification value.
|
||||||
|
*/
|
||||||
|
void NimBLECharacteristic::indicate(const std::vector<uint8_t>& value) {
|
||||||
|
notify(value.data(), value.size(), false);
|
||||||
|
} // indicate
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Send a notification or indication.
|
||||||
* @param[in] is_notification if true sends a notification, false sends an indication.
|
* @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());
|
notify(m_value.data(), m_value.length(), is_notification);
|
||||||
|
} // notify
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Send a notification or indication.
|
||||||
|
* @param[in] value A std::vector<uint8_t> containing the value to send as the notification value.
|
||||||
|
* @param[in] is_notification if true sends a notification, false sends an indication.
|
||||||
|
*/
|
||||||
|
void NimBLECharacteristic::notify(const std::vector<uint8_t>& value, bool is_notification) {
|
||||||
|
notify(value.data(), value.size(), is_notification);
|
||||||
|
} // notify
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Send a notification or indication.
|
||||||
|
* @param[in] value A pointer to the data to send.
|
||||||
|
* @param[in] length The length of the data to send.
|
||||||
|
* @param[in] is_notification if true sends a notification, false sends an indication.
|
||||||
|
*/
|
||||||
|
void NimBLECharacteristic::notify(const uint8_t* value, size_t length, bool is_notification) {
|
||||||
|
NIMBLE_LOGD(LOG_TAG, ">> notify: length: %d", length);
|
||||||
|
|
||||||
if(!(m_properties & NIMBLE_PROPERTY::NOTIFY) &&
|
if(!(m_properties & NIMBLE_PROPERTY::NOTIFY) &&
|
||||||
!(m_properties & NIMBLE_PROPERTY::INDICATE))
|
!(m_properties & NIMBLE_PROPERTY::INDICATE))
|
||||||
{
|
{
|
||||||
|
@ -424,15 +451,13 @@ void NimBLECharacteristic::notify(bool is_notification) {
|
||||||
|
|
||||||
m_pCallbacks->onNotify(this);
|
m_pCallbacks->onNotify(this);
|
||||||
|
|
||||||
std::string value = getValue();
|
|
||||||
size_t length = value.length();
|
|
||||||
bool reqSec = (m_properties & BLE_GATT_CHR_F_READ_AUTHEN) ||
|
bool reqSec = (m_properties & BLE_GATT_CHR_F_READ_AUTHEN) ||
|
||||||
(m_properties & BLE_GATT_CHR_F_READ_AUTHOR) ||
|
(m_properties & BLE_GATT_CHR_F_READ_AUTHOR) ||
|
||||||
(m_properties & BLE_GATT_CHR_F_READ_ENC);
|
(m_properties & BLE_GATT_CHR_F_READ_ENC);
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
for (auto &it : m_subscribedVec) {
|
for (auto &it : m_subscribedVec) {
|
||||||
uint16_t _mtu = getService()->getServer()->getPeerMTU(it.first);
|
uint16_t _mtu = getService()->getServer()->getPeerMTU(it.first) - 3;
|
||||||
|
|
||||||
// check if connected and subscribed
|
// check if connected and subscribed
|
||||||
if(_mtu == 0 || it.second == 0) {
|
if(_mtu == 0 || it.second == 0) {
|
||||||
|
@ -448,8 +473,8 @@ void NimBLECharacteristic::notify(bool is_notification) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (length > _mtu - 3) {
|
if (length > _mtu) {
|
||||||
NIMBLE_LOGW(LOG_TAG, "- Truncating to %d bytes (maximum notify size)", _mtu - 3);
|
NIMBLE_LOGW(LOG_TAG, "- Truncating to %d bytes (maximum notify size)", _mtu);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(is_notification && (!(it.second & NIMBLE_SUB_NOTIFY))) {
|
if(is_notification && (!(it.second & NIMBLE_SUB_NOTIFY))) {
|
||||||
|
@ -467,7 +492,7 @@ void NimBLECharacteristic::notify(bool is_notification) {
|
||||||
// don't create the m_buf until we are sure to send the data or else
|
// don't create the m_buf until we are sure to send the data or else
|
||||||
// we could be allocating a buffer that doesn't get released.
|
// we could be allocating a buffer that doesn't get released.
|
||||||
// We also must create it in each loop iteration because it is consumed with each host call.
|
// We also must create it in each loop iteration because it is consumed with each host call.
|
||||||
os_mbuf *om = ble_hs_mbuf_from_flat((uint8_t*)value.data(), length);
|
os_mbuf *om = ble_hs_mbuf_from_flat(value, length);
|
||||||
|
|
||||||
if(!is_notification && (m_properties & NIMBLE_PROPERTY::INDICATE)) {
|
if(!is_notification && (m_properties & NIMBLE_PROPERTY::INDICATE)) {
|
||||||
if(!NimBLEDevice::getServer()->setIndicateWait(it.first)) {
|
if(!NimBLEDevice::getServer()->setIndicateWait(it.first)) {
|
||||||
|
@ -511,40 +536,30 @@ NimBLECharacteristicCallbacks* NimBLECharacteristic::getCallbacks() {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the value of the characteristic.
|
* @brief Set the value of the characteristic from a data buffer .
|
||||||
* @param [in] data The data to set for the characteristic.
|
* @param [in] data The data buffer to set for the characteristic.
|
||||||
* @param [in] length The length of the data in bytes.
|
* @param [in] length The number of bytes in the data buffer.
|
||||||
*/
|
*/
|
||||||
void NimBLECharacteristic::setValue(const uint8_t* data, size_t length) {
|
void NimBLECharacteristic::setValue(const uint8_t* data, size_t length) {
|
||||||
#if CONFIG_NIMBLE_CPP_DEBUG_LEVEL >= 4
|
#if CONFIG_NIMBLE_CPP_LOG_LEVEL >= 4
|
||||||
char* pHex = NimBLEUtils::buildHexData(nullptr, data, length);
|
char* pHex = NimBLEUtils::buildHexData(nullptr, data, length);
|
||||||
NIMBLE_LOGD(LOG_TAG, ">> setValue: length=%d, data=%s, characteristic UUID=%s", length, pHex, getUUID().toString().c_str());
|
NIMBLE_LOGD(LOG_TAG, ">> setValue: length=%d, data=%s, characteristic UUID=%s",
|
||||||
|
length, pHex, getUUID().toString().c_str());
|
||||||
free(pHex);
|
free(pHex);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (length > BLE_ATT_ATTR_MAX_LEN) {
|
m_value.setValue(data, length);
|
||||||
NIMBLE_LOGE(LOG_TAG, "Size %d too large, must be no bigger than %d", length, BLE_ATT_ATTR_MAX_LEN);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
time_t t = time(nullptr);
|
|
||||||
portENTER_CRITICAL(&m_valMux);
|
|
||||||
m_value = std::string((char*)data, length);
|
|
||||||
m_timestamp = t;
|
|
||||||
portEXIT_CRITICAL(&m_valMux);
|
|
||||||
|
|
||||||
NIMBLE_LOGD(LOG_TAG, "<< setValue");
|
NIMBLE_LOGD(LOG_TAG, "<< setValue");
|
||||||
} // setValue
|
} // setValue
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the value of the characteristic from string data.\n
|
* @brief Set the value of the characteristic from a `std::vector<uint8_t>`.\n
|
||||||
* We set the value of the characteristic from the bytes contained in the string.
|
* @param [in] vec The std::vector<uint8_t> reference to set the characteristic value from.
|
||||||
* @param [in] value the std::string value of the characteristic.
|
|
||||||
*/
|
*/
|
||||||
void NimBLECharacteristic::setValue(const std::string &value) {
|
void NimBLECharacteristic::setValue(const std::vector<uint8_t>& vec) {
|
||||||
setValue((uint8_t*)(value.data()), value.length());
|
return setValue((uint8_t*)&vec[0], vec.size());
|
||||||
} // setValue
|
}// setValue
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -641,6 +656,4 @@ void NimBLECharacteristicCallbacks::onSubscribe(NimBLECharacteristic* pCharacter
|
||||||
NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onSubscribe: default");
|
NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onSubscribe: default");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL */
|
||||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
|
||||||
#endif /* CONFIG_BT_ENABLED */
|
|
||||||
|
|
|
@ -13,13 +13,15 @@
|
||||||
|
|
||||||
#ifndef MAIN_NIMBLECHARACTERISTIC_H_
|
#ifndef MAIN_NIMBLECHARACTERISTIC_H_
|
||||||
#define MAIN_NIMBLECHARACTERISTIC_H_
|
#define MAIN_NIMBLECHARACTERISTIC_H_
|
||||||
#include "sdkconfig.h"
|
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
|
||||||
|
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||||
|
|
||||||
|
#if defined(CONFIG_NIMBLE_CPP_IDF)
|
||||||
#include "host/ble_hs.h"
|
#include "host/ble_hs.h"
|
||||||
|
#else
|
||||||
|
#include "nimble/nimble/host/include/host/ble_hs.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/**** FIX COMPILATION ****/
|
/**** FIX COMPILATION ****/
|
||||||
#undef min
|
#undef min
|
||||||
#undef max
|
#undef max
|
||||||
|
@ -42,6 +44,7 @@ typedef enum {
|
||||||
|
|
||||||
#include "NimBLEService.h"
|
#include "NimBLEService.h"
|
||||||
#include "NimBLEDescriptor.h"
|
#include "NimBLEDescriptor.h"
|
||||||
|
#include "NimBLEAttValue.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -63,11 +66,13 @@ public:
|
||||||
uint16_t properties =
|
uint16_t properties =
|
||||||
NIMBLE_PROPERTY::READ |
|
NIMBLE_PROPERTY::READ |
|
||||||
NIMBLE_PROPERTY::WRITE,
|
NIMBLE_PROPERTY::WRITE,
|
||||||
|
uint16_t max_len = BLE_ATT_ATTR_MAX_LEN,
|
||||||
NimBLEService* pService = nullptr);
|
NimBLEService* pService = nullptr);
|
||||||
NimBLECharacteristic(const NimBLEUUID &uuid,
|
NimBLECharacteristic(const NimBLEUUID &uuid,
|
||||||
uint16_t properties =
|
uint16_t properties =
|
||||||
NIMBLE_PROPERTY::READ |
|
NIMBLE_PROPERTY::READ |
|
||||||
NIMBLE_PROPERTY::WRITE,
|
NIMBLE_PROPERTY::WRITE,
|
||||||
|
uint16_t max_len = BLE_ATT_ATTR_MAX_LEN,
|
||||||
NimBLEService* pService = nullptr);
|
NimBLEService* pService = nullptr);
|
||||||
|
|
||||||
~NimBLECharacteristic();
|
~NimBLECharacteristic();
|
||||||
|
@ -75,64 +80,93 @@ public:
|
||||||
uint16_t getHandle();
|
uint16_t getHandle();
|
||||||
NimBLEUUID getUUID();
|
NimBLEUUID getUUID();
|
||||||
std::string toString();
|
std::string toString();
|
||||||
|
|
||||||
void setCallbacks(NimBLECharacteristicCallbacks* pCallbacks);
|
|
||||||
NimBLECharacteristicCallbacks*
|
|
||||||
getCallbacks();
|
|
||||||
|
|
||||||
void indicate();
|
void indicate();
|
||||||
|
void indicate(const uint8_t* value, size_t length);
|
||||||
|
void indicate(const std::vector<uint8_t>& value);
|
||||||
void notify(bool is_notification = true);
|
void notify(bool is_notification = true);
|
||||||
|
void notify(const uint8_t* value, size_t length, bool is_notification = true);
|
||||||
|
void notify(const std::vector<uint8_t>& value, bool is_notification = true);
|
||||||
size_t getSubscribedCount();
|
size_t getSubscribedCount();
|
||||||
|
|
||||||
NimBLEDescriptor* createDescriptor(const char* uuid,
|
|
||||||
uint32_t properties =
|
|
||||||
NIMBLE_PROPERTY::READ |
|
|
||||||
NIMBLE_PROPERTY::WRITE,
|
|
||||||
uint16_t max_len = 100);
|
|
||||||
NimBLEDescriptor* createDescriptor(const NimBLEUUID &uuid,
|
|
||||||
uint32_t properties =
|
|
||||||
NIMBLE_PROPERTY::READ |
|
|
||||||
NIMBLE_PROPERTY::WRITE,
|
|
||||||
uint16_t max_len = 100);
|
|
||||||
|
|
||||||
void addDescriptor(NimBLEDescriptor *pDescriptor);
|
void addDescriptor(NimBLEDescriptor *pDescriptor);
|
||||||
NimBLEDescriptor* getDescriptorByUUID(const char* uuid);
|
NimBLEDescriptor* getDescriptorByUUID(const char* uuid);
|
||||||
NimBLEDescriptor* getDescriptorByUUID(const NimBLEUUID &uuid);
|
NimBLEDescriptor* getDescriptorByUUID(const NimBLEUUID &uuid);
|
||||||
NimBLEDescriptor* getDescriptorByHandle(uint16_t handle);
|
NimBLEDescriptor* getDescriptorByHandle(uint16_t handle);
|
||||||
void removeDescriptor(NimBLEDescriptor *pDescriptor, bool deleteDsc = false);
|
void removeDescriptor(NimBLEDescriptor *pDescriptor, bool deleteDsc = false);
|
||||||
|
NimBLEService* getService();
|
||||||
std::string getValue(time_t *timestamp = nullptr);
|
uint16_t getProperties();
|
||||||
|
NimBLEAttValue getValue(time_t *timestamp = nullptr);
|
||||||
size_t getDataLength();
|
size_t getDataLength();
|
||||||
/**
|
|
||||||
* @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>(×tamp, skipSizeCheck);</tt>
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
T getValue(time_t *timestamp = nullptr, bool skipSizeCheck = false) {
|
|
||||||
std::string value = getValue();
|
|
||||||
if(!skipSizeCheck && value.size() < sizeof(T)) return T();
|
|
||||||
const char *pData = value.data();
|
|
||||||
return *((T *)pData);
|
|
||||||
}
|
|
||||||
|
|
||||||
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::vector<uint8_t>& vec);
|
||||||
|
void setCallbacks(NimBLECharacteristicCallbacks* pCallbacks);
|
||||||
|
NimBLEDescriptor* createDescriptor(const char* uuid,
|
||||||
|
uint32_t properties =
|
||||||
|
NIMBLE_PROPERTY::READ |
|
||||||
|
NIMBLE_PROPERTY::WRITE,
|
||||||
|
uint16_t max_len = BLE_ATT_ATTR_MAX_LEN);;
|
||||||
|
NimBLEDescriptor* createDescriptor(const NimBLEUUID &uuid,
|
||||||
|
uint32_t properties =
|
||||||
|
NIMBLE_PROPERTY::READ |
|
||||||
|
NIMBLE_PROPERTY::WRITE,
|
||||||
|
uint16_t max_len = BLE_ATT_ATTR_MAX_LEN);
|
||||||
|
|
||||||
|
NimBLECharacteristicCallbacks* getCallbacks();
|
||||||
|
|
||||||
|
|
||||||
|
/*********************** Template Functions ************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Convenience template to set the characteristic value to <type\>val.
|
* @brief Template to set the characteristic value to <type\>val.
|
||||||
* @param [in] s The value to set.
|
* @param [in] s The value to set.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void setValue(const T &s) {
|
void setValue(const T &s) { m_value.setValue<T>(s); }
|
||||||
setValue((uint8_t*)&s, sizeof(T));
|
|
||||||
|
/**
|
||||||
|
* @brief Template to convert the characteristic data to <type\>.
|
||||||
|
* @tparam T The type to convert the data to.
|
||||||
|
* @param [in] timestamp (Optional) A pointer to a time_t struct to store the time the value was read.
|
||||||
|
* @param [in] skipSizeCheck (Optional) 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>(×tamp, skipSizeCheck);</tt>
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
T getValue(time_t *timestamp = nullptr, bool skipSizeCheck = false) {
|
||||||
|
return m_value.getValue<T>(timestamp, skipSizeCheck);
|
||||||
}
|
}
|
||||||
|
|
||||||
NimBLEService* getService();
|
/**
|
||||||
uint16_t getProperties();
|
* @brief Template to send a notification from a class type that has a c_str() and length() method.
|
||||||
|
* @tparam T The a reference to a class containing the data to send.
|
||||||
|
* @param[in] value The <type\>value to set.
|
||||||
|
* @param[in] is_notification if true sends a notification, false sends an indication.
|
||||||
|
* @details Only used if the <type\> has a `c_str()` method.
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
#ifdef _DOXYGEN_
|
||||||
|
void
|
||||||
|
#else
|
||||||
|
typename std::enable_if<Has_c_str_len<T>::value, void>::type
|
||||||
|
#endif
|
||||||
|
notify(const T& value, bool is_notification = true) {
|
||||||
|
notify((uint8_t*)value.c_str(), value.length(), is_notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Template to send an indication from a class type that has a c_str() and length() method.
|
||||||
|
* @tparam T The a reference to a class containing the data to send.
|
||||||
|
* @param[in] value The <type\>value to set.
|
||||||
|
* @details Only used if the <type\> has a `c_str()` method.
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
#ifdef _DOXYGEN_
|
||||||
|
void
|
||||||
|
#else
|
||||||
|
typename std::enable_if<Has_c_str_len<T>::value, void>::type
|
||||||
|
#endif
|
||||||
|
indicate(const T& value) {
|
||||||
|
indicate((uint8_t*)value.c_str(), value.length());
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -149,10 +183,8 @@ private:
|
||||||
uint16_t m_properties;
|
uint16_t m_properties;
|
||||||
NimBLECharacteristicCallbacks* m_pCallbacks;
|
NimBLECharacteristicCallbacks* m_pCallbacks;
|
||||||
NimBLEService* m_pService;
|
NimBLEService* m_pService;
|
||||||
std::string m_value;
|
NimBLEAttValue m_value;
|
||||||
std::vector<NimBLEDescriptor*> m_dscVec;
|
std::vector<NimBLEDescriptor*> m_dscVec;
|
||||||
portMUX_TYPE m_valMux;
|
|
||||||
time_t m_timestamp;
|
|
||||||
uint8_t m_removed;
|
uint8_t m_removed;
|
||||||
|
|
||||||
std::vector<std::pair<uint16_t, uint16_t>> m_subscribedVec;
|
std::vector<std::pair<uint16_t, uint16_t>> m_subscribedVec;
|
||||||
|
@ -185,7 +217,7 @@ public:
|
||||||
ERROR_INDICATE_FAILURE
|
ERROR_INDICATE_FAILURE
|
||||||
}Status;
|
}Status;
|
||||||
|
|
||||||
virtual ~NimBLECharacteristicCallbacks();
|
virtual ~NimBLECharacteristicCallbacks();
|
||||||
virtual void onRead(NimBLECharacteristic* pCharacteristic);
|
virtual void onRead(NimBLECharacteristic* pCharacteristic);
|
||||||
virtual void onRead(NimBLECharacteristic* pCharacteristic, ble_gap_conn_desc* desc);
|
virtual void onRead(NimBLECharacteristic* pCharacteristic, ble_gap_conn_desc* desc);
|
||||||
virtual void onWrite(NimBLECharacteristic* pCharacteristic);
|
virtual void onWrite(NimBLECharacteristic* pCharacteristic);
|
||||||
|
@ -195,6 +227,5 @@ public:
|
||||||
virtual void onSubscribe(NimBLECharacteristic* pCharacteristic, ble_gap_conn_desc* desc, uint16_t subValue);
|
virtual void onSubscribe(NimBLECharacteristic* pCharacteristic, ble_gap_conn_desc* desc, uint16_t subValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL */
|
||||||
#endif /* CONFIG_BT_ENABLED */
|
|
||||||
#endif /*MAIN_NIMBLECHARACTERISTIC_H_*/
|
#endif /*MAIN_NIMBLECHARACTERISTIC_H_*/
|
||||||
|
|
|
@ -11,11 +11,8 @@
|
||||||
* Author: kolban
|
* Author: kolban
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "sdkconfig.h"
|
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
|
||||||
|
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||||
|
|
||||||
#include "NimBLEClient.h"
|
#include "NimBLEClient.h"
|
||||||
#include "NimBLEDevice.h"
|
#include "NimBLEDevice.h"
|
||||||
|
@ -23,9 +20,13 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
#include <climits>
|
||||||
|
|
||||||
|
#if defined(CONFIG_NIMBLE_CPP_IDF)
|
||||||
#include "nimble/nimble_port.h"
|
#include "nimble/nimble_port.h"
|
||||||
|
#else
|
||||||
|
#include "nimble/porting/nimble/include/nimble/nimble_port.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
static const char* LOG_TAG = "NimBLEClient";
|
static const char* LOG_TAG = "NimBLEClient";
|
||||||
static NimBLEClientCallbacks defaultCallbacks;
|
static NimBLEClientCallbacks defaultCallbacks;
|
||||||
|
@ -74,6 +75,7 @@ NimBLEClient::NimBLEClient(const NimBLEAddress &peerAddress) : m_peerAddress(pee
|
||||||
m_pConnParams.min_ce_len = BLE_GAP_INITIAL_CONN_MIN_CE_LEN; // Minimum length of connection event in 0.625ms units
|
m_pConnParams.min_ce_len = BLE_GAP_INITIAL_CONN_MIN_CE_LEN; // Minimum length of connection event in 0.625ms units
|
||||||
m_pConnParams.max_ce_len = BLE_GAP_INITIAL_CONN_MAX_CE_LEN; // Maximum length of connection event in 0.625ms units
|
m_pConnParams.max_ce_len = BLE_GAP_INITIAL_CONN_MAX_CE_LEN; // Maximum length of connection event in 0.625ms units
|
||||||
|
|
||||||
|
memset(&m_dcTimer, 0, sizeof(m_dcTimer));
|
||||||
ble_npl_callout_init(&m_dcTimer, nimble_port_get_dflt_eventq(),
|
ble_npl_callout_init(&m_dcTimer, nimble_port_get_dflt_eventq(),
|
||||||
NimBLEClient::dcTimerCb, this);
|
NimBLEClient::dcTimerCb, this);
|
||||||
} // NimBLEClient
|
} // NimBLEClient
|
||||||
|
@ -453,6 +455,29 @@ void NimBLEClient::updateConnParams(uint16_t minInterval, uint16_t maxInterval,
|
||||||
} // updateConnParams
|
} // updateConnParams
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Request an update of the data packet length.
|
||||||
|
* * Can only be used after a connection has been established.
|
||||||
|
* @details Sends a data length update request to the server the client is connected to.
|
||||||
|
* The Data Length Extension (DLE) allows to increase the Data Channel Payload from 27 bytes to up to 251 bytes.
|
||||||
|
* The server needs to support the Bluetooth 4.2 specifications, to be capable of DLE.
|
||||||
|
* @param [in] tx_octets The preferred number of payload octets to use (Range 0x001B-0x00FB).
|
||||||
|
*/
|
||||||
|
void NimBLEClient::setDataLen(uint16_t tx_octets) {
|
||||||
|
#if defined(CONFIG_NIMBLE_CPP_IDF) && defined(ESP_IDF_VERSION) && \
|
||||||
|
ESP_IDF_VERSION_MAJOR >= 4 && ESP_IDF_VERSION_MINOR >= 3 && ESP_IDF_VERSION_PATCH >= 2
|
||||||
|
return;
|
||||||
|
#else
|
||||||
|
uint16_t tx_time = (tx_octets + 14) * 8;
|
||||||
|
|
||||||
|
int rc = ble_gap_set_data_len(m_conn_id, tx_octets, tx_time);
|
||||||
|
if(rc != 0) {
|
||||||
|
NIMBLE_LOGE(LOG_TAG, "Set data length error: %d, %s", rc, NimBLEUtils::returnCodeToString(rc));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} // setDataLen
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get detailed information about the current peer connection.
|
* @brief Get detailed information about the current peer connection.
|
||||||
*/
|
*/
|
||||||
|
@ -586,7 +611,7 @@ NimBLERemoteService* NimBLEClient::getService(const NimBLEUUID &uuid) {
|
||||||
return m_servicesVector.back();
|
return m_servicesVector.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the request was successful but 16/32 bit service not found
|
// If the request was successful but 16/32 bit uuid not found
|
||||||
// try again with the 128 bit uuid.
|
// try again with the 128 bit uuid.
|
||||||
if(uuid.bitSize() == BLE_UUID_TYPE_16 ||
|
if(uuid.bitSize() == BLE_UUID_TYPE_16 ||
|
||||||
uuid.bitSize() == BLE_UUID_TYPE_32)
|
uuid.bitSize() == BLE_UUID_TYPE_32)
|
||||||
|
@ -594,6 +619,15 @@ NimBLERemoteService* NimBLEClient::getService(const NimBLEUUID &uuid) {
|
||||||
NimBLEUUID uuid128(uuid);
|
NimBLEUUID uuid128(uuid);
|
||||||
uuid128.to128();
|
uuid128.to128();
|
||||||
return getService(uuid128);
|
return getService(uuid128);
|
||||||
|
} else {
|
||||||
|
// If the request was successful but the 128 bit uuid not found
|
||||||
|
// try again with the 16 bit uuid.
|
||||||
|
NimBLEUUID uuid16(uuid);
|
||||||
|
uuid16.to16();
|
||||||
|
// if the uuid was 128 bit but not of the BLE base type this check will fail
|
||||||
|
if (uuid16.bitSize() == BLE_UUID_TYPE_16) {
|
||||||
|
return getService(uuid16);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -743,11 +777,11 @@ int NimBLEClient::serviceDiscoveredCB(
|
||||||
* @param [in] characteristicUUID The characteristic whose value we wish to read.
|
* @param [in] characteristicUUID The characteristic whose value we wish to read.
|
||||||
* @returns characteristic value or an empty string if not found
|
* @returns characteristic value or an empty string if not found
|
||||||
*/
|
*/
|
||||||
std::string NimBLEClient::getValue(const NimBLEUUID &serviceUUID, const NimBLEUUID &characteristicUUID) {
|
NimBLEAttValue NimBLEClient::getValue(const NimBLEUUID &serviceUUID, const NimBLEUUID &characteristicUUID) {
|
||||||
NIMBLE_LOGD(LOG_TAG, ">> getValue: serviceUUID: %s, characteristicUUID: %s",
|
NIMBLE_LOGD(LOG_TAG, ">> getValue: serviceUUID: %s, characteristicUUID: %s",
|
||||||
serviceUUID.toString().c_str(), characteristicUUID.toString().c_str());
|
serviceUUID.toString().c_str(), characteristicUUID.toString().c_str());
|
||||||
|
|
||||||
std::string ret = "";
|
NimBLEAttValue ret;
|
||||||
NimBLERemoteService* pService = getService(serviceUUID);
|
NimBLERemoteService* pService = getService(serviceUUID);
|
||||||
|
|
||||||
if(pService != nullptr) {
|
if(pService != nullptr) {
|
||||||
|
@ -771,7 +805,7 @@ std::string NimBLEClient::getValue(const NimBLEUUID &serviceUUID, const NimBLEUU
|
||||||
* @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,
|
||||||
const std::string &value, bool response)
|
const NimBLEAttValue &value, bool response)
|
||||||
{
|
{
|
||||||
NIMBLE_LOGD(LOG_TAG, ">> setValue: serviceUUID: %s, characteristicUUID: %s",
|
NIMBLE_LOGD(LOG_TAG, ">> setValue: serviceUUID: %s, characteristicUUID: %s",
|
||||||
serviceUUID.toString().c_str(), characteristicUUID.toString().c_str());
|
serviceUUID.toString().c_str(), characteristicUUID.toString().c_str());
|
||||||
|
@ -832,7 +866,7 @@ uint16_t NimBLEClient::getMTU() {
|
||||||
* @param [in] arg A pointer to the client instance that registered for this callback.
|
* @param [in] arg A pointer to the client instance that registered for this callback.
|
||||||
*/
|
*/
|
||||||
/*STATIC*/
|
/*STATIC*/
|
||||||
int NimBLEClient::handleGapEvent(struct ble_gap_event *event, void *arg) {
|
int NimBLEClient::handleGapEvent(struct ble_gap_event *event, void *arg) {
|
||||||
NimBLEClient* client = (NimBLEClient*)arg;
|
NimBLEClient* client = (NimBLEClient*)arg;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
@ -950,19 +984,14 @@ uint16_t NimBLEClient::getMTU() {
|
||||||
NIMBLE_LOGD(LOG_TAG, "Got Notification for characteristic %s",
|
NIMBLE_LOGD(LOG_TAG, "Got Notification for characteristic %s",
|
||||||
(*characteristic)->toString().c_str());
|
(*characteristic)->toString().c_str());
|
||||||
|
|
||||||
time_t t = time(nullptr);
|
uint32_t data_len = OS_MBUF_PKTLEN(event->notify_rx.om);
|
||||||
portENTER_CRITICAL(&(*characteristic)->m_valMux);
|
(*characteristic)->m_value.setValue(event->notify_rx.om->om_data, data_len);
|
||||||
(*characteristic)->m_value = std::string((char *)event->notify_rx.om->om_data,
|
|
||||||
event->notify_rx.om->om_len);
|
|
||||||
(*characteristic)->m_timestamp = t;
|
|
||||||
portEXIT_CRITICAL(&(*characteristic)->m_valMux);
|
|
||||||
|
|
||||||
if ((*characteristic)->m_notifyCallback != nullptr) {
|
if ((*characteristic)->m_notifyCallback != nullptr) {
|
||||||
NIMBLE_LOGD(LOG_TAG, "Invoking callback for notification on characteristic %s",
|
NIMBLE_LOGD(LOG_TAG, "Invoking callback for notification on characteristic %s",
|
||||||
(*characteristic)->toString().c_str());
|
(*characteristic)->toString().c_str());
|
||||||
(*characteristic)->m_notifyCallback(*characteristic, event->notify_rx.om->om_data,
|
(*characteristic)->m_notifyCallback(*characteristic, event->notify_rx.om->om_data,
|
||||||
event->notify_rx.om->om_len,
|
data_len, !event->notify_rx.indication);
|
||||||
!event->notify_rx.indication);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1060,7 +1089,7 @@ uint16_t NimBLEClient::getMTU() {
|
||||||
NIMBLE_LOGD(LOG_TAG, "ble_sm_inject_io result: %d", rc);
|
NIMBLE_LOGD(LOG_TAG, "ble_sm_inject_io result: %d", rc);
|
||||||
|
|
||||||
} else if (event->passkey.params.action == BLE_SM_IOACT_NUMCMP) {
|
} else if (event->passkey.params.action == BLE_SM_IOACT_NUMCMP) {
|
||||||
NIMBLE_LOGD(LOG_TAG, "Passkey on device's display: %d", event->passkey.params.numcmp);
|
NIMBLE_LOGD(LOG_TAG, "Passkey on device's display: %" PRIu32, event->passkey.params.numcmp);
|
||||||
pkey.action = event->passkey.params.action;
|
pkey.action = event->passkey.params.action;
|
||||||
// Compatibility only - Do not use, should be removed the in future
|
// Compatibility only - Do not use, should be removed the in future
|
||||||
if(NimBLEDevice::m_securityCallbacks != nullptr) {
|
if(NimBLEDevice::m_securityCallbacks != nullptr) {
|
||||||
|
@ -1205,5 +1234,4 @@ bool NimBLEClientCallbacks::onConfirmPIN(uint32_t pin){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL */
|
||||||
#endif // CONFIG_BT_ENABLED
|
|
||||||
|
|
|
@ -14,16 +14,14 @@
|
||||||
#ifndef MAIN_NIMBLECLIENT_H_
|
#ifndef MAIN_NIMBLECLIENT_H_
|
||||||
#define MAIN_NIMBLECLIENT_H_
|
#define MAIN_NIMBLECLIENT_H_
|
||||||
|
|
||||||
#include "sdkconfig.h"
|
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
|
||||||
|
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||||
|
|
||||||
#include "NimBLEAddress.h"
|
#include "NimBLEAddress.h"
|
||||||
#include "NimBLEUUID.h"
|
#include "NimBLEUUID.h"
|
||||||
#include "NimBLEUtils.h"
|
#include "NimBLEUtils.h"
|
||||||
#include "NimBLEConnInfo.h"
|
#include "NimBLEConnInfo.h"
|
||||||
|
#include "NimBLEAttValue.h"
|
||||||
#include "NimBLEAdvertisedDevice.h"
|
#include "NimBLEAdvertisedDevice.h"
|
||||||
#include "NimBLERemoteService.h"
|
#include "NimBLERemoteService.h"
|
||||||
|
|
||||||
|
@ -54,9 +52,9 @@ public:
|
||||||
NimBLERemoteService* getService(const NimBLEUUID &uuid);
|
NimBLERemoteService* getService(const NimBLEUUID &uuid);
|
||||||
void deleteServices();
|
void deleteServices();
|
||||||
size_t deleteService(const NimBLEUUID &uuid);
|
size_t deleteService(const NimBLEUUID &uuid);
|
||||||
std::string getValue(const NimBLEUUID &serviceUUID, const NimBLEUUID &characteristicUUID);
|
NimBLEAttValue getValue(const NimBLEUUID &serviceUUID, const NimBLEUUID &characteristicUUID);
|
||||||
bool setValue(const NimBLEUUID &serviceUUID, const NimBLEUUID &characteristicUUID,
|
bool setValue(const NimBLEUUID &serviceUUID, const NimBLEUUID &characteristicUUID,
|
||||||
const std::string &value, bool response = false);
|
const NimBLEAttValue &value, bool response = false);
|
||||||
NimBLERemoteCharacteristic* getCharacteristic(const uint16_t handle);
|
NimBLERemoteCharacteristic* getCharacteristic(const uint16_t handle);
|
||||||
bool isConnected();
|
bool isConnected();
|
||||||
void setClientCallbacks(NimBLEClientCallbacks *pClientCallbacks,
|
void setClientCallbacks(NimBLEClientCallbacks *pClientCallbacks,
|
||||||
|
@ -71,6 +69,7 @@ public:
|
||||||
uint16_t scanInterval=16, uint16_t scanWindow=16);
|
uint16_t scanInterval=16, uint16_t scanWindow=16);
|
||||||
void updateConnParams(uint16_t minInterval, uint16_t maxInterval,
|
void updateConnParams(uint16_t minInterval, uint16_t maxInterval,
|
||||||
uint16_t latency, uint16_t timeout);
|
uint16_t latency, uint16_t timeout);
|
||||||
|
void setDataLen(uint16_t tx_octets);
|
||||||
void discoverAttributes();
|
void discoverAttributes();
|
||||||
NimBLEConnInfo getConnInfo();
|
NimBLEConnInfo getConnInfo();
|
||||||
int getLastError();
|
int getLastError();
|
||||||
|
@ -160,6 +159,5 @@ public:
|
||||||
virtual bool onConfirmPIN(uint32_t pin);
|
virtual bool onConfirmPIN(uint32_t pin);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL */
|
||||||
#endif // CONFIG_BT_ENABLED
|
|
||||||
#endif /* MAIN_NIMBLECLIENT_H_ */
|
#endif /* MAIN_NIMBLECLIENT_H_ */
|
||||||
|
|
|
@ -11,11 +11,9 @@
|
||||||
* Created on: Jun 22, 2017
|
* Created on: Jun 22, 2017
|
||||||
* Author: kolban
|
* Author: kolban
|
||||||
*/
|
*/
|
||||||
#include "sdkconfig.h"
|
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
|
||||||
|
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||||
|
|
||||||
#include "NimBLEService.h"
|
#include "NimBLEService.h"
|
||||||
#include "NimBLEDescriptor.h"
|
#include "NimBLEDescriptor.h"
|
||||||
|
@ -30,28 +28,32 @@ static NimBLEDescriptorCallbacks defaultCallbacks;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief NimBLEDescriptor constructor.
|
* @brief Construct a descriptor
|
||||||
|
* @param [in] uuid - UUID (const char*) for the descriptor.
|
||||||
|
* @param [in] properties - Properties for the descriptor.
|
||||||
|
* @param [in] max_len - The maximum length in bytes that the descriptor value can hold. (Default: 512 bytes for esp32, 20 for all others).
|
||||||
|
* @param [in] pCharacteristic - pointer to the characteristic instance this descriptor belongs to.
|
||||||
*/
|
*/
|
||||||
NimBLEDescriptor::NimBLEDescriptor(const char* uuid, uint16_t properties, uint16_t max_len,
|
NimBLEDescriptor::NimBLEDescriptor(const char* uuid, uint16_t properties, uint16_t max_len,
|
||||||
NimBLECharacteristic* pCharacteristic)
|
NimBLECharacteristic* pCharacteristic)
|
||||||
: NimBLEDescriptor(NimBLEUUID(uuid), max_len, properties, pCharacteristic) {
|
: NimBLEDescriptor(NimBLEUUID(uuid), properties, max_len, pCharacteristic) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief NimBLEDescriptor constructor.
|
* @brief Construct a descriptor
|
||||||
|
* @param [in] uuid - UUID (const char*) for the descriptor.
|
||||||
|
* @param [in] properties - Properties for the descriptor.
|
||||||
|
* @param [in] max_len - The maximum length in bytes that the descriptor value can hold. (Default: 512 bytes for esp32, 20 for all others).
|
||||||
|
* @param [in] pCharacteristic - pointer to the characteristic instance this descriptor belongs to.
|
||||||
*/
|
*/
|
||||||
NimBLEDescriptor::NimBLEDescriptor(NimBLEUUID uuid, uint16_t properties, uint16_t max_len,
|
NimBLEDescriptor::NimBLEDescriptor(NimBLEUUID uuid, uint16_t properties, uint16_t max_len,
|
||||||
NimBLECharacteristic* pCharacteristic)
|
NimBLECharacteristic* pCharacteristic)
|
||||||
{
|
: m_value(std::min(CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH , (int)max_len), max_len) {
|
||||||
m_uuid = uuid;
|
m_uuid = uuid;
|
||||||
m_value.attr_len = 0; // Initial length is 0.
|
|
||||||
m_value.attr_max_len = max_len; // Maximum length of the data.
|
|
||||||
m_handle = NULL_HANDLE; // Handle is initially unknown.
|
m_handle = NULL_HANDLE; // Handle is initially unknown.
|
||||||
m_pCharacteristic = pCharacteristic;
|
m_pCharacteristic = pCharacteristic;
|
||||||
m_pCallbacks = &defaultCallbacks; // No initial callback.
|
m_pCallbacks = &defaultCallbacks; // No initial callback.
|
||||||
m_value.attr_value = (uint8_t*) calloc(max_len,1); // Allocate storage for the value.
|
|
||||||
m_valMux = portMUX_INITIALIZER_UNLOCKED;
|
|
||||||
m_properties = 0;
|
m_properties = 0;
|
||||||
m_removed = 0;
|
m_removed = 0;
|
||||||
|
|
||||||
|
@ -87,7 +89,6 @@ NimBLEDescriptor::NimBLEDescriptor(NimBLEUUID uuid, uint16_t properties, uint16_
|
||||||
* @brief NimBLEDescriptor destructor.
|
* @brief NimBLEDescriptor destructor.
|
||||||
*/
|
*/
|
||||||
NimBLEDescriptor::~NimBLEDescriptor() {
|
NimBLEDescriptor::~NimBLEDescriptor() {
|
||||||
free(m_value.attr_value); // Release the storage we created in the constructor.
|
|
||||||
} // ~NimBLEDescriptor
|
} // ~NimBLEDescriptor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -104,7 +105,7 @@ uint16_t NimBLEDescriptor::getHandle() {
|
||||||
* @return The length (in bytes) of the value of this descriptor.
|
* @return The length (in bytes) of the value of this descriptor.
|
||||||
*/
|
*/
|
||||||
size_t NimBLEDescriptor::getLength() {
|
size_t NimBLEDescriptor::getLength() {
|
||||||
return m_value.attr_len;
|
return m_value.size();
|
||||||
} // getLength
|
} // getLength
|
||||||
|
|
||||||
|
|
||||||
|
@ -118,10 +119,14 @@ NimBLEUUID NimBLEDescriptor::getUUID() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the value of this descriptor.
|
* @brief Get the value of this descriptor.
|
||||||
* @return A pointer to the value of this descriptor.
|
* @return The NimBLEAttValue of this descriptor.
|
||||||
*/
|
*/
|
||||||
uint8_t* NimBLEDescriptor::getValue() {
|
NimBLEAttValue NimBLEDescriptor::getValue(time_t *timestamp) {
|
||||||
return m_value.attr_value;
|
if (timestamp != nullptr) {
|
||||||
|
m_value.getValue(timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_value;
|
||||||
} // getValue
|
} // getValue
|
||||||
|
|
||||||
|
|
||||||
|
@ -130,7 +135,7 @@ uint8_t* NimBLEDescriptor::getValue() {
|
||||||
* @return A std::string instance containing a copy of the descriptor's value.
|
* @return A std::string instance containing a copy of the descriptor's value.
|
||||||
*/
|
*/
|
||||||
std::string NimBLEDescriptor::getStringValue() {
|
std::string NimBLEDescriptor::getStringValue() {
|
||||||
return std::string((char *) m_value.attr_value, m_value.attr_len);
|
return std::string(m_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -145,6 +150,9 @@ NimBLECharacteristic* NimBLEDescriptor::getCharacteristic() {
|
||||||
|
|
||||||
int NimBLEDescriptor::handleGapEvent(uint16_t conn_handle, uint16_t attr_handle,
|
int NimBLEDescriptor::handleGapEvent(uint16_t conn_handle, uint16_t attr_handle,
|
||||||
struct ble_gatt_access_ctxt *ctxt, void *arg) {
|
struct ble_gatt_access_ctxt *ctxt, void *arg) {
|
||||||
|
(void)conn_handle;
|
||||||
|
(void)attr_handle;
|
||||||
|
|
||||||
const ble_uuid_t *uuid;
|
const ble_uuid_t *uuid;
|
||||||
int rc;
|
int rc;
|
||||||
NimBLEDescriptor* pDescriptor = (NimBLEDescriptor*)arg;
|
NimBLEDescriptor* pDescriptor = (NimBLEDescriptor*)arg;
|
||||||
|
@ -161,24 +169,27 @@ int NimBLEDescriptor::handleGapEvent(uint16_t conn_handle, uint16_t attr_handle,
|
||||||
if(ctxt->om->om_pkthdr_len > 8) {
|
if(ctxt->om->om_pkthdr_len > 8) {
|
||||||
pDescriptor->m_pCallbacks->onRead(pDescriptor);
|
pDescriptor->m_pCallbacks->onRead(pDescriptor);
|
||||||
}
|
}
|
||||||
portENTER_CRITICAL(&pDescriptor->m_valMux);
|
|
||||||
rc = os_mbuf_append(ctxt->om, pDescriptor->getValue(), pDescriptor->getLength());
|
ble_npl_hw_enter_critical();
|
||||||
portEXIT_CRITICAL(&pDescriptor->m_valMux);
|
rc = os_mbuf_append(ctxt->om, pDescriptor->m_value.data(), pDescriptor->m_value.size());
|
||||||
|
ble_npl_hw_exit_critical(0);
|
||||||
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
|
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
|
||||||
}
|
}
|
||||||
|
|
||||||
case BLE_GATT_ACCESS_OP_WRITE_DSC: {
|
case BLE_GATT_ACCESS_OP_WRITE_DSC: {
|
||||||
if (ctxt->om->om_len > pDescriptor->m_value.attr_max_len) {
|
uint16_t att_max_len = pDescriptor->m_value.max_size();
|
||||||
|
|
||||||
|
if (ctxt->om->om_len > att_max_len) {
|
||||||
return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
|
return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t buf[pDescriptor->m_value.attr_max_len];
|
uint8_t buf[att_max_len];
|
||||||
size_t len = ctxt->om->om_len;
|
size_t len = ctxt->om->om_len;
|
||||||
memcpy(buf, ctxt->om->om_data,len);
|
memcpy(buf, ctxt->om->om_data,len);
|
||||||
os_mbuf *next;
|
os_mbuf *next;
|
||||||
next = SLIST_NEXT(ctxt->om, om_next);
|
next = SLIST_NEXT(ctxt->om, om_next);
|
||||||
while(next != NULL){
|
while(next != NULL){
|
||||||
if((len + next->om_len) > pDescriptor->m_value.attr_max_len) {
|
if((len + next->om_len) > att_max_len) {
|
||||||
return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
|
return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
|
||||||
}
|
}
|
||||||
memcpy(&buf[len], next->om_data, next->om_len);
|
memcpy(&buf[len], next->om_data, next->om_len);
|
||||||
|
@ -230,25 +241,19 @@ void NimBLEDescriptor::setHandle(uint16_t handle) {
|
||||||
* @param [in] length The length of the data in bytes.
|
* @param [in] length The length of the data in bytes.
|
||||||
*/
|
*/
|
||||||
void NimBLEDescriptor::setValue(const uint8_t* data, size_t length) {
|
void NimBLEDescriptor::setValue(const uint8_t* data, size_t length) {
|
||||||
if (length > m_value.attr_max_len) {
|
m_value.setValue(data, length);
|
||||||
NIMBLE_LOGE(LOG_TAG, "Size %d too large, must be no bigger than %d", length, m_value.attr_max_len);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
portENTER_CRITICAL(&m_valMux);
|
|
||||||
m_value.attr_len = length;
|
|
||||||
memcpy(m_value.attr_value, data, length);
|
|
||||||
portEXIT_CRITICAL(&m_valMux);
|
|
||||||
} // setValue
|
} // setValue
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the value of the descriptor.
|
* @brief Set the value of the descriptor from a `std::vector<uint8_t>`.\n
|
||||||
* @param [in] value The value of the descriptor in string form.
|
* @param [in] vec The std::vector<uint8_t> reference to set the descriptor value from.
|
||||||
*/
|
*/
|
||||||
void NimBLEDescriptor::setValue(const std::string &value) {
|
void NimBLEDescriptor::setValue(const std::vector<uint8_t>& vec) {
|
||||||
setValue((uint8_t*) value.data(), value.length());
|
return setValue((uint8_t*)&vec[0], vec.size());
|
||||||
} // setValue
|
} // setValue
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the characteristic this descriptor belongs to.
|
* @brief Set the characteristic this descriptor belongs to.
|
||||||
* @param [in] pChar A pointer to the characteristic this descriptior belongs to.
|
* @param [in] pChar A pointer to the characteristic this descriptior belongs to.
|
||||||
|
@ -277,6 +282,7 @@ NimBLEDescriptorCallbacks::~NimBLEDescriptorCallbacks() {}
|
||||||
* @param [in] pDescriptor The descriptor that is the source of the event.
|
* @param [in] pDescriptor The descriptor that is the source of the event.
|
||||||
*/
|
*/
|
||||||
void NimBLEDescriptorCallbacks::onRead(NimBLEDescriptor* pDescriptor) {
|
void NimBLEDescriptorCallbacks::onRead(NimBLEDescriptor* pDescriptor) {
|
||||||
|
(void)pDescriptor;
|
||||||
NIMBLE_LOGD("NimBLEDescriptorCallbacks", "onRead: default");
|
NIMBLE_LOGD("NimBLEDescriptorCallbacks", "onRead: default");
|
||||||
} // onRead
|
} // onRead
|
||||||
|
|
||||||
|
@ -286,8 +292,8 @@ void NimBLEDescriptorCallbacks::onRead(NimBLEDescriptor* pDescriptor) {
|
||||||
* @param [in] pDescriptor The descriptor that is the source of the event.
|
* @param [in] pDescriptor The descriptor that is the source of the event.
|
||||||
*/
|
*/
|
||||||
void NimBLEDescriptorCallbacks::onWrite(NimBLEDescriptor* pDescriptor) {
|
void NimBLEDescriptorCallbacks::onWrite(NimBLEDescriptor* pDescriptor) {
|
||||||
|
(void)pDescriptor;
|
||||||
NIMBLE_LOGD("NimBLEDescriptorCallbacks", "onWrite: default");
|
NIMBLE_LOGD("NimBLEDescriptorCallbacks", "onWrite: default");
|
||||||
} // onWrite
|
} // onWrite
|
||||||
|
|
||||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL */
|
||||||
#endif /* CONFIG_BT_ENABLED */
|
|
||||||
|
|
|
@ -14,25 +14,16 @@
|
||||||
|
|
||||||
#ifndef MAIN_NIMBLEDESCRIPTOR_H_
|
#ifndef MAIN_NIMBLEDESCRIPTOR_H_
|
||||||
#define MAIN_NIMBLEDESCRIPTOR_H_
|
#define MAIN_NIMBLEDESCRIPTOR_H_
|
||||||
#include "sdkconfig.h"
|
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
|
||||||
|
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||||
|
|
||||||
#include "NimBLECharacteristic.h"
|
#include "NimBLECharacteristic.h"
|
||||||
#include "NimBLEUUID.h"
|
#include "NimBLEUUID.h"
|
||||||
|
#include "NimBLEAttValue.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint16_t attr_max_len; /*!< attribute max value length */
|
|
||||||
uint16_t attr_len; /*!< attribute current value length */
|
|
||||||
uint8_t *attr_value; /*!< the pointer to attribute value */
|
|
||||||
} attr_value_t;
|
|
||||||
|
|
||||||
class NimBLEService;
|
class NimBLEService;
|
||||||
class NimBLECharacteristic;
|
class NimBLECharacteristic;
|
||||||
class NimBLEDescriptorCallbacks;
|
class NimBLEDescriptorCallbacks;
|
||||||
|
@ -56,24 +47,36 @@ public:
|
||||||
uint16_t getHandle();
|
uint16_t getHandle();
|
||||||
NimBLEUUID getUUID();
|
NimBLEUUID getUUID();
|
||||||
std::string toString();
|
std::string toString();
|
||||||
|
|
||||||
void setCallbacks(NimBLEDescriptorCallbacks* pCallbacks);
|
void setCallbacks(NimBLEDescriptorCallbacks* pCallbacks);
|
||||||
|
NimBLECharacteristic* getCharacteristic();
|
||||||
|
|
||||||
size_t getLength();
|
size_t getLength();
|
||||||
uint8_t* getValue();
|
NimBLEAttValue getValue(time_t *timestamp = nullptr);
|
||||||
std::string getStringValue();
|
std::string getStringValue();
|
||||||
|
|
||||||
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::vector<uint8_t>& vec);
|
||||||
NimBLECharacteristic* getCharacteristic();
|
|
||||||
|
/*********************** Template Functions ************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Convenience template to set the descriptor value to <type\>val.
|
* @brief Template to set the characteristic value to <type\>val.
|
||||||
* @param [in] s The value to set.
|
* @param [in] s The value to set.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void setValue(const T &s) {
|
void setValue(const T &s) { m_value.setValue<T>(s); }
|
||||||
setValue((uint8_t*)&s, sizeof(T));
|
|
||||||
|
/**
|
||||||
|
* @brief Template to convert the descriptor data to <type\>.
|
||||||
|
* @tparam T The type to convert the data to.
|
||||||
|
* @param [in] timestamp (Optional) A pointer to a time_t struct to store the time the value was read.
|
||||||
|
* @param [in] skipSizeCheck (Optional) 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>(×tamp, skipSizeCheck);</tt>
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
T getValue(time_t *timestamp = nullptr, bool skipSizeCheck = false) {
|
||||||
|
return m_value.getValue<T>(timestamp, skipSizeCheck);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -91,8 +94,7 @@ private:
|
||||||
NimBLEDescriptorCallbacks* m_pCallbacks;
|
NimBLEDescriptorCallbacks* m_pCallbacks;
|
||||||
NimBLECharacteristic* m_pCharacteristic;
|
NimBLECharacteristic* m_pCharacteristic;
|
||||||
uint8_t m_properties;
|
uint8_t m_properties;
|
||||||
attr_value_t m_value;
|
NimBLEAttValue m_value;
|
||||||
portMUX_TYPE m_valMux;
|
|
||||||
uint8_t m_removed;
|
uint8_t m_removed;
|
||||||
}; // NimBLEDescriptor
|
}; // NimBLEDescriptor
|
||||||
|
|
||||||
|
@ -113,6 +115,5 @@ public:
|
||||||
|
|
||||||
#include "NimBLE2904.h"
|
#include "NimBLE2904.h"
|
||||||
|
|
||||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL */
|
||||||
#endif /* CONFIG_BT_ENABLED */
|
|
||||||
#endif /* MAIN_NIMBLEDESCRIPTOR_H_ */
|
#endif /* MAIN_NIMBLEDESCRIPTOR_H_ */
|
||||||
|
|
|
@ -11,27 +11,45 @@
|
||||||
* Created on: Mar 16, 2017
|
* Created on: Mar 16, 2017
|
||||||
* Author: kolban
|
* Author: kolban
|
||||||
*/
|
*/
|
||||||
#include "sdkconfig.h"
|
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
|
||||||
|
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
|
#if defined(CONFIG_BT_ENABLED)
|
||||||
|
|
||||||
#include "NimBLEDevice.h"
|
#include "NimBLEDevice.h"
|
||||||
#include "NimBLEUtils.h"
|
#include "NimBLEUtils.h"
|
||||||
|
|
||||||
#include "esp_err.h"
|
#ifdef ESP_PLATFORM
|
||||||
#include "esp_bt.h"
|
# include "esp_err.h"
|
||||||
#include "nvs_flash.h"
|
# include "esp_bt.h"
|
||||||
#include "esp_nimble_hci.h"
|
# include "nvs_flash.h"
|
||||||
#include "nimble/nimble_port.h"
|
# if defined(CONFIG_NIMBLE_CPP_IDF)
|
||||||
#include "nimble/nimble_port_freertos.h"
|
# include "esp_nimble_hci.h"
|
||||||
#include "host/ble_hs.h"
|
# include "nimble/nimble_port.h"
|
||||||
#include "host/ble_hs_pvcy.h"
|
# include "nimble/nimble_port_freertos.h"
|
||||||
#include "host/util/util.h"
|
# include "host/ble_hs.h"
|
||||||
#include "services/gap/ble_svc_gap.h"
|
# include "host/ble_hs_pvcy.h"
|
||||||
#include "services/gatt/ble_svc_gatt.h"
|
# include "host/util/util.h"
|
||||||
|
# include "services/gap/ble_svc_gap.h"
|
||||||
|
# include "services/gatt/ble_svc_gatt.h"
|
||||||
|
# else
|
||||||
|
# include "nimble/esp_port/esp-hci/include/esp_nimble_hci.h"
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# include "nimble/nimble/controller/include/controller/ble_phy.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_ENABLE_ARDUINO_DEPENDS
|
#ifndef CONFIG_NIMBLE_CPP_IDF
|
||||||
#include "esp32-hal-bt.h"
|
# include "nimble/porting/nimble/include/nimble/nimble_port.h"
|
||||||
|
# include "nimble/porting/npl/freertos/include/nimble/nimble_port_freertos.h"
|
||||||
|
# include "nimble/nimble/host/include/host/ble_hs.h"
|
||||||
|
# include "nimble/nimble/host/include/host/ble_hs_pvcy.h"
|
||||||
|
# include "nimble/nimble/host/util/include/host/util/util.h"
|
||||||
|
# include "nimble/nimble/host/services/gap/include/services/gap/ble_svc_gap.h"
|
||||||
|
# include "nimble/nimble/host/services/gatt/include/services/gatt/ble_svc_gatt.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ESP_PLATFORM) && defined(CONFIG_ENABLE_ARDUINO_DEPENDS)
|
||||||
|
# include "esp32-hal-bt.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "NimBLELog.h"
|
#include "NimBLELog.h"
|
||||||
|
@ -63,9 +81,10 @@ std::list <NimBLEAddress> NimBLEDevice::m_ignoreList;
|
||||||
std::vector<NimBLEAddress> NimBLEDevice::m_whiteList;
|
std::vector<NimBLEAddress> NimBLEDevice::m_whiteList;
|
||||||
NimBLESecurityCallbacks* NimBLEDevice::m_securityCallbacks = nullptr;
|
NimBLESecurityCallbacks* NimBLEDevice::m_securityCallbacks = nullptr;
|
||||||
uint8_t NimBLEDevice::m_own_addr_type = BLE_OWN_ADDR_PUBLIC;
|
uint8_t NimBLEDevice::m_own_addr_type = BLE_OWN_ADDR_PUBLIC;
|
||||||
|
#ifdef ESP_PLATFORM
|
||||||
uint16_t NimBLEDevice::m_scanDuplicateSize = CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE;
|
uint16_t NimBLEDevice::m_scanDuplicateSize = CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE;
|
||||||
uint8_t NimBLEDevice::m_scanFilterMode = CONFIG_BTDM_SCAN_DUPL_TYPE;
|
uint8_t NimBLEDevice::m_scanFilterMode = CONFIG_BTDM_SCAN_DUPL_TYPE;
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create a new instance of a server.
|
* @brief Create a new instance of a server.
|
||||||
|
@ -130,7 +149,8 @@ void NimBLEDevice::stopAdvertising() {
|
||||||
* try and release/delete it.
|
* try and release/delete it.
|
||||||
*/
|
*/
|
||||||
#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
||||||
/* STATIC */ NimBLEScan* NimBLEDevice::getScan() {
|
/* STATIC */
|
||||||
|
NimBLEScan* NimBLEDevice::getScan() {
|
||||||
if (m_pScan == nullptr) {
|
if (m_pScan == nullptr) {
|
||||||
m_pScan = new NimBLEScan();
|
m_pScan = new NimBLEScan();
|
||||||
}
|
}
|
||||||
|
@ -147,7 +167,8 @@ void NimBLEDevice::stopAdvertising() {
|
||||||
* @return A reference to the new client object.
|
* @return A reference to the new client object.
|
||||||
*/
|
*/
|
||||||
#if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
#if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||||
/* STATIC */ NimBLEClient* NimBLEDevice::createClient(NimBLEAddress peerAddress) {
|
/* STATIC */
|
||||||
|
NimBLEClient* NimBLEDevice::createClient(NimBLEAddress peerAddress) {
|
||||||
if(m_cList.size() >= NIMBLE_MAX_CONNECTIONS) {
|
if(m_cList.size() >= NIMBLE_MAX_CONNECTIONS) {
|
||||||
NIMBLE_LOGW(LOG_TAG,"Number of clients exceeds Max connections. Cur=%d Max=%d",
|
NIMBLE_LOGW(LOG_TAG,"Number of clients exceeds Max connections. Cur=%d Max=%d",
|
||||||
m_cList.size(), NIMBLE_MAX_CONNECTIONS);
|
m_cList.size(), NIMBLE_MAX_CONNECTIONS);
|
||||||
|
@ -165,7 +186,8 @@ void NimBLEDevice::stopAdvertising() {
|
||||||
* Checks if it is connected or trying to connect and disconnects/stops it first.
|
* Checks if it is connected or trying to connect and disconnects/stops it first.
|
||||||
* @param [in] pClient A 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) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -209,7 +231,8 @@ void NimBLEDevice::stopAdvertising() {
|
||||||
* @brief Get the list of created client objects.
|
* @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;
|
||||||
} // getClientList
|
} // getClientList
|
||||||
|
|
||||||
|
@ -218,7 +241,8 @@ void NimBLEDevice::stopAdvertising() {
|
||||||
* @brief Get the number of created client objects.
|
* @brief Get the number of created client objects.
|
||||||
* @return Number of client objects created.
|
* @return Number of client objects created.
|
||||||
*/
|
*/
|
||||||
/* STATIC */size_t NimBLEDevice::getClientListSize() {
|
/* STATIC */
|
||||||
|
size_t NimBLEDevice::getClientListSize() {
|
||||||
return m_cList.size();
|
return m_cList.size();
|
||||||
} // getClientList
|
} // getClientList
|
||||||
|
|
||||||
|
@ -228,7 +252,8 @@ void NimBLEDevice::stopAdvertising() {
|
||||||
* @param [in] conn_id The client connection ID to search for.
|
* @param [in] conn_id The client connection ID to search for.
|
||||||
* @return A pointer to the client object 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) {
|
||||||
if((*it)->getConnId() == conn_id) {
|
if((*it)->getConnId() == conn_id) {
|
||||||
return (*it);
|
return (*it);
|
||||||
|
@ -244,7 +269,8 @@ void NimBLEDevice::stopAdvertising() {
|
||||||
* @param [in] peer_addr The address of the peer to search for.
|
* @param [in] peer_addr The address of the peer to search for.
|
||||||
* @return A pointer to the client object 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) {
|
||||||
if((*it)->getPeerAddress().equals(peer_addr)) {
|
if((*it)->getPeerAddress().equals(peer_addr)) {
|
||||||
return (*it);
|
return (*it);
|
||||||
|
@ -258,7 +284,8 @@ void NimBLEDevice::stopAdvertising() {
|
||||||
* @brief Finds the first disconnected client in the list.
|
* @brief Finds the first disconnected client in the list.
|
||||||
* @return A pointer to the first client object 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) {
|
||||||
if(!(*it)->isConnected()) {
|
if(!(*it)->isConnected()) {
|
||||||
return (*it);
|
return (*it);
|
||||||
|
@ -269,7 +296,7 @@ void NimBLEDevice::stopAdvertising() {
|
||||||
|
|
||||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||||
|
|
||||||
|
#ifdef ESP_PLATFORM
|
||||||
/**
|
/**
|
||||||
* @brief Set the transmission power.
|
* @brief Set the transmission power.
|
||||||
* @param [in] powerLevel The power level to set, can be one of:
|
* @param [in] powerLevel The power level to set, can be one of:
|
||||||
|
@ -295,12 +322,15 @@ void NimBLEDevice::stopAdvertising() {
|
||||||
* * ESP_BLE_PWR_TYPE_SCAN = 10, For scan
|
* * 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
|
* * 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);
|
||||||
|
|
||||||
esp_err_t errRc = esp_ble_tx_power_set(powerType, powerLevel);
|
esp_err_t errRc = esp_ble_tx_power_set(powerType, powerLevel);
|
||||||
if (errRc != ESP_OK) {
|
if (errRc != ESP_OK) {
|
||||||
NIMBLE_LOGE(LOG_TAG, "esp_ble_tx_power_set: rc=%d", errRc);
|
NIMBLE_LOGE(LOG_TAG, "esp_ble_tx_power_set: rc=%d", errRc);
|
||||||
}
|
}
|
||||||
|
|
||||||
NIMBLE_LOGD(LOG_TAG, "<< setPower");
|
NIMBLE_LOGD(LOG_TAG, "<< setPower");
|
||||||
} // setPower
|
} // setPower
|
||||||
|
|
||||||
|
@ -322,9 +352,8 @@ void NimBLEDevice::stopAdvertising() {
|
||||||
* * ESP_BLE_PWR_TYPE_DEFAULT = 11, For default, if not set other, it will use default value
|
* * 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.
|
* @return the power level currently used by the type specified.
|
||||||
*/
|
*/
|
||||||
|
/* STATIC */
|
||||||
/* STATIC */ int NimBLEDevice::getPower(esp_ble_power_type_t powerType) {
|
int NimBLEDevice::getPower(esp_ble_power_type_t powerType) {
|
||||||
|
|
||||||
switch(esp_ble_tx_power_get(powerType)) {
|
switch(esp_ble_tx_power_get(powerType)) {
|
||||||
case ESP_PWR_LVL_N12:
|
case ESP_PWR_LVL_N12:
|
||||||
return -12;
|
return -12;
|
||||||
|
@ -347,13 +376,25 @@ void NimBLEDevice::stopAdvertising() {
|
||||||
}
|
}
|
||||||
} // getPower
|
} // getPower
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
void NimBLEDevice::setPower(int dbm) {
|
||||||
|
ble_phy_txpwr_set(dbm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int NimBLEDevice::getPower() {
|
||||||
|
return ble_phy_txpwr_get();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get our device address.
|
* @brief Get our device address.
|
||||||
* @return A NimBLEAddress object of our public address if we have one,
|
* @return A NimBLEAddress object of our public address if we have one,
|
||||||
* if not then our current random address.
|
* if not then our current random address.
|
||||||
*/
|
*/
|
||||||
/* STATIC*/ NimBLEAddress NimBLEDevice::getAddress() {
|
/* STATIC*/
|
||||||
|
NimBLEAddress NimBLEDevice::getAddress() {
|
||||||
ble_addr_t addr = {BLE_ADDR_PUBLIC, 0};
|
ble_addr_t addr = {BLE_ADDR_PUBLIC, 0};
|
||||||
|
|
||||||
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)) {
|
||||||
|
@ -370,7 +411,8 @@ void NimBLEDevice::stopAdvertising() {
|
||||||
* @brief Return a string representation of the address of this device.
|
* @brief Return a string representation of the address of this device.
|
||||||
* @return A string representation of this device address.
|
* @return A string representation of this device address.
|
||||||
*/
|
*/
|
||||||
/* STATIC */ std::string NimBLEDevice::toString() {
|
/* STATIC */
|
||||||
|
std::string NimBLEDevice::toString() {
|
||||||
return getAddress().toString();
|
return getAddress().toString();
|
||||||
} // toString
|
} // toString
|
||||||
|
|
||||||
|
@ -380,7 +422,8 @@ void NimBLEDevice::stopAdvertising() {
|
||||||
* @param [in] mtu Value to set local mtu:
|
* @param [in] mtu Value to set local mtu:
|
||||||
* * This should be larger than 23 and lower or equal to 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);
|
||||||
|
|
||||||
int rc = ble_att_set_preferred_mtu(mtu);
|
int rc = ble_att_set_preferred_mtu(mtu);
|
||||||
|
@ -398,11 +441,13 @@ void NimBLEDevice::stopAdvertising() {
|
||||||
* @brief Get local MTU value set.
|
* @brief Get local MTU value set.
|
||||||
* @return The current preferred MTU setting.
|
* @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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef ESP_PLATFORM
|
||||||
/**
|
/**
|
||||||
* @brief Set the duplicate filter cache size for filtering scanned devices.
|
* @brief Set the duplicate filter cache size for filtering scanned devices.
|
||||||
* @param [in] cacheSize The number of advertisements filtered before the cache is reset.\n
|
* @param [in] cacheSize The number of advertisements filtered before the cache is reset.\n
|
||||||
|
@ -448,6 +493,7 @@ void NimBLEDevice::setScanFilterMode(uint8_t mode) {
|
||||||
|
|
||||||
m_scanFilterMode = mode;
|
m_scanFilterMode = mode;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) || defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
#if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) || defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||||
/**
|
/**
|
||||||
|
@ -470,7 +516,7 @@ int NimBLEDevice::getNumBonds() {
|
||||||
/**
|
/**
|
||||||
* @brief Deletes all bonding information.
|
* @brief Deletes all bonding information.
|
||||||
*/
|
*/
|
||||||
/*STATIC*/
|
/*STATIC*/
|
||||||
void NimBLEDevice::deleteAllBonds() {
|
void NimBLEDevice::deleteAllBonds() {
|
||||||
ble_store_clear();
|
ble_store_clear();
|
||||||
}
|
}
|
||||||
|
@ -550,6 +596,7 @@ NimBLEAddress NimBLEDevice::getBondedAddress(int index) {
|
||||||
* @param [in] address The address to check for in the whitelist.
|
* @param [in] address The address to check for in the whitelist.
|
||||||
* @returns true if the address is in the whitelist.
|
* @returns true if the address is in the whitelist.
|
||||||
*/
|
*/
|
||||||
|
/*STATIC*/
|
||||||
bool NimBLEDevice::onWhiteList(const NimBLEAddress & address) {
|
bool NimBLEDevice::onWhiteList(const NimBLEAddress & address) {
|
||||||
for (auto &it : m_whiteList) {
|
for (auto &it : m_whiteList) {
|
||||||
if (it == address) {
|
if (it == address) {
|
||||||
|
@ -566,6 +613,7 @@ bool NimBLEDevice::onWhiteList(const NimBLEAddress & address) {
|
||||||
* @param [in] address The address to add to the whitelist.
|
* @param [in] address The address to add to the whitelist.
|
||||||
* @returns true if successful.
|
* @returns true if successful.
|
||||||
*/
|
*/
|
||||||
|
/*STATIC*/
|
||||||
bool NimBLEDevice::whiteListAdd(const NimBLEAddress & address) {
|
bool NimBLEDevice::whiteListAdd(const NimBLEAddress & address) {
|
||||||
if (NimBLEDevice::onWhiteList(address)) {
|
if (NimBLEDevice::onWhiteList(address)) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -597,6 +645,7 @@ bool NimBLEDevice::whiteListAdd(const NimBLEAddress & address) {
|
||||||
* @param [in] address The address to remove from the whitelist.
|
* @param [in] address The address to remove from the whitelist.
|
||||||
* @returns true if successful.
|
* @returns true if successful.
|
||||||
*/
|
*/
|
||||||
|
/*STATIC*/
|
||||||
bool NimBLEDevice::whiteListRemove(const NimBLEAddress & address) {
|
bool NimBLEDevice::whiteListRemove(const NimBLEAddress & address) {
|
||||||
if (!NimBLEDevice::onWhiteList(address)) {
|
if (!NimBLEDevice::onWhiteList(address)) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -636,6 +685,7 @@ bool NimBLEDevice::whiteListRemove(const NimBLEAddress & address) {
|
||||||
* @brief Gets the count of addresses in the whitelist.
|
* @brief Gets the count of addresses in the whitelist.
|
||||||
* @returns The number of addresses in the whitelist.
|
* @returns The number of addresses in the whitelist.
|
||||||
*/
|
*/
|
||||||
|
/*STATIC*/
|
||||||
size_t NimBLEDevice::getWhiteListCount() {
|
size_t NimBLEDevice::getWhiteListCount() {
|
||||||
return m_whiteList.size();
|
return m_whiteList.size();
|
||||||
}
|
}
|
||||||
|
@ -646,6 +696,7 @@ size_t NimBLEDevice::getWhiteListCount() {
|
||||||
* @param [in] index The vector index to retrieve the address from.
|
* @param [in] index The vector index to retrieve the address from.
|
||||||
* @returns the NimBLEAddress at the whitelist index or nullptr if not found.
|
* @returns the NimBLEAddress at the whitelist index or nullptr if not found.
|
||||||
*/
|
*/
|
||||||
|
/*STATIC*/
|
||||||
NimBLEAddress NimBLEDevice::getWhiteListAddress(size_t index) {
|
NimBLEAddress NimBLEDevice::getWhiteListAddress(size_t index) {
|
||||||
if (index > m_whiteList.size()) {
|
if (index > m_whiteList.size()) {
|
||||||
NIMBLE_LOGE(LOG_TAG, "Invalid index; %u", index);
|
NIMBLE_LOGE(LOG_TAG, "Invalid index; %u", index);
|
||||||
|
@ -659,7 +710,8 @@ NimBLEAddress NimBLEDevice::getWhiteListAddress(size_t index) {
|
||||||
* @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.
|
* @param [in] reason The reason code for the reset.
|
||||||
*/
|
*/
|
||||||
/* STATIC */ void NimBLEDevice::onReset(int reason)
|
/* STATIC */
|
||||||
|
void NimBLEDevice::onReset(int reason)
|
||||||
{
|
{
|
||||||
if(!m_synced) {
|
if(!m_synced) {
|
||||||
return;
|
return;
|
||||||
|
@ -683,7 +735,8 @@ NimBLEAddress NimBLEDevice::getWhiteListAddress(size_t index) {
|
||||||
/**
|
/**
|
||||||
* @brief Host resynced with controller, all clear to make calls to the stack.
|
* @brief Host resynced with controller, all clear to make calls to the stack.
|
||||||
*/
|
*/
|
||||||
/* STATIC */ void NimBLEDevice::onSync(void)
|
/* STATIC */
|
||||||
|
void NimBLEDevice::onSync(void)
|
||||||
{
|
{
|
||||||
NIMBLE_LOGI(LOG_TAG, "NimBle host synced.");
|
NIMBLE_LOGI(LOG_TAG, "NimBle host synced.");
|
||||||
// This check is needed due to potentially being called multiple times in succession
|
// This check is needed due to potentially being called multiple times in succession
|
||||||
|
@ -696,6 +749,14 @@ NimBLEAddress NimBLEDevice::getWhiteListAddress(size_t index) {
|
||||||
int rc = ble_hs_util_ensure_addr(0);
|
int rc = ble_hs_util_ensure_addr(0);
|
||||||
assert(rc == 0);
|
assert(rc == 0);
|
||||||
|
|
||||||
|
#ifndef ESP_PLATFORM
|
||||||
|
rc = ble_hs_id_infer_auto(m_own_addr_type, &m_own_addr_type);
|
||||||
|
if (rc != 0) {
|
||||||
|
NIMBLE_LOGE(LOG_TAG, "error determining address type; rc=%d", rc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Yield for houskeeping before returning to operations.
|
// Yield for houskeeping before returning to operations.
|
||||||
// Occasionally triggers exception without.
|
// Occasionally triggers exception without.
|
||||||
taskYIELD();
|
taskYIELD();
|
||||||
|
@ -721,9 +782,11 @@ NimBLEAddress NimBLEDevice::getWhiteListAddress(size_t index) {
|
||||||
/**
|
/**
|
||||||
* @brief The main host task.
|
* @brief The main host task.
|
||||||
*/
|
*/
|
||||||
/* STATIC */ void NimBLEDevice::host_task(void *param)
|
/* STATIC */
|
||||||
|
void NimBLEDevice::host_task(void *param)
|
||||||
{
|
{
|
||||||
NIMBLE_LOGI(LOG_TAG, "BLE Host Task Started");
|
NIMBLE_LOGI(LOG_TAG, "BLE Host Task Started");
|
||||||
|
|
||||||
/* This function will return only when nimble_port_stop() is executed */
|
/* This function will return only when nimble_port_stop() is executed */
|
||||||
nimble_port_run();
|
nimble_port_run();
|
||||||
|
|
||||||
|
@ -735,9 +798,11 @@ NimBLEAddress NimBLEDevice::getWhiteListAddress(size_t index) {
|
||||||
* @brief Initialize the %BLE environment.
|
* @brief Initialize the %BLE environment.
|
||||||
* @param [in] 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){
|
||||||
int rc=0;
|
int rc=0;
|
||||||
|
#ifdef ESP_PLATFORM
|
||||||
esp_err_t errRc = ESP_OK;
|
esp_err_t errRc = ESP_OK;
|
||||||
|
|
||||||
#ifdef CONFIG_ENABLE_ARDUINO_DEPENDS
|
#ifdef CONFIG_ENABLE_ARDUINO_DEPENDS
|
||||||
|
@ -757,7 +822,7 @@ NimBLEAddress NimBLEDevice::getWhiteListAddress(size_t index) {
|
||||||
esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT);
|
esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT);
|
||||||
|
|
||||||
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
|
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
|
||||||
#ifdef CONFIG_IDF_TARGET_ESP32C3
|
#if defined (CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||||
bt_cfg.bluetooth_mode = ESP_BT_MODE_BLE;
|
bt_cfg.bluetooth_mode = ESP_BT_MODE_BLE;
|
||||||
#else
|
#else
|
||||||
bt_cfg.mode = ESP_BT_MODE_BLE;
|
bt_cfg.mode = ESP_BT_MODE_BLE;
|
||||||
|
@ -769,6 +834,7 @@ NimBLEAddress NimBLEDevice::getWhiteListAddress(size_t index) {
|
||||||
ESP_ERROR_CHECK(esp_bt_controller_init(&bt_cfg));
|
ESP_ERROR_CHECK(esp_bt_controller_init(&bt_cfg));
|
||||||
ESP_ERROR_CHECK(esp_bt_controller_enable(ESP_BT_MODE_BLE));
|
ESP_ERROR_CHECK(esp_bt_controller_enable(ESP_BT_MODE_BLE));
|
||||||
ESP_ERROR_CHECK(esp_nimble_hci_init());
|
ESP_ERROR_CHECK(esp_nimble_hci_init());
|
||||||
|
#endif
|
||||||
nimble_port_init();
|
nimble_port_init();
|
||||||
|
|
||||||
// Setup callbacks for host events
|
// Setup callbacks for host events
|
||||||
|
@ -793,9 +859,10 @@ NimBLEAddress NimBLEDevice::getWhiteListAddress(size_t index) {
|
||||||
|
|
||||||
nimble_port_freertos_init(NimBLEDevice::host_task);
|
nimble_port_freertos_init(NimBLEDevice::host_task);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for host and controller to sync before returning and accepting new tasks
|
// Wait for host and controller to sync before returning and accepting new tasks
|
||||||
while(!m_synced){
|
while(!m_synced){
|
||||||
vTaskDelay(1 / portTICK_PERIOD_MS);
|
taskYIELD();
|
||||||
}
|
}
|
||||||
|
|
||||||
initialized = true; // Set the initialization flag to ensure we are only initialized once.
|
initialized = true; // Set the initialization flag to ensure we are only initialized once.
|
||||||
|
@ -807,16 +874,17 @@ NimBLEAddress NimBLEDevice::getWhiteListAddress(size_t index) {
|
||||||
* @param [in] clearAll If true, deletes all server/advertising/scan/client objects after deinitializing.
|
* @param [in] clearAll If true, deletes all server/advertising/scan/client objects after deinitializing.
|
||||||
* @note If clearAll is true when called, any references to the created objects become invalid.
|
* @note If clearAll is true when called, any references to the created objects become invalid.
|
||||||
*/
|
*/
|
||||||
/* STATIC */ void NimBLEDevice::deinit(bool clearAll) {
|
/* STATIC */
|
||||||
|
void NimBLEDevice::deinit(bool clearAll) {
|
||||||
int ret = nimble_port_stop();
|
int ret = nimble_port_stop();
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
nimble_port_deinit();
|
nimble_port_deinit();
|
||||||
|
#ifdef ESP_PLATFORM
|
||||||
ret = esp_nimble_hci_and_controller_deinit();
|
ret = esp_nimble_hci_and_controller_deinit();
|
||||||
if (ret != ESP_OK) {
|
if (ret != ESP_OK) {
|
||||||
NIMBLE_LOGE(LOG_TAG, "esp_nimble_hci_and_controller_deinit() failed with error: %d", ret);
|
NIMBLE_LOGE(LOG_TAG, "esp_nimble_hci_and_controller_deinit() failed with error: %d", ret);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
initialized = false;
|
initialized = false;
|
||||||
m_synced = false;
|
m_synced = false;
|
||||||
|
|
||||||
|
@ -863,6 +931,7 @@ NimBLEAddress NimBLEDevice::getWhiteListAddress(size_t index) {
|
||||||
* @brief Check if the initialization is complete.
|
* @brief Check if the initialization is complete.
|
||||||
* @return true if initialized.
|
* @return true if initialized.
|
||||||
*/
|
*/
|
||||||
|
/*STATIC*/
|
||||||
bool NimBLEDevice::getInitialized() {
|
bool NimBLEDevice::getInitialized() {
|
||||||
return initialized;
|
return initialized;
|
||||||
} // getInitialized
|
} // getInitialized
|
||||||
|
@ -874,7 +943,8 @@ bool NimBLEDevice::getInitialized() {
|
||||||
* @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);
|
||||||
ble_hs_cfg.sm_bonding = bonding;
|
ble_hs_cfg.sm_bonding = bonding;
|
||||||
ble_hs_cfg.sm_mitm = mitm;
|
ble_hs_cfg.sm_mitm = mitm;
|
||||||
|
@ -891,7 +961,8 @@ bool NimBLEDevice::getInitialized() {
|
||||||
* * 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.
|
||||||
*/
|
*/
|
||||||
/*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,
|
||||||
(auth_req & BLE_SM_PAIR_AUTHREQ_MITM)>0,
|
(auth_req & BLE_SM_PAIR_AUTHREQ_MITM)>0,
|
||||||
(auth_req & BLE_SM_PAIR_AUTHREQ_SC)>0);
|
(auth_req & BLE_SM_PAIR_AUTHREQ_SC)>0);
|
||||||
|
@ -907,7 +978,8 @@ bool NimBLEDevice::getInitialized() {
|
||||||
* * 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;
|
||||||
} // setSecurityIOCap
|
} // setSecurityIOCap
|
||||||
|
|
||||||
|
@ -921,7 +993,8 @@ bool NimBLEDevice::getInitialized() {
|
||||||
* * 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;
|
||||||
} // setsSecurityInitKey
|
} // setsSecurityInitKey
|
||||||
|
|
||||||
|
@ -935,7 +1008,8 @@ bool NimBLEDevice::getInitialized() {
|
||||||
* * 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 resp_key) {
|
/*STATIC*/
|
||||||
|
void NimBLEDevice::setSecurityRespKey(uint8_t resp_key) {
|
||||||
ble_hs_cfg.sm_their_key_dist = resp_key;
|
ble_hs_cfg.sm_their_key_dist = resp_key;
|
||||||
} // setsSecurityRespKey
|
} // setsSecurityRespKey
|
||||||
|
|
||||||
|
@ -944,7 +1018,8 @@ bool NimBLEDevice::getInitialized() {
|
||||||
* @brief Set the passkey the server will ask for when pairing.
|
* @brief Set the passkey the server will ask for when pairing.
|
||||||
* @param [in] pin The passkey to use.
|
* @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;
|
||||||
} // setSecurityPasskey
|
} // setSecurityPasskey
|
||||||
|
|
||||||
|
@ -953,7 +1028,8 @@ bool NimBLEDevice::getInitialized() {
|
||||||
* @brief Get the current passkey used for pairing.
|
* @brief Get the current passkey used for pairing.
|
||||||
* @return The current passkey.
|
* @return The current passkey.
|
||||||
*/
|
*/
|
||||||
/*STATIC*/uint32_t NimBLEDevice::getSecurityPasskey() {
|
/*STATIC*/
|
||||||
|
uint32_t NimBLEDevice::getSecurityPasskey() {
|
||||||
return m_passkey;
|
return m_passkey;
|
||||||
} // getSecurityPasskey
|
} // getSecurityPasskey
|
||||||
|
|
||||||
|
@ -963,11 +1039,13 @@ bool NimBLEDevice::getInitialized() {
|
||||||
* @param [in] callbacks Pointer to NimBLESecurityCallbacks class
|
* @param [in] callbacks Pointer to NimBLESecurityCallbacks class
|
||||||
* @deprecated For backward compatibility, New code should use client/server callback methods.
|
* @deprecated For backward compatibility, New code should use client/server callback methods.
|
||||||
*/
|
*/
|
||||||
|
/*STATIC*/
|
||||||
void NimBLEDevice::setSecurityCallbacks(NimBLESecurityCallbacks* callbacks) {
|
void NimBLEDevice::setSecurityCallbacks(NimBLESecurityCallbacks* callbacks) {
|
||||||
NimBLEDevice::m_securityCallbacks = callbacks;
|
NimBLEDevice::m_securityCallbacks = callbacks;
|
||||||
} // setSecurityCallbacks
|
} // setSecurityCallbacks
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef ESP_PLATFORM
|
||||||
/**
|
/**
|
||||||
* @brief Set the own address type.
|
* @brief Set the own address type.
|
||||||
* @param [in] own_addr_type Own Bluetooth Device address type.\n
|
* @param [in] own_addr_type Own Bluetooth Device address type.\n
|
||||||
|
@ -978,6 +1056,7 @@ void NimBLEDevice::setSecurityCallbacks(NimBLESecurityCallbacks* callbacks) {
|
||||||
* * 0x03: BLE_OWN_ADDR_RPA_RANDOM_DEFAULT
|
* * 0x03: BLE_OWN_ADDR_RPA_RANDOM_DEFAULT
|
||||||
* @param [in] useNRPA If true, and address type is random, uses a non-resolvable random address.
|
* @param [in] useNRPA If true, and address type is random, uses a non-resolvable random address.
|
||||||
*/
|
*/
|
||||||
|
/*STATIC*/
|
||||||
void NimBLEDevice::setOwnAddrType(uint8_t own_addr_type, bool useNRPA) {
|
void NimBLEDevice::setOwnAddrType(uint8_t own_addr_type, bool useNRPA) {
|
||||||
m_own_addr_type = own_addr_type;
|
m_own_addr_type = own_addr_type;
|
||||||
switch (own_addr_type) {
|
switch (own_addr_type) {
|
||||||
|
@ -1001,18 +1080,15 @@ void NimBLEDevice::setOwnAddrType(uint8_t own_addr_type, bool useNRPA) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} // setOwnAddrType
|
} // setOwnAddrType
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Start the connection securing and authorization for this connection.
|
* @brief Start the connection securing and authorization for this connection.
|
||||||
* @param conn_id The connection id of the peer device.
|
* @param conn_id The connection id of the peer device.
|
||||||
* @returns NimBLE stack return code, 0 = success.
|
* @returns NimBLE stack return code, 0 = success.
|
||||||
*/
|
*/
|
||||||
/* STATIC */int NimBLEDevice::startSecurity(uint16_t conn_id) {
|
/* STATIC */
|
||||||
/* if(m_securityCallbacks != nullptr) {
|
int NimBLEDevice::startSecurity(uint16_t conn_id) {
|
||||||
m_securityCallbacks->onSecurityRequest();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
int rc = ble_gap_security_initiate(conn_id);
|
int rc = ble_gap_security_initiate(conn_id);
|
||||||
if(rc != 0){
|
if(rc != 0){
|
||||||
NIMBLE_LOGE(LOG_TAG, "ble_gap_security_initiate: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
|
NIMBLE_LOGE(LOG_TAG, "ble_gap_security_initiate: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
|
||||||
|
@ -1027,7 +1103,8 @@ void NimBLEDevice::setOwnAddrType(uint8_t own_addr_type, bool useNRPA) {
|
||||||
* @param [in] address The address to look for.
|
* @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) {
|
||||||
for(auto &it : m_ignoreList) {
|
for(auto &it : m_ignoreList) {
|
||||||
if(it.equals(address)){
|
if(it.equals(address)){
|
||||||
return true;
|
return true;
|
||||||
|
@ -1042,7 +1119,8 @@ void NimBLEDevice::setOwnAddrType(uint8_t own_addr_type, bool useNRPA) {
|
||||||
* @brief Add a device to the ignore list.
|
* @brief Add a device to the ignore list.
|
||||||
* @param [in] address The 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1051,7 +1129,8 @@ void NimBLEDevice::setOwnAddrType(uint8_t own_addr_type, bool useNRPA) {
|
||||||
* @brief Remove a device from the ignore list.
|
* @brief Remove a device from the ignore list.
|
||||||
* @param [in] address The 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) {
|
||||||
if((*it).equals(address)){
|
if((*it).equals(address)){
|
||||||
m_ignoreList.erase(it);
|
m_ignoreList.erase(it);
|
||||||
|
@ -1065,6 +1144,7 @@ void NimBLEDevice::setOwnAddrType(uint8_t own_addr_type, bool useNRPA) {
|
||||||
* @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.
|
* @param [in] handler The function to call when gap events occur.
|
||||||
*/
|
*/
|
||||||
|
/*STATIC*/
|
||||||
void NimBLEDevice::setCustomGapHandler(gap_event_handler handler) {
|
void NimBLEDevice::setCustomGapHandler(gap_event_handler handler) {
|
||||||
m_customGapHandler = handler;
|
m_customGapHandler = handler;
|
||||||
int rc = ble_gap_event_listener_register(&m_listener, m_customGapHandler, NULL);
|
int rc = ble_gap_event_listener_register(&m_listener, m_customGapHandler, NULL);
|
||||||
|
@ -1076,5 +1156,4 @@ void NimBLEDevice::setCustomGapHandler(gap_event_handler handler) {
|
||||||
}
|
}
|
||||||
} // setCustomGapHandler
|
} // setCustomGapHandler
|
||||||
|
|
||||||
|
|
||||||
#endif // CONFIG_BT_ENABLED
|
#endif // CONFIG_BT_ENABLED
|
||||||
|
|
|
@ -14,10 +14,9 @@
|
||||||
|
|
||||||
#ifndef MAIN_NIMBLEDEVICE_H_
|
#ifndef MAIN_NIMBLEDEVICE_H_
|
||||||
#define MAIN_NIMBLEDEVICE_H_
|
#define MAIN_NIMBLEDEVICE_H_
|
||||||
#include "sdkconfig.h"
|
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
|
||||||
|
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
|
#if defined(CONFIG_BT_ENABLED)
|
||||||
|
|
||||||
#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
||||||
#include "NimBLEScan.h"
|
#include "NimBLEScan.h"
|
||||||
|
@ -39,7 +38,9 @@
|
||||||
#include "NimBLESecurity.h"
|
#include "NimBLESecurity.h"
|
||||||
#include "NimBLEAddress.h"
|
#include "NimBLEAddress.h"
|
||||||
|
|
||||||
#include "esp_bt.h"
|
#ifdef ESP_PLATFORM
|
||||||
|
# include "esp_bt.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -110,8 +111,17 @@ public:
|
||||||
static NimBLEServer* getServer();
|
static NimBLEServer* getServer();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ESP_PLATFORM
|
||||||
static void setPower(esp_power_level_t powerLevel, esp_ble_power_type_t powerType=ESP_BLE_PWR_TYPE_DEFAULT);
|
static void setPower(esp_power_level_t powerLevel, esp_ble_power_type_t powerType=ESP_BLE_PWR_TYPE_DEFAULT);
|
||||||
static int getPower(esp_ble_power_type_t powerType=ESP_BLE_PWR_TYPE_DEFAULT);
|
static int getPower(esp_ble_power_type_t powerType=ESP_BLE_PWR_TYPE_DEFAULT);
|
||||||
|
static void setOwnAddrType(uint8_t own_addr_type, bool useNRPA=false);
|
||||||
|
static void setScanDuplicateCacheSize(uint16_t cacheSize);
|
||||||
|
static void setScanFilterMode(uint8_t type);
|
||||||
|
#else
|
||||||
|
static void setPower(int dbm);
|
||||||
|
static int getPower();
|
||||||
|
#endif
|
||||||
|
|
||||||
static void setCustomGapHandler(gap_event_handler handler);
|
static void setCustomGapHandler(gap_event_handler handler);
|
||||||
static void setSecurityAuth(bool bonding, bool mitm, bool sc);
|
static void setSecurityAuth(bool bonding, bool mitm, bool sc);
|
||||||
static void setSecurityAuth(uint8_t auth_req);
|
static void setSecurityAuth(uint8_t auth_req);
|
||||||
|
@ -121,15 +131,12 @@ public:
|
||||||
static void setSecurityPasskey(uint32_t pin);
|
static void setSecurityPasskey(uint32_t pin);
|
||||||
static uint32_t getSecurityPasskey();
|
static uint32_t getSecurityPasskey();
|
||||||
static void setSecurityCallbacks(NimBLESecurityCallbacks* pCallbacks);
|
static void setSecurityCallbacks(NimBLESecurityCallbacks* pCallbacks);
|
||||||
static void setOwnAddrType(uint8_t own_addr_type, bool useNRPA=false);
|
|
||||||
static int startSecurity(uint16_t conn_id);
|
static int startSecurity(uint16_t conn_id);
|
||||||
static int setMTU(uint16_t mtu);
|
static int setMTU(uint16_t mtu);
|
||||||
static uint16_t getMTU();
|
static uint16_t getMTU();
|
||||||
static bool isIgnored(const NimBLEAddress &address);
|
static bool isIgnored(const NimBLEAddress &address);
|
||||||
static void addIgnored(const NimBLEAddress &address);
|
static void addIgnored(const NimBLEAddress &address);
|
||||||
static void removeIgnored(const NimBLEAddress &address);
|
static void removeIgnored(const NimBLEAddress &address);
|
||||||
static void setScanDuplicateCacheSize(uint16_t cacheSize);
|
|
||||||
static void setScanFilterMode(uint8_t type);
|
|
||||||
|
|
||||||
#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
|
#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
|
||||||
static NimBLEAdvertising* getAdvertising();
|
static NimBLEAdvertising* getAdvertising();
|
||||||
|
@ -199,8 +206,10 @@ private:
|
||||||
static ble_gap_event_listener m_listener;
|
static ble_gap_event_listener m_listener;
|
||||||
static gap_event_handler m_customGapHandler;
|
static gap_event_handler m_customGapHandler;
|
||||||
static uint8_t m_own_addr_type;
|
static uint8_t m_own_addr_type;
|
||||||
|
#ifdef ESP_PLATFORM
|
||||||
static uint16_t m_scanDuplicateSize;
|
static uint16_t m_scanDuplicateSize;
|
||||||
static uint8_t m_scanFilterMode;
|
static uint8_t m_scanFilterMode;
|
||||||
|
#endif
|
||||||
static std::vector<NimBLEAddress> m_whiteList;
|
static std::vector<NimBLEAddress> m_whiteList;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -11,12 +11,14 @@
|
||||||
* Created on: Mar 12, 2018
|
* Created on: Mar 12, 2018
|
||||||
* Author: pcbreflux
|
* Author: pcbreflux
|
||||||
*/
|
*/
|
||||||
#include "sdkconfig.h"
|
|
||||||
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
#if defined(CONFIG_BT_ENABLED)
|
||||||
|
|
||||||
#include "NimBLEEddystoneTLM.h"
|
#include "NimBLEEddystoneTLM.h"
|
||||||
#include "NimBLELog.h"
|
#include "NimBLELog.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#define ENDIAN_CHANGE_U16(x) ((((x)&0xFF00)>>8) + (((x)&0xFF)<<8))
|
#define ENDIAN_CHANGE_U16(x) ((((x)&0xFF00)>>8) + (((x)&0xFF)<<8))
|
||||||
|
@ -124,30 +126,30 @@ std::string NimBLEEddystoneTLM::toString() {
|
||||||
out += " C\n";
|
out += " C\n";
|
||||||
|
|
||||||
out += "Adv. Count ";
|
out += "Adv. Count ";
|
||||||
snprintf(val, sizeof(val), "%d", ENDIAN_CHANGE_U32(m_eddystoneData.advCount));
|
snprintf(val, sizeof(val), "%" PRIu32, ENDIAN_CHANGE_U32(m_eddystoneData.advCount));
|
||||||
out += val;
|
out += val;
|
||||||
out += "\n";
|
out += "\n";
|
||||||
|
|
||||||
out += "Time in seconds ";
|
out += "Time in seconds ";
|
||||||
snprintf(val, sizeof(val), "%d", rawsec/10);
|
snprintf(val, sizeof(val), "%" PRIu32, rawsec/10);
|
||||||
out += val;
|
out += val;
|
||||||
out += "\n";
|
out += "\n";
|
||||||
|
|
||||||
out += "Time ";
|
out += "Time ";
|
||||||
|
|
||||||
snprintf(val, sizeof(val), "%04d", rawsec / 864000);
|
snprintf(val, sizeof(val), "%04" PRIu32, rawsec / 864000);
|
||||||
out += val;
|
out += val;
|
||||||
out += ".";
|
out += ".";
|
||||||
|
|
||||||
snprintf(val, sizeof(val), "%02d", (rawsec / 36000) % 24);
|
snprintf(val, sizeof(val), "%02" PRIu32, (rawsec / 36000) % 24);
|
||||||
out += val;
|
out += val;
|
||||||
out += ":";
|
out += ":";
|
||||||
|
|
||||||
snprintf(val, sizeof(val), "%02d", (rawsec / 600) % 60);
|
snprintf(val, sizeof(val), "%02" PRIu32, (rawsec / 600) % 60);
|
||||||
out += val;
|
out += val;
|
||||||
out += ":";
|
out += ":";
|
||||||
|
|
||||||
snprintf(val, sizeof(val), "%02d", (rawsec / 10) % 60);
|
snprintf(val, sizeof(val), "%02" PRIu32, (rawsec / 10) % 60);
|
||||||
out += val;
|
out += val;
|
||||||
out += "\n";
|
out += "\n";
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
#ifndef _NimBLEEddystoneTLM_H_
|
#ifndef _NimBLEEddystoneTLM_H_
|
||||||
#define _NimBLEEddystoneTLM_H_
|
#define _NimBLEEddystoneTLM_H_
|
||||||
|
|
||||||
#include "NimBLEUUID.h"
|
#include "NimBLEUUID.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
* Created on: Mar 12, 2018
|
* Created on: Mar 12, 2018
|
||||||
* Author: pcbreflux
|
* Author: pcbreflux
|
||||||
*/
|
*/
|
||||||
#include "sdkconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
#if defined(CONFIG_BT_ENABLED)
|
||||||
|
|
||||||
#include "NimBLEEddystoneURL.h"
|
#include "NimBLEEddystoneURL.h"
|
||||||
|
|
|
@ -11,11 +11,9 @@
|
||||||
* Created on: Jan 03, 2018
|
* Created on: Jan 03, 2018
|
||||||
* Author: chegewara
|
* Author: chegewara
|
||||||
*/
|
*/
|
||||||
#include "sdkconfig.h"
|
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
|
||||||
|
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||||
|
|
||||||
#include "NimBLEHIDDevice.h"
|
#include "NimBLEHIDDevice.h"
|
||||||
#include "NimBLE2904.h"
|
#include "NimBLE2904.h"
|
||||||
|
@ -29,7 +27,7 @@ NimBLEHIDDevice::NimBLEHIDDevice(NimBLEServer* server) {
|
||||||
* Here we create mandatory services described in bluetooth specification
|
* Here we create mandatory services described in bluetooth specification
|
||||||
*/
|
*/
|
||||||
m_deviceInfoService = server->createService(NimBLEUUID((uint16_t) 0x180a));
|
m_deviceInfoService = server->createService(NimBLEUUID((uint16_t) 0x180a));
|
||||||
m_hidService = server->createService(NimBLEUUID((uint16_t) 0x1812), 40);
|
m_hidService = server->createService(NimBLEUUID((uint16_t) 0x1812));
|
||||||
m_batteryService = server->createService(NimBLEUUID((uint16_t) 0x180f));
|
m_batteryService = server->createService(NimBLEUUID((uint16_t) 0x180f));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -247,5 +245,4 @@ NimBLEService* NimBLEHIDDevice::batteryService() {
|
||||||
return m_batteryService;
|
return m_batteryService;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL */
|
||||||
#endif // #if defined(CONFIG_BT_ENABLED)
|
|
||||||
|
|
|
@ -15,11 +15,8 @@
|
||||||
#ifndef _BLEHIDDEVICE_H_
|
#ifndef _BLEHIDDEVICE_H_
|
||||||
#define _BLEHIDDEVICE_H_
|
#define _BLEHIDDEVICE_H_
|
||||||
|
|
||||||
#include "sdkconfig.h"
|
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
|
||||||
|
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
|
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
|
||||||
|
|
||||||
#include "NimBLECharacteristic.h"
|
#include "NimBLECharacteristic.h"
|
||||||
#include "NimBLEService.h"
|
#include "NimBLEService.h"
|
||||||
|
@ -84,6 +81,6 @@ private:
|
||||||
NimBLECharacteristic* m_protocolModeCharacteristic; //0x2a4e
|
NimBLECharacteristic* m_protocolModeCharacteristic; //0x2a4e
|
||||||
NimBLECharacteristic* m_batteryLevelCharacteristic; //0x2a19
|
NimBLECharacteristic* m_batteryLevelCharacteristic; //0x2a19
|
||||||
};
|
};
|
||||||
#endif // CONFIG_BT_NIMBLE_ROLE_BROADCASTER
|
|
||||||
#endif // CONFIG_BT_ENABLED
|
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_BROADCASTER */
|
||||||
#endif /* _BLEHIDDEVICE_H_ */
|
#endif /* _BLEHIDDEVICE_H_ */
|
||||||
|
|
|
@ -12,59 +12,69 @@
|
||||||
|
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
#if defined(CONFIG_BT_ENABLED)
|
||||||
|
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#if defined(CONFIG_NIMBLE_CPP_IDF) // using esp-idf
|
||||||
#include "syscfg/syscfg.h"
|
# include "esp_log.h"
|
||||||
#include "modlog/modlog.h"
|
# ifndef CONFIG_NIMBLE_CPP_LOG_LEVEL
|
||||||
|
# define CONFIG_NIMBLE_CPP_LOG_LEVEL 0
|
||||||
|
# endif
|
||||||
|
|
||||||
// If Arduino is being used, strip out the colors and ignore log printing below ui setting.
|
# define NIMBLE_CPP_LOG_PRINT(level, tag, format, ...) do { \
|
||||||
// Note: because CONFIG_LOG_DEFAULT_LEVEL is set at ERROR in Arduino we must use MODLOG_DFLT(ERROR
|
if (CONFIG_NIMBLE_CPP_LOG_LEVEL >= level) \
|
||||||
// otherwise no messages will be printed above that level.
|
ESP_LOG_LEVEL_LOCAL(level, tag, format, ##__VA_ARGS__); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
#ifndef CONFIG_NIMBLE_CPP_DEBUG_LEVEL
|
# define NIMBLE_LOGD(tag, format, ...) \
|
||||||
#ifdef CORE_DEBUG_LEVEL
|
NIMBLE_CPP_LOG_PRINT(ESP_LOG_DEBUG, tag, format, ##__VA_ARGS__)
|
||||||
#define CONFIG_NIMBLE_CPP_DEBUG_LEVEL CORE_DEBUG_LEVEL
|
|
||||||
#else
|
|
||||||
#define CONFIG_NIMBLE_CPP_DEBUG_LEVEL 0
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CONFIG_NIMBLE_CPP_DEBUG_LEVEL >= 4
|
# define NIMBLE_LOGI(tag, format, ...) \
|
||||||
#define NIMBLE_LOGD( tag, format, ... ) MODLOG_DFLT(ERROR, "D %s: "#format"\n",tag,##__VA_ARGS__)
|
NIMBLE_CPP_LOG_PRINT(ESP_LOG_INFO, tag, format, ##__VA_ARGS__)
|
||||||
#else
|
|
||||||
#define NIMBLE_LOGD( tag, format, ... ) (void)tag
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CONFIG_NIMBLE_CPP_DEBUG_LEVEL >= 3
|
# define NIMBLE_LOGW(tag, format, ...) \
|
||||||
#define NIMBLE_LOGI( tag, format, ... ) MODLOG_DFLT(ERROR, "I %s: "#format"\n",tag,##__VA_ARGS__)
|
NIMBLE_CPP_LOG_PRINT(ESP_LOG_WARN, tag, format, ##__VA_ARGS__)
|
||||||
#else
|
|
||||||
#define NIMBLE_LOGI( tag, format, ... ) (void)tag
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CONFIG_NIMBLE_CPP_DEBUG_LEVEL >= 2
|
# define NIMBLE_LOGE(tag, format, ...) \
|
||||||
#define NIMBLE_LOGW( tag, format, ... ) MODLOG_DFLT(ERROR, "W %s: "#format"\n",tag,##__VA_ARGS__)
|
NIMBLE_CPP_LOG_PRINT(ESP_LOG_ERROR, tag, format, ##__VA_ARGS__)
|
||||||
#else
|
|
||||||
#define NIMBLE_LOGW( tag, format, ... ) (void)tag
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CONFIG_NIMBLE_CPP_DEBUG_LEVEL >= 1
|
# define NIMBLE_LOGC(tag, format, ...) \
|
||||||
#define NIMBLE_LOGE( tag, format, ... ) MODLOG_DFLT(ERROR, "E %s: "#format"\n",tag,##__VA_ARGS__)
|
NIMBLE_CPP_LOG_PRINT(ESP_LOG_ERROR, tag, format, ##__VA_ARGS__)
|
||||||
#else
|
|
||||||
#define NIMBLE_LOGE( tag, format, ... ) (void)tag
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define NIMBLE_LOGC( tag, format, ... ) MODLOG_DFLT(CRITICAL, "CRIT %s: "#format"\n",tag,##__VA_ARGS__)
|
#else // using Arduino
|
||||||
|
# include "nimble/porting/nimble/include/syscfg/syscfg.h"
|
||||||
|
# include "nimble/console/console.h"
|
||||||
|
# ifndef CONFIG_NIMBLE_CPP_LOG_LEVEL
|
||||||
|
# if defined(ARDUINO_ARCH_ESP32) && defined(CORE_DEBUG_LEVEL)
|
||||||
|
# define CONFIG_NIMBLE_CPP_LOG_LEVEL CORE_DEBUG_LEVEL
|
||||||
|
# else
|
||||||
|
# define CONFIG_NIMBLE_CPP_LOG_LEVEL 0
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
|
||||||
#else
|
# if CONFIG_NIMBLE_CPP_LOG_LEVEL >= 4
|
||||||
|
# define NIMBLE_LOGD( tag, format, ... ) console_printf("D %s: " format "\n", tag, ##__VA_ARGS__)
|
||||||
|
# else
|
||||||
|
# define NIMBLE_LOGD( tag, format, ... ) (void)tag
|
||||||
|
# endif
|
||||||
|
|
||||||
#include "esp_log.h"
|
# if CONFIG_NIMBLE_CPP_LOG_LEVEL >= 3
|
||||||
|
# define NIMBLE_LOGI( tag, format, ... ) console_printf("I %s: " format "\n", tag, ##__VA_ARGS__)
|
||||||
|
# else
|
||||||
|
# define NIMBLE_LOGI( tag, format, ... ) (void)tag
|
||||||
|
# endif
|
||||||
|
|
||||||
#define NIMBLE_LOGE(tag, format, ...) ESP_LOGE(tag, format, ##__VA_ARGS__)
|
# if CONFIG_NIMBLE_CPP_LOG_LEVEL >= 2
|
||||||
#define NIMBLE_LOGW(tag, format, ...) ESP_LOGW(tag, format, ##__VA_ARGS__)
|
# define NIMBLE_LOGW( tag, format, ... ) console_printf("W %s: " format "\n", tag, ##__VA_ARGS__)
|
||||||
#define NIMBLE_LOGI(tag, format, ...) ESP_LOGI(tag, format, ##__VA_ARGS__)
|
# else
|
||||||
#define NIMBLE_LOGD(tag, format, ...) ESP_LOGD(tag, format, ##__VA_ARGS__)
|
# define NIMBLE_LOGW( tag, format, ... ) (void)tag
|
||||||
#define NIMBLE_LOGC(tag, format, ...) ESP_LOGE(tag, format, ##__VA_ARGS__)
|
# endif
|
||||||
|
|
||||||
#endif /*ARDUINO_ARCH_ESP32*/
|
# if CONFIG_NIMBLE_CPP_LOG_LEVEL >= 1
|
||||||
|
# define NIMBLE_LOGE( tag, format, ... ) console_printf("E %s: " format "\n", tag, ##__VA_ARGS__)
|
||||||
|
# define NIMBLE_LOGC( tag, format, ... ) console_printf("CRIT %s: " format "\n", tag, ##__VA_ARGS__)
|
||||||
|
# else
|
||||||
|
# define NIMBLE_LOGE( tag, format, ... ) (void)tag
|
||||||
|
# define NIMBLE_LOGC( tag, format, ... ) (void)tag
|
||||||
|
# endif
|
||||||
|
|
||||||
#endif /*CONFIG_BT_ENABLED*/
|
#endif /* CONFIG_NIMBLE_CPP_IDF */
|
||||||
#endif /*MAIN_NIMBLELOG_H_*/
|
#endif /* CONFIG_BT_ENABLED */
|
||||||
|
#endif /* MAIN_NIMBLELOG_H_ */
|
||||||
|
|
|
@ -12,16 +12,15 @@
|
||||||
* Author: kolban
|
* Author: kolban
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "sdkconfig.h"
|
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
|
||||||
|
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||||
|
|
||||||
#include "NimBLERemoteCharacteristic.h"
|
#include "NimBLERemoteCharacteristic.h"
|
||||||
#include "NimBLEUtils.h"
|
#include "NimBLEUtils.h"
|
||||||
#include "NimBLELog.h"
|
#include "NimBLELog.h"
|
||||||
|
|
||||||
|
#include <climits>
|
||||||
|
|
||||||
static const char* LOG_TAG = "NimBLERemoteCharacteristic";
|
static const char* LOG_TAG = "NimBLERemoteCharacteristic";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,8 +58,6 @@ static const char* LOG_TAG = "NimBLERemoteCharacteristic";
|
||||||
m_charProp = chr->properties;
|
m_charProp = chr->properties;
|
||||||
m_pRemoteService = pRemoteService;
|
m_pRemoteService = pRemoteService;
|
||||||
m_notifyCallback = nullptr;
|
m_notifyCallback = nullptr;
|
||||||
m_timestamp = 0;
|
|
||||||
m_valMux = portMUX_INITIALIZER_UNLOCKED;
|
|
||||||
|
|
||||||
NIMBLE_LOGD(LOG_TAG, "<< NimBLERemoteCharacteristic(): %s", m_uuid.toString().c_str());
|
NIMBLE_LOGD(LOG_TAG, "<< NimBLERemoteCharacteristic(): %s", m_uuid.toString().c_str());
|
||||||
} // NimBLERemoteCharacteristic
|
} // NimBLERemoteCharacteristic
|
||||||
|
@ -319,7 +316,7 @@ NimBLERemoteDescriptor* NimBLERemoteCharacteristic::getDescriptor(const NimBLEUU
|
||||||
return m_descriptorVector.back();
|
return m_descriptorVector.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the request was successful but 16/32 bit descriptor not found
|
// If the request was successful but 16/32 bit uuid not found
|
||||||
// try again with the 128 bit uuid.
|
// try again with the 128 bit uuid.
|
||||||
if(uuid.bitSize() == BLE_UUID_TYPE_16 ||
|
if(uuid.bitSize() == BLE_UUID_TYPE_16 ||
|
||||||
uuid.bitSize() == BLE_UUID_TYPE_32)
|
uuid.bitSize() == BLE_UUID_TYPE_32)
|
||||||
|
@ -327,6 +324,15 @@ NimBLERemoteDescriptor* NimBLERemoteCharacteristic::getDescriptor(const NimBLEUU
|
||||||
NimBLEUUID uuid128(uuid);
|
NimBLEUUID uuid128(uuid);
|
||||||
uuid128.to128();
|
uuid128.to128();
|
||||||
return getDescriptor(uuid128);
|
return getDescriptor(uuid128);
|
||||||
|
} else {
|
||||||
|
// If the request was successful but the 128 bit uuid not found
|
||||||
|
// try again with the 16 bit uuid.
|
||||||
|
NimBLEUUID uuid16(uuid);
|
||||||
|
uuid16.to16();
|
||||||
|
// if the uuid was 128 bit but not of the BLE base type this check will fail
|
||||||
|
if (uuid16.bitSize() == BLE_UUID_TYPE_16) {
|
||||||
|
return getDescriptor(uuid16);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,15 +422,12 @@ NimBLEUUID NimBLERemoteCharacteristic::getUUID() {
|
||||||
* @param [in] timestamp A pointer to a time_t struct to store the time the value was read.
|
* @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) {
|
NimBLEAttValue NimBLERemoteCharacteristic::getValue(time_t *timestamp) {
|
||||||
portENTER_CRITICAL(&m_valMux);
|
|
||||||
std::string value = m_value;
|
|
||||||
if(timestamp != nullptr) {
|
if(timestamp != nullptr) {
|
||||||
*timestamp = m_timestamp;
|
*timestamp = m_value.getTimeStamp();
|
||||||
}
|
}
|
||||||
portEXIT_CRITICAL(&m_valMux);
|
|
||||||
|
|
||||||
return value;
|
return m_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -472,12 +475,12 @@ float NimBLERemoteCharacteristic::readFloat() {
|
||||||
* @param [in] timestamp A pointer to a time_t struct to store the time the value was read.
|
* @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) {
|
NimBLEAttValue NimBLERemoteCharacteristic::readValue(time_t *timestamp) {
|
||||||
NIMBLE_LOGD(LOG_TAG, ">> readValue(): uuid: %s, handle: %d 0x%.2x",
|
NIMBLE_LOGD(LOG_TAG, ">> readValue(): uuid: %s, handle: %d 0x%.2x",
|
||||||
getUUID().toString().c_str(), getHandle(), getHandle());
|
getUUID().toString().c_str(), getHandle(), getHandle());
|
||||||
|
|
||||||
NimBLEClient* pClient = getRemoteService()->getClient();
|
NimBLEClient* pClient = getRemoteService()->getClient();
|
||||||
std::string value;
|
NimBLEAttValue value;
|
||||||
|
|
||||||
if (!pClient->isConnected()) {
|
if (!pClient->isConnected()) {
|
||||||
NIMBLE_LOGE(LOG_TAG, "Disconnected");
|
NIMBLE_LOGE(LOG_TAG, "Disconnected");
|
||||||
|
@ -528,14 +531,11 @@ std::string NimBLERemoteCharacteristic::readValue(time_t *timestamp) {
|
||||||
}
|
}
|
||||||
} while(rc != 0 && retryCount--);
|
} while(rc != 0 && retryCount--);
|
||||||
|
|
||||||
time_t t = time(nullptr);
|
value.setTimeStamp();
|
||||||
portENTER_CRITICAL(&m_valMux);
|
|
||||||
m_value = value;
|
m_value = value;
|
||||||
m_timestamp = t;
|
|
||||||
if(timestamp != nullptr) {
|
if(timestamp != nullptr) {
|
||||||
*timestamp = m_timestamp;
|
*timestamp = value.getTimeStamp();
|
||||||
}
|
}
|
||||||
portEXIT_CRITICAL(&m_valMux);
|
|
||||||
|
|
||||||
NIMBLE_LOGD(LOG_TAG, "<< readValue length: %d rc=%d", value.length(), rc);
|
NIMBLE_LOGD(LOG_TAG, "<< readValue length: %d rc=%d", value.length(), rc);
|
||||||
return value;
|
return value;
|
||||||
|
@ -560,17 +560,17 @@ int NimBLERemoteCharacteristic::onReadCB(uint16_t conn_handle,
|
||||||
|
|
||||||
NIMBLE_LOGI(LOG_TAG, "Read complete; status=%d conn_handle=%d", error->status, conn_handle);
|
NIMBLE_LOGI(LOG_TAG, "Read complete; status=%d conn_handle=%d", error->status, conn_handle);
|
||||||
|
|
||||||
std::string *strBuf = (std::string*)pTaskData->buf;
|
NimBLEAttValue *valBuf = (NimBLEAttValue*)pTaskData->buf;
|
||||||
int rc = error->status;
|
int rc = error->status;
|
||||||
|
|
||||||
if(rc == 0) {
|
if(rc == 0) {
|
||||||
if(attr) {
|
if(attr) {
|
||||||
uint32_t data_len = OS_MBUF_PKTLEN(attr->om);
|
uint16_t data_len = OS_MBUF_PKTLEN(attr->om);
|
||||||
if(((*strBuf).length() + data_len) > BLE_ATT_ATTR_MAX_LEN) {
|
if((valBuf->size() + data_len) > BLE_ATT_ATTR_MAX_LEN) {
|
||||||
rc = BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
|
rc = BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
|
||||||
} else {
|
} else {
|
||||||
NIMBLE_LOGD(LOG_TAG, "Got %d bytes", data_len);
|
NIMBLE_LOGD(LOG_TAG, "Got %u bytes", data_len);
|
||||||
(*strBuf) += std::string((char*) attr->om->om_data, data_len);
|
valBuf->append(attr->om->om_data, data_len);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -721,22 +721,33 @@ std::string NimBLERemoteCharacteristic::toString() {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Write the new value for the characteristic.
|
* @brief Write a new value to the remote characteristic from a std::vector<uint8_t>.
|
||||||
* @param [in] newValue The new value to write.
|
* @param [in] vec A std::vector<uint8_t> value to write to the remote characteristic.
|
||||||
* @param [in] response Do we expect a response?
|
* @param [in] response Whether we require a response from the write.
|
||||||
* @return false if not connected or cant perform write for some reason.
|
* @return false if not connected or otherwise cannot perform write.
|
||||||
*/
|
*/
|
||||||
bool NimBLERemoteCharacteristic::writeValue(const std::string &newValue, bool response) {
|
bool NimBLERemoteCharacteristic::writeValue(const std::vector<uint8_t>& vec, bool response) {
|
||||||
return writeValue((uint8_t*)newValue.c_str(), newValue.length(), response);
|
return writeValue((uint8_t*)&vec[0], vec.size(), response);
|
||||||
} // writeValue
|
} // writeValue
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Write the new value for the characteristic from a data buffer.
|
* @brief Write a new value to the remote characteristic from a const char*.
|
||||||
|
* @param [in] char_s A character string to write to the remote characteristic.
|
||||||
|
* @param [in] response Whether we require a response from the write.
|
||||||
|
* @return false if not connected or otherwise cannot perform write.
|
||||||
|
*/
|
||||||
|
bool NimBLERemoteCharacteristic::writeValue(const char* char_s, bool response) {
|
||||||
|
return writeValue((uint8_t*)char_s, strlen(char_s), response);
|
||||||
|
} // writeValue
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Write a new value to the remote characteristic from a data buffer.
|
||||||
* @param [in] data A pointer to a data buffer.
|
* @param [in] data A pointer to a data buffer.
|
||||||
* @param [in] length The length of the data in the data buffer.
|
* @param [in] length The length of the data in the data buffer.
|
||||||
* @param [in] response Whether we require a response from the write.
|
* @param [in] response Whether we require a response from the write.
|
||||||
* @return false if not connected or cant perform write for some reason.
|
* @return false if not connected or otherwise cannot perform write.
|
||||||
*/
|
*/
|
||||||
bool NimBLERemoteCharacteristic::writeValue(const uint8_t* data, size_t length, bool response) {
|
bool NimBLERemoteCharacteristic::writeValue(const uint8_t* data, size_t length, bool response) {
|
||||||
|
|
||||||
|
@ -839,6 +850,4 @@ int NimBLERemoteCharacteristic::onWriteCB(uint16_t conn_handle,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL */
|
||||||
#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
|
||||||
#endif /* CONFIG_BT_ENABLED */
|
|
||||||
|
|
|
@ -14,17 +14,16 @@
|
||||||
|
|
||||||
#ifndef COMPONENTS_NIMBLEREMOTECHARACTERISTIC_H_
|
#ifndef COMPONENTS_NIMBLEREMOTECHARACTERISTIC_H_
|
||||||
#define COMPONENTS_NIMBLEREMOTECHARACTERISTIC_H_
|
#define COMPONENTS_NIMBLEREMOTECHARACTERISTIC_H_
|
||||||
#include "sdkconfig.h"
|
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
|
||||||
|
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||||
|
|
||||||
#include "NimBLERemoteService.h"
|
#include "NimBLERemoteService.h"
|
||||||
#include "NimBLERemoteDescriptor.h"
|
#include "NimBLERemoteDescriptor.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include "NimBLELog.h"
|
||||||
|
|
||||||
class NimBLERemoteService;
|
class NimBLERemoteService;
|
||||||
class NimBLERemoteDescriptor;
|
class NimBLERemoteDescriptor;
|
||||||
|
@ -62,47 +61,15 @@ public:
|
||||||
uint16_t getHandle();
|
uint16_t getHandle();
|
||||||
uint16_t getDefHandle();
|
uint16_t getDefHandle();
|
||||||
NimBLEUUID getUUID();
|
NimBLEUUID getUUID();
|
||||||
std::string readValue(time_t *timestamp = nullptr);
|
NimBLEAttValue readValue(time_t *timestamp = nullptr);
|
||||||
|
std::string toString();
|
||||||
/**
|
NimBLERemoteService* getRemoteService();
|
||||||
* @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>(×tamp, skipSizeCheck);</tt>
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
T readValue(time_t *timestamp = nullptr, bool skipSizeCheck = false) {
|
|
||||||
std::string value = readValue(timestamp);
|
|
||||||
if(!skipSizeCheck && value.size() < sizeof(T)) return T();
|
|
||||||
const char *pData = value.data();
|
|
||||||
return *((T *)pData);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t readUInt8() __attribute__ ((deprecated("Use template readValue<uint8_t>()")));
|
uint8_t readUInt8() __attribute__ ((deprecated("Use template readValue<uint8_t>()")));
|
||||||
uint16_t readUInt16() __attribute__ ((deprecated("Use template readValue<uint16_t>()")));
|
uint16_t readUInt16() __attribute__ ((deprecated("Use template readValue<uint16_t>()")));
|
||||||
uint32_t readUInt32() __attribute__ ((deprecated("Use template readValue<uint32_t>()")));
|
uint32_t readUInt32() __attribute__ ((deprecated("Use template readValue<uint32_t>()")));
|
||||||
float readFloat() __attribute__ ((deprecated("Use template readValue<float>()")));
|
float readFloat() __attribute__ ((deprecated("Use template readValue<float>()")));
|
||||||
std::string getValue(time_t *timestamp = nullptr);
|
NimBLEAttValue 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>(×tamp, skipSizeCheck);</tt>
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
T getValue(time_t *timestamp = nullptr, bool skipSizeCheck = false) {
|
|
||||||
std::string value = getValue(timestamp);
|
|
||||||
if(!skipSizeCheck && value.size() < sizeof(T)) return T();
|
|
||||||
const char *pData = value.data();
|
|
||||||
return *((T *)pData);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool subscribe(bool notifications = true,
|
bool subscribe(bool notifications = true,
|
||||||
notify_callback notifyCallback = nullptr,
|
notify_callback notifyCallback = nullptr,
|
||||||
|
@ -115,20 +82,74 @@ public:
|
||||||
bool writeValue(const uint8_t* data,
|
bool writeValue(const uint8_t* data,
|
||||||
size_t length,
|
size_t length,
|
||||||
bool response = false);
|
bool response = false);
|
||||||
bool writeValue(const std::string &newValue,
|
bool writeValue(const std::vector<uint8_t>& v, bool response = false);
|
||||||
bool response = false);
|
bool writeValue(const char* s, bool response = false);
|
||||||
|
|
||||||
|
|
||||||
|
/*********************** Template Functions ************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Convenience template to set the remote characteristic value to <type\>val.
|
* @brief Template to set the remote characteristic value to <type\>val.
|
||||||
* @param [in] s The value to write.
|
* @param [in] s The value to write.
|
||||||
* @param [in] response True == request write response.
|
* @param [in] response True == request write response.
|
||||||
|
* @details Only used for non-arrays and types without a `c_str()` method.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool writeValue(const T &s, bool response = false) {
|
#ifdef _DOXYGEN_
|
||||||
|
bool
|
||||||
|
#else
|
||||||
|
typename std::enable_if<!std::is_array<T>::value && !Has_c_str_len<T>::value, bool>::type
|
||||||
|
#endif
|
||||||
|
writeValue(const T& s, bool response = false) {
|
||||||
return writeValue((uint8_t*)&s, sizeof(T), response);
|
return writeValue((uint8_t*)&s, sizeof(T), response);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string toString();
|
/**
|
||||||
NimBLERemoteService* getRemoteService();
|
* @brief Template to set the remote characteristic value to <type\>val.
|
||||||
|
* @param [in] s The value to write.
|
||||||
|
* @param [in] response True == request write response.
|
||||||
|
* @details Only used if the <type\> has a `c_str()` method.
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
#ifdef _DOXYGEN_
|
||||||
|
bool
|
||||||
|
#else
|
||||||
|
typename std::enable_if<Has_c_str_len<T>::value, bool>::type
|
||||||
|
#endif
|
||||||
|
writeValue(const T& s, bool response = false) {
|
||||||
|
return writeValue((uint8_t*)s.c_str(), s.length(), response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 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>(×tamp, skipSizeCheck);</tt>
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
T getValue(time_t *timestamp = nullptr, bool skipSizeCheck = false) {
|
||||||
|
if(!skipSizeCheck && m_value.size() < sizeof(T)) return T();
|
||||||
|
return *((T *)m_value.getValue(timestamp));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 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>(×tamp, skipSizeCheck);</tt>
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
T readValue(time_t *timestamp = nullptr, bool skipSizeCheck = false) {
|
||||||
|
NimBLEAttValue value = readValue();
|
||||||
|
if(!skipSizeCheck && value.size() < sizeof(T)) return T();
|
||||||
|
return *((T *)value.getValue(timestamp));
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -158,15 +179,12 @@ private:
|
||||||
uint16_t m_defHandle;
|
uint16_t m_defHandle;
|
||||||
uint16_t m_endHandle;
|
uint16_t m_endHandle;
|
||||||
NimBLERemoteService* m_pRemoteService;
|
NimBLERemoteService* m_pRemoteService;
|
||||||
std::string m_value;
|
NimBLEAttValue m_value;
|
||||||
notify_callback m_notifyCallback;
|
notify_callback m_notifyCallback;
|
||||||
time_t m_timestamp;
|
|
||||||
portMUX_TYPE m_valMux;
|
|
||||||
|
|
||||||
// We maintain a vector of descriptors owned by this characteristic.
|
// We maintain a vector of descriptors owned by this characteristic.
|
||||||
std::vector<NimBLERemoteDescriptor*> m_descriptorVector;
|
std::vector<NimBLERemoteDescriptor*> m_descriptorVector;
|
||||||
}; // NimBLERemoteCharacteristic
|
}; // NimBLERemoteCharacteristic
|
||||||
|
|
||||||
#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL */
|
||||||
#endif /* CONFIG_BT_ENABLED */
|
|
||||||
#endif /* COMPONENTS_NIMBLEREMOTECHARACTERISTIC_H_ */
|
#endif /* COMPONENTS_NIMBLEREMOTECHARACTERISTIC_H_ */
|
||||||
|
|
|
@ -11,16 +11,16 @@
|
||||||
* Created on: Jul 8, 2017
|
* Created on: Jul 8, 2017
|
||||||
* Author: kolban
|
* Author: kolban
|
||||||
*/
|
*/
|
||||||
#include "sdkconfig.h"
|
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
|
||||||
|
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||||
|
|
||||||
#include "NimBLERemoteDescriptor.h"
|
#include "NimBLERemoteDescriptor.h"
|
||||||
#include "NimBLEUtils.h"
|
#include "NimBLEUtils.h"
|
||||||
#include "NimBLELog.h"
|
#include "NimBLELog.h"
|
||||||
|
|
||||||
|
#include <climits>
|
||||||
|
|
||||||
static const char* LOG_TAG = "NimBLERemoteDescriptor";
|
static const char* LOG_TAG = "NimBLERemoteDescriptor";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -86,11 +86,7 @@ NimBLEUUID NimBLERemoteDescriptor::getUUID() {
|
||||||
* @deprecated Use readValue<uint8_t>().
|
* @deprecated Use readValue<uint8_t>().
|
||||||
*/
|
*/
|
||||||
uint8_t NimBLERemoteDescriptor::readUInt8() {
|
uint8_t NimBLERemoteDescriptor::readUInt8() {
|
||||||
std::string value = readValue();
|
return readValue<uint8_t>();
|
||||||
if (value.length() >= 1) {
|
|
||||||
return (uint8_t) value[0];
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
} // readUInt8
|
} // readUInt8
|
||||||
|
|
||||||
|
|
||||||
|
@ -100,11 +96,7 @@ uint8_t NimBLERemoteDescriptor::readUInt8() {
|
||||||
* @deprecated Use readValue<uint16_t>().
|
* @deprecated Use readValue<uint16_t>().
|
||||||
*/
|
*/
|
||||||
uint16_t NimBLERemoteDescriptor::readUInt16() {
|
uint16_t NimBLERemoteDescriptor::readUInt16() {
|
||||||
std::string value = readValue();
|
return readValue<uint16_t>();
|
||||||
if (value.length() >= 2) {
|
|
||||||
return *(uint16_t*) value.data();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
} // readUInt16
|
} // readUInt16
|
||||||
|
|
||||||
|
|
||||||
|
@ -114,11 +106,7 @@ uint16_t NimBLERemoteDescriptor::readUInt16() {
|
||||||
* @deprecated Use readValue<uint32_t>().
|
* @deprecated Use readValue<uint32_t>().
|
||||||
*/
|
*/
|
||||||
uint32_t NimBLERemoteDescriptor::readUInt32() {
|
uint32_t NimBLERemoteDescriptor::readUInt32() {
|
||||||
std::string value = readValue();
|
return readValue<uint32_t>();
|
||||||
if (value.length() >= 4) {
|
|
||||||
return *(uint32_t*) value.data();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
} // readUInt32
|
} // readUInt32
|
||||||
|
|
||||||
|
|
||||||
|
@ -126,11 +114,11 @@ uint32_t NimBLERemoteDescriptor::readUInt32() {
|
||||||
* @brief Read the value of the remote descriptor.
|
* @brief Read the value of the remote descriptor.
|
||||||
* @return The value of the remote descriptor.
|
* @return The value of the remote descriptor.
|
||||||
*/
|
*/
|
||||||
std::string NimBLERemoteDescriptor::readValue() {
|
NimBLEAttValue NimBLERemoteDescriptor::readValue() {
|
||||||
NIMBLE_LOGD(LOG_TAG, ">> Descriptor readValue: %s", toString().c_str());
|
NIMBLE_LOGD(LOG_TAG, ">> Descriptor readValue: %s", toString().c_str());
|
||||||
|
|
||||||
NimBLEClient* pClient = getRemoteCharacteristic()->getRemoteService()->getClient();
|
NimBLEClient* pClient = getRemoteCharacteristic()->getRemoteService()->getClient();
|
||||||
std::string value;
|
NimBLEAttValue value;
|
||||||
|
|
||||||
if (!pClient->isConnected()) {
|
if (!pClient->isConnected()) {
|
||||||
NIMBLE_LOGE(LOG_TAG, "Disconnected");
|
NIMBLE_LOGE(LOG_TAG, "Disconnected");
|
||||||
|
@ -180,7 +168,7 @@ std::string NimBLERemoteDescriptor::readValue() {
|
||||||
}
|
}
|
||||||
} while(rc != 0 && retryCount--);
|
} while(rc != 0 && retryCount--);
|
||||||
|
|
||||||
NIMBLE_LOGD(LOG_TAG, "<< Descriptor readValue(): length: %d rc=%d", value.length(), rc);
|
NIMBLE_LOGD(LOG_TAG, "<< Descriptor readValue(): length: %u rc=%d", value.length(), rc);
|
||||||
return value;
|
return value;
|
||||||
} // readValue
|
} // readValue
|
||||||
|
|
||||||
|
@ -193,6 +181,7 @@ int NimBLERemoteDescriptor::onReadCB(uint16_t conn_handle,
|
||||||
const struct ble_gatt_error *error,
|
const struct ble_gatt_error *error,
|
||||||
struct ble_gatt_attr *attr, void *arg)
|
struct ble_gatt_attr *attr, void *arg)
|
||||||
{
|
{
|
||||||
|
(void)attr;
|
||||||
ble_task_data_t *pTaskData = (ble_task_data_t*)arg;
|
ble_task_data_t *pTaskData = (ble_task_data_t*)arg;
|
||||||
NimBLERemoteDescriptor* desc = (NimBLERemoteDescriptor*)pTaskData->pATT;
|
NimBLERemoteDescriptor* desc = (NimBLERemoteDescriptor*)pTaskData->pATT;
|
||||||
uint16_t conn_id = desc->getRemoteCharacteristic()->getRemoteService()->getClient()->getConnId();
|
uint16_t conn_id = desc->getRemoteCharacteristic()->getRemoteService()->getClient()->getConnId();
|
||||||
|
@ -203,17 +192,17 @@ int NimBLERemoteDescriptor::onReadCB(uint16_t conn_handle,
|
||||||
|
|
||||||
NIMBLE_LOGD(LOG_TAG, "Read complete; status=%d conn_handle=%d", error->status, conn_handle);
|
NIMBLE_LOGD(LOG_TAG, "Read complete; status=%d conn_handle=%d", error->status, conn_handle);
|
||||||
|
|
||||||
std::string *strBuf = (std::string*)pTaskData->buf;
|
NimBLEAttValue *valBuf = (NimBLEAttValue*)pTaskData->buf;
|
||||||
int rc = error->status;
|
int rc = error->status;
|
||||||
|
|
||||||
if(rc == 0) {
|
if(rc == 0) {
|
||||||
if(attr) {
|
if(attr) {
|
||||||
uint32_t data_len = OS_MBUF_PKTLEN(attr->om);
|
uint16_t data_len = OS_MBUF_PKTLEN(attr->om);
|
||||||
if(((*strBuf).length() + data_len) > BLE_ATT_ATTR_MAX_LEN) {
|
if((valBuf->size() + data_len) > BLE_ATT_ATTR_MAX_LEN) {
|
||||||
rc = BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
|
rc = BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
|
||||||
} else {
|
} else {
|
||||||
NIMBLE_LOGD(LOG_TAG, "Got %d bytes", data_len);
|
NIMBLE_LOGD(LOG_TAG, "Got %u bytes", data_len);
|
||||||
(*strBuf) += std::string((char*) attr->om->om_data, data_len);
|
valBuf->append(attr->om->om_data, data_len);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -266,11 +255,33 @@ int NimBLERemoteDescriptor::onWriteCB(uint16_t conn_handle,
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Write data to the BLE Remote Descriptor.
|
* @brief Write a new value to a remote descriptor from a std::vector<uint8_t>.
|
||||||
|
* @param [in] vec A std::vector<uint8_t> value to write to the remote descriptor.
|
||||||
|
* @param [in] response Whether we require a response from the write.
|
||||||
|
* @return false if not connected or otherwise cannot perform write.
|
||||||
|
*/
|
||||||
|
bool NimBLERemoteDescriptor::writeValue(const std::vector<uint8_t>& vec, bool response) {
|
||||||
|
return writeValue((uint8_t*)&vec[0], vec.size(), response);
|
||||||
|
} // writeValue
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Write a new value to the remote descriptor from a const char*.
|
||||||
|
* @param [in] char_s A character string to write to the remote descriptor.
|
||||||
|
* @param [in] response Whether we require a response from the write.
|
||||||
|
* @return false if not connected or otherwise cannot perform write.
|
||||||
|
*/
|
||||||
|
bool NimBLERemoteDescriptor::writeValue(const char* char_s, bool response) {
|
||||||
|
return writeValue((uint8_t*)char_s, strlen(char_s), response);
|
||||||
|
} // writeValue
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Write a new value to a 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 write response.
|
* @param [in] response True if we expect a write response.
|
||||||
* @return True if successful
|
* @return false if not connected or otherwise cannot perform write.
|
||||||
*/
|
*/
|
||||||
bool NimBLERemoteDescriptor::writeValue(const uint8_t* data, size_t length, bool response) {
|
bool NimBLERemoteDescriptor::writeValue(const uint8_t* data, size_t length, bool response) {
|
||||||
|
|
||||||
|
@ -351,15 +362,4 @@ bool NimBLERemoteDescriptor::writeValue(const uint8_t* data, size_t length, bool
|
||||||
} // writeValue
|
} // writeValue
|
||||||
|
|
||||||
|
|
||||||
/**
|
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL */
|
||||||
* @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] response True if we expect a response.
|
|
||||||
* @return True if successful
|
|
||||||
*/
|
|
||||||
bool NimBLERemoteDescriptor::writeValue(const std::string &newValue, bool response) {
|
|
||||||
return writeValue((uint8_t*) newValue.data(), newValue.length(), response);
|
|
||||||
} // writeValue
|
|
||||||
|
|
||||||
#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
|
||||||
#endif /* CONFIG_BT_ENABLED */
|
|
||||||
|
|
|
@ -14,11 +14,9 @@
|
||||||
|
|
||||||
#ifndef COMPONENTS_NIMBLEREMOTEDESCRIPTOR_H_
|
#ifndef COMPONENTS_NIMBLEREMOTEDESCRIPTOR_H_
|
||||||
#define COMPONENTS_NIMBLEREMOTEDESCRIPTOR_H_
|
#define COMPONENTS_NIMBLEREMOTEDESCRIPTOR_H_
|
||||||
#include "sdkconfig.h"
|
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
|
||||||
|
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||||
|
|
||||||
#include "NimBLERemoteCharacteristic.h"
|
#include "NimBLERemoteCharacteristic.h"
|
||||||
|
|
||||||
|
@ -31,10 +29,53 @@ public:
|
||||||
uint16_t getHandle();
|
uint16_t getHandle();
|
||||||
NimBLERemoteCharacteristic* getRemoteCharacteristic();
|
NimBLERemoteCharacteristic* getRemoteCharacteristic();
|
||||||
NimBLEUUID getUUID();
|
NimBLEUUID getUUID();
|
||||||
std::string readValue();
|
NimBLEAttValue readValue();
|
||||||
|
|
||||||
|
uint8_t readUInt8() __attribute__ ((deprecated("Use template readValue<uint8_t>()")));
|
||||||
|
uint16_t readUInt16() __attribute__ ((deprecated("Use template readValue<uint16_t>()")));
|
||||||
|
uint32_t readUInt32() __attribute__ ((deprecated("Use template readValue<uint32_t>()")));
|
||||||
|
std::string toString(void);
|
||||||
|
bool writeValue(const uint8_t* data, size_t length, bool response = false);
|
||||||
|
bool writeValue(const std::vector<uint8_t>& v, bool response = false);
|
||||||
|
bool writeValue(const char* s, bool response = false);
|
||||||
|
|
||||||
|
|
||||||
|
/*********************** Template Functions ************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A template to convert the remote descriptor data to <type\>.
|
* @brief Template to set the remote descriptor value to <type\>val.
|
||||||
|
* @param [in] s The value to write.
|
||||||
|
* @param [in] response True == request write response.
|
||||||
|
* @details Only used for non-arrays and types without a `c_str()` method.
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
#ifdef _DOXYGEN_
|
||||||
|
bool
|
||||||
|
#else
|
||||||
|
typename std::enable_if<!std::is_array<T>::value && !Has_c_str_len<T>::value, bool>::type
|
||||||
|
#endif
|
||||||
|
writeValue(const T& s, bool response = false) {
|
||||||
|
return writeValue((uint8_t*)&s, sizeof(T), response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Template to set the remote descriptor value to <type\>val.
|
||||||
|
* @param [in] s The value to write.
|
||||||
|
* @param [in] response True == request write response.
|
||||||
|
* @details Only used if the <type\> has a `c_str()` method.
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
#ifdef _DOXYGEN_
|
||||||
|
bool
|
||||||
|
#else
|
||||||
|
typename std::enable_if<Has_c_str_len<T>::value, bool>::type
|
||||||
|
#endif
|
||||||
|
writeValue(const T& s, bool response = false) {
|
||||||
|
return writeValue((uint8_t*)s.c_str(), s.length(), response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Template to convert the remote descriptor data to <type\>.
|
||||||
* @tparam T The type to convert the data to.
|
* @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>.
|
* @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
|
* @return The data converted to <type\> or NULL if skipSizeCheck is false and the data is
|
||||||
|
@ -42,28 +83,10 @@ public:
|
||||||
* @details <b>Use:</b> <tt>readValue<type>(skipSizeCheck);</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();
|
NimBLEAttValue value = readValue();
|
||||||
if(!skipSizeCheck && value.size() < sizeof(T)) return T();
|
if(!skipSizeCheck && value.size() < sizeof(T)) return T();
|
||||||
const char *pData = value.data();
|
return *((T *)value.data());
|
||||||
return *((T *)pData);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t readUInt8() __attribute__ ((deprecated("Use template readValue<uint8_t>()")));
|
|
||||||
uint16_t readUInt16() __attribute__ ((deprecated("Use template readValue<uint16_t>()")));
|
|
||||||
uint32_t readUInt32() __attribute__ ((deprecated("Use template readValue<uint32_t>()")));
|
|
||||||
std::string toString(void);
|
|
||||||
bool writeValue(const uint8_t* data, size_t length, 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>
|
|
||||||
bool writeValue(const T &s, bool response = false) {
|
|
||||||
return writeValue((uint8_t*)&s, sizeof(T), response);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -81,6 +104,5 @@ private:
|
||||||
NimBLERemoteCharacteristic* m_pRemoteCharacteristic;
|
NimBLERemoteCharacteristic* m_pRemoteCharacteristic;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL */
|
||||||
#endif /* CONFIG_BT_ENABLED */
|
|
||||||
#endif /* COMPONENTS_NIMBLEREMOTEDESCRIPTOR_H_ */
|
#endif /* COMPONENTS_NIMBLEREMOTEDESCRIPTOR_H_ */
|
||||||
|
|
|
@ -11,17 +11,17 @@
|
||||||
* Created on: Jul 8, 2017
|
* Created on: Jul 8, 2017
|
||||||
* Author: kolban
|
* Author: kolban
|
||||||
*/
|
*/
|
||||||
#include "sdkconfig.h"
|
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
|
||||||
|
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||||
|
|
||||||
#include "NimBLERemoteService.h"
|
#include "NimBLERemoteService.h"
|
||||||
#include "NimBLEUtils.h"
|
#include "NimBLEUtils.h"
|
||||||
#include "NimBLEDevice.h"
|
#include "NimBLEDevice.h"
|
||||||
#include "NimBLELog.h"
|
#include "NimBLELog.h"
|
||||||
|
|
||||||
|
#include <climits>
|
||||||
|
|
||||||
static const char* LOG_TAG = "NimBLERemoteService";
|
static const char* LOG_TAG = "NimBLERemoteService";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -109,7 +109,7 @@ NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const NimBLEU
|
||||||
return m_characteristicVector.back();
|
return m_characteristicVector.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the request was successful but 16/32 bit characteristic not found
|
// If the request was successful but 16/32 bit uuid not found
|
||||||
// try again with the 128 bit uuid.
|
// try again with the 128 bit uuid.
|
||||||
if(uuid.bitSize() == BLE_UUID_TYPE_16 ||
|
if(uuid.bitSize() == BLE_UUID_TYPE_16 ||
|
||||||
uuid.bitSize() == BLE_UUID_TYPE_32)
|
uuid.bitSize() == BLE_UUID_TYPE_32)
|
||||||
|
@ -117,6 +117,15 @@ NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const NimBLEU
|
||||||
NimBLEUUID uuid128(uuid);
|
NimBLEUUID uuid128(uuid);
|
||||||
uuid128.to128();
|
uuid128.to128();
|
||||||
return getCharacteristic(uuid128);
|
return getCharacteristic(uuid128);
|
||||||
|
} else {
|
||||||
|
// If the request was successful but the 128 bit uuid not found
|
||||||
|
// try again with the 16 bit uuid.
|
||||||
|
NimBLEUUID uuid16(uuid);
|
||||||
|
uuid16.to16();
|
||||||
|
// if the uuid was 128 bit but not of the BLE base type this check will fail
|
||||||
|
if (uuid16.bitSize() == BLE_UUID_TYPE_16) {
|
||||||
|
return getCharacteristic(uuid16);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,6 +400,4 @@ std::string NimBLERemoteService::toString() {
|
||||||
return res;
|
return res;
|
||||||
} // toString
|
} // toString
|
||||||
|
|
||||||
|
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL */
|
||||||
#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
|
||||||
#endif /* CONFIG_BT_ENABLED */
|
|
||||||
|
|
|
@ -14,11 +14,9 @@
|
||||||
|
|
||||||
#ifndef COMPONENTS_NIMBLEREMOTESERVICE_H_
|
#ifndef COMPONENTS_NIMBLEREMOTESERVICE_H_
|
||||||
#define COMPONENTS_NIMBLEREMOTESERVICE_H_
|
#define COMPONENTS_NIMBLEREMOTESERVICE_H_
|
||||||
#include "sdkconfig.h"
|
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
|
||||||
|
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||||
|
|
||||||
#include "NimBLEClient.h"
|
#include "NimBLEClient.h"
|
||||||
#include "NimBLEUUID.h"
|
#include "NimBLEUUID.h"
|
||||||
|
@ -83,6 +81,5 @@ private:
|
||||||
uint16_t m_endHandle;
|
uint16_t m_endHandle;
|
||||||
}; // NimBLERemoteService
|
}; // NimBLERemoteService
|
||||||
|
|
||||||
#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL */
|
||||||
#endif /* CONFIG_BT_ENABLED */
|
|
||||||
#endif /* COMPONENTS_NIMBLEREMOTESERVICE_H_ */
|
#endif /* COMPONENTS_NIMBLEREMOTESERVICE_H_ */
|
||||||
|
|
|
@ -11,17 +11,16 @@
|
||||||
* Created on: Jul 1, 2017
|
* Created on: Jul 1, 2017
|
||||||
* Author: kolban
|
* Author: kolban
|
||||||
*/
|
*/
|
||||||
#include "sdkconfig.h"
|
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
|
||||||
|
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
||||||
|
|
||||||
#include "NimBLEScan.h"
|
#include "NimBLEScan.h"
|
||||||
#include "NimBLEDevice.h"
|
#include "NimBLEDevice.h"
|
||||||
#include "NimBLELog.h"
|
#include "NimBLELog.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <climits>
|
||||||
|
|
||||||
static const char* LOG_TAG = "NimBLEScan";
|
static const char* LOG_TAG = "NimBLEScan";
|
||||||
|
|
||||||
|
@ -284,7 +283,7 @@ bool NimBLEScan::isScanning() {
|
||||||
* @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) {
|
||||||
NIMBLE_LOGD(LOG_TAG, ">> start(duration=%d)", duration);
|
NIMBLE_LOGD(LOG_TAG, ">> start: duration=%" PRIu32, duration);
|
||||||
|
|
||||||
// Save the callback to be invoked when the scan completes.
|
// Save the callback to be invoked when the scan completes.
|
||||||
m_scanCompleteCB = scanCompleteCB;
|
m_scanCompleteCB = scanCompleteCB;
|
||||||
|
@ -539,5 +538,4 @@ NimBLEAdvertisedDevice *NimBLEScanResults::getDevice(const NimBLEAddress &addres
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_OBSERVER */
|
||||||
#endif /* CONFIG_BT_ENABLED */
|
|
||||||
|
|
|
@ -13,16 +13,18 @@
|
||||||
*/
|
*/
|
||||||
#ifndef COMPONENTS_NIMBLE_SCAN_H_
|
#ifndef COMPONENTS_NIMBLE_SCAN_H_
|
||||||
#define COMPONENTS_NIMBLE_SCAN_H_
|
#define COMPONENTS_NIMBLE_SCAN_H_
|
||||||
#include "sdkconfig.h"
|
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
|
||||||
|
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
||||||
|
|
||||||
#include "NimBLEAdvertisedDevice.h"
|
#include "NimBLEAdvertisedDevice.h"
|
||||||
#include "NimBLEUtils.h"
|
#include "NimBLEUtils.h"
|
||||||
|
|
||||||
|
#if defined(CONFIG_NIMBLE_CPP_IDF)
|
||||||
#include "host/ble_gap.h"
|
#include "host/ble_gap.h"
|
||||||
|
#else
|
||||||
|
#include "nimble/nimble/host/include/host/ble_gap.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -97,6 +99,5 @@ private:
|
||||||
uint8_t m_maxResults;
|
uint8_t m_maxResults;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
#endif /* CONFIG_BT_ENABLED CONFIG_BT_NIMBLE_ROLE_OBSERVER */
|
||||||
#endif /* CONFIG_BT_ENABLED */
|
|
||||||
#endif /* COMPONENTS_NIMBLE_SCAN_H_ */
|
#endif /* COMPONENTS_NIMBLE_SCAN_H_ */
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
* Author: chegewara
|
* Author: chegewara
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "sdkconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
#if defined(CONFIG_BT_ENABLED)
|
||||||
|
|
||||||
#include "NimBLESecurity.h"
|
#include "NimBLESecurity.h"
|
||||||
|
|
|
@ -14,10 +14,16 @@
|
||||||
|
|
||||||
#ifndef COMPONENTS_NIMBLESECURITY_H_
|
#ifndef COMPONENTS_NIMBLESECURITY_H_
|
||||||
#define COMPONENTS_NIMBLESECURITY_H_
|
#define COMPONENTS_NIMBLESECURITY_H_
|
||||||
#include "sdkconfig.h"
|
|
||||||
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
#if defined(CONFIG_BT_ENABLED)
|
||||||
|
|
||||||
|
#if defined(CONFIG_NIMBLE_CPP_IDF)
|
||||||
#include "host/ble_gap.h"
|
#include "host/ble_gap.h"
|
||||||
|
#else
|
||||||
|
#include "nimble/nimble/host/include/host/ble_gap.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/**** FIX COMPILATION ****/
|
/**** FIX COMPILATION ****/
|
||||||
#undef min
|
#undef min
|
||||||
#undef max
|
#undef max
|
||||||
|
|
|
@ -12,19 +12,20 @@
|
||||||
* Author: kolban
|
* Author: kolban
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "sdkconfig.h"
|
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
|
||||||
|
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||||
|
|
||||||
#include "NimBLEServer.h"
|
#include "NimBLEServer.h"
|
||||||
#include "NimBLEDevice.h"
|
#include "NimBLEDevice.h"
|
||||||
#include "NimBLELog.h"
|
#include "NimBLELog.h"
|
||||||
|
|
||||||
|
#if defined(CONFIG_NIMBLE_CPP_IDF)
|
||||||
#include "services/gap/ble_svc_gap.h"
|
#include "services/gap/ble_svc_gap.h"
|
||||||
#include "services/gatt/ble_svc_gatt.h"
|
#include "services/gatt/ble_svc_gatt.h"
|
||||||
|
#else
|
||||||
|
#include "nimble/nimble/host/services/gap/include/services/gap/ble_svc_gap.h"
|
||||||
|
#include "nimble/nimble/host/services/gatt/include/services/gatt/ble_svc_gatt.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
static const char* LOG_TAG = "NimBLEServer";
|
static const char* LOG_TAG = "NimBLEServer";
|
||||||
static NimBLEServerCallbacks defaultCallbacks;
|
static NimBLEServerCallbacks defaultCallbacks;
|
||||||
|
@ -74,23 +75,19 @@ NimBLEService* NimBLEServer::createService(const char* uuid) {
|
||||||
/**
|
/**
|
||||||
* @brief Create a %BLE Service.
|
* @brief Create a %BLE Service.
|
||||||
* @param [in] uuid The UUID of the new service.
|
* @param [in] uuid The UUID of the new service.
|
||||||
* @param [in] numHandles The maximum number of handles associated with this service.
|
|
||||||
* @param [in] inst_id if we have multiple services with the same UUID we need
|
|
||||||
* to provide inst_id value different for each service.
|
|
||||||
* @return A reference to the new service object.
|
* @return A reference to the new service object.
|
||||||
*/
|
*/
|
||||||
NimBLEService* NimBLEServer::createService(const NimBLEUUID &uuid, uint32_t numHandles, uint8_t inst_id) {
|
NimBLEService* NimBLEServer::createService(const NimBLEUUID &uuid) {
|
||||||
NIMBLE_LOGD(LOG_TAG, ">> createService - %s", uuid.toString().c_str());
|
NIMBLE_LOGD(LOG_TAG, ">> createService - %s", uuid.toString().c_str());
|
||||||
// TODO: add functionality to use inst_id for multiple services with same uuid
|
|
||||||
(void)inst_id;
|
|
||||||
// Check that a service with the supplied UUID does not already exist.
|
// Check that a service with the supplied UUID does not already exist.
|
||||||
if(getServiceByUUID(uuid) != nullptr) {
|
if(getServiceByUUID(uuid) != nullptr) {
|
||||||
NIMBLE_LOGW(LOG_TAG, "Warning creating a duplicate service UUID: %s",
|
NIMBLE_LOGW(LOG_TAG, "Warning creating a duplicate service UUID: %s",
|
||||||
std::string(uuid).c_str());
|
std::string(uuid).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
NimBLEService* pService = new NimBLEService(uuid, numHandles, this);
|
NimBLEService* pService = new NimBLEService(uuid);
|
||||||
m_svcVec.push_back(pService); // Save a reference to this service being on this server.
|
m_svcVec.push_back(pService);
|
||||||
serviceChanged();
|
serviceChanged();
|
||||||
|
|
||||||
NIMBLE_LOGD(LOG_TAG, "<< createService");
|
NIMBLE_LOGD(LOG_TAG, "<< createService");
|
||||||
|
@ -181,7 +178,7 @@ void NimBLEServer::start() {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_NIMBLE_CPP_DEBUG_LEVEL >= 4
|
#if CONFIG_NIMBLE_CPP_LOG_LEVEL >= 4
|
||||||
ble_gatts_show_local();
|
ble_gatts_show_local();
|
||||||
#endif
|
#endif
|
||||||
/*** Future use ***
|
/*** Future use ***
|
||||||
|
@ -537,7 +534,7 @@ NimBLEConnInfo NimBLEServer::getPeerIDInfo(uint16_t id) {
|
||||||
NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_DISP; ble_sm_inject_io result: %d", rc);
|
NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_DISP; ble_sm_inject_io result: %d", rc);
|
||||||
|
|
||||||
} else if (event->passkey.params.action == BLE_SM_IOACT_NUMCMP) {
|
} else if (event->passkey.params.action == BLE_SM_IOACT_NUMCMP) {
|
||||||
NIMBLE_LOGD(LOG_TAG, "Passkey on device's display: %d", event->passkey.params.numcmp);
|
NIMBLE_LOGD(LOG_TAG, "Passkey on device's display: %" PRIu32, event->passkey.params.numcmp);
|
||||||
pkey.action = event->passkey.params.action;
|
pkey.action = event->passkey.params.action;
|
||||||
// Compatibility only - Do not use, should be removed the in future
|
// Compatibility only - Do not use, should be removed the in future
|
||||||
if(NimBLEDevice::m_securityCallbacks != nullptr) {
|
if(NimBLEDevice::m_securityCallbacks != nullptr) {
|
||||||
|
@ -734,7 +731,7 @@ void NimBLEServer::startAdvertising() {
|
||||||
*/
|
*/
|
||||||
void NimBLEServer::stopAdvertising() {
|
void NimBLEServer::stopAdvertising() {
|
||||||
NimBLEDevice::stopAdvertising();
|
NimBLEDevice::stopAdvertising();
|
||||||
} // startAdvertising
|
} // stopAdvertising
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -772,7 +769,31 @@ void NimBLEServer::updateConnParams(uint16_t conn_handle,
|
||||||
if(rc != 0) {
|
if(rc != 0) {
|
||||||
NIMBLE_LOGE(LOG_TAG, "Update params error: %d, %s", rc, NimBLEUtils::returnCodeToString(rc));
|
NIMBLE_LOGE(LOG_TAG, "Update params error: %d, %s", rc, NimBLEUtils::returnCodeToString(rc));
|
||||||
}
|
}
|
||||||
}// updateConnParams
|
} // updateConnParams
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Request an update of the data packet length.
|
||||||
|
* * Can only be used after a connection has been established.
|
||||||
|
* @details Sends a data length update request to the peer.
|
||||||
|
* The Data Length Extension (DLE) allows to increase the Data Channel Payload from 27 bytes to up to 251 bytes.
|
||||||
|
* The peer needs to support the Bluetooth 4.2 specifications, to be capable of DLE.
|
||||||
|
* @param [in] conn_handle The connection handle of the peer to send the request to.
|
||||||
|
* @param [in] tx_octets The preferred number of payload octets to use (Range 0x001B-0x00FB).
|
||||||
|
*/
|
||||||
|
void NimBLEServer::setDataLen(uint16_t conn_handle, uint16_t tx_octets) {
|
||||||
|
#if defined(CONFIG_NIMBLE_CPP_IDF) && defined(ESP_IDF_VERSION) && \
|
||||||
|
ESP_IDF_VERSION_MAJOR >= 4 && ESP_IDF_VERSION_MINOR >= 3 && ESP_IDF_VERSION_PATCH >= 2
|
||||||
|
return;
|
||||||
|
#else
|
||||||
|
uint16_t tx_time = (tx_octets + 14) * 8;
|
||||||
|
|
||||||
|
int rc = ble_gap_set_data_len(conn_handle, tx_octets, tx_time);
|
||||||
|
if(rc != 0) {
|
||||||
|
NIMBLE_LOGE(LOG_TAG, "Set data length error: %d, %s", rc, NimBLEUtils::returnCodeToString(rc));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} // setDataLen
|
||||||
|
|
||||||
|
|
||||||
bool NimBLEServer::setIndicateWait(uint16_t conn_handle) {
|
bool NimBLEServer::setIndicateWait(uint16_t conn_handle) {
|
||||||
|
@ -842,6 +863,4 @@ bool NimBLEServerCallbacks::onConfirmPIN(uint32_t pin){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL */
|
||||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
|
||||||
#endif // CONFIG_BT_ENABLED
|
|
||||||
|
|
|
@ -14,15 +14,15 @@
|
||||||
|
|
||||||
#ifndef MAIN_NIMBLESERVER_H_
|
#ifndef MAIN_NIMBLESERVER_H_
|
||||||
#define MAIN_NIMBLESERVER_H_
|
#define MAIN_NIMBLESERVER_H_
|
||||||
#include "sdkconfig.h"
|
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
|
||||||
|
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||||
|
|
||||||
#define NIMBLE_ATT_REMOVE_HIDE 1
|
#define NIMBLE_ATT_REMOVE_HIDE 1
|
||||||
#define NIMBLE_ATT_REMOVE_DELETE 2
|
#define NIMBLE_ATT_REMOVE_DELETE 2
|
||||||
|
|
||||||
|
#define onMtuChanged onMTUChange
|
||||||
|
|
||||||
#include "NimBLEUtils.h"
|
#include "NimBLEUtils.h"
|
||||||
#include "NimBLEAddress.h"
|
#include "NimBLEAddress.h"
|
||||||
#include "NimBLEAdvertising.h"
|
#include "NimBLEAdvertising.h"
|
||||||
|
@ -43,8 +43,7 @@ class NimBLEServer {
|
||||||
public:
|
public:
|
||||||
size_t getConnectedCount();
|
size_t getConnectedCount();
|
||||||
NimBLEService* createService(const char* uuid);
|
NimBLEService* createService(const char* uuid);
|
||||||
NimBLEService* createService(const NimBLEUUID &uuid, uint32_t numHandles=15,
|
NimBLEService* createService(const NimBLEUUID &uuid);
|
||||||
uint8_t inst_id=0);
|
|
||||||
void removeService(NimBLEService* service, bool deleteSvc = false);
|
void removeService(NimBLEService* service, bool deleteSvc = false);
|
||||||
void addService(NimBLEService* service);
|
void addService(NimBLEService* service);
|
||||||
NimBLEAdvertising* getAdvertising();
|
NimBLEAdvertising* getAdvertising();
|
||||||
|
@ -61,6 +60,7 @@ public:
|
||||||
void updateConnParams(uint16_t conn_handle,
|
void updateConnParams(uint16_t conn_handle,
|
||||||
uint16_t minInterval, uint16_t maxInterval,
|
uint16_t minInterval, uint16_t maxInterval,
|
||||||
uint16_t latency, uint16_t timeout);
|
uint16_t latency, uint16_t timeout);
|
||||||
|
void setDataLen(uint16_t conn_handle, uint16_t tx_octets);
|
||||||
uint16_t getPeerMTU(uint16_t conn_id);
|
uint16_t getPeerMTU(uint16_t conn_id);
|
||||||
std::vector<uint16_t> getPeerDevices();
|
std::vector<uint16_t> getPeerDevices();
|
||||||
NimBLEConnInfo getPeerInfo(size_t index);
|
NimBLEConnInfo getPeerInfo(size_t index);
|
||||||
|
@ -168,7 +168,5 @@ public:
|
||||||
virtual bool onConfirmPIN(uint32_t pin);
|
virtual bool onConfirmPIN(uint32_t pin);
|
||||||
}; // NimBLEServerCallbacks
|
}; // NimBLEServerCallbacks
|
||||||
|
|
||||||
|
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL */
|
||||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
|
||||||
#endif /* CONFIG_BT_ENABLED */
|
|
||||||
#endif /* MAIN_NIMBLESERVER_H_ */
|
#endif /* MAIN_NIMBLESERVER_H_ */
|
||||||
|
|
|
@ -14,12 +14,10 @@
|
||||||
|
|
||||||
// A service is identified by a UUID. A service is also the container for one or more characteristics.
|
// A service is identified by a UUID. A service is also the container for one or more characteristics.
|
||||||
|
|
||||||
#include "sdkconfig.h"
|
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
|
||||||
|
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||||
|
|
||||||
|
#include "NimBLEDevice.h"
|
||||||
#include "NimBLEService.h"
|
#include "NimBLEService.h"
|
||||||
#include "NimBLEUtils.h"
|
#include "NimBLEUtils.h"
|
||||||
#include "NimBLELog.h"
|
#include "NimBLELog.h"
|
||||||
|
@ -34,25 +32,19 @@ static const char* LOG_TAG = "NimBLEService"; // Tag for logging.
|
||||||
/**
|
/**
|
||||||
* @brief Construct an instance of the NimBLEService
|
* @brief Construct an instance of the NimBLEService
|
||||||
* @param [in] uuid The UUID of the service.
|
* @param [in] uuid The UUID of the service.
|
||||||
* @param [in] numHandles The maximum number of handles associated with the service.
|
|
||||||
* @param [in] pServer A pointer to the server instance that this service belongs to.
|
|
||||||
*/
|
*/
|
||||||
NimBLEService::NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer* pServer)
|
NimBLEService::NimBLEService(const char* uuid)
|
||||||
: NimBLEService(NimBLEUUID(uuid), numHandles, pServer) {
|
: NimBLEService(NimBLEUUID(uuid)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Construct an instance of the BLEService
|
* @brief Construct an instance of the BLEService
|
||||||
* @param [in] uuid The UUID of the service.
|
* @param [in] uuid The UUID of the service.
|
||||||
* @param [in] numHandles The maximum number of handles associated with the service.
|
|
||||||
* @param [in] pServer A pointer to the server instance that this service belongs to.
|
|
||||||
*/
|
*/
|
||||||
NimBLEService::NimBLEService(const NimBLEUUID &uuid, uint16_t numHandles, NimBLEServer* pServer) {
|
NimBLEService::NimBLEService(const NimBLEUUID &uuid) {
|
||||||
m_uuid = uuid;
|
m_uuid = uuid;
|
||||||
m_handle = NULL_HANDLE;
|
m_handle = NULL_HANDLE;
|
||||||
m_pServer = pServer;
|
|
||||||
m_numHandles = numHandles;
|
|
||||||
m_pSvcDef = nullptr;
|
m_pSvcDef = nullptr;
|
||||||
m_removed = 0;
|
m_removed = 0;
|
||||||
|
|
||||||
|
@ -121,6 +113,12 @@ bool NimBLEService::start() {
|
||||||
|
|
||||||
// Rebuild the service definition if the server attributes have changed.
|
// Rebuild the service definition if the server attributes have changed.
|
||||||
if(getServer()->m_svcChanged && m_pSvcDef != nullptr) {
|
if(getServer()->m_svcChanged && m_pSvcDef != nullptr) {
|
||||||
|
if(m_pSvcDef[0].characteristics) {
|
||||||
|
if(m_pSvcDef[0].characteristics[0].descriptors) {
|
||||||
|
delete(m_pSvcDef[0].characteristics[0].descriptors);
|
||||||
|
}
|
||||||
|
delete(m_pSvcDef[0].characteristics);
|
||||||
|
}
|
||||||
delete(m_pSvcDef);
|
delete(m_pSvcDef);
|
||||||
m_pSvcDef = nullptr;
|
m_pSvcDef = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -258,10 +256,11 @@ uint16_t NimBLEService::getHandle() {
|
||||||
* @brief Create a new BLE Characteristic associated with this service.
|
* @brief Create a new BLE Characteristic associated with this service.
|
||||||
* @param [in] uuid - The UUID of the characteristic.
|
* @param [in] uuid - The UUID of the characteristic.
|
||||||
* @param [in] properties - The properties of the characteristic.
|
* @param [in] properties - The properties of the characteristic.
|
||||||
|
* @param [in] max_len - The maximum length in bytes that the characteristic value can hold.
|
||||||
* @return The new BLE characteristic.
|
* @return The new BLE characteristic.
|
||||||
*/
|
*/
|
||||||
NimBLECharacteristic* NimBLEService::createCharacteristic(const char* uuid, uint32_t properties) {
|
NimBLECharacteristic* NimBLEService::createCharacteristic(const char* uuid, uint32_t properties, uint16_t max_len) {
|
||||||
return createCharacteristic(NimBLEUUID(uuid), properties);
|
return createCharacteristic(NimBLEUUID(uuid), properties, max_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -269,10 +268,11 @@ NimBLECharacteristic* NimBLEService::createCharacteristic(const char* uuid, uint
|
||||||
* @brief Create a new BLE Characteristic associated with this service.
|
* @brief Create a new BLE Characteristic associated with this service.
|
||||||
* @param [in] uuid - The UUID of the characteristic.
|
* @param [in] uuid - The UUID of the characteristic.
|
||||||
* @param [in] properties - The properties of the characteristic.
|
* @param [in] properties - The properties of the characteristic.
|
||||||
|
* @param [in] max_len - The maximum length in bytes that the characteristic value can hold.
|
||||||
* @return The new BLE characteristic.
|
* @return The new BLE characteristic.
|
||||||
*/
|
*/
|
||||||
NimBLECharacteristic* NimBLEService::createCharacteristic(const NimBLEUUID &uuid, uint32_t properties) {
|
NimBLECharacteristic* NimBLEService::createCharacteristic(const NimBLEUUID &uuid, uint32_t properties, uint16_t max_len) {
|
||||||
NimBLECharacteristic* pCharacteristic = new NimBLECharacteristic(uuid, properties, this);
|
NimBLECharacteristic* pCharacteristic = new NimBLECharacteristic(uuid, properties, max_len, this);
|
||||||
|
|
||||||
if (getCharacteristic(uuid) != nullptr) {
|
if (getCharacteristic(uuid) != nullptr) {
|
||||||
NIMBLE_LOGD(LOG_TAG, "<< Adding a duplicate characteristic with UUID: %s",
|
NIMBLE_LOGD(LOG_TAG, "<< Adding a duplicate characteristic with UUID: %s",
|
||||||
|
@ -429,8 +429,7 @@ std::string NimBLEService::toString() {
|
||||||
* @return The BLEServer associated with this service.
|
* @return The BLEServer associated with this service.
|
||||||
*/
|
*/
|
||||||
NimBLEServer* NimBLEService::getServer() {
|
NimBLEServer* NimBLEService::getServer() {
|
||||||
return m_pServer;
|
return NimBLEDevice::getServer();
|
||||||
}// getServer
|
}// getServer
|
||||||
|
|
||||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL */
|
||||||
#endif // CONFIG_BT_ENABLED
|
|
||||||
|
|
|
@ -14,11 +14,9 @@
|
||||||
|
|
||||||
#ifndef MAIN_NIMBLESERVICE_H_
|
#ifndef MAIN_NIMBLESERVICE_H_
|
||||||
#define MAIN_NIMBLESERVICE_H_
|
#define MAIN_NIMBLESERVICE_H_
|
||||||
#include "sdkconfig.h"
|
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
|
||||||
|
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||||
|
|
||||||
#include "NimBLEServer.h"
|
#include "NimBLEServer.h"
|
||||||
#include "NimBLECharacteristic.h"
|
#include "NimBLECharacteristic.h"
|
||||||
|
@ -36,8 +34,8 @@ class NimBLECharacteristic;
|
||||||
class NimBLEService {
|
class NimBLEService {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer* pServer);
|
NimBLEService(const char* uuid);
|
||||||
NimBLEService(const NimBLEUUID &uuid, uint16_t numHandles, NimBLEServer* pServer);
|
NimBLEService(const NimBLEUUID &uuid);
|
||||||
~NimBLEService();
|
~NimBLEService();
|
||||||
|
|
||||||
NimBLEServer* getServer();
|
NimBLEServer* getServer();
|
||||||
|
@ -52,12 +50,14 @@ public:
|
||||||
NimBLECharacteristic* createCharacteristic(const char* uuid,
|
NimBLECharacteristic* createCharacteristic(const char* uuid,
|
||||||
uint32_t properties =
|
uint32_t properties =
|
||||||
NIMBLE_PROPERTY::READ |
|
NIMBLE_PROPERTY::READ |
|
||||||
NIMBLE_PROPERTY::WRITE);
|
NIMBLE_PROPERTY::WRITE,
|
||||||
|
uint16_t max_len = BLE_ATT_ATTR_MAX_LEN);
|
||||||
|
|
||||||
NimBLECharacteristic* createCharacteristic(const NimBLEUUID &uuid,
|
NimBLECharacteristic* createCharacteristic(const NimBLEUUID &uuid,
|
||||||
uint32_t properties =
|
uint32_t properties =
|
||||||
NIMBLE_PROPERTY::READ |
|
NIMBLE_PROPERTY::READ |
|
||||||
NIMBLE_PROPERTY::WRITE);
|
NIMBLE_PROPERTY::WRITE,
|
||||||
|
uint16_t max_len = BLE_ATT_ATTR_MAX_LEN);
|
||||||
|
|
||||||
void addCharacteristic(NimBLECharacteristic* pCharacteristic);
|
void addCharacteristic(NimBLECharacteristic* pCharacteristic);
|
||||||
void removeCharacteristic(NimBLECharacteristic* pCharacteristic, bool deleteChr = false);
|
void removeCharacteristic(NimBLECharacteristic* pCharacteristic, bool deleteChr = false);
|
||||||
|
@ -76,16 +76,12 @@ private:
|
||||||
friend class NimBLEDevice;
|
friend class NimBLEDevice;
|
||||||
|
|
||||||
uint16_t m_handle;
|
uint16_t m_handle;
|
||||||
NimBLEServer* m_pServer;
|
|
||||||
NimBLEUUID m_uuid;
|
NimBLEUUID m_uuid;
|
||||||
uint16_t m_numHandles;
|
|
||||||
ble_gatt_svc_def* m_pSvcDef;
|
ble_gatt_svc_def* m_pSvcDef;
|
||||||
uint8_t m_removed;
|
uint8_t m_removed;
|
||||||
std::vector<NimBLECharacteristic*> m_chrVec;
|
std::vector<NimBLECharacteristic*> m_chrVec;
|
||||||
|
|
||||||
}; // NimBLEService
|
}; // NimBLEService
|
||||||
|
|
||||||
|
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL */
|
||||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
|
||||||
#endif // CONFIG_BT_ENABLED
|
|
||||||
#endif /* MAIN_NIMBLESERVICE_H_ */
|
#endif /* MAIN_NIMBLESERVICE_H_ */
|
||||||
|
|
|
@ -11,7 +11,8 @@
|
||||||
* Created on: Jun 21, 2017
|
* Created on: Jun 21, 2017
|
||||||
* Author: kolban
|
* Author: kolban
|
||||||
*/
|
*/
|
||||||
#include "sdkconfig.h"
|
|
||||||
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
#if defined(CONFIG_BT_ENABLED)
|
||||||
|
|
||||||
#include "NimBLEUtils.h"
|
#include "NimBLEUtils.h"
|
||||||
|
@ -234,8 +235,8 @@ 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
|
* @details A UUID can be internally represented as 16bit, 32bit or the full 128bit.
|
||||||
* will convert 16 or 32 bit representations to the full 128bit.
|
* This method will convert 16 or 32bit representations to the full 128bit.
|
||||||
* @return The NimBLEUUID converted to 128bit.
|
* @return The NimBLEUUID converted to 128bit.
|
||||||
*/
|
*/
|
||||||
const NimBLEUUID &NimBLEUUID::to128() {
|
const NimBLEUUID &NimBLEUUID::to128() {
|
||||||
|
@ -256,6 +257,29 @@ const NimBLEUUID &NimBLEUUID::to128() {
|
||||||
} // to128
|
} // to128
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Convert 128 bit UUID to its 16 bit representation.
|
||||||
|
* @details A UUID can be internally represented as 16bit, 32bit or the full 128bit.
|
||||||
|
* This method will convert a 128bit uuid to 16bit if it contains the ble base uuid.
|
||||||
|
* @return The NimBLEUUID converted to 16bit if successful, otherwise the original uuid.
|
||||||
|
*/
|
||||||
|
const NimBLEUUID& NimBLEUUID::to16() {
|
||||||
|
if (!m_valueSet || m_uuid.u.type == BLE_UUID_TYPE_16) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_uuid.u.type == BLE_UUID_TYPE_128) {
|
||||||
|
uint8_t base128[] = {0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00,
|
||||||
|
0x00, 0x80, 0x00, 0x10, 0x00, 0x00};
|
||||||
|
if (memcmp(m_uuid.u128.value, base128, sizeof(base128)) == 0 ) {
|
||||||
|
*this = NimBLEUUID(*(uint16_t*)(m_uuid.u128.value + 12));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get a string representation of the UUID.
|
* @brief Get a string representation of the UUID.
|
||||||
* @details
|
* @details
|
||||||
|
|
|
@ -14,10 +14,16 @@
|
||||||
|
|
||||||
#ifndef COMPONENTS_NIMBLEUUID_H_
|
#ifndef COMPONENTS_NIMBLEUUID_H_
|
||||||
#define COMPONENTS_NIMBLEUUID_H_
|
#define COMPONENTS_NIMBLEUUID_H_
|
||||||
#include "sdkconfig.h"
|
|
||||||
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
#if defined(CONFIG_BT_ENABLED)
|
||||||
|
|
||||||
|
#if defined(CONFIG_NIMBLE_CPP_IDF)
|
||||||
#include "host/ble_uuid.h"
|
#include "host/ble_uuid.h"
|
||||||
|
#else
|
||||||
|
#include "nimble/nimble/host/include/host/ble_uuid.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/**** FIX COMPILATION ****/
|
/**** FIX COMPILATION ****/
|
||||||
#undef min
|
#undef min
|
||||||
#undef max
|
#undef max
|
||||||
|
@ -42,6 +48,7 @@ public:
|
||||||
bool equals(const NimBLEUUID &uuid) 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();
|
||||||
|
const NimBLEUUID& to16();
|
||||||
std::string toString() const;
|
std::string toString() const;
|
||||||
static NimBLEUUID fromString(const std::string &uuid);
|
static NimBLEUUID fromString(const std::string &uuid);
|
||||||
|
|
||||||
|
|
|
@ -6,12 +6,13 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "sdkconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
#if defined(CONFIG_BT_ENABLED)
|
||||||
|
|
||||||
#include "NimBLEUtils.h"
|
#include "NimBLEUtils.h"
|
||||||
#include "NimBLELog.h"
|
#include "NimBLELog.h"
|
||||||
#include "nimconfig.h"
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
static const char* LOG_TAG = "NimBLEUtils";
|
static const char* LOG_TAG = "NimBLEUtils";
|
||||||
|
|
||||||
|
@ -342,6 +343,7 @@ const char* NimBLEUtils::returnCodeToString(int rc) {
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
#else // #if defined(CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT)
|
#else // #if defined(CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT)
|
||||||
|
(void)rc;
|
||||||
return "";
|
return "";
|
||||||
#endif // #if defined(CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT)
|
#endif // #if defined(CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT)
|
||||||
}
|
}
|
||||||
|
@ -369,6 +371,7 @@ const char* NimBLEUtils::advTypeToString(uint8_t advType) {
|
||||||
return "Unknown flag";
|
return "Unknown flag";
|
||||||
}
|
}
|
||||||
#else // #if defined(CONFIG_NIMBLE_CPP_ENABLE_ADVERTISMENT_TYPE_TEXT)
|
#else // #if defined(CONFIG_NIMBLE_CPP_ENABLE_ADVERTISMENT_TYPE_TEXT)
|
||||||
|
(void)advType;
|
||||||
return "";
|
return "";
|
||||||
#endif // #if defined(CONFIG_NIMBLE_CPP_ENABLE_ADVERTISMENT_TYPE_TEXT)
|
#endif // #if defined(CONFIG_NIMBLE_CPP_ENABLE_ADVERTISMENT_TYPE_TEXT)
|
||||||
} // adFlagsToString
|
} // adFlagsToString
|
||||||
|
@ -416,8 +419,11 @@ char* NimBLEUtils::buildHexData(uint8_t* target, const uint8_t* source, uint8_t
|
||||||
* @param [in] arg Unused.
|
* @param [in] arg Unused.
|
||||||
*/
|
*/
|
||||||
void NimBLEUtils::dumpGapEvent(ble_gap_event *event, void *arg){
|
void NimBLEUtils::dumpGapEvent(ble_gap_event *event, void *arg){
|
||||||
|
(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));
|
||||||
|
#else
|
||||||
|
(void)event;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,6 +510,7 @@ const char* NimBLEUtils::gapEventToString(uint8_t eventType) {
|
||||||
return "Unknown event type";
|
return "Unknown event type";
|
||||||
}
|
}
|
||||||
#else // #if defined(CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT)
|
#else // #if defined(CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT)
|
||||||
|
(void)eventType;
|
||||||
return "";
|
return "";
|
||||||
#endif // #if defined(CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT)
|
#endif // #if defined(CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT)
|
||||||
} // gapEventToString
|
} // gapEventToString
|
||||||
|
|
|
@ -8,10 +8,15 @@
|
||||||
|
|
||||||
#ifndef COMPONENTS_NIMBLEUTILS_H_
|
#ifndef COMPONENTS_NIMBLEUTILS_H_
|
||||||
#define COMPONENTS_NIMBLEUTILS_H_
|
#define COMPONENTS_NIMBLEUTILS_H_
|
||||||
#include "sdkconfig.h"
|
|
||||||
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
#if defined(CONFIG_BT_ENABLED)
|
||||||
|
|
||||||
|
#if defined(CONFIG_NIMBLE_CPP_IDF)
|
||||||
#include "host/ble_gap.h"
|
#include "host/ble_gap.h"
|
||||||
|
#else
|
||||||
|
#include "nimble/nimble/host/include/host/ble_gap.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/**** FIX COMPILATION ****/
|
/**** FIX COMPILATION ****/
|
||||||
#undef min
|
#undef min
|
||||||
|
@ -24,7 +29,7 @@ typedef struct {
|
||||||
void *pATT;
|
void *pATT;
|
||||||
TaskHandle_t task;
|
TaskHandle_t task;
|
||||||
int rc;
|
int rc;
|
||||||
std::string *buf;
|
void *buf;
|
||||||
} ble_task_data_t;
|
} ble_task_data_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
|
||||||
//
|
|
||||||
//Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
//you may not use this file except in compliance with the License.
|
|
||||||
//You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
//Unless required by applicable law or agreed to in writing, software
|
|
||||||
//distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
//See the License for the specific language governing permissions and
|
|
||||||
//limitations under the License.
|
|
||||||
#ifndef _CONSOLE_H
|
|
||||||
#define _CONSOLE_H
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#define console_printf printf
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,33 +0,0 @@
|
||||||
// Copyright 2016-2019 Espressif Systems (Shanghai) PTE LTD
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
#ifndef __ESP_COMPILER_H
|
|
||||||
#define __ESP_COMPILER_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The likely and unlikely macro pairs:
|
|
||||||
* These macros are useful to place when application
|
|
||||||
* knows the majority ocurrence of a decision paths,
|
|
||||||
* placing one of these macros can hint the compiler
|
|
||||||
* to reorder instructions producing more optimized
|
|
||||||
* code.
|
|
||||||
*/
|
|
||||||
#if (CONFIG_COMPILER_OPTIMIZATION_PERF)
|
|
||||||
#define likely(x) __builtin_expect(!!(x), 1)
|
|
||||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
|
||||||
#else
|
|
||||||
#define likely(x) (x)
|
|
||||||
#define unlikely(x) (x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -0,0 +1,217 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright {yyyy} {name of copyright owner}
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
This product bundles queue.h 8.5, which is available under the "3-clause BSD"
|
||||||
|
license. For details, see porting/nimble/include/os/queue.h
|
||||||
|
|
||||||
|
This product partly derives from FreeBSD, which is available under the
|
||||||
|
"3-clause BSD" license. For details, see:
|
||||||
|
* porting/nimble/src/os_mbuf.c
|
||||||
|
|
||||||
|
This product bundles Gary S. Brown's CRC32 implementation, which is available
|
||||||
|
under the following license:
|
||||||
|
COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
|
||||||
|
code or tables extracted from it, as desired without restriction.
|
||||||
|
|
||||||
|
This product bundles tinycrypt, which is available under the "3-clause BSD"
|
||||||
|
license. For details, and bundled files see:
|
||||||
|
* ext/tinycrypt/LICENSE
|
|
@ -1,5 +1,6 @@
|
||||||
Apache Mynewt NimBLE
|
Apache Mynewt NimBLE
|
||||||
Copyright 2015-2018 The Apache Software Foundation
|
Copyright 2015-2020 The Apache Software Foundation
|
||||||
|
Modifications Copyright 2017-2020 Espressif Systems (Shanghai) CO., LTD.
|
||||||
|
|
||||||
This product includes software developed at
|
This product includes software developed at
|
||||||
The Apache Software Foundation (http://www.apache.org/).
|
The Apache Software Foundation (http://www.apache.org/).
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
Apache NimBLE is an open-source Bluetooth 5.0 stack (both Host & Controller)
|
Apache NimBLE is an open-source Bluetooth 5.1 stack (both Host & Controller)
|
||||||
that completely replaces the proprietary SoftDevice on Nordic chipsets. It is
|
that completely replaces the proprietary SoftDevice on Nordic chipsets. It is
|
||||||
part of [Apache Mynewt project](https://github.com/apache/mynewt-core).
|
part of [Apache Mynewt project](https://github.com/apache/mynewt-core).
|
||||||
|
|
||||||
|
@ -33,7 +33,6 @@ Features highlight:
|
||||||
- Support for up to 32 simultaneous connections.
|
- Support for up to 32 simultaneous connections.
|
||||||
- Legacy and SC (secure connections) SMP support (pairing and bonding).
|
- Legacy and SC (secure connections) SMP support (pairing and bonding).
|
||||||
- Advertising Extensions.
|
- Advertising Extensions.
|
||||||
- Periodic Advertising.
|
|
||||||
- Coded (aka Long Range) and 2M PHYs.
|
- Coded (aka Long Range) and 2M PHYs.
|
||||||
- Bluetooth Mesh.
|
- Bluetooth Mesh.
|
||||||
|
|
||||||
|
@ -84,27 +83,24 @@ There are also some sample applications that show how to Apache Mynewt NimBLE
|
||||||
stack. These sample applications are located in the `apps/` directory of
|
stack. These sample applications are located in the `apps/` directory of
|
||||||
Apache Mynewt [repo](https://github.com/apache/mynewt-core). Some examples:
|
Apache Mynewt [repo](https://github.com/apache/mynewt-core). Some examples:
|
||||||
|
|
||||||
* [blecent](https://github.com/apache/mynewt-core/tree/master/apps/blecent):
|
* [blecent](https://github.com/apache/mynewt-nimble/tree/master/apps/blecent):
|
||||||
A basic central device with no user interface. This application scans for
|
A basic central device with no user interface. This application scans for
|
||||||
a peripheral that supports the alert notification service (ANS). Upon
|
a peripheral that supports the alert notification service (ANS). Upon
|
||||||
discovering such a peripheral, blecent connects and performs a characteristic
|
discovering such a peripheral, blecent connects and performs a characteristic
|
||||||
read, characteristic write, and notification subscription.
|
read, characteristic write, and notification subscription.
|
||||||
* [blehci](https://github.com/apache/mynewt-core/tree/master/apps/blehci):
|
* [blehci](https://github.com/apache/mynewt-nimble/tree/master/apps/blehci):
|
||||||
Implements a BLE controller-only application. A separate host-only
|
Implements a BLE controller-only application. A separate host-only
|
||||||
implementation, such as Linux's BlueZ, can interface with this application via
|
implementation, such as Linux's BlueZ, can interface with this application via
|
||||||
HCI over UART.
|
HCI over UART.
|
||||||
* [bleprph](https://github.com/apache/mynewt-core/tree/master/apps/bleprph): An
|
* [bleprph](https://github.com/apache/mynewt-nimble/tree/master/apps/bleprph): An
|
||||||
implementation of a minimal BLE peripheral.
|
implementation of a minimal BLE peripheral.
|
||||||
* [btshell](https://github.com/apache/mynewt-core/tree/master/apps/btshell): A
|
* [btshell](https://github.com/apache/mynewt-nimble/tree/master/apps/btshell): A
|
||||||
shell-like application allowing to configure and use most of NimBLE
|
shell-like application allowing to configure and use most of NimBLE
|
||||||
functionality from command line.
|
functionality from command line.
|
||||||
* [bleuart](https://github.com/apache/mynewt-core/tree/master/apps/bleuart):
|
* [bleuart](https://github.com/apache/mynewt-core/tree/master/apps/bleuart):
|
||||||
Implements a simple BLE peripheral that supports the Nordic
|
Implements a simple BLE peripheral that supports the Nordic
|
||||||
UART / Serial Port Emulation service
|
UART / Serial Port Emulation service
|
||||||
(https://developer.nordicsemi.com/nRF5_SDK/nRF51_SDK_v8.x.x/doc/8.0.0/s110/html/a00072.html).
|
(https://developer.nordicsemi.com/nRF5_SDK/nRF51_SDK_v8.x.x/doc/8.0.0/s110/html/a00072.html).
|
||||||
* [test](https://github.com/apache/mynewt-core/tree/master/apps/test): Test
|
|
||||||
project which can be compiled either with the simulator, or on a per-architecture basis.
|
|
||||||
Test will run all the package's unit tests.
|
|
||||||
|
|
||||||
# Getting Help
|
# Getting Help
|
||||||
|
|
||||||
|
@ -113,7 +109,7 @@ want to talk to a human about what you're working on, you can contact us via the
|
||||||
[developers mailing list](mailto:dev@mynewt.apache.org).
|
[developers mailing list](mailto:dev@mynewt.apache.org).
|
||||||
|
|
||||||
Although not a formal channel, you can also find a number of core developers
|
Although not a formal channel, you can also find a number of core developers
|
||||||
on the #mynewt channel on Freenode IRC or #general channel on [Mynewt Slack](https://join.slack.com/mynewt/shared_invite/MTkwMTg1ODM1NTg5LTE0OTYxNzQ4NzQtZTU1YmNhYjhkMg)
|
on the #mynewt channel on Freenode IRC or #general channel on [Mynewt Slack](https://mynewt.slack.com/join/shared_invite/enQtNjA1MTg0NzgyNzg3LTcyMmZiOGQzOGMxM2U4ODFmMTIwNjNmYTE5Y2UwYjQwZWIxNTE0MTUzY2JmMTEzOWFjYWZkNGM0YmM4MzAxNWQ)
|
||||||
|
|
||||||
Also, be sure to checkout the [Frequently Asked Questions](https://mynewt.apache.org/faq/answers)
|
Also, be sure to checkout the [Frequently Asked Questions](https://mynewt.apache.org/faq/answers)
|
||||||
for some help troubleshooting first.
|
for some help troubleshooting first.
|
|
@ -1,26 +1,32 @@
|
||||||
# RELEASE NOTES
|
# RELEASE NOTES
|
||||||
|
|
||||||
16 July 2019 - Apache NimBLE v1.2.0
|
18 March 2020 - Apache NimBLE v1.3.0
|
||||||
|
|
||||||
For full release notes, please visit the
|
For full release notes, please visit the
|
||||||
[Apache Mynewt Wiki](https://cwiki.apache.org/confluence/display/MYNEWT/Release+Notes).
|
[Apache Mynewt Wiki](https://cwiki.apache.org/confluence/display/MYNEWT/Release+Notes).
|
||||||
|
|
||||||
Apache NimBLE is an open-source Bluetooth 5.0 stack (both Host & Controller) that completely
|
Apache NimBLE is an open-source Bluetooth 5.1 stack (both Host & Controller) that completely
|
||||||
replaces the proprietary SoftDevice on Nordic chipsets.
|
replaces the proprietary SoftDevice on Nordic chipsets.
|
||||||
|
|
||||||
New features in this version of NimBLE include:
|
New features in this version of NimBLE include:
|
||||||
|
|
||||||
* Perdiodic Advertising support with up to 1650 bytes of data (scanner and advertiser)
|
* Support for Bluetooth Core Specification 5.1
|
||||||
* Support for scan request notification in GAP API
|
* New blestress test application
|
||||||
* Updated host qualification ID
|
* Dialog DA1469x CMAC driver
|
||||||
|
* Support for LE Secure Connections out-of-band (OOB) association model
|
||||||
|
* Support for automated generation of syscfg for ports
|
||||||
* Qualification related bugfixes
|
* Qualification related bugfixes
|
||||||
* GAP API doxygen documentation update
|
|
||||||
* BLE Mesh improvements - fixes and resync with latest Zephyr code
|
* BLE Mesh improvements - fixes and resync with latest Zephyr code
|
||||||
* RIOT OS port fixes and improvements
|
* RIOT OS port fixes and improvements
|
||||||
* btshell sample application improvements
|
* btshell sample application improvements
|
||||||
* improvements for bttester application
|
* improvements for bttester application
|
||||||
* Controller duplicates filtering improvements
|
* Controller duplicates filtering improvements
|
||||||
* Memory and CPU usage optimizations in controller
|
* Multi PHY support improvements
|
||||||
|
* Memory and CPU usage optimizations
|
||||||
|
* Use of packed structs for HCI (code size reduction)
|
||||||
|
* Linux sample improvements
|
||||||
|
* PTS test instructions updates
|
||||||
|
* Clock managements improvements in controller
|
||||||
|
|
||||||
If working on next-generation RTOS and Bluetooth protocol stack
|
If working on next-generation RTOS and Bluetooth protocol stack
|
||||||
sounds exciting to you, get in touch, by sending a mail to the Apache Mynewt
|
sounds exciting to you, get in touch, by sending a mail to the Apache Mynewt
|
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef __CONSOLE_H__
|
||||||
|
#define __CONSOLE_H__
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define console_printf printf
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __CONSOLE_H__ */
|
|
@ -0,0 +1,51 @@
|
||||||
|
// Copyright 2016-2019 Espressif Systems (Shanghai) PTE LTD
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
#ifndef __ESP_COMPILER_H
|
||||||
|
#define __ESP_COMPILER_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The likely and unlikely macro pairs:
|
||||||
|
* These macros are useful to place when application
|
||||||
|
* knows the majority ocurrence of a decision paths,
|
||||||
|
* placing one of these macros can hint the compiler
|
||||||
|
* to reorder instructions producing more optimized
|
||||||
|
* code.
|
||||||
|
*/
|
||||||
|
#if (CONFIG_COMPILER_OPTIMIZATION_PERF)
|
||||||
|
#define likely(x) __builtin_expect(!!(x), 1)
|
||||||
|
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||||
|
#else
|
||||||
|
#define likely(x) (x)
|
||||||
|
#define unlikely(x) (x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility macros used for designated initializers, which work differently
|
||||||
|
* in C99 and C++ standards mainly for aggregate types.
|
||||||
|
* The member separator, comma, is already part of the macro, please omit the trailing comma.
|
||||||
|
* Usage example:
|
||||||
|
* struct config_t { char* pchr; char arr[SIZE]; } config = {
|
||||||
|
* ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_EMPTY(pchr)
|
||||||
|
* ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_STR(arr, "Value")
|
||||||
|
* };
|
||||||
|
*/
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_STR(member, value) { .member = value },
|
||||||
|
#define ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_EMPTY(member) .member = { },
|
||||||
|
#else
|
||||||
|
#define ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_STR(member, value) .member = value,
|
||||||
|
#define ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_EMPTY(member)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -19,10 +19,11 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef ESP_PLATFORM
|
||||||
#ifndef __ESP_NIMBLE_HCI_H__
|
#ifndef __ESP_NIMBLE_HCI_H__
|
||||||
#define __ESP_NIMBLE_HCI_H__
|
#define __ESP_NIMBLE_HCI_H__
|
||||||
|
|
||||||
#include "nimble/ble_hci_trans.h"
|
#include "nimble/nimble/include/nimble/ble_hci_trans.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -136,3 +137,4 @@ esp_err_t esp_nimble_hci_and_controller_deinit(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __ESP_NIMBLE_HCI_H__ */
|
#endif /* __ESP_NIMBLE_HCI_H__ */
|
||||||
|
#endif
|
|
@ -19,17 +19,19 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef ESP_PLATFORM
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "sysinit/sysinit.h"
|
#include "nimble/porting/nimble/include/sysinit/sysinit.h"
|
||||||
#include "nimble/hci_common.h"
|
#include "nimble/nimble/include/nimble/hci_common.h"
|
||||||
#include "host/ble_hs.h"
|
#include "nimble/nimble/host/include/host/ble_hs.h"
|
||||||
#include "nimble/nimble_port.h"
|
#include "nimble/porting/nimble/include/nimble/nimble_port.h"
|
||||||
#include "nimble/nimble_port_freertos.h"
|
#include "nimble/porting/npl/freertos/include/nimble/nimble_port_freertos.h"
|
||||||
#include "esp_nimble_hci.h"
|
#include "../include/esp_nimble_hci.h"
|
||||||
#include "esp_nimble_mem.h"
|
#include "../../port/include/esp_nimble_mem.h"
|
||||||
#include "esp_bt.h"
|
#include <esp_bt.h>
|
||||||
#include "freertos/semphr.h"
|
#include <freertos/semphr.h>
|
||||||
#include "esp_compiler.h"
|
#include "../include/esp_compiler.h"
|
||||||
/* IPC is used to improve performance when calls come from a processor not running the NimBLE stack */
|
/* IPC is used to improve performance when calls come from a processor not running the NimBLE stack */
|
||||||
/* but does not exist for solo */
|
/* but does not exist for solo */
|
||||||
#ifndef CONFIG_FREERTOS_UNICORE
|
#ifndef CONFIG_FREERTOS_UNICORE
|
||||||
|
@ -110,7 +112,7 @@ int ble_hci_trans_hs_cmd_tx(uint8_t *cmd)
|
||||||
if (xSemaphoreTake(vhci_send_sem, NIMBLE_VHCI_TIMEOUT_MS / portTICK_PERIOD_MS) == pdTRUE) {
|
if (xSemaphoreTake(vhci_send_sem, NIMBLE_VHCI_TIMEOUT_MS / portTICK_PERIOD_MS) == pdTRUE) {
|
||||||
/* esp_ipc_call_blocking does not exist for solo */
|
/* esp_ipc_call_blocking does not exist for solo */
|
||||||
#ifndef CONFIG_FREERTOS_UNICORE
|
#ifndef CONFIG_FREERTOS_UNICORE
|
||||||
if (xPortGetCoreID() != CONFIG_BT_NIMBLE_PINNED_TO_CORE) {
|
if (xPortGetCoreID() != CONFIG_BT_NIMBLE_PINNED_TO_CORE && !xPortInIsrContext()) {
|
||||||
esp_ipc_call_blocking(CONFIG_BT_NIMBLE_PINNED_TO_CORE,
|
esp_ipc_call_blocking(CONFIG_BT_NIMBLE_PINNED_TO_CORE,
|
||||||
ble_hci_trans_hs_cmd_tx_on_core, cmd);
|
ble_hci_trans_hs_cmd_tx_on_core, cmd);
|
||||||
} else {
|
} else {
|
||||||
|
@ -166,7 +168,7 @@ int ble_hci_trans_hs_acl_tx(struct os_mbuf *om)
|
||||||
/* Don't check core ID if unicore */
|
/* Don't check core ID if unicore */
|
||||||
#ifndef CONFIG_FREERTOS_UNICORE
|
#ifndef CONFIG_FREERTOS_UNICORE
|
||||||
tx_using_nimble_core = xPortGetCoreID() != CONFIG_BT_NIMBLE_PINNED_TO_CORE;
|
tx_using_nimble_core = xPortGetCoreID() != CONFIG_BT_NIMBLE_PINNED_TO_CORE;
|
||||||
if (tx_using_nimble_core) {
|
if (tx_using_nimble_core && !xPortInIsrContext()) {
|
||||||
data[0] = len;
|
data[0] = len;
|
||||||
data[1] = (len >> 8);
|
data[1] = (len >> 8);
|
||||||
data[2] = BLE_HCI_UART_H4_ACL;
|
data[2] = BLE_HCI_UART_H4_ACL;
|
||||||
|
@ -183,7 +185,7 @@ int ble_hci_trans_hs_acl_tx(struct os_mbuf *om)
|
||||||
if (xSemaphoreTake(vhci_send_sem, NIMBLE_VHCI_TIMEOUT_MS / portTICK_PERIOD_MS) == pdTRUE) {
|
if (xSemaphoreTake(vhci_send_sem, NIMBLE_VHCI_TIMEOUT_MS / portTICK_PERIOD_MS) == pdTRUE) {
|
||||||
/* esp_ipc_call_blocking does not exist for solo */
|
/* esp_ipc_call_blocking does not exist for solo */
|
||||||
#ifndef CONFIG_FREERTOS_UNICORE
|
#ifndef CONFIG_FREERTOS_UNICORE
|
||||||
if (tx_using_nimble_core) {
|
if (tx_using_nimble_core && !xPortInIsrContext()) {
|
||||||
esp_ipc_call_blocking(CONFIG_BT_NIMBLE_PINNED_TO_CORE,
|
esp_ipc_call_blocking(CONFIG_BT_NIMBLE_PINNED_TO_CORE,
|
||||||
ble_hci_trans_hs_acl_tx_on_core, data);
|
ble_hci_trans_hs_acl_tx_on_core, data);
|
||||||
} else {
|
} else {
|
||||||
|
@ -310,7 +312,6 @@ static struct os_mbuf *ble_hci_trans_acl_buf_alloc(void)
|
||||||
static void ble_hci_rx_acl(uint8_t *data, uint16_t len)
|
static void ble_hci_rx_acl(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
struct os_mbuf *m;
|
struct os_mbuf *m;
|
||||||
int rc;
|
|
||||||
int sr;
|
int sr;
|
||||||
if (len < BLE_HCI_DATA_HDR_SZ || len > MYNEWT_VAL(BLE_ACL_BUF_SIZE)) {
|
if (len < BLE_HCI_DATA_HDR_SZ || len > MYNEWT_VAL(BLE_ACL_BUF_SIZE)) {
|
||||||
return;
|
return;
|
||||||
|
@ -319,11 +320,9 @@ static void ble_hci_rx_acl(uint8_t *data, uint16_t len)
|
||||||
m = ble_hci_trans_acl_buf_alloc();
|
m = ble_hci_trans_acl_buf_alloc();
|
||||||
|
|
||||||
if (!m) {
|
if (!m) {
|
||||||
ESP_LOGE(TAG, "%s failed to allocate ACL buffers; increase ACL_BUF_COUNT", __func__);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((rc = os_mbuf_append(m, data, len)) != 0) {
|
if (os_mbuf_append(m, data, len)) {
|
||||||
ESP_LOGE(TAG, "%s failed to os_mbuf_append; rc = %d", __func__, rc);
|
|
||||||
os_mbuf_free_chain(m);
|
os_mbuf_free_chain(m);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -531,7 +530,6 @@ esp_err_t esp_nimble_hci_and_controller_init(void)
|
||||||
if ((ret = esp_bt_controller_enable(ESP_BT_MODE_BLE)) != ESP_OK) {
|
if ((ret = esp_bt_controller_enable(ESP_BT_MODE_BLE)) != ESP_OK) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return esp_nimble_hci_init();
|
return esp_nimble_hci_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -593,3 +591,5 @@ esp_err_t esp_nimble_hci_and_controller_deinit(void)
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -18,11 +18,12 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
#ifdef ESP_PLATFORM
|
||||||
|
|
||||||
#include "esp_attr.h"
|
#include "esp_attr.h"
|
||||||
#include "esp_heap_caps.h"
|
#include "esp_heap_caps.h"
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
#include "esp_nimble_mem.h"
|
#include "../include/esp_nimble_mem.h"
|
||||||
|
|
||||||
IRAM_ATTR void *nimble_platform_mem_malloc(size_t size)
|
IRAM_ATTR void *nimble_platform_mem_malloc(size_t size)
|
||||||
{
|
{
|
||||||
|
@ -54,3 +55,4 @@ IRAM_ATTR void nimble_platform_mem_free(void *ptr)
|
||||||
{
|
{
|
||||||
heap_caps_free(ptr);
|
heap_caps_free(ptr);
|
||||||
}
|
}
|
||||||
|
#endif
|
|
@ -74,7 +74,7 @@
|
||||||
#ifndef __TC_CBC_MODE_H__
|
#ifndef __TC_CBC_MODE_H__
|
||||||
#define __TC_CBC_MODE_H__
|
#define __TC_CBC_MODE_H__
|
||||||
|
|
||||||
#include <tinycrypt/aes.h>
|
#include "aes.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
|
@ -74,7 +74,7 @@
|
||||||
#ifndef __TC_CCM_MODE_H__
|
#ifndef __TC_CCM_MODE_H__
|
||||||
#define __TC_CCM_MODE_H__
|
#define __TC_CCM_MODE_H__
|
||||||
|
|
||||||
#include <tinycrypt/aes.h>
|
#include "aes.h"
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
|
@ -97,7 +97,7 @@
|
||||||
#ifndef __TC_CMAC_MODE_H__
|
#ifndef __TC_CMAC_MODE_H__
|
||||||
#define __TC_CMAC_MODE_H__
|
#define __TC_CMAC_MODE_H__
|
||||||
|
|
||||||
#include <tinycrypt/aes.h>
|
#include "aes.h"
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
|
@ -67,8 +67,8 @@
|
||||||
#ifndef __TC_CTR_MODE_H__
|
#ifndef __TC_CTR_MODE_H__
|
||||||
#define __TC_CTR_MODE_H__
|
#define __TC_CTR_MODE_H__
|
||||||
|
|
||||||
#include <tinycrypt/aes.h>
|
#include "aes.h"
|
||||||
#include <tinycrypt/constants.h>
|
#include "constants.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
|
@ -59,7 +59,7 @@
|
||||||
#ifndef __TC_CTR_PRNG_H__
|
#ifndef __TC_CTR_PRNG_H__
|
||||||
#define __TC_CTR_PRNG_H__
|
#define __TC_CTR_PRNG_H__
|
||||||
|
|
||||||
#include <tinycrypt/aes.h>
|
#include "aes.h"
|
||||||
|
|
||||||
#define TC_CTR_PRNG_RESEED_REQ -1
|
#define TC_CTR_PRNG_RESEED_REQ -1
|
||||||
|
|
|
@ -69,7 +69,7 @@
|
||||||
#ifndef __TC_ECC_DH_H__
|
#ifndef __TC_ECC_DH_H__
|
||||||
#define __TC_ECC_DH_H__
|
#define __TC_ECC_DH_H__
|
||||||
|
|
||||||
#include <tinycrypt/ecc.h>
|
#include "ecc.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
|
@ -78,7 +78,7 @@
|
||||||
#ifndef __TC_ECC_DSA_H__
|
#ifndef __TC_ECC_DSA_H__
|
||||||
#define __TC_ECC_DSA_H__
|
#define __TC_ECC_DSA_H__
|
||||||
|
|
||||||
#include <tinycrypt/ecc.h>
|
#include "ecc.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
|
@ -63,7 +63,7 @@
|
||||||
#ifndef __TC_HMAC_H__
|
#ifndef __TC_HMAC_H__
|
||||||
#define __TC_HMAC_H__
|
#define __TC_HMAC_H__
|
||||||
|
|
||||||
#include <tinycrypt/sha256.h>
|
#include "sha256.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
|
@ -68,8 +68,8 @@
|
||||||
#ifndef __TC_HMAC_PRNG_H__
|
#ifndef __TC_HMAC_PRNG_H__
|
||||||
#define __TC_HMAC_PRNG_H__
|
#define __TC_HMAC_PRNG_H__
|
||||||
|
|
||||||
#include <tinycrypt/sha256.h>
|
#include "sha256.h"
|
||||||
#include <tinycrypt/hmac.h>
|
#include "hmac.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
|
@ -30,9 +30,9 @@
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <tinycrypt/aes.h>
|
#include "../include/tinycrypt/aes.h"
|
||||||
#include <tinycrypt/constants.h>
|
#include "../include/tinycrypt/constants.h"
|
||||||
#include <tinycrypt/utils.h>
|
#include "../include/tinycrypt/utils.h"
|
||||||
|
|
||||||
static const uint8_t inv_sbox[256] = {
|
static const uint8_t inv_sbox[256] = {
|
||||||
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e,
|
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e,
|
|
@ -30,9 +30,9 @@
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <tinycrypt/aes.h>
|
#include "../include/tinycrypt/aes.h"
|
||||||
#include <tinycrypt/utils.h>
|
#include "../include/tinycrypt/utils.h"
|
||||||
#include <tinycrypt/constants.h>
|
#include "../include/tinycrypt/constants.h"
|
||||||
|
|
||||||
static const uint8_t sbox[256] = {
|
static const uint8_t sbox[256] = {
|
||||||
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b,
|
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b,
|
|
@ -30,9 +30,9 @@
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <tinycrypt/cbc_mode.h>
|
#include "../include/tinycrypt/cbc_mode.h"
|
||||||
#include <tinycrypt/constants.h>
|
#include "../include/tinycrypt/constants.h"
|
||||||
#include <tinycrypt/utils.h>
|
#include "../include/tinycrypt/utils.h"
|
||||||
|
|
||||||
int tc_cbc_mode_encrypt(uint8_t *out, unsigned int outlen, const uint8_t *in,
|
int tc_cbc_mode_encrypt(uint8_t *out, unsigned int outlen, const uint8_t *in,
|
||||||
unsigned int inlen, const uint8_t *iv,
|
unsigned int inlen, const uint8_t *iv,
|
|
@ -30,9 +30,9 @@
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <tinycrypt/ccm_mode.h>
|
#include "../include/tinycrypt/ccm_mode.h"
|
||||||
#include <tinycrypt/constants.h>
|
#include "../include/tinycrypt/constants.h"
|
||||||
#include <tinycrypt/utils.h>
|
#include "../include/tinycrypt/utils.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
|
@ -30,10 +30,10 @@
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <tinycrypt/aes.h>
|
#include "../include/tinycrypt/aes.h"
|
||||||
#include <tinycrypt/cmac_mode.h>
|
#include "../include/tinycrypt/cmac_mode.h"
|
||||||
#include <tinycrypt/constants.h>
|
#include "../include/tinycrypt/constants.h"
|
||||||
#include <tinycrypt/utils.h>
|
#include "../include/tinycrypt/utils.h"
|
||||||
|
|
||||||
/* max number of calls until change the key (2^48).*/
|
/* max number of calls until change the key (2^48).*/
|
||||||
const static uint64_t MAX_CALLS = ((uint64_t)1 << 48);
|
const static uint64_t MAX_CALLS = ((uint64_t)1 << 48);
|
|
@ -30,9 +30,9 @@
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <tinycrypt/constants.h>
|
#include "../include/tinycrypt/constants.h"
|
||||||
#include <tinycrypt/ctr_mode.h>
|
#include "../include/tinycrypt/ctr_mode.h"
|
||||||
#include <tinycrypt/utils.h>
|
#include "../include/tinycrypt/utils.h"
|
||||||
|
|
||||||
int tc_ctr_mode(uint8_t *out, unsigned int outlen, const uint8_t *in,
|
int tc_ctr_mode(uint8_t *out, unsigned int outlen, const uint8_t *in,
|
||||||
unsigned int inlen, uint8_t *ctr, const TCAesKeySched_t sched)
|
unsigned int inlen, uint8_t *ctr, const TCAesKeySched_t sched)
|
|
@ -27,9 +27,9 @@
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <tinycrypt/ctr_prng.h>
|
#include "../include/tinycrypt/ctr_prng.h"
|
||||||
#include <tinycrypt/utils.h>
|
#include "../include/tinycrypt/utils.h"
|
||||||
#include <tinycrypt/constants.h>
|
#include "../include/tinycrypt/constants.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/*
|
/*
|
|
@ -52,8 +52,8 @@
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <tinycrypt/ecc.h>
|
#include "../include/tinycrypt/ecc.h"
|
||||||
#include <tinycrypt/ecc_platform_specific.h>
|
#include "../include/tinycrypt/ecc_platform_specific.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/* IMPORTANT: Make sure a cryptographically-secure PRNG is set and the platform
|
/* IMPORTANT: Make sure a cryptographically-secure PRNG is set and the platform
|
|
@ -54,9 +54,9 @@
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
#include <tinycrypt/constants.h>
|
#include "../include/tinycrypt/constants.h"
|
||||||
#include <tinycrypt/ecc.h>
|
#include "../include/tinycrypt/ecc.h"
|
||||||
#include <tinycrypt/ecc_dh.h>
|
#include "../include/tinycrypt/ecc_dh.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#if default_RNG_defined
|
#if default_RNG_defined
|
|
@ -53,9 +53,9 @@
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <tinycrypt/constants.h>
|
#include "../include/tinycrypt/constants.h"
|
||||||
#include <tinycrypt/ecc.h>
|
#include "../include/tinycrypt/ecc.h"
|
||||||
#include <tinycrypt/ecc_dsa.h>
|
#include "../include/tinycrypt/ecc_dsa.h"
|
||||||
|
|
||||||
#if default_RNG_defined
|
#if default_RNG_defined
|
||||||
static uECC_RNG_Function g_rng_function = &default_CSPRNG;
|
static uECC_RNG_Function g_rng_function = &default_CSPRNG;
|
|
@ -30,9 +30,9 @@
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <tinycrypt/hmac.h>
|
#include "../include/tinycrypt/hmac.h"
|
||||||
#include <tinycrypt/constants.h>
|
#include "../include/tinycrypt/constants.h"
|
||||||
#include <tinycrypt/utils.h>
|
#include "../include/tinycrypt/utils.h"
|
||||||
|
|
||||||
static void rekey(uint8_t *key, const uint8_t *new_key, unsigned int key_size)
|
static void rekey(uint8_t *key, const uint8_t *new_key, unsigned int key_size)
|
||||||
{
|
{
|
|
@ -30,10 +30,10 @@
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <tinycrypt/hmac_prng.h>
|
#include "../include/tinycrypt/hmac_prng.h"
|
||||||
#include <tinycrypt/hmac.h>
|
#include "../include/tinycrypt/hmac.h"
|
||||||
#include <tinycrypt/constants.h>
|
#include "../include/tinycrypt/constants.h"
|
||||||
#include <tinycrypt/utils.h>
|
#include "../include/tinycrypt/utils.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* min bytes in the seed string.
|
* min bytes in the seed string.
|
|
@ -30,9 +30,9 @@
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <tinycrypt/sha256.h>
|
#include "../include/tinycrypt/sha256.h"
|
||||||
#include <tinycrypt/constants.h>
|
#include "../include/tinycrypt/constants.h"
|
||||||
#include <tinycrypt/utils.h>
|
#include "../include/tinycrypt/utils.h"
|
||||||
|
|
||||||
static void compress(unsigned int *iv, const uint8_t *data);
|
static void compress(unsigned int *iv, const uint8_t *data);
|
||||||
|
|
|
@ -30,8 +30,8 @@
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <tinycrypt/utils.h>
|
#include "../include/tinycrypt/utils.h"
|
||||||
#include <tinycrypt/constants.h>
|
#include "../include/tinycrypt/constants.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
|
@ -1,307 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef H_BLE_ATT_PRIV_
|
|
||||||
#define H_BLE_ATT_PRIV_
|
|
||||||
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include "stats/stats.h"
|
|
||||||
#include "host/ble_att.h"
|
|
||||||
#include "host/ble_uuid.h"
|
|
||||||
#include "nimble/nimble_npl.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct os_mbuf;
|
|
||||||
struct ble_hs_conn;
|
|
||||||
struct ble_l2cap_chan;
|
|
||||||
struct ble_att_find_info_req;
|
|
||||||
struct ble_att_error_rsp;
|
|
||||||
struct ble_att_mtu_cmd;
|
|
||||||
struct ble_att_read_req;
|
|
||||||
struct ble_att_read_blob_req;
|
|
||||||
struct ble_att_read_type_req;
|
|
||||||
struct ble_att_read_group_type_req;
|
|
||||||
struct ble_att_read_group_type_rsp;
|
|
||||||
struct ble_att_find_type_value_req;
|
|
||||||
struct ble_att_write_req;
|
|
||||||
struct ble_att_prep_write_cmd;
|
|
||||||
struct ble_att_exec_write_req;
|
|
||||||
struct ble_att_notify_req;
|
|
||||||
struct ble_att_indicate_req;
|
|
||||||
|
|
||||||
STATS_SECT_START(ble_att_stats)
|
|
||||||
STATS_SECT_ENTRY(error_rsp_rx)
|
|
||||||
STATS_SECT_ENTRY(error_rsp_tx)
|
|
||||||
STATS_SECT_ENTRY(mtu_req_rx)
|
|
||||||
STATS_SECT_ENTRY(mtu_req_tx)
|
|
||||||
STATS_SECT_ENTRY(mtu_rsp_rx)
|
|
||||||
STATS_SECT_ENTRY(mtu_rsp_tx)
|
|
||||||
STATS_SECT_ENTRY(find_info_req_rx)
|
|
||||||
STATS_SECT_ENTRY(find_info_req_tx)
|
|
||||||
STATS_SECT_ENTRY(find_info_rsp_rx)
|
|
||||||
STATS_SECT_ENTRY(find_info_rsp_tx)
|
|
||||||
STATS_SECT_ENTRY(find_type_value_req_rx)
|
|
||||||
STATS_SECT_ENTRY(find_type_value_req_tx)
|
|
||||||
STATS_SECT_ENTRY(find_type_value_rsp_rx)
|
|
||||||
STATS_SECT_ENTRY(find_type_value_rsp_tx)
|
|
||||||
STATS_SECT_ENTRY(read_type_req_rx)
|
|
||||||
STATS_SECT_ENTRY(read_type_req_tx)
|
|
||||||
STATS_SECT_ENTRY(read_type_rsp_rx)
|
|
||||||
STATS_SECT_ENTRY(read_type_rsp_tx)
|
|
||||||
STATS_SECT_ENTRY(read_req_rx)
|
|
||||||
STATS_SECT_ENTRY(read_req_tx)
|
|
||||||
STATS_SECT_ENTRY(read_rsp_rx)
|
|
||||||
STATS_SECT_ENTRY(read_rsp_tx)
|
|
||||||
STATS_SECT_ENTRY(read_blob_req_rx)
|
|
||||||
STATS_SECT_ENTRY(read_blob_req_tx)
|
|
||||||
STATS_SECT_ENTRY(read_blob_rsp_rx)
|
|
||||||
STATS_SECT_ENTRY(read_blob_rsp_tx)
|
|
||||||
STATS_SECT_ENTRY(read_mult_req_rx)
|
|
||||||
STATS_SECT_ENTRY(read_mult_req_tx)
|
|
||||||
STATS_SECT_ENTRY(read_mult_rsp_rx)
|
|
||||||
STATS_SECT_ENTRY(read_mult_rsp_tx)
|
|
||||||
STATS_SECT_ENTRY(read_group_type_req_rx)
|
|
||||||
STATS_SECT_ENTRY(read_group_type_req_tx)
|
|
||||||
STATS_SECT_ENTRY(read_group_type_rsp_rx)
|
|
||||||
STATS_SECT_ENTRY(read_group_type_rsp_tx)
|
|
||||||
STATS_SECT_ENTRY(write_req_rx)
|
|
||||||
STATS_SECT_ENTRY(write_req_tx)
|
|
||||||
STATS_SECT_ENTRY(write_rsp_rx)
|
|
||||||
STATS_SECT_ENTRY(write_rsp_tx)
|
|
||||||
STATS_SECT_ENTRY(prep_write_req_rx)
|
|
||||||
STATS_SECT_ENTRY(prep_write_req_tx)
|
|
||||||
STATS_SECT_ENTRY(prep_write_rsp_rx)
|
|
||||||
STATS_SECT_ENTRY(prep_write_rsp_tx)
|
|
||||||
STATS_SECT_ENTRY(exec_write_req_rx)
|
|
||||||
STATS_SECT_ENTRY(exec_write_req_tx)
|
|
||||||
STATS_SECT_ENTRY(exec_write_rsp_rx)
|
|
||||||
STATS_SECT_ENTRY(exec_write_rsp_tx)
|
|
||||||
STATS_SECT_ENTRY(notify_req_rx)
|
|
||||||
STATS_SECT_ENTRY(notify_req_tx)
|
|
||||||
STATS_SECT_ENTRY(indicate_req_rx)
|
|
||||||
STATS_SECT_ENTRY(indicate_req_tx)
|
|
||||||
STATS_SECT_ENTRY(indicate_rsp_rx)
|
|
||||||
STATS_SECT_ENTRY(indicate_rsp_tx)
|
|
||||||
STATS_SECT_ENTRY(write_cmd_rx)
|
|
||||||
STATS_SECT_ENTRY(write_cmd_tx)
|
|
||||||
STATS_SECT_END
|
|
||||||
extern STATS_SECT_DECL(ble_att_stats) ble_att_stats;
|
|
||||||
|
|
||||||
struct ble_att_prep_entry {
|
|
||||||
SLIST_ENTRY(ble_att_prep_entry) bape_next;
|
|
||||||
uint16_t bape_handle;
|
|
||||||
uint16_t bape_offset;
|
|
||||||
|
|
||||||
/* XXX: This is wasteful; we should use one mbuf chain for the entire
|
|
||||||
* prepared write, and compress the data into as few mbufs as possible.
|
|
||||||
*/
|
|
||||||
struct os_mbuf *bape_value;
|
|
||||||
};
|
|
||||||
|
|
||||||
SLIST_HEAD(ble_att_prep_entry_list, ble_att_prep_entry);
|
|
||||||
|
|
||||||
struct ble_att_svr_conn {
|
|
||||||
/** This list is sorted by attribute handle ID. */
|
|
||||||
struct ble_att_prep_entry_list basc_prep_list;
|
|
||||||
ble_npl_time_t basc_prep_timeout_at;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles a host attribute request.
|
|
||||||
*
|
|
||||||
* @param entry The host attribute being requested.
|
|
||||||
* @param op The operation being performed on the attribute.
|
|
||||||
* @param arg The request data associated with that host
|
|
||||||
* attribute.
|
|
||||||
*
|
|
||||||
* @return 0 on success;
|
|
||||||
* One of the BLE_ATT_ERR_[...] codes on
|
|
||||||
* failure.
|
|
||||||
*/
|
|
||||||
typedef int ble_att_svr_access_fn(uint16_t conn_handle, uint16_t attr_handle,
|
|
||||||
uint8_t op, uint16_t offset,
|
|
||||||
struct os_mbuf **om, void *arg);
|
|
||||||
|
|
||||||
int ble_att_svr_register(const ble_uuid_t *uuid, uint8_t flags,
|
|
||||||
uint8_t min_key_size, uint16_t *handle_id,
|
|
||||||
ble_att_svr_access_fn *cb, void *cb_arg);
|
|
||||||
|
|
||||||
struct ble_att_svr_entry {
|
|
||||||
STAILQ_ENTRY(ble_att_svr_entry) ha_next;
|
|
||||||
|
|
||||||
const ble_uuid_t *ha_uuid;
|
|
||||||
uint8_t ha_flags;
|
|
||||||
uint8_t ha_min_key_size;
|
|
||||||
uint16_t ha_handle_id;
|
|
||||||
ble_att_svr_access_fn *ha_cb;
|
|
||||||
void *ha_cb_arg;
|
|
||||||
};
|
|
||||||
|
|
||||||
SLIST_HEAD(ble_att_clt_entry_list, ble_att_clt_entry);
|
|
||||||
|
|
||||||
/*** @gen */
|
|
||||||
|
|
||||||
struct ble_l2cap_chan *ble_att_create_chan(uint16_t conn_handle);
|
|
||||||
int ble_att_conn_chan_find(uint16_t conn_handle, struct ble_hs_conn **out_conn,
|
|
||||||
struct ble_l2cap_chan **out_chan);
|
|
||||||
void ble_att_inc_tx_stat(uint8_t att_op);
|
|
||||||
void ble_att_truncate_to_mtu(const struct ble_l2cap_chan *att_chan,
|
|
||||||
struct os_mbuf *txom);
|
|
||||||
void ble_att_set_peer_mtu(struct ble_l2cap_chan *chan, uint16_t peer_mtu);
|
|
||||||
uint16_t ble_att_chan_mtu(const struct ble_l2cap_chan *chan);
|
|
||||||
int ble_att_init(void);
|
|
||||||
|
|
||||||
#define BLE_ATT_LOG_CMD(is_tx, cmd_name, conn_handle, log_cb, cmd) \
|
|
||||||
BLE_HS_LOG_CMD((is_tx), "att", (cmd_name), (conn_handle), (log_cb), (cmd))
|
|
||||||
|
|
||||||
#define BLE_ATT_LOG_EMPTY_CMD(is_tx, cmd_name, conn_handle) \
|
|
||||||
BLE_HS_LOG_EMPTY_CMD((is_tx), "att", (cmd_name), (conn_handle))
|
|
||||||
|
|
||||||
/*** @svr */
|
|
||||||
|
|
||||||
int ble_att_svr_start(void);
|
|
||||||
void ble_att_svr_stop(void);
|
|
||||||
|
|
||||||
struct ble_att_svr_entry *
|
|
||||||
ble_att_svr_find_by_uuid(struct ble_att_svr_entry *start_at,
|
|
||||||
const ble_uuid_t *uuid,
|
|
||||||
uint16_t end_handle);
|
|
||||||
uint16_t ble_att_svr_prev_handle(void);
|
|
||||||
int ble_att_svr_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom);
|
|
||||||
struct ble_att_svr_entry *ble_att_svr_find_by_handle(uint16_t handle_id);
|
|
||||||
int32_t ble_att_svr_ticks_until_tmo(const struct ble_att_svr_conn *svr,
|
|
||||||
ble_npl_time_t now);
|
|
||||||
int ble_att_svr_rx_find_info(uint16_t conn_handle, struct os_mbuf **rxom);
|
|
||||||
int ble_att_svr_rx_find_type_value(uint16_t conn_handle,
|
|
||||||
struct os_mbuf **rxom);
|
|
||||||
int ble_att_svr_rx_read_type(uint16_t conn_handle,
|
|
||||||
struct os_mbuf **rxom);
|
|
||||||
int ble_att_svr_rx_read_group_type(uint16_t conn_handle,
|
|
||||||
struct os_mbuf **rxom);
|
|
||||||
int ble_att_svr_rx_read(uint16_t conn_handle,
|
|
||||||
struct os_mbuf **rxom);
|
|
||||||
int ble_att_svr_rx_read_blob(uint16_t conn_handle,
|
|
||||||
struct os_mbuf **rxom);
|
|
||||||
int ble_att_svr_rx_read_mult(uint16_t conn_handle,
|
|
||||||
struct os_mbuf **rxom);
|
|
||||||
int ble_att_svr_rx_write(uint16_t conn_handle,
|
|
||||||
struct os_mbuf **rxom);
|
|
||||||
int ble_att_svr_rx_write_no_rsp(uint16_t conn_handle, struct os_mbuf **rxom);
|
|
||||||
int ble_att_svr_rx_prep_write(uint16_t conn_handle,
|
|
||||||
struct os_mbuf **rxom);
|
|
||||||
int ble_att_svr_rx_exec_write(uint16_t conn_handle,
|
|
||||||
struct os_mbuf **rxom);
|
|
||||||
int ble_att_svr_rx_notify(uint16_t conn_handle,
|
|
||||||
struct os_mbuf **rxom);
|
|
||||||
int ble_att_svr_rx_indicate(uint16_t conn_handle,
|
|
||||||
struct os_mbuf **rxom);
|
|
||||||
void ble_att_svr_prep_clear(struct ble_att_prep_entry_list *prep_list);
|
|
||||||
int ble_att_svr_read_handle(uint16_t conn_handle, uint16_t attr_handle,
|
|
||||||
uint16_t offset, struct os_mbuf *om,
|
|
||||||
uint8_t *out_att_err);
|
|
||||||
void ble_att_svr_reset(void);
|
|
||||||
int ble_att_svr_init(void);
|
|
||||||
|
|
||||||
void ble_att_svr_hide_range(uint16_t start_handle, uint16_t end_handle);
|
|
||||||
void ble_att_svr_restore_range(uint16_t start_handle, uint16_t end_handle);
|
|
||||||
|
|
||||||
int ble_att_svr_tx_error_rsp(uint16_t conn_handle, struct os_mbuf *txom,
|
|
||||||
uint8_t req_op, uint16_t handle,
|
|
||||||
uint8_t error_code);
|
|
||||||
/*** $clt */
|
|
||||||
|
|
||||||
/** An information-data entry in a find information response. */
|
|
||||||
struct ble_att_find_info_idata {
|
|
||||||
uint16_t attr_handle;
|
|
||||||
ble_uuid_any_t uuid;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** A handles-information entry in a find by type value response. */
|
|
||||||
struct ble_att_find_type_value_hinfo {
|
|
||||||
uint16_t attr_handle;
|
|
||||||
uint16_t group_end_handle;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** An attribute-data entry in a read by type response. */
|
|
||||||
struct ble_att_read_type_adata {
|
|
||||||
uint16_t att_handle;
|
|
||||||
int value_len;
|
|
||||||
uint8_t *value;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/** An attribute-data entry in a read by group type response. */
|
|
||||||
struct ble_att_read_group_type_adata {
|
|
||||||
uint16_t att_handle;
|
|
||||||
uint16_t end_group_handle;
|
|
||||||
int value_len;
|
|
||||||
uint8_t *value;
|
|
||||||
};
|
|
||||||
|
|
||||||
int ble_att_clt_rx_error(uint16_t conn_handle, struct os_mbuf **rxom);
|
|
||||||
int ble_att_clt_tx_mtu(uint16_t conn_handle, uint16_t mtu);
|
|
||||||
int ble_att_clt_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom);
|
|
||||||
int ble_att_clt_tx_read(uint16_t conn_handle, uint16_t handle);
|
|
||||||
int ble_att_clt_rx_read(uint16_t conn_handle, struct os_mbuf **rxom);
|
|
||||||
int ble_att_clt_tx_read_blob(uint16_t conn_handle, uint16_t handle,
|
|
||||||
uint16_t offset);
|
|
||||||
int ble_att_clt_rx_read_blob(uint16_t conn_handle, struct os_mbuf **rxom);
|
|
||||||
int ble_att_clt_tx_read_mult(uint16_t conn_handle,
|
|
||||||
const uint16_t *handles, int num_handles);
|
|
||||||
int ble_att_clt_rx_read_mult(uint16_t conn_handle, struct os_mbuf **rxom);
|
|
||||||
int ble_att_clt_tx_read_type(uint16_t conn_handle, uint16_t start_handle,
|
|
||||||
uint16_t end_handle, const ble_uuid_t *uuid);
|
|
||||||
int ble_att_clt_rx_read_type(uint16_t conn_handle, struct os_mbuf **rxom);
|
|
||||||
int ble_att_clt_tx_read_group_type(uint16_t conn_handle,
|
|
||||||
uint16_t start_handle, uint16_t end_handle,
|
|
||||||
const ble_uuid_t *uuid128);
|
|
||||||
int ble_att_clt_rx_read_group_type(uint16_t conn_handle,
|
|
||||||
struct os_mbuf **rxom);
|
|
||||||
int ble_att_clt_tx_find_info(uint16_t conn_handle, uint16_t start_handle,
|
|
||||||
uint16_t end_handle);
|
|
||||||
int ble_att_clt_rx_find_info(uint16_t conn_handle, struct os_mbuf **rxom);
|
|
||||||
int ble_att_clt_tx_find_type_value(uint16_t conn_handle, uint16_t start_handle,
|
|
||||||
uint16_t end_handle, uint16_t attribute_type,
|
|
||||||
const void *attribute_value, int value_len);
|
|
||||||
int ble_att_clt_rx_find_type_value(uint16_t conn_handle,
|
|
||||||
struct os_mbuf **rxom);
|
|
||||||
int ble_att_clt_tx_write_req(uint16_t conn_handle, uint16_t handle,
|
|
||||||
struct os_mbuf *txom);
|
|
||||||
int ble_att_clt_tx_write_cmd(uint16_t conn_handle, uint16_t handle,
|
|
||||||
struct os_mbuf *txom);
|
|
||||||
int ble_att_clt_tx_prep_write(uint16_t conn_handle, uint16_t handle,
|
|
||||||
uint16_t offset, struct os_mbuf *txom);
|
|
||||||
int ble_att_clt_rx_prep_write(uint16_t conn_handle, struct os_mbuf **rxom);
|
|
||||||
int ble_att_clt_tx_exec_write(uint16_t conn_handle, uint8_t flags);
|
|
||||||
int ble_att_clt_rx_exec_write(uint16_t conn_handle, struct os_mbuf **rxom);
|
|
||||||
int ble_att_clt_rx_write(uint16_t conn_handle, struct os_mbuf **rxom);
|
|
||||||
int ble_att_clt_tx_notify(uint16_t conn_handle, uint16_t handle,
|
|
||||||
struct os_mbuf *txom);
|
|
||||||
int ble_att_clt_tx_indicate(uint16_t conn_handle, uint16_t handle,
|
|
||||||
struct os_mbuf *txom);
|
|
||||||
int ble_att_clt_rx_indicate(uint16_t conn_handle, struct os_mbuf **rxom);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,128 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef H_BLE_HS_CONN_
|
|
||||||
#define H_BLE_HS_CONN_
|
|
||||||
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include "ble_l2cap_priv.h"
|
|
||||||
#include "ble_gatt_priv.h"
|
|
||||||
#include "ble_att_priv.h"
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct hci_le_conn_complete;
|
|
||||||
struct hci_create_conn;
|
|
||||||
struct ble_l2cap_chan;
|
|
||||||
|
|
||||||
typedef uint8_t ble_hs_conn_flags_t;
|
|
||||||
|
|
||||||
#define BLE_HS_CONN_F_MASTER 0x01
|
|
||||||
#define BLE_HS_CONN_F_TERMINATING 0x02
|
|
||||||
#define BLE_HS_CONN_F_TX_FRAG 0x04 /* Cur ACL packet partially txed. */
|
|
||||||
|
|
||||||
struct ble_hs_conn {
|
|
||||||
SLIST_ENTRY(ble_hs_conn) bhc_next;
|
|
||||||
uint16_t bhc_handle;
|
|
||||||
uint8_t bhc_our_addr_type;
|
|
||||||
#if MYNEWT_VAL(BLE_EXT_ADV)
|
|
||||||
uint8_t bhc_our_rnd_addr[6];
|
|
||||||
#endif
|
|
||||||
ble_addr_t bhc_peer_addr;
|
|
||||||
ble_addr_t bhc_our_rpa_addr;
|
|
||||||
ble_addr_t bhc_peer_rpa_addr;
|
|
||||||
|
|
||||||
uint16_t bhc_itvl;
|
|
||||||
uint16_t bhc_latency;
|
|
||||||
uint16_t bhc_supervision_timeout;
|
|
||||||
uint8_t bhc_master_clock_accuracy;
|
|
||||||
|
|
||||||
uint32_t supported_feat;
|
|
||||||
|
|
||||||
ble_hs_conn_flags_t bhc_flags;
|
|
||||||
|
|
||||||
struct ble_l2cap_chan_list bhc_channels;
|
|
||||||
struct ble_l2cap_chan *bhc_rx_chan; /* Channel rxing current packet. */
|
|
||||||
ble_npl_time_t bhc_rx_timeout;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Count of packets sent over this connection that the controller has not
|
|
||||||
* transmitted or flushed yet.
|
|
||||||
*/
|
|
||||||
uint16_t bhc_outstanding_pkts;
|
|
||||||
|
|
||||||
#if MYNEWT_VAL(BLE_HS_FLOW_CTRL)
|
|
||||||
/**
|
|
||||||
* Count of packets received over this connection that have been processed
|
|
||||||
* and freed.
|
|
||||||
*/
|
|
||||||
uint16_t bhc_completed_pkts;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Queue of outgoing packets that could not be sent. */
|
|
||||||
STAILQ_HEAD(, os_mbuf_pkthdr) bhc_tx_q;
|
|
||||||
|
|
||||||
struct ble_att_svr_conn bhc_att_svr;
|
|
||||||
struct ble_gatts_conn bhc_gatt_svr;
|
|
||||||
|
|
||||||
struct ble_gap_sec_state bhc_sec_state;
|
|
||||||
|
|
||||||
ble_gap_event_fn *bhc_cb;
|
|
||||||
void *bhc_cb_arg;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ble_hs_conn_addrs {
|
|
||||||
ble_addr_t our_id_addr;
|
|
||||||
ble_addr_t peer_id_addr;
|
|
||||||
ble_addr_t our_ota_addr;
|
|
||||||
ble_addr_t peer_ota_addr;
|
|
||||||
};
|
|
||||||
|
|
||||||
int ble_hs_conn_can_alloc(void);
|
|
||||||
struct ble_hs_conn *ble_hs_conn_alloc(uint16_t conn_handle);
|
|
||||||
void ble_hs_conn_free(struct ble_hs_conn *conn);
|
|
||||||
void ble_hs_conn_insert(struct ble_hs_conn *conn);
|
|
||||||
void ble_hs_conn_remove(struct ble_hs_conn *conn);
|
|
||||||
struct ble_hs_conn *ble_hs_conn_find(uint16_t conn_handle);
|
|
||||||
struct ble_hs_conn *ble_hs_conn_find_assert(uint16_t conn_handle);
|
|
||||||
struct ble_hs_conn *ble_hs_conn_find_by_addr(const ble_addr_t *addr);
|
|
||||||
struct ble_hs_conn *ble_hs_conn_find_by_idx(int idx);
|
|
||||||
int ble_hs_conn_exists(uint16_t conn_handle);
|
|
||||||
struct ble_hs_conn *ble_hs_conn_first(void);
|
|
||||||
struct ble_l2cap_chan *ble_hs_conn_chan_find_by_scid(struct ble_hs_conn *conn,
|
|
||||||
uint16_t cid);
|
|
||||||
struct ble_l2cap_chan *ble_hs_conn_chan_find_by_dcid(struct ble_hs_conn *conn,
|
|
||||||
uint16_t cid);
|
|
||||||
int ble_hs_conn_chan_insert(struct ble_hs_conn *conn,
|
|
||||||
struct ble_l2cap_chan *chan);
|
|
||||||
void
|
|
||||||
ble_hs_conn_delete_chan(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan);
|
|
||||||
|
|
||||||
void ble_hs_conn_addrs(const struct ble_hs_conn *conn,
|
|
||||||
struct ble_hs_conn_addrs *addrs);
|
|
||||||
int32_t ble_hs_conn_timer(void);
|
|
||||||
|
|
||||||
int ble_hs_conn_init(void);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue