mirror of
https://github.com/h2zero/esp-nimble-cpp.git
synced 2024-12-22 19:10:46 +01:00
Conditionally compile code for specific roles.
This allows NimBLE options in menuconfig to reduce code size based on the roles selected (scan/advertising/central/peripheral). Significant code space can be saved by removing unnecessary roles for the application.
This commit is contained in:
parent
3d6f8b691e
commit
03cb7b21d9
53 changed files with 2335 additions and 2012 deletions
27
Kconfig
Normal file
27
Kconfig
Normal file
|
@ -0,0 +1,27 @@
|
|||
menu "ESP-NimBLE-CPP configuration"
|
||||
|
||||
config NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT
|
||||
bool "Show NimBLE return codes as text in debug log."
|
||||
default "n"
|
||||
help
|
||||
Enabling this option will display return code values as text
|
||||
messages in the debug log. This will use approximately 8kB
|
||||
of flash memory.
|
||||
|
||||
config NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT
|
||||
bool "Show NimBLE gap events as text in debug log."
|
||||
default "n"
|
||||
help
|
||||
Enabling this option will display gap event codes as text
|
||||
messages in the debug log. This will use approximately 1kB
|
||||
of flash memory.
|
||||
|
||||
config NIMBLE_CPP_ENABLE_ADVERTISMENT_TYPE_TEXT
|
||||
bool "Show advertisment types as text in debug log."
|
||||
default "n"
|
||||
help
|
||||
Enabling this option will display advertisment types recieved
|
||||
while scanning as text messages in the debug log.
|
||||
This will use approximately 250 bytes of flash memory.
|
||||
|
||||
endmenu
|
|
@ -89,28 +89,28 @@ uint32_t FreeRTOS::Semaphore::wait(std::string owner) {
|
|||
* @return True if we took the semaphore within timeframe.
|
||||
*/
|
||||
bool FreeRTOS::Semaphore::timedWait(std::string owner, uint32_t timeoutMs) {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> wait: Semaphore waiting: %s for %s", toString().c_str(), owner.c_str());
|
||||
NIMBLE_LOGD(LOG_TAG, ">> wait: Semaphore waiting: %s for %s", toString().c_str(), owner.c_str());
|
||||
|
||||
if (m_usePthreads && timeoutMs != portMAX_DELAY) {
|
||||
assert(false); // We apparently don't have a timed wait for pthreads.
|
||||
}
|
||||
if (m_usePthreads && timeoutMs != portMAX_DELAY) {
|
||||
assert(false); // We apparently don't have a timed wait for pthreads.
|
||||
}
|
||||
|
||||
auto ret = pdTRUE;
|
||||
auto ret = pdTRUE;
|
||||
|
||||
if (m_usePthreads) {
|
||||
pthread_mutex_lock(&m_pthread_mutex);
|
||||
} else {
|
||||
ret = xSemaphoreTake(m_semaphore, timeoutMs);
|
||||
}
|
||||
if (m_usePthreads) {
|
||||
pthread_mutex_lock(&m_pthread_mutex);
|
||||
} else {
|
||||
ret = xSemaphoreTake(m_semaphore, timeoutMs);
|
||||
}
|
||||
|
||||
if (m_usePthreads) {
|
||||
pthread_mutex_unlock(&m_pthread_mutex);
|
||||
} else {
|
||||
xSemaphoreGive(m_semaphore);
|
||||
}
|
||||
if (m_usePthreads) {
|
||||
pthread_mutex_unlock(&m_pthread_mutex);
|
||||
} else {
|
||||
xSemaphoreGive(m_semaphore);
|
||||
}
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "<< wait: Semaphore %s released: %d", toString().c_str(), ret);
|
||||
return ret;
|
||||
NIMBLE_LOGD(LOG_TAG, "<< wait: Semaphore %s released: %d", toString().c_str(), ret);
|
||||
return ret;
|
||||
} // wait
|
||||
|
||||
|
||||
|
|
|
@ -40,9 +40,9 @@ public:
|
|||
bool take(std::string owner = "<Unknown>");
|
||||
bool take(uint32_t timeoutMs, std::string owner = "<Unknown>");
|
||||
std::string toString();
|
||||
bool timedWait(std::string owner = "<Unknown>", uint32_t timeoutMs = portMAX_DELAY);
|
||||
bool timedWait(std::string owner = "<Unknown>", uint32_t timeoutMs = portMAX_DELAY);
|
||||
uint32_t wait(std::string owner = "<Unknown>");
|
||||
uint32_t value(){ return m_value; };
|
||||
uint32_t value(){ return m_value; };
|
||||
|
||||
private:
|
||||
SemaphoreHandle_t m_semaphore;
|
||||
|
|
|
@ -26,9 +26,9 @@
|
|||
|
||||
/* Modifiers */
|
||||
enum MODIFIER_KEY {
|
||||
KEY_CTRL = 1,
|
||||
KEY_SHIFT = 2,
|
||||
KEY_ALT = 4,
|
||||
KEY_CTRL = 1,
|
||||
KEY_SHIFT = 2,
|
||||
KEY_ALT = 4,
|
||||
};
|
||||
|
||||
|
||||
|
@ -43,37 +43,37 @@ enum MEDIA_KEY {
|
|||
};
|
||||
|
||||
enum FUNCTION_KEY {
|
||||
KEY_F1 = 128, /* F1 key */
|
||||
KEY_F2, /* F2 key */
|
||||
KEY_F3, /* F3 key */
|
||||
KEY_F4, /* F4 key */
|
||||
KEY_F5, /* F5 key */
|
||||
KEY_F6, /* F6 key */
|
||||
KEY_F7, /* F7 key */
|
||||
KEY_F8, /* F8 key */
|
||||
KEY_F9, /* F9 key */
|
||||
KEY_F10, /* F10 key */
|
||||
KEY_F11, /* F11 key */
|
||||
KEY_F12, /* F12 key */
|
||||
KEY_F1 = 128, /* F1 key */
|
||||
KEY_F2, /* F2 key */
|
||||
KEY_F3, /* F3 key */
|
||||
KEY_F4, /* F4 key */
|
||||
KEY_F5, /* F5 key */
|
||||
KEY_F6, /* F6 key */
|
||||
KEY_F7, /* F7 key */
|
||||
KEY_F8, /* F8 key */
|
||||
KEY_F9, /* F9 key */
|
||||
KEY_F10, /* F10 key */
|
||||
KEY_F11, /* F11 key */
|
||||
KEY_F12, /* F12 key */
|
||||
|
||||
KEY_PRINT_SCREEN, /* Print Screen key */
|
||||
KEY_SCROLL_LOCK, /* Scroll lock */
|
||||
KEY_CAPS_LOCK, /* caps lock */
|
||||
KEY_NUM_LOCK, /* num lock */
|
||||
KEY_INSERT, /* Insert key */
|
||||
KEY_HOME, /* Home key */
|
||||
KEY_PAGE_UP, /* Page Up key */
|
||||
KEY_PAGE_DOWN, /* Page Down key */
|
||||
KEY_PRINT_SCREEN, /* Print Screen key */
|
||||
KEY_SCROLL_LOCK, /* Scroll lock */
|
||||
KEY_CAPS_LOCK, /* caps lock */
|
||||
KEY_NUM_LOCK, /* num lock */
|
||||
KEY_INSERT, /* Insert key */
|
||||
KEY_HOME, /* Home key */
|
||||
KEY_PAGE_UP, /* Page Up key */
|
||||
KEY_PAGE_DOWN, /* Page Down key */
|
||||
|
||||
RIGHT_ARROW, /* Right arrow */
|
||||
LEFT_ARROW, /* Left arrow */
|
||||
DOWN_ARROW, /* Down arrow */
|
||||
UP_ARROW, /* Up arrow */
|
||||
RIGHT_ARROW, /* Right arrow */
|
||||
LEFT_ARROW, /* Left arrow */
|
||||
DOWN_ARROW, /* Down arrow */
|
||||
UP_ARROW, /* Up arrow */
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
unsigned char usage;
|
||||
unsigned char modifier;
|
||||
unsigned char usage;
|
||||
unsigned char modifier;
|
||||
} KEYMAP;
|
||||
|
||||
#ifdef US_KEYBOARD
|
||||
|
|
|
@ -89,8 +89,8 @@
|
|||
#define MAX_HID_REPORT_SIZE (64)
|
||||
|
||||
typedef struct {
|
||||
uint32_t length;
|
||||
uint8_t data[MAX_HID_REPORT_SIZE];
|
||||
uint32_t length;
|
||||
uint8_t data[MAX_HID_REPORT_SIZE];
|
||||
} HID_REPORT;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on March 10, 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLE2902.cpp
|
||||
|
@ -20,16 +20,19 @@
|
|||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
|
||||
#include "NimBLE2902.h"
|
||||
|
||||
NimBLE2902::NimBLE2902(NimBLECharacteristic* pCharacterisitic)
|
||||
: NimBLEDescriptor(NimBLEUUID((uint16_t) 0x2902),
|
||||
BLE_GATT_CHR_F_READ |
|
||||
BLE_GATT_CHR_F_WRITE,
|
||||
2, pCharacterisitic)
|
||||
NimBLE2902::NimBLE2902(NimBLECharacteristic* pCharacterisitic)
|
||||
: NimBLEDescriptor(NimBLEUUID((uint16_t) 0x2902),
|
||||
BLE_GATT_CHR_F_READ |
|
||||
BLE_GATT_CHR_F_WRITE,
|
||||
2, pCharacterisitic)
|
||||
{
|
||||
uint8_t data[2] = { 0, 0 };
|
||||
setValue(data, 2);
|
||||
uint8_t data[2] = { 0, 0 };
|
||||
setValue(data, 2);
|
||||
} // NimBLE2902
|
||||
|
||||
|
||||
|
@ -38,7 +41,7 @@ NimBLE2902::NimBLE2902(NimBLECharacteristic* pCharacterisitic)
|
|||
* @return The notifications value. True if notifications are enabled and false if not.
|
||||
*/
|
||||
bool NimBLE2902::getNotifications() {
|
||||
return (getValue()[0] & (1 << 0)) != 0;
|
||||
return (getValue()[0] & (1 << 0)) != 0;
|
||||
} // getNotifications
|
||||
|
||||
|
||||
|
@ -47,7 +50,7 @@ bool NimBLE2902::getNotifications() {
|
|||
* @return The indications value. True if indications are enabled and false if not.
|
||||
*/
|
||||
bool NimBLE2902::getIndications() {
|
||||
return (getValue()[0] & (1 << 1)) != 0;
|
||||
return (getValue()[0] & (1 << 1)) != 0;
|
||||
} // getIndications
|
||||
|
||||
|
||||
|
@ -56,9 +59,9 @@ bool NimBLE2902::getIndications() {
|
|||
* @param [in] flag The indications flag.
|
||||
*/
|
||||
void NimBLE2902::setIndications(bool flag) {
|
||||
uint8_t *pValue = getValue();
|
||||
if (flag) pValue[0] |= 1 << 1;
|
||||
else pValue[0] &= ~(1 << 1);
|
||||
uint8_t *pValue = getValue();
|
||||
if (flag) pValue[0] |= 1 << 1;
|
||||
else pValue[0] &= ~(1 << 1);
|
||||
} // setIndications
|
||||
|
||||
|
||||
|
@ -67,9 +70,10 @@ void NimBLE2902::setIndications(bool flag) {
|
|||
* @param [in] flag The notifications flag.
|
||||
*/
|
||||
void NimBLE2902::setNotifications(bool flag) {
|
||||
uint8_t *pValue = getValue();
|
||||
if (flag) pValue[0] |= 1 << 0;
|
||||
else pValue[0] &= ~(1 << 0);
|
||||
uint8_t *pValue = getValue();
|
||||
if (flag) pValue[0] |= 1 << 0;
|
||||
else pValue[0] &= ~(1 << 0);
|
||||
} // setNotifications
|
||||
|
||||
#endif
|
||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
#endif
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on March 10, 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLE2902.h
|
||||
|
@ -17,6 +17,9 @@
|
|||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
|
||||
#include "NimBLEDescriptor.h"
|
||||
|
||||
#include <map>
|
||||
|
@ -35,16 +38,17 @@
|
|||
*/
|
||||
class NimBLE2902: public NimBLEDescriptor {
|
||||
public:
|
||||
bool getNotifications();
|
||||
bool getIndications();
|
||||
void setNotifications(bool flag);
|
||||
void setIndications(bool flag);
|
||||
bool getNotifications();
|
||||
bool getIndications();
|
||||
void setNotifications(bool flag);
|
||||
void setIndications(bool flag);
|
||||
private:
|
||||
NimBLE2902(NimBLECharacteristic* pCharacterisitic);
|
||||
NimBLE2902(NimBLECharacteristic* pCharacterisitic);
|
||||
friend class NimBLECharacteristic;
|
||||
std::map<uint16_t, uint16_t> m_subscribedMap;
|
||||
|
||||
}; // NimBLE2902
|
||||
|
||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
#endif /* CONFIG_BT_ENABLED */
|
||||
#endif /* MAIN_NIMBLE2902_H_ */
|
||||
#endif /* MAIN_NIMBLE2902_H_ */
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on March 13, 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLE2904.cpp
|
||||
|
@ -19,21 +19,24 @@
|
|||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
|
||||
#include "NimBLE2904.h"
|
||||
|
||||
|
||||
NimBLE2904::NimBLE2904(NimBLECharacteristic* pCharacterisitic)
|
||||
NimBLE2904::NimBLE2904(NimBLECharacteristic* pCharacterisitic)
|
||||
: NimBLEDescriptor(NimBLEUUID((uint16_t) 0x2904),
|
||||
BLE_GATT_CHR_F_READ,
|
||||
sizeof(BLE2904_Data),
|
||||
pCharacterisitic)
|
||||
BLE_GATT_CHR_F_READ,
|
||||
sizeof(BLE2904_Data),
|
||||
pCharacterisitic)
|
||||
{
|
||||
m_data.m_format = 0;
|
||||
m_data.m_exponent = 0;
|
||||
m_data.m_namespace = 1; // 1 = Bluetooth SIG Assigned Numbers
|
||||
m_data.m_unit = 0;
|
||||
m_data.m_description = 0;
|
||||
setValue((uint8_t*) &m_data, sizeof(m_data));
|
||||
m_data.m_format = 0;
|
||||
m_data.m_exponent = 0;
|
||||
m_data.m_namespace = 1; // 1 = Bluetooth SIG Assigned Numbers
|
||||
m_data.m_unit = 0;
|
||||
m_data.m_description = 0;
|
||||
setValue((uint8_t*) &m_data, sizeof(m_data));
|
||||
} // BLE2902
|
||||
|
||||
|
||||
|
@ -41,8 +44,8 @@ NimBLE2904::NimBLE2904(NimBLECharacteristic* pCharacterisitic)
|
|||
* @brief Set the description.
|
||||
*/
|
||||
void NimBLE2904::setDescription(uint16_t description) {
|
||||
m_data.m_description = description;
|
||||
setValue((uint8_t*) &m_data, sizeof(m_data));
|
||||
m_data.m_description = description;
|
||||
setValue((uint8_t*) &m_data, sizeof(m_data));
|
||||
}
|
||||
|
||||
|
||||
|
@ -50,8 +53,8 @@ void NimBLE2904::setDescription(uint16_t description) {
|
|||
* @brief Set the exponent.
|
||||
*/
|
||||
void NimBLE2904::setExponent(int8_t exponent) {
|
||||
m_data.m_exponent = exponent;
|
||||
setValue((uint8_t*) &m_data, sizeof(m_data));
|
||||
m_data.m_exponent = exponent;
|
||||
setValue((uint8_t*) &m_data, sizeof(m_data));
|
||||
} // setExponent
|
||||
|
||||
|
||||
|
@ -59,8 +62,8 @@ void NimBLE2904::setExponent(int8_t exponent) {
|
|||
* @brief Set the format.
|
||||
*/
|
||||
void NimBLE2904::setFormat(uint8_t format) {
|
||||
m_data.m_format = format;
|
||||
setValue((uint8_t*) &m_data, sizeof(m_data));
|
||||
m_data.m_format = format;
|
||||
setValue((uint8_t*) &m_data, sizeof(m_data));
|
||||
} // setFormat
|
||||
|
||||
|
||||
|
@ -68,8 +71,8 @@ void NimBLE2904::setFormat(uint8_t format) {
|
|||
* @brief Set the namespace.
|
||||
*/
|
||||
void NimBLE2904::setNamespace(uint8_t namespace_value) {
|
||||
m_data.m_namespace = namespace_value;
|
||||
setValue((uint8_t*) &m_data, sizeof(m_data));
|
||||
m_data.m_namespace = namespace_value;
|
||||
setValue((uint8_t*) &m_data, sizeof(m_data));
|
||||
} // setNamespace
|
||||
|
||||
|
||||
|
@ -79,8 +82,9 @@ void NimBLE2904::setNamespace(uint8_t namespace_value) {
|
|||
* @param [in] unit The type of units of this characteristic as defined by assigned numbers.
|
||||
*/
|
||||
void NimBLE2904::setUnit(uint16_t unit) {
|
||||
m_data.m_unit = unit;
|
||||
setValue((uint8_t*) &m_data, sizeof(m_data));
|
||||
m_data.m_unit = unit;
|
||||
setValue((uint8_t*) &m_data, sizeof(m_data));
|
||||
} // setUnit
|
||||
|
||||
#endif
|
||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
#endif
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on March 13, 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLE2904.h
|
||||
|
@ -17,14 +17,17 @@
|
|||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
|
||||
#include "NimBLEDescriptor.h"
|
||||
|
||||
struct BLE2904_Data {
|
||||
uint8_t m_format;
|
||||
int8_t m_exponent;
|
||||
uint16_t m_unit; // See https://www.bluetooth.com/specifications/assigned-numbers/units
|
||||
uint8_t m_namespace;
|
||||
uint16_t m_description;
|
||||
uint8_t m_format;
|
||||
int8_t m_exponent;
|
||||
uint16_t m_unit; // See https://www.bluetooth.com/specifications/assigned-numbers/units
|
||||
uint8_t m_namespace;
|
||||
uint16_t m_description;
|
||||
|
||||
} __attribute__((packed));
|
||||
|
||||
|
@ -38,45 +41,46 @@ struct BLE2904_Data {
|
|||
*/
|
||||
class NimBLE2904: public NimBLEDescriptor {
|
||||
public:
|
||||
static const uint8_t FORMAT_BOOLEAN = 1;
|
||||
static const uint8_t FORMAT_UINT2 = 2;
|
||||
static const uint8_t FORMAT_UINT4 = 3;
|
||||
static const uint8_t FORMAT_UINT8 = 4;
|
||||
static const uint8_t FORMAT_UINT12 = 5;
|
||||
static const uint8_t FORMAT_UINT16 = 6;
|
||||
static const uint8_t FORMAT_UINT24 = 7;
|
||||
static const uint8_t FORMAT_UINT32 = 8;
|
||||
static const uint8_t FORMAT_UINT48 = 9;
|
||||
static const uint8_t FORMAT_UINT64 = 10;
|
||||
static const uint8_t FORMAT_UINT128 = 11;
|
||||
static const uint8_t FORMAT_SINT8 = 12;
|
||||
static const uint8_t FORMAT_SINT12 = 13;
|
||||
static const uint8_t FORMAT_SINT16 = 14;
|
||||
static const uint8_t FORMAT_SINT24 = 15;
|
||||
static const uint8_t FORMAT_SINT32 = 16;
|
||||
static const uint8_t FORMAT_SINT48 = 17;
|
||||
static const uint8_t FORMAT_SINT64 = 18;
|
||||
static const uint8_t FORMAT_SINT128 = 19;
|
||||
static const uint8_t FORMAT_FLOAT32 = 20;
|
||||
static const uint8_t FORMAT_FLOAT64 = 21;
|
||||
static const uint8_t FORMAT_SFLOAT16 = 22;
|
||||
static const uint8_t FORMAT_SFLOAT32 = 23;
|
||||
static const uint8_t FORMAT_IEEE20601 = 24;
|
||||
static const uint8_t FORMAT_UTF8 = 25;
|
||||
static const uint8_t FORMAT_UTF16 = 26;
|
||||
static const uint8_t FORMAT_OPAQUE = 27;
|
||||
static const uint8_t FORMAT_BOOLEAN = 1;
|
||||
static const uint8_t FORMAT_UINT2 = 2;
|
||||
static const uint8_t FORMAT_UINT4 = 3;
|
||||
static const uint8_t FORMAT_UINT8 = 4;
|
||||
static const uint8_t FORMAT_UINT12 = 5;
|
||||
static const uint8_t FORMAT_UINT16 = 6;
|
||||
static const uint8_t FORMAT_UINT24 = 7;
|
||||
static const uint8_t FORMAT_UINT32 = 8;
|
||||
static const uint8_t FORMAT_UINT48 = 9;
|
||||
static const uint8_t FORMAT_UINT64 = 10;
|
||||
static const uint8_t FORMAT_UINT128 = 11;
|
||||
static const uint8_t FORMAT_SINT8 = 12;
|
||||
static const uint8_t FORMAT_SINT12 = 13;
|
||||
static const uint8_t FORMAT_SINT16 = 14;
|
||||
static const uint8_t FORMAT_SINT24 = 15;
|
||||
static const uint8_t FORMAT_SINT32 = 16;
|
||||
static const uint8_t FORMAT_SINT48 = 17;
|
||||
static const uint8_t FORMAT_SINT64 = 18;
|
||||
static const uint8_t FORMAT_SINT128 = 19;
|
||||
static const uint8_t FORMAT_FLOAT32 = 20;
|
||||
static const uint8_t FORMAT_FLOAT64 = 21;
|
||||
static const uint8_t FORMAT_SFLOAT16 = 22;
|
||||
static const uint8_t FORMAT_SFLOAT32 = 23;
|
||||
static const uint8_t FORMAT_IEEE20601 = 24;
|
||||
static const uint8_t FORMAT_UTF8 = 25;
|
||||
static const uint8_t FORMAT_UTF16 = 26;
|
||||
static const uint8_t FORMAT_OPAQUE = 27;
|
||||
|
||||
void setDescription(uint16_t);
|
||||
void setExponent(int8_t exponent);
|
||||
void setFormat(uint8_t format);
|
||||
void setNamespace(uint8_t namespace_value);
|
||||
void setUnit(uint16_t unit);
|
||||
void setDescription(uint16_t);
|
||||
void setExponent(int8_t exponent);
|
||||
void setFormat(uint8_t format);
|
||||
void setNamespace(uint8_t namespace_value);
|
||||
void setUnit(uint16_t unit);
|
||||
|
||||
private:
|
||||
NimBLE2904(NimBLECharacteristic* pCharacterisitic);
|
||||
NimBLE2904(NimBLECharacteristic* pCharacterisitic);
|
||||
friend class NimBLECharacteristic;
|
||||
BLE2904_Data m_data;
|
||||
BLE2904_Data m_data;
|
||||
}; // BLE2904
|
||||
|
||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
#endif /* CONFIG_BT_ENABLED */
|
||||
#endif /* MAIN_NIMBLE2904_H_ */
|
||||
#endif /* MAIN_NIMBLE2904_H_ */
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on Jan 24 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLEAddress.cpp
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on Jan 24 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLEAddress.h
|
||||
|
@ -40,9 +40,9 @@ public:
|
|||
const uint8_t* getNative() const;
|
||||
std::string toString() const;
|
||||
|
||||
bool operator ==(const NimBLEAddress & rhs) const;
|
||||
bool operator !=(const NimBLEAddress & rhs) const;
|
||||
operator std::string() const;
|
||||
bool operator ==(const NimBLEAddress & rhs) const;
|
||||
bool operator !=(const NimBLEAddress & rhs) const;
|
||||
operator std::string() const;
|
||||
|
||||
private:
|
||||
uint8_t m_address[6];
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on Jan 24 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLEAdvertisedDevice.cpp
|
||||
|
@ -14,6 +14,9 @@
|
|||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
||||
|
||||
#include "NimBLEAdvertisedDevice.h"
|
||||
#include "NimBLEUtils.h"
|
||||
#include "NimBLELog.h"
|
||||
|
@ -121,7 +124,7 @@ std::string NimBLEAdvertisedDevice::getServiceData() {
|
|||
* @brief Get the service data UUID.
|
||||
* @return The service data UUID.
|
||||
*/
|
||||
|
||||
|
||||
NimBLEUUID NimBLEAdvertisedDevice::getServiceDataUUID() {
|
||||
return m_serviceDataUUID;
|
||||
} // getServiceDataUUID
|
||||
|
@ -131,7 +134,7 @@ NimBLEUUID NimBLEAdvertisedDevice::getServiceDataUUID() {
|
|||
* @brief Get the Service UUID.
|
||||
* @return The Service UUID of the advertised device.
|
||||
*/
|
||||
|
||||
|
||||
NimBLEUUID NimBLEAdvertisedDevice::getServiceUUID() { //TODO Remove it eventually, is no longer useful
|
||||
return m_serviceUUIDs[0];
|
||||
} // getServiceUUID
|
||||
|
@ -270,7 +273,7 @@ bool NimBLEAdvertisedDevice::haveTXPower() {
|
|||
|
||||
u8p = fields->svc_data_uuid16;
|
||||
length = fields->svc_data_uuid16_len;
|
||||
|
||||
|
||||
if (length < 2) {
|
||||
NIMBLE_LOGE(LOG_TAG,"Length too small for ESP_BLE_AD_TYPE_SERVICE_DATA");
|
||||
}
|
||||
|
@ -287,23 +290,23 @@ bool NimBLEAdvertisedDevice::haveTXPower() {
|
|||
|
||||
u8p = fields->svc_data_uuid16;
|
||||
length = fields->svc_data_uuid16_len;
|
||||
|
||||
|
||||
if (length < 4) {
|
||||
NIMBLE_LOGE(LOG_TAG,"Length too small for ESP_BLE_AD_TYPE_32SERVICE_DATA");
|
||||
}
|
||||
|
||||
|
||||
uint32_t uuid = *(uint32_t*) u8p;
|
||||
setServiceDataUUID(NimBLEUUID(uuid));
|
||||
if (length > 4) {
|
||||
setServiceData(std::string(reinterpret_cast<char*>(u8p + 4), length - 4));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (fields->svc_data_uuid128 != NULL) {
|
||||
|
||||
u8p = fields->svc_data_uuid16;
|
||||
length = fields->svc_data_uuid16_len;
|
||||
|
||||
|
||||
if (length < 16) {
|
||||
NIMBLE_LOGE(LOG_TAG,"Length too small for ESP_BLE_AD_TYPE_128SERVICE_DATA");
|
||||
}
|
||||
|
@ -318,7 +321,7 @@ bool NimBLEAdvertisedDevice::haveTXPower() {
|
|||
NIMBLE_LOGD(LOG_TAG, " appearance=0x%04x", fields->appearance);
|
||||
setAppearance(fields->appearance);
|
||||
}
|
||||
|
||||
|
||||
/**** TODO: create storage and fucntions for these parameters
|
||||
if (fields->public_tgt_addr != NULL) {
|
||||
NIMBLE_LOGD(LOG_TAG, " public_tgt_addr=");
|
||||
|
@ -329,7 +332,7 @@ bool NimBLEAdvertisedDevice::haveTXPower() {
|
|||
}
|
||||
NIMBLE_LOGD(LOG_TAG, "\n");
|
||||
}
|
||||
|
||||
|
||||
if (fields->slave_itvl_range != NULL) {
|
||||
NIMBLE_LOGD(LOG_TAG, " slave_itvl_range=");
|
||||
print_bytes(fields->slave_itvl_range, BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN);
|
||||
|
@ -350,7 +353,7 @@ bool NimBLEAdvertisedDevice::haveTXPower() {
|
|||
setManufacturerData(std::string(reinterpret_cast<char*>(fields->mfg_data), fields->mfg_data_len));
|
||||
}
|
||||
} //parseAdvertisement
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set the address of the advertised device.
|
||||
|
@ -430,7 +433,7 @@ void NimBLEAdvertisedDevice::setScan(NimBLEScan* pScan) {
|
|||
* @brief Set the Service UUID for this device.
|
||||
* @param [in] serviceUUID The discovered serviceUUID
|
||||
*/
|
||||
|
||||
|
||||
void NimBLEAdvertisedDevice::setServiceUUID(const char* serviceUUID) {
|
||||
return setServiceUUID(NimBLEUUID(serviceUUID));
|
||||
} // setServiceUUID
|
||||
|
@ -488,9 +491,9 @@ void NimBLEAdvertisedDevice::setTXPower(int8_t txPower) {
|
|||
* @brief Create a string representation of this device.
|
||||
* @return A string representation of this device.
|
||||
*/
|
||||
std::string NimBLEAdvertisedDevice::toString() {
|
||||
std::string NimBLEAdvertisedDevice::toString() {
|
||||
std::string res = "Name: " + getName() + ", Address: " + getAddress().toString();
|
||||
|
||||
|
||||
if (haveAppearance()) {
|
||||
char val[6];
|
||||
snprintf(val, sizeof(val), "%d", getAppearance());
|
||||
|
@ -508,16 +511,16 @@ std::string NimBLEAdvertisedDevice::toString() {
|
|||
if (haveServiceUUID()) {
|
||||
res += ", serviceUUID: " + getServiceUUID().toString();
|
||||
}
|
||||
|
||||
|
||||
if (haveTXPower()) {
|
||||
char val[5];
|
||||
snprintf(val, sizeof(val), "%d", getTXPower());
|
||||
res += ", txPower: ";
|
||||
res += val;
|
||||
}
|
||||
|
||||
|
||||
res += ", advType: " + std::string(NimBLEUtils::advTypeToString(m_advType));
|
||||
|
||||
|
||||
return res;
|
||||
|
||||
} // toString
|
||||
|
@ -548,5 +551,6 @@ void NimBLEAdvertisedDevice::setAdvertisementResult(uint8_t* payload, uint8_t le
|
|||
m_payloadLength = length;
|
||||
}
|
||||
|
||||
#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||
#endif /* CONFIG_BT_ENABLED */
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on Jan 24 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLEAdvertisedDevice.h
|
||||
|
@ -17,6 +17,9 @@
|
|||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
||||
|
||||
#include "NimBLEAddress.h"
|
||||
#include "NimBLEScan.h"
|
||||
#include "NimBLEUUID.h"
|
||||
|
@ -24,7 +27,7 @@
|
|||
#include "host/ble_hs_adv.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <vector>
|
||||
|
||||
|
||||
class NimBLEScan;
|
||||
|
@ -129,5 +132,6 @@ public:
|
|||
virtual void onResult(NimBLEAdvertisedDevice* advertisedDevice) = 0;
|
||||
};
|
||||
|
||||
#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||
#endif /* CONFIG_BT_ENABLED */
|
||||
#endif /* COMPONENTS_NIMBLEADVERTISEDDEVICE_H_ */
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on March 3, 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLEAdvertising.cpp
|
||||
|
@ -15,6 +15,10 @@
|
|||
*/
|
||||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
|
||||
|
||||
#include "services/gap/ble_svc_gap.h"
|
||||
#include "NimBLEAdvertising.h"
|
||||
#include "NimBLEDevice.h"
|
||||
|
@ -31,26 +35,26 @@ static const char* LOG_TAG = "NimBLEAdvertising";
|
|||
*/
|
||||
NimBLEAdvertising::NimBLEAdvertising() {
|
||||
memset(&m_advData, 0, sizeof m_advData);
|
||||
memset(&m_scanData, 0, sizeof m_scanData);
|
||||
memset(&m_advParams, 0, sizeof m_advParams);
|
||||
memset(&m_scanData, 0, sizeof m_scanData);
|
||||
memset(&m_advParams, 0, sizeof m_advParams);
|
||||
const char *name = ble_svc_gap_device_name();
|
||||
|
||||
m_advData.name = (uint8_t *)name;
|
||||
m_advData.name = (uint8_t *)name;
|
||||
m_advData.name_len = strlen(name);
|
||||
m_advData.name_is_complete = 1;
|
||||
m_scanData.tx_pwr_lvl_is_present = 1;
|
||||
m_scanData.tx_pwr_lvl = NimBLEDevice::getPower();
|
||||
m_advData.flags = (BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP);
|
||||
m_advData.appearance = 0;
|
||||
m_advData.appearance_is_present = 0;
|
||||
m_advData.mfg_data_len = 0;
|
||||
m_advData.mfg_data = nullptr;
|
||||
|
||||
m_advParams.conn_mode = BLE_GAP_CONN_MODE_UND;
|
||||
m_advData.appearance = 0;
|
||||
m_advData.appearance_is_present = 0;
|
||||
m_advData.mfg_data_len = 0;
|
||||
m_advData.mfg_data = nullptr;
|
||||
|
||||
m_advParams.conn_mode = BLE_GAP_CONN_MODE_UND;
|
||||
m_advParams.disc_mode = BLE_GAP_DISC_MODE_GEN;
|
||||
m_advParams.itvl_min = 0;
|
||||
m_advParams.itvl_max = 0;
|
||||
|
||||
m_advParams.itvl_min = 0;
|
||||
m_advParams.itvl_max = 0;
|
||||
|
||||
} // NimBLEAdvertising
|
||||
|
||||
|
||||
|
@ -59,7 +63,7 @@ NimBLEAdvertising::NimBLEAdvertising() {
|
|||
* @param [in] serviceUUID The UUID of the service to expose.
|
||||
*/
|
||||
void NimBLEAdvertising::addServiceUUID(const NimBLEUUID &serviceUUID) {
|
||||
m_serviceUUIDs.push_back(serviceUUID);
|
||||
m_serviceUUIDs.push_back(serviceUUID);
|
||||
} // addServiceUUID
|
||||
|
||||
|
||||
|
@ -68,7 +72,7 @@ void NimBLEAdvertising::addServiceUUID(const NimBLEUUID &serviceUUID) {
|
|||
* @param [in] serviceUUID The string representation of the service to expose.
|
||||
*/
|
||||
void NimBLEAdvertising::addServiceUUID(const char* serviceUUID) {
|
||||
addServiceUUID(NimBLEUUID(serviceUUID));
|
||||
addServiceUUID(NimBLEUUID(serviceUUID));
|
||||
} // addServiceUUID
|
||||
|
||||
|
||||
|
@ -80,34 +84,34 @@ void NimBLEAdvertising::addServiceUUID(const char* serviceUUID) {
|
|||
* @return N/A.
|
||||
*/
|
||||
void NimBLEAdvertising::setAppearance(uint16_t appearance) {
|
||||
m_advData.appearance = appearance;
|
||||
m_advData.appearance_is_present = 1;
|
||||
m_advData.appearance = appearance;
|
||||
m_advData.appearance_is_present = 1;
|
||||
} // setAppearance
|
||||
|
||||
void NimBLEAdvertising::setAdvertisementType(uint8_t adv_type){
|
||||
m_advParams.conn_mode = adv_type;
|
||||
m_advParams.conn_mode = adv_type;
|
||||
} // setAdvertisementType
|
||||
|
||||
void NimBLEAdvertising::setMinInterval(uint16_t mininterval) {
|
||||
m_advParams.itvl_min = mininterval;
|
||||
m_advParams.itvl_min = mininterval;
|
||||
} // setMinInterval
|
||||
|
||||
void NimBLEAdvertising::setMaxInterval(uint16_t maxinterval) {
|
||||
m_advParams.itvl_max = maxinterval;
|
||||
m_advParams.itvl_max = maxinterval;
|
||||
} // setMaxInterval
|
||||
|
||||
// These are dummy functions for now for compatibility
|
||||
void NimBLEAdvertising::setMinPreferred(uint16_t mininterval) {
|
||||
//m_advData.min_interval = mininterval;
|
||||
} //
|
||||
//m_advData.min_interval = mininterval;
|
||||
} //
|
||||
|
||||
void NimBLEAdvertising::setMaxPreferred(uint16_t maxinterval) {
|
||||
//m_advData.max_interval = maxinterval;
|
||||
} //
|
||||
//m_advData.max_interval = maxinterval;
|
||||
} //
|
||||
//////////////////////////////////////////////////////////
|
||||
|
||||
void NimBLEAdvertising::setScanResponse(bool set) {
|
||||
m_scanResp = set;
|
||||
m_scanResp = set;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -116,44 +120,44 @@ void NimBLEAdvertising::setScanResponse(bool set) {
|
|||
* @param [in] connectWhitelistOnly If true, only allow connections from those on the white list.
|
||||
*/
|
||||
void NimBLEAdvertising::setScanFilter(bool scanRequestWhitelistOnly, bool connectWhitelistOnly) {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> setScanFilter: scanRequestWhitelistOnly: %d, connectWhitelistOnly: %d", scanRequestWhitelistOnly, connectWhitelistOnly);
|
||||
if (!scanRequestWhitelistOnly && !connectWhitelistOnly) {
|
||||
m_advParams.filter_policy = BLE_HCI_ADV_FILT_NONE;
|
||||
NIMBLE_LOGD(LOG_TAG, "<< setScanFilter");
|
||||
return;
|
||||
}
|
||||
if (scanRequestWhitelistOnly && !connectWhitelistOnly) {
|
||||
m_advParams.filter_policy = BLE_HCI_ADV_FILT_SCAN;
|
||||
NIMBLE_LOGD(LOG_TAG, "<< setScanFilter");
|
||||
return;
|
||||
}
|
||||
if (!scanRequestWhitelistOnly && connectWhitelistOnly) {
|
||||
m_advParams.filter_policy = BLE_HCI_ADV_FILT_CONN;
|
||||
NIMBLE_LOGD(LOG_TAG, "<< setScanFilter");
|
||||
return;
|
||||
}
|
||||
if (scanRequestWhitelistOnly && connectWhitelistOnly) {
|
||||
m_advParams.filter_policy = BLE_HCI_ADV_FILT_BOTH;
|
||||
NIMBLE_LOGD(LOG_TAG, "<< setScanFilter");
|
||||
return;
|
||||
}
|
||||
NIMBLE_LOGD(LOG_TAG, ">> setScanFilter: scanRequestWhitelistOnly: %d, connectWhitelistOnly: %d", scanRequestWhitelistOnly, connectWhitelistOnly);
|
||||
if (!scanRequestWhitelistOnly && !connectWhitelistOnly) {
|
||||
m_advParams.filter_policy = BLE_HCI_ADV_FILT_NONE;
|
||||
NIMBLE_LOGD(LOG_TAG, "<< setScanFilter");
|
||||
return;
|
||||
}
|
||||
if (scanRequestWhitelistOnly && !connectWhitelistOnly) {
|
||||
m_advParams.filter_policy = BLE_HCI_ADV_FILT_SCAN;
|
||||
NIMBLE_LOGD(LOG_TAG, "<< setScanFilter");
|
||||
return;
|
||||
}
|
||||
if (!scanRequestWhitelistOnly && connectWhitelistOnly) {
|
||||
m_advParams.filter_policy = BLE_HCI_ADV_FILT_CONN;
|
||||
NIMBLE_LOGD(LOG_TAG, "<< setScanFilter");
|
||||
return;
|
||||
}
|
||||
if (scanRequestWhitelistOnly && connectWhitelistOnly) {
|
||||
m_advParams.filter_policy = BLE_HCI_ADV_FILT_BOTH;
|
||||
NIMBLE_LOGD(LOG_TAG, "<< setScanFilter");
|
||||
return;
|
||||
}
|
||||
} // setScanFilter
|
||||
|
||||
/**
|
||||
* @brief Set the advertisement data that is to be published in a regular advertisement.
|
||||
* @param [in] advertisementData The data to be advertised.
|
||||
*/
|
||||
|
||||
|
||||
void NimBLEAdvertising::setAdvertisementData(NimBLEAdvertisementData& advertisementData) {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> setAdvertisementData");
|
||||
int rc = ble_gap_adv_set_data(
|
||||
(uint8_t*)advertisementData.getPayload().data(),
|
||||
advertisementData.getPayload().length());
|
||||
if (rc != 0) {
|
||||
NIMBLE_LOGE(LOG_TAG, "ble_gap_adv_set_data: %d %s", rc, NimBLEUtils::returnCodeToString(rc));
|
||||
}
|
||||
m_customAdvData = true; // Set the flag that indicates we are using custom advertising data.
|
||||
NIMBLE_LOGD(LOG_TAG, "<< setAdvertisementData");
|
||||
NIMBLE_LOGD(LOG_TAG, ">> setAdvertisementData");
|
||||
int rc = ble_gap_adv_set_data(
|
||||
(uint8_t*)advertisementData.getPayload().data(),
|
||||
advertisementData.getPayload().length());
|
||||
if (rc != 0) {
|
||||
NIMBLE_LOGE(LOG_TAG, "ble_gap_adv_set_data: %d %s", rc, NimBLEUtils::returnCodeToString(rc));
|
||||
}
|
||||
m_customAdvData = true; // Set the flag that indicates we are using custom advertising data.
|
||||
NIMBLE_LOGD(LOG_TAG, "<< setAdvertisementData");
|
||||
} // setAdvertisementData
|
||||
|
||||
|
||||
|
@ -162,15 +166,15 @@ void NimBLEAdvertising::setAdvertisementData(NimBLEAdvertisementData& advertisem
|
|||
* @param [in] advertisementData The data to be advertised.
|
||||
*/
|
||||
void NimBLEAdvertising::setScanResponseData(NimBLEAdvertisementData& advertisementData) {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> setScanResponseData");
|
||||
int rc = ble_gap_adv_rsp_set_data(
|
||||
(uint8_t*)advertisementData.getPayload().data(),
|
||||
advertisementData.getPayload().length());
|
||||
if (rc != 0) {
|
||||
NIMBLE_LOGE(LOG_TAG, "ble_gap_adv_rsp_set_data: %d %s", rc, NimBLEUtils::returnCodeToString(rc));
|
||||
}
|
||||
m_customScanResponseData = true; // Set the flag that indicates we are using custom scan response data.
|
||||
NIMBLE_LOGD(LOG_TAG, "<< setScanResponseData");
|
||||
NIMBLE_LOGD(LOG_TAG, ">> setScanResponseData");
|
||||
int rc = ble_gap_adv_rsp_set_data(
|
||||
(uint8_t*)advertisementData.getPayload().data(),
|
||||
advertisementData.getPayload().length());
|
||||
if (rc != 0) {
|
||||
NIMBLE_LOGE(LOG_TAG, "ble_gap_adv_rsp_set_data: %d %s", rc, NimBLEUtils::returnCodeToString(rc));
|
||||
}
|
||||
m_customScanResponseData = true; // Set the flag that indicates we are using custom scan response data.
|
||||
NIMBLE_LOGD(LOG_TAG, "<< setScanResponseData");
|
||||
} // setScanResponseData
|
||||
|
||||
|
||||
|
@ -180,186 +184,191 @@ void NimBLEAdvertising::setScanResponseData(NimBLEAdvertisementData& advertiseme
|
|||
* @return N/A.
|
||||
*/
|
||||
void NimBLEAdvertising::start() {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> Advertising start: customAdvData: %d, customScanResponseData: %d", m_customAdvData, m_customScanResponseData);
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, ">> Advertising start: customAdvData: %d, customScanResponseData: %d", m_customAdvData, m_customScanResponseData);
|
||||
|
||||
// If Host is not synced we cannot start advertising.
|
||||
if(!NimBLEDevice::m_synced) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Host reset, wait for sync.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(NimBLEDevice::createServer()->getConnectedCount() >= NIMBLE_MAX_CONNECTIONS) {
|
||||
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
NimBLEServer* pServer = NimBLEDevice::createServer();
|
||||
if(!pServer->m_gattsStarted){
|
||||
pServer->start();
|
||||
} else if(pServer->getConnectedCount() >= NIMBLE_MAX_CONNECTIONS) {
|
||||
NIMBLE_LOGW(LOG_TAG, "Max connections reached - not advertising");
|
||||
return;
|
||||
}
|
||||
|
||||
int numServices = m_serviceUUIDs.size();
|
||||
#endif
|
||||
|
||||
int numServices = m_serviceUUIDs.size();
|
||||
int rc = 0;
|
||||
uint8_t addressType;
|
||||
uint8_t payloadLen = 3; //start with 3 bytes for the flags data
|
||||
|
||||
uint8_t payloadLen = 3; //start with 3 bytes for the flags data
|
||||
|
||||
// If already advertising just return
|
||||
if(ble_gap_adv_active()) {
|
||||
return;
|
||||
}
|
||||
|
||||
NimBLEServer* pServer = NimBLEDevice::createServer();
|
||||
if(!pServer->m_gattsStarted){
|
||||
pServer->start();
|
||||
}
|
||||
|
||||
if (!m_customAdvData && !m_advSvcsSet && numServices > 0) {
|
||||
for (int i = 0; i < numServices; i++) {
|
||||
if(m_serviceUUIDs[i].getNative()->u.type == BLE_UUID_TYPE_16) {
|
||||
int add = (m_advData.num_uuids16 > 0) ? 2 : 4;
|
||||
if((payloadLen + add) > 31){
|
||||
m_advData.uuids16_is_complete = 0;
|
||||
continue;
|
||||
}
|
||||
payloadLen += add;
|
||||
|
||||
if(nullptr == (m_advData.uuids16 = (ble_uuid16_t*)realloc(m_advData.uuids16,
|
||||
(m_advData.num_uuids16 + 1) * sizeof(ble_uuid16_t))))
|
||||
|
||||
if (!m_customAdvData && !m_advSvcsSet && numServices > 0) {
|
||||
for (int i = 0; i < numServices; i++) {
|
||||
if(m_serviceUUIDs[i].getNative()->u.type == BLE_UUID_TYPE_16) {
|
||||
int add = (m_advData.num_uuids16 > 0) ? 2 : 4;
|
||||
if((payloadLen + add) > 31){
|
||||
m_advData.uuids16_is_complete = 0;
|
||||
continue;
|
||||
}
|
||||
payloadLen += add;
|
||||
|
||||
if(nullptr == (m_advData.uuids16 = (ble_uuid16_t*)realloc(m_advData.uuids16,
|
||||
(m_advData.num_uuids16 + 1) * sizeof(ble_uuid16_t))))
|
||||
{
|
||||
NIMBLE_LOGE(LOG_TAG, "Error, no mem");
|
||||
abort();
|
||||
}
|
||||
memcpy(&m_advData.uuids16[m_advData.num_uuids16].value,
|
||||
memcpy(&m_advData.uuids16[m_advData.num_uuids16].value,
|
||||
&m_serviceUUIDs[i].getNative()->u16.value, sizeof(uint16_t));
|
||||
|
||||
|
||||
m_advData.uuids16[m_advData.num_uuids16].u.type = BLE_UUID_TYPE_16;
|
||||
m_advData.uuids16_is_complete = 1;
|
||||
m_advData.num_uuids16++;
|
||||
}
|
||||
if(m_serviceUUIDs[i].getNative()->u.type == BLE_UUID_TYPE_32) {
|
||||
int add = (m_advData.num_uuids32 > 0) ? 4 : 6;
|
||||
if((payloadLen + add) > 31){
|
||||
m_advData.uuids32_is_complete = 0;
|
||||
continue;
|
||||
}
|
||||
payloadLen += add;
|
||||
|
||||
}
|
||||
if(m_serviceUUIDs[i].getNative()->u.type == BLE_UUID_TYPE_32) {
|
||||
int add = (m_advData.num_uuids32 > 0) ? 4 : 6;
|
||||
if((payloadLen + add) > 31){
|
||||
m_advData.uuids32_is_complete = 0;
|
||||
continue;
|
||||
}
|
||||
payloadLen += add;
|
||||
|
||||
if(nullptr == (m_advData.uuids32 = (ble_uuid32_t*)realloc(m_advData.uuids32,
|
||||
(m_advData.num_uuids32 + 1) * sizeof(ble_uuid32_t))))
|
||||
(m_advData.num_uuids32 + 1) * sizeof(ble_uuid32_t))))
|
||||
{
|
||||
NIMBLE_LOGE(LOG_TAG, "Error, no mem");
|
||||
abort();
|
||||
}
|
||||
memcpy(&m_advData.uuids32[m_advData.num_uuids32].value,
|
||||
memcpy(&m_advData.uuids32[m_advData.num_uuids32].value,
|
||||
&m_serviceUUIDs[i].getNative()->u32.value, sizeof(uint32_t));
|
||||
|
||||
m_advData.uuids32[m_advData.num_uuids32].u.type = BLE_UUID_TYPE_32;
|
||||
|
||||
m_advData.uuids32[m_advData.num_uuids32].u.type = BLE_UUID_TYPE_32;
|
||||
m_advData.uuids32_is_complete = 1;
|
||||
m_advData.num_uuids32++;
|
||||
}
|
||||
if(m_serviceUUIDs[i].getNative()->u.type == BLE_UUID_TYPE_128){
|
||||
int add = (m_advData.num_uuids128 > 0) ? 16 : 18;
|
||||
if((payloadLen + add) > 31){
|
||||
m_advData.uuids128_is_complete = 0;
|
||||
continue;
|
||||
}
|
||||
payloadLen += add;
|
||||
|
||||
if(nullptr == (m_advData.uuids128 = (ble_uuid128_t*)realloc(m_advData.uuids128,
|
||||
}
|
||||
if(m_serviceUUIDs[i].getNative()->u.type == BLE_UUID_TYPE_128){
|
||||
int add = (m_advData.num_uuids128 > 0) ? 16 : 18;
|
||||
if((payloadLen + add) > 31){
|
||||
m_advData.uuids128_is_complete = 0;
|
||||
continue;
|
||||
}
|
||||
payloadLen += add;
|
||||
|
||||
if(nullptr == (m_advData.uuids128 = (ble_uuid128_t*)realloc(m_advData.uuids128,
|
||||
(m_advData.num_uuids128 + 1) * sizeof(ble_uuid128_t)))) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Error, no mem");
|
||||
abort();
|
||||
}
|
||||
memcpy(&m_advData.uuids128[m_advData.num_uuids128].value,
|
||||
memcpy(&m_advData.uuids128[m_advData.num_uuids128].value,
|
||||
&m_serviceUUIDs[i].getNative()->u128.value, 16);
|
||||
|
||||
m_advData.uuids128[m_advData.num_uuids128].u.type = BLE_UUID_TYPE_128;
|
||||
|
||||
m_advData.uuids128[m_advData.num_uuids128].u.type = BLE_UUID_TYPE_128;
|
||||
m_advData.uuids128_is_complete = 1;
|
||||
m_advData.num_uuids128++;
|
||||
}
|
||||
}
|
||||
|
||||
// check if there is room for the name, if not put it in scan data
|
||||
if((payloadLen + m_advData.name_len) > 29) {
|
||||
if(m_scanResp){
|
||||
m_scanData.name = m_advData.name;
|
||||
m_scanData.name_len = m_advData.name_len;
|
||||
m_scanData.name_is_complete = m_advData.name_is_complete;
|
||||
m_advData.name = nullptr;
|
||||
m_advData.name_len = 0;
|
||||
} else {
|
||||
// if not using scan response just cut the name down
|
||||
// leaving 2 bytes for the data specifier.
|
||||
m_advData.name_len = (29 - payloadLen);
|
||||
}
|
||||
m_advData.name_is_complete = 0;
|
||||
}
|
||||
|
||||
if(m_advData.name_len > 0) {
|
||||
payloadLen += (m_advData.name_len + 2);
|
||||
}
|
||||
|
||||
if(m_scanResp) {
|
||||
// name length + type byte + length byte + tx power type + length + data
|
||||
if((m_scanData.name_len + 5) > 31) {
|
||||
// prioritize name data over tx power
|
||||
m_scanData.tx_pwr_lvl_is_present = 0;
|
||||
m_scanData.tx_pwr_lvl = 0;
|
||||
// limit name to 29 to leave room for the data specifiers
|
||||
if(m_scanData.name_len > 29) {
|
||||
m_scanData.name_len = 29;
|
||||
m_scanData.name_is_complete = false;
|
||||
}
|
||||
}
|
||||
|
||||
rc = ble_gap_adv_rsp_set_fields(&m_scanData);
|
||||
if (rc != 0) {
|
||||
NIMBLE_LOGE(LOG_TAG, "error setting scan response data; rc=%d, %s", rc, NimBLEUtils::returnCodeToString(rc));
|
||||
abort();
|
||||
}
|
||||
// if not using scan response and there is room,
|
||||
// throw the tx power data into the advertisment
|
||||
}
|
||||
}
|
||||
|
||||
// check if there is room for the name, if not put it in scan data
|
||||
if((payloadLen + m_advData.name_len) > 29) {
|
||||
if(m_scanResp){
|
||||
m_scanData.name = m_advData.name;
|
||||
m_scanData.name_len = m_advData.name_len;
|
||||
m_scanData.name_is_complete = m_advData.name_is_complete;
|
||||
m_advData.name = nullptr;
|
||||
m_advData.name_len = 0;
|
||||
} else {
|
||||
// if not using scan response just cut the name down
|
||||
// leaving 2 bytes for the data specifier.
|
||||
m_advData.name_len = (29 - payloadLen);
|
||||
}
|
||||
m_advData.name_is_complete = 0;
|
||||
}
|
||||
|
||||
if(m_advData.name_len > 0) {
|
||||
payloadLen += (m_advData.name_len + 2);
|
||||
}
|
||||
|
||||
if(m_scanResp) {
|
||||
// name length + type byte + length byte + tx power type + length + data
|
||||
if((m_scanData.name_len + 5) > 31) {
|
||||
// prioritize name data over tx power
|
||||
m_scanData.tx_pwr_lvl_is_present = 0;
|
||||
m_scanData.tx_pwr_lvl = 0;
|
||||
// limit name to 29 to leave room for the data specifiers
|
||||
if(m_scanData.name_len > 29) {
|
||||
m_scanData.name_len = 29;
|
||||
m_scanData.name_is_complete = false;
|
||||
}
|
||||
}
|
||||
|
||||
rc = ble_gap_adv_rsp_set_fields(&m_scanData);
|
||||
if (rc != 0) {
|
||||
NIMBLE_LOGE(LOG_TAG, "error setting scan response data; rc=%d, %s", rc, NimBLEUtils::returnCodeToString(rc));
|
||||
abort();
|
||||
}
|
||||
// if not using scan response and there is room,
|
||||
// throw the tx power data into the advertisment
|
||||
} else if (payloadLen < 29) {
|
||||
m_advData.tx_pwr_lvl_is_present = 1;
|
||||
m_advData.tx_pwr_lvl = NimBLEDevice::getPower();
|
||||
}
|
||||
|
||||
m_advData.tx_pwr_lvl_is_present = 1;
|
||||
m_advData.tx_pwr_lvl = NimBLEDevice::getPower();
|
||||
}
|
||||
|
||||
rc = ble_gap_adv_set_fields(&m_advData);
|
||||
if (rc != 0) {
|
||||
NIMBLE_LOGE(LOG_TAG, "error setting advertisement data; rc=%d, %s", rc, NimBLEUtils::returnCodeToString(rc));
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
if(m_advData.num_uuids128 > 0) {
|
||||
free(m_advData.uuids128);
|
||||
m_advData.uuids128 = nullptr;
|
||||
m_advData.num_uuids128 = 0;
|
||||
}
|
||||
|
||||
|
||||
if(m_advData.num_uuids32 > 0) {
|
||||
free(m_advData.uuids32);
|
||||
m_advData.uuids32 = nullptr;
|
||||
m_advData.num_uuids32 = 0;
|
||||
}
|
||||
|
||||
|
||||
if(m_advData.num_uuids16 > 0) {
|
||||
free(m_advData.uuids16);
|
||||
m_advData.uuids16 = nullptr;
|
||||
m_advData.num_uuids16 = 0;
|
||||
}
|
||||
|
||||
|
||||
m_advSvcsSet = true;
|
||||
}
|
||||
|
||||
|
||||
rc = ble_hs_id_infer_auto(0, &addressType);
|
||||
if (rc != 0) {
|
||||
NIMBLE_LOGC(LOG_TAG, "Error determining address type; rc=%d, %s", rc, NimBLEUtils::returnCodeToString(rc));
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
rc = ble_gap_adv_start(addressType, NULL, BLE_HS_FOREVER,
|
||||
&m_advParams, NimBLEServer::handleGapEvent, NimBLEDevice::createServer()); //get a reference to the server (does not create a new one)
|
||||
#else
|
||||
rc = ble_gap_adv_start(addressType, NULL, BLE_HS_FOREVER,
|
||||
&m_advParams, NULL,NULL);
|
||||
#endif
|
||||
if (rc != 0) {
|
||||
NIMBLE_LOGC(LOG_TAG, "Error enabling advertising; rc=%d, %s", rc, NimBLEUtils::returnCodeToString(rc));
|
||||
abort();
|
||||
}
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "<< Advertising start");
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "<< Advertising start");
|
||||
} // start
|
||||
|
||||
|
||||
|
@ -369,35 +378,35 @@ void NimBLEAdvertising::start() {
|
|||
* @return N/A.
|
||||
*/
|
||||
void NimBLEAdvertising::stop() {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> stop");
|
||||
int rc = ble_gap_adv_stop();
|
||||
if (rc != 0 && rc != BLE_HS_EALREADY) {
|
||||
NIMBLE_LOGE(LOG_TAG, "ble_gap_adv_stop rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
|
||||
return;
|
||||
}
|
||||
NIMBLE_LOGD(LOG_TAG, ">> stop");
|
||||
int rc = ble_gap_adv_stop();
|
||||
if (rc != 0 && rc != BLE_HS_EALREADY) {
|
||||
NIMBLE_LOGE(LOG_TAG, "ble_gap_adv_stop rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
|
||||
return;
|
||||
}
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "<< stop");
|
||||
NIMBLE_LOGD(LOG_TAG, "<< stop");
|
||||
} // stop
|
||||
|
||||
|
||||
/**
|
||||
* Host reset seems to clear advertising data,
|
||||
* Host reset seems to clear advertising data,
|
||||
* we need clear the flag so it reloads it.
|
||||
*/
|
||||
*/
|
||||
void NimBLEAdvertising::onHostReset() {
|
||||
m_advSvcsSet = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Add data to the payload to be advertised.
|
||||
* @param [in] data The data to be added to the payload.
|
||||
*/
|
||||
void NimBLEAdvertisementData::addData(const std::string &data) {
|
||||
if ((m_payload.length() + data.length()) > BLE_HS_ADV_MAX_SZ) {
|
||||
return;
|
||||
}
|
||||
m_payload.append(data);
|
||||
if ((m_payload.length() + data.length()) > BLE_HS_ADV_MAX_SZ) {
|
||||
return;
|
||||
}
|
||||
m_payload.append(data);
|
||||
} // addData
|
||||
|
||||
|
||||
|
@ -409,10 +418,10 @@ void NimBLEAdvertisementData::addData(const std::string &data) {
|
|||
* https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.gap.appearance.xml
|
||||
*/
|
||||
void NimBLEAdvertisementData::setAppearance(uint16_t appearance) {
|
||||
char cdata[2];
|
||||
cdata[0] = 3;
|
||||
cdata[1] = BLE_HS_ADV_TYPE_APPEARANCE; // 0x19
|
||||
addData(std::string(cdata, 2) + std::string((char*) &appearance, 2));
|
||||
char cdata[2];
|
||||
cdata[0] = 3;
|
||||
cdata[1] = BLE_HS_ADV_TYPE_APPEARANCE; // 0x19
|
||||
addData(std::string(cdata, 2) + std::string((char*) &appearance, 2));
|
||||
} // setAppearance
|
||||
|
||||
|
||||
|
@ -421,35 +430,35 @@ void NimBLEAdvertisementData::setAppearance(uint16_t appearance) {
|
|||
* @param [in] uuid The single service to advertise.
|
||||
*/
|
||||
void NimBLEAdvertisementData::setCompleteServices(const NimBLEUUID &uuid) {
|
||||
char cdata[2];
|
||||
switch (uuid.bitSize()) {
|
||||
case 16: {
|
||||
// [Len] [0x02] [LL] [HH]
|
||||
cdata[0] = 3;
|
||||
cdata[1] = BLE_HS_ADV_TYPE_COMP_UUIDS16; // 0x03
|
||||
addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->u16.value, 2));
|
||||
break;
|
||||
}
|
||||
char cdata[2];
|
||||
switch (uuid.bitSize()) {
|
||||
case 16: {
|
||||
// [Len] [0x02] [LL] [HH]
|
||||
cdata[0] = 3;
|
||||
cdata[1] = BLE_HS_ADV_TYPE_COMP_UUIDS16; // 0x03
|
||||
addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->u16.value, 2));
|
||||
break;
|
||||
}
|
||||
|
||||
case 32: {
|
||||
// [Len] [0x04] [LL] [LL] [HH] [HH]
|
||||
cdata[0] = 5;
|
||||
cdata[1] = BLE_HS_ADV_TYPE_COMP_UUIDS32; // 0x05
|
||||
addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->u32.value, 4));
|
||||
break;
|
||||
}
|
||||
case 32: {
|
||||
// [Len] [0x04] [LL] [LL] [HH] [HH]
|
||||
cdata[0] = 5;
|
||||
cdata[1] = BLE_HS_ADV_TYPE_COMP_UUIDS32; // 0x05
|
||||
addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->u32.value, 4));
|
||||
break;
|
||||
}
|
||||
|
||||
case 128: {
|
||||
// [Len] [0x04] [0] [1] ... [15]
|
||||
cdata[0] = 17;
|
||||
cdata[1] = BLE_HS_ADV_TYPE_COMP_UUIDS128; // 0x07
|
||||
addData(std::string(cdata, 2) + std::string((char*) uuid.getNative()->u128.value, 16));
|
||||
break;
|
||||
}
|
||||
case 128: {
|
||||
// [Len] [0x04] [0] [1] ... [15]
|
||||
cdata[0] = 17;
|
||||
cdata[1] = BLE_HS_ADV_TYPE_COMP_UUIDS128; // 0x07
|
||||
addData(std::string(cdata, 2) + std::string((char*) uuid.getNative()->u128.value, 16));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
} // setCompleteServices
|
||||
|
||||
|
||||
|
@ -463,18 +472,18 @@ void NimBLEAdvertisementData::setCompleteServices(const NimBLEUUID &uuid) {
|
|||
* * ESP_BLE_ADV_FLAG_DMT_CONTROLLER_SPT
|
||||
* * ESP_BLE_ADV_FLAG_DMT_HOST_SPT
|
||||
* * ESP_BLE_ADV_FLAG_NON_LIMIT_DISC
|
||||
* *
|
||||
* *
|
||||
* * ****THESE ARE SUPPORTED****
|
||||
* * BLE_HS_ADV_F_DISC_LTD
|
||||
* * BLE_HS_ADV_F_DISC_GEN
|
||||
* * BLE_HS_ADV_F_BREDR_UNSUP - must always use with NimBLE
|
||||
*/
|
||||
void NimBLEAdvertisementData::setFlags(uint8_t flag) {
|
||||
char cdata[3];
|
||||
cdata[0] = 2;
|
||||
cdata[1] = BLE_HS_ADV_TYPE_FLAGS; // 0x01
|
||||
cdata[2] = flag | BLE_HS_ADV_F_BREDR_UNSUP;
|
||||
addData(std::string(cdata, 3));
|
||||
char cdata[3];
|
||||
cdata[0] = 2;
|
||||
cdata[1] = BLE_HS_ADV_TYPE_FLAGS; // 0x01
|
||||
cdata[2] = flag | BLE_HS_ADV_F_BREDR_UNSUP;
|
||||
addData(std::string(cdata, 3));
|
||||
} // setFlag
|
||||
|
||||
|
||||
|
@ -483,12 +492,12 @@ void NimBLEAdvertisementData::setFlags(uint8_t flag) {
|
|||
* @param [in] data Manufacturer data.
|
||||
*/
|
||||
void NimBLEAdvertisementData::setManufacturerData(const std::string &data) {
|
||||
NIMBLE_LOGD("NimBLEAdvertisementData", ">> setManufacturerData");
|
||||
char cdata[2];
|
||||
cdata[0] = data.length() + 1;
|
||||
cdata[1] = BLE_HS_ADV_TYPE_MFG_DATA ; // 0xff
|
||||
addData(std::string(cdata, 2) + data);
|
||||
NIMBLE_LOGD("NimBLEAdvertisementData", "<< setManufacturerData");
|
||||
NIMBLE_LOGD("NimBLEAdvertisementData", ">> setManufacturerData");
|
||||
char cdata[2];
|
||||
cdata[0] = data.length() + 1;
|
||||
cdata[1] = BLE_HS_ADV_TYPE_MFG_DATA ; // 0xff
|
||||
addData(std::string(cdata, 2) + data);
|
||||
NIMBLE_LOGD("NimBLEAdvertisementData", "<< setManufacturerData");
|
||||
} // setManufacturerData
|
||||
|
||||
|
||||
|
@ -497,12 +506,12 @@ void NimBLEAdvertisementData::setManufacturerData(const std::string &data) {
|
|||
* @param [in] The complete name of the device.
|
||||
*/
|
||||
void NimBLEAdvertisementData::setName(const std::string &name) {
|
||||
NIMBLE_LOGD("NimBLEAdvertisementData", ">> setName: %s", name.c_str());
|
||||
char cdata[2];
|
||||
cdata[0] = name.length() + 1;
|
||||
cdata[1] = BLE_HS_ADV_TYPE_COMP_NAME; // 0x09
|
||||
addData(std::string(cdata, 2) + name);
|
||||
NIMBLE_LOGD("NimBLEAdvertisementData", "<< setName");
|
||||
NIMBLE_LOGD("NimBLEAdvertisementData", ">> setName: %s", name.c_str());
|
||||
char cdata[2];
|
||||
cdata[0] = name.length() + 1;
|
||||
cdata[1] = BLE_HS_ADV_TYPE_COMP_NAME; // 0x09
|
||||
addData(std::string(cdata, 2) + name);
|
||||
NIMBLE_LOGD("NimBLEAdvertisementData", "<< setName");
|
||||
} // setName
|
||||
|
||||
|
||||
|
@ -511,35 +520,35 @@ void NimBLEAdvertisementData::setName(const std::string &name) {
|
|||
* @param [in] uuid The single service to advertise.
|
||||
*/
|
||||
void NimBLEAdvertisementData::setPartialServices(const NimBLEUUID &uuid) {
|
||||
char cdata[2];
|
||||
switch (uuid.bitSize()) {
|
||||
case 16: {
|
||||
// [Len] [0x02] [LL] [HH]
|
||||
cdata[0] = 3;
|
||||
cdata[1] = BLE_HS_ADV_TYPE_INCOMP_UUIDS16; // 0x02
|
||||
addData(std::string(cdata, 2) + std::string((char *) &uuid.getNative()->u16.value, 2));
|
||||
break;
|
||||
}
|
||||
char cdata[2];
|
||||
switch (uuid.bitSize()) {
|
||||
case 16: {
|
||||
// [Len] [0x02] [LL] [HH]
|
||||
cdata[0] = 3;
|
||||
cdata[1] = BLE_HS_ADV_TYPE_INCOMP_UUIDS16; // 0x02
|
||||
addData(std::string(cdata, 2) + std::string((char *) &uuid.getNative()->u16.value, 2));
|
||||
break;
|
||||
}
|
||||
|
||||
case 32: {
|
||||
// [Len] [0x04] [LL] [LL] [HH] [HH]
|
||||
cdata[0] = 5;
|
||||
cdata[1] = BLE_HS_ADV_TYPE_INCOMP_UUIDS32; // 0x04
|
||||
addData(std::string(cdata, 2) + std::string((char *) &uuid.getNative()->u32.value, 4));
|
||||
break;
|
||||
}
|
||||
case 32: {
|
||||
// [Len] [0x04] [LL] [LL] [HH] [HH]
|
||||
cdata[0] = 5;
|
||||
cdata[1] = BLE_HS_ADV_TYPE_INCOMP_UUIDS32; // 0x04
|
||||
addData(std::string(cdata, 2) + std::string((char *) &uuid.getNative()->u32.value, 4));
|
||||
break;
|
||||
}
|
||||
|
||||
case 128: {
|
||||
// [Len] [0x04] [0] [1] ... [15]
|
||||
cdata[0] = 17;
|
||||
cdata[1] = BLE_HS_ADV_TYPE_INCOMP_UUIDS128; // 0x06
|
||||
addData(std::string(cdata, 2) + std::string((char *) &uuid.getNative()->u128.value, 16));
|
||||
break;
|
||||
}
|
||||
case 128: {
|
||||
// [Len] [0x04] [0] [1] ... [15]
|
||||
cdata[0] = 17;
|
||||
cdata[1] = BLE_HS_ADV_TYPE_INCOMP_UUIDS128; // 0x06
|
||||
addData(std::string(cdata, 2) + std::string((char *) &uuid.getNative()->u128.value, 16));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
} // setPartialServices
|
||||
|
||||
|
||||
|
@ -549,35 +558,35 @@ void NimBLEAdvertisementData::setPartialServices(const NimBLEUUID &uuid) {
|
|||
* @param [in] data The data to be associated with the service data advert.
|
||||
*/
|
||||
void NimBLEAdvertisementData::setServiceData(const NimBLEUUID &uuid, const std::string &data) {
|
||||
char cdata[2];
|
||||
switch (uuid.bitSize()) {
|
||||
case 16: {
|
||||
// [Len] [0x16] [UUID16] data
|
||||
cdata[0] = data.length() + 3;
|
||||
cdata[1] = BLE_HS_ADV_TYPE_SVC_DATA_UUID16; // 0x16
|
||||
addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->u16.value, 2) + data);
|
||||
break;
|
||||
}
|
||||
char cdata[2];
|
||||
switch (uuid.bitSize()) {
|
||||
case 16: {
|
||||
// [Len] [0x16] [UUID16] data
|
||||
cdata[0] = data.length() + 3;
|
||||
cdata[1] = BLE_HS_ADV_TYPE_SVC_DATA_UUID16; // 0x16
|
||||
addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->u16.value, 2) + data);
|
||||
break;
|
||||
}
|
||||
|
||||
case 32: {
|
||||
// [Len] [0x20] [UUID32] data
|
||||
cdata[0] = data.length() + 5;
|
||||
cdata[1] = BLE_HS_ADV_TYPE_SVC_DATA_UUID32; // 0x20
|
||||
addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->u32.value, 4) + data);
|
||||
break;
|
||||
}
|
||||
case 32: {
|
||||
// [Len] [0x20] [UUID32] data
|
||||
cdata[0] = data.length() + 5;
|
||||
cdata[1] = BLE_HS_ADV_TYPE_SVC_DATA_UUID32; // 0x20
|
||||
addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->u32.value, 4) + data);
|
||||
break;
|
||||
}
|
||||
|
||||
case 128: {
|
||||
// [Len] [0x21] [UUID128] data
|
||||
cdata[0] = data.length() + 17;
|
||||
cdata[1] = BLE_HS_ADV_TYPE_SVC_DATA_UUID128; // 0x21
|
||||
addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->u128.value, 16) + data);
|
||||
break;
|
||||
}
|
||||
case 128: {
|
||||
// [Len] [0x21] [UUID128] data
|
||||
cdata[0] = data.length() + 17;
|
||||
cdata[1] = BLE_HS_ADV_TYPE_SVC_DATA_UUID128; // 0x21
|
||||
addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->u128.value, 16) + data);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
} // setServiceData
|
||||
|
||||
|
||||
|
@ -586,12 +595,12 @@ void NimBLEAdvertisementData::setServiceData(const NimBLEUUID &uuid, const std::
|
|||
* @param [in] The short name of the device.
|
||||
*/
|
||||
void NimBLEAdvertisementData::setShortName(const std::string &name) {
|
||||
NIMBLE_LOGD("NimBLEAdvertisementData", ">> setShortName: %s", name.c_str());
|
||||
char cdata[2];
|
||||
cdata[0] = name.length() + 1;
|
||||
cdata[1] = BLE_HS_ADV_TYPE_INCOMP_NAME; // 0x08
|
||||
addData(std::string(cdata, 2) + name);
|
||||
NIMBLE_LOGD("NimBLEAdvertisementData", "<< setShortName");
|
||||
NIMBLE_LOGD("NimBLEAdvertisementData", ">> setShortName: %s", name.c_str());
|
||||
char cdata[2];
|
||||
cdata[0] = name.length() + 1;
|
||||
cdata[1] = BLE_HS_ADV_TYPE_INCOMP_NAME; // 0x08
|
||||
addData(std::string(cdata, 2) + name);
|
||||
NIMBLE_LOGD("NimBLEAdvertisementData", "<< setShortName");
|
||||
} // setShortName
|
||||
|
||||
|
||||
|
@ -600,7 +609,8 @@ void NimBLEAdvertisementData::setShortName(const std::string &name) {
|
|||
* @return The payload that is to be advertised.
|
||||
*/
|
||||
std::string NimBLEAdvertisementData::getPayload() {
|
||||
return m_payload;
|
||||
return m_payload;
|
||||
} // getPayload
|
||||
|
||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
#endif /* CONFIG_BT_ENABLED */
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on March 3, 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLEAdvertising.h
|
||||
|
@ -17,6 +17,9 @@
|
|||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
|
||||
|
||||
#include "host/ble_gap.h"
|
||||
/**** FIX COMPILATION ****/
|
||||
#undef min
|
||||
|
@ -42,24 +45,24 @@
|
|||
* @brief Advertisement data set by the programmer to be published by the %BLE server.
|
||||
*/
|
||||
class NimBLEAdvertisementData {
|
||||
// Only a subset of the possible BLE architected advertisement fields are currently exposed. Others will
|
||||
// be exposed on demand/request or as time permits.
|
||||
//
|
||||
// Only a subset of the possible BLE architected advertisement fields are currently exposed. Others will
|
||||
// be exposed on demand/request or as time permits.
|
||||
//
|
||||
public:
|
||||
void setAppearance(uint16_t appearance);
|
||||
void setCompleteServices(const NimBLEUUID &uuid);
|
||||
void setFlags(uint8_t);
|
||||
void setManufacturerData(const std::string &data);
|
||||
void setName(const std::string &name);
|
||||
void setPartialServices(const NimBLEUUID &uuid);
|
||||
void setServiceData(const NimBLEUUID &uuid, const std::string &data);
|
||||
void setShortName(const std::string &name);
|
||||
void addData(const std::string &data); // Add data to the payload.
|
||||
std::string getPayload(); // Retrieve the current advert payload.
|
||||
void setAppearance(uint16_t appearance);
|
||||
void setCompleteServices(const NimBLEUUID &uuid);
|
||||
void setFlags(uint8_t);
|
||||
void setManufacturerData(const std::string &data);
|
||||
void setName(const std::string &name);
|
||||
void setPartialServices(const NimBLEUUID &uuid);
|
||||
void setServiceData(const NimBLEUUID &uuid, const std::string &data);
|
||||
void setShortName(const std::string &name);
|
||||
void addData(const std::string &data); // Add data to the payload.
|
||||
std::string getPayload(); // Retrieve the current advert payload.
|
||||
|
||||
private:
|
||||
friend class NimBLEAdvertising;
|
||||
std::string m_payload; // The payload of the advertisement.
|
||||
friend class NimBLEAdvertising;
|
||||
std::string m_payload; // The payload of the advertisement.
|
||||
}; // NimBLEAdvertisementData
|
||||
|
||||
|
||||
|
@ -70,36 +73,40 @@ private:
|
|||
*/
|
||||
class NimBLEAdvertising {
|
||||
public:
|
||||
NimBLEAdvertising();
|
||||
void addServiceUUID(const NimBLEUUID &serviceUUID);
|
||||
void addServiceUUID(const char* serviceUUID);
|
||||
void start();
|
||||
void stop();
|
||||
void setAppearance(uint16_t appearance);
|
||||
NimBLEAdvertising();
|
||||
void addServiceUUID(const NimBLEUUID &serviceUUID);
|
||||
void addServiceUUID(const char* serviceUUID);
|
||||
void start();
|
||||
void stop();
|
||||
void setAppearance(uint16_t appearance);
|
||||
void setAdvertisementType(uint8_t adv_type);
|
||||
void setMaxInterval(uint16_t maxinterval);
|
||||
void setMinInterval(uint16_t mininterval);
|
||||
void setAdvertisementData(NimBLEAdvertisementData& advertisementData);
|
||||
void setScanFilter(bool scanRequertWhitelistOnly, bool connectWhitelistOnly);
|
||||
void setScanResponseData(NimBLEAdvertisementData& advertisementData);
|
||||
void setPrivateAddress(uint8_t type = BLE_ADDR_RANDOM);
|
||||
void setMaxInterval(uint16_t maxinterval);
|
||||
void setMinInterval(uint16_t mininterval);
|
||||
void setAdvertisementData(NimBLEAdvertisementData& advertisementData);
|
||||
void setScanFilter(bool scanRequertWhitelistOnly, bool connectWhitelistOnly);
|
||||
void setScanResponseData(NimBLEAdvertisementData& advertisementData);
|
||||
void setPrivateAddress(uint8_t type = BLE_ADDR_RANDOM);
|
||||
|
||||
void setMinPreferred(uint16_t);
|
||||
void setMaxPreferred(uint16_t);
|
||||
void setScanResponse(bool);
|
||||
void setMinPreferred(uint16_t);
|
||||
void setMaxPreferred(uint16_t);
|
||||
void setScanResponse(bool);
|
||||
|
||||
private:
|
||||
friend class NimBLEDevice;
|
||||
|
||||
void onHostReset();
|
||||
ble_hs_adv_fields m_advData;
|
||||
ble_hs_adv_fields m_scanData;
|
||||
ble_gap_adv_params m_advParams;
|
||||
std::vector<NimBLEUUID> m_serviceUUIDs;
|
||||
bool m_customAdvData = false; // Are we using custom advertising data?
|
||||
bool m_customScanResponseData = false; // Are we using custom scan response data?
|
||||
bool m_scanResp = true;
|
||||
|
||||
ble_hs_adv_fields m_advData;
|
||||
ble_hs_adv_fields m_scanData;
|
||||
ble_gap_adv_params m_advParams;
|
||||
std::vector<NimBLEUUID> m_serviceUUIDs;
|
||||
bool m_customAdvData = false; // Are we using custom advertising data?
|
||||
bool m_customScanResponseData = false; // Are we using custom scan response data?
|
||||
bool m_scanResp = true;
|
||||
bool m_advSvcsSet = false;
|
||||
|
||||
};
|
||||
|
||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
#endif /* CONFIG_BT_ENABLED */
|
||||
#endif /* MAIN_BLEADVERTISING_H_ */
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on March 15 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLEBeacon.cpp
|
||||
|
@ -13,6 +13,7 @@
|
|||
*/
|
||||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include <string.h>
|
||||
#include "NimBLEBeacon.h"
|
||||
#include "NimBLELog.h"
|
||||
|
@ -22,72 +23,71 @@
|
|||
static const char* LOG_TAG = "NimBLEBeacon";
|
||||
|
||||
NimBLEBeacon::NimBLEBeacon() {
|
||||
m_beaconData.manufacturerId = 0x4c00;
|
||||
m_beaconData.subType = 0x02;
|
||||
m_beaconData.subTypeLength = 0x15;
|
||||
m_beaconData.major = 0;
|
||||
m_beaconData.minor = 0;
|
||||
m_beaconData.signalPower = 0;
|
||||
memset(m_beaconData.proximityUUID, 0, sizeof(m_beaconData.proximityUUID));
|
||||
m_beaconData.manufacturerId = 0x4c00;
|
||||
m_beaconData.subType = 0x02;
|
||||
m_beaconData.subTypeLength = 0x15;
|
||||
m_beaconData.major = 0;
|
||||
m_beaconData.minor = 0;
|
||||
m_beaconData.signalPower = 0;
|
||||
memset(m_beaconData.proximityUUID, 0, sizeof(m_beaconData.proximityUUID));
|
||||
} // NimBLEBeacon
|
||||
|
||||
std::string NimBLEBeacon::getData() {
|
||||
return std::string((char*) &m_beaconData, sizeof(m_beaconData));
|
||||
return std::string((char*) &m_beaconData, sizeof(m_beaconData));
|
||||
} // getData
|
||||
|
||||
uint16_t NimBLEBeacon::getMajor() {
|
||||
return m_beaconData.major;
|
||||
return m_beaconData.major;
|
||||
}
|
||||
|
||||
uint16_t NimBLEBeacon::getManufacturerId() {
|
||||
return m_beaconData.manufacturerId;
|
||||
return m_beaconData.manufacturerId;
|
||||
}
|
||||
|
||||
uint16_t NimBLEBeacon::getMinor() {
|
||||
return m_beaconData.minor;
|
||||
return m_beaconData.minor;
|
||||
}
|
||||
|
||||
NimBLEUUID NimBLEBeacon::getProximityUUID() {
|
||||
return NimBLEUUID(m_beaconData.proximityUUID, 16, false);
|
||||
return NimBLEUUID(m_beaconData.proximityUUID, 16, false);
|
||||
}
|
||||
|
||||
int8_t NimBLEBeacon::getSignalPower() {
|
||||
return m_beaconData.signalPower;
|
||||
return m_beaconData.signalPower;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the raw data for the beacon record.
|
||||
*/
|
||||
void NimBLEBeacon::setData(const std::string &data) {
|
||||
if (data.length() != sizeof(m_beaconData)) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Unable to set the data ... length passed in was %d and expected %d",
|
||||
if (data.length() != sizeof(m_beaconData)) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Unable to set the data ... length passed in was %d and expected %d",
|
||||
data.length(), sizeof(m_beaconData));
|
||||
return;
|
||||
}
|
||||
memcpy(&m_beaconData, data.data(), sizeof(m_beaconData));
|
||||
return;
|
||||
}
|
||||
memcpy(&m_beaconData, data.data(), sizeof(m_beaconData));
|
||||
} // setData
|
||||
|
||||
void NimBLEBeacon::setMajor(uint16_t major) {
|
||||
m_beaconData.major = ENDIAN_CHANGE_U16(major);
|
||||
m_beaconData.major = ENDIAN_CHANGE_U16(major);
|
||||
} // setMajor
|
||||
|
||||
void NimBLEBeacon::setManufacturerId(uint16_t manufacturerId) {
|
||||
m_beaconData.manufacturerId = ENDIAN_CHANGE_U16(manufacturerId);
|
||||
m_beaconData.manufacturerId = ENDIAN_CHANGE_U16(manufacturerId);
|
||||
} // setManufacturerId
|
||||
|
||||
void NimBLEBeacon::setMinor(uint16_t minor) {
|
||||
m_beaconData.minor = ENDIAN_CHANGE_U16(minor);
|
||||
m_beaconData.minor = ENDIAN_CHANGE_U16(minor);
|
||||
} // setMinior
|
||||
|
||||
void NimBLEBeacon::setProximityUUID(const NimBLEUUID &uuid) {
|
||||
NimBLEUUID temp_uuid = uuid;
|
||||
temp_uuid.to128();
|
||||
memcpy(m_beaconData.proximityUUID, temp_uuid.getNative()->u128.value, 16);
|
||||
NimBLEUUID temp_uuid = uuid;
|
||||
temp_uuid.to128();
|
||||
memcpy(m_beaconData.proximityUUID, temp_uuid.getNative()->u128.value, 16);
|
||||
} // setProximityUUID
|
||||
|
||||
void NimBLEBeacon::setSignalPower(int8_t signalPower) {
|
||||
m_beaconData.signalPower = signalPower;
|
||||
m_beaconData.signalPower = signalPower;
|
||||
} // setSignalPower
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on March 15 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLEBeacon2.h
|
||||
|
@ -14,6 +14,7 @@
|
|||
|
||||
#ifndef MAIN_NIMBLEBEACON_H_
|
||||
#define MAIN_NIMBLEBEACON_H_
|
||||
|
||||
#include "NimBLEUUID.h"
|
||||
/**
|
||||
* @brief Representation of a beacon.
|
||||
|
@ -22,29 +23,29 @@
|
|||
*/
|
||||
class NimBLEBeacon {
|
||||
private:
|
||||
struct {
|
||||
uint16_t manufacturerId;
|
||||
uint8_t subType;
|
||||
uint8_t subTypeLength;
|
||||
uint8_t proximityUUID[16];
|
||||
uint16_t major;
|
||||
uint16_t minor;
|
||||
int8_t signalPower;
|
||||
} __attribute__((packed)) m_beaconData;
|
||||
struct {
|
||||
uint16_t manufacturerId;
|
||||
uint8_t subType;
|
||||
uint8_t subTypeLength;
|
||||
uint8_t proximityUUID[16];
|
||||
uint16_t major;
|
||||
uint16_t minor;
|
||||
int8_t signalPower;
|
||||
} __attribute__((packed)) m_beaconData;
|
||||
public:
|
||||
NimBLEBeacon();
|
||||
std::string getData();
|
||||
uint16_t getMajor();
|
||||
uint16_t getMinor();
|
||||
uint16_t getManufacturerId();
|
||||
NimBLEUUID getProximityUUID();
|
||||
int8_t getSignalPower();
|
||||
void setData(const std::string &data);
|
||||
void setMajor(uint16_t major);
|
||||
void setMinor(uint16_t minor);
|
||||
void setManufacturerId(uint16_t manufacturerId);
|
||||
void setProximityUUID(const NimBLEUUID &uuid);
|
||||
void setSignalPower(int8_t signalPower);
|
||||
NimBLEBeacon();
|
||||
std::string getData();
|
||||
uint16_t getMajor();
|
||||
uint16_t getMinor();
|
||||
uint16_t getManufacturerId();
|
||||
NimBLEUUID getProximityUUID();
|
||||
int8_t getSignalPower();
|
||||
void setData(const std::string &data);
|
||||
void setMajor(uint16_t major);
|
||||
void setMinor(uint16_t minor);
|
||||
void setManufacturerId(uint16_t manufacturerId);
|
||||
void setProximityUUID(const NimBLEUUID &uuid);
|
||||
void setSignalPower(int8_t signalPower);
|
||||
}; // NimBLEBeacon
|
||||
|
||||
#endif /* MAIN_NIMBLEBEACON_H_ */
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on March 3, 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* BLECharacteristic.cpp
|
||||
*
|
||||
* Created on: Jun 22, 2017
|
||||
|
@ -12,6 +12,9 @@
|
|||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
|
||||
#include "NimBLECharacteristic.h"
|
||||
#include "NimBLE2902.h"
|
||||
#include "NimBLE2904.h"
|
||||
|
@ -32,7 +35,7 @@ static const char* LOG_TAG = "NimBLECharacteristic";
|
|||
* @param [in] uuid - UUID (const char*) for the characteristic.
|
||||
* @param [in] properties - Properties for the characteristic.
|
||||
*/
|
||||
NimBLECharacteristic::NimBLECharacteristic(const char* uuid, uint16_t properties, NimBLEService* pService)
|
||||
NimBLECharacteristic::NimBLECharacteristic(const char* uuid, uint16_t properties, NimBLEService* pService)
|
||||
: NimBLECharacteristic(NimBLEUUID(uuid), properties, pService) {
|
||||
}
|
||||
|
||||
|
@ -42,18 +45,18 @@ NimBLECharacteristic::NimBLECharacteristic(const char* uuid, uint16_t properties
|
|||
* @param [in] properties - Properties for the characteristic.
|
||||
*/
|
||||
NimBLECharacteristic::NimBLECharacteristic(const NimBLEUUID &uuid, uint16_t properties, NimBLEService* pService) {
|
||||
m_uuid = uuid;
|
||||
m_handle = NULL_HANDLE;
|
||||
m_properties = properties;
|
||||
m_pCallbacks = &defaultCallback;
|
||||
m_uuid = uuid;
|
||||
m_handle = NULL_HANDLE;
|
||||
m_properties = properties;
|
||||
m_pCallbacks = &defaultCallback;
|
||||
m_pService = pService;
|
||||
// Backward Compatibility - to be removed
|
||||
/* setBroadcastProperty((properties & PROPERTY_BROADCAST) != 0);
|
||||
setReadProperty((properties & PROPERTY_READ) != 0);
|
||||
setWriteProperty((properties & PROPERTY_WRITE) != 0);
|
||||
setNotifyProperty((properties & PROPERTY_NOTIFY) != 0);
|
||||
setIndicateProperty((properties & PROPERTY_INDICATE) != 0);
|
||||
setWriteNoResponseProperty((properties & PROPERTY_WRITE_NR) != 0);
|
||||
/* setBroadcastProperty((properties & PROPERTY_BROADCAST) != 0);
|
||||
setReadProperty((properties & PROPERTY_READ) != 0);
|
||||
setWriteProperty((properties & PROPERTY_WRITE) != 0);
|
||||
setNotifyProperty((properties & PROPERTY_NOTIFY) != 0);
|
||||
setIndicateProperty((properties & PROPERTY_INDICATE) != 0);
|
||||
setWriteNoResponseProperty((properties & PROPERTY_WRITE_NR) != 0);
|
||||
*/
|
||||
///////////////////////////////////////////
|
||||
} // NimBLECharacteristic
|
||||
|
@ -71,14 +74,14 @@ NimBLECharacteristic::~NimBLECharacteristic() {
|
|||
* @return N/A.
|
||||
*/
|
||||
void NimBLECharacteristic::addDescriptor(NimBLEDescriptor* pDescriptor) {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> addDescriptor(): Adding %s to %s", pDescriptor->toString().c_str(), toString().c_str());
|
||||
// Check that we don't add the same descriptor twice.
|
||||
if (m_descriptorMap.getByUUID(pDescriptor->getUUID()) != nullptr) {
|
||||
NIMBLE_LOGW(LOG_TAG, "<< Adding a new descriptor with the same UUID as a previous one");
|
||||
//return;
|
||||
}
|
||||
m_descriptorMap.setByUUID(pDescriptor->getUUID(), pDescriptor);
|
||||
NIMBLE_LOGD(LOG_TAG, "<< addDescriptor()");
|
||||
NIMBLE_LOGD(LOG_TAG, ">> addDescriptor(): Adding %s to %s", pDescriptor->toString().c_str(), toString().c_str());
|
||||
// Check that we don't add the same descriptor twice.
|
||||
if (m_descriptorMap.getByUUID(pDescriptor->getUUID()) != nullptr) {
|
||||
NIMBLE_LOGW(LOG_TAG, "<< Adding a new descriptor with the same UUID as a previous one");
|
||||
//return;
|
||||
}
|
||||
m_descriptorMap.setByUUID(pDescriptor->getUUID(), pDescriptor);
|
||||
NIMBLE_LOGD(LOG_TAG, "<< addDescriptor()");
|
||||
} // addDescriptor
|
||||
|
||||
|
||||
|
@ -89,7 +92,7 @@ void NimBLECharacteristic::addDescriptor(NimBLEDescriptor* pDescriptor) {
|
|||
* @return The new BLE descriptor.
|
||||
*/
|
||||
NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const char* uuid, uint32_t properties, uint16_t max_len) {
|
||||
return createDescriptor(NimBLEUUID(uuid), properties, max_len);
|
||||
return createDescriptor(NimBLEUUID(uuid), properties, max_len);
|
||||
}
|
||||
|
||||
|
||||
|
@ -100,8 +103,8 @@ NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const char* uuid, uint3
|
|||
* @return The new BLE descriptor.
|
||||
*/
|
||||
NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const NimBLEUUID &uuid, uint32_t properties, uint16_t max_len) {
|
||||
NimBLEDescriptor* pDescriptor = nullptr;
|
||||
if(uuid.equals(NimBLEUUID((uint16_t)0x2902))) {
|
||||
NimBLEDescriptor* pDescriptor = nullptr;
|
||||
if(uuid.equals(NimBLEUUID((uint16_t)0x2902))) {
|
||||
if(!(m_properties & BLE_GATT_CHR_F_NOTIFY) && !(m_properties & BLE_GATT_CHR_F_INDICATE)) {
|
||||
assert(0 && "Cannot create 2902 descriptior without characteristic notification or indication property set");
|
||||
}
|
||||
|
@ -112,15 +115,15 @@ NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const NimBLEUUID &uuid,
|
|||
} else {
|
||||
return pDescriptor;
|
||||
}
|
||||
|
||||
} else if (uuid.equals(NimBLEUUID((uint16_t)0x2904))) {
|
||||
pDescriptor = new NimBLE2904(this);
|
||||
|
||||
} else {
|
||||
pDescriptor = new NimBLEDescriptor(uuid, properties, max_len, this);
|
||||
}
|
||||
addDescriptor(pDescriptor);
|
||||
return pDescriptor;
|
||||
|
||||
} else if (uuid.equals(NimBLEUUID((uint16_t)0x2904))) {
|
||||
pDescriptor = new NimBLE2904(this);
|
||||
|
||||
} else {
|
||||
pDescriptor = new NimBLEDescriptor(uuid, properties, max_len, this);
|
||||
}
|
||||
addDescriptor(pDescriptor);
|
||||
return pDescriptor;
|
||||
} // createCharacteristic
|
||||
|
||||
|
||||
|
@ -130,7 +133,7 @@ NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const NimBLEUUID &uuid,
|
|||
* @return The BLE Descriptor. If no such descriptor is associated with the characteristic, nullptr is returned.
|
||||
*/
|
||||
NimBLEDescriptor* NimBLECharacteristic::getDescriptorByUUID(const char* descriptorUUID) {
|
||||
return m_descriptorMap.getByUUID(NimBLEUUID(descriptorUUID));
|
||||
return m_descriptorMap.getByUUID(NimBLEUUID(descriptorUUID));
|
||||
} // getDescriptorByUUID
|
||||
|
||||
|
||||
|
@ -140,7 +143,7 @@ NimBLEDescriptor* NimBLECharacteristic::getDescriptorByUUID(const char* descript
|
|||
* @return The BLE Descriptor. If no such descriptor is associated with the characteristic, nullptr is returned.
|
||||
*/
|
||||
NimBLEDescriptor* NimBLECharacteristic::getDescriptorByUUID(const NimBLEUUID &descriptorUUID) {
|
||||
return m_descriptorMap.getByUUID(descriptorUUID);
|
||||
return m_descriptorMap.getByUUID(descriptorUUID);
|
||||
} // getDescriptorByUUID
|
||||
|
||||
|
||||
|
@ -149,17 +152,17 @@ NimBLEDescriptor* NimBLECharacteristic::getDescriptorByUUID(const NimBLEUUID &de
|
|||
* @return The handle of the characteristic.
|
||||
*/
|
||||
uint16_t NimBLECharacteristic::getHandle() {
|
||||
return m_handle;
|
||||
return m_handle;
|
||||
} // getHandle
|
||||
|
||||
/*
|
||||
void NimBLECharacteristic::setAccessPermissions(uint16_t perm) {
|
||||
m_permissions = perm;
|
||||
m_permissions = perm;
|
||||
}
|
||||
*/
|
||||
|
||||
uint8_t NimBLECharacteristic::getProperties() {
|
||||
return m_properties;
|
||||
return m_properties;
|
||||
} // getProperties
|
||||
|
||||
|
||||
|
@ -167,7 +170,7 @@ uint8_t NimBLECharacteristic::getProperties() {
|
|||
* @brief Get the service associated with this characteristic.
|
||||
*/
|
||||
NimBLEService* NimBLECharacteristic::getService() {
|
||||
return m_pService;
|
||||
return m_pService;
|
||||
} // getService
|
||||
|
||||
|
||||
|
@ -176,7 +179,7 @@ NimBLEService* NimBLECharacteristic::getService() {
|
|||
* @return The UUID of the characteristic.
|
||||
*/
|
||||
NimBLEUUID NimBLECharacteristic::getUUID() {
|
||||
return m_uuid;
|
||||
return m_uuid;
|
||||
} // getUUID
|
||||
|
||||
|
||||
|
@ -185,7 +188,7 @@ NimBLEUUID NimBLECharacteristic::getUUID() {
|
|||
* @return A pointer to storage containing the current characteristic value.
|
||||
*/
|
||||
std::string NimBLECharacteristic::getValue() {
|
||||
return m_value.getValue();
|
||||
return m_value.getValue();
|
||||
} // getValue
|
||||
|
||||
|
||||
|
@ -194,7 +197,7 @@ std::string NimBLECharacteristic::getValue() {
|
|||
* @return A pointer to storage containing the current characteristic data.
|
||||
*/
|
||||
uint8_t* NimBLECharacteristic::getData() {
|
||||
return m_value.getData();
|
||||
return m_value.getData();
|
||||
} // getData
|
||||
|
||||
|
||||
|
@ -203,7 +206,7 @@ uint8_t* NimBLECharacteristic::getData() {
|
|||
* @return The length of the current characteristic data.
|
||||
*/
|
||||
size_t NimBLECharacteristic:: getDataLength() {
|
||||
return m_value.getLength();
|
||||
return m_value.getLength();
|
||||
}
|
||||
|
||||
|
||||
|
@ -211,43 +214,43 @@ int NimBLECharacteristic::handleGapEvent(uint16_t conn_handle, uint16_t attr_han
|
|||
struct ble_gatt_access_ctxt *ctxt,
|
||||
void *arg)
|
||||
{
|
||||
const ble_uuid_t *uuid;
|
||||
const ble_uuid_t *uuid;
|
||||
int rc;
|
||||
NimBLECharacteristic* pCharacteristic = (NimBLECharacteristic*)arg;
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "Characteristic %s %s event", pCharacteristic->getUUID().toString().c_str(),
|
||||
NimBLECharacteristic* pCharacteristic = (NimBLECharacteristic*)arg;
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "Characteristic %s %s event", pCharacteristic->getUUID().toString().c_str(),
|
||||
ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR ? "Read" : "Write");
|
||||
|
||||
uuid = ctxt->chr->uuid;
|
||||
if(ble_uuid_cmp(uuid, &pCharacteristic->getUUID().getNative()->u) == 0){
|
||||
|
||||
uuid = ctxt->chr->uuid;
|
||||
if(ble_uuid_cmp(uuid, &pCharacteristic->getUUID().getNative()->u) == 0){
|
||||
switch(ctxt->op) {
|
||||
case BLE_GATT_ACCESS_OP_READ_CHR: {
|
||||
//NIMBLE_LOGD(LOG_TAG, "read char pkthdr len:%d flags:%d", ctxt->om->om_pkthdr_len, ctxt->om->om_flags);
|
||||
// If the packet header is only 8 bytes this is a follow up of a long read
|
||||
// so we don't want to call the onRead() callback again.
|
||||
if(ctxt->om->om_pkthdr_len > 8) {
|
||||
pCharacteristic->m_pCallbacks->onRead(pCharacteristic);
|
||||
}
|
||||
// If the packet header is only 8 bytes this is a follow up of a long read
|
||||
// so we don't want to call the onRead() callback again.
|
||||
if(ctxt->om->om_pkthdr_len > 8) {
|
||||
pCharacteristic->m_pCallbacks->onRead(pCharacteristic);
|
||||
}
|
||||
rc = os_mbuf_append(ctxt->om, pCharacteristic->getData(), pCharacteristic->m_value.getLength());
|
||||
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
|
||||
}
|
||||
|
||||
|
||||
case BLE_GATT_ACCESS_OP_WRITE_CHR: {
|
||||
//NIMBLE_LOGD(LOG_TAG, "write char pkthdr len:%d datalen:%d", ctxt->om->om_pkthdr_len, ctxt->om->om_len);
|
||||
if (ctxt->om->om_len > BLE_ATT_ATTR_MAX_LEN) {
|
||||
return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
|
||||
}
|
||||
|
||||
|
||||
//pCharacteristic->setValue(ctxt->om->om_data, ctxt->om->om_len);
|
||||
pCharacteristic->m_value.addPart(ctxt->om->om_data, ctxt->om->om_len);
|
||||
os_mbuf *next;
|
||||
next = SLIST_NEXT(ctxt->om, om_next);
|
||||
while(next != NULL){
|
||||
//NIMBLE_LOGD(LOG_TAG, "Found long write data, len:%d", next->om_len);
|
||||
pCharacteristic->m_value.addPart(next->om_data, next->om_len);
|
||||
next = SLIST_NEXT(next, om_next);
|
||||
}
|
||||
pCharacteristic->m_value.commit();
|
||||
pCharacteristic->m_value.addPart(ctxt->om->om_data, ctxt->om->om_len);
|
||||
os_mbuf *next;
|
||||
next = SLIST_NEXT(ctxt->om, om_next);
|
||||
while(next != NULL){
|
||||
//NIMBLE_LOGD(LOG_TAG, "Found long write data, len:%d", next->om_len);
|
||||
pCharacteristic->m_value.addPart(next->om_data, next->om_len);
|
||||
next = SLIST_NEXT(next, om_next);
|
||||
}
|
||||
pCharacteristic->m_value.commit();
|
||||
pCharacteristic->m_pCallbacks->onWrite(pCharacteristic);
|
||||
|
||||
return 0;
|
||||
|
@ -255,11 +258,11 @@ int NimBLECharacteristic::handleGapEvent(uint16_t conn_handle, uint16_t attr_han
|
|||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return BLE_ATT_ERR_UNLIKELY;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set the subscribe status for this characteristic.
|
||||
|
@ -274,23 +277,23 @@ void NimBLECharacteristic::setSubscribe(struct ble_gap_event *event) {
|
|||
if(event->subscribe.cur_indicate) {
|
||||
subVal |= NIMBLE_DESC_FLAG_INDICATE;
|
||||
}
|
||||
|
||||
|
||||
m_semaphoreConfEvt.give((subVal | NIMBLE_DESC_FLAG_INDICATE) ? 0 :
|
||||
NimBLECharacteristicCallbacks::Status::ERROR_INDICATE_DISABLED);
|
||||
|
||||
|
||||
NIMBLE_LOGI(LOG_TAG, "New subscribe value for conn: %d val: %d", event->subscribe.conn_handle, subVal);
|
||||
|
||||
|
||||
NimBLE2902* p2902 = (NimBLE2902*)getDescriptorByUUID((uint16_t)0x2902);
|
||||
if(p2902 == nullptr){
|
||||
ESP_LOGE(LOG_TAG, "No 2902 descriptor found for %s", getUUID().toString().c_str());
|
||||
if(p2902 == nullptr){
|
||||
ESP_LOGE(LOG_TAG, "No 2902 descriptor found for %s", getUUID().toString().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
p2902->setNotifications(subVal & NIMBLE_DESC_FLAG_NOTIFY);
|
||||
p2902->setIndications(subVal & NIMBLE_DESC_FLAG_INDICATE);
|
||||
p2902->m_pCallbacks->onWrite(p2902);
|
||||
|
||||
|
||||
|
||||
|
||||
auto it = p2902->m_subscribedMap.find(event->subscribe.conn_handle);
|
||||
if(subVal > 0 && it == p2902->m_subscribedMap.cend()) {
|
||||
p2902->m_subscribedMap.insert(std::pair<uint16_t, uint16_t>(event->subscribe.conn_handle, subVal));
|
||||
|
@ -299,12 +302,12 @@ void NimBLECharacteristic::setSubscribe(struct ble_gap_event *event) {
|
|||
p2902->m_subscribedMap.erase(event->subscribe.conn_handle);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
/*
|
||||
if(event->subscribe.reason == BLE_GAP_SUBSCRIBE_REASON_TERM) {
|
||||
p2902->m_subscribedMap.erase(event->subscribe.conn_handle);
|
||||
return;
|
||||
}
|
||||
*/
|
||||
*/
|
||||
(*it).second = subVal;
|
||||
}
|
||||
|
||||
|
@ -316,11 +319,11 @@ void NimBLECharacteristic::setSubscribe(struct ble_gap_event *event) {
|
|||
* @return N/A
|
||||
*/
|
||||
void NimBLECharacteristic::indicate() {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> indicate: length: %d", m_value.getValue().length());
|
||||
notify(false);
|
||||
NIMBLE_LOGD(LOG_TAG, "<< indicate");
|
||||
NIMBLE_LOGD(LOG_TAG, ">> indicate: length: %d", m_value.getValue().length());
|
||||
notify(false);
|
||||
NIMBLE_LOGD(LOG_TAG, "<< indicate");
|
||||
} // indicate
|
||||
|
||||
|
||||
/**
|
||||
* @brief Send a notify.
|
||||
* A notification is a transmission of up to the first 20 bytes of the characteristic value. An notification
|
||||
|
@ -328,29 +331,29 @@ void NimBLECharacteristic::indicate() {
|
|||
* @return N/A.
|
||||
*/
|
||||
void NimBLECharacteristic::notify(bool is_notification) {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> notify: length: %d", m_value.getValue().length());
|
||||
NIMBLE_LOGD(LOG_TAG, ">> notify: length: %d", m_value.getValue().length());
|
||||
|
||||
assert(getService() != nullptr);
|
||||
assert(getService()->getServer() != nullptr);
|
||||
assert(getService() != nullptr);
|
||||
assert(getService()->getServer() != nullptr);
|
||||
|
||||
|
||||
if (getService()->getServer()->getConnectedCount() == 0) {
|
||||
NIMBLE_LOGD(LOG_TAG, "<< notify: No connected clients.");
|
||||
return;
|
||||
}
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "<< notify: No connected clients.");
|
||||
return;
|
||||
}
|
||||
|
||||
m_pCallbacks->onNotify(this);
|
||||
|
||||
|
||||
int rc = 0;
|
||||
NimBLE2902* p2902 = (NimBLE2902*)getDescriptorByUUID((uint16_t)0x2902);
|
||||
|
||||
|
||||
for (auto it = p2902->m_subscribedMap.cbegin(); it != p2902->m_subscribedMap.cend(); ++it) {
|
||||
uint16_t _mtu = getService()->getServer()->getPeerMTU((*it).first);
|
||||
// Must rebuild the data on each loop iteration as NimBLE will release it.
|
||||
// Must rebuild the data on each loop iteration as NimBLE will release it.
|
||||
size_t length = m_value.getValue().length();
|
||||
uint8_t* data = (uint8_t*)m_value.getValue().data();
|
||||
os_mbuf *om;
|
||||
|
||||
|
||||
if(_mtu == 0) {
|
||||
//NIMBLE_LOGD(LOG_TAG, "peer not connected, removing from map");
|
||||
p2902->m_subscribedMap.erase((*it).first);
|
||||
|
@ -360,33 +363,33 @@ void NimBLECharacteristic::notify(bool is_notification) {
|
|||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (length > _mtu - 3) {
|
||||
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 - 3);
|
||||
}
|
||||
|
||||
if((*it).second == 0) {
|
||||
//NIMBLE_LOGI(LOG_TAG, "Skipping unsubscribed client");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if(is_notification && (!((*it).second & NIMBLE_DESC_FLAG_NOTIFY))) {
|
||||
NIMBLE_LOGW(LOG_TAG,
|
||||
NIMBLE_LOGW(LOG_TAG,
|
||||
"Sending notification to client subscribed to indications, sending indication instead");
|
||||
is_notification = false;
|
||||
}
|
||||
|
||||
|
||||
if(!is_notification && (!((*it).second & NIMBLE_DESC_FLAG_INDICATE))) {
|
||||
NIMBLE_LOGW(LOG_TAG,
|
||||
"Sending indication to client subscribed to notifications, sending notifications instead");
|
||||
is_notification = true;
|
||||
}
|
||||
|
||||
|
||||
// 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 also must create it in each loop iteration because it is consumed with each host call.
|
||||
om = ble_hs_mbuf_from_flat(data, length);
|
||||
|
||||
|
||||
if(!is_notification) {
|
||||
m_semaphoreConfEvt.take("indicate");
|
||||
rc = ble_gattc_indicate_custom((*it).first, m_handle, om);
|
||||
|
@ -395,9 +398,9 @@ void NimBLECharacteristic::notify(bool is_notification) {
|
|||
m_pCallbacks->onStatus(this, NimBLECharacteristicCallbacks::Status::ERROR_GATT, rc);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
rc = m_semaphoreConfEvt.wait();
|
||||
|
||||
|
||||
if(rc == BLE_HS_ETIMEOUT) {
|
||||
m_pCallbacks->onStatus(this, NimBLECharacteristicCallbacks::Status::ERROR_INDICATE_TIMEOUT, rc);
|
||||
} else if(rc == BLE_HS_EDONE) {
|
||||
|
@ -410,12 +413,12 @@ void NimBLECharacteristic::notify(bool is_notification) {
|
|||
if(rc == 0) {
|
||||
m_pCallbacks->onStatus(this, NimBLECharacteristicCallbacks::Status::SUCCESS_NOTIFY, 0);
|
||||
} else {
|
||||
m_pCallbacks->onStatus(this, NimBLECharacteristicCallbacks::Status::ERROR_GATT, rc);
|
||||
m_pCallbacks->onStatus(this, NimBLECharacteristicCallbacks::Status::ERROR_GATT, rc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "<< notify");
|
||||
NIMBLE_LOGD(LOG_TAG, "<< notify");
|
||||
} // Notify
|
||||
|
||||
|
||||
|
@ -424,11 +427,11 @@ void NimBLECharacteristic::notify(bool is_notification) {
|
|||
* @param [in] pCallbacks An instance of a callbacks structure used to define any callbacks for the characteristic.
|
||||
*/
|
||||
void NimBLECharacteristic::setCallbacks(NimBLECharacteristicCallbacks* pCallbacks) {
|
||||
if (pCallbacks != nullptr){
|
||||
m_pCallbacks = pCallbacks;
|
||||
} else {
|
||||
m_pCallbacks = &defaultCallback;
|
||||
}
|
||||
if (pCallbacks != nullptr){
|
||||
m_pCallbacks = pCallbacks;
|
||||
} else {
|
||||
m_pCallbacks = &defaultCallback;
|
||||
}
|
||||
} // setCallbacks
|
||||
|
||||
// Backward compatibility - to be removed ////////////////////////////////
|
||||
|
@ -440,11 +443,11 @@ void NimBLECharacteristic::setCallbacks(NimBLECharacteristicCallbacks* pCallback
|
|||
* @return N/A
|
||||
*/
|
||||
void NimBLECharacteristic::setBroadcastProperty(bool value) {
|
||||
if (value) {
|
||||
m_properties = (m_properties | BLE_GATT_CHR_F_BROADCAST);
|
||||
} else {
|
||||
m_properties = (m_properties & ~BLE_GATT_CHR_F_BROADCAST);
|
||||
}
|
||||
if (value) {
|
||||
m_properties = (m_properties | BLE_GATT_CHR_F_BROADCAST);
|
||||
} else {
|
||||
m_properties = (m_properties & ~BLE_GATT_CHR_F_BROADCAST);
|
||||
}
|
||||
} // setBroadcastProperty
|
||||
|
||||
|
||||
|
@ -453,11 +456,11 @@ void NimBLECharacteristic::setBroadcastProperty(bool value) {
|
|||
* @param [in] value Set to true if we are to allow indicate messages.
|
||||
*/
|
||||
void NimBLECharacteristic::setIndicateProperty(bool value) {
|
||||
if (value) {
|
||||
m_properties = (m_properties | BLE_GATT_CHR_F_INDICATE);
|
||||
} else {
|
||||
m_properties = (m_properties & ~BLE_GATT_CHR_F_INDICATE);
|
||||
}
|
||||
if (value) {
|
||||
m_properties = (m_properties | BLE_GATT_CHR_F_INDICATE);
|
||||
} else {
|
||||
m_properties = (m_properties & ~BLE_GATT_CHR_F_INDICATE);
|
||||
}
|
||||
} // setIndicateProperty
|
||||
|
||||
|
||||
|
@ -466,11 +469,11 @@ void NimBLECharacteristic::setIndicateProperty(bool value) {
|
|||
* @param [in] value Set to true if we are to allow notification messages.
|
||||
*/
|
||||
void NimBLECharacteristic::setNotifyProperty(bool value) {
|
||||
if (value) {
|
||||
m_properties = (m_properties | BLE_GATT_CHR_F_NOTIFY);
|
||||
} else {
|
||||
m_properties = (m_properties & ~BLE_GATT_CHR_F_NOTIFY);
|
||||
}
|
||||
if (value) {
|
||||
m_properties = (m_properties | BLE_GATT_CHR_F_NOTIFY);
|
||||
} else {
|
||||
m_properties = (m_properties & ~BLE_GATT_CHR_F_NOTIFY);
|
||||
}
|
||||
} // setNotifyProperty
|
||||
|
||||
|
||||
|
@ -479,11 +482,11 @@ void NimBLECharacteristic::setNotifyProperty(bool value) {
|
|||
* @param [in] value Set to true if we are to allow reads.
|
||||
*/
|
||||
void NimBLECharacteristic::setReadProperty(bool value) {
|
||||
if (value) {
|
||||
m_properties = (m_properties | BLE_GATT_CHR_F_READ);
|
||||
} else {
|
||||
m_properties = (m_properties & ~BLE_GATT_CHR_F_READ);
|
||||
}
|
||||
if (value) {
|
||||
m_properties = (m_properties | BLE_GATT_CHR_F_READ);
|
||||
} else {
|
||||
m_properties = (m_properties & ~BLE_GATT_CHR_F_READ);
|
||||
}
|
||||
} // setReadProperty
|
||||
|
||||
|
||||
|
@ -492,11 +495,11 @@ void NimBLECharacteristic::setReadProperty(bool value) {
|
|||
* @param [in] value Set to true if we are to allow writes with no response.
|
||||
*/
|
||||
void NimBLECharacteristic::setWriteNoResponseProperty(bool value) {
|
||||
if (value) {
|
||||
m_properties = (m_properties | BLE_GATT_CHR_F_WRITE_NO_RSP);
|
||||
} else {
|
||||
m_properties = (m_properties & ~BLE_GATT_CHR_F_WRITE_NO_RSP);
|
||||
}
|
||||
if (value) {
|
||||
m_properties = (m_properties | BLE_GATT_CHR_F_WRITE_NO_RSP);
|
||||
} else {
|
||||
m_properties = (m_properties & ~BLE_GATT_CHR_F_WRITE_NO_RSP);
|
||||
}
|
||||
} // setWriteNoResponseProperty
|
||||
|
||||
|
||||
|
@ -505,11 +508,11 @@ void NimBLECharacteristic::setWriteNoResponseProperty(bool value) {
|
|||
* @param [in] value Set to true if we are to allow writes.
|
||||
*/
|
||||
void NimBLECharacteristic::setWriteProperty(bool value) {
|
||||
if (value) {
|
||||
m_properties = (m_properties | BLE_GATT_CHR_F_WRITE );
|
||||
} else {
|
||||
m_properties = (m_properties & ~BLE_GATT_CHR_F_WRITE );
|
||||
}
|
||||
if (value) {
|
||||
m_properties = (m_properties | BLE_GATT_CHR_F_WRITE );
|
||||
} else {
|
||||
m_properties = (m_properties & ~BLE_GATT_CHR_F_WRITE );
|
||||
}
|
||||
} // setWriteProperty
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -519,23 +522,23 @@ void NimBLECharacteristic::setWriteProperty(bool value) {
|
|||
* @param [in] length The length of the data in bytes.
|
||||
*/
|
||||
void NimBLECharacteristic::setValue(const uint8_t* data, size_t 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());
|
||||
free(pHex);
|
||||
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());
|
||||
free(pHex);
|
||||
|
||||
if (length > BLE_ATT_ATTR_MAX_LEN) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Size %d too large, must be no bigger than %d", length, BLE_ATT_ATTR_MAX_LEN);
|
||||
return;
|
||||
}
|
||||
|
||||
m_value.setValue(data, length);
|
||||
|
||||
if (length > BLE_ATT_ATTR_MAX_LEN) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Size %d too large, must be no bigger than %d", length, BLE_ATT_ATTR_MAX_LEN);
|
||||
return;
|
||||
}
|
||||
|
||||
m_value.setValue(data, length);
|
||||
|
||||
// if(m_handle != NULL_HANDLE) {
|
||||
//ble_gatts_chr_updated(m_handle);
|
||||
// ble_gattc_notify(getService()->getServer()->m_connId, m_handle);
|
||||
// }
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "<< setValue");
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "<< setValue");
|
||||
} // setValue
|
||||
|
||||
|
||||
|
@ -547,42 +550,42 @@ void NimBLECharacteristic::setValue(const uint8_t* data, size_t length) {
|
|||
* @return N/A.
|
||||
*/
|
||||
void NimBLECharacteristic::setValue(const std::string &value) {
|
||||
setValue((uint8_t*)(value.data()), value.length());
|
||||
setValue((uint8_t*)(value.data()), value.length());
|
||||
} // setValue
|
||||
|
||||
void NimBLECharacteristic::setValue(uint16_t& data16) {
|
||||
uint8_t temp[2];
|
||||
temp[0] = data16;
|
||||
temp[1] = data16 >> 8;
|
||||
setValue(temp, 2);
|
||||
uint8_t temp[2];
|
||||
temp[0] = data16;
|
||||
temp[1] = data16 >> 8;
|
||||
setValue(temp, 2);
|
||||
} // setValue
|
||||
|
||||
void NimBLECharacteristic::setValue(uint32_t& data32) {
|
||||
uint8_t temp[4];
|
||||
temp[0] = data32;
|
||||
temp[1] = data32 >> 8;
|
||||
temp[2] = data32 >> 16;
|
||||
temp[3] = data32 >> 24;
|
||||
setValue(temp, 4);
|
||||
uint8_t temp[4];
|
||||
temp[0] = data32;
|
||||
temp[1] = data32 >> 8;
|
||||
temp[2] = data32 >> 16;
|
||||
temp[3] = data32 >> 24;
|
||||
setValue(temp, 4);
|
||||
} // setValue
|
||||
|
||||
void NimBLECharacteristic::setValue(int& data32) {
|
||||
uint8_t temp[4];
|
||||
temp[0] = data32;
|
||||
temp[1] = data32 >> 8;
|
||||
temp[2] = data32 >> 16;
|
||||
temp[3] = data32 >> 24;
|
||||
setValue(temp, 4);
|
||||
uint8_t temp[4];
|
||||
temp[0] = data32;
|
||||
temp[1] = data32 >> 8;
|
||||
temp[2] = data32 >> 16;
|
||||
temp[3] = data32 >> 24;
|
||||
setValue(temp, 4);
|
||||
} // setValue
|
||||
|
||||
void NimBLECharacteristic::setValue(float& data32) {
|
||||
float temp = data32;
|
||||
setValue((uint8_t*)&temp, 4);
|
||||
float temp = data32;
|
||||
setValue((uint8_t*)&temp, 4);
|
||||
} // setValue
|
||||
|
||||
void NimBLECharacteristic::setValue(double& data64) {
|
||||
double temp = data64;
|
||||
setValue((uint8_t*)&temp, 8);
|
||||
double temp = data64;
|
||||
setValue((uint8_t*)&temp, 8);
|
||||
} // setValue
|
||||
|
||||
|
||||
|
@ -591,18 +594,18 @@ void NimBLECharacteristic::setValue(double& data64) {
|
|||
* @return A string representation of the characteristic.
|
||||
*/
|
||||
std::string NimBLECharacteristic::toString() {
|
||||
std::string res = "UUID: " + m_uuid.toString() + ", handle : 0x";
|
||||
char hex[5];
|
||||
snprintf(hex, sizeof(hex), "%04x", m_handle);
|
||||
res += hex;
|
||||
res += " ";
|
||||
if (m_properties & BLE_GATT_CHR_PROP_READ ) res += "Read ";
|
||||
if (m_properties & BLE_GATT_CHR_PROP_WRITE) res += "Write ";
|
||||
if (m_properties & BLE_GATT_CHR_PROP_WRITE_NO_RSP) res += "WriteNoResponse ";
|
||||
if (m_properties & BLE_GATT_CHR_PROP_BROADCAST) res += "Broadcast ";
|
||||
if (m_properties & BLE_GATT_CHR_PROP_NOTIFY) res += "Notify ";
|
||||
if (m_properties & BLE_GATT_CHR_PROP_INDICATE) res += "Indicate ";
|
||||
return res;
|
||||
std::string res = "UUID: " + m_uuid.toString() + ", handle : 0x";
|
||||
char hex[5];
|
||||
snprintf(hex, sizeof(hex), "%04x", m_handle);
|
||||
res += hex;
|
||||
res += " ";
|
||||
if (m_properties & BLE_GATT_CHR_PROP_READ ) res += "Read ";
|
||||
if (m_properties & BLE_GATT_CHR_PROP_WRITE) res += "Write ";
|
||||
if (m_properties & BLE_GATT_CHR_PROP_WRITE_NO_RSP) res += "WriteNoResponse ";
|
||||
if (m_properties & BLE_GATT_CHR_PROP_BROADCAST) res += "Broadcast ";
|
||||
if (m_properties & BLE_GATT_CHR_PROP_NOTIFY) res += "Notify ";
|
||||
if (m_properties & BLE_GATT_CHR_PROP_INDICATE) res += "Indicate ";
|
||||
return res;
|
||||
} // toString
|
||||
|
||||
|
||||
|
@ -614,7 +617,7 @@ NimBLECharacteristicCallbacks::~NimBLECharacteristicCallbacks() {}
|
|||
* @param [in] pCharacteristic The characteristic that is the source of the event.
|
||||
*/
|
||||
void NimBLECharacteristicCallbacks::onRead(NimBLECharacteristic* pCharacteristic) {
|
||||
NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onRead: default");
|
||||
NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onRead: default");
|
||||
} // onRead
|
||||
|
||||
|
||||
|
@ -623,7 +626,7 @@ void NimBLECharacteristicCallbacks::onRead(NimBLECharacteristic* pCharacteristic
|
|||
* @param [in] pCharacteristic The characteristic that is the source of the event.
|
||||
*/
|
||||
void NimBLECharacteristicCallbacks::onWrite(NimBLECharacteristic* pCharacteristic) {
|
||||
NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onWrite: default");
|
||||
NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onWrite: default");
|
||||
} // onWrite
|
||||
|
||||
|
||||
|
@ -632,7 +635,7 @@ void NimBLECharacteristicCallbacks::onWrite(NimBLECharacteristic* pCharacteristi
|
|||
* @param [in] pCharacteristic The characteristic that is the source of the event.
|
||||
*/
|
||||
void NimBLECharacteristicCallbacks::onNotify(NimBLECharacteristic* pCharacteristic) {
|
||||
NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onNotify: default");
|
||||
NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onNotify: default");
|
||||
} // onNotify
|
||||
|
||||
|
||||
|
@ -643,7 +646,8 @@ void NimBLECharacteristicCallbacks::onNotify(NimBLECharacteristic* pCharacterist
|
|||
* @param [in] code Additional code of underlying errors
|
||||
*/
|
||||
void NimBLECharacteristicCallbacks::onStatus(NimBLECharacteristic* pCharacteristic, Status s, int code) {
|
||||
NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onStatus: default");
|
||||
NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onStatus: default");
|
||||
} // onStatus
|
||||
|
||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
#endif /* CONFIG_BT_ENABLED */
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on March 3, 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
* BLECharacteristic.h
|
||||
*
|
||||
|
@ -16,6 +16,9 @@
|
|||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
|
||||
#include "host/ble_hs.h"
|
||||
/**** FIX COMPILATION ****/
|
||||
#undef min
|
||||
|
@ -23,10 +26,10 @@
|
|||
/**************************/
|
||||
|
||||
typedef enum {
|
||||
READ = BLE_GATT_CHR_F_READ,
|
||||
READ = BLE_GATT_CHR_F_READ,
|
||||
READ_ENC = BLE_GATT_CHR_F_READ_ENC,
|
||||
READ_AUTHEN = BLE_GATT_CHR_F_READ_AUTHEN,
|
||||
READ_AUTHOR = BLE_GATT_CHR_F_READ_AUTHOR,
|
||||
READ_AUTHOR = BLE_GATT_CHR_F_READ_AUTHOR,
|
||||
WRITE = BLE_GATT_CHR_F_WRITE,
|
||||
WRITE_NR = BLE_GATT_CHR_F_WRITE_NO_RSP,
|
||||
WRITE_ENC = BLE_GATT_CHR_F_WRITE_ENC,
|
||||
|
@ -57,21 +60,21 @@ class NimBLECharacteristicCallbacks;
|
|||
*/
|
||||
class NimBLEDescriptorMap {
|
||||
public:
|
||||
void setByUUID(const char* uuid, NimBLEDescriptor* pDescriptor);
|
||||
void setByUUID(const NimBLEUUID &uuid, NimBLEDescriptor* pDescriptor);
|
||||
// void setByHandle(uint16_t handle, NimBLEDescriptor* pDescriptor);
|
||||
NimBLEDescriptor* getByUUID(const char* uuid);
|
||||
NimBLEDescriptor* getByUUID(const NimBLEUUID &uuid);
|
||||
// NimBLEDescriptor* getByHandle(uint16_t handle);
|
||||
std::string toString();
|
||||
NimBLEDescriptor* getFirst();
|
||||
NimBLEDescriptor* getNext();
|
||||
void setByUUID(const char* uuid, NimBLEDescriptor* pDescriptor);
|
||||
void setByUUID(const NimBLEUUID &uuid, NimBLEDescriptor* pDescriptor);
|
||||
// void setByHandle(uint16_t handle, NimBLEDescriptor* pDescriptor);
|
||||
NimBLEDescriptor* getByUUID(const char* uuid);
|
||||
NimBLEDescriptor* getByUUID(const NimBLEUUID &uuid);
|
||||
// NimBLEDescriptor* getByHandle(uint16_t handle);
|
||||
std::string toString();
|
||||
NimBLEDescriptor* getFirst();
|
||||
NimBLEDescriptor* getNext();
|
||||
uint8_t getSize();
|
||||
|
||||
|
||||
private:
|
||||
std::map<NimBLEDescriptor*, std::string> m_uuidMap;
|
||||
// std::map<uint16_t, BLEDescriptor*> m_handleMap;
|
||||
std::map<NimBLEDescriptor*, std::string>::iterator m_iterator;
|
||||
std::map<NimBLEDescriptor*, std::string> m_uuidMap;
|
||||
// std::map<uint16_t, BLEDescriptor*> m_handleMap;
|
||||
std::map<NimBLEDescriptor*, std::string>::iterator m_iterator;
|
||||
};
|
||||
|
||||
|
||||
|
@ -83,85 +86,85 @@ private:
|
|||
*/
|
||||
class NimBLECharacteristic {
|
||||
public:
|
||||
NimBLEDescriptor* createDescriptor(const char* uuid,
|
||||
uint32_t properties = NIMBLE_PROPERTY::READ |
|
||||
NIMBLE_PROPERTY::WRITE,
|
||||
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,
|
||||
NimBLEDescriptor* createDescriptor(const NimBLEUUID &uuid,
|
||||
uint32_t properties = NIMBLE_PROPERTY::READ |
|
||||
NIMBLE_PROPERTY::WRITE,
|
||||
uint16_t max_len = 100);
|
||||
|
||||
NimBLEDescriptor* getDescriptorByUUID(const char* descriptorUUID);
|
||||
NimBLEDescriptor* getDescriptorByUUID(const NimBLEUUID &descriptorUUID);
|
||||
NimBLEUUID getUUID();
|
||||
std::string getValue();
|
||||
uint8_t* getData();
|
||||
size_t getDataLength();
|
||||
|
||||
void indicate();
|
||||
void notify(bool is_notification = true);
|
||||
void setCallbacks(NimBLECharacteristicCallbacks* pCallbacks);
|
||||
NimBLEDescriptor* getDescriptorByUUID(const char* descriptorUUID);
|
||||
NimBLEDescriptor* getDescriptorByUUID(const NimBLEUUID &descriptorUUID);
|
||||
NimBLEUUID getUUID();
|
||||
std::string getValue();
|
||||
uint8_t* getData();
|
||||
size_t getDataLength();
|
||||
|
||||
void indicate();
|
||||
void notify(bool is_notification = true);
|
||||
void setCallbacks(NimBLECharacteristicCallbacks* pCallbacks);
|
||||
// Backward Compatibility - to be removed
|
||||
void setBroadcastProperty(bool value);
|
||||
void setIndicateProperty(bool value);
|
||||
void setNotifyProperty(bool value);
|
||||
void setReadProperty(bool value);
|
||||
void setIndicateProperty(bool value);
|
||||
void setNotifyProperty(bool value);
|
||||
void setReadProperty(bool value);
|
||||
void setWriteProperty(bool value);
|
||||
void setWriteNoResponseProperty(bool value);
|
||||
//////////////////////////////////////////////////////
|
||||
void setValue(const uint8_t* data, size_t size);
|
||||
void setValue(const std::string &value);
|
||||
void setValue(uint16_t& data16);
|
||||
void setValue(uint32_t& data32);
|
||||
void setValue(int& data32);
|
||||
void setValue(float& data32);
|
||||
void setValue(double& data64);
|
||||
void setWriteNoResponseProperty(bool value);
|
||||
//////////////////////////////////////////////////////
|
||||
void setValue(const uint8_t* data, size_t size);
|
||||
void setValue(const std::string &value);
|
||||
void setValue(uint16_t& data16);
|
||||
void setValue(uint32_t& data32);
|
||||
void setValue(int& data32);
|
||||
void setValue(float& data32);
|
||||
void setValue(double& data64);
|
||||
|
||||
std::string toString();
|
||||
uint16_t getHandle();
|
||||
// void setAccessPermissions(uint16_t perm);
|
||||
std::string toString();
|
||||
uint16_t getHandle();
|
||||
// void setAccessPermissions(uint16_t perm);
|
||||
|
||||
// Backward Compatibility - to be removed
|
||||
/* static const uint32_t PROPERTY_READ = 1<<0;
|
||||
static const uint32_t PROPERTY_WRITE = 1<<1;
|
||||
static const uint32_t PROPERTY_NOTIFY = 1<<2;
|
||||
static const uint32_t PROPERTY_BROADCAST = 1<<3;
|
||||
static const uint32_t PROPERTY_INDICATE = 1<<4;
|
||||
static const uint32_t PROPERTY_WRITE_NR = 1<<5;
|
||||
/* static const uint32_t PROPERTY_READ = 1<<0;
|
||||
static const uint32_t PROPERTY_WRITE = 1<<1;
|
||||
static const uint32_t PROPERTY_NOTIFY = 1<<2;
|
||||
static const uint32_t PROPERTY_BROADCAST = 1<<3;
|
||||
static const uint32_t PROPERTY_INDICATE = 1<<4;
|
||||
static const uint32_t PROPERTY_WRITE_NR = 1<<5;
|
||||
*/
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
|
||||
private:
|
||||
|
||||
friend class NimBLEServer;
|
||||
friend class NimBLEService;
|
||||
// friend class NimBLEDescriptor;
|
||||
// friend class NimBLECharacteristicMap;
|
||||
friend class NimBLEServer;
|
||||
friend class NimBLEService;
|
||||
// friend class NimBLEDescriptor;
|
||||
// friend class NimBLECharacteristicMap;
|
||||
|
||||
NimBLECharacteristic(const char* uuid, uint16_t properties = NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE,
|
||||
NimBLEService* pService = nullptr);
|
||||
NimBLECharacteristic(const NimBLEUUID &uuid, uint16_t properties = NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE,
|
||||
NimBLEService* pService = nullptr);
|
||||
virtual ~NimBLECharacteristic();
|
||||
NimBLECharacteristic(const char* uuid, uint16_t properties = NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE,
|
||||
NimBLEService* pService = nullptr);
|
||||
NimBLECharacteristic(const NimBLEUUID &uuid, uint16_t properties = NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE,
|
||||
NimBLEService* pService = nullptr);
|
||||
virtual ~NimBLECharacteristic();
|
||||
|
||||
NimBLEUUID m_uuid;
|
||||
NimBLEDescriptorMap m_descriptorMap;
|
||||
uint16_t m_handle;
|
||||
uint16_t m_properties;
|
||||
NimBLECharacteristicCallbacks* m_pCallbacks;
|
||||
NimBLEService* m_pService;
|
||||
NimBLEValue m_value;
|
||||
// uint16_t m_permissions;
|
||||
|
||||
void addDescriptor(NimBLEDescriptor* pDescriptor);
|
||||
NimBLEUUID m_uuid;
|
||||
NimBLEDescriptorMap m_descriptorMap;
|
||||
uint16_t m_handle;
|
||||
uint16_t m_properties;
|
||||
NimBLECharacteristicCallbacks* m_pCallbacks;
|
||||
NimBLEService* m_pService;
|
||||
NimBLEValue m_value;
|
||||
// uint16_t m_permissions;
|
||||
|
||||
void addDescriptor(NimBLEDescriptor* pDescriptor);
|
||||
NimBLEService* getService();
|
||||
uint8_t getProperties();
|
||||
void setSubscribe(struct ble_gap_event *event);
|
||||
static int handleGapEvent(uint16_t conn_handle, uint16_t attr_handle,
|
||||
static int handleGapEvent(uint16_t conn_handle, uint16_t attr_handle,
|
||||
struct ble_gatt_access_ctxt *ctxt, void *arg);
|
||||
|
||||
FreeRTOS::Semaphore m_semaphoreConfEvt = FreeRTOS::Semaphore("ConfEvt");
|
||||
FreeRTOS::Semaphore m_semaphoreConfEvt = FreeRTOS::Semaphore("ConfEvt");
|
||||
}; // NimBLECharacteristic
|
||||
|
||||
|
||||
|
@ -175,21 +178,23 @@ private:
|
|||
class NimBLECharacteristicCallbacks {
|
||||
public:
|
||||
typedef enum {
|
||||
SUCCESS_INDICATE,
|
||||
SUCCESS_NOTIFY,
|
||||
ERROR_INDICATE_DISABLED,
|
||||
ERROR_NOTIFY_DISABLED,
|
||||
ERROR_GATT,
|
||||
ERROR_NO_CLIENT,
|
||||
ERROR_INDICATE_TIMEOUT,
|
||||
ERROR_INDICATE_FAILURE
|
||||
}Status;
|
||||
|
||||
virtual ~NimBLECharacteristicCallbacks();
|
||||
virtual void onRead(NimBLECharacteristic* pCharacteristic);
|
||||
virtual void onWrite(NimBLECharacteristic* pCharacteristic);
|
||||
SUCCESS_INDICATE,
|
||||
SUCCESS_NOTIFY,
|
||||
ERROR_INDICATE_DISABLED,
|
||||
ERROR_NOTIFY_DISABLED,
|
||||
ERROR_GATT,
|
||||
ERROR_NO_CLIENT,
|
||||
ERROR_INDICATE_TIMEOUT,
|
||||
ERROR_INDICATE_FAILURE
|
||||
}Status;
|
||||
|
||||
virtual ~NimBLECharacteristicCallbacks();
|
||||
virtual void onRead(NimBLECharacteristic* pCharacteristic);
|
||||
virtual void onWrite(NimBLECharacteristic* pCharacteristic);
|
||||
virtual void onNotify(NimBLECharacteristic* pCharacteristic);
|
||||
virtual void onStatus(NimBLECharacteristic* pCharacteristic, Status s, int code);
|
||||
virtual void onStatus(NimBLECharacteristic* pCharacteristic, Status s, int code);
|
||||
};
|
||||
|
||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
#endif /* CONFIG_BT_ENABLED */
|
||||
#endif /*MAIN_NIMBLECHARACTERISTIC_H_*/
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
|
||||
#include "NimBLEService.h"
|
||||
#include "NimBLELog.h"
|
||||
|
||||
|
@ -20,9 +23,9 @@
|
|||
* @brief Return the characteristic by handle.
|
||||
* @param [in] handle The handle to look up the characteristic.
|
||||
* @return The characteristic.
|
||||
*/
|
||||
*/
|
||||
NimBLECharacteristic* NimBLECharacteristicMap::getByHandle(uint16_t handle) {
|
||||
return m_handleMap.at(handle);
|
||||
return m_handleMap.at(handle);
|
||||
} // getByHandle
|
||||
|
||||
|
||||
|
@ -42,20 +45,20 @@ NimBLECharacteristic* NimBLECharacteristicMap::getByUUID(const char* uuid) {
|
|||
* @return The characteristic.
|
||||
*/
|
||||
NimBLECharacteristic* NimBLECharacteristicMap::getByUUID(const NimBLEUUID &uuid) {
|
||||
for (auto &myPair : m_uuidMap) {
|
||||
if (myPair.first->getUUID().equals(uuid)) {
|
||||
return myPair.first;
|
||||
}
|
||||
}
|
||||
for (auto &myPair : m_uuidMap) {
|
||||
if (myPair.first->getUUID().equals(uuid)) {
|
||||
return myPair.first;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return nullptr;
|
||||
} // getByUUID
|
||||
|
||||
/**
|
||||
* @brief Get the number of characteristics in the map.
|
||||
*/
|
||||
uint8_t NimBLECharacteristicMap::getSize() {
|
||||
return (uint8_t)m_uuidMap.size();
|
||||
return (uint8_t)m_uuidMap.size();
|
||||
} // getSize
|
||||
|
||||
/**
|
||||
|
@ -63,11 +66,11 @@ uint8_t NimBLECharacteristicMap::getSize() {
|
|||
* @return The first characteristic in the map.
|
||||
*/
|
||||
NimBLECharacteristic* NimBLECharacteristicMap::getFirst() {
|
||||
m_iterator = m_uuidMap.begin();
|
||||
if (m_iterator == m_uuidMap.end()) return nullptr;
|
||||
NimBLECharacteristic* pRet = m_iterator->first;
|
||||
m_iterator++;
|
||||
return pRet;
|
||||
m_iterator = m_uuidMap.begin();
|
||||
if (m_iterator == m_uuidMap.end()) return nullptr;
|
||||
NimBLECharacteristic* pRet = m_iterator->first;
|
||||
m_iterator++;
|
||||
return pRet;
|
||||
} // getFirst
|
||||
|
||||
|
||||
|
@ -76,10 +79,10 @@ NimBLECharacteristic* NimBLECharacteristicMap::getFirst() {
|
|||
* @return The next characteristic in the map.
|
||||
*/
|
||||
NimBLECharacteristic* NimBLECharacteristicMap::getNext() {
|
||||
if (m_iterator == m_uuidMap.end()) return nullptr;
|
||||
NimBLECharacteristic* pRet = m_iterator->first;
|
||||
m_iterator++;
|
||||
return pRet;
|
||||
if (m_iterator == m_uuidMap.end()) return nullptr;
|
||||
NimBLECharacteristic* pRet = m_iterator->first;
|
||||
m_iterator++;
|
||||
return pRet;
|
||||
} // getNext
|
||||
|
||||
|
||||
|
@ -90,7 +93,7 @@ NimBLECharacteristic* NimBLECharacteristicMap::getNext() {
|
|||
* @return N/A.
|
||||
*/
|
||||
void NimBLECharacteristicMap::setByHandle(uint16_t handle, NimBLECharacteristic* characteristic) {
|
||||
m_handleMap.insert(std::pair<uint16_t, NimBLECharacteristic*>(handle, characteristic));
|
||||
m_handleMap.insert(std::pair<uint16_t, NimBLECharacteristic*>(handle, characteristic));
|
||||
} // setByHandle
|
||||
|
||||
|
||||
|
@ -101,7 +104,7 @@ void NimBLECharacteristicMap::setByHandle(uint16_t handle, NimBLECharacteristic*
|
|||
* @return N/A.
|
||||
*/
|
||||
void NimBLECharacteristicMap::setByUUID(NimBLECharacteristic* pCharacteristic, const NimBLEUUID &uuid) {
|
||||
m_uuidMap.insert(std::pair<NimBLECharacteristic*, std::string>(pCharacteristic, uuid.toString()));
|
||||
m_uuidMap.insert(std::pair<NimBLECharacteristic*, std::string>(pCharacteristic, uuid.toString()));
|
||||
} // setByUUID
|
||||
|
||||
|
||||
|
@ -110,19 +113,20 @@ void NimBLECharacteristicMap::setByUUID(NimBLECharacteristic* pCharacteristic, c
|
|||
* @return A string representation of the characteristic map.
|
||||
*/
|
||||
std::string NimBLECharacteristicMap::toString() {
|
||||
std::string res;
|
||||
int count = 0;
|
||||
char hex[5];
|
||||
for (auto &myPair: m_uuidMap) {
|
||||
if (count > 0) {res += "\n";}
|
||||
snprintf(hex, sizeof(hex), "%04x", myPair.first->getHandle());
|
||||
count++;
|
||||
res += "handle: 0x";
|
||||
res += hex;
|
||||
res += ", uuid: " + myPair.first->getUUID().toString();
|
||||
}
|
||||
return res;
|
||||
std::string res;
|
||||
int count = 0;
|
||||
char hex[5];
|
||||
for (auto &myPair: m_uuidMap) {
|
||||
if (count > 0) {res += "\n";}
|
||||
snprintf(hex, sizeof(hex), "%04x", myPair.first->getHandle());
|
||||
count++;
|
||||
res += "handle: 0x";
|
||||
res += hex;
|
||||
res += ", uuid: " + myPair.first->getUUID().toString();
|
||||
}
|
||||
return res;
|
||||
} // toString
|
||||
|
||||
|
||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
#endif /* CONFIG_BT_ENABLED */
|
||||
|
|
|
@ -3,17 +3,20 @@
|
|||
*
|
||||
* Created: on Jan 26 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
* BLEClient.cpp
|
||||
*
|
||||
* Created on: Mar 22, 2017
|
||||
* Author: kolban
|
||||
*/
|
||||
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||
|
||||
#include "NimBLEClient.h"
|
||||
#include "NimBLEUtils.h"
|
||||
#include "NimBLEDevice.h"
|
||||
|
@ -52,16 +55,16 @@ NimBLEClient::NimBLEClient()
|
|||
m_conn_id = BLE_HS_CONN_HANDLE_NONE;
|
||||
m_haveServices = false;
|
||||
m_isConnected = false;
|
||||
m_connectTimeout = 30000;
|
||||
|
||||
m_pConnParams.scan_itvl = 16; // Scan interval in 0.625ms units (NimBLE Default)
|
||||
m_connectTimeout = 30000;
|
||||
|
||||
m_pConnParams.scan_itvl = 16; // Scan interval in 0.625ms units (NimBLE Default)
|
||||
m_pConnParams.scan_window = 16; // Scan window in 0.625ms units (NimBLE Default)
|
||||
m_pConnParams.itvl_min = BLE_GAP_INITIAL_CONN_ITVL_MIN; // min_int = 0x10*1.25ms = 20ms
|
||||
m_pConnParams.itvl_max = BLE_GAP_INITIAL_CONN_ITVL_MAX; // max_int = 0x20*1.25ms = 40ms
|
||||
m_pConnParams.latency = BLE_GAP_INITIAL_CONN_LATENCY; // number of packets allowed to skip (extends max interval)
|
||||
m_pConnParams.supervision_timeout = BLE_GAP_INITIAL_SUPERVISION_TIMEOUT; // timeout = 400*10ms = 4000ms
|
||||
m_pConnParams.itvl_min = BLE_GAP_INITIAL_CONN_ITVL_MIN; // min_int = 0x10*1.25ms = 20ms
|
||||
m_pConnParams.itvl_max = BLE_GAP_INITIAL_CONN_ITVL_MAX; // max_int = 0x20*1.25ms = 40ms
|
||||
m_pConnParams.latency = BLE_GAP_INITIAL_CONN_LATENCY; // number of packets allowed to skip (extends max interval)
|
||||
m_pConnParams.supervision_timeout = BLE_GAP_INITIAL_SUPERVISION_TIMEOUT; // timeout = 400*10ms = 4000ms
|
||||
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
|
||||
} // NimBLEClient
|
||||
|
||||
|
||||
|
@ -69,11 +72,11 @@ NimBLEClient::NimBLEClient()
|
|||
* @brief Destructor, private - only callable by NimBLEDevice::deleteClient
|
||||
* to ensure proper disconnect and removal from device list.
|
||||
*/
|
||||
NimBLEClient::~NimBLEClient() {
|
||||
// We may have allocated service references associated with this client.
|
||||
NimBLEClient::~NimBLEClient() {
|
||||
// We may have allocated service references associated with this client.
|
||||
// Before we are finished with the client, we must release resources.
|
||||
clearServices();
|
||||
|
||||
|
||||
if(m_deleteCallbacks && m_pClientCallbacks != &defaultCallbacks) {
|
||||
delete m_pClientCallbacks;
|
||||
}
|
||||
|
@ -101,10 +104,10 @@ void NimBLEClient::clearServices() {
|
|||
*/
|
||||
/*
|
||||
void NimBLEClient::onHostReset() {
|
||||
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* Add overloaded function to ease connect to peer device with not public address
|
||||
*/
|
||||
|
@ -122,12 +125,12 @@ bool NimBLEClient::connect(NimBLEAdvertisedDevice* device, bool refreshServices)
|
|||
*/
|
||||
bool NimBLEClient::connect(const NimBLEAddress &address, uint8_t type, bool refreshServices) {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> connect(%s)", address.toString().c_str());
|
||||
|
||||
|
||||
if(!NimBLEDevice::m_synced) {
|
||||
NIMBLE_LOGC(LOG_TAG, "Host reset, wait for sync.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if(ble_gap_conn_active()) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Connection in progress - must wait.");
|
||||
return false;
|
||||
|
@ -135,15 +138,15 @@ bool NimBLEClient::connect(const NimBLEAddress &address, uint8_t type, bool refr
|
|||
|
||||
int rc = 0;
|
||||
m_peerAddress = address;
|
||||
|
||||
|
||||
ble_addr_t peerAddrt;
|
||||
memcpy(&peerAddrt.val, address.getNative(),6);
|
||||
peerAddrt.type = type;
|
||||
|
||||
|
||||
m_semaphoreOpenEvt.take("connect");
|
||||
|
||||
|
||||
/** Try to connect the the advertiser. Allow 30 seconds (30000 ms) for
|
||||
* timeout (default value of m_connectTimeout).
|
||||
* timeout (default value of m_connectTimeout).
|
||||
* Loop on BLE_HS_EBUSY if the scan hasn't stopped yet.
|
||||
*/
|
||||
do{
|
||||
|
@ -153,21 +156,21 @@ bool NimBLEClient::connect(const NimBLEAddress &address, uint8_t type, bool refr
|
|||
vTaskDelay(1);
|
||||
}
|
||||
}while(rc == BLE_HS_EBUSY);
|
||||
|
||||
|
||||
if (rc != 0 && rc != BLE_HS_EDONE) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Error: Failed to connect to device; addr_type=%d "
|
||||
"addr=%s, rc=%d; %s",
|
||||
type,
|
||||
type,
|
||||
m_peerAddress.toString().c_str(),
|
||||
rc, NimBLEUtils::returnCodeToString(rc));
|
||||
|
||||
|
||||
m_semaphoreOpenEvt.give();
|
||||
m_waitingToConnect = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
m_waitingToConnect = true;
|
||||
|
||||
|
||||
rc = m_semaphoreOpenEvt.wait("connect"); // Wait for the connection to complete.
|
||||
|
||||
if(rc != 0){
|
||||
|
@ -178,7 +181,7 @@ bool NimBLEClient::connect(const NimBLEAddress &address, uint8_t type, bool refr
|
|||
NIMBLE_LOGD(LOG_TAG, "Refreshing Services for: (%s)", address.toString().c_str());
|
||||
clearServices();
|
||||
}
|
||||
|
||||
|
||||
if (!m_haveServices) {
|
||||
if (!retrieveServices()) {
|
||||
// error getting services, make sure we disconnect and release any resources before returning
|
||||
|
@ -191,8 +194,8 @@ bool NimBLEClient::connect(const NimBLEAddress &address, uint8_t type, bool refr
|
|||
}
|
||||
}
|
||||
|
||||
m_pClientCallbacks->onConnect(this);
|
||||
|
||||
m_pClientCallbacks->onConnect(this);
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "<< connect()");
|
||||
return true;
|
||||
} // connect
|
||||
|
@ -204,23 +207,23 @@ bool NimBLEClient::connect(const NimBLEAddress &address, uint8_t type, bool refr
|
|||
* @return True on success.
|
||||
*/
|
||||
bool NimBLEClient::secureConnection() {
|
||||
|
||||
|
||||
m_semeaphoreSecEvt.take("secureConnection");
|
||||
|
||||
|
||||
int rc = NimBLEDevice::startSecurity(m_conn_id);
|
||||
if(rc != 0){
|
||||
m_semeaphoreSecEvt.give();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
rc = m_semeaphoreSecEvt.wait("secureConnection");
|
||||
if(rc != 0){
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Disconnect from the peer.
|
||||
|
@ -240,7 +243,7 @@ int NimBLEClient::disconnect(uint8_t reason) {
|
|||
// the device can be found again.
|
||||
NimBLEDevice::removeIgnored(m_peerAddress);
|
||||
}
|
||||
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "<< disconnect()");
|
||||
return rc;
|
||||
} // disconnect
|
||||
|
@ -250,23 +253,23 @@ int NimBLEClient::disconnect(uint8_t reason) {
|
|||
* @brief Set the connection paramaters to use when connecting to a server.
|
||||
*/
|
||||
void NimBLEClient::setConnectionParams(uint16_t minInterval, uint16_t maxInterval,
|
||||
uint16_t latency, uint16_t timeout,
|
||||
uint16_t latency, uint16_t timeout,
|
||||
uint16_t scanInterval, uint16_t scanWindow)/*,
|
||||
uint16_t minConnTime, uint16_t maxConnTime)*/
|
||||
{
|
||||
|
||||
m_pConnParams.scan_itvl = scanInterval; // Scan interval in 0.625ms units
|
||||
m_pConnParams.scan_itvl = scanInterval; // Scan interval in 0.625ms units
|
||||
m_pConnParams.scan_window = scanWindow; // Scan window in 0.625ms units
|
||||
m_pConnParams.itvl_min = minInterval; // min_int = 0x10*1.25ms = 20ms
|
||||
m_pConnParams.itvl_max = maxInterval; // max_int = 0x20*1.25ms = 40ms
|
||||
m_pConnParams.latency = latency; // number of packets allowed to skip (extends max interval)
|
||||
m_pConnParams.supervision_timeout = timeout; // timeout = 400*10ms = 4000ms
|
||||
|
||||
// These are not used by NimBLE at this time - Must leave at defaults
|
||||
m_pConnParams.itvl_min = minInterval; // min_int = 0x10*1.25ms = 20ms
|
||||
m_pConnParams.itvl_max = maxInterval; // max_int = 0x20*1.25ms = 40ms
|
||||
m_pConnParams.latency = latency; // number of packets allowed to skip (extends max interval)
|
||||
m_pConnParams.supervision_timeout = timeout; // timeout = 400*10ms = 4000ms
|
||||
|
||||
// These are not used by NimBLE at this time - Must leave at defaults
|
||||
//m_pConnParams->min_ce_len = minConnTime; // Minimum length of connection event in 0.625ms units
|
||||
//m_pConnParams->max_ce_len = maxConnTime; // Maximum length of connection event in 0.625ms units
|
||||
|
||||
int rc = NimBLEUtils::checkConnParams(&m_pConnParams);
|
||||
//m_pConnParams->max_ce_len = maxConnTime; // Maximum length of connection event in 0.625ms units
|
||||
|
||||
int rc = NimBLEUtils::checkConnParams(&m_pConnParams);
|
||||
assert(rc == 0 && "Invalid Connection parameters");
|
||||
}
|
||||
|
||||
|
@ -274,24 +277,24 @@ void NimBLEClient::setConnectionParams(uint16_t minInterval, uint16_t maxInterva
|
|||
/**
|
||||
* Update connection parameters can be called only after connection has been established
|
||||
*/
|
||||
void NimBLEClient::updateConnParams(uint16_t minInterval, uint16_t maxInterval,
|
||||
void NimBLEClient::updateConnParams(uint16_t minInterval, uint16_t maxInterval,
|
||||
uint16_t latency, uint16_t timeout)
|
||||
{
|
||||
ble_gap_upd_params params;
|
||||
{
|
||||
ble_gap_upd_params params;
|
||||
|
||||
params.latency = latency;
|
||||
params.itvl_max = maxInterval;
|
||||
params.itvl_min = minInterval;
|
||||
params.supervision_timeout = timeout;
|
||||
// These are not used by NimBLE at this time - Must leave at defaults
|
||||
params.latency = latency;
|
||||
params.itvl_max = maxInterval;
|
||||
params.itvl_min = minInterval;
|
||||
params.supervision_timeout = timeout;
|
||||
// These are not used by NimBLE at this time - Must leave at defaults
|
||||
params.min_ce_len = BLE_GAP_INITIAL_CONN_MIN_CE_LEN;
|
||||
params.max_ce_len = BLE_GAP_INITIAL_CONN_MAX_CE_LEN;
|
||||
|
||||
|
||||
int rc = ble_gap_update_params(m_conn_id, ¶ms);
|
||||
if(rc != 0) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Update params error: %d, %s",
|
||||
rc, NimBLEUtils::returnCodeToString(rc));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -331,15 +334,15 @@ int NimBLEClient::getRssi() {
|
|||
NIMBLE_LOGE(LOG_TAG, "<< getRssi(): Not connected");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int8_t rssiValue = 0;
|
||||
int rc = ble_gap_conn_rssi(m_conn_id, &rssiValue);
|
||||
if(rc != 0) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Failed to read RSSI error code: %d, %s",
|
||||
NIMBLE_LOGE(LOG_TAG, "Failed to read RSSI error code: %d, %s",
|
||||
rc, NimBLEUtils::returnCodeToString(rc));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
return rssiValue;
|
||||
} // getRssi
|
||||
|
||||
|
@ -371,7 +374,7 @@ NimBLERemoteService* NimBLEClient::getService(const NimBLEUUID &uuid) {
|
|||
NIMBLE_LOGD(LOG_TAG, "<< getService: found the service with uuid: %s", uuid.toString().c_str());
|
||||
return myPair.second;
|
||||
}
|
||||
}
|
||||
}
|
||||
NIMBLE_LOGD(LOG_TAG, "<< getService: not found");
|
||||
return nullptr;
|
||||
} // getService
|
||||
|
@ -379,7 +382,7 @@ NimBLERemoteService* NimBLEClient::getService(const NimBLEUUID &uuid) {
|
|||
|
||||
/**
|
||||
* @Get a pointer to the map of found services.
|
||||
*/
|
||||
*/
|
||||
std::map<std::string, NimBLERemoteService*>* NimBLEClient::getServices() {
|
||||
return &m_servicesMap;
|
||||
}
|
||||
|
@ -391,7 +394,7 @@ std::map<std::string, NimBLERemoteService*>* NimBLEClient::getServices() {
|
|||
* services and wait until we have received them all.
|
||||
* We then ask for the characteristics for each service found and their desciptors.
|
||||
* @return true on success otherwise false if an error occurred
|
||||
*/
|
||||
*/
|
||||
bool NimBLEClient::retrieveServices() {
|
||||
/**
|
||||
* Design
|
||||
|
@ -399,25 +402,25 @@ bool NimBLEClient::retrieveServices() {
|
|||
* We invoke ble_gattc_disc_all_svcs. This will request a list of the services exposed by the
|
||||
* peer BLE partner to be returned in the callback function provided.
|
||||
*/
|
||||
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, ">> retrieveServices");
|
||||
|
||||
|
||||
if(!m_isConnected){
|
||||
NIMBLE_LOGE(LOG_TAG, "Disconnected, could not retrieve services -aborting");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_semaphoreSearchCmplEvt.take("retrieveServices");
|
||||
|
||||
|
||||
int rc = ble_gattc_disc_all_svcs(m_conn_id, NimBLEClient::serviceDiscoveredCB, this);
|
||||
|
||||
|
||||
if (rc != 0) {
|
||||
NIMBLE_LOGE(LOG_TAG, "ble_gattc_disc_all_svcs: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
|
||||
m_haveServices = false;
|
||||
m_semaphoreSearchCmplEvt.give();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// wait until we have all the services
|
||||
// If sucessful, remember that we now have services.
|
||||
m_haveServices = (m_semaphoreSearchCmplEvt.wait("retrieveServices") == 0);
|
||||
|
@ -428,7 +431,7 @@ bool NimBLEClient::retrieveServices() {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "<< retrieveServices");
|
||||
return true;
|
||||
}
|
||||
|
@ -440,14 +443,14 @@ bool NimBLEClient::retrieveServices() {
|
|||
|
||||
|
||||
/**
|
||||
* @brief STATIC Callback for the service discovery API function.
|
||||
* @brief STATIC Callback for the service discovery API function.
|
||||
* When a service is found or there is none left or there was an error
|
||||
* the API will call this and report findings.
|
||||
*/
|
||||
int NimBLEClient::serviceDiscoveredCB(
|
||||
uint16_t conn_handle,
|
||||
uint16_t conn_handle,
|
||||
const struct ble_gatt_error *error,
|
||||
const struct ble_gatt_svc *service, void *arg)
|
||||
const struct ble_gatt_svc *service, void *arg)
|
||||
{
|
||||
NIMBLE_LOGD(LOG_TAG,"Service Discovered >> status: %d handle: %d", error->status, conn_handle);
|
||||
NimBLEClient *peer = (NimBLEClient*)arg;
|
||||
|
@ -466,7 +469,7 @@ int NimBLEClient::serviceDiscoveredCB(
|
|||
break;
|
||||
}
|
||||
case BLE_HS_EDONE:{
|
||||
// All services discovered; start discovering characteristics.
|
||||
// All services discovered; start discovering characteristics.
|
||||
|
||||
//NIMBLE_LOGD(LOG_TAG,"Giving search semaphore - completed");
|
||||
peer->m_semaphoreSearchCmplEvt.give(0);
|
||||
|
@ -481,7 +484,7 @@ int NimBLEClient::serviceDiscoveredCB(
|
|||
|
||||
if (rc != 0) {
|
||||
// pass non-zero to semaphore on error to indicate an error finding services
|
||||
peer->m_semaphoreSearchCmplEvt.give(1);
|
||||
peer->m_semaphoreSearchCmplEvt.give(1);
|
||||
}
|
||||
NIMBLE_LOGD(LOG_TAG,"<< Service Discovered. status: %d", rc);
|
||||
return rc;
|
||||
|
@ -496,10 +499,10 @@ int NimBLEClient::serviceDiscoveredCB(
|
|||
*/
|
||||
std::string NimBLEClient::getValue(const NimBLEUUID &serviceUUID, const NimBLEUUID &characteristicUUID) {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> getValue: serviceUUID: %s, characteristicUUID: %s", serviceUUID.toString().c_str(), characteristicUUID.toString().c_str());
|
||||
|
||||
|
||||
std::string ret = "";
|
||||
NimBLERemoteService* pService = getService(serviceUUID);
|
||||
|
||||
|
||||
if(pService != nullptr) {
|
||||
NimBLERemoteCharacteristic* pChar = pService->getCharacteristic(characteristicUUID);
|
||||
if(pChar != nullptr) {
|
||||
|
@ -520,17 +523,17 @@ std::string NimBLEClient::getValue(const NimBLEUUID &serviceUUID, const NimBLEUU
|
|||
*/
|
||||
bool NimBLEClient::setValue(const NimBLEUUID &serviceUUID, const NimBLEUUID &characteristicUUID, const std::string &value) {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> setValue: serviceUUID: %s, characteristicUUID: %s", serviceUUID.toString().c_str(), characteristicUUID.toString().c_str());
|
||||
|
||||
|
||||
bool ret = false;
|
||||
NimBLERemoteService* pService = getService(serviceUUID);
|
||||
|
||||
|
||||
if(pService != nullptr) {
|
||||
NimBLERemoteCharacteristic* pChar = pService->getCharacteristic(characteristicUUID);
|
||||
if(pChar != nullptr) {
|
||||
ret = pChar->writeValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "<< setValue");
|
||||
return ret;
|
||||
} // setValue
|
||||
|
@ -552,8 +555,8 @@ uint16_t NimBLEClient::getMTU() {
|
|||
* @param [in] arg = pointer to the client instance
|
||||
*/
|
||||
/*STATIC*/ int NimBLEClient::handleGapEvent(struct ble_gap_event *event, void *arg) {
|
||||
|
||||
NimBLEClient* client = (NimBLEClient*)arg;
|
||||
|
||||
NimBLEClient* client = (NimBLEClient*)arg;
|
||||
//struct ble_gap_conn_desc desc;
|
||||
//struct ble_hs_adv_fields fields;
|
||||
int rc;
|
||||
|
@ -566,22 +569,22 @@ uint16_t NimBLEClient::getMTU() {
|
|||
case BLE_GAP_EVENT_DISCONNECT: {
|
||||
if(!client->m_isConnected)
|
||||
return 0;
|
||||
|
||||
|
||||
if(client->m_conn_id != event->disconnect.conn.conn_handle)
|
||||
return 0;
|
||||
|
||||
|
||||
client->m_isConnected = false;
|
||||
client->m_waitingToConnect=false;
|
||||
// Remove the device from ignore list so we will scan it again
|
||||
NimBLEDevice::removeIgnored(client->m_peerAddress);
|
||||
|
||||
|
||||
NIMBLE_LOGI(LOG_TAG, "disconnect; reason=%d, %s", event->disconnect.reason,
|
||||
NimBLEUtils::returnCodeToString(event->disconnect.reason));
|
||||
//print_conn_desc(&event->disconnect.conn);
|
||||
//MODLOG_DFLT(INFO, "\n");
|
||||
|
||||
|
||||
// If Host reset tell the device now before returning to prevent
|
||||
|
||||
// If Host reset tell the device now before returning to prevent
|
||||
// any errors caused by calling host functions before resyncing.
|
||||
switch(event->disconnect.reason) {
|
||||
case BLE_HS_ETIMEOUT_HCI:
|
||||
|
@ -591,19 +594,19 @@ uint16_t NimBLEClient::getMTU() {
|
|||
NIMBLE_LOGC(LOG_TAG, "Disconnect - host reset, rc=%d", event->disconnect.reason);
|
||||
NimBLEDevice::onReset(event->disconnect.reason);
|
||||
break;
|
||||
default:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
//client->m_conn_id = BLE_HS_CONN_HANDLE_NONE;
|
||||
|
||||
// Indicate a non-success return value to any semaphores waiting
|
||||
|
||||
// Indicate a non-success return value to any semaphores waiting
|
||||
client->m_semaphoreOpenEvt.give(1);
|
||||
client->m_semaphoreSearchCmplEvt.give(1);
|
||||
client->m_semeaphoreSecEvt.give(1);
|
||||
|
||||
|
||||
client->m_pClientCallbacks->onDisconnect(client);
|
||||
|
||||
|
||||
return 0;
|
||||
} // BLE_GAP_EVENT_DISCONNECT
|
||||
|
||||
|
@ -611,26 +614,26 @@ uint16_t NimBLEClient::getMTU() {
|
|||
|
||||
if(!client->m_waitingToConnect)
|
||||
return 0;
|
||||
|
||||
|
||||
//if(client->m_conn_id != BLE_HS_CONN_HANDLE_NONE)
|
||||
// return 0;
|
||||
|
||||
|
||||
client->m_waitingToConnect=false;
|
||||
|
||||
|
||||
if (event->connect.status == 0) {
|
||||
client->m_isConnected = true;
|
||||
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "Connection established");
|
||||
|
||||
|
||||
client->m_conn_id = event->connect.conn_handle;
|
||||
|
||||
|
||||
// rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
|
||||
// assert(rc == 0);
|
||||
// print_conn_desc(&desc);
|
||||
// MODLOG_DFLT(INFO, "\n");
|
||||
|
||||
|
||||
// In the case of a multiconnecting device we ignore this device when
|
||||
|
||||
// In the case of a multiconnecting device we ignore this device when
|
||||
// scanning since we are already connected to it
|
||||
NimBLEDevice::addIgnored(client->m_peerAddress);
|
||||
|
||||
|
@ -638,9 +641,9 @@ uint16_t NimBLEClient::getMTU() {
|
|||
if(rc != 0) {
|
||||
NIMBLE_LOGE(LOG_TAG, "ble_gattc_exchange_mtu: rc=%d %s",rc,
|
||||
NimBLEUtils::returnCodeToString(rc));
|
||||
// if error getting mtu indicate a connection error.
|
||||
// if error getting mtu indicate a connection error.
|
||||
client->m_semaphoreOpenEvt.give(rc);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Connection attempt failed
|
||||
NIMBLE_LOGE(LOG_TAG, "Error: Connection failed; status=%d %s",
|
||||
|
@ -654,11 +657,11 @@ uint16_t NimBLEClient::getMTU() {
|
|||
case BLE_GAP_EVENT_NOTIFY_RX: {
|
||||
if(client->m_conn_id != event->notify_rx.conn_handle)
|
||||
return 0;
|
||||
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "Notify Recieved for handle: %d",event->notify_rx.attr_handle);
|
||||
if(!client->m_haveServices)
|
||||
return 0;
|
||||
|
||||
|
||||
for(auto &sPair : client->m_servicesMap){
|
||||
// Dont waste cycles searching services without this handle in their range
|
||||
if(sPair.second->getEndHandle() < event->notify_rx.attr_handle) {
|
||||
|
@ -669,20 +672,20 @@ uint16_t NimBLEClient::getMTU() {
|
|||
auto characteristic = cMap->find(event->notify_rx.attr_handle);
|
||||
if(characteristic != cMap->end()) {
|
||||
NIMBLE_LOGD(LOG_TAG, "Got Notification for characteristic %s", characteristic->second->toString().c_str());
|
||||
|
||||
|
||||
if (characteristic->second->m_notifyCallback != nullptr) {
|
||||
NIMBLE_LOGD(LOG_TAG, "Invoking callback for notification on characteristic %s", characteristic->second->toString().c_str());
|
||||
characteristic->second->m_notifyCallback(characteristic->second, event->notify_rx.om->om_data, event->notify_rx.om->om_len, !event->notify_rx.indication);
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
} // BLE_GAP_EVENT_NOTIFY_RX
|
||||
|
||||
case BLE_GAP_EVENT_CONN_UPDATE_REQ:
|
||||
|
||||
case BLE_GAP_EVENT_CONN_UPDATE_REQ:
|
||||
case BLE_GAP_EVENT_L2CAP_UPDATE_REQ: {
|
||||
if(client->m_conn_id != event->conn_update_req.conn_handle){
|
||||
return 0; //BLE_HS_ENOTCONN BLE_ATT_ERR_INVALID_HANDLE
|
||||
|
@ -696,7 +699,7 @@ uint16_t NimBLEClient::getMTU() {
|
|||
|
||||
rc = client->m_pClientCallbacks->onConnParamsUpdateRequest(client,
|
||||
event->conn_update_req.peer_params) ? 0 : BLE_ERR_CONN_PARMS;
|
||||
|
||||
|
||||
|
||||
if(!rc && event->type == BLE_GAP_EVENT_CONN_UPDATE_REQ ) {
|
||||
event->conn_update_req.self_params->itvl_min = client->m_pConnParams.itvl_min;
|
||||
|
@ -708,7 +711,7 @@ uint16_t NimBLEClient::getMTU() {
|
|||
NIMBLE_LOGD(LOG_TAG, "%s peer params", (rc == 0) ? "Accepted" : "Rejected");
|
||||
return rc;
|
||||
} // BLE_GAP_EVENT_CONN_UPDATE_REQ, BLE_GAP_EVENT_L2CAP_UPDATE_REQ
|
||||
|
||||
|
||||
case BLE_GAP_EVENT_CONN_UPDATE: {
|
||||
if(client->m_conn_id != event->conn_update.conn_handle){
|
||||
return 0; //BLE_HS_ENOTCONN BLE_ATT_ERR_INVALID_HANDLE
|
||||
|
@ -720,28 +723,28 @@ uint16_t NimBLEClient::getMTU() {
|
|||
}
|
||||
return 0;
|
||||
} // BLE_GAP_EVENT_CONN_UPDATE
|
||||
|
||||
|
||||
case BLE_GAP_EVENT_ENC_CHANGE: {
|
||||
if(client->m_conn_id != event->enc_change.conn_handle){
|
||||
return 0; //BLE_HS_ENOTCONN BLE_ATT_ERR_INVALID_HANDLE
|
||||
}
|
||||
|
||||
|
||||
if(event->enc_change.status == 0) {
|
||||
struct ble_gap_conn_desc desc;
|
||||
rc = ble_gap_conn_find(event->conn_update.conn_handle, &desc);
|
||||
assert(rc == 0);
|
||||
|
||||
|
||||
if(NimBLEDevice::m_securityCallbacks != nullptr) {
|
||||
NimBLEDevice::m_securityCallbacks->onAuthenticationComplete(&desc);
|
||||
} else {
|
||||
client->m_pClientCallbacks->onAuthenticationComplete(&desc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
client->m_semeaphoreSecEvt.give(event->enc_change.status);
|
||||
return 0;
|
||||
} //BLE_GAP_EVENT_ENC_CHANGE
|
||||
|
||||
|
||||
case BLE_GAP_EVENT_MTU: {
|
||||
if(client->m_conn_id != event->mtu.conn_handle){
|
||||
return 0; //BLE_HS_ENOTCONN BLE_ATT_ERR_INVALID_HANDLE
|
||||
|
@ -749,15 +752,15 @@ uint16_t NimBLEClient::getMTU() {
|
|||
NIMBLE_LOGI(LOG_TAG, "mtu update event; conn_handle=%d mtu=%d",
|
||||
event->mtu.conn_handle,
|
||||
event->mtu.value);
|
||||
client->m_semaphoreOpenEvt.give(0);
|
||||
client->m_semaphoreOpenEvt.give(0);
|
||||
//client->m_mtu = event->mtu.value;
|
||||
return 0;
|
||||
} // BLE_GAP_EVENT_MTU
|
||||
|
||||
|
||||
case BLE_GAP_EVENT_PASSKEY_ACTION: {
|
||||
struct ble_sm_io pkey = {0};
|
||||
|
||||
if(client->m_conn_id != event->passkey.conn_handle)
|
||||
|
||||
if(client->m_conn_id != event->passkey.conn_handle)
|
||||
return 0;
|
||||
|
||||
if (event->passkey.params.action == BLE_SM_IOACT_DISP) {
|
||||
|
@ -765,7 +768,7 @@ uint16_t NimBLEClient::getMTU() {
|
|||
pkey.passkey = NimBLEDevice::m_passkey; // This is the passkey to be entered on peer
|
||||
rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
|
||||
NIMBLE_LOGD(LOG_TAG, "ble_sm_inject_io result: %d", rc);
|
||||
|
||||
|
||||
} else if (event->passkey.params.action == BLE_SM_IOACT_NUMCMP) {
|
||||
NIMBLE_LOGD(LOG_TAG, "Passkey on device's display: %d", event->passkey.params.numcmp);
|
||||
pkey.action = event->passkey.params.action;
|
||||
|
@ -779,8 +782,8 @@ uint16_t NimBLEClient::getMTU() {
|
|||
|
||||
rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
|
||||
NIMBLE_LOGD(LOG_TAG, "ble_sm_inject_io result: %d", rc);
|
||||
|
||||
//TODO: Handle out of band pairing
|
||||
|
||||
//TODO: Handle out of band pairing
|
||||
} else if (event->passkey.params.action == BLE_SM_IOACT_OOB) {
|
||||
static uint8_t tem_oob[16] = {0};
|
||||
pkey.action = event->passkey.params.action;
|
||||
|
@ -789,11 +792,11 @@ uint16_t NimBLEClient::getMTU() {
|
|||
}
|
||||
rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
|
||||
NIMBLE_LOGD(LOG_TAG, "ble_sm_inject_io result: %d", rc);
|
||||
////////
|
||||
////////
|
||||
} else if (event->passkey.params.action == BLE_SM_IOACT_INPUT) {
|
||||
NIMBLE_LOGD(LOG_TAG, "Enter the passkey");
|
||||
pkey.action = event->passkey.params.action;
|
||||
|
||||
|
||||
// Compatibility only - Do not use, should be removed the in future
|
||||
if(NimBLEDevice::m_securityCallbacks != nullptr) {
|
||||
pkey.passkey = NimBLEDevice::m_securityCallbacks->onPassKeyRequest();
|
||||
|
@ -804,14 +807,14 @@ uint16_t NimBLEClient::getMTU() {
|
|||
|
||||
rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
|
||||
NIMBLE_LOGD(LOG_TAG, "ble_sm_inject_io result: %d", rc);
|
||||
|
||||
|
||||
} else if (event->passkey.params.action == BLE_SM_IOACT_NONE) {
|
||||
NIMBLE_LOGD(LOG_TAG, "No passkey action required");
|
||||
}
|
||||
|
||||
return 0;
|
||||
} // BLE_GAP_EVENT_PASSKEY_ACTION
|
||||
|
||||
|
||||
default: {
|
||||
return 0;
|
||||
}
|
||||
|
@ -833,10 +836,10 @@ bool NimBLEClient::isConnected() {
|
|||
*/
|
||||
void NimBLEClient::setClientCallbacks(NimBLEClientCallbacks* pClientCallbacks, bool deleteCallbacks) {
|
||||
if (pClientCallbacks != nullptr){
|
||||
m_pClientCallbacks = pClientCallbacks;
|
||||
} else {
|
||||
m_pClientCallbacks = &defaultCallbacks;
|
||||
}
|
||||
m_pClientCallbacks = pClientCallbacks;
|
||||
} else {
|
||||
m_pClientCallbacks = &defaultCallbacks;
|
||||
}
|
||||
m_deleteCallbacks = deleteCallbacks;
|
||||
} // setClientCallbacks
|
||||
|
||||
|
@ -865,7 +868,7 @@ void NimBLEClientCallbacks::onDisconnect(NimBLEClient* pClient) {
|
|||
}
|
||||
|
||||
bool NimBLEClientCallbacks::onConnParamsUpdateRequest(NimBLEClient* pClient, const ble_gap_upd_params* params) {
|
||||
NIMBLE_LOGD("NimBLEClientCallbacks", "onConnParamsUpdateRequest: default");
|
||||
NIMBLE_LOGD("NimBLEClientCallbacks", "onConnParamsUpdateRequest: default");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -890,4 +893,5 @@ bool NimBLEClientCallbacks::onConfirmPIN(uint32_t pin){
|
|||
return true;
|
||||
}
|
||||
|
||||
#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||
#endif // CONFIG_BT_ENABLED
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on Jan 26 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
* BLEClient.h
|
||||
*
|
||||
|
@ -14,8 +14,11 @@
|
|||
#ifndef MAIN_NIMBLECLIENT_H_
|
||||
#define MAIN_NIMBLECLIENT_H_
|
||||
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||
|
||||
#include "NimBLEAddress.h"
|
||||
#include "NimBLEAdvertisedDevice.h"
|
||||
|
@ -50,13 +53,13 @@ public:
|
|||
uint16_t getMTU();
|
||||
bool secureConnection();
|
||||
void setConnectTimeout(uint8_t timeout);
|
||||
void setConnectionParams(uint16_t minInterval, uint16_t maxInterval,
|
||||
uint16_t latency, uint16_t timeout,
|
||||
void setConnectionParams(uint16_t minInterval, uint16_t maxInterval,
|
||||
uint16_t latency, uint16_t timeout,
|
||||
uint16_t scanInterval=16, uint16_t scanWindow=16); // NimBLE default scan settings
|
||||
void updateConnParams(uint16_t minInterval, uint16_t maxInterval,
|
||||
uint16_t latency, uint16_t timeout);
|
||||
|
||||
|
||||
void updateConnParams(uint16_t minInterval, uint16_t maxInterval,
|
||||
uint16_t latency, uint16_t timeout);
|
||||
|
||||
|
||||
private:
|
||||
NimBLEClient();
|
||||
~NimBLEClient();
|
||||
|
@ -75,7 +78,7 @@ private:
|
|||
bool m_isConnected = false; // Are we currently connected.
|
||||
bool m_waitingToConnect =false;
|
||||
bool m_deleteCallbacks = true;
|
||||
int32_t m_connectTimeout;
|
||||
int32_t m_connectTimeout;
|
||||
//uint16_t m_mtu = 23;
|
||||
|
||||
NimBLEClientCallbacks* m_pClientCallbacks = nullptr;
|
||||
|
@ -85,12 +88,12 @@ private:
|
|||
FreeRTOS::Semaphore m_semeaphoreSecEvt = FreeRTOS::Semaphore("Security");
|
||||
|
||||
std::map<std::string, NimBLERemoteService*> m_servicesMap;
|
||||
|
||||
|
||||
private:
|
||||
friend class NimBLEClientCallbacks;
|
||||
ble_gap_conn_params m_pConnParams;
|
||||
|
||||
}; // class NimBLEClient
|
||||
}; // class NimBLEClient
|
||||
|
||||
|
||||
/**
|
||||
|
@ -109,5 +112,6 @@ public:
|
|||
virtual bool onConfirmPIN(uint32_t pin);
|
||||
};
|
||||
|
||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||
#endif // CONFIG_BT_ENABLED
|
||||
#endif /* MAIN_NIMBLECLIENT_H_ */
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on March 10, 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLEDescriptor.cpp
|
||||
|
@ -14,6 +14,9 @@
|
|||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
|
||||
#include "NimBLEService.h"
|
||||
#include "NimBLEDescriptor.h"
|
||||
#include "NimBLELog.h"
|
||||
|
@ -29,26 +32,26 @@ static NimBLEDescriptorCallbacks defaultCallbacks;
|
|||
/**
|
||||
* @brief NimBLEDescriptor constructor.
|
||||
*/
|
||||
NimBLEDescriptor::NimBLEDescriptor(const char* uuid, uint16_t properties, uint16_t max_len,
|
||||
NimBLECharacteristic* pCharacteristic)
|
||||
NimBLEDescriptor::NimBLEDescriptor(const char* uuid, uint16_t properties, uint16_t max_len,
|
||||
NimBLECharacteristic* pCharacteristic)
|
||||
: NimBLEDescriptor(NimBLEUUID(uuid), max_len, properties, pCharacteristic) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief NimBLEDescriptor constructor.
|
||||
*/
|
||||
NimBLEDescriptor::NimBLEDescriptor(NimBLEUUID uuid, uint16_t properties, uint16_t max_len,
|
||||
NimBLECharacteristic* pCharacteristic)
|
||||
NimBLECharacteristic* pCharacteristic)
|
||||
{
|
||||
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_pCharacteristic = nullptr; // No initial characteristic.
|
||||
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_pCharacteristic = nullptr; // No initial characteristic.
|
||||
m_pCallbacks = &defaultCallbacks; // No initial callback.
|
||||
m_value.attr_value = (uint8_t*) calloc(max_len,1); // Allocate storage for the value.
|
||||
m_properties = 0;
|
||||
|
||||
|
||||
if (properties & BLE_GATT_CHR_F_READ) { // convert uint16_t properties to uint8_t
|
||||
m_properties |= BLE_ATT_F_READ;
|
||||
}
|
||||
|
@ -81,7 +84,7 @@ NimBLEDescriptor::NimBLEDescriptor(NimBLEUUID uuid, uint16_t properties, uint16_
|
|||
* @brief NimBLEDescriptor destructor.
|
||||
*/
|
||||
NimBLEDescriptor::~NimBLEDescriptor() {
|
||||
free(m_value.attr_value); // Release the storage we created in the constructor.
|
||||
free(m_value.attr_value); // Release the storage we created in the constructor.
|
||||
} // ~NimBLEDescriptor
|
||||
|
||||
/**
|
||||
|
@ -89,7 +92,7 @@ NimBLEDescriptor::~NimBLEDescriptor() {
|
|||
* @return The handle for this descriptor.
|
||||
*/
|
||||
uint16_t NimBLEDescriptor::getHandle() {
|
||||
return m_handle;
|
||||
return m_handle;
|
||||
} // getHandle
|
||||
|
||||
|
||||
|
@ -98,7 +101,7 @@ uint16_t NimBLEDescriptor::getHandle() {
|
|||
* @return The length (in bytes) of the value of this descriptor.
|
||||
*/
|
||||
size_t NimBLEDescriptor::getLength() {
|
||||
return m_value.attr_len;
|
||||
return m_value.attr_len;
|
||||
} // getLength
|
||||
|
||||
|
||||
|
@ -106,7 +109,7 @@ size_t NimBLEDescriptor::getLength() {
|
|||
* @brief Get the UUID of the descriptor.
|
||||
*/
|
||||
NimBLEUUID NimBLEDescriptor::getUUID() {
|
||||
return m_uuid;
|
||||
return m_uuid;
|
||||
} // getUUID
|
||||
|
||||
|
||||
|
@ -115,7 +118,7 @@ NimBLEUUID NimBLEDescriptor::getUUID() {
|
|||
* @return A pointer to the value of this descriptor.
|
||||
*/
|
||||
uint8_t* NimBLEDescriptor::getValue() {
|
||||
return m_value.attr_value;
|
||||
return m_value.attr_value;
|
||||
} // getValue
|
||||
|
||||
|
||||
|
@ -125,25 +128,25 @@ int NimBLEDescriptor::handleGapEvent(uint16_t conn_handle, uint16_t attr_handle,
|
|||
{
|
||||
const ble_uuid_t *uuid;
|
||||
int rc;
|
||||
NimBLEDescriptor* pDescriptor = (NimBLEDescriptor*)arg;
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "Descriptor %s %s event", pDescriptor->getUUID().toString().c_str(),
|
||||
NimBLEDescriptor* pDescriptor = (NimBLEDescriptor*)arg;
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "Descriptor %s %s event", pDescriptor->getUUID().toString().c_str(),
|
||||
ctxt->op == BLE_GATT_ACCESS_OP_READ_DSC ? "Read" : "Write");
|
||||
|
||||
uuid = ctxt->chr->uuid;
|
||||
if(ble_uuid_cmp(uuid, &pDescriptor->getUUID().getNative()->u) == 0){
|
||||
|
||||
uuid = ctxt->chr->uuid;
|
||||
if(ble_uuid_cmp(uuid, &pDescriptor->getUUID().getNative()->u) == 0){
|
||||
switch(ctxt->op) {
|
||||
case BLE_GATT_ACCESS_OP_READ_DSC: {
|
||||
pDescriptor->m_pCallbacks->onRead(pDescriptor);
|
||||
rc = os_mbuf_append(ctxt->om, pDescriptor->getValue(), pDescriptor->getLength());
|
||||
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
|
||||
}
|
||||
|
||||
|
||||
case BLE_GATT_ACCESS_OP_WRITE_DSC: {
|
||||
if (ctxt->om->om_len > BLE_ATT_ATTR_MAX_LEN) {
|
||||
return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
|
||||
}
|
||||
|
||||
|
||||
pDescriptor->setValue(ctxt->om->om_data, ctxt->om->om_len);
|
||||
pDescriptor->m_pCallbacks->onWrite(pDescriptor);
|
||||
return 0;
|
||||
|
@ -151,8 +154,8 @@ int NimBLEDescriptor::handleGapEvent(uint16_t conn_handle, uint16_t attr_handle,
|
|||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return BLE_ATT_ERR_UNLIKELY;
|
||||
}
|
||||
|
||||
|
@ -162,10 +165,10 @@ int NimBLEDescriptor::handleGapEvent(uint16_t conn_handle, uint16_t attr_handle,
|
|||
*/
|
||||
void NimBLEDescriptor::setCallbacks(NimBLEDescriptorCallbacks* pCallbacks) {
|
||||
if (pCallbacks != nullptr){
|
||||
m_pCallbacks = pCallbacks;
|
||||
} else {
|
||||
m_pCallbacks = &defaultCallbacks;
|
||||
}
|
||||
m_pCallbacks = pCallbacks;
|
||||
} else {
|
||||
m_pCallbacks = &defaultCallbacks;
|
||||
}
|
||||
} // setCallbacks
|
||||
|
||||
|
||||
|
@ -176,9 +179,9 @@ void NimBLEDescriptor::setCallbacks(NimBLEDescriptorCallbacks* pCallbacks) {
|
|||
* @return N/A.
|
||||
*/
|
||||
void NimBLEDescriptor::setHandle(uint16_t handle) {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> setHandle(0x%.2x): Setting descriptor handle to be 0x%.2x", handle, handle);
|
||||
m_handle = handle;
|
||||
NIMBLE_LOGD(LOG_TAG, "<< setHandle()");
|
||||
NIMBLE_LOGD(LOG_TAG, ">> setHandle(0x%.2x): Setting descriptor handle to be 0x%.2x", handle, handle);
|
||||
m_handle = handle;
|
||||
NIMBLE_LOGD(LOG_TAG, "<< setHandle()");
|
||||
} // setHandle
|
||||
|
||||
|
||||
|
@ -188,12 +191,12 @@ void NimBLEDescriptor::setHandle(uint16_t handle) {
|
|||
* @param [in] length The length of the data in bytes.
|
||||
*/
|
||||
void NimBLEDescriptor::setValue(const uint8_t* data, size_t length) {
|
||||
if (length > BLE_ATT_ATTR_MAX_LEN) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Size %d too large, must be no bigger than %d", length, BLE_ATT_ATTR_MAX_LEN);
|
||||
return;
|
||||
}
|
||||
m_value.attr_len = length;
|
||||
memcpy(m_value.attr_value, data, length);
|
||||
if (length > BLE_ATT_ATTR_MAX_LEN) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Size %d too large, must be no bigger than %d", length, BLE_ATT_ATTR_MAX_LEN);
|
||||
return;
|
||||
}
|
||||
m_value.attr_len = length;
|
||||
memcpy(m_value.attr_value, data, length);
|
||||
} // setValue
|
||||
|
||||
|
||||
|
@ -202,15 +205,15 @@ void NimBLEDescriptor::setValue(const uint8_t* data, size_t length) {
|
|||
* @param [in] value The value of the descriptor in string form.
|
||||
*/
|
||||
void NimBLEDescriptor::setValue(const std::string &value) {
|
||||
setValue((uint8_t*) value.data(), value.length());
|
||||
setValue((uint8_t*) value.data(), value.length());
|
||||
} // setValue
|
||||
|
||||
|
||||
/*
|
||||
void NimBLEDescriptor::setAccessPermissions(uint8_t perm) {
|
||||
m_permissions = perm;
|
||||
m_permissions = perm;
|
||||
}
|
||||
*/
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
|
@ -218,10 +221,10 @@ void NimBLEDescriptor::setAccessPermissions(uint8_t perm) {
|
|||
* @return A string representation of the descriptor.
|
||||
*/
|
||||
std::string NimBLEDescriptor::toString() {
|
||||
char hex[5];
|
||||
snprintf(hex, sizeof(hex), "%04x", m_handle);
|
||||
std::string res = "UUID: " + m_uuid.toString() + ", handle: 0x" + hex;
|
||||
return res;
|
||||
char hex[5];
|
||||
snprintf(hex, sizeof(hex), "%04x", m_handle);
|
||||
std::string res = "UUID: " + m_uuid.toString() + ", handle: 0x" + hex;
|
||||
return res;
|
||||
} // toString
|
||||
|
||||
|
||||
|
@ -232,7 +235,7 @@ NimBLEDescriptorCallbacks::~NimBLEDescriptorCallbacks() {}
|
|||
* @param [in] pDescriptor The descriptor that is the source of the event.
|
||||
*/
|
||||
void NimBLEDescriptorCallbacks::onRead(NimBLEDescriptor* pDescriptor) {
|
||||
NIMBLE_LOGD("NimBLEDescriptorCallbacks", "onRead: default");
|
||||
NIMBLE_LOGD("NimBLEDescriptorCallbacks", "onRead: default");
|
||||
} // onRead
|
||||
|
||||
|
||||
|
@ -241,8 +244,8 @@ void NimBLEDescriptorCallbacks::onRead(NimBLEDescriptor* pDescriptor) {
|
|||
* @param [in] pDescriptor The descriptor that is the source of the event.
|
||||
*/
|
||||
void NimBLEDescriptorCallbacks::onWrite(NimBLEDescriptor* pDescriptor) {
|
||||
NIMBLE_LOGD("NimBLEDescriptorCallbacks", "onWrite: default");
|
||||
NIMBLE_LOGD("NimBLEDescriptorCallbacks", "onWrite: default");
|
||||
} // onWrite
|
||||
|
||||
|
||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
#endif /* CONFIG_BT_ENABLED */
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on March 10, 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLEDescriptor.h
|
||||
|
@ -17,6 +17,9 @@
|
|||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
|
||||
#include "NimBLECharacteristic.h"
|
||||
#include "NimBLEUUID.h"
|
||||
#include "FreeRTOS.h"
|
||||
|
@ -43,44 +46,44 @@ class NimBLEDescriptorCallbacks;
|
|||
*/
|
||||
class NimBLEDescriptor {
|
||||
public:
|
||||
virtual ~NimBLEDescriptor();
|
||||
uint16_t getHandle(); // Get the handle of the descriptor.
|
||||
size_t getLength(); // Get the length of the value of the descriptor.
|
||||
NimBLEUUID getUUID(); // Get the UUID of the descriptor.
|
||||
uint8_t* getValue(); // Get a pointer to the value of the descriptor.
|
||||
// void setAccessPermissions(uint8_t perm); // Set the permissions of the descriptor.
|
||||
void setCallbacks(NimBLEDescriptorCallbacks* pCallbacks); // Set callbacks to be invoked for the descriptor.
|
||||
void setValue(const uint8_t* data, size_t size); // Set the value of the descriptor as a pointer to data.
|
||||
void setValue(const std::string &value); // Set the value of the descriptor as a data buffer.
|
||||
virtual ~NimBLEDescriptor();
|
||||
uint16_t getHandle(); // Get the handle of the descriptor.
|
||||
size_t getLength(); // Get the length of the value of the descriptor.
|
||||
NimBLEUUID getUUID(); // Get the UUID of the descriptor.
|
||||
uint8_t* getValue(); // Get a pointer to the value of the descriptor.
|
||||
// void setAccessPermissions(uint8_t perm); // Set the permissions of the descriptor.
|
||||
void setCallbacks(NimBLEDescriptorCallbacks* pCallbacks); // Set callbacks to be invoked for the descriptor.
|
||||
void setValue(const uint8_t* data, size_t size); // Set the value of the descriptor as a pointer to data.
|
||||
void setValue(const std::string &value); // Set the value of the descriptor as a data buffer.
|
||||
|
||||
std::string toString(); // Convert the descriptor to a string representation.
|
||||
std::string toString(); // Convert the descriptor to a string representation.
|
||||
|
||||
private:
|
||||
friend class NimBLEDescriptorMap;
|
||||
friend class NimBLECharacteristic;
|
||||
friend class NimBLEDescriptorMap;
|
||||
friend class NimBLECharacteristic;
|
||||
friend class NimBLEService;
|
||||
friend class NimBLE2902;
|
||||
friend class NimBLE2904;
|
||||
|
||||
NimBLEDescriptor(const char* uuid, uint16_t properties,
|
||||
uint16_t max_len,
|
||||
NimBLECharacteristic* pCharacteristic);
|
||||
|
||||
NimBLEDescriptor(NimBLEUUID uuid, uint16_t properties,
|
||||
uint16_t max_len,
|
||||
NimBLECharacteristic* pCharacteristic);
|
||||
|
||||
NimBLEUUID m_uuid;
|
||||
uint16_t m_handle;
|
||||
NimBLEDescriptorCallbacks* m_pCallbacks;
|
||||
NimBLECharacteristic* m_pCharacteristic;
|
||||
uint8_t m_properties;
|
||||
attr_value_t m_value;
|
||||
friend class NimBLE2902;
|
||||
friend class NimBLE2904;
|
||||
|
||||
static int handleGapEvent(uint16_t conn_handle, uint16_t attr_handle,
|
||||
NimBLEDescriptor(const char* uuid, uint16_t properties,
|
||||
uint16_t max_len,
|
||||
NimBLECharacteristic* pCharacteristic);
|
||||
|
||||
NimBLEDescriptor(NimBLEUUID uuid, uint16_t properties,
|
||||
uint16_t max_len,
|
||||
NimBLECharacteristic* pCharacteristic);
|
||||
|
||||
NimBLEUUID m_uuid;
|
||||
uint16_t m_handle;
|
||||
NimBLEDescriptorCallbacks* m_pCallbacks;
|
||||
NimBLECharacteristic* m_pCharacteristic;
|
||||
uint8_t m_properties;
|
||||
attr_value_t m_value;
|
||||
|
||||
static int handleGapEvent(uint16_t conn_handle, uint16_t attr_handle,
|
||||
struct ble_gatt_access_ctxt *ctxt, void *arg);
|
||||
|
||||
void setHandle(uint16_t handle);
|
||||
|
||||
void setHandle(uint16_t handle);
|
||||
}; // BLEDescriptor
|
||||
|
||||
|
||||
|
@ -93,9 +96,11 @@ private:
|
|||
*/
|
||||
class NimBLEDescriptorCallbacks {
|
||||
public:
|
||||
virtual ~NimBLEDescriptorCallbacks();
|
||||
virtual void onRead(NimBLEDescriptor* pDescriptor);
|
||||
virtual void onWrite(NimBLEDescriptor* pDescriptor);
|
||||
virtual ~NimBLEDescriptorCallbacks();
|
||||
virtual void onRead(NimBLEDescriptor* pDescriptor);
|
||||
virtual void onWrite(NimBLEDescriptor* pDescriptor);
|
||||
};
|
||||
|
||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
#endif /* CONFIG_BT_ENABLED */
|
||||
#endif /* MAIN_NIMBLEDESCRIPTOR_H_ */
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on March 10, 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLEDescriptorMap.cpp
|
||||
|
@ -13,6 +13,10 @@
|
|||
*/
|
||||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
|
||||
#include "NimBLECharacteristic.h"
|
||||
#include "NimBLEDescriptor.h"
|
||||
|
||||
|
@ -23,7 +27,7 @@
|
|||
* @return The descriptor. If not present, then nullptr is returned.
|
||||
*/
|
||||
NimBLEDescriptor* NimBLEDescriptorMap::getByUUID(const char* uuid) {
|
||||
return getByUUID(NimBLEUUID(uuid));
|
||||
return getByUUID(NimBLEUUID(uuid));
|
||||
}
|
||||
|
||||
|
||||
|
@ -33,12 +37,12 @@ NimBLEDescriptor* NimBLEDescriptorMap::getByUUID(const char* uuid) {
|
|||
* @return The descriptor. If not present, then nullptr is returned.
|
||||
*/
|
||||
NimBLEDescriptor* NimBLEDescriptorMap::getByUUID(const NimBLEUUID &uuid) {
|
||||
for (auto &myPair : m_uuidMap) {
|
||||
if (myPair.first->getUUID().equals(uuid)) {
|
||||
return myPair.first;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
for (auto &myPair : m_uuidMap) {
|
||||
if (myPair.first->getUUID().equals(uuid)) {
|
||||
return myPair.first;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
} // getByUUID
|
||||
|
||||
|
||||
|
@ -49,7 +53,7 @@ NimBLEDescriptor* NimBLEDescriptorMap::getByUUID(const NimBLEUUID &uuid) {
|
|||
*/
|
||||
/*
|
||||
NimBLEDescriptor* NimBLEDescriptorMap::getByHandle(uint16_t handle) {
|
||||
return m_handleMap.at(handle);
|
||||
return m_handleMap.at(handle);
|
||||
} // getByHandle
|
||||
*/
|
||||
|
||||
|
@ -60,7 +64,7 @@ NimBLEDescriptor* NimBLEDescriptorMap::getByHandle(uint16_t handle) {
|
|||
* @return N/A.
|
||||
*/
|
||||
void NimBLEDescriptorMap::setByUUID(const char* uuid, NimBLEDescriptor* pDescriptor){
|
||||
m_uuidMap.insert(std::pair<NimBLEDescriptor*, std::string>(pDescriptor, uuid));
|
||||
m_uuidMap.insert(std::pair<NimBLEDescriptor*, std::string>(pDescriptor, uuid));
|
||||
} // setByUUID
|
||||
|
||||
|
||||
|
@ -72,7 +76,7 @@ void NimBLEDescriptorMap::setByUUID(const char* uuid, NimBLEDescriptor* pDescrip
|
|||
* @return N/A.
|
||||
*/
|
||||
void NimBLEDescriptorMap::setByUUID(const NimBLEUUID &uuid, NimBLEDescriptor* pDescriptor) {
|
||||
m_uuidMap.insert(std::pair<NimBLEDescriptor*, std::string>(pDescriptor, uuid.toString()));
|
||||
m_uuidMap.insert(std::pair<NimBLEDescriptor*, std::string>(pDescriptor, uuid.toString()));
|
||||
} // setByUUID
|
||||
|
||||
|
||||
|
@ -84,7 +88,7 @@ void NimBLEDescriptorMap::setByUUID(const NimBLEUUID &uuid, NimBLEDescriptor* pD
|
|||
*/
|
||||
/*
|
||||
void NimBLEDescriptorMap::setByHandle(uint16_t handle, NimBLEDescriptor* pDescriptor) {
|
||||
m_handleMap.insert(std::pair<uint16_t, NimBLEDescriptor*>(handle, pDescriptor));
|
||||
m_handleMap.insert(std::pair<uint16_t, NimBLEDescriptor*>(handle, pDescriptor));
|
||||
} // setByHandle
|
||||
*/
|
||||
|
||||
|
@ -93,7 +97,7 @@ void NimBLEDescriptorMap::setByHandle(uint16_t handle, NimBLEDescriptor* pDescri
|
|||
* @brief Get the number of descriptors in the map.
|
||||
*/
|
||||
uint8_t NimBLEDescriptorMap::getSize() {
|
||||
return (uint8_t)m_uuidMap.size();
|
||||
return (uint8_t)m_uuidMap.size();
|
||||
} // getSize
|
||||
|
||||
|
||||
|
@ -102,18 +106,18 @@ uint8_t NimBLEDescriptorMap::getSize() {
|
|||
* @return A string representation of the descriptor map.
|
||||
*/
|
||||
std::string NimBLEDescriptorMap::toString() {
|
||||
std::string res;
|
||||
char hex[5];
|
||||
int count = 0;
|
||||
for (auto &myPair : m_uuidMap) {
|
||||
if (count > 0) {res += "\n";}
|
||||
snprintf(hex, sizeof(hex), "%04x", myPair.first->getHandle());
|
||||
count++;
|
||||
res += "handle: 0x";
|
||||
res += hex;
|
||||
res += ", uuid: " + myPair.first->getUUID().toString();
|
||||
}
|
||||
return res;
|
||||
std::string res;
|
||||
char hex[5];
|
||||
int count = 0;
|
||||
for (auto &myPair : m_uuidMap) {
|
||||
if (count > 0) {res += "\n";}
|
||||
snprintf(hex, sizeof(hex), "%04x", myPair.first->getHandle());
|
||||
count++;
|
||||
res += "handle: 0x";
|
||||
res += hex;
|
||||
res += ", uuid: " + myPair.first->getUUID().toString();
|
||||
}
|
||||
return res;
|
||||
} // toString
|
||||
|
||||
|
||||
|
@ -122,11 +126,11 @@ std::string NimBLEDescriptorMap::toString() {
|
|||
* @return The first descriptor in the map.
|
||||
*/
|
||||
NimBLEDescriptor* NimBLEDescriptorMap::getFirst() {
|
||||
m_iterator = m_uuidMap.begin();
|
||||
if (m_iterator == m_uuidMap.end()) return nullptr;
|
||||
NimBLEDescriptor* pRet = m_iterator->first;
|
||||
m_iterator++;
|
||||
return pRet;
|
||||
m_iterator = m_uuidMap.begin();
|
||||
if (m_iterator == m_uuidMap.end()) return nullptr;
|
||||
NimBLEDescriptor* pRet = m_iterator->first;
|
||||
m_iterator++;
|
||||
return pRet;
|
||||
} // getFirst
|
||||
|
||||
|
||||
|
@ -135,9 +139,11 @@ NimBLEDescriptor* NimBLEDescriptorMap::getFirst() {
|
|||
* @return The next descriptor in the map.
|
||||
*/
|
||||
NimBLEDescriptor* NimBLEDescriptorMap::getNext() {
|
||||
if (m_iterator == m_uuidMap.end()) return nullptr;
|
||||
NimBLEDescriptor* pRet = m_iterator->first;
|
||||
m_iterator++;
|
||||
return pRet;
|
||||
if (m_iterator == m_uuidMap.end()) return nullptr;
|
||||
NimBLEDescriptor* pRet = m_iterator->first;
|
||||
m_iterator++;
|
||||
return pRet;
|
||||
} // getNext
|
||||
|
||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
#endif /* CONFIG_BT_ENABLED */
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on Jan 24 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLEDevice.cpp
|
||||
|
@ -14,6 +14,7 @@
|
|||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#include "NimBLEDevice.h"
|
||||
#include "NimBLEUtils.h"
|
||||
|
||||
|
@ -40,61 +41,63 @@ static const char* LOG_TAG = "NimBLEDevice";
|
|||
* Singletons for the NimBLEDevice.
|
||||
*/
|
||||
bool initialized = false;
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
||||
NimBLEScan* NimBLEDevice::m_pScan = nullptr;
|
||||
#endif
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
NimBLEServer* NimBLEDevice::m_pServer = nullptr;
|
||||
#endif
|
||||
uint32_t NimBLEDevice::m_passkey = 123456;
|
||||
bool NimBLEDevice::m_synced = false;
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
|
||||
NimBLEAdvertising* NimBLEDevice::m_bleAdvertising = nullptr;
|
||||
#endif
|
||||
|
||||
gap_event_handler NimBLEDevice::m_customGapHandler = nullptr;
|
||||
ble_gap_event_listener NimBLEDevice::m_listener;
|
||||
#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||
std::list <NimBLEClient*> NimBLEDevice::m_cList;
|
||||
#endif
|
||||
std::list <NimBLEAddress> NimBLEDevice::m_ignoreList;
|
||||
NimBLESecurityCallbacks* NimBLEDevice::m_securityCallbacks = nullptr;
|
||||
|
||||
//std::map<uint16_t, conn_status_t> BLEDevice::m_connectedClientsMap;
|
||||
|
||||
//gattc_event_handler BLEDevice::m_customGattcHandler = nullptr;
|
||||
//gatts_event_handler BLEDevice::m_customGattsHandler = nullptr;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Create a new instance of a server.
|
||||
* @return A new instance of the server.
|
||||
*/
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
/* STATIC */ NimBLEServer* NimBLEDevice::createServer() {
|
||||
/*#ifndef CONFIG_GATTS_ENABLE // Check that BLE GATTS is enabled in make menuconfig
|
||||
NIMBLE_LOGE(LOG_TAG, "BLE GATTS is not enabled - CONFIG_GATTS_ENABLE not defined");
|
||||
abort();
|
||||
#endif // CONFIG_GATTS_ENABLE
|
||||
*/
|
||||
if(NimBLEDevice::m_pServer == nullptr) {
|
||||
NimBLEDevice::m_pServer = new NimBLEServer();
|
||||
ble_gatts_reset();
|
||||
ble_gatts_reset();
|
||||
ble_svc_gap_init();
|
||||
ble_svc_gatt_init();
|
||||
}
|
||||
|
||||
return m_pServer;
|
||||
} // createServer
|
||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
|
||||
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
|
||||
NimBLEAdvertising* NimBLEDevice::getAdvertising() {
|
||||
if(m_bleAdvertising == nullptr) {
|
||||
m_bleAdvertising = new NimBLEAdvertising();
|
||||
}
|
||||
return m_bleAdvertising;
|
||||
if(m_bleAdvertising == nullptr) {
|
||||
m_bleAdvertising = new NimBLEAdvertising();
|
||||
}
|
||||
return m_bleAdvertising;
|
||||
}
|
||||
|
||||
|
||||
void NimBLEDevice::startAdvertising() {
|
||||
getAdvertising()->start();
|
||||
getAdvertising()->start();
|
||||
} // startAdvertising
|
||||
|
||||
|
||||
void NimBLEDevice::stopAdvertising() {
|
||||
getAdvertising()->stop();
|
||||
} // stopAdvertising
|
||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
|
||||
|
||||
|
||||
/**
|
||||
|
@ -102,25 +105,27 @@ void NimBLEDevice::stopAdvertising() {
|
|||
* @return The scanning object reference. This is a singleton object. The caller should not
|
||||
* try and release/delete it.
|
||||
*/
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
||||
/* STATIC */ NimBLEScan* NimBLEDevice::getScan() {
|
||||
if (m_pScan == nullptr) {
|
||||
m_pScan = new NimBLEScan();
|
||||
}
|
||||
return m_pScan;
|
||||
} // getScan
|
||||
|
||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
||||
|
||||
/**
|
||||
* @brief Creates a new client object and maintains a list of all client objects
|
||||
* each client can connect to 1 peripheral device.
|
||||
* each client can connect to 1 peripheral device.
|
||||
* @return A reference to the new client object.
|
||||
*/
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||
/* STATIC */ NimBLEClient* NimBLEDevice::createClient() {
|
||||
if(m_cList.size() >= NIMBLE_MAX_CONNECTIONS) {
|
||||
NIMBLE_LOGW("Number of clients exceeds Max connections. Max=(%d)",
|
||||
NIMBLE_LOGW("Number of clients exceeds Max connections. Max=(%d)",
|
||||
NIMBLE_MAX_CONNECTIONS);
|
||||
}
|
||||
|
||||
|
||||
NimBLEClient* pClient = new NimBLEClient();
|
||||
m_cList.push_back(pClient);
|
||||
|
||||
|
@ -137,7 +142,7 @@ void NimBLEDevice::stopAdvertising() {
|
|||
if(pClient == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if(pClient->m_isConnected) {
|
||||
if (pClient->disconnect() != 0) {
|
||||
return false;
|
||||
|
@ -146,7 +151,7 @@ void NimBLEDevice::stopAdvertising() {
|
|||
vTaskDelay(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(pClient->m_waitingToConnect) {
|
||||
if(ble_gap_conn_cancel() != 0){
|
||||
return false;
|
||||
|
@ -155,10 +160,10 @@ void NimBLEDevice::stopAdvertising() {
|
|||
vTaskDelay(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
m_cList.remove(pClient);
|
||||
delete pClient;
|
||||
|
||||
|
||||
return true;
|
||||
} // deleteClient
|
||||
|
||||
|
@ -225,18 +230,20 @@ void NimBLEDevice::stopAdvertising() {
|
|||
return nullptr;
|
||||
} // getDisconnectedClient
|
||||
|
||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set the transmission power.
|
||||
* The power level can be one of:
|
||||
* * ESP_PWR_LVL_N12 = 0, !< Corresponding to -12dbm
|
||||
* * ESP_PWR_LVL_N9 = 1, !< Corresponding to -9dbm
|
||||
* * ESP_PWR_LVL_N6 = 2, !< Corresponding to -6dbm
|
||||
* * ESP_PWR_LVL_N3 = 3, !< Corresponding to -3dbm
|
||||
* * ESP_PWR_LVL_N0 = 4, !< Corresponding to 0dbm
|
||||
* * ESP_PWR_LVL_P3 = 5, !< Corresponding to +3dbm
|
||||
* * ESP_PWR_LVL_P6 = 6, !< Corresponding to +6dbm
|
||||
* * ESP_PWR_LVL_P9 = 7, !< Corresponding to +9dbm
|
||||
* * ESP_PWR_LVL_N12 = 0, !< Corresponding to -12dbm
|
||||
* * ESP_PWR_LVL_N9 = 1, !< Corresponding to -9dbm
|
||||
* * ESP_PWR_LVL_N6 = 2, !< Corresponding to -6dbm
|
||||
* * ESP_PWR_LVL_N3 = 3, !< Corresponding to -3dbm
|
||||
* * ESP_PWR_LVL_N0 = 4, !< Corresponding to 0dbm
|
||||
* * ESP_PWR_LVL_P3 = 5, !< Corresponding to +3dbm
|
||||
* * ESP_PWR_LVL_P6 = 6, !< Corresponding to +6dbm
|
||||
* * ESP_PWR_LVL_P9 = 7, !< Corresponding to +9dbm
|
||||
* @param [in] powerLevel.
|
||||
*/
|
||||
/* STATIC */ void NimBLEDevice::setPower(esp_power_level_t powerLevel, esp_ble_power_type_t powerType) {
|
||||
|
@ -251,26 +258,26 @@ void NimBLEDevice::stopAdvertising() {
|
|||
|
||||
/* STATIC */ int NimBLEDevice::getPower(esp_ble_power_type_t powerType) {
|
||||
|
||||
switch(esp_ble_tx_power_get(powerType)) {
|
||||
case ESP_PWR_LVL_N12:
|
||||
return -12;
|
||||
case ESP_PWR_LVL_N9:
|
||||
return -9;
|
||||
case ESP_PWR_LVL_N6:
|
||||
return -6;
|
||||
case ESP_PWR_LVL_N3:
|
||||
return -6;
|
||||
case ESP_PWR_LVL_N0:
|
||||
return 0;
|
||||
case ESP_PWR_LVL_P3:
|
||||
return 3;
|
||||
case ESP_PWR_LVL_P6:
|
||||
return 6;
|
||||
case ESP_PWR_LVL_P9:
|
||||
return 9;
|
||||
default:
|
||||
return BLE_HS_ADV_TX_PWR_LVL_AUTO;
|
||||
}
|
||||
switch(esp_ble_tx_power_get(powerType)) {
|
||||
case ESP_PWR_LVL_N12:
|
||||
return -12;
|
||||
case ESP_PWR_LVL_N9:
|
||||
return -9;
|
||||
case ESP_PWR_LVL_N6:
|
||||
return -6;
|
||||
case ESP_PWR_LVL_N3:
|
||||
return -6;
|
||||
case ESP_PWR_LVL_N0:
|
||||
return 0;
|
||||
case ESP_PWR_LVL_P3:
|
||||
return 3;
|
||||
case ESP_PWR_LVL_P6:
|
||||
return 6;
|
||||
case ESP_PWR_LVL_P9:
|
||||
return 9;
|
||||
default:
|
||||
return BLE_HS_ADV_TX_PWR_LVL_AUTO;
|
||||
}
|
||||
} // setPower
|
||||
|
||||
|
||||
|
@ -282,13 +289,13 @@ void NimBLEDevice::stopAdvertising() {
|
|||
/* STATIC*/ NimBLEAddress NimBLEDevice::getAddress() {
|
||||
ble_addr_t addr = {BLE_ADDR_PUBLIC, 0};
|
||||
//ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, addr.val, NULL)
|
||||
|
||||
|
||||
if(BLE_HS_ENOADDR == ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, addr.val, NULL)) {
|
||||
NIMBLE_LOGD(LOG_TAG, "Public address not found, checking random");
|
||||
addr.type = BLE_ADDR_RANDOM;
|
||||
ble_hs_id_copy_addr(BLE_ADDR_RANDOM, addr.val, NULL);
|
||||
}
|
||||
|
||||
|
||||
return NimBLEAddress(addr);
|
||||
} // getAddress
|
||||
|
||||
|
@ -309,13 +316,13 @@ void NimBLEDevice::stopAdvertising() {
|
|||
*/
|
||||
/* STATIC */int NimBLEDevice::setMTU(uint16_t mtu) {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> setLocalMTU: %d", mtu);
|
||||
|
||||
|
||||
int rc = ble_att_set_preferred_mtu(mtu);
|
||||
|
||||
if (rc != 0) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Could not set local mtu value to: %d", mtu);
|
||||
}
|
||||
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "<< setLocalMTU");
|
||||
return rc;
|
||||
} // setMTU
|
||||
|
@ -337,26 +344,32 @@ void NimBLEDevice::stopAdvertising() {
|
|||
if(!m_synced) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
m_synced = false;
|
||||
|
||||
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
||||
if(m_pScan != nullptr) {
|
||||
m_pScan->onHostReset();
|
||||
}
|
||||
/* Not needed
|
||||
#endif
|
||||
|
||||
/* Not needed
|
||||
if(m_pServer != nullptr) {
|
||||
m_pServer->onHostReset();
|
||||
}
|
||||
|
||||
|
||||
for(auto it = m_cList.cbegin(); it != m_cList.cend(); ++it) {
|
||||
(*it)->onHostReset();
|
||||
}
|
||||
*/
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
|
||||
if(m_bleAdvertising != nullptr) {
|
||||
m_bleAdvertising->onHostReset();
|
||||
}
|
||||
|
||||
NIMBLE_LOGC(LOG_TAG, "Resetting state; reason=%d, %s", reason,
|
||||
#endif
|
||||
|
||||
NIMBLE_LOGC(LOG_TAG, "Resetting state; reason=%d, %s", reason,
|
||||
NimBLEUtils::returnCodeToString(reason));
|
||||
} // onReset
|
||||
|
||||
|
@ -372,23 +385,27 @@ void NimBLEDevice::stopAdvertising() {
|
|||
if(m_synced) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Make sure we have proper identity address set (public preferred) */
|
||||
int rc = ble_hs_util_ensure_addr(0);
|
||||
assert(rc == 0);
|
||||
|
||||
|
||||
m_synced = true;
|
||||
|
||||
|
||||
if(initialized) {
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
||||
if(m_pScan != nullptr) {
|
||||
// Restart scanning with the last values sent, allow to clear results.
|
||||
m_pScan->start(m_pScan->m_duration, m_pScan->m_scanCompleteCB);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
|
||||
if(m_bleAdvertising != nullptr) {
|
||||
// Restart advertisng, parameters should already be set.
|
||||
m_bleAdvertising->start();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} // onSync
|
||||
|
||||
|
@ -414,7 +431,7 @@ void NimBLEDevice::stopAdvertising() {
|
|||
if(!initialized){
|
||||
int rc=0;
|
||||
esp_err_t errRc = ESP_OK;
|
||||
|
||||
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
// make sure the linker includes esp32-hal-bt.c so ardruino init doesn't release BLE memory.
|
||||
btStarted();
|
||||
|
@ -428,25 +445,25 @@ void NimBLEDevice::stopAdvertising() {
|
|||
}
|
||||
|
||||
ESP_ERROR_CHECK(errRc);
|
||||
|
||||
|
||||
ESP_ERROR_CHECK(esp_nimble_hci_and_controller_init());
|
||||
|
||||
|
||||
nimble_port_init();
|
||||
|
||||
// Setup callbacks for host events
|
||||
|
||||
// Setup callbacks for host events
|
||||
ble_hs_cfg.reset_cb = NimBLEDevice::onReset;
|
||||
ble_hs_cfg.sync_cb = NimBLEDevice::onSync;
|
||||
|
||||
|
||||
// Set initial security capabilities
|
||||
ble_hs_cfg.sm_io_cap = BLE_HS_IO_NO_INPUT_OUTPUT;
|
||||
ble_hs_cfg.sm_io_cap = BLE_HS_IO_NO_INPUT_OUTPUT;
|
||||
ble_hs_cfg.sm_bonding = 0;
|
||||
ble_hs_cfg.sm_mitm = 0;
|
||||
ble_hs_cfg.sm_sc = 1;
|
||||
ble_hs_cfg.sm_our_key_dist = 1;
|
||||
ble_hs_cfg.sm_their_key_dist = 3;
|
||||
|
||||
|
||||
ble_hs_cfg.store_status_cb = ble_store_util_status_rr; /*TODO: Implement handler for this*/
|
||||
|
||||
|
||||
// Set the device name.
|
||||
rc = ble_svc_gap_device_name_set(deviceName.c_str());
|
||||
assert(rc == 0);
|
||||
|
@ -471,12 +488,12 @@ void NimBLEDevice::stopAdvertising() {
|
|||
int ret = nimble_port_stop();
|
||||
if (ret == 0) {
|
||||
nimble_port_deinit();
|
||||
|
||||
|
||||
ret = esp_nimble_hci_and_controller_deinit();
|
||||
if (ret != ESP_OK) {
|
||||
NIMBLE_LOGE(LOG_TAG, "esp_nimble_hci_and_controller_deinit() failed with error: %d", ret);
|
||||
}
|
||||
|
||||
|
||||
initialized = false;
|
||||
m_synced = false;
|
||||
}
|
||||
|
@ -509,12 +526,12 @@ bool NimBLEDevice::getInitialized() {
|
|||
* @brief Set the authorization mode for this device.
|
||||
* @param A bitmap indicating what modes are supported.
|
||||
* The bits are defined as follows:
|
||||
** 0x01 BLE_SM_PAIR_AUTHREQ_BOND
|
||||
** 0x04 BLE_SM_PAIR_AUTHREQ_MITM
|
||||
** 0x08 BLE_SM_PAIR_AUTHREQ_SC
|
||||
** 0x10 BLE_SM_PAIR_AUTHREQ_KEYPRESS - not yet supported.
|
||||
** 0x01 BLE_SM_PAIR_AUTHREQ_BOND
|
||||
** 0x04 BLE_SM_PAIR_AUTHREQ_MITM
|
||||
** 0x08 BLE_SM_PAIR_AUTHREQ_SC
|
||||
** 0x10 BLE_SM_PAIR_AUTHREQ_KEYPRESS - not yet supported.
|
||||
** 0xe2 BLE_SM_PAIR_AUTHREQ_RESERVED - for reference only.
|
||||
*/
|
||||
*/
|
||||
/*STATIC*/void NimBLEDevice::setSecurityAuth(uint8_t auth_req) {
|
||||
NimBLEDevice::setSecurityAuth((auth_req & BLE_SM_PAIR_AUTHREQ_BOND)>0,
|
||||
(auth_req & BLE_SM_PAIR_AUTHREQ_MITM)>0,
|
||||
|
@ -527,8 +544,8 @@ bool NimBLEDevice::getInitialized() {
|
|||
* @param One of the following:
|
||||
** 0x00 BLE_HS_IO_DISPLAY_ONLY DisplayOnly IO capability
|
||||
** 0x01 BLE_HS_IO_DISPLAY_YESNO DisplayYesNo IO capability
|
||||
** 0x02 BLE_HS_IO_KEYBOARD_ONLY KeyboardOnly IO capability
|
||||
** 0x03 BLE_HS_IO_NO_INPUT_OUTPUT NoInputNoOutput IO capability
|
||||
** 0x02 BLE_HS_IO_KEYBOARD_ONLY KeyboardOnly IO capability
|
||||
** 0x03 BLE_HS_IO_NO_INPUT_OUTPUT NoInputNoOutput IO capability
|
||||
** 0x04 BLE_HS_IO_KEYBOARD_DISPLAY KeyboardDisplay Only IO capability
|
||||
*/
|
||||
/*STATIC*/ void NimBLEDevice::setSecurityIOCap(uint8_t iocap) {
|
||||
|
@ -539,7 +556,7 @@ bool NimBLEDevice::getInitialized() {
|
|||
/**
|
||||
* @brief If we are the initiator of the security procedure this sets the keys we will distribute.
|
||||
* @param A bitmap indicating which keys to distribute during pairing.
|
||||
* The bits are defined as follows:
|
||||
* The bits are defined as follows:
|
||||
** 0x01: BLE_SM_PAIR_KEY_DIST_ENC - Distribute the encryption key.
|
||||
** 0x02: BLE_SM_PAIR_KEY_DIST_ID - Distribute the ID key (IRK).
|
||||
** 0x04: BLE_SM_PAIR_KEY_DIST_SIGN
|
||||
|
@ -553,7 +570,7 @@ bool NimBLEDevice::getInitialized() {
|
|||
/**
|
||||
* @brief Set the keys we are willing to accept during pairing.
|
||||
* @param A bitmap indicating which keys to accept during pairing.
|
||||
* The bits are defined as follows:
|
||||
* The bits are defined as follows:
|
||||
** 0x01: BLE_SM_PAIR_KEY_DIST_ENC - Accept the encryption key.
|
||||
** 0x02: BLE_SM_PAIR_KEY_DIST_ID - Accept the ID key (IRK).
|
||||
** 0x04: BLE_SM_PAIR_KEY_DIST_SIGN
|
||||
|
@ -596,14 +613,14 @@ void NimBLEDevice::setSecurityCallbacks(NimBLESecurityCallbacks* callbacks) {
|
|||
*/
|
||||
/* STATIC */int NimBLEDevice::startSecurity(uint16_t conn_id) {
|
||||
/* if(m_securityCallbacks != nullptr) {
|
||||
m_securityCallbacks->onSecurityRequest();
|
||||
m_securityCallbacks->onSecurityRequest();
|
||||
}
|
||||
*/
|
||||
*/
|
||||
int rc = ble_gap_security_initiate(conn_id);
|
||||
if(rc != 0){
|
||||
NIMBLE_LOGE(LOG_TAG, "ble_gap_security_initiate: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
|
||||
}
|
||||
|
||||
|
||||
return rc;
|
||||
} // startSecurity
|
||||
|
||||
|
@ -661,20 +678,4 @@ void NimBLEDevice::setCustomGapHandler(gap_event_handler handler) {
|
|||
} // setCustomGapHandler
|
||||
|
||||
|
||||
/**
|
||||
* @brief Backward compatibility for bluedroid gatt events.
|
||||
* NimBLe does not send GATT events
|
||||
*/
|
||||
/*
|
||||
void BLEDevice::setCustomGattcHandler(gattc_event_handler handler) {
|
||||
setCustomGapHandler(handler);
|
||||
}
|
||||
|
||||
void BLEDevice::setCustomGattsHandler(gatts_event_handler handler) {
|
||||
setCustomGapHandler(handler);
|
||||
}
|
||||
*/
|
||||
/**********************************************************/
|
||||
|
||||
|
||||
#endif // CONFIG_BT_ENABLED
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on Jan 24 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLEDevice.h
|
||||
|
@ -17,11 +17,27 @@
|
|||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
||||
#include "NimBLEScan.h"
|
||||
#include "NimBLEUtils.h"
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
|
||||
#include "NimBLEAdvertising.h"
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||
#include "NimBLEClient.h"
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
#include "NimBLEServer.h"
|
||||
#endif
|
||||
|
||||
#include "NimBLEUtils.h"
|
||||
#include "NimBLESecurity.h"
|
||||
#include "NimBLEAddress.h"
|
||||
|
||||
#include "esp_bt.h"
|
||||
|
||||
|
@ -50,43 +66,46 @@
|
|||
#define BLEAdvertising NimBLEAdvertising
|
||||
#define BLEServerCallbacks NimBLEServerCallbacks
|
||||
#define BLECharacteristicCallbacks NimBLECharacteristicCallbacks
|
||||
#define BLEAdvertisementData NimBLEAdvertisementData
|
||||
#define BLEDescriptor NimBLEDescriptor
|
||||
#define BLE2902 NimBLE2902
|
||||
#define BLE2904 NimBLE2904
|
||||
#define BLEDescriptorCallbacks NimBLEDescriptorCallbacks
|
||||
#define BLEAdvertisementData NimBLEAdvertisementData
|
||||
#define BLEDescriptor NimBLEDescriptor
|
||||
#define BLE2902 NimBLE2902
|
||||
#define BLE2904 NimBLE2904
|
||||
#define BLEDescriptorCallbacks NimBLEDescriptorCallbacks
|
||||
#define BLEBeacon NimBLEBeacon
|
||||
#define BLEEddystoneTLM NimBLEEddystoneTLM
|
||||
#define BLEEddystoneURL NimBLEEddystoneURL
|
||||
|
||||
#ifdef CONFIG_BT_NIMBLE_MAX_CONNECTIONS
|
||||
#define NIMBLE_MAX_CONNECTIONS CONFIG_BT_NIMBLE_MAX_CONNECTIONS
|
||||
#else
|
||||
#else
|
||||
#define NIMBLE_MAX_CONNECTIONS CONFIG_NIMBLE_MAX_CONNECTIONS
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @brief BLE functions.
|
||||
*/
|
||||
typedef int (*gap_event_handler)(ble_gap_event *event, void *arg);
|
||||
//typedef void (*gattc_event_handler)(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t* param);
|
||||
//typedef void (*gatts_event_handler)(esp_gatts_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gatts_cb_param_t* param);
|
||||
|
||||
extern "C" void ble_store_config_init(void);
|
||||
|
||||
class NimBLEDevice {
|
||||
public:
|
||||
static void init(const std::string &deviceName); // Initialize the local BLE environment.
|
||||
static void init(const std::string &deviceName);
|
||||
static void deinit();
|
||||
static bool getInitialized();
|
||||
static NimBLEAddress getAddress();
|
||||
static std::string toString();
|
||||
static NimBLEScan* getScan(); // Get the scan object
|
||||
static NimBLEClient* createClient();
|
||||
static NimBLEServer* createServer();
|
||||
static bool deleteClient(NimBLEClient* pClient);
|
||||
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
||||
static NimBLEScan* getScan();
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
static NimBLEServer* createServer();
|
||||
#endif
|
||||
|
||||
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 setCustomGapHandler(gap_event_handler handler);
|
||||
static void setSecurityAuth(bool bonding, bool mitm, bool sc);
|
||||
static void setSecurityAuth(uint8_t auth_req);
|
||||
|
@ -101,36 +120,66 @@ public:
|
|||
static bool isIgnored(const NimBLEAddress &address);
|
||||
static void addIgnored(const NimBLEAddress &address);
|
||||
static void removeIgnored(const NimBLEAddress &address);
|
||||
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
|
||||
static NimBLEAdvertising* getAdvertising();
|
||||
static void startAdvertising();
|
||||
static void stopAdvertising();
|
||||
static void startAdvertising();
|
||||
static void stopAdvertising();
|
||||
#endif
|
||||
|
||||
#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||
static NimBLEClient* createClient();
|
||||
static bool deleteClient(NimBLEClient* pClient);
|
||||
static NimBLEClient* getClientByID(uint16_t conn_id);
|
||||
static NimBLEClient* getClientByPeerAddress(const NimBLEAddress &peer_addr);
|
||||
static NimBLEClient* getDisconnectedClient();
|
||||
static size_t getClientListSize();
|
||||
static std::list<NimBLEClient*>* getClientList();
|
||||
|
||||
static size_t getClientListSize();
|
||||
static std::list<NimBLEClient*>* getClientList();
|
||||
#endif
|
||||
|
||||
private:
|
||||
friend class NimBLEServer;
|
||||
#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||
friend class NimBLEClient;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
||||
friend class NimBLEScan;
|
||||
friend class NimBLEAdvertising;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
friend class NimBLEServer;
|
||||
friend class NimBLECharacteristic;
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
|
||||
friend class NimBLEAdvertising;
|
||||
#endif
|
||||
|
||||
static void onReset(int reason);
|
||||
static void onSync(void);
|
||||
static void host_task(void *param);
|
||||
static int startSecurity( uint16_t conn_id);
|
||||
|
||||
static bool m_synced;
|
||||
static int startSecurity(uint16_t conn_id);
|
||||
static bool m_synced;
|
||||
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
||||
static NimBLEScan* m_pScan;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
static NimBLEServer* m_pServer;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
|
||||
static NimBLEAdvertising* m_bleAdvertising;
|
||||
static ble_gap_event_listener m_listener;
|
||||
static uint32_t m_passkey;
|
||||
#endif
|
||||
|
||||
#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||
static std::list <NimBLEClient*> m_cList;
|
||||
#endif
|
||||
static std::list <NimBLEAddress> m_ignoreList;
|
||||
static NimBLESecurityCallbacks* m_securityCallbacks;
|
||||
static uint32_t m_passkey;
|
||||
static ble_gap_event_listener m_listener;
|
||||
|
||||
public:
|
||||
static gap_event_handler m_customGapHandler;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on March 15 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLEEddystoneTLM.cpp
|
||||
|
@ -26,41 +26,41 @@ static const char LOG_TAG[] = "NimBLEEddystoneTLM";
|
|||
|
||||
|
||||
NimBLEEddystoneTLM::NimBLEEddystoneTLM() {
|
||||
beaconUUID = 0xFEAA;
|
||||
m_eddystoneData.frameType = EDDYSTONE_TLM_FRAME_TYPE;
|
||||
m_eddystoneData.version = 0;
|
||||
m_eddystoneData.volt = 3300; // 3300mV = 3.3V
|
||||
m_eddystoneData.temp = (uint16_t) ((float) 23.00 * 256); // 8.8 fixed format
|
||||
m_eddystoneData.advCount = 0;
|
||||
m_eddystoneData.tmil = 0;
|
||||
beaconUUID = 0xFEAA;
|
||||
m_eddystoneData.frameType = EDDYSTONE_TLM_FRAME_TYPE;
|
||||
m_eddystoneData.version = 0;
|
||||
m_eddystoneData.volt = 3300; // 3300mV = 3.3V
|
||||
m_eddystoneData.temp = (uint16_t) ((float) 23.00 * 256); // 8.8 fixed format
|
||||
m_eddystoneData.advCount = 0;
|
||||
m_eddystoneData.tmil = 0;
|
||||
} // NimBLEEddystoneTLM
|
||||
|
||||
std::string NimBLEEddystoneTLM::getData() {
|
||||
return std::string((char*) &m_eddystoneData, sizeof(m_eddystoneData));
|
||||
return std::string((char*) &m_eddystoneData, sizeof(m_eddystoneData));
|
||||
} // getData
|
||||
|
||||
NimBLEUUID NimBLEEddystoneTLM::getUUID() {
|
||||
return NimBLEUUID(beaconUUID);
|
||||
return NimBLEUUID(beaconUUID);
|
||||
} // getUUID
|
||||
|
||||
uint8_t NimBLEEddystoneTLM::getVersion() {
|
||||
return m_eddystoneData.version;
|
||||
return m_eddystoneData.version;
|
||||
} // getVersion
|
||||
|
||||
uint16_t NimBLEEddystoneTLM::getVolt() {
|
||||
return ENDIAN_CHANGE_U16(m_eddystoneData.volt);
|
||||
return ENDIAN_CHANGE_U16(m_eddystoneData.volt);
|
||||
} // getVolt
|
||||
|
||||
float NimBLEEddystoneTLM::getTemp() {
|
||||
return ENDIAN_CHANGE_U16(m_eddystoneData.temp) / 256.0f;
|
||||
return ENDIAN_CHANGE_U16(m_eddystoneData.temp) / 256.0f;
|
||||
} // getTemp
|
||||
|
||||
uint32_t NimBLEEddystoneTLM::getCount() {
|
||||
return ENDIAN_CHANGE_U32(m_eddystoneData.advCount);
|
||||
return ENDIAN_CHANGE_U32(m_eddystoneData.advCount);
|
||||
} // getCount
|
||||
|
||||
uint32_t NimBLEEddystoneTLM::getTime() {
|
||||
return (ENDIAN_CHANGE_U32(m_eddystoneData.tmil)) / 10;
|
||||
return (ENDIAN_CHANGE_U32(m_eddystoneData.tmil)) / 10;
|
||||
} // getTime
|
||||
|
||||
std::string NimBLEEddystoneTLM::toString() {
|
||||
|
@ -117,36 +117,36 @@ std::string NimBLEEddystoneTLM::toString() {
|
|||
* Set the raw data for the beacon record.
|
||||
*/
|
||||
void NimBLEEddystoneTLM::setData(const std::string &data) {
|
||||
if (data.length() != sizeof(m_eddystoneData)) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Unable to set the data ... length passed in was %d and expected %d",
|
||||
if (data.length() != sizeof(m_eddystoneData)) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Unable to set the data ... length passed in was %d and expected %d",
|
||||
data.length(), sizeof(m_eddystoneData));
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
memcpy(&m_eddystoneData, data.data(), data.length());
|
||||
} // setData
|
||||
|
||||
void NimBLEEddystoneTLM::setUUID(const NimBLEUUID &l_uuid) {
|
||||
beaconUUID = l_uuid.getNative()->u16.value;
|
||||
beaconUUID = l_uuid.getNative()->u16.value;
|
||||
} // setUUID
|
||||
|
||||
void NimBLEEddystoneTLM::setVersion(uint8_t version) {
|
||||
m_eddystoneData.version = version;
|
||||
m_eddystoneData.version = version;
|
||||
} // setVersion
|
||||
|
||||
void NimBLEEddystoneTLM::setVolt(uint16_t volt) {
|
||||
m_eddystoneData.volt = volt;
|
||||
m_eddystoneData.volt = volt;
|
||||
} // setVolt
|
||||
|
||||
void NimBLEEddystoneTLM::setTemp(float temp) {
|
||||
m_eddystoneData.temp = (uint16_t)temp;
|
||||
m_eddystoneData.temp = (uint16_t)temp;
|
||||
} // setTemp
|
||||
|
||||
void NimBLEEddystoneTLM::setCount(uint32_t advCount) {
|
||||
m_eddystoneData.advCount = advCount;
|
||||
m_eddystoneData.advCount = advCount;
|
||||
} // setCount
|
||||
|
||||
void NimBLEEddystoneTLM::setTime(uint32_t tmil) {
|
||||
m_eddystoneData.tmil = tmil;
|
||||
m_eddystoneData.tmil = tmil;
|
||||
} // setTime
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on March 15 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLEEddystoneTLM.h
|
||||
|
@ -27,33 +27,33 @@
|
|||
*/
|
||||
class NimBLEEddystoneTLM {
|
||||
public:
|
||||
NimBLEEddystoneTLM();
|
||||
std::string getData();
|
||||
NimBLEUUID getUUID();
|
||||
uint8_t getVersion();
|
||||
uint16_t getVolt();
|
||||
float getTemp();
|
||||
uint32_t getCount();
|
||||
uint32_t getTime();
|
||||
std::string toString();
|
||||
void setData(const std::string &data);
|
||||
void setUUID(const NimBLEUUID &l_uuid);
|
||||
void setVersion(uint8_t version);
|
||||
void setVolt(uint16_t volt);
|
||||
void setTemp(float temp);
|
||||
void setCount(uint32_t advCount);
|
||||
void setTime(uint32_t tmil);
|
||||
NimBLEEddystoneTLM();
|
||||
std::string getData();
|
||||
NimBLEUUID getUUID();
|
||||
uint8_t getVersion();
|
||||
uint16_t getVolt();
|
||||
float getTemp();
|
||||
uint32_t getCount();
|
||||
uint32_t getTime();
|
||||
std::string toString();
|
||||
void setData(const std::string &data);
|
||||
void setUUID(const NimBLEUUID &l_uuid);
|
||||
void setVersion(uint8_t version);
|
||||
void setVolt(uint16_t volt);
|
||||
void setTemp(float temp);
|
||||
void setCount(uint32_t advCount);
|
||||
void setTime(uint32_t tmil);
|
||||
|
||||
private:
|
||||
uint16_t beaconUUID;
|
||||
struct {
|
||||
uint8_t frameType;
|
||||
uint8_t version;
|
||||
uint16_t volt;
|
||||
uint16_t temp;
|
||||
uint32_t advCount;
|
||||
uint32_t tmil;
|
||||
} __attribute__((packed)) m_eddystoneData;
|
||||
uint16_t beaconUUID;
|
||||
struct {
|
||||
uint8_t frameType;
|
||||
uint8_t version;
|
||||
uint16_t volt;
|
||||
uint16_t temp;
|
||||
uint32_t advCount;
|
||||
uint32_t tmil;
|
||||
} __attribute__((packed)) m_eddystoneData;
|
||||
|
||||
}; // NimBLEEddystoneTLM
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on March 15 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLEEddystoneURL.cpp
|
||||
|
@ -22,102 +22,102 @@
|
|||
static const char LOG_TAG[] = "NimBLEEddystoneURL";
|
||||
|
||||
NimBLEEddystoneURL::NimBLEEddystoneURL() {
|
||||
beaconUUID = 0xFEAA;
|
||||
lengthURL = 0;
|
||||
m_eddystoneData.frameType = EDDYSTONE_URL_FRAME_TYPE;
|
||||
m_eddystoneData.advertisedTxPower = 0;
|
||||
memset(m_eddystoneData.url, 0, sizeof(m_eddystoneData.url));
|
||||
beaconUUID = 0xFEAA;
|
||||
lengthURL = 0;
|
||||
m_eddystoneData.frameType = EDDYSTONE_URL_FRAME_TYPE;
|
||||
m_eddystoneData.advertisedTxPower = 0;
|
||||
memset(m_eddystoneData.url, 0, sizeof(m_eddystoneData.url));
|
||||
} // BLEEddystoneURL
|
||||
|
||||
std::string NimBLEEddystoneURL::getData() {
|
||||
return std::string((char*) &m_eddystoneData, sizeof(m_eddystoneData));
|
||||
return std::string((char*) &m_eddystoneData, sizeof(m_eddystoneData));
|
||||
} // getData
|
||||
|
||||
NimBLEUUID NimBLEEddystoneURL::getUUID() {
|
||||
return NimBLEUUID(beaconUUID);
|
||||
return NimBLEUUID(beaconUUID);
|
||||
} // getUUID
|
||||
|
||||
int8_t NimBLEEddystoneURL::getPower() {
|
||||
return m_eddystoneData.advertisedTxPower;
|
||||
return m_eddystoneData.advertisedTxPower;
|
||||
} // getPower
|
||||
|
||||
std::string NimBLEEddystoneURL::getURL() {
|
||||
return std::string((char*) &m_eddystoneData.url, sizeof(m_eddystoneData.url));
|
||||
return std::string((char*) &m_eddystoneData.url, sizeof(m_eddystoneData.url));
|
||||
} // getURL
|
||||
|
||||
std::string NimBLEEddystoneURL::getDecodedURL() {
|
||||
std::string decodedURL = "";
|
||||
std::string decodedURL = "";
|
||||
|
||||
switch (m_eddystoneData.url[0]) {
|
||||
case 0x00:
|
||||
decodedURL += "http://www.";
|
||||
break;
|
||||
case 0x01:
|
||||
decodedURL += "https://www.";
|
||||
break;
|
||||
case 0x02:
|
||||
decodedURL += "http://";
|
||||
break;
|
||||
case 0x03:
|
||||
decodedURL += "https://";
|
||||
break;
|
||||
default:
|
||||
decodedURL += m_eddystoneData.url[0];
|
||||
}
|
||||
switch (m_eddystoneData.url[0]) {
|
||||
case 0x00:
|
||||
decodedURL += "http://www.";
|
||||
break;
|
||||
case 0x01:
|
||||
decodedURL += "https://www.";
|
||||
break;
|
||||
case 0x02:
|
||||
decodedURL += "http://";
|
||||
break;
|
||||
case 0x03:
|
||||
decodedURL += "https://";
|
||||
break;
|
||||
default:
|
||||
decodedURL += m_eddystoneData.url[0];
|
||||
}
|
||||
|
||||
for (int i = 1; i < lengthURL; i++) {
|
||||
if (m_eddystoneData.url[i] > 33 && m_eddystoneData.url[i] < 127) {
|
||||
decodedURL += m_eddystoneData.url[i];
|
||||
} else {
|
||||
switch (m_eddystoneData.url[i]) {
|
||||
case 0x00:
|
||||
decodedURL += ".com/";
|
||||
break;
|
||||
case 0x01:
|
||||
decodedURL += ".org/";
|
||||
break;
|
||||
case 0x02:
|
||||
decodedURL += ".edu/";
|
||||
break;
|
||||
case 0x03:
|
||||
decodedURL += ".net/";
|
||||
break;
|
||||
case 0x04:
|
||||
decodedURL += ".info/";
|
||||
break;
|
||||
case 0x05:
|
||||
decodedURL += ".biz/";
|
||||
break;
|
||||
case 0x06:
|
||||
decodedURL += ".gov/";
|
||||
break;
|
||||
case 0x07:
|
||||
decodedURL += ".com";
|
||||
break;
|
||||
case 0x08:
|
||||
decodedURL += ".org";
|
||||
break;
|
||||
case 0x09:
|
||||
decodedURL += ".edu";
|
||||
break;
|
||||
case 0x0A:
|
||||
decodedURL += ".net";
|
||||
break;
|
||||
case 0x0B:
|
||||
decodedURL += ".info";
|
||||
break;
|
||||
case 0x0C:
|
||||
decodedURL += ".biz";
|
||||
break;
|
||||
case 0x0D:
|
||||
decodedURL += ".gov";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return decodedURL;
|
||||
for (int i = 1; i < lengthURL; i++) {
|
||||
if (m_eddystoneData.url[i] > 33 && m_eddystoneData.url[i] < 127) {
|
||||
decodedURL += m_eddystoneData.url[i];
|
||||
} else {
|
||||
switch (m_eddystoneData.url[i]) {
|
||||
case 0x00:
|
||||
decodedURL += ".com/";
|
||||
break;
|
||||
case 0x01:
|
||||
decodedURL += ".org/";
|
||||
break;
|
||||
case 0x02:
|
||||
decodedURL += ".edu/";
|
||||
break;
|
||||
case 0x03:
|
||||
decodedURL += ".net/";
|
||||
break;
|
||||
case 0x04:
|
||||
decodedURL += ".info/";
|
||||
break;
|
||||
case 0x05:
|
||||
decodedURL += ".biz/";
|
||||
break;
|
||||
case 0x06:
|
||||
decodedURL += ".gov/";
|
||||
break;
|
||||
case 0x07:
|
||||
decodedURL += ".com";
|
||||
break;
|
||||
case 0x08:
|
||||
decodedURL += ".org";
|
||||
break;
|
||||
case 0x09:
|
||||
decodedURL += ".edu";
|
||||
break;
|
||||
case 0x0A:
|
||||
decodedURL += ".net";
|
||||
break;
|
||||
case 0x0B:
|
||||
decodedURL += ".info";
|
||||
break;
|
||||
case 0x0C:
|
||||
decodedURL += ".biz";
|
||||
break;
|
||||
case 0x0D:
|
||||
decodedURL += ".gov";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return decodedURL;
|
||||
} // getDecodedURL
|
||||
|
||||
|
||||
|
@ -126,29 +126,29 @@ std::string NimBLEEddystoneURL::getDecodedURL() {
|
|||
* Set the raw data for the beacon record.
|
||||
*/
|
||||
void NimBLEEddystoneURL::setData(const std::string &data) {
|
||||
if (data.length() > sizeof(m_eddystoneData)) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Unable to set the data ... length passed in was %d and max expected %d",
|
||||
if (data.length() > sizeof(m_eddystoneData)) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Unable to set the data ... length passed in was %d and max expected %d",
|
||||
data.length(), sizeof(m_eddystoneData));
|
||||
return;
|
||||
}
|
||||
memset(&m_eddystoneData, 0, sizeof(m_eddystoneData));
|
||||
memcpy(&m_eddystoneData, data.data(), data.length());
|
||||
lengthURL = data.length() - (sizeof(m_eddystoneData) - sizeof(m_eddystoneData.url));
|
||||
return;
|
||||
}
|
||||
memset(&m_eddystoneData, 0, sizeof(m_eddystoneData));
|
||||
memcpy(&m_eddystoneData, data.data(), data.length());
|
||||
lengthURL = data.length() - (sizeof(m_eddystoneData) - sizeof(m_eddystoneData.url));
|
||||
} // setData
|
||||
|
||||
void NimBLEEddystoneURL::setUUID(const NimBLEUUID &l_uuid) {
|
||||
beaconUUID = l_uuid.getNative()->u16.value;
|
||||
beaconUUID = l_uuid.getNative()->u16.value;
|
||||
} // setUUID
|
||||
|
||||
void NimBLEEddystoneURL::setPower(int8_t advertisedTxPower) {
|
||||
m_eddystoneData.advertisedTxPower = advertisedTxPower;
|
||||
m_eddystoneData.advertisedTxPower = advertisedTxPower;
|
||||
} // setPower
|
||||
|
||||
void NimBLEEddystoneURL::setURL(const std::string &url) {
|
||||
if (url.length() > sizeof(m_eddystoneData.url)) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Unable to set the url ... length passed in was %d and max expected %d",
|
||||
NIMBLE_LOGE(LOG_TAG, "Unable to set the url ... length passed in was %d and max expected %d",
|
||||
url.length(), sizeof(m_eddystoneData.url));
|
||||
return;
|
||||
return;
|
||||
}
|
||||
memset(m_eddystoneData.url, 0, sizeof(m_eddystoneData.url));
|
||||
memcpy(m_eddystoneData.url, url.data(), url.length());
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on March 15 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLEEddystoneURL.h
|
||||
|
@ -27,25 +27,25 @@
|
|||
*/
|
||||
class NimBLEEddystoneURL {
|
||||
public:
|
||||
NimBLEEddystoneURL();
|
||||
std::string getData();
|
||||
NimBLEUUID getUUID();
|
||||
int8_t getPower();
|
||||
std::string getURL();
|
||||
std::string getDecodedURL();
|
||||
void setData(const std::string &data);
|
||||
void setUUID(const NimBLEUUID &l_uuid);
|
||||
void setPower(int8_t advertisedTxPower);
|
||||
void setURL(const std::string &url);
|
||||
NimBLEEddystoneURL();
|
||||
std::string getData();
|
||||
NimBLEUUID getUUID();
|
||||
int8_t getPower();
|
||||
std::string getURL();
|
||||
std::string getDecodedURL();
|
||||
void setData(const std::string &data);
|
||||
void setUUID(const NimBLEUUID &l_uuid);
|
||||
void setPower(int8_t advertisedTxPower);
|
||||
void setURL(const std::string &url);
|
||||
|
||||
private:
|
||||
uint16_t beaconUUID;
|
||||
uint8_t lengthURL;
|
||||
struct {
|
||||
uint8_t frameType;
|
||||
int8_t advertisedTxPower;
|
||||
uint8_t url[16];
|
||||
} __attribute__((packed)) m_eddystoneData;
|
||||
uint16_t beaconUUID;
|
||||
uint8_t lengthURL;
|
||||
struct {
|
||||
uint8_t frameType;
|
||||
int8_t advertisedTxPower;
|
||||
uint8_t url[16];
|
||||
} __attribute__((packed)) m_eddystoneData;
|
||||
|
||||
}; // NIMBLEEddystoneURL
|
||||
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
#include "modlog/modlog.h"
|
||||
|
||||
|
||||
// If Arduino is being used, strip out the colors and ignore log printing below ui setting.
|
||||
// Note: because CONFIG_LOG_DEFAULT_LEVEL is set at ERROR in Arduino we must use MODLOG_DFLT(ERROR
|
||||
// If Arduino is being used, strip out the colors and ignore log printing below ui setting.
|
||||
// Note: because CONFIG_LOG_DEFAULT_LEVEL is set at ERROR in Arduino we must use MODLOG_DFLT(ERROR
|
||||
// otherwise no messages will be printed above that level.
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
#ifndef CORE_DEBUG_LEVEL
|
||||
#ifndef CORE_DEBUG_LEVEL
|
||||
#define CORE_DEBUG_LEVEL CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL
|
||||
#endif
|
||||
|
||||
|
@ -48,7 +48,7 @@
|
|||
|
||||
#define NIMBLE_LOGC( tag, format, ... ) MODLOG_DFLT(CRITICAL, "CRIT %s: "#format"\n",tag,##__VA_ARGS__)
|
||||
|
||||
#else
|
||||
#else
|
||||
#define NIMBLE_LOGE( tag, format, ... ) MODLOG_DFLT(ERROR, "\033[0;31mE %s: "#format"\033[0m\n",tag,##__VA_ARGS__)
|
||||
#define NIMBLE_LOGW( tag, format, ... ) MODLOG_DFLT(WARN, "\033[0;33mW %s: "#format"\033[0m\n",tag,##__VA_ARGS__)
|
||||
#define NIMBLE_LOGI( tag, format, ... ) MODLOG_DFLT(INFO, "\033[0;32mI %s: "#format"\033[0m\n",tag,##__VA_ARGS__)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on Jan 27 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLERemoteCharacteristic.cpp
|
||||
|
@ -15,6 +15,9 @@
|
|||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||
|
||||
#include "NimBLERemoteCharacteristic.h"
|
||||
#include "NimBLEUtils.h"
|
||||
#include "NimBLELog.h"
|
||||
|
@ -35,13 +38,13 @@ static const char* LOG_TAG = "NimBLERemoteCharacteristic";
|
|||
NimBLERemoteCharacteristic::NimBLERemoteCharacteristic(NimBLERemoteService *pRemoteService, const struct ble_gatt_chr *chr) {
|
||||
|
||||
switch (chr->uuid.u.type) {
|
||||
case BLE_UUID_TYPE_16:
|
||||
case BLE_UUID_TYPE_16:
|
||||
m_uuid = NimBLEUUID(chr->uuid.u16.value);
|
||||
break;
|
||||
case BLE_UUID_TYPE_32:
|
||||
case BLE_UUID_TYPE_32:
|
||||
m_uuid = NimBLEUUID(chr->uuid.u32.value);
|
||||
break;
|
||||
case BLE_UUID_TYPE_128:
|
||||
case BLE_UUID_TYPE_128:
|
||||
m_uuid = NimBLEUUID(const_cast<ble_uuid128_t*>(&chr->uuid.u128));
|
||||
break;
|
||||
default:
|
||||
|
@ -136,14 +139,14 @@ bool NimBLERemoteCharacteristic::canWriteNoResponse() {
|
|||
/**
|
||||
* @brief Callback used by the API when a descriptor is discovered or search complete.
|
||||
*/
|
||||
int NimBLERemoteCharacteristic::descriptorDiscCB(uint16_t conn_handle,
|
||||
int NimBLERemoteCharacteristic::descriptorDiscCB(uint16_t conn_handle,
|
||||
const struct ble_gatt_error *error,
|
||||
uint16_t chr_val_handle,
|
||||
uint16_t chr_val_handle,
|
||||
const struct ble_gatt_dsc *dsc,
|
||||
void *arg)
|
||||
void *arg)
|
||||
{
|
||||
NIMBLE_LOGD(LOG_TAG,"Descriptor Discovered >> status: %d handle: %d", error->status, conn_handle);
|
||||
|
||||
|
||||
NimBLERemoteCharacteristic *characteristic = (NimBLERemoteCharacteristic*)arg;
|
||||
int rc=0;
|
||||
|
||||
|
@ -151,13 +154,13 @@ int NimBLERemoteCharacteristic::descriptorDiscCB(uint16_t conn_handle,
|
|||
if(characteristic->getRemoteService()->getClient()->getConnId() != conn_handle){
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
switch (error->status) {
|
||||
case 0: {
|
||||
// Found a descriptor - add it to the map
|
||||
NimBLERemoteDescriptor* pNewRemoteDescriptor = new NimBLERemoteDescriptor(characteristic, dsc);
|
||||
characteristic->m_descriptorMap.insert(std::pair<std::string, NimBLERemoteDescriptor*>(pNewRemoteDescriptor->getUUID().toString(), pNewRemoteDescriptor));
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
case BLE_HS_EDONE:{
|
||||
|
@ -188,9 +191,9 @@ bool NimBLERemoteCharacteristic::retrieveDescriptors(uint16_t endHdl) {
|
|||
|
||||
int rc = 0;
|
||||
//removeDescriptors(); // Remove any existing descriptors.
|
||||
|
||||
|
||||
m_semaphoreGetDescEvt.take("retrieveDescriptors");
|
||||
|
||||
|
||||
rc = ble_gattc_disc_all_dscs(getRemoteService()->getClient()->getConnId(),
|
||||
m_handle,
|
||||
endHdl,
|
||||
|
@ -201,13 +204,13 @@ bool NimBLERemoteCharacteristic::retrieveDescriptors(uint16_t endHdl) {
|
|||
m_semaphoreGetDescEvt.give();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if(m_semaphoreGetDescEvt.wait("retrieveCharacteristics") != 0) {
|
||||
// if there was an error release the resources
|
||||
//removeDescriptors();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
NIMBLE_LOGD(LOG_TAG, "<< retrieveDescriptors(): Found %d descriptors.", m_descriptorMap.size());
|
||||
} // getDescriptors
|
||||
|
@ -215,7 +218,7 @@ bool NimBLERemoteCharacteristic::retrieveDescriptors(uint16_t endHdl) {
|
|||
|
||||
/**
|
||||
* @brief Retrieve the map of descriptors keyed by UUID.
|
||||
*/
|
||||
*/
|
||||
std::map<std::string, NimBLERemoteDescriptor*>* NimBLERemoteCharacteristic::getDescriptors() {
|
||||
return &m_descriptorMap;
|
||||
} // getDescriptors
|
||||
|
@ -313,7 +316,7 @@ uint8_t NimBLERemoteCharacteristic::readUInt8() {
|
|||
return 0;
|
||||
} // readUInt8
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Read the value of the remote characteristic.
|
||||
* @return The value of the remote characteristic.
|
||||
|
@ -346,7 +349,7 @@ std::string NimBLERemoteCharacteristic::readValue() {
|
|||
m_semaphoreReadCharEvt.give(0);
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
rc = m_semaphoreReadCharEvt.wait("readValue");
|
||||
switch(rc){
|
||||
case 0:
|
||||
|
@ -356,19 +359,19 @@ std::string NimBLERemoteCharacteristic::readValue() {
|
|||
// Characteristic is not long-readable, return with what we have.
|
||||
case BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_LONG):
|
||||
NIMBLE_LOGI(LOG_TAG, "Attribute not long");
|
||||
rc = 0;
|
||||
rc = 0;
|
||||
break;
|
||||
case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHEN):
|
||||
case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHOR):
|
||||
case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_ENC):
|
||||
if (retryCount && pClient->secureConnection())
|
||||
break;
|
||||
/* Else falls through. */
|
||||
/* Else falls through. */
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
} while(rc != 0 && retryCount--);
|
||||
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "<< readValue(): length: %d", m_value.length());
|
||||
return m_value;
|
||||
} // readValue
|
||||
|
@ -380,11 +383,11 @@ std::string NimBLERemoteCharacteristic::readValue() {
|
|||
*/
|
||||
int NimBLERemoteCharacteristic::onReadCB(uint16_t conn_handle,
|
||||
const struct ble_gatt_error *error,
|
||||
struct ble_gatt_attr *attr, void *arg)
|
||||
struct ble_gatt_attr *attr, void *arg)
|
||||
{
|
||||
NimBLERemoteCharacteristic* characteristic = (NimBLERemoteCharacteristic*)arg;
|
||||
uint16_t conn_id = characteristic->getRemoteService()->getClient()->getConnId();
|
||||
|
||||
|
||||
// Make sure the read is for this client
|
||||
if(conn_id != conn_handle) {
|
||||
return 0;
|
||||
|
@ -401,7 +404,7 @@ int NimBLERemoteCharacteristic::onReadCB(uint16_t conn_handle,
|
|||
}
|
||||
// Read complete release semaphore and let the app can continue.
|
||||
characteristic->m_semaphoreReadCharEvt.give(error->status);
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -421,7 +424,7 @@ bool NimBLERemoteCharacteristic::registerForNotify(notify_callback notifyCallbac
|
|||
uint8_t val[] = {0x01, 0x00};
|
||||
|
||||
NimBLERemoteDescriptor* desc = getDescriptor(NimBLEUUID((uint16_t)0x2902));
|
||||
if(desc == nullptr)
|
||||
if(desc == nullptr)
|
||||
return false;
|
||||
|
||||
if(notifyCallback != nullptr){
|
||||
|
@ -435,7 +438,7 @@ bool NimBLERemoteCharacteristic::registerForNotify(notify_callback notifyCallbac
|
|||
}
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "<< registerForNotify()");
|
||||
|
||||
|
||||
return desc->writeValue(val, 2, response);
|
||||
} // registerForNotify
|
||||
|
||||
|
@ -474,11 +477,11 @@ std::string NimBLERemoteCharacteristic::toString() {
|
|||
res += " 0x";
|
||||
snprintf(val, sizeof(val), "%02x", m_charProp);
|
||||
res += val;
|
||||
|
||||
|
||||
for (auto &myPair : m_descriptorMap) {
|
||||
res += "\n" + myPair.second->toString();
|
||||
}
|
||||
|
||||
|
||||
return res;
|
||||
} // toString
|
||||
|
||||
|
@ -515,20 +518,20 @@ bool NimBLERemoteCharacteristic::writeValue(uint8_t newValue, bool response) {
|
|||
* @return false if not connected or cant perform write for some reason.
|
||||
*/
|
||||
bool NimBLERemoteCharacteristic::writeValue(const uint8_t* data, size_t length, bool response) {
|
||||
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, ">> writeValue(), length: %d", length);
|
||||
|
||||
|
||||
NimBLEClient* pClient = getRemoteService()->getClient();
|
||||
int rc = 0;
|
||||
int retryCount = 1;
|
||||
uint16_t mtu;
|
||||
|
||||
|
||||
// Check to see that we are connected.
|
||||
if (!pClient->isConnected()) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Disconnected");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
mtu = ble_att_mtu(pClient->getConnId()) - 3;
|
||||
|
||||
// Check if the data length is longer than we can write in 1 connection event.
|
||||
|
@ -537,7 +540,7 @@ bool NimBLERemoteCharacteristic::writeValue(const uint8_t* data, size_t length,
|
|||
rc = ble_gattc_write_no_rsp_flat(pClient->getConnId(), m_handle, data, length);
|
||||
return (rc==0);
|
||||
}
|
||||
|
||||
|
||||
do {
|
||||
m_semaphoreWriteCharEvt.take("writeValue");
|
||||
|
||||
|
@ -558,26 +561,26 @@ bool NimBLERemoteCharacteristic::writeValue(const uint8_t* data, size_t length,
|
|||
m_semaphoreWriteCharEvt.give();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
rc = m_semaphoreWriteCharEvt.wait("writeValue");
|
||||
|
||||
switch(rc){
|
||||
case 0:
|
||||
case BLE_HS_EDONE:
|
||||
rc = 0;
|
||||
rc = 0;
|
||||
break;
|
||||
case BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_LONG):
|
||||
NIMBLE_LOGE(LOG_TAG, "Long write not supported by peer; Truncating length to %d", mtu);
|
||||
retryCount++;
|
||||
length = mtu;
|
||||
break;
|
||||
|
||||
|
||||
case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHEN):
|
||||
case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHOR):
|
||||
case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_ENC):
|
||||
if (retryCount && pClient->secureConnection())
|
||||
break;
|
||||
/* Else falls through. */
|
||||
/* Else falls through. */
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -594,17 +597,17 @@ bool NimBLERemoteCharacteristic::writeValue(const uint8_t* data, size_t length,
|
|||
*/
|
||||
int NimBLERemoteCharacteristic::onWriteCB(uint16_t conn_handle,
|
||||
const struct ble_gatt_error *error,
|
||||
struct ble_gatt_attr *attr, void *arg)
|
||||
struct ble_gatt_attr *attr, void *arg)
|
||||
{
|
||||
NimBLERemoteCharacteristic* characteristic = (NimBLERemoteCharacteristic*)arg;
|
||||
|
||||
|
||||
// Make sure the discovery is for this device
|
||||
if(characteristic->getRemoteService()->getClient()->getConnId() != conn_handle){
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
NIMBLE_LOGI(LOG_TAG, "Write complete; status=%d conn_handle=%d", error->status, conn_handle);
|
||||
|
||||
|
||||
characteristic->m_semaphoreWriteCharEvt.give(error->status);
|
||||
|
||||
return 0;
|
||||
|
@ -649,4 +652,6 @@ void NimBLERemoteCharacteristic::releaseSemaphores() {
|
|||
m_semaphoreGetDescEvt.give(1);
|
||||
m_semaphoreReadCharEvt.give(1);
|
||||
}
|
||||
|
||||
#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||
#endif /* CONFIG_BT_ENABLED */
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on Jan 27 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLERemoteCharacteristic.h
|
||||
|
@ -17,6 +17,9 @@
|
|||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||
|
||||
//#include "NimBLEUUID.h"
|
||||
//#include "FreeRTOS.h"
|
||||
#include "NimBLERemoteService.h"
|
||||
|
@ -66,7 +69,7 @@ public:
|
|||
private:
|
||||
|
||||
NimBLERemoteCharacteristic(NimBLERemoteService *pRemoteservice, const struct ble_gatt_chr *chr);
|
||||
|
||||
|
||||
friend class NimBLEClient;
|
||||
friend class NimBLERemoteService;
|
||||
friend class NimBLERemoteDescriptor;
|
||||
|
@ -80,7 +83,7 @@ private:
|
|||
static int descriptorDiscCB(uint16_t conn_handle, const struct ble_gatt_error *error,
|
||||
uint16_t chr_val_handle, const struct ble_gatt_dsc *dsc,
|
||||
void *arg);
|
||||
|
||||
|
||||
// Private properties
|
||||
NimBLEUUID m_uuid;
|
||||
uint8_t m_charProp;
|
||||
|
@ -98,5 +101,7 @@ private:
|
|||
// We maintain a map of descriptors owned by this characteristic keyed by a string representation of the UUID.
|
||||
std::map<std::string, NimBLERemoteDescriptor*> m_descriptorMap;
|
||||
}; // BLERemoteCharacteristic
|
||||
|
||||
#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||
#endif /* CONFIG_BT_ENABLED */
|
||||
#endif /* COMPONENTS_NIMBLEREMOTECHARACTERISTIC_H_ */
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on Jan 27 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLERemoteDescriptor.cpp
|
||||
|
@ -14,6 +14,9 @@
|
|||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||
|
||||
#include "NimBLERemoteDescriptor.h"
|
||||
#include "NimBLEUtils.h"
|
||||
#include "NimBLELog.h"
|
||||
|
@ -25,17 +28,17 @@ static const char* LOG_TAG = "NimBLERemoteDescriptor";
|
|||
* @param [in] Reference to the Characteristic that this belongs to.
|
||||
* @param [in] Reference to the struct that contains the descriptor information.
|
||||
*/
|
||||
NimBLERemoteDescriptor::NimBLERemoteDescriptor(NimBLERemoteCharacteristic* pRemoteCharacteristic,
|
||||
NimBLERemoteDescriptor::NimBLERemoteDescriptor(NimBLERemoteCharacteristic* pRemoteCharacteristic,
|
||||
const struct ble_gatt_dsc *dsc)
|
||||
{
|
||||
switch (dsc->uuid.u.type) {
|
||||
case BLE_UUID_TYPE_16:
|
||||
case BLE_UUID_TYPE_16:
|
||||
m_uuid = NimBLEUUID(dsc->uuid.u16.value);
|
||||
break;
|
||||
case BLE_UUID_TYPE_32:
|
||||
case BLE_UUID_TYPE_32:
|
||||
m_uuid = NimBLEUUID(dsc->uuid.u32.value);
|
||||
break;
|
||||
case BLE_UUID_TYPE_128:
|
||||
case BLE_UUID_TYPE_128:
|
||||
m_uuid = NimBLEUUID(const_cast<ble_uuid128_t*>(&dsc->uuid.u128));
|
||||
break;
|
||||
default:
|
||||
|
@ -44,7 +47,7 @@ NimBLERemoteDescriptor::NimBLERemoteDescriptor(NimBLERemoteCharacteristic* pRemo
|
|||
}
|
||||
m_handle = dsc->handle;
|
||||
m_pRemoteCharacteristic = pRemoteCharacteristic;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -81,18 +84,18 @@ NimBLEUUID NimBLERemoteDescriptor::getUUID() {
|
|||
*/
|
||||
int NimBLERemoteDescriptor::onReadCB(uint16_t conn_handle,
|
||||
const struct ble_gatt_error *error,
|
||||
struct ble_gatt_attr *attr, void *arg)
|
||||
struct ble_gatt_attr *attr, void *arg)
|
||||
{
|
||||
NimBLERemoteDescriptor* desc = (NimBLERemoteDescriptor*)arg;
|
||||
uint16_t conn_id = desc->getRemoteCharacteristic()->getRemoteService()->getClient()->getConnId();
|
||||
|
||||
|
||||
// Make sure the discovery is for this device
|
||||
if(conn_id != conn_handle){
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "Read complete; status=%d conn_handle=%d", error->status, conn_handle);
|
||||
|
||||
|
||||
if(error->status == 0){
|
||||
if(attr){
|
||||
NIMBLE_LOGD(LOG_TAG, "Got %d bytes", attr->om->om_len);
|
||||
|
@ -110,23 +113,23 @@ int NimBLERemoteDescriptor::onReadCB(uint16_t conn_handle,
|
|||
|
||||
std::string NimBLERemoteDescriptor::readValue() {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> Descriptor readValue: %s", toString().c_str());
|
||||
|
||||
|
||||
int rc = 0;
|
||||
int retryCount = 1;
|
||||
// Clear the value before reading.
|
||||
m_value = "";
|
||||
|
||||
NimBLEClient* pClient = getRemoteCharacteristic()->getRemoteService()->getClient();
|
||||
|
||||
|
||||
// Check to see that we are connected.
|
||||
if (!pClient->isConnected()) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Disconnected");
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
do {
|
||||
m_semaphoreReadDescrEvt.take("ReadDescriptor");
|
||||
|
||||
|
||||
rc = ble_gattc_read_long(pClient->getConnId(), m_handle, 0,
|
||||
NimBLERemoteDescriptor::onReadCB,
|
||||
this);
|
||||
|
@ -136,7 +139,7 @@ std::string NimBLERemoteDescriptor::readValue() {
|
|||
m_semaphoreReadDescrEvt.give(0);
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
rc = m_semaphoreReadDescrEvt.wait("ReadDescriptor");
|
||||
|
||||
switch(rc){
|
||||
|
@ -147,14 +150,14 @@ std::string NimBLERemoteDescriptor::readValue() {
|
|||
// Descriptor is not long-readable, return with what we have.
|
||||
case BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_LONG):
|
||||
NIMBLE_LOGI(LOG_TAG, "Attribute not long");
|
||||
rc = 0;
|
||||
rc = 0;
|
||||
break;
|
||||
case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHEN):
|
||||
case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHOR):
|
||||
case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_ENC):
|
||||
if (retryCount && pClient->secureConnection())
|
||||
break;
|
||||
/* Else falls through. */
|
||||
/* Else falls through. */
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
@ -202,7 +205,7 @@ std::string NimBLERemoteDescriptor::toString() {
|
|||
res += ", handle: ";
|
||||
snprintf(val, sizeof(val), "%d", getHandle());
|
||||
res += val;
|
||||
|
||||
|
||||
return res;
|
||||
} // toString
|
||||
|
||||
|
@ -213,10 +216,10 @@ std::string NimBLERemoteDescriptor::toString() {
|
|||
*/
|
||||
int NimBLERemoteDescriptor::onWriteCB(uint16_t conn_handle,
|
||||
const struct ble_gatt_error *error,
|
||||
struct ble_gatt_attr *attr, void *arg)
|
||||
struct ble_gatt_attr *attr, void *arg)
|
||||
{
|
||||
NimBLERemoteDescriptor* descriptor = (NimBLERemoteDescriptor*)arg;
|
||||
|
||||
|
||||
// Make sure the discovery is for this device
|
||||
if(descriptor->getRemoteCharacteristic()->getRemoteService()->getClient()->getConnId() != conn_handle){
|
||||
return 0;
|
||||
|
@ -239,19 +242,19 @@ int NimBLERemoteDescriptor::onWriteCB(uint16_t conn_handle,
|
|||
bool NimBLERemoteDescriptor::writeValue(const uint8_t* data, size_t length, bool response) {
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, ">> Descriptor writeValue: %s", toString().c_str());
|
||||
|
||||
|
||||
NimBLEClient* pClient = getRemoteCharacteristic()->getRemoteService()->getClient();
|
||||
|
||||
|
||||
int rc = 0;
|
||||
int retryCount = 1;
|
||||
uint16_t mtu;
|
||||
|
||||
|
||||
// Check to see that we are connected.
|
||||
if (!pClient->isConnected()) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Disconnected");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
mtu = ble_att_mtu(pClient->getConnId()) - 3;
|
||||
|
||||
// Check if the data length is longer than we can write in 1 connection event.
|
||||
|
@ -260,10 +263,10 @@ bool NimBLERemoteDescriptor::writeValue(const uint8_t* data, size_t length, bool
|
|||
rc = ble_gattc_write_no_rsp_flat(pClient->getConnId(), m_handle, data, length);
|
||||
return (rc == 0);
|
||||
}
|
||||
|
||||
|
||||
do {
|
||||
m_semaphoreDescWrite.take("WriteDescriptor");
|
||||
|
||||
|
||||
if(length > mtu) {
|
||||
NIMBLE_LOGI(LOG_TAG,"long write %d bytes", length);
|
||||
os_mbuf *om = ble_hs_mbuf_from_flat(data, length);
|
||||
|
@ -282,7 +285,7 @@ bool NimBLERemoteDescriptor::writeValue(const uint8_t* data, size_t length, bool
|
|||
m_semaphoreDescWrite.give();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
rc = m_semaphoreDescWrite.wait("WriteDescriptor");
|
||||
|
||||
switch(rc){
|
||||
|
@ -295,13 +298,13 @@ bool NimBLERemoteDescriptor::writeValue(const uint8_t* data, size_t length, bool
|
|||
retryCount++;
|
||||
length = mtu;
|
||||
break;
|
||||
|
||||
|
||||
case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHEN):
|
||||
case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHOR):
|
||||
case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_ENC):
|
||||
if (retryCount && pClient->secureConnection())
|
||||
break;
|
||||
/* Else falls through. */
|
||||
/* Else falls through. */
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -339,4 +342,6 @@ void NimBLERemoteDescriptor::releaseSemaphores() {
|
|||
m_semaphoreDescWrite.give(1);
|
||||
m_semaphoreReadDescrEvt.give(1);
|
||||
}
|
||||
|
||||
#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||
#endif /* CONFIG_BT_ENABLED */
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on Jan 27 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLERemoteDescriptor.h
|
||||
|
@ -17,6 +17,9 @@
|
|||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||
|
||||
#include "NimBLERemoteCharacteristic.h"
|
||||
|
||||
class NimBLERemoteCharacteristic;
|
||||
|
@ -54,5 +57,7 @@ private:
|
|||
|
||||
|
||||
};
|
||||
|
||||
#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||
#endif /* CONFIG_BT_ENABLED */
|
||||
#endif /* COMPONENTS_NIMBLEREMOTEDESCRIPTOR_H_ */
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on Jan 27 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLERemoteService.cpp
|
||||
|
@ -14,6 +14,9 @@
|
|||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||
|
||||
#include "NimBLERemoteService.h"
|
||||
#include "NimBLEUtils.h"
|
||||
#include "NimBLEDevice.h"
|
||||
|
@ -25,19 +28,19 @@ static const char* LOG_TAG = "NimBLERemoteService";
|
|||
* @brief Remote Service constructor.
|
||||
* @param [in] Reference to the client this belongs to.
|
||||
* @param [in] Refernce to the structure with the services' information.
|
||||
*/
|
||||
*/
|
||||
NimBLERemoteService::NimBLERemoteService(NimBLEClient* pClient, const struct ble_gatt_svc* service) {
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, ">> BLERemoteService()");
|
||||
m_pClient = pClient;
|
||||
switch (service->uuid.u.type) {
|
||||
case BLE_UUID_TYPE_16:
|
||||
case BLE_UUID_TYPE_16:
|
||||
m_uuid = NimBLEUUID(service->uuid.u16.value);
|
||||
break;
|
||||
case BLE_UUID_TYPE_32:
|
||||
case BLE_UUID_TYPE_32:
|
||||
m_uuid = NimBLEUUID(service->uuid.u32.value);
|
||||
break;
|
||||
case BLE_UUID_TYPE_128:
|
||||
case BLE_UUID_TYPE_128:
|
||||
m_uuid = NimBLEUUID(const_cast<ble_uuid128_t*>(&service->uuid.u128));
|
||||
break;
|
||||
default:
|
||||
|
@ -55,7 +58,7 @@ NimBLERemoteService::NimBLERemoteService(NimBLEClient* pClient, const struct ble
|
|||
/**
|
||||
* @brief When deleting the service make sure we delete all characteristics and descriptors.
|
||||
* Also release any semaphores they may be holding.
|
||||
*/
|
||||
*/
|
||||
NimBLERemoteService::~NimBLERemoteService() {
|
||||
removeCharacteristics();
|
||||
}
|
||||
|
@ -65,12 +68,12 @@ NimBLERemoteService::~NimBLERemoteService() {
|
|||
* @brief Get the remote characteristic object for the characteristic UUID.
|
||||
* @param [in] uuid Remote characteristic uuid.
|
||||
* @return Reference to the remote characteristic object.
|
||||
*/
|
||||
*/
|
||||
NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const char* uuid) {
|
||||
return getCharacteristic(NimBLEUUID(uuid));
|
||||
} // getCharacteristic
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get the characteristic object for the UUID.
|
||||
* @param [in] uuid Characteristic uuid.
|
||||
|
@ -93,12 +96,12 @@ NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const NimBLEU
|
|||
/**
|
||||
* @brief Callback for Characterisic discovery.
|
||||
*/
|
||||
int NimBLERemoteService::characteristicDiscCB(uint16_t conn_handle,
|
||||
int NimBLERemoteService::characteristicDiscCB(uint16_t conn_handle,
|
||||
const struct ble_gatt_error *error,
|
||||
const struct ble_gatt_chr *chr, void *arg)
|
||||
const struct ble_gatt_chr *chr, void *arg)
|
||||
{
|
||||
NIMBLE_LOGD(LOG_TAG,"Characteristic Discovered >> status: %d handle: %d", error->status, conn_handle);
|
||||
|
||||
|
||||
NimBLERemoteService *service = (NimBLERemoteService*)arg;
|
||||
int rc=0;
|
||||
|
||||
|
@ -106,7 +109,7 @@ int NimBLERemoteService::characteristicDiscCB(uint16_t conn_handle,
|
|||
if(service->getClient()->getConnId() != conn_handle){
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
switch (error->status) {
|
||||
case 0: {
|
||||
// Found a service - add it to the map
|
||||
|
@ -147,12 +150,12 @@ int NimBLERemoteService::characteristicDiscCB(uint16_t conn_handle,
|
|||
*/
|
||||
bool NimBLERemoteService::retrieveCharacteristics() {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> retrieveCharacteristics() for service: %s", getUUID().toString().c_str());
|
||||
|
||||
|
||||
int rc = 0;
|
||||
//removeCharacteristics(); // Forget any previous characteristics.
|
||||
|
||||
|
||||
m_semaphoreGetCharEvt.take("retrieveCharacteristics");
|
||||
|
||||
|
||||
rc = ble_gattc_disc_all_chrs(m_pClient->getConnId(),
|
||||
m_startHandle,
|
||||
m_endHandle,
|
||||
|
@ -164,7 +167,7 @@ bool NimBLERemoteService::retrieveCharacteristics() {
|
|||
m_semaphoreGetCharEvt.give();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
m_haveCharacteristics = (m_semaphoreGetCharEvt.wait("retrieveCharacteristics") == 0);
|
||||
if(m_haveCharacteristics){
|
||||
uint16_t endHdl = 0xFFFF;
|
||||
|
@ -173,19 +176,19 @@ bool NimBLERemoteService::retrieveCharacteristics() {
|
|||
NIMBLE_LOGD(LOG_TAG, "Found UUID: %s Handle: %d Def Handle: %d", (*it).second->getUUID().toString().c_str(), (*it).second->getHandle(), (*it).second->getDefHandle());
|
||||
// The descriptor handle is between this characteristic val_handle and the next ones def_handle
|
||||
// so make the end of the scan at the handle before the next characteristic def_handle
|
||||
|
||||
|
||||
// Make sure we don't go past the service end handle
|
||||
if(++it != m_characteristicMapByHandle.cend()){
|
||||
NIMBLE_LOGD(LOG_TAG, "Next UUID: %s Handle: %d Def Handle: %d", (*it).second->getUUID().toString().c_str(), (*it).second->getHandle(),(*it).second->getDefHandle());
|
||||
|
||||
|
||||
endHdl = (*it).second->getDefHandle()-1;
|
||||
}
|
||||
else{
|
||||
else{
|
||||
NIMBLE_LOGD(LOG_TAG, "END CHARS");
|
||||
endHdl = m_endHandle;
|
||||
}
|
||||
--it;
|
||||
|
||||
|
||||
//If there is no handles between this characteristic and the next there is no descriptor so skip to the next
|
||||
if((*it).second->getHandle() != endHdl){
|
||||
if(!m_pClient->m_isConnected || !(*it).second->retrieveDescriptors(endHdl)) {
|
||||
|
@ -194,14 +197,14 @@ bool NimBLERemoteService::retrieveCharacteristics() {
|
|||
}
|
||||
//NIMBLE_LOGD(LOG_TAG, "Found %d Characteristics in service UUID: %s", chars->size(), myPair.first.c_str());
|
||||
}
|
||||
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "<< retrieveCharacteristics()");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
NIMBLE_LOGE(LOG_TAG, "Could not retrieve characteristics");
|
||||
return false;
|
||||
|
||||
|
||||
} // retrieveCharacteristics
|
||||
|
||||
|
||||
|
@ -263,10 +266,10 @@ NimBLEUUID NimBLERemoteService::getUUID() {
|
|||
*/
|
||||
std::string NimBLERemoteService::getValue(const NimBLEUUID &characteristicUuid) {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> readValue: uuid: %s", characteristicUuid.toString().c_str());
|
||||
|
||||
|
||||
std::string ret = "";
|
||||
NimBLERemoteCharacteristic* pChar = getCharacteristic(characteristicUuid);
|
||||
|
||||
|
||||
if(pChar != nullptr) {
|
||||
ret = pChar->readValue();
|
||||
}
|
||||
|
@ -284,10 +287,10 @@ std::string NimBLERemoteService::getValue(const NimBLEUUID &characteristicUuid)
|
|||
*/
|
||||
bool NimBLERemoteService::setValue(const NimBLEUUID &characteristicUuid, const std::string &value) {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> setValue: uuid: %s", characteristicUuid.toString().c_str());
|
||||
|
||||
|
||||
bool ret = false;
|
||||
NimBLERemoteCharacteristic* pChar = getCharacteristic(characteristicUuid);
|
||||
|
||||
|
||||
if(pChar != nullptr) {
|
||||
ret = pChar->writeValue(value);
|
||||
}
|
||||
|
@ -306,12 +309,12 @@ bool NimBLERemoteService::setValue(const NimBLEUUID &characteristicUuid, const s
|
|||
*/
|
||||
void NimBLERemoteService::removeCharacteristics() {
|
||||
m_characteristicMap.clear(); // Clear the map
|
||||
|
||||
|
||||
for (auto &myPair : m_characteristicMapByHandle) {
|
||||
delete myPair.second;
|
||||
}
|
||||
m_characteristicMapByHandle.clear(); // Clear the map
|
||||
|
||||
|
||||
} // removeCharacteristics
|
||||
|
||||
|
||||
|
@ -334,7 +337,7 @@ std::string NimBLERemoteService::toString() {
|
|||
snprintf(val, sizeof(val), "%04x", m_endHandle);
|
||||
res += " 0x";
|
||||
res += val;
|
||||
|
||||
|
||||
for (auto &myPair : m_characteristicMap) {
|
||||
res += "\n" + myPair.second->toString();
|
||||
}
|
||||
|
@ -345,7 +348,7 @@ std::string NimBLERemoteService::toString() {
|
|||
|
||||
/**
|
||||
* @brief called when an error occurrs and we need to release the semaphores to resume operations.
|
||||
* Will release all characteristic and subsequently all descriptor semaphores for this service.
|
||||
* Will release all characteristic and subsequently all descriptor semaphores for this service.
|
||||
*/
|
||||
void NimBLERemoteService::releaseSemaphores() {
|
||||
for (auto &cPair : m_characteristicMapByHandle) {
|
||||
|
@ -354,4 +357,5 @@ void NimBLERemoteService::releaseSemaphores() {
|
|||
m_semaphoreGetCharEvt.give(1);
|
||||
}
|
||||
|
||||
#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||
#endif /* CONFIG_BT_ENABLED */
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on Jan 27 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLERemoteService.h
|
||||
|
@ -17,6 +17,9 @@
|
|||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||
|
||||
#include "NimBLEClient.h"
|
||||
#include "NimBLEUUID.h"
|
||||
#include "FreeRTOS.h"
|
||||
|
@ -52,7 +55,7 @@ public:
|
|||
|
||||
private:
|
||||
// Private constructor ... never meant to be created by a user application.
|
||||
NimBLERemoteService(NimBLEClient* pClient, const struct ble_gatt_svc *service);
|
||||
NimBLERemoteService(NimBLEClient* pClient, const struct ble_gatt_svc *service);
|
||||
|
||||
// Friends
|
||||
friend class NimBLEClient;
|
||||
|
@ -60,7 +63,7 @@ private:
|
|||
|
||||
// Private methods
|
||||
bool retrieveCharacteristics(void); // Retrieve the characteristics from the BLE Server.
|
||||
static int characteristicDiscCB(uint16_t conn_handle,
|
||||
static int characteristicDiscCB(uint16_t conn_handle,
|
||||
const struct ble_gatt_error *error,
|
||||
const struct ble_gatt_chr *chr, void *arg);
|
||||
|
||||
|
@ -85,5 +88,6 @@ private:
|
|||
uint16_t m_endHandle; // The ending handle of this service.
|
||||
}; // BLERemoteService
|
||||
|
||||
#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||
#endif /* CONFIG_BT_ENABLED */
|
||||
#endif /* COMPONENTS_NIMBLEREMOTESERVICE_H_ */
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on Jan 24 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLEScan.cpp
|
||||
|
@ -14,6 +14,9 @@
|
|||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
||||
|
||||
#include "NimBLEScan.h"
|
||||
#include "NimBLEUtils.h"
|
||||
#include "NimBLEDevice.h"
|
||||
|
@ -40,7 +43,7 @@ static const char* LOG_TAG = "NimBLEScan";
|
|||
* directed advertisement shall not be ignored if the InitA is a
|
||||
* resolvable private address.
|
||||
*/
|
||||
|
||||
|
||||
//#define BLE_HCI_SCAN_FILT_NO_WL (0)
|
||||
//#define BLE_HCI_SCAN_FILT_USE_WL (1)
|
||||
//#define BLE_HCI_SCAN_FILT_NO_WL_INITA (2)
|
||||
|
@ -76,33 +79,33 @@ NimBLEScan::NimBLEScan() {
|
|||
* @param [in] param Parameter data for this event.
|
||||
*/
|
||||
/*STATIC*/int NimBLEScan::handleGapEvent(ble_gap_event* event, void* arg) {
|
||||
|
||||
|
||||
NimBLEScan* pScan = (NimBLEScan*)arg;
|
||||
struct ble_hs_adv_fields fields;
|
||||
int rc = 0;
|
||||
|
||||
|
||||
switch(event->type) {
|
||||
|
||||
case BLE_GAP_EVENT_DISC: {
|
||||
if(pScan->m_stopped) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Scan stop called, ignoring results.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(pScan->m_stopped) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Scan stop called, ignoring results.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = ble_hs_adv_parse_fields(&fields, event->disc.data,
|
||||
event->disc.length_data);
|
||||
if (rc != 0) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Gap Event Parse ERROR.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
NimBLEAddress advertisedAddress(event->disc.addr);
|
||||
|
||||
// Print advertisement data
|
||||
// print_adv_fields(&fields);
|
||||
|
||||
// If we are not scanning, nothing to do with the extra results.
|
||||
if (pScan->m_stopped) {
|
||||
if (pScan->m_stopped) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -111,9 +114,9 @@ NimBLEScan::NimBLEScan() {
|
|||
NIMBLE_LOGI(LOG_TAG, "Ignoring device: address: %s", advertisedAddress.toString().c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
NimBLEAdvertisedDevice* advertisedDevice = nullptr;
|
||||
|
||||
|
||||
NimBLEAdvertisedDevice* advertisedDevice = nullptr;
|
||||
|
||||
// If we've seen this device before get a pointer to it from the map
|
||||
auto it = pScan->m_scanResults.m_advertisedDevicesMap.find(advertisedAddress.toString());
|
||||
if(it != pScan->m_scanResults.m_advertisedDevicesMap.cend()) {
|
||||
|
@ -134,7 +137,7 @@ NimBLEScan::NimBLEScan() {
|
|||
else{
|
||||
NIMBLE_LOGI(LOG_TAG, "UPDATING PREVIOUSLY FOUND DEVICE: %s", advertisedAddress.toString().c_str());
|
||||
}
|
||||
advertisedDevice->setRSSI(event->disc.rssi);
|
||||
advertisedDevice->setRSSI(event->disc.rssi);
|
||||
advertisedDevice->parseAdvertisement(&fields);
|
||||
advertisedDevice->setScan(pScan);
|
||||
advertisedDevice->setAdvertisementResult(event->disc.data, event->disc.length_data);
|
||||
|
@ -155,13 +158,13 @@ NimBLEScan::NimBLEScan() {
|
|||
case BLE_GAP_EVENT_DISC_COMPLETE: {
|
||||
NIMBLE_LOGD(LOG_TAG, "discovery complete; reason=%d",
|
||||
event->disc_complete.reason);
|
||||
|
||||
|
||||
if (pScan->m_scanCompleteCB != nullptr) {
|
||||
pScan->m_scanCompleteCB(pScan->m_scanResults);
|
||||
}
|
||||
|
||||
|
||||
pScan->m_stopped = true;
|
||||
pScan->m_semaphoreScanEnd.give();
|
||||
pScan->m_semaphoreScanEnd.give();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -224,13 +227,13 @@ void NimBLEScan::setWindow(uint16_t windowMSecs) {
|
|||
*/
|
||||
bool NimBLEScan::start(uint32_t duration, void (*scanCompleteCB)(NimBLEScanResults), bool is_continue) {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> start(duration=%d)", duration);
|
||||
|
||||
|
||||
// If Host is not synced we cannot start scanning.
|
||||
if(!NimBLEDevice::m_synced) {
|
||||
NIMBLE_LOGC(LOG_TAG, "Host reset, wait for sync.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if(ble_gap_conn_active()) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Connection in progress - must wait.");
|
||||
return false;
|
||||
|
@ -244,12 +247,12 @@ bool NimBLEScan::start(uint32_t duration, void (*scanCompleteCB)(NimBLEScanResul
|
|||
|
||||
m_stopped = false;
|
||||
m_semaphoreScanEnd.take("start");
|
||||
|
||||
|
||||
// Save the callback to be invoked when the scan completes.
|
||||
m_scanCompleteCB = scanCompleteCB;
|
||||
m_scanCompleteCB = scanCompleteCB;
|
||||
// Save the duration in the case that the host is reset so we can reuse it.
|
||||
m_duration = duration;
|
||||
|
||||
|
||||
// If 0 duration specified then we assume a continuous scan is desired.
|
||||
if(duration == 0){
|
||||
duration = BLE_HS_FOREVER;
|
||||
|
@ -257,22 +260,22 @@ bool NimBLEScan::start(uint32_t duration, void (*scanCompleteCB)(NimBLEScanResul
|
|||
else{
|
||||
duration = duration*1000; // convert duration to milliseconds
|
||||
}
|
||||
|
||||
|
||||
// if we are connecting to devices that are advertising even after being connected, multiconnecting peripherals
|
||||
// then we should not clear map or we will connect the same device few times
|
||||
if(!is_continue) {
|
||||
clearResults();
|
||||
}
|
||||
|
||||
|
||||
int rc = 0;
|
||||
do{
|
||||
rc = ble_gap_disc(m_own_addr_type, duration, &m_scan_params,
|
||||
do{
|
||||
rc = ble_gap_disc(m_own_addr_type, duration, &m_scan_params,
|
||||
NimBLEScan::handleGapEvent, this);
|
||||
if(rc == BLE_HS_EBUSY) {
|
||||
vTaskDelay(2);
|
||||
}
|
||||
} while(rc == BLE_HS_EBUSY);
|
||||
|
||||
|
||||
if (rc != 0 && rc != BLE_HS_EDONE) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Error initiating GAP discovery procedure; rc=%d, %s",
|
||||
rc, NimBLEUtils::returnCodeToString(rc));
|
||||
|
@ -305,7 +308,7 @@ NimBLEScanResults NimBLEScan::start(uint32_t duration, bool is_continue) {
|
|||
*/
|
||||
void NimBLEScan::stop() {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> stop()");
|
||||
|
||||
|
||||
int rc = ble_gap_disc_cancel();
|
||||
if (rc != 0 && rc != BLE_HS_EALREADY) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Failed to cancel scan; rc=%d\n", rc);
|
||||
|
@ -313,13 +316,13 @@ void NimBLEScan::stop() {
|
|||
}
|
||||
|
||||
m_stopped = true;
|
||||
|
||||
|
||||
if (m_scanCompleteCB != nullptr) {
|
||||
m_scanCompleteCB(m_scanResults);
|
||||
}
|
||||
|
||||
|
||||
m_semaphoreScanEnd.give();
|
||||
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "<< stop()");
|
||||
} // stop
|
||||
|
||||
|
@ -400,4 +403,5 @@ NimBLEAdvertisedDevice NimBLEScanResults::getDevice(uint32_t i) {
|
|||
return dev;
|
||||
}
|
||||
|
||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
||||
#endif /* CONFIG_BT_ENABLED */
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on Jan 24 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLEScan.h
|
||||
|
@ -16,6 +16,9 @@
|
|||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
||||
|
||||
#include "NimBLEAdvertisedDevice.h"
|
||||
#include "FreeRTOS.h"
|
||||
|
||||
|
@ -63,14 +66,14 @@ public:
|
|||
void clearResults();
|
||||
NimBLEScanResults getResults();
|
||||
void erase(const NimBLEAddress &address);
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
NimBLEScan();
|
||||
friend class NimBLEDevice;
|
||||
static int handleGapEvent(ble_gap_event* event, void* arg);
|
||||
void onHostReset();
|
||||
|
||||
|
||||
NimBLEAdvertisedDeviceCallbacks* m_pAdvertisedDeviceCallbacks = nullptr;
|
||||
void (*m_scanCompleteCB)(NimBLEScanResults scanResults);
|
||||
ble_gap_disc_params m_scan_params;
|
||||
|
@ -82,6 +85,6 @@ private:
|
|||
uint32_t m_duration;
|
||||
};
|
||||
|
||||
|
||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
||||
#endif /* CONFIG_BT_ENABLED */
|
||||
#endif /* COMPONENTS_NIMBLE_SCAN_H_ */
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on Feb 22 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLESecurity.cpp
|
||||
|
@ -73,7 +73,7 @@ void NimBLESecurity::setRespEncryptionKey(uint8_t resp_key) {
|
|||
*
|
||||
*/
|
||||
void NimBLESecurity::setKeySize(uint8_t key_size) {
|
||||
|
||||
|
||||
//m_keySize = key_size;
|
||||
//esp_ble_gap_set_security_param(ESP_BLE_SM_MAX_KEY_SIZE, &m_keySize, sizeof(uint8_t));
|
||||
} //setKeySize
|
||||
|
@ -132,7 +132,7 @@ char* BLESecurity::esp_key_type_to_str(esp_ble_key_type_t key_type) {
|
|||
break;
|
||||
}
|
||||
return key_str;
|
||||
|
||||
|
||||
} // esp_key_type_to_str
|
||||
*/
|
||||
#endif // CONFIG_BT_ENABLED
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on Feb 22 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLESecurity.h
|
||||
|
@ -12,8 +12,8 @@
|
|||
* Author: chegewara
|
||||
*/
|
||||
|
||||
/** This class exists for backward compatibility - Should not be used in new code
|
||||
* See the security functions in NimBLEDevice and callbacks in NimBLEServer / NimBLEClient
|
||||
/** This class exists for backward compatibility - Should not be used in new code
|
||||
* See the security functions in NimBLEDevice and callbacks in NimBLEServer / NimBLEClient
|
||||
*/
|
||||
|
||||
#ifndef COMPONENTS_NIMBLESECURITY_H_
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on March 2, 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLEServer.cpp
|
||||
|
@ -15,6 +15,9 @@
|
|||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
|
||||
#include "NimBLEServer.h"
|
||||
#include "NimBLE2902.h"
|
||||
#include "NimBLEUtils.h"
|
||||
|
@ -32,10 +35,10 @@ static NimBLEServerCallbacks defaultCallbacks;
|
|||
* the BLEDevice class.
|
||||
*/
|
||||
NimBLEServer::NimBLEServer() {
|
||||
m_connId = BLE_HS_CONN_HANDLE_NONE;
|
||||
m_connId = BLE_HS_CONN_HANDLE_NONE;
|
||||
m_svcChgChrHdl = 0xffff;
|
||||
m_pServerCallbacks = &defaultCallbacks;
|
||||
m_gattsStarted = false;
|
||||
m_pServerCallbacks = &defaultCallbacks;
|
||||
m_gattsStarted = false;
|
||||
} // BLEServer
|
||||
|
||||
|
||||
|
@ -48,7 +51,7 @@ NimBLEServer::NimBLEServer() {
|
|||
* @return A reference to the new service object.
|
||||
*/
|
||||
NimBLEService* NimBLEServer::createService(const char* uuid) {
|
||||
return createService(NimBLEUUID(uuid));
|
||||
return createService(NimBLEUUID(uuid));
|
||||
}
|
||||
|
||||
|
||||
|
@ -63,20 +66,20 @@ NimBLEService* NimBLEServer::createService(const char* uuid) {
|
|||
* @return A reference to the new service object.
|
||||
*/
|
||||
NimBLEService* NimBLEServer::createService(const NimBLEUUID &uuid, uint32_t numHandles, uint8_t inst_id) {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> createService - %s", uuid.toString().c_str());
|
||||
NIMBLE_LOGD(LOG_TAG, ">> createService - %s", uuid.toString().c_str());
|
||||
|
||||
// Check that a service with the supplied UUID does not already exist.
|
||||
if (m_serviceMap.getByUUID(uuid) != nullptr) {
|
||||
NIMBLE_LOGW(LOG_TAG, "<< Attempt to create a new service with uuid %s but a service with that UUID already exists.",
|
||||
uuid.toString().c_str());
|
||||
}
|
||||
// Check that a service with the supplied UUID does not already exist.
|
||||
if (m_serviceMap.getByUUID(uuid) != nullptr) {
|
||||
NIMBLE_LOGW(LOG_TAG, "<< Attempt to create a new service with uuid %s but a service with that UUID already exists.",
|
||||
uuid.toString().c_str());
|
||||
}
|
||||
|
||||
NimBLEService* pService = new NimBLEService(uuid, numHandles, this);
|
||||
pService->m_instId = inst_id;
|
||||
m_serviceMap.setByUUID(uuid, pService); // Save a reference to this service being on this server.
|
||||
NimBLEService* pService = new NimBLEService(uuid, numHandles, this);
|
||||
pService->m_instId = inst_id;
|
||||
m_serviceMap.setByUUID(uuid, pService); // Save a reference to this service being on this server.
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "<< createService");
|
||||
return pService;
|
||||
NIMBLE_LOGD(LOG_TAG, "<< createService");
|
||||
return pService;
|
||||
} // createService
|
||||
|
||||
|
||||
|
@ -86,7 +89,7 @@ NimBLEService* NimBLEServer::createService(const NimBLEUUID &uuid, uint32_t numH
|
|||
* @return A reference to the service object.
|
||||
*/
|
||||
NimBLEService* NimBLEServer::getServiceByUUID(const char* uuid) {
|
||||
return m_serviceMap.getByUUID(uuid);
|
||||
return m_serviceMap.getByUUID(uuid);
|
||||
}
|
||||
|
||||
|
||||
|
@ -96,7 +99,7 @@ NimBLEService* NimBLEServer::getServiceByUUID(const char* uuid) {
|
|||
* @return A reference to the service object.
|
||||
*/
|
||||
NimBLEService* NimBLEServer::getServiceByUUID(const NimBLEUUID &uuid) {
|
||||
return m_serviceMap.getByUUID(uuid);
|
||||
return m_serviceMap.getByUUID(uuid);
|
||||
}
|
||||
|
||||
|
||||
|
@ -106,7 +109,7 @@ NimBLEService* NimBLEServer::getServiceByUUID(const NimBLEUUID &uuid) {
|
|||
* @return An advertising object.
|
||||
*/
|
||||
NimBLEAdvertising* NimBLEServer::getAdvertising() {
|
||||
return BLEDevice::getAdvertising();
|
||||
return BLEDevice::getAdvertising();
|
||||
}
|
||||
|
||||
|
||||
|
@ -116,58 +119,58 @@ NimBLEAdvertising* NimBLEServer::getAdvertising() {
|
|||
* @return Client connection id.
|
||||
*/
|
||||
uint16_t NimBLEServer::getConnId() {
|
||||
return m_connId;
|
||||
return m_connId;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Start the GATT server. Required to be called after setup of all
|
||||
* @brief Start the GATT server. Required to be called after setup of all
|
||||
* services and characteristics / descriptors for the NimBLE host to register them.
|
||||
*/
|
||||
void NimBLEServer::start() {
|
||||
if(m_gattsStarted) {
|
||||
NIMBLE_LOGW(LOG_TAG, "Gatt server already started");
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_gattsStarted) {
|
||||
NIMBLE_LOGW(LOG_TAG, "Gatt server already started");
|
||||
return;
|
||||
}
|
||||
|
||||
int rc = ble_gatts_start();
|
||||
if (rc != 0) {
|
||||
NIMBLE_LOGE(LOG_TAG, "ble_gatts_start; rc=%d, %s", rc,
|
||||
NIMBLE_LOGE(LOG_TAG, "ble_gatts_start; rc=%d, %s", rc,
|
||||
NimBLEUtils::returnCodeToString(rc));
|
||||
abort();
|
||||
}
|
||||
|
||||
#if CONFIG_LOG_DEFAULT_LEVEL > 3 || (ARDUINO_ARCH_ESP32 && CORE_DEBUG_LEVEL >= 4)
|
||||
|
||||
#if CONFIG_LOG_DEFAULT_LEVEL > 3 || (ARDUINO_ARCH_ESP32 && CORE_DEBUG_LEVEL >= 4)
|
||||
ble_gatts_show_local();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
ble_uuid16_t svc = {BLE_UUID_TYPE_16, 0x1801};
|
||||
ble_uuid16_t chr = {BLE_UUID_TYPE_16, 0x2a05};
|
||||
|
||||
rc = ble_gatts_find_chr(&svc.u, &chr.u, NULL, &m_svcChgChrHdl);
|
||||
|
||||
rc = ble_gatts_find_chr(&svc.u, &chr.u, NULL, &m_svcChgChrHdl);
|
||||
if(rc != 0) {
|
||||
NIMBLE_LOGE(LOG_TAG, "ble_gatts_find_chr: rc=%d, %s", rc,
|
||||
NIMBLE_LOGE(LOG_TAG, "ble_gatts_find_chr: rc=%d, %s", rc,
|
||||
NimBLEUtils::returnCodeToString(rc));
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
NIMBLE_LOGI(LOG_TAG, "Service changed characterisic handle: %d", m_svcChgChrHdl);
|
||||
|
||||
|
||||
// Build a map of characteristics with Notify / Indicate capabilities for event handling
|
||||
uint8_t numSvcs = m_serviceMap.getRegisteredServiceCount();
|
||||
NimBLEService* pService = m_serviceMap.getFirst();
|
||||
|
||||
|
||||
for(int i = 0; i < numSvcs; i++) {
|
||||
uint8_t numChrs = pService->m_characteristicMap.getSize();
|
||||
NimBLECharacteristic* pChr = pService->m_characteristicMap.getFirst();
|
||||
|
||||
uint8_t numChrs = pService->m_characteristicMap.getSize();
|
||||
NimBLECharacteristic* pChr = pService->m_characteristicMap.getFirst();
|
||||
|
||||
if(pChr != nullptr) {
|
||||
for( int d = 0; d < numChrs; d++) {
|
||||
// if Notify / Indicate is enabled but we didn't create the descriptor
|
||||
// we do it now.
|
||||
if((pChr->m_properties & BLE_GATT_CHR_F_INDICATE) ||
|
||||
if((pChr->m_properties & BLE_GATT_CHR_F_INDICATE) ||
|
||||
(pChr->m_properties & BLE_GATT_CHR_F_NOTIFY)) {
|
||||
|
||||
|
||||
if(nullptr == pChr->getDescriptorByUUID("2902")) {
|
||||
pChr->createDescriptor("2902");
|
||||
}
|
||||
|
@ -179,8 +182,8 @@ void NimBLEServer::start() {
|
|||
}
|
||||
pService = m_serviceMap.getNext();
|
||||
}
|
||||
|
||||
m_gattsStarted = true;
|
||||
|
||||
m_gattsStarted = true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -192,13 +195,13 @@ void NimBLEServer::start() {
|
|||
*/
|
||||
int NimBLEServer::disconnect(uint16_t connId, uint8_t reason) {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> disconnect()");
|
||||
|
||||
|
||||
int rc = ble_gap_terminate(connId, reason);
|
||||
if(rc != 0){
|
||||
NIMBLE_LOGE(LOG_TAG, "ble_gap_terminate failed: rc=%d %s", rc,
|
||||
NIMBLE_LOGE(LOG_TAG, "ble_gap_terminate failed: rc=%d %s", rc,
|
||||
NimBLEUtils::returnCodeToString(rc));
|
||||
}
|
||||
|
||||
|
||||
return rc;
|
||||
NIMBLE_LOGD(LOG_TAG, "<< disconnect()");
|
||||
}
|
||||
|
@ -209,7 +212,7 @@ int NimBLEServer::disconnect(uint16_t connId, uint8_t reason) {
|
|||
* @return The number of connected clients.
|
||||
*/
|
||||
uint32_t NimBLEServer::getConnectedCount() {
|
||||
return m_connectedServersMap.size();
|
||||
return m_connectedServersMap.size();
|
||||
} // getConnectedCount
|
||||
|
||||
|
||||
|
@ -222,15 +225,15 @@ uint32_t NimBLEServer::getConnectedCount() {
|
|||
*
|
||||
*/
|
||||
/*STATIC*/int NimBLEServer::handleGapEvent(struct ble_gap_event *event, void *arg) {
|
||||
NimBLEServer* server = (NimBLEServer*)arg;
|
||||
NIMBLE_LOGD(LOG_TAG, ">> handleGapEvent: %s",
|
||||
NimBLEUtils::gapEventToString(event->type));
|
||||
NimBLEServer* server = (NimBLEServer*)arg;
|
||||
NIMBLE_LOGD(LOG_TAG, ">> handleGapEvent: %s",
|
||||
NimBLEUtils::gapEventToString(event->type));
|
||||
int rc = 0;
|
||||
struct ble_gap_conn_desc desc;
|
||||
|
||||
switch(event->type) {
|
||||
|
||||
case BLE_GAP_EVENT_CONNECT: {
|
||||
|
||||
switch(event->type) {
|
||||
|
||||
case BLE_GAP_EVENT_CONNECT: {
|
||||
if (event->connect.status != 0) {
|
||||
/* Connection failed; resume advertising */
|
||||
NIMBLE_LOGC(LOG_TAG, "Connection failed");
|
||||
|
@ -240,21 +243,21 @@ uint32_t NimBLEServer::getConnectedCount() {
|
|||
else {
|
||||
server->m_connId = event->connect.conn_handle;
|
||||
server->addPeerDevice((void*)server, false, server->m_connId);
|
||||
|
||||
|
||||
ble_gap_conn_desc desc;
|
||||
rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
|
||||
assert(rc == 0);
|
||||
|
||||
|
||||
server->m_pServerCallbacks->onConnect(server);
|
||||
server->m_pServerCallbacks->onConnect(server, &desc);
|
||||
server->m_pServerCallbacks->onConnect(server, &desc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
} // BLE_GAP_EVENT_CONNECT
|
||||
|
||||
|
||||
} // BLE_GAP_EVENT_CONNECT
|
||||
|
||||
|
||||
case BLE_GAP_EVENT_DISCONNECT: {
|
||||
// If Host reset tell the device now before returning to prevent
|
||||
// If Host reset tell the device now before returning to prevent
|
||||
// any errors caused by calling host functions before resyncing.
|
||||
switch(event->disconnect.reason) {
|
||||
case BLE_HS_ETIMEOUT_HCI:
|
||||
|
@ -264,22 +267,22 @@ uint32_t NimBLEServer::getConnectedCount() {
|
|||
NIMBLE_LOGC(LOG_TAG, "Disconnect - host reset, rc=%d", event->disconnect.reason);
|
||||
NimBLEDevice::onReset(event->disconnect.reason);
|
||||
break;
|
||||
default:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
server->removePeerDevice(event->disconnect.conn.conn_handle, false);
|
||||
server->m_connId = BLE_HS_CONN_HANDLE_NONE;
|
||||
server->m_connId = BLE_HS_CONN_HANDLE_NONE;
|
||||
server->m_pServerCallbacks->onDisconnect(server);
|
||||
|
||||
|
||||
return 0;
|
||||
} // BLE_GAP_EVENT_DISCONNECT
|
||||
|
||||
|
||||
case BLE_GAP_EVENT_SUBSCRIBE: {
|
||||
NIMBLE_LOGI(LOG_TAG, "subscribe event; cur_notify=%d\n value handle; "
|
||||
"val_handle=%d\n",
|
||||
event->subscribe.cur_notify, event->subscribe.attr_handle);
|
||||
|
||||
|
||||
auto it = server->m_notifyChrMap.find(event->subscribe.attr_handle);
|
||||
if(it != server->m_notifyChrMap.cend()) {
|
||||
(*it).second->setSubscribe(event);
|
||||
|
@ -287,7 +290,7 @@ uint32_t NimBLEServer::getConnectedCount() {
|
|||
|
||||
return 0;
|
||||
} // BLE_GAP_EVENT_SUBSCRIBE
|
||||
|
||||
|
||||
case BLE_GAP_EVENT_MTU: {
|
||||
NIMBLE_LOGI(LOG_TAG, "mtu update event; conn_handle=%d mtu=%d",
|
||||
event->mtu.conn_handle,
|
||||
|
@ -295,7 +298,7 @@ uint32_t NimBLEServer::getConnectedCount() {
|
|||
server->updatePeerMTU(event->mtu.conn_handle, event->mtu.value);
|
||||
return 0;
|
||||
} // BLE_GAP_EVENT_MTU
|
||||
|
||||
|
||||
case BLE_GAP_EVENT_NOTIFY_TX: {
|
||||
if(event->notify_tx.indication && event->notify_tx.status != 0) {
|
||||
auto it = server->m_notifyChrMap.find(event->notify_tx.attr_handle);
|
||||
|
@ -303,15 +306,15 @@ uint32_t NimBLEServer::getConnectedCount() {
|
|||
(*it).second->m_semaphoreConfEvt.give(event->notify_tx.status);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
} // BLE_GAP_EVENT_NOTIFY_TX
|
||||
|
||||
|
||||
case BLE_GAP_EVENT_CONN_UPDATE: {
|
||||
NIMBLE_LOGD(LOG_TAG, "Connection parameters updated.");
|
||||
return 0;
|
||||
} // BLE_GAP_EVENT_CONN_UPDATE
|
||||
|
||||
|
||||
case BLE_GAP_EVENT_REPEAT_PAIRING: {
|
||||
/* We already have a bond with the peer, but it is attempting to
|
||||
* establish a new secure link. This app sacrifices security for
|
||||
|
@ -328,8 +331,8 @@ uint32_t NimBLEServer::getConnectedCount() {
|
|||
*/
|
||||
return BLE_GAP_REPEAT_PAIRING_RETRY;
|
||||
} // BLE_GAP_EVENT_REPEAT_PAIRING
|
||||
|
||||
case BLE_GAP_EVENT_ENC_CHANGE: {
|
||||
|
||||
case BLE_GAP_EVENT_ENC_CHANGE: {
|
||||
rc = ble_gap_conn_find(event->conn_update.conn_handle, &desc);
|
||||
if(rc != 0) {
|
||||
return BLE_ATT_ERR_INVALID_HANDLE;
|
||||
|
@ -341,10 +344,10 @@ uint32_t NimBLEServer::getConnectedCount() {
|
|||
} else {
|
||||
server->m_pServerCallbacks->onAuthenticationComplete(&desc);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
} // BLE_GAP_EVENT_ENC_CHANGE
|
||||
|
||||
|
||||
case BLE_GAP_EVENT_PASSKEY_ACTION: {
|
||||
struct ble_sm_io pkey = {0};
|
||||
|
||||
|
@ -359,7 +362,7 @@ uint32_t NimBLEServer::getConnectedCount() {
|
|||
}
|
||||
rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
|
||||
NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_DISP; ble_sm_inject_io result: %d", rc);
|
||||
|
||||
|
||||
} else if (event->passkey.params.action == BLE_SM_IOACT_NUMCMP) {
|
||||
NIMBLE_LOGD(LOG_TAG, "Passkey on device's display: %d", event->passkey.params.numcmp);
|
||||
pkey.action = event->passkey.params.action;
|
||||
|
@ -370,11 +373,11 @@ uint32_t NimBLEServer::getConnectedCount() {
|
|||
} else {
|
||||
pkey.numcmp_accept = server->m_pServerCallbacks->onConfirmPIN(event->passkey.params.numcmp);
|
||||
}
|
||||
|
||||
|
||||
rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
|
||||
NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_NUMCMP; ble_sm_inject_io result: %d", rc);
|
||||
|
||||
//TODO: Handle out of band pairing
|
||||
|
||||
//TODO: Handle out of band pairing
|
||||
} else if (event->passkey.params.action == BLE_SM_IOACT_OOB) {
|
||||
static uint8_t tem_oob[16] = {0};
|
||||
pkey.action = event->passkey.params.action;
|
||||
|
@ -383,35 +386,35 @@ uint32_t NimBLEServer::getConnectedCount() {
|
|||
}
|
||||
rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
|
||||
NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_OOB; ble_sm_inject_io result: %d", rc);
|
||||
//////////////////////////////////
|
||||
//////////////////////////////////
|
||||
} else if (event->passkey.params.action == BLE_SM_IOACT_INPUT) {
|
||||
NIMBLE_LOGD(LOG_TAG, "Enter the passkey");
|
||||
pkey.action = event->passkey.params.action;
|
||||
|
||||
|
||||
// Compatibility only - Do not use, should be removed the in future
|
||||
if(NimBLEDevice::m_securityCallbacks != nullptr) {
|
||||
pkey.passkey = NimBLEDevice::m_securityCallbacks->onPassKeyRequest();
|
||||
/////////////////////////////////////////////
|
||||
} else {
|
||||
pkey.passkey = server->m_pServerCallbacks->onPassKeyRequest();
|
||||
}
|
||||
}
|
||||
|
||||
rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
|
||||
NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_INPUT; ble_sm_inject_io result: %d", rc);
|
||||
|
||||
|
||||
} else if (event->passkey.params.action == BLE_SM_IOACT_NONE) {
|
||||
NIMBLE_LOGD(LOG_TAG, "No passkey action required");
|
||||
}
|
||||
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "<< handleGATTServerEvent");
|
||||
return 0;
|
||||
} // BLE_GAP_EVENT_PASSKEY_ACTION
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "<< handleGATTServerEvent");
|
||||
NIMBLE_LOGD(LOG_TAG, "<< handleGATTServerEvent");
|
||||
return 0;
|
||||
} // handleGATTServerEvent
|
||||
|
||||
|
@ -427,10 +430,10 @@ uint32_t NimBLEServer::getConnectedCount() {
|
|||
*/
|
||||
void NimBLEServer::setCallbacks(NimBLEServerCallbacks* pCallbacks) {
|
||||
if (pCallbacks != nullptr){
|
||||
m_pServerCallbacks = pCallbacks;
|
||||
} else {
|
||||
m_pServerCallbacks = &defaultCallbacks;
|
||||
}
|
||||
m_pServerCallbacks = pCallbacks;
|
||||
} else {
|
||||
m_pServerCallbacks = &defaultCallbacks;
|
||||
}
|
||||
} // setCallbacks
|
||||
|
||||
|
||||
|
@ -439,9 +442,9 @@ void NimBLEServer::setCallbacks(NimBLEServerCallbacks* pCallbacks) {
|
|||
*/
|
||||
/*
|
||||
void BLEServer::removeService(BLEService* service) {
|
||||
service->stop();
|
||||
service->executeDelete();
|
||||
m_serviceMap.removeService(service);
|
||||
service->stop();
|
||||
service->executeDelete();
|
||||
m_serviceMap.removeService(service);
|
||||
}
|
||||
*/
|
||||
|
||||
|
@ -453,9 +456,9 @@ void BLEServer::removeService(BLEService* service) {
|
|||
* retrieving the advertising object and invoking start upon it.
|
||||
*/
|
||||
void NimBLEServer::startAdvertising() {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> startAdvertising");
|
||||
NimBLEDevice::startAdvertising();
|
||||
NIMBLE_LOGD(LOG_TAG, "<< startAdvertising");
|
||||
NIMBLE_LOGD(LOG_TAG, ">> startAdvertising");
|
||||
NimBLEDevice::startAdvertising();
|
||||
NIMBLE_LOGD(LOG_TAG, "<< startAdvertising");
|
||||
} // startAdvertising
|
||||
|
||||
|
||||
|
@ -463,51 +466,51 @@ void NimBLEServer::startAdvertising() {
|
|||
* @brief Stop advertising.
|
||||
*/
|
||||
void NimBLEServer::stopAdvertising() {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> stopAdvertising");
|
||||
NimBLEDevice::stopAdvertising();
|
||||
NIMBLE_LOGD(LOG_TAG, "<< stopAdvertising");
|
||||
NIMBLE_LOGD(LOG_TAG, ">> stopAdvertising");
|
||||
NimBLEDevice::stopAdvertising();
|
||||
NIMBLE_LOGD(LOG_TAG, "<< stopAdvertising");
|
||||
} // startAdvertising
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Allow to connect GATT server to peer device
|
||||
* Probably can be used in ANCS for iPhone
|
||||
*/
|
||||
/*
|
||||
bool BLEServer::connect(BLEAddress address) {
|
||||
esp_bd_addr_t addr;
|
||||
memcpy(&addr, address.getNative(), 6);
|
||||
// Perform the open connection request against the target BLE Server.
|
||||
m_semaphoreOpenEvt.take("connect");
|
||||
esp_err_t errRc = ::esp_ble_gatts_open(
|
||||
getGattsIf(),
|
||||
addr, // address
|
||||
1 // direct connection
|
||||
);
|
||||
if (errRc != ESP_OK) {
|
||||
ESP_LOGE(LOG_TAG, "esp_ble_gattc_open: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
|
||||
return false;
|
||||
}
|
||||
esp_bd_addr_t addr;
|
||||
memcpy(&addr, address.getNative(), 6);
|
||||
// Perform the open connection request against the target BLE Server.
|
||||
m_semaphoreOpenEvt.take("connect");
|
||||
esp_err_t errRc = ::esp_ble_gatts_open(
|
||||
getGattsIf(),
|
||||
addr, // address
|
||||
1 // direct connection
|
||||
);
|
||||
if (errRc != ESP_OK) {
|
||||
ESP_LOGE(LOG_TAG, "esp_ble_gattc_open: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t rc = m_semaphoreOpenEvt.wait("connect"); // Wait for the connection to complete.
|
||||
ESP_LOGD(LOG_TAG, "<< connect(), rc=%d", rc==ESP_GATT_OK);
|
||||
return rc == ESP_GATT_OK;
|
||||
uint32_t rc = m_semaphoreOpenEvt.wait("connect"); // Wait for the connection to complete.
|
||||
ESP_LOGD(LOG_TAG, "<< connect(), rc=%d", rc==ESP_GATT_OK);
|
||||
return rc == ESP_GATT_OK;
|
||||
} // connect
|
||||
*/
|
||||
|
||||
|
||||
void NimBLEServerCallbacks::onConnect(NimBLEServer* pServer) {
|
||||
NIMBLE_LOGD("NimBLEServerCallbacks", "onConnect(): Default");
|
||||
NIMBLE_LOGD("NimBLEServerCallbacks", "onConnect(): Default");
|
||||
} // onConnect
|
||||
|
||||
|
||||
void NimBLEServerCallbacks::onConnect(NimBLEServer* pServer, ble_gap_conn_desc* desc) {
|
||||
NIMBLE_LOGD("NimBLEServerCallbacks", "onConnect(): Default");
|
||||
NIMBLE_LOGD("NimBLEServerCallbacks", "onConnect(): Default");
|
||||
} // onConnect
|
||||
|
||||
|
||||
void NimBLEServerCallbacks::onDisconnect(NimBLEServer* pServer) {
|
||||
NIMBLE_LOGD("NimBLEServerCallbacks", "onDisconnect(): Default");
|
||||
NIMBLE_LOGD("NimBLEServerCallbacks", "onDisconnect(): Default");
|
||||
} // onDisconnect
|
||||
|
||||
uint32_t NimBLEServerCallbacks::onPassKeyRequest(){
|
||||
|
@ -533,14 +536,14 @@ bool NimBLEServerCallbacks::onConfirmPIN(uint32_t pin){
|
|||
|
||||
/* multi connect support */
|
||||
void NimBLEServer::updatePeerMTU(uint16_t conn_id, uint16_t mtu) {
|
||||
const std::map<uint16_t, conn_status_t>::iterator it = m_connectedServersMap.find(conn_id);
|
||||
if (it != m_connectedServersMap.end()) {
|
||||
it->second.mtu = mtu;
|
||||
}
|
||||
const std::map<uint16_t, conn_status_t>::iterator it = m_connectedServersMap.find(conn_id);
|
||||
if (it != m_connectedServersMap.end()) {
|
||||
it->second.mtu = mtu;
|
||||
}
|
||||
}
|
||||
|
||||
std::map<uint16_t, conn_status_t> NimBLEServer::getPeerDevices() {
|
||||
return m_connectedServersMap;
|
||||
return m_connectedServersMap;
|
||||
}
|
||||
|
||||
|
||||
|
@ -558,17 +561,17 @@ uint16_t NimBLEServer::getPeerMTU(uint16_t conn_id) {
|
|||
}
|
||||
|
||||
void NimBLEServer::addPeerDevice(void* peer, bool _client, uint16_t conn_id) {
|
||||
conn_status_t status = {
|
||||
.peer_device = peer,
|
||||
.connected = true,
|
||||
.mtu = 23
|
||||
};
|
||||
conn_status_t status = {
|
||||
.peer_device = peer,
|
||||
.connected = true,
|
||||
.mtu = 23
|
||||
};
|
||||
|
||||
m_connectedServersMap.insert(std::pair<uint16_t, conn_status_t>(conn_id, status));
|
||||
m_connectedServersMap.insert(std::pair<uint16_t, conn_status_t>(conn_id, status));
|
||||
}
|
||||
|
||||
void NimBLEServer::removePeerDevice(uint16_t conn_id, bool _client) {
|
||||
m_connectedServersMap.erase(conn_id);
|
||||
m_connectedServersMap.erase(conn_id);
|
||||
}
|
||||
/* multi connect support */
|
||||
|
||||
|
@ -576,20 +579,20 @@ void NimBLEServer::removePeerDevice(uint16_t conn_id, bool _client) {
|
|||
/**
|
||||
* Update connection parameters can be called only after connection has been established
|
||||
*/
|
||||
void NimBLEServer::updateConnParams(uint16_t conn_handle,
|
||||
uint16_t minInterval, uint16_t maxInterval,
|
||||
void NimBLEServer::updateConnParams(uint16_t conn_handle,
|
||||
uint16_t minInterval, uint16_t maxInterval,
|
||||
uint16_t latency, uint16_t timeout,
|
||||
uint16_t minConnTime, uint16_t maxConnTime)
|
||||
uint16_t minConnTime, uint16_t maxConnTime)
|
||||
{
|
||||
ble_gap_upd_params params;
|
||||
ble_gap_upd_params params;
|
||||
|
||||
params.latency = latency;
|
||||
params.itvl_max = maxInterval; // max_int = 0x20*1.25ms = 40ms
|
||||
params.itvl_min = minInterval; // min_int = 0x10*1.25ms = 20ms
|
||||
params.supervision_timeout = timeout; // timeout = 400*10ms = 4000ms
|
||||
params.latency = latency;
|
||||
params.itvl_max = maxInterval; // max_int = 0x20*1.25ms = 40ms
|
||||
params.itvl_min = minInterval; // min_int = 0x10*1.25ms = 20ms
|
||||
params.supervision_timeout = timeout; // timeout = 400*10ms = 4000ms
|
||||
params.min_ce_len = minConnTime; // Minimum length of connection event in 0.625ms units
|
||||
params.max_ce_len = maxConnTime; // Maximum length of connection event in 0.625ms units
|
||||
|
||||
|
||||
int rc = ble_gap_update_params(conn_handle, ¶ms);
|
||||
if(rc != 0) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Update params error: %d, %s", rc, NimBLEUtils::returnCodeToString(rc));
|
||||
|
@ -602,7 +605,9 @@ void NimBLEServer::onHostReset() {
|
|||
for(auto it = m_notifyChrMap.cbegin(); it != m_notifyChrMap.cend(); ++it) {
|
||||
(*it).second->m_semaphoreConfEvt.give(0);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
#endif // CONFIG_BT_ENABLED
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on March 2, 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLEServer.h
|
||||
|
@ -17,6 +17,9 @@
|
|||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
|
||||
#include "NimBLEAddress.h"
|
||||
#include "NimBLEUUID.h"
|
||||
#include "NimBLEAdvertising.h"
|
||||
|
@ -24,14 +27,13 @@
|
|||
#include "NimBLESecurity.h"
|
||||
#include "FreeRTOS.h"
|
||||
|
||||
|
||||
#include <map>
|
||||
|
||||
class NimBLEService;
|
||||
class NimBLECharacteristic;
|
||||
class NimBLEServerCallbacks;
|
||||
|
||||
/* TODO possibly refactor this struct */
|
||||
/* TODO possibly refactor this struct */
|
||||
typedef struct {
|
||||
void *peer_device; // peer device BLEClient or BLEServer - maybe its better to have 2 structures or union here
|
||||
bool connected; // do we need it?
|
||||
|
@ -45,7 +47,7 @@ typedef struct {
|
|||
class NimBLEServiceMap {
|
||||
public:
|
||||
// NimBLEService* getByHandle(uint16_t handle);
|
||||
NimBLEService* getByUUID(const char* uuid);
|
||||
NimBLEService* getByUUID(const char* uuid);
|
||||
NimBLEService* getByUUID(const NimBLEUUID &uuid, uint8_t inst_id = 0);
|
||||
// void setByHandle(uint16_t handle, NimBLEService* service);
|
||||
void setByUUID(const char* uuid, NimBLEService* service);
|
||||
|
@ -69,7 +71,7 @@ private:
|
|||
class NimBLEServer {
|
||||
public:
|
||||
uint32_t getConnectedCount();
|
||||
NimBLEService* createService(const char* uuid);
|
||||
NimBLEService* createService(const char* uuid);
|
||||
NimBLEService* createService(const NimBLEUUID &uuid, uint32_t numHandles=15, uint8_t inst_id=0);
|
||||
NimBLEAdvertising* getAdvertising();
|
||||
void setCallbacks(NimBLEServerCallbacks* pCallbacks);
|
||||
|
@ -81,8 +83,8 @@ public:
|
|||
NimBLEService* getServiceByUUID(const NimBLEUUID &uuid);
|
||||
int disconnect(uint16_t connID, uint8_t reason = BLE_ERR_REM_USER_CONN_TERM);
|
||||
// bool connect(BLEAddress address);
|
||||
void updateConnParams(uint16_t conn_handle,
|
||||
uint16_t minInterval, uint16_t maxInterval,
|
||||
void updateConnParams(uint16_t conn_handle,
|
||||
uint16_t minInterval, uint16_t maxInterval,
|
||||
uint16_t latency, uint16_t timeout,
|
||||
uint16_t minConnTime=0, uint16_t maxConnTime=0);
|
||||
|
||||
|
@ -106,15 +108,15 @@ private:
|
|||
// BLEAdvertising m_bleAdvertising;
|
||||
uint16_t m_connId;
|
||||
uint16_t m_svcChgChrHdl;
|
||||
bool m_gattsStarted;
|
||||
|
||||
bool m_gattsStarted;
|
||||
|
||||
std::map<uint16_t, conn_status_t> m_connectedServersMap;
|
||||
std::map<uint16_t, NimBLECharacteristic*> m_notifyChrMap;
|
||||
|
||||
NimBLEServiceMap m_serviceMap;
|
||||
NimBLEServerCallbacks* m_pServerCallbacks;
|
||||
|
||||
static int handleGapEvent(struct ble_gap_event *event, void *arg);
|
||||
static int handleGapEvent(struct ble_gap_event *event, void *arg);
|
||||
}; // NimBLEServer
|
||||
|
||||
|
||||
|
@ -141,7 +143,7 @@ public:
|
|||
* @param [in] pServer A reference to the %BLE server that received the existing client disconnection.
|
||||
*/
|
||||
virtual void onDisconnect(NimBLEServer* pServer);
|
||||
|
||||
|
||||
virtual uint32_t onPassKeyRequest(); //{return 0;}
|
||||
virtual void onPassKeyNotify(uint32_t pass_key); //{}
|
||||
virtual bool onSecurityRequest(); //{return true;}
|
||||
|
@ -150,5 +152,6 @@ public:
|
|||
}; // BLEServerCallbacks
|
||||
|
||||
|
||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
#endif /* CONFIG_BT_ENABLED */
|
||||
#endif /* MAIN_NIMBLESERVER_H_ */
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on March 2, 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLEService.cpp
|
||||
|
@ -17,6 +17,9 @@
|
|||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
|
||||
#include "NimBLEService.h"
|
||||
#include "NimBLEUtils.h"
|
||||
#include "NimBLELog.h"
|
||||
|
@ -33,7 +36,7 @@ static const char* LOG_TAG = "NimBLEService"; // Tag for logging.
|
|||
* @param [in] uuid The UUID of the service.
|
||||
* @param [in] numHandles The maximum number of handles associated with the service.
|
||||
*/
|
||||
NimBLEService::NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer* pServer)
|
||||
NimBLEService::NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer* pServer)
|
||||
: NimBLEService(NimBLEUUID(uuid), numHandles, pServer) {
|
||||
}
|
||||
|
||||
|
@ -44,10 +47,10 @@ NimBLEService::NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer
|
|||
* @param [in] numHandles The maximum number of handles associated with the service.
|
||||
*/
|
||||
NimBLEService::NimBLEService(const NimBLEUUID &uuid, uint16_t numHandles, NimBLEServer* pServer) {
|
||||
m_uuid = uuid;
|
||||
m_handle = NULL_HANDLE;
|
||||
m_pServer = pServer;
|
||||
m_numHandles = numHandles;
|
||||
m_uuid = uuid;
|
||||
m_handle = NULL_HANDLE;
|
||||
m_pServer = pServer;
|
||||
m_numHandles = numHandles;
|
||||
} // NimBLEService
|
||||
|
||||
|
||||
|
@ -56,10 +59,10 @@ NimBLEService::NimBLEService(const NimBLEUUID &uuid, uint16_t numHandles, NimBLE
|
|||
* @return N/A.
|
||||
*/
|
||||
void NimBLEService::dump() {
|
||||
NIMBLE_LOGD(LOG_TAG, "Service: uuid:%s, handle: 0x%.2x",
|
||||
m_uuid.toString().c_str(),
|
||||
m_handle);
|
||||
NIMBLE_LOGD(LOG_TAG, "Characteristics:\n%s", m_characteristicMap.toString().c_str());
|
||||
NIMBLE_LOGD(LOG_TAG, "Service: uuid:%s, handle: 0x%.2x",
|
||||
m_uuid.toString().c_str(),
|
||||
m_handle);
|
||||
NIMBLE_LOGD(LOG_TAG, "Characteristics:\n%s", m_characteristicMap.toString().c_str());
|
||||
} // dump
|
||||
|
||||
|
||||
|
@ -68,7 +71,7 @@ void NimBLEService::dump() {
|
|||
* @return the UUID of the service.
|
||||
*/
|
||||
NimBLEUUID NimBLEService::getUUID() {
|
||||
return m_uuid;
|
||||
return m_uuid;
|
||||
} // getUUID
|
||||
|
||||
|
||||
|
@ -78,46 +81,46 @@ NimBLEUUID NimBLEService::getUUID() {
|
|||
* Starting a service also means that we can create the corresponding characteristics.
|
||||
* @return Start the service.
|
||||
*/
|
||||
|
||||
|
||||
bool NimBLEService::start() {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> start(): Starting service: %s", toString().c_str());
|
||||
int rc = 0;
|
||||
// Nimble requires an array of services to be sent to the api
|
||||
// Since we are adding 1 at a time we create an array of 2 and set the type
|
||||
// of the second service to 0 to indicate the end of the array.
|
||||
NIMBLE_LOGD(LOG_TAG, ">> start(): Starting service: %s", toString().c_str());
|
||||
int rc = 0;
|
||||
// Nimble requires an array of services to be sent to the api
|
||||
// Since we are adding 1 at a time we create an array of 2 and set the type
|
||||
// of the second service to 0 to indicate the end of the array.
|
||||
ble_gatt_svc_def* svc = new ble_gatt_svc_def[2];
|
||||
ble_gatt_chr_def* pChr_a = nullptr;
|
||||
ble_gatt_chr_def* pChr_a = nullptr;
|
||||
ble_gatt_dsc_def* pDsc_a = nullptr;
|
||||
|
||||
|
||||
svc[0].type = BLE_GATT_SVC_TYPE_PRIMARY;
|
||||
svc[0].uuid = &m_uuid.getNative()->u;
|
||||
svc[0].includes = NULL;
|
||||
|
||||
uint8_t numChrs = m_characteristicMap.getSize();
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG,"Adding %d characteristics for service %s", numChrs, toString().c_str());
|
||||
|
||||
if(!numChrs){
|
||||
svc[0].characteristics = NULL;
|
||||
}else{
|
||||
svc[0].includes = NULL;
|
||||
|
||||
uint8_t numChrs = m_characteristicMap.getSize();
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG,"Adding %d characteristics for service %s", numChrs, toString().c_str());
|
||||
|
||||
if(!numChrs){
|
||||
svc[0].characteristics = NULL;
|
||||
}else{
|
||||
// Nimble requires the last characteristic to have it's uuid = 0 to indicate the end
|
||||
// of the characteristics for the service. We create 1 extra and set it to null
|
||||
// for this purpose.
|
||||
pChr_a = new ble_gatt_chr_def[numChrs+1];
|
||||
NimBLECharacteristic* pCharacteristic = m_characteristicMap.getFirst();
|
||||
|
||||
for(uint8_t i=0; i < numChrs; i++) {
|
||||
pChr_a = new ble_gatt_chr_def[numChrs+1];
|
||||
NimBLECharacteristic* pCharacteristic = m_characteristicMap.getFirst();
|
||||
|
||||
for(uint8_t i=0; i < numChrs; i++) {
|
||||
uint8_t numDscs = pCharacteristic->m_descriptorMap.getSize();
|
||||
if(numDscs) {
|
||||
// skip 2902 as it's automatically created by NimBLE
|
||||
// if Indicate or Notify flags are set
|
||||
if(((pCharacteristic->m_properties & BLE_GATT_CHR_F_INDICATE) ||
|
||||
if(((pCharacteristic->m_properties & BLE_GATT_CHR_F_INDICATE) ||
|
||||
(pCharacteristic->m_properties & BLE_GATT_CHR_F_NOTIFY)) &&
|
||||
pCharacteristic->getDescriptorByUUID("2902") != nullptr) {
|
||||
numDscs--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(!numDscs){
|
||||
pChr_a[i].descriptors = NULL;
|
||||
} else {
|
||||
|
@ -140,41 +143,41 @@ bool NimBLEService::start() {
|
|||
pDescriptor = pCharacteristic->m_descriptorMap.getNext();
|
||||
d++;
|
||||
}
|
||||
|
||||
|
||||
pDsc_a[numDscs].uuid = NULL;
|
||||
pChr_a[i].descriptors = pDsc_a;
|
||||
}
|
||||
|
||||
pChr_a[i].uuid = &pCharacteristic->m_uuid.getNative()->u;
|
||||
|
||||
pChr_a[i].uuid = &pCharacteristic->m_uuid.getNative()->u;
|
||||
pChr_a[i].access_cb = NimBLECharacteristic::handleGapEvent;
|
||||
pChr_a[i].arg = pCharacteristic;
|
||||
pChr_a[i].flags = pCharacteristic->m_properties;
|
||||
pChr_a[i].min_key_size = 0;
|
||||
pChr_a[i].val_handle = &pCharacteristic->m_handle;
|
||||
pCharacteristic = m_characteristicMap.getNext();
|
||||
}
|
||||
|
||||
pChr_a[numChrs].uuid = NULL;
|
||||
svc[0].characteristics = pChr_a;
|
||||
}
|
||||
|
||||
// end of services must indicate to api with type = 0
|
||||
svc[1].type = 0;
|
||||
|
||||
pCharacteristic = m_characteristicMap.getNext();
|
||||
}
|
||||
|
||||
pChr_a[numChrs].uuid = NULL;
|
||||
svc[0].characteristics = pChr_a;
|
||||
}
|
||||
|
||||
// end of services must indicate to api with type = 0
|
||||
svc[1].type = 0;
|
||||
|
||||
rc = ble_gatts_count_cfg((const ble_gatt_svc_def*)svc);
|
||||
if (rc != 0) {
|
||||
NIMBLE_LOGE(LOG_TAG, "ble_gatts_count_cfg failed, rc= %d, %s", rc, NimBLEUtils::returnCodeToString(rc));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
rc = ble_gatts_add_svcs((const ble_gatt_svc_def*)svc);
|
||||
if (rc != 0) {
|
||||
NIMBLE_LOGE(LOG_TAG, "ble_gatts_add_svcs, rc= %d, %s", rc, NimBLEUtils::returnCodeToString(rc));
|
||||
return false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "<< start()");
|
||||
NIMBLE_LOGD(LOG_TAG, "<< start()");
|
||||
return true;
|
||||
} // start
|
||||
|
||||
|
@ -184,13 +187,13 @@ bool NimBLEService::start() {
|
|||
* @param [in] handle The handle associated with the service.
|
||||
*/
|
||||
void NimBLEService::setHandle(uint16_t handle) {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> setHandle - Handle=0x%.2x, service UUID=%s)", handle, getUUID().toString().c_str());
|
||||
if (m_handle != NULL_HANDLE) {
|
||||
NIMBLE_LOGE(LOG_TAG, "!!! Handle is already set %.2x", m_handle);
|
||||
return;
|
||||
}
|
||||
m_handle = handle;
|
||||
NIMBLE_LOGD(LOG_TAG, "<< setHandle");
|
||||
NIMBLE_LOGD(LOG_TAG, ">> setHandle - Handle=0x%.2x, service UUID=%s)", handle, getUUID().toString().c_str());
|
||||
if (m_handle != NULL_HANDLE) {
|
||||
NIMBLE_LOGE(LOG_TAG, "!!! Handle is already set %.2x", m_handle);
|
||||
return;
|
||||
}
|
||||
m_handle = handle;
|
||||
NIMBLE_LOGD(LOG_TAG, "<< setHandle");
|
||||
} // setHandle
|
||||
|
||||
|
||||
|
@ -199,7 +202,7 @@ void NimBLEService::setHandle(uint16_t handle) {
|
|||
* @return The handle associated with this service.
|
||||
*/
|
||||
uint16_t NimBLEService::getHandle() {
|
||||
return m_handle;
|
||||
return m_handle;
|
||||
} // getHandle
|
||||
|
||||
|
||||
|
@ -208,26 +211,26 @@ uint16_t NimBLEService::getHandle() {
|
|||
* @param [in] pCharacteristic A pointer to the characteristic to be added.
|
||||
*/
|
||||
void NimBLEService::addCharacteristic(NimBLECharacteristic* pCharacteristic) {
|
||||
// We maintain a mapping of characteristics owned by this service. These are managed by the
|
||||
// BLECharacteristicMap class instance found in m_characteristicMap. We add the characteristic
|
||||
// to the map and then ask the service to add the characteristic at the BLE level (ESP-IDF).
|
||||
// We maintain a mapping of characteristics owned by this service. These are managed by the
|
||||
// BLECharacteristicMap class instance found in m_characteristicMap. We add the characteristic
|
||||
// to the map and then ask the service to add the characteristic at the BLE level (ESP-IDF).
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, ">> addCharacteristic()");
|
||||
NIMBLE_LOGD(LOG_TAG, "Adding characteristic: uuid=%s to service: %s",
|
||||
pCharacteristic->getUUID().toString().c_str(),
|
||||
toString().c_str());
|
||||
NIMBLE_LOGD(LOG_TAG, ">> addCharacteristic()");
|
||||
NIMBLE_LOGD(LOG_TAG, "Adding characteristic: uuid=%s to service: %s",
|
||||
pCharacteristic->getUUID().toString().c_str(),
|
||||
toString().c_str());
|
||||
|
||||
// Check that we don't add the same characteristic twice.
|
||||
if (m_characteristicMap.getByUUID(pCharacteristic->getUUID()) != nullptr) {
|
||||
NIMBLE_LOGW(LOG_TAG, "<< Adding a new characteristic with the same UUID as a previous one");
|
||||
//return;
|
||||
}
|
||||
// Check that we don't add the same characteristic twice.
|
||||
if (m_characteristicMap.getByUUID(pCharacteristic->getUUID()) != nullptr) {
|
||||
NIMBLE_LOGW(LOG_TAG, "<< Adding a new characteristic with the same UUID as a previous one");
|
||||
//return;
|
||||
}
|
||||
|
||||
// Remember this characteristic in our map of characteristics. At this point, we can lookup by UUID
|
||||
// but not by handle. The handle is allocated to us on the ESP_GATTS_ADD_CHAR_EVT.
|
||||
m_characteristicMap.setByUUID(pCharacteristic, pCharacteristic->getUUID());
|
||||
// Remember this characteristic in our map of characteristics. At this point, we can lookup by UUID
|
||||
// but not by handle. The handle is allocated to us on the ESP_GATTS_ADD_CHAR_EVT.
|
||||
m_characteristicMap.setByUUID(pCharacteristic, pCharacteristic->getUUID());
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "<< addCharacteristic()");
|
||||
NIMBLE_LOGD(LOG_TAG, "<< addCharacteristic()");
|
||||
} // addCharacteristic
|
||||
|
||||
|
||||
|
@ -238,7 +241,7 @@ void NimBLEService::addCharacteristic(NimBLECharacteristic* pCharacteristic) {
|
|||
* @return The new BLE characteristic.
|
||||
*/
|
||||
NimBLECharacteristic* NimBLEService::createCharacteristic(const char* uuid, uint32_t properties) {
|
||||
return createCharacteristic(NimBLEUUID(uuid), properties);
|
||||
return createCharacteristic(NimBLEUUID(uuid), properties);
|
||||
}
|
||||
|
||||
|
||||
|
@ -249,20 +252,20 @@ NimBLECharacteristic* NimBLEService::createCharacteristic(const char* uuid, uint
|
|||
* @return The new BLE characteristic.
|
||||
*/
|
||||
NimBLECharacteristic* NimBLEService::createCharacteristic(const NimBLEUUID &uuid, uint32_t properties) {
|
||||
NimBLECharacteristic* pCharacteristic = new NimBLECharacteristic(uuid, properties, this);
|
||||
addCharacteristic(pCharacteristic);
|
||||
NimBLECharacteristic* pCharacteristic = new NimBLECharacteristic(uuid, properties, this);
|
||||
addCharacteristic(pCharacteristic);
|
||||
//pCharacteristic->executeCreate(this);
|
||||
return pCharacteristic;
|
||||
return pCharacteristic;
|
||||
} // createCharacteristic
|
||||
|
||||
|
||||
NimBLECharacteristic* NimBLEService::getCharacteristic(const char* uuid) {
|
||||
return getCharacteristic(NimBLEUUID(uuid));
|
||||
return getCharacteristic(NimBLEUUID(uuid));
|
||||
}
|
||||
|
||||
|
||||
NimBLECharacteristic* NimBLEService::getCharacteristic(const NimBLEUUID &uuid) {
|
||||
return m_characteristicMap.getByUUID(uuid);
|
||||
return m_characteristicMap.getByUUID(uuid);
|
||||
}
|
||||
|
||||
|
||||
|
@ -274,12 +277,12 @@ NimBLECharacteristic* NimBLEService::getCharacteristic(const NimBLEUUID &uuid) {
|
|||
* @return A string representation of this service.
|
||||
*/
|
||||
std::string NimBLEService::toString() {
|
||||
std::string res = "UUID: " + getUUID().toString();
|
||||
char hex[5];
|
||||
snprintf(hex, sizeof(hex), "%04x", getHandle());
|
||||
res += ", handle: 0x";
|
||||
res += hex;
|
||||
return res;
|
||||
std::string res = "UUID: " + getUUID().toString();
|
||||
char hex[5];
|
||||
snprintf(hex, sizeof(hex), "%04x", getHandle());
|
||||
res += ", handle: 0x";
|
||||
res += hex;
|
||||
return res;
|
||||
} // toString
|
||||
|
||||
|
||||
|
@ -288,7 +291,8 @@ std::string NimBLEService::toString() {
|
|||
* @return The BLEServer associated with this service.
|
||||
*/
|
||||
NimBLEServer* NimBLEService::getServer() {
|
||||
return m_pServer;
|
||||
return m_pServer;
|
||||
} // getServer
|
||||
|
||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
#endif // CONFIG_BT_ENABLED
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on March 2, 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLEService.h
|
||||
|
@ -17,6 +17,9 @@
|
|||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
|
||||
#include "NimBLECharacteristic.h"
|
||||
#include "NimBLEServer.h"
|
||||
#include "NimBLEUUID.h"
|
||||
|
@ -31,21 +34,21 @@ class NimBLECharacteristic;
|
|||
*/
|
||||
class NimBLECharacteristicMap {
|
||||
public:
|
||||
void setByUUID(NimBLECharacteristic* pCharacteristic, const char* uuid);
|
||||
void setByUUID(NimBLECharacteristic* pCharacteristic, const NimBLEUUID &uuid);
|
||||
void setByHandle(uint16_t handle, NimBLECharacteristic* pCharacteristic);
|
||||
NimBLECharacteristic* getByUUID(const char* uuid);
|
||||
NimBLECharacteristic* getByUUID(const NimBLEUUID &uuid);
|
||||
NimBLECharacteristic* getByHandle(uint16_t handle);
|
||||
NimBLECharacteristic* getFirst();
|
||||
NimBLECharacteristic* getNext();
|
||||
uint8_t getSize();
|
||||
std::string toString();
|
||||
void setByUUID(NimBLECharacteristic* pCharacteristic, const char* uuid);
|
||||
void setByUUID(NimBLECharacteristic* pCharacteristic, const NimBLEUUID &uuid);
|
||||
void setByHandle(uint16_t handle, NimBLECharacteristic* pCharacteristic);
|
||||
NimBLECharacteristic* getByUUID(const char* uuid);
|
||||
NimBLECharacteristic* getByUUID(const NimBLEUUID &uuid);
|
||||
NimBLECharacteristic* getByHandle(uint16_t handle);
|
||||
NimBLECharacteristic* getFirst();
|
||||
NimBLECharacteristic* getNext();
|
||||
uint8_t getSize();
|
||||
std::string toString();
|
||||
|
||||
private:
|
||||
std::map<NimBLECharacteristic*, std::string> m_uuidMap;
|
||||
std::map<uint16_t, NimBLECharacteristic*> m_handleMap;
|
||||
std::map<NimBLECharacteristic*, std::string>::iterator m_iterator;
|
||||
std::map<NimBLECharacteristic*, std::string> m_uuidMap;
|
||||
std::map<uint16_t, NimBLECharacteristic*> m_handleMap;
|
||||
std::map<NimBLECharacteristic*, std::string>::iterator m_iterator;
|
||||
};
|
||||
|
||||
|
||||
|
@ -55,42 +58,43 @@ private:
|
|||
*/
|
||||
class NimBLEService {
|
||||
public:
|
||||
NimBLECharacteristic* createCharacteristic(const char* uuid,
|
||||
uint32_t properties = NIMBLE_PROPERTY::READ |
|
||||
NIMBLE_PROPERTY::WRITE);
|
||||
|
||||
NimBLECharacteristic* createCharacteristic(const NimBLEUUID &uuid,
|
||||
uint32_t properties = NIMBLE_PROPERTY::READ |
|
||||
NIMBLE_PROPERTY::WRITE);
|
||||
|
||||
void dump();
|
||||
NimBLECharacteristic* getCharacteristic(const char* uuid);
|
||||
NimBLECharacteristic* getCharacteristic(const NimBLEUUID &uuid);
|
||||
NimBLEUUID getUUID();
|
||||
NimBLEServer* getServer();
|
||||
bool start();
|
||||
// void stop();
|
||||
std::string toString();
|
||||
uint16_t getHandle();
|
||||
uint8_t m_instId = 0;
|
||||
NimBLECharacteristic* createCharacteristic(const char* uuid,
|
||||
uint32_t properties = NIMBLE_PROPERTY::READ |
|
||||
NIMBLE_PROPERTY::WRITE);
|
||||
|
||||
NimBLECharacteristic* createCharacteristic(const NimBLEUUID &uuid,
|
||||
uint32_t properties = NIMBLE_PROPERTY::READ |
|
||||
NIMBLE_PROPERTY::WRITE);
|
||||
|
||||
void dump();
|
||||
NimBLECharacteristic* getCharacteristic(const char* uuid);
|
||||
NimBLECharacteristic* getCharacteristic(const NimBLEUUID &uuid);
|
||||
NimBLEUUID getUUID();
|
||||
NimBLEServer* getServer();
|
||||
bool start();
|
||||
// void stop();
|
||||
std::string toString();
|
||||
uint16_t getHandle();
|
||||
uint8_t m_instId = 0;
|
||||
|
||||
private:
|
||||
NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer* pServer);
|
||||
NimBLEService(const NimBLEUUID &uuid, uint16_t numHandles, NimBLEServer* pServer);
|
||||
friend class NimBLEServer;
|
||||
friend class NimBLEDevice;
|
||||
|
||||
void addCharacteristic(NimBLECharacteristic* pCharacteristic);
|
||||
NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer* pServer);
|
||||
NimBLEService(const NimBLEUUID &uuid, uint16_t numHandles, NimBLEServer* pServer);
|
||||
friend class NimBLEServer;
|
||||
friend class NimBLEDevice;
|
||||
|
||||
NimBLECharacteristicMap m_characteristicMap;
|
||||
uint16_t m_handle;
|
||||
NimBLEServer* m_pServer = nullptr;
|
||||
NimBLEUUID m_uuid;
|
||||
void addCharacteristic(NimBLECharacteristic* pCharacteristic);
|
||||
|
||||
uint16_t m_numHandles;
|
||||
void setHandle(uint16_t handle);
|
||||
NimBLECharacteristicMap m_characteristicMap;
|
||||
uint16_t m_handle;
|
||||
NimBLEServer* m_pServer = nullptr;
|
||||
NimBLEUUID m_uuid;
|
||||
|
||||
uint16_t m_numHandles;
|
||||
void setHandle(uint16_t handle);
|
||||
}; // BLEService
|
||||
|
||||
|
||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
#endif // CONFIG_BT_ENABLED
|
||||
#endif /* MAIN_NIMBLESERVICE_H_ */
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on March 7, 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLEServiceMap.cpp
|
||||
|
@ -14,6 +14,9 @@
|
|||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
|
||||
#include "NimBLEService.h"
|
||||
|
||||
|
||||
|
@ -23,7 +26,7 @@
|
|||
* @return The characteristic.
|
||||
*/
|
||||
NimBLEService* NimBLEServiceMap::getByUUID(const char* uuid) {
|
||||
return getByUUID(NimBLEUUID(uuid));
|
||||
return getByUUID(NimBLEUUID(uuid));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -32,13 +35,13 @@ NimBLEService* NimBLEServiceMap::getByUUID(const char* uuid) {
|
|||
* @return The characteristic.
|
||||
*/
|
||||
NimBLEService* NimBLEServiceMap::getByUUID(const NimBLEUUID &uuid, uint8_t inst_id) {
|
||||
for (auto &myPair : m_uuidMap) {
|
||||
if (myPair.first->getUUID().equals(uuid)) {
|
||||
return myPair.first;
|
||||
}
|
||||
}
|
||||
//return m_uuidMap.at(uuid.toString());
|
||||
return nullptr;
|
||||
for (auto &myPair : m_uuidMap) {
|
||||
if (myPair.first->getUUID().equals(uuid)) {
|
||||
return myPair.first;
|
||||
}
|
||||
}
|
||||
//return m_uuidMap.at(uuid.toString());
|
||||
return nullptr;
|
||||
} // getByUUID
|
||||
|
||||
|
||||
|
@ -49,7 +52,7 @@ NimBLEService* NimBLEServiceMap::getByUUID(const NimBLEUUID &uuid, uint8_t inst_
|
|||
*/
|
||||
/*
|
||||
NimBLEService* NimBLEServiceMap::getByHandle(uint16_t handle) {
|
||||
return m_handleMap.at(handle);
|
||||
return m_handleMap.at(handle);
|
||||
} // getByHandle
|
||||
*/
|
||||
|
||||
|
@ -60,7 +63,7 @@ NimBLEService* NimBLEServiceMap::getByHandle(uint16_t handle) {
|
|||
* @return N/A.
|
||||
*/
|
||||
void NimBLEServiceMap::setByUUID(const NimBLEUUID &uuid, NimBLEService* service) {
|
||||
m_uuidMap.insert(std::pair<NimBLEService*, std::string>(service, uuid.toString()));
|
||||
m_uuidMap.insert(std::pair<NimBLEService*, std::string>(service, uuid.toString()));
|
||||
} // setByUUID
|
||||
|
||||
|
||||
|
@ -72,7 +75,7 @@ void NimBLEServiceMap::setByUUID(const NimBLEUUID &uuid, NimBLEService* service)
|
|||
*/
|
||||
/*
|
||||
void NimBLEServiceMap::setByHandle(uint16_t handle, NimBLEService* service) {
|
||||
m_handleMap.insert(std::pair<uint16_t, NimBLEService*>(handle, service));
|
||||
m_handleMap.insert(std::pair<uint16_t, NimBLEService*>(handle, service));
|
||||
} // setByHandle
|
||||
*/
|
||||
|
||||
|
@ -81,15 +84,15 @@ void NimBLEServiceMap::setByHandle(uint16_t handle, NimBLEService* service) {
|
|||
* @return A string representation of the service map.
|
||||
*/
|
||||
std::string NimBLEServiceMap::toString() {
|
||||
std::string res;
|
||||
//char hex[5];
|
||||
for (auto &myPair: m_uuidMap) {
|
||||
// res += "handle: 0x";
|
||||
// snprintf(hex, sizeof(hex), "%04x", myPair.first);
|
||||
// res += hex;
|
||||
res += ", uuid: " + myPair.second + "\n";
|
||||
}
|
||||
return res;
|
||||
std::string res;
|
||||
//char hex[5];
|
||||
for (auto &myPair: m_uuidMap) {
|
||||
// res += "handle: 0x";
|
||||
// snprintf(hex, sizeof(hex), "%04x", myPair.first);
|
||||
// res += hex;
|
||||
res += ", uuid: " + myPair.second + "\n";
|
||||
}
|
||||
return res;
|
||||
} // toString
|
||||
|
||||
|
||||
|
@ -98,40 +101,45 @@ std::string NimBLEServiceMap::toString() {
|
|||
* @return The first service in the map.
|
||||
*/
|
||||
NimBLEService* NimBLEServiceMap::getFirst() {
|
||||
m_iterator = m_uuidMap.begin();
|
||||
if (m_iterator == m_uuidMap.end()) return nullptr;
|
||||
NimBLEService* pRet = m_iterator->first;
|
||||
m_iterator++;
|
||||
return pRet;
|
||||
m_iterator = m_uuidMap.begin();
|
||||
if (m_iterator == m_uuidMap.end()) return nullptr;
|
||||
NimBLEService* pRet = m_iterator->first;
|
||||
m_iterator++;
|
||||
return pRet;
|
||||
} // getFirst
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get the next service in the map.
|
||||
* @return The next service in the map.
|
||||
*/
|
||||
NimBLEService* NimBLEServiceMap::getNext() {
|
||||
if (m_iterator == m_uuidMap.end()) return nullptr;
|
||||
NimBLEService* pRet = m_iterator->first;
|
||||
m_iterator++;
|
||||
return pRet;
|
||||
if (m_iterator == m_uuidMap.end()) return nullptr;
|
||||
NimBLEService* pRet = m_iterator->first;
|
||||
m_iterator++;
|
||||
return pRet;
|
||||
} // getNext
|
||||
|
||||
|
||||
/**
|
||||
* @brief Removes service from maps.
|
||||
* @return N/A.
|
||||
*/
|
||||
void NimBLEServiceMap::removeService(NimBLEService* service) {
|
||||
//m_handleMap.erase(service->getHandle());
|
||||
m_uuidMap.erase(service);
|
||||
//m_handleMap.erase(service->getHandle());
|
||||
m_uuidMap.erase(service);
|
||||
} // removeService
|
||||
|
||||
|
||||
/**
|
||||
* @brief Returns the amount of registered services
|
||||
* @return amount of registered services
|
||||
*/
|
||||
int NimBLEServiceMap::getRegisteredServiceCount(){
|
||||
//return m_handleMap.size();
|
||||
//return m_handleMap.size();
|
||||
return m_uuidMap.size();
|
||||
}
|
||||
|
||||
|
||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
#endif /* CONFIG_BT_ENABLED */
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on Jan 24 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLEUUID.cpp
|
||||
|
@ -57,11 +57,11 @@ static const char* LOG_TAG = "NimBLEUUID";
|
|||
// If the length of the string is 36 bytes then we will assume it is a long hex string in
|
||||
// UUID format.
|
||||
char * position = const_cast<char *>(value.c_str());
|
||||
uint32_t first = strtoul(position, &position, 16);
|
||||
uint16_t second = strtoul(position + 1, &position, 16);
|
||||
uint16_t third = strtoul(position + 1, &position, 16);
|
||||
uint16_t fourth = strtoul(position + 1, &position, 16);
|
||||
uint64_t fifth = strtoull(position + 1, NULL, 16);
|
||||
uint32_t first = strtoul(position, &position, 16);
|
||||
uint16_t second = strtoul(position + 1, &position, 16);
|
||||
uint16_t third = strtoul(position + 1, &position, 16);
|
||||
uint16_t fourth = strtoul(position + 1, &position, 16);
|
||||
uint64_t fifth = strtoull(position + 1, NULL, 16);
|
||||
*this = NimBLEUUID(first, second, third, (uint64_t(fourth) << 48) + fifth);
|
||||
}
|
||||
else {
|
||||
|
@ -134,8 +134,8 @@ NimBLEUUID::NimBLEUUID(const ble_uuid128_t* uuid) {
|
|||
|
||||
|
||||
/**
|
||||
* @brief Create a UUID from the 128bit value using hex parts instead of string,
|
||||
* instead of BLEUUID("ebe0ccb0-7a0a-4b0c-8a1a-6ff2997da3a6"), it becomes
|
||||
* @brief Create a UUID from the 128bit value using hex parts instead of string,
|
||||
* instead of BLEUUID("ebe0ccb0-7a0a-4b0c-8a1a-6ff2997da3a6"), it becomes
|
||||
* BLEUUID(0xebe0ccb0, 0x7a0a, 0x4b0c, 0x8a1a6ff2997da3a6)
|
||||
*
|
||||
* @param [in] first The first 32bit of the UUID.
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on Jan 25 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
@ -11,42 +11,10 @@
|
|||
|
||||
#include "NimBLEUtils.h"
|
||||
#include "NimBLELog.h"
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_NIMBLE_ENABLED)
|
||||
#include "nimconfig.h"
|
||||
#endif
|
||||
|
||||
static const char* LOG_TAG = "NimBLEUtils";
|
||||
static const char* LOG_TAG = "NimBLEUtils";
|
||||
|
||||
/**
|
||||
* @brief Copy memory from source to target but in reverse order.
|
||||
*
|
||||
* When we move memory from one location it is normally:
|
||||
*
|
||||
* ```
|
||||
* [0][1][2]...[n] -> [0][1][2]...[n]
|
||||
* ```
|
||||
*
|
||||
* with this function, it is:
|
||||
*
|
||||
* ```
|
||||
* [0][1][2]...[n] -> [n][n-1][n-2]...[0]
|
||||
* ```
|
||||
*
|
||||
* @param [in] target The target of the copy
|
||||
* @param [in] source The source of the copy
|
||||
* @param [in] size The number of bytes to copy
|
||||
*/
|
||||
void NimBLEUtils::memrcpy(uint8_t* target, const uint8_t* source, uint32_t size) {
|
||||
assert(size > 0);
|
||||
target += (size - 1); // Point target to the last byte of the target data
|
||||
while (size > 0) {
|
||||
*target = *source;
|
||||
target--;
|
||||
source++;
|
||||
size--;
|
||||
}
|
||||
} // memrcpy
|
||||
|
||||
int NimBLEUtils::checkConnParams(ble_gap_conn_params* params) {
|
||||
/* Check connection interval min */
|
||||
|
@ -82,7 +50,7 @@ int NimBLEUtils::checkConnParams(ble_gap_conn_params* params) {
|
|||
|
||||
|
||||
const char* NimBLEUtils::returnCodeToString(int rc) {
|
||||
#if CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT > 0
|
||||
#if defined(CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT)
|
||||
switch(rc) {
|
||||
case 0:
|
||||
return "SUCCESS";
|
||||
|
@ -363,19 +331,19 @@ const char* NimBLEUtils::returnCodeToString(int rc) {
|
|||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
#else // #if CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT
|
||||
#else // #if defined(CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT)
|
||||
return "";
|
||||
#endif // #if CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT
|
||||
}
|
||||
#endif // #if defined(CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Convert the BLE Advertising Data flags to a string.
|
||||
* @param adFlags The flags to convert
|
||||
* @return std::string A string representation of the advertising flags.
|
||||
*/
|
||||
|
||||
const char* NimBLEUtils::advTypeToString(uint8_t advType) {
|
||||
#if CONFIG_NIMBLE_CPP_ENABLE_ADVERTISMENT_TYPE_TEXT > 0
|
||||
#if defined(CONFIG_NIMBLE_CPP_ENABLE_ADVERTISMENT_TYPE_TEXT)
|
||||
switch(advType) {
|
||||
case BLE_HCI_ADV_TYPE_ADV_IND : //0
|
||||
return "Undirected - Connectable / Scannable";
|
||||
|
@ -390,9 +358,9 @@ const char* NimBLEUtils::advTypeToString(uint8_t advType) {
|
|||
default:
|
||||
return "Unknown flag";
|
||||
}
|
||||
#else // #if CONFIG_NIMBLE_CPP_ENABLE_ADVERTISMENT_TYPE_TEXT
|
||||
#else // #if defined(CONFIG_NIMBLE_CPP_ENABLE_ADVERTISMENT_TYPE_TEXT)
|
||||
return "";
|
||||
#endif // #if CONFIG_NIMBLE_CPP_ENABLE_ADVERTISMENT_TYPE_TEXT
|
||||
#endif // #if defined(CONFIG_NIMBLE_CPP_ENABLE_ADVERTISMENT_TYPE_TEXT)
|
||||
} // adFlagsToString
|
||||
|
||||
|
||||
|
@ -432,85 +400,87 @@ char* NimBLEUtils::buildHexData(uint8_t* target, const uint8_t* source, uint8_t
|
|||
} // buildHexData
|
||||
|
||||
|
||||
|
||||
void NimBLEUtils::dumpGapEvent(ble_gap_event *event, void *arg){
|
||||
#if defined(CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT)
|
||||
NIMBLE_LOGD(LOG_TAG, "Received a GAP event: %s", gapEventToString(event->type));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Convert a BT GAP event type to a string representation.
|
||||
* @param [in] eventType The type of event.
|
||||
* @return A string representation of the event type.
|
||||
*/
|
||||
const char* NimBLEUtils::gapEventToString(uint8_t eventType) {
|
||||
#if CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT > 0
|
||||
#if defined(CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT)
|
||||
switch (eventType) {
|
||||
case BLE_GAP_EVENT_CONNECT : //0
|
||||
return "BLE_GAP_EVENT_CONNECT ";
|
||||
|
||||
|
||||
case BLE_GAP_EVENT_DISCONNECT: //1
|
||||
return "BLE_GAP_EVENT_DISCONNECT";
|
||||
|
||||
|
||||
case BLE_GAP_EVENT_CONN_UPDATE: //3
|
||||
return "BLE_GAP_EVENT_CONN_UPDATE";
|
||||
|
||||
case BLE_GAP_EVENT_CONN_UPDATE_REQ: //4
|
||||
|
||||
case BLE_GAP_EVENT_CONN_UPDATE_REQ: //4
|
||||
return "BLE_GAP_EVENT_CONN_UPDATE_REQ";
|
||||
|
||||
case BLE_GAP_EVENT_L2CAP_UPDATE_REQ: //5
|
||||
|
||||
case BLE_GAP_EVENT_L2CAP_UPDATE_REQ: //5
|
||||
return "BLE_GAP_EVENT_L2CAP_UPDATE_REQ";
|
||||
|
||||
|
||||
case BLE_GAP_EVENT_TERM_FAILURE: //6
|
||||
return "BLE_GAP_EVENT_TERM_FAILURE";
|
||||
|
||||
|
||||
case BLE_GAP_EVENT_DISC: //7
|
||||
return "BLE_GAP_EVENT_DISC";
|
||||
|
||||
case BLE_GAP_EVENT_DISC_COMPLETE: //8
|
||||
|
||||
case BLE_GAP_EVENT_DISC_COMPLETE: //8
|
||||
return "BLE_GAP_EVENT_DISC_COMPLETE";
|
||||
|
||||
case BLE_GAP_EVENT_ADV_COMPLETE: //9
|
||||
|
||||
case BLE_GAP_EVENT_ADV_COMPLETE: //9
|
||||
return "BLE_GAP_EVENT_ADV_COMPLETE";
|
||||
|
||||
case BLE_GAP_EVENT_ENC_CHANGE: //10
|
||||
|
||||
case BLE_GAP_EVENT_ENC_CHANGE: //10
|
||||
return "BLE_GAP_EVENT_ENC_CHANGE";
|
||||
|
||||
|
||||
case BLE_GAP_EVENT_PASSKEY_ACTION : //11
|
||||
return "BLE_GAP_EVENT_PASSKEY_ACTION";
|
||||
|
||||
|
||||
case BLE_GAP_EVENT_NOTIFY_RX: //12
|
||||
return "BLE_GAP_EVENT_NOTIFY_RX";
|
||||
|
||||
|
||||
case BLE_GAP_EVENT_NOTIFY_TX : //13
|
||||
return "BLE_GAP_EVENT_NOTIFY_TX";
|
||||
|
||||
|
||||
case BLE_GAP_EVENT_SUBSCRIBE : //14
|
||||
return "BLE_GAP_EVENT_SUBSCRIBE";
|
||||
|
||||
|
||||
case BLE_GAP_EVENT_MTU: //15
|
||||
return "BLE_GAP_EVENT_MTU";
|
||||
|
||||
|
||||
case BLE_GAP_EVENT_IDENTITY_RESOLVED: //16
|
||||
return "BLE_GAP_EVENT_IDENTITY_RESOLVED";
|
||||
|
||||
|
||||
case BLE_GAP_EVENT_REPEAT_PAIRING: //17
|
||||
return "BLE_GAP_EVENT_REPEAT_PAIRING";
|
||||
|
||||
|
||||
case BLE_GAP_EVENT_PHY_UPDATE_COMPLETE: //18
|
||||
return "BLE_GAP_EVENT_PHY_UPDATE_COMPLETE";
|
||||
|
||||
|
||||
case BLE_GAP_EVENT_EXT_DISC: //19
|
||||
return "BLE_GAP_EVENT_EXT_DISC";
|
||||
#ifdef BLE_GAP_EVENT_PERIODIC_SYNC // IDF 4.0 does not support these
|
||||
case BLE_GAP_EVENT_PERIODIC_SYNC: //20
|
||||
return "BLE_GAP_EVENT_PERIODIC_SYNC";
|
||||
|
||||
|
||||
case BLE_GAP_EVENT_PERIODIC_REPORT: //21
|
||||
return "BLE_GAP_EVENT_PERIODIC_REPORT";
|
||||
|
||||
|
||||
case BLE_GAP_EVENT_PERIODIC_SYNC_LOST: //22
|
||||
return "BLE_GAP_EVENT_PERIODIC_SYNC_LOST";
|
||||
|
||||
|
||||
case BLE_GAP_EVENT_SCAN_REQ_RCVD: //23
|
||||
return "BLE_GAP_EVENT_SCAN_REQ_RCVD";
|
||||
#endif
|
||||
|
@ -518,9 +488,9 @@ const char* NimBLEUtils::gapEventToString(uint8_t eventType) {
|
|||
NIMBLE_LOGD(LOG_TAG, "gapEventToString: Unknown event type %d 0x%.2x", eventType, eventType);
|
||||
return "Unknown event type";
|
||||
}
|
||||
#else // #if CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT
|
||||
#else // #if defined(CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT)
|
||||
return "";
|
||||
#endif // #if CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT
|
||||
#endif // #if defined(CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT)
|
||||
} // gapEventToString
|
||||
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on Jan 25 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef COMPONENTS_NIMBLEUTILS_H_
|
||||
|
@ -28,7 +28,6 @@ public:
|
|||
static char* buildHexData(uint8_t* target, const uint8_t* source, uint8_t length);
|
||||
static const char* advTypeToString(uint8_t advType);
|
||||
static const char* returnCodeToString(int rc);
|
||||
static void memrcpy(uint8_t* target, const uint8_t* source, uint32_t size);
|
||||
static int checkConnParams(ble_gap_conn_params* params);
|
||||
};
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Created: on March 6, 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
* BLEValue.cpp
|
||||
|
@ -14,15 +14,18 @@
|
|||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
|
||||
#include "NimBLEValue.h"
|
||||
#include "NimBLELog.h"
|
||||
|
||||
static const char* LOG_TAG="NimBLEValue";
|
||||
|
||||
NimBLEValue::NimBLEValue() {
|
||||
m_accumulation = "";
|
||||
m_value = "";
|
||||
m_readOffset = 0;
|
||||
m_accumulation = "";
|
||||
m_value = "";
|
||||
m_readOffset = 0;
|
||||
} // NimBLEValue
|
||||
|
||||
|
||||
|
@ -32,8 +35,8 @@ NimBLEValue::NimBLEValue() {
|
|||
* @param [in] part A message part being added.
|
||||
*/
|
||||
void NimBLEValue::addPart(const std::string &part) {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> addPart: length=%d", part.length());
|
||||
m_accumulation += part;
|
||||
NIMBLE_LOGD(LOG_TAG, ">> addPart: length=%d", part.length());
|
||||
m_accumulation += part;
|
||||
} // addPart
|
||||
|
||||
|
||||
|
@ -44,8 +47,8 @@ void NimBLEValue::addPart(const std::string &part) {
|
|||
* @param [in] length The number of bytes being added.
|
||||
*/
|
||||
void NimBLEValue::addPart(const uint8_t* pData, size_t length) {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> addPart: length=%d", length);
|
||||
m_accumulation += std::string((char*) pData, length);
|
||||
NIMBLE_LOGD(LOG_TAG, ">> addPart: length=%d", length);
|
||||
m_accumulation += std::string((char*) pData, length);
|
||||
} // addPart
|
||||
|
||||
|
||||
|
@ -53,9 +56,9 @@ void NimBLEValue::addPart(const uint8_t* pData, size_t length) {
|
|||
* @brief Cancel the current accumulation.
|
||||
*/
|
||||
void NimBLEValue::cancel() {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> cancel");
|
||||
m_accumulation = "";
|
||||
m_readOffset = 0;
|
||||
NIMBLE_LOGD(LOG_TAG, ">> cancel");
|
||||
m_accumulation = "";
|
||||
m_readOffset = 0;
|
||||
} // cancel
|
||||
|
||||
|
||||
|
@ -66,12 +69,12 @@ void NimBLEValue::cancel() {
|
|||
* we now have the complete message and commit the change as a unit.
|
||||
*/
|
||||
void NimBLEValue::commit() {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> commit");
|
||||
// If there is nothing to commit, do nothing.
|
||||
if (m_accumulation.length() == 0) return;
|
||||
setValue(m_accumulation);
|
||||
m_accumulation = "";
|
||||
m_readOffset = 0;
|
||||
NIMBLE_LOGD(LOG_TAG, ">> commit");
|
||||
// If there is nothing to commit, do nothing.
|
||||
if (m_accumulation.length() == 0) return;
|
||||
setValue(m_accumulation);
|
||||
m_accumulation = "";
|
||||
m_readOffset = 0;
|
||||
} // commit
|
||||
|
||||
|
||||
|
@ -80,7 +83,7 @@ void NimBLEValue::commit() {
|
|||
* @return A pointer to the data.
|
||||
*/
|
||||
uint8_t* NimBLEValue::getData() {
|
||||
return (uint8_t*) m_value.data();
|
||||
return (uint8_t*) m_value.data();
|
||||
}
|
||||
|
||||
|
||||
|
@ -89,7 +92,7 @@ uint8_t* NimBLEValue::getData() {
|
|||
* @return The length of the data in bytes.
|
||||
*/
|
||||
size_t NimBLEValue::getLength() {
|
||||
return m_value.length();
|
||||
return m_value.length();
|
||||
} // getLength
|
||||
|
||||
|
||||
|
@ -98,7 +101,7 @@ size_t NimBLEValue::getLength() {
|
|||
* @return The read offset into the read.
|
||||
*/
|
||||
uint16_t NimBLEValue::getReadOffset() {
|
||||
return m_readOffset;
|
||||
return m_readOffset;
|
||||
} // getReadOffset
|
||||
|
||||
|
||||
|
@ -106,7 +109,7 @@ uint16_t NimBLEValue::getReadOffset() {
|
|||
* @brief Get the current value.
|
||||
*/
|
||||
std::string NimBLEValue::getValue() {
|
||||
return m_value;
|
||||
return m_value;
|
||||
} // getValue
|
||||
|
||||
|
||||
|
@ -115,7 +118,7 @@ std::string NimBLEValue::getValue() {
|
|||
* @param [in] readOffset The offset into the read.
|
||||
*/
|
||||
void NimBLEValue::setReadOffset(uint16_t readOffset) {
|
||||
m_readOffset = readOffset;
|
||||
m_readOffset = readOffset;
|
||||
} // setReadOffset
|
||||
|
||||
|
||||
|
@ -123,7 +126,7 @@ void NimBLEValue::setReadOffset(uint16_t readOffset) {
|
|||
* @brief Set the current value.
|
||||
*/
|
||||
void NimBLEValue::setValue(const std::string &value) {
|
||||
m_value = value;
|
||||
m_value = value;
|
||||
} // setValue
|
||||
|
||||
|
||||
|
@ -133,8 +136,8 @@ void NimBLEValue::setValue(const std::string &value) {
|
|||
* @param [in] The length of the new current value.
|
||||
*/
|
||||
void NimBLEValue::setValue(const uint8_t* pData, size_t length) {
|
||||
m_value = std::string((char*) pData, length);
|
||||
m_value = std::string((char*) pData, length);
|
||||
} // setValue
|
||||
|
||||
|
||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
#endif // CONFIG_BT_ENABLED
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
*
|
||||
* Created: on March 6, 2020
|
||||
* Author H2zero
|
||||
*
|
||||
*
|
||||
* Originally:
|
||||
*
|
||||
*
|
||||
* BLEValue.h
|
||||
*
|
||||
* Created on: Jul 17, 2017
|
||||
|
@ -16,6 +16,10 @@
|
|||
#define MAIN_BLEVALUE_H_
|
||||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
|
@ -23,24 +27,26 @@
|
|||
*/
|
||||
class NimBLEValue {
|
||||
public:
|
||||
NimBLEValue();
|
||||
void addPart(const std::string &part);
|
||||
void addPart(const uint8_t* pData, size_t length);
|
||||
void cancel();
|
||||
void commit();
|
||||
uint8_t* getData();
|
||||
size_t getLength();
|
||||
uint16_t getReadOffset();
|
||||
std::string getValue();
|
||||
void setReadOffset(uint16_t readOffset);
|
||||
void setValue(const std::string &value);
|
||||
void setValue(const uint8_t* pData, size_t length);
|
||||
NimBLEValue();
|
||||
void addPart(const std::string &part);
|
||||
void addPart(const uint8_t* pData, size_t length);
|
||||
void cancel();
|
||||
void commit();
|
||||
uint8_t* getData();
|
||||
size_t getLength();
|
||||
uint16_t getReadOffset();
|
||||
std::string getValue();
|
||||
void setReadOffset(uint16_t readOffset);
|
||||
void setValue(const std::string &value);
|
||||
void setValue(const uint8_t* pData, size_t length);
|
||||
|
||||
private:
|
||||
std::string m_accumulation;
|
||||
uint16_t m_readOffset;
|
||||
std::string m_value;
|
||||
std::string m_accumulation;
|
||||
uint16_t m_readOffset;
|
||||
std::string m_value;
|
||||
|
||||
};
|
||||
|
||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||
#endif // CONFIG_BT_ENABLED
|
||||
#endif /* MAIN_BLEVALUE_H_ */
|
||||
|
|
132
src/nimconfig.h
Normal file
132
src/nimconfig.h
Normal file
|
@ -0,0 +1,132 @@
|
|||
#pragma once
|
||||
|
||||
#include "sdkconfig.h"
|
||||
/** For ESP-IDF compatibility
|
||||
*
|
||||
* Some versions of ESP-IDF used the config name format "CONFIG_NIMBLE_".
|
||||
* This converts them to "CONFIG_BT_NIMBLE_" format used in the latest IDF.
|
||||
*/
|
||||
/* Detect if using ESP-IDF or Arduino (Arduino won't have these defines in sdkconfig)*/
|
||||
#if defined(CONFIG_BT_NIMBLE_TASK_STACK_SIZE) || defined(CONFIG_NIMBLE_TASK_STACK_SIZE)
|
||||
|
||||
#if defined(CONFIG_NIMBLE_ENABLED)
|
||||
#define CONFIG_BT_NIMBLE_ENABLED
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_NIMBLE_ROLE_OBSERVER)
|
||||
#define CONFIG_BT_NIMBLE_ROLE_OBSERVER
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_NIMBLE_ROLE_BROADCASTER)
|
||||
#define CONFIG_BT_NIMBLE_ROLE_BROADCASTER
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_NIMBLE_ROLE_CENTRAL)
|
||||
#define CONFIG_BT_NIMBLE_ROLE_CENTRAL
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_NIMBLE_ROLE_PERIPHERAL)
|
||||
#define CONFIG_BT_NIMBLE_ROLE_PERIPHERAL
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_NIMBLE_DEBUG)
|
||||
#define CONFIG_BT_NIMBLE_DEBUG
|
||||
#endif
|
||||
|
||||
#else // Using Arduino
|
||||
|
||||
/***********************************************
|
||||
* Arduino config options
|
||||
**********************************************/
|
||||
|
||||
/** Comment out if not using NimBLE Client functions
|
||||
* Reduces flash size by approx. 7kB.
|
||||
*/
|
||||
#define CONFIG_BT_NIMBLE_ROLE_CENTRAL
|
||||
|
||||
/** Comment out if not using NimBLE Scan functions
|
||||
* Reduces flash size by approx. 26kB.
|
||||
*/
|
||||
#define CONFIG_BT_NIMBLE_ROLE_OBSERVER
|
||||
|
||||
/** Comment out if not using NimBLE Server functions
|
||||
* Reduces flash size by approx. 16kB.
|
||||
*/
|
||||
#define CONFIG_BT_NIMBLE_ROLE_PERIPHERAL
|
||||
|
||||
/** Comment out if not using NimBLE Advertising functions
|
||||
* Reduces flash size by approx. 5kB.
|
||||
*/
|
||||
#define CONFIG_BT_NIMBLE_ROLE_BROADCASTER
|
||||
|
||||
/** Uncomment to see debug log messages from the NimBLE host
|
||||
* Uses approx. 32kB of flash memory.
|
||||
*/
|
||||
// #define CONFIG_BT_NIMBLE_DEBUG
|
||||
|
||||
/** Uncomment to see NimBLE host return codes as text debug log messages.
|
||||
* Uses approx. 7kB of flash memory.
|
||||
*/
|
||||
// #define CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT
|
||||
|
||||
/** Uncomment to see GAP event codes as text in debug log messages.
|
||||
* Uses approx. 1kB of flash memory.
|
||||
*/
|
||||
// #define CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT
|
||||
|
||||
/** Uncomment to see advertisment types as text while scanning in debug log messages.
|
||||
* Uses approx. 250 bytes of flash memory.
|
||||
*/
|
||||
// #define CONFIG_NIMBLE_CPP_ENABLE_ADVERTISMENT_TYPE_TEXT
|
||||
|
||||
/** Sets the core NimBLE host runs on */
|
||||
#define CONFIG_BT_NIMBLE_PINNED_TO_CORE 0
|
||||
|
||||
/** Sets the stack size for the NimBLE host task */
|
||||
#define CONFIG_BT_NIMBLE_TASK_STACK_SIZE 4096
|
||||
|
||||
/** Sets the number of simultaneous connections (esp controller max is 9) */
|
||||
#define CONFIG_BT_NIMBLE_MAX_CONNECTIONS 3
|
||||
|
||||
/** Sets the number of devices allowed to store/bond with */
|
||||
#define CONFIG_BT_NIMBLE_MAX_BONDS 3
|
||||
|
||||
/** Sets the number of CCCD's to store per bonded device */
|
||||
#define CONFIG_BT_NIMBLE_MAX_CCCDS 8
|
||||
|
||||
#define CONFIG_BT_NIMBLE_NVS_PERSIST 1
|
||||
#define CONFIG_BT_NIMBLE_SM_LEGACY 1
|
||||
#define CONFIG_BT_NIMBLE_SM_SC 1
|
||||
#define CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME "nimble"
|
||||
#define CONFIG_BT_NIMBLE_GAP_DEVICE_NAME_MAX_LEN 31
|
||||
#define CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU 256
|
||||
#define CONFIG_BT_NIMBLE_SVC_GAP_APPEARANCE 0x0
|
||||
#define CONFIG_BT_NIMBLE_ACL_BUF_COUNT 12
|
||||
#define CONFIG_BT_NIMBLE_ACL_BUF_SIZE 255
|
||||
#define CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE 70
|
||||
#define CONFIG_BT_NIMBLE_HCI_EVT_HI_BUF_COUNT 30
|
||||
#define CONFIG_BT_NIMBLE_HCI_EVT_LO_BUF_COUNT 8
|
||||
#define CONFIG_BT_NIMBLE_MSYS1_BLOCK_COUNT 12
|
||||
#define CONFIG_BT_NIMBLE_HS_FLOW_CTRL 1
|
||||
#define CONFIG_BT_NIMBLE_HS_FLOW_CTRL_ITVL 1000
|
||||
#define CONFIG_BT_NIMBLE_HS_FLOW_CTRL_THRESH 2
|
||||
#define CONFIG_BT_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT 1
|
||||
#define CONFIG_BT_NIMBLE_RPA_TIMEOUT 900
|
||||
#define CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM 0
|
||||
|
||||
/** Do not comment out */
|
||||
#define CONFIG_BT_ENABLED
|
||||
#define CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY
|
||||
#define CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL
|
||||
|
||||
#endif // #if defined(CONFIG_BT_NIMBLE_TASK_STACK_SIZE) || defined(CONFIG_NIMBLE_TASK_STACK_SIZE)
|
||||
|
||||
/** Cannot use client without scan */
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) && !defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
||||
#define CONFIG_BT_NIMBLE_ROLE_OBSERVER
|
||||
#endif
|
||||
|
||||
/** Cannot use server without advertise */
|
||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) && !defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
|
||||
#define CONFIG_BT_NIMBLE_ROLE_BROADCASTER
|
||||
#endif
|
Loading…
Reference in a new issue