From 3b71bb070e786d425b3c5a732660bf2892140cc5 Mon Sep 17 00:00:00 2001 From: lianggao Date: Mon, 13 Feb 2017 09:18:48 +0800 Subject: [PATCH 1/4] Jira 832 Sample Sketch to exercise the BLEbroadcast option. 1. Add example sketch libraries/CurieBLE/examples/peripheral/broadcast --- .../peripheral/broadcast/broadcast.ino | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 libraries/CurieBLE/examples/peripheral/broadcast/broadcast.ino diff --git a/libraries/CurieBLE/examples/peripheral/broadcast/broadcast.ino b/libraries/CurieBLE/examples/peripheral/broadcast/broadcast.ino new file mode 100644 index 00000000..6aa23370 --- /dev/null +++ b/libraries/CurieBLE/examples/peripheral/broadcast/broadcast.ino @@ -0,0 +1,31 @@ +#include + +uint8_t value = 0; + +BLEPeripheral peripheral; +BLEService service = BLEService("EEE0"); +BLEShortCharacteristic characteristic = BLEShortCharacteristic("EEE1", BLERead | BLENotify | BLEBroadcast); + +void setup() { + Serial.begin(9600); + + peripheral.setLocalName("BLEBroadcast"); + peripheral.setAdvertisedServiceUuid(service.uuid()); + + peripheral.addAttribute(service); + peripheral.addAttribute(characteristic); + + characteristic.setValue(value); + + peripheral.begin(); + characteristic.broadcast(); + + Serial.println(F("BLE Broadcast Count")); +} + +void loop() { + peripheral.poll(); + characteristic.setValue(value); + delay(1000); + value++; +} From 11108f7a37e140259f4ebf39122ed68195c5bef1 Mon Sep 17 00:00:00 2001 From: lianggao Date: Wed, 15 Feb 2017 15:26:45 +0800 Subject: [PATCH 2/4] Jira793 Central returned incorrect Characteristic value for some Service Git#384 1. The root cause is Nordic stack can't return long UUID when discover - Change the discover process. - Add read operation after discover returned invalid UUID. --- .../CurieBLE/src/internal/BLECallbacks.cpp | 17 ++ .../CurieBLE/src/internal/BLECallbacks.h | 5 + .../src/internal/BLEProfileManager.cpp | 34 +++ .../CurieBLE/src/internal/BLEProfileManager.h | 1 + .../CurieBLE/src/internal/BLEServiceImp.cpp | 200 ++++++++++++++---- .../CurieBLE/src/internal/BLEServiceImp.h | 16 ++ 6 files changed, 234 insertions(+), 39 deletions(-) diff --git a/libraries/CurieBLE/src/internal/BLECallbacks.cpp b/libraries/CurieBLE/src/internal/BLECallbacks.cpp index 568c54f8..37eae4f0 100644 --- a/libraries/CurieBLE/src/internal/BLECallbacks.cpp +++ b/libraries/CurieBLE/src/internal/BLECallbacks.cpp @@ -172,6 +172,23 @@ uint8_t profile_service_read_rsp_process(bt_conn_t *conn, return ret; } +uint8_t profile_characteristic_read_rsp_process(bt_conn_t *conn, + int err, + bt_gatt_read_params_t *params, + const void *data, + uint16_t length) +{ + BLEDevice bleDevice(bt_conn_get_dst(conn)); + BLEServiceImp* service_imp = BLEProfileManager::instance()->getServiceBySubHandle(bleDevice, params->single.handle); + + uint8_t ret = service_imp->characteristicReadRspProc(conn, + err, + params, + data, + length); + pr_debug(LOG_MODULE_BLE, "%s-%d:ret-%d", __FUNCTION__, __LINE__, ret); + return ret; +} void bleConnectEventHandler(bt_conn_t *conn, diff --git a/libraries/CurieBLE/src/internal/BLECallbacks.h b/libraries/CurieBLE/src/internal/BLECallbacks.h index 213bd794..7eefaaa6 100644 --- a/libraries/CurieBLE/src/internal/BLECallbacks.h +++ b/libraries/CurieBLE/src/internal/BLECallbacks.h @@ -76,6 +76,11 @@ uint8_t profile_service_read_rsp_process(bt_conn_t *conn, void ble_on_write_no_rsp_complete(struct bt_conn *conn, uint8_t err, const void *data); +uint8_t profile_characteristic_read_rsp_process(bt_conn_t *conn, + int err, + bt_gatt_read_params_t *params, + const void *data, + uint16_t length); #endif diff --git a/libraries/CurieBLE/src/internal/BLEProfileManager.cpp b/libraries/CurieBLE/src/internal/BLEProfileManager.cpp index df34c996..f10bb5b2 100644 --- a/libraries/CurieBLE/src/internal/BLEProfileManager.cpp +++ b/libraries/CurieBLE/src/internal/BLEProfileManager.cpp @@ -507,6 +507,40 @@ BLEServiceImp* BLEProfileManager::service(const BLEDevice &bledevice, int index) return serviceImp; } +BLEServiceImp* BLEProfileManager::getServiceBySubHandle(const BLEDevice &bledevice, uint16_t handle) const +{ + BLEServiceImp* serviceImp = NULL; + uint16_t start_handle; + uint16_t end_handle; + #if 1 + const BLEServiceLinkNodeHeader* serviceHeader = getServiceHeader(bledevice); + if (NULL == serviceHeader) + { + // Doesn't find the service + return NULL; + } + BLEServiceNodePtr node = serviceHeader->next; + + while (node != NULL) + { + serviceImp = node->value; + start_handle = serviceImp->startHandle(); + end_handle = serviceImp->endHandle(); + if (handle >= start_handle && handle <= end_handle) + { + break; + } + node = node->next; + } + + if (NULL == node) + { + serviceImp = NULL; + } + #endif + return serviceImp; +} + void BLEProfileManager::handleConnectedEvent(const bt_addr_le_t* deviceAddr) { int index = getUnusedIndex(); diff --git a/libraries/CurieBLE/src/internal/BLEProfileManager.h b/libraries/CurieBLE/src/internal/BLEProfileManager.h index 02c42c9c..a83ba431 100644 --- a/libraries/CurieBLE/src/internal/BLEProfileManager.h +++ b/libraries/CurieBLE/src/internal/BLEProfileManager.h @@ -98,6 +98,7 @@ class BLEProfileManager{ BLEServiceImp* service(const BLEDevice &bledevice, const char * uuid) const; BLEServiceImp* service(const BLEDevice &bledevice, int index) const; BLEServiceImp* service(const BLEDevice &bledevice, const bt_uuid_t* uuid) const; + BLEServiceImp* getServiceBySubHandle(const BLEDevice &bledevice, uint16_t handle) const; int serviceCount(const BLEDevice &bledevice) const; int characteristicCount(const BLEDevice &bledevice) const; diff --git a/libraries/CurieBLE/src/internal/BLEServiceImp.cpp b/libraries/CurieBLE/src/internal/BLEServiceImp.cpp index 4f4d3dc1..ba479b90 100644 --- a/libraries/CurieBLE/src/internal/BLEServiceImp.cpp +++ b/libraries/CurieBLE/src/internal/BLEServiceImp.cpp @@ -26,6 +26,7 @@ #include "BLECharacteristicImp.h" bt_uuid_16_t BLEServiceImp::_gatt_primary_uuid = {BT_UUID_TYPE_16, BT_UUID_GATT_PRIMARY_VAL}; +bt_gatt_read_params_t BLEServiceImp::_read_params; bt_uuid_t *BLEServiceImp::getPrimayUuid(void) { @@ -36,6 +37,7 @@ BLEServiceImp::BLEServiceImp(BLEService& service): BLEAttribute(service.uuid(), BLETypeService), _start_handle(0), _end_handle(0xFFFF), + _reading(false), _cur_discover_chrc(NULL) { memset(&_characteristics_header, 0, sizeof(_characteristics_header)); @@ -46,6 +48,7 @@ BLEServiceImp::BLEServiceImp(const bt_uuid_t* uuid): BLEAttribute(uuid, BLETypeService), _start_handle(0), _end_handle(0xFFFF), + _reading(false), _cur_discover_chrc(NULL) { memset(&_characteristics_header, 0, sizeof(_characteristics_header)); @@ -242,10 +245,17 @@ BLECharacteristicImp* BLEServiceImp::characteristic(const char* uuid) bool BLEServiceImp::discovering() { - return (_cur_discover_chrc != NULL); + return (_cur_discover_chrc != NULL || _reading); } bool BLEServiceImp::discoverAttributes(BLEDevice* device) +{ + return discoverAttributes(device, _start_handle, _end_handle); +} + +bool BLEServiceImp::discoverAttributes(BLEDevice* device, + uint16_t start_handle, + uint16_t end_handle) { pr_debug(LOG_MODULE_BLE, "%s-%d", __FUNCTION__, __LINE__); int err; @@ -273,8 +283,8 @@ bool BLEServiceImp::discoverAttributes(BLEDevice* device) return false; } temp = &_discover_params; - temp->start_handle = _start_handle; - temp->end_handle = _end_handle; + temp->start_handle = start_handle; + temp->end_handle = end_handle; temp->uuid = NULL; temp->type = BT_GATT_DISCOVER_CHARACTERISTIC; temp->func = profile_discover_process; @@ -309,21 +319,34 @@ uint8_t BLEServiceImp::discoverResponseProc(bt_conn_t *conn, //const bt_uuid_t* chrc_uuid = attr->uuid; uint16_t chrc_handle = attr->handle + 1; struct bt_gatt_chrc* psttemp = (struct bt_gatt_chrc*)attr->user_data; - int retval = (int)addCharacteristic(device, - psttemp->uuid, - chrc_handle, - psttemp->properties); + const bt_uuid_t* chrc_uuid = psttemp->uuid; - //pr_debug(LOG_MODULE_BLE, "%s-%d:handle-%d:%d", __FUNCTION__, __LINE__,attr->handle, chrc_handle); - if (BLE_STATUS_SUCCESS != retval) + uint16_t le16; + memcpy(&le16, &BT_UUID_16(chrc_uuid)->val, sizeof(le16)); + if (chrc_uuid->type == BT_UUID_TYPE_16 && + le16 == 0) { - pr_error(LOG_MODULE_BLE, "%s-%d: Error-%d", - __FUNCTION__, __LINE__, retval); - errno = ENOMEM; + // Read the UUID + readCharacteristic(device, chrc_handle); + retVal = BT_GATT_ITER_CONTINUE; } else { - retVal = BT_GATT_ITER_CONTINUE; + int retval = (int)addCharacteristic(device, + psttemp->uuid, + chrc_handle, + psttemp->properties); + + if (BLE_STATUS_SUCCESS != retval) + { + pr_error(LOG_MODULE_BLE, "%s-%d: Error-%d", + __FUNCTION__, __LINE__, retval); + errno = ENOMEM; + } + else + { + retVal = BT_GATT_ITER_CONTINUE; + } } } break; @@ -335,8 +358,8 @@ uint8_t BLEServiceImp::discoverResponseProc(bt_conn_t *conn, if (NULL != _cur_discover_chrc) { retVal = _cur_discover_chrc->discoverResponseProc(conn, - attr, - params); + attr, + params); } break; } @@ -347,7 +370,7 @@ uint8_t BLEServiceImp::discoverResponseProc(bt_conn_t *conn, } } - pr_debug(LOG_MODULE_BLE, "%s-%d:ret-%d",__FUNCTION__, __LINE__, retVal); + //pr_debug(LOG_MODULE_BLE, "%s-%d:ret-%d",__FUNCTION__, __LINE__, retVal); if (retVal == BT_GATT_ITER_STOP) { if (errno == ENOMEM) @@ -355,36 +378,135 @@ uint8_t BLEServiceImp::discoverResponseProc(bt_conn_t *conn, _cur_discover_chrc = NULL; return retVal; } - const BLECharacteristicLinkNodeHeader* chrcHeader = &_characteristics_header; - BLECharacteristicImp* chrcCurImp = NULL; - BLECharacteristicNodePtr node = chrcHeader->next; - pr_debug(LOG_MODULE_BLE, "%s-%d: node-%p",__FUNCTION__, __LINE__, node); - // Discover next service - while (node != NULL) + if (false == _reading) { - chrcCurImp = node->value; - - if (NULL == _cur_discover_chrc) + discoverNextCharacteristic(device); + } + } + return retVal; +} + +void BLEServiceImp::discoverNextCharacteristic(BLEDevice &bledevice) +{ + const BLECharacteristicLinkNodeHeader* chrcHeader = &_characteristics_header; + BLECharacteristicImp* chrcCurImp = NULL; + BLECharacteristicNodePtr node = chrcHeader->next; + + //pr_debug(LOG_MODULE_BLE, "%s-%d: node-%p",__FUNCTION__, __LINE__, node); + // Discover next service + while (node != NULL) + { + chrcCurImp = node->value; + + if (NULL == _cur_discover_chrc) + { + bool result = chrcCurImp->discoverAttributes(&bledevice); + pr_debug(LOG_MODULE_BLE, "%s-%d",__FUNCTION__, __LINE__); + if (result == true) { - bool result = chrcCurImp->discoverAttributes(&device); - pr_debug(LOG_MODULE_BLE, "%s-%d",__FUNCTION__, __LINE__); - if (result == true) - { - // Record the current discovering service - _cur_discover_chrc = chrcCurImp; - break; - } + // Record the current discovering service + _cur_discover_chrc = chrcCurImp; + break; } - else if (_cur_discover_chrc == chrcCurImp) + } + else if (_cur_discover_chrc == chrcCurImp) + { + // Find next discoverable service + _cur_discover_chrc = NULL; + } + node = node->next; + } +} + +bool BLEServiceImp::readCharacteristic(const BLEDevice &bledevice, uint16_t handle) +{ + int retval = 0; + bt_conn_t* conn = NULL; + + if (true == BLEUtils::isLocalBLE(bledevice)) + { + // GATT server can't write + return false; + } + + if (_reading) + { + return false; + } + + _read_params.func = profile_characteristic_read_rsp_process; + _read_params.handle_count = 1; + _read_params.single.handle = handle - 1; + _read_params.single.offset = 0; + + if (0 == _read_params.single.handle) + { + // Discover not complete + return false; + } + + conn = bt_conn_lookup_addr_le(bledevice.bt_le_address()); + if (NULL == conn) + { + return false; + } + // Send read request + retval = bt_gatt_read(conn, &_read_params); + bt_conn_unref(conn); + if (0 == retval) + { + _reading = true; + } + pr_debug(LOG_MODULE_BLE, "%s-%d", __FUNCTION__, __LINE__); + return _reading; +} + +uint8_t BLEServiceImp::characteristicReadRspProc(bt_conn_t *conn, + int err, + bt_gatt_read_params_t *params, + const void *data, + uint16_t length) +{ + _reading = false; + if (NULL == data) + { + return BT_GATT_ITER_STOP; + } + BLEDevice bleDevice(bt_conn_get_dst(conn)); + + pr_debug(LOG_MODULE_BLE, "%s-%d:length-%d", __FUNCTION__, __LINE__, length); + if (length == UUID_SIZE_128 + 3) + { + const uint8_t* rspdata = (const uint8_t*) data; + bt_uuid_128_t uuid_tmp; + uint16_t chrc_handle = rspdata[1] | (rspdata[2] << 8); + uuid_tmp.uuid.type = BT_UUID_TYPE_128; + memcpy(uuid_tmp.val, &rspdata[3], UUID_SIZE_128); + int retval = (int)addCharacteristic(bleDevice, + (const bt_uuid_t*)&uuid_tmp, + chrc_handle, + rspdata[0]); + + if (BLE_STATUS_SUCCESS != retval) + { + pr_error(LOG_MODULE_BLE, "%s-%d: Error-%d", + __FUNCTION__, __LINE__, retval); + errno = ENOMEM; + } + else + { + if (false == discovering()) { - // Find next discoverable service - _cur_discover_chrc = NULL; + if (false == discoverAttributes(&bleDevice, chrc_handle + 1, _end_handle)) + { + discoverNextCharacteristic(bleDevice); + } } - node = node->next; } } - return retVal; + pr_debug(LOG_MODULE_BLE, "%s-%d", __FUNCTION__, __LINE__); + + return BT_GATT_ITER_STOP; } - diff --git a/libraries/CurieBLE/src/internal/BLEServiceImp.h b/libraries/CurieBLE/src/internal/BLEServiceImp.h index d6c63389..a2ef1571 100644 --- a/libraries/CurieBLE/src/internal/BLEServiceImp.h +++ b/libraries/CurieBLE/src/internal/BLEServiceImp.h @@ -71,6 +71,12 @@ class BLEServiceImp: public BLEAttribute{ uint8_t discoverResponseProc(bt_conn_t *conn, const bt_gatt_attr_t *attr, bt_gatt_discover_params_t *params); + + uint8_t characteristicReadRspProc(bt_conn_t *conn, + int err, + bt_gatt_read_params_t *params, + const void *data, + uint16_t length); bool discovering(); static bt_uuid_t *getPrimayUuid(void); @@ -81,6 +87,13 @@ class BLEServiceImp: public BLEAttribute{ int updateProfile(bt_gatt_attr_t *attr_start, int& index); + +private: + void discoverNextCharacteristic(BLEDevice &bledevice); + bool readCharacteristic(const BLEDevice &bledevice, uint16_t handle); + bool discoverAttributes(BLEDevice* device, + uint16_t start_handle, + uint16_t end_handle); private: typedef LinkNode BLECharacteristicLinkNodeHeader; typedef LinkNode* BLECharacteristicNodePtr; @@ -89,6 +102,9 @@ class BLEServiceImp: public BLEAttribute{ uint16_t _start_handle; uint16_t _end_handle; + static bt_gatt_read_params_t _read_params; + bool _reading; + void releaseCharacteristic(); BLECharacteristicImp *_cur_discover_chrc; From 3563ce45db9855b805120ddac5c4dff0db879294 Mon Sep 17 00:00:00 2001 From: lianggao Date: Mon, 20 Feb 2017 09:37:36 +0800 Subject: [PATCH 3/4] Fix #445 Deprecated BLEConnected and BLEDisconnected events not triggered 1. Root casue: The callback regiter before the begin and the begin reset the callback. 2. Solution: Remove it from the init method and init it when create. --- libraries/CurieBLE/src/BLEPeripheral.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/CurieBLE/src/BLEPeripheral.cpp b/libraries/CurieBLE/src/BLEPeripheral.cpp index 760d374f..990bd965 100644 --- a/libraries/CurieBLE/src/BLEPeripheral.cpp +++ b/libraries/CurieBLE/src/BLEPeripheral.cpp @@ -21,7 +21,7 @@ #include "BLEPeripheral.h" -static BLEPeripheralEventHandler m_eventHandlers[BLEDeviceLastEvent]; +static BLEPeripheralEventHandler m_eventHandlers[BLEDeviceLastEvent] = {NULL, NULL, NULL, NULL}; void bleBackCompatiblePeripheralConnectHandler(BLEDevice central) { @@ -154,7 +154,6 @@ void BLEPeripheral::init() if (!_initCalled) { BLE.begin(); - memset(m_eventHandlers, 0, sizeof(m_eventHandlers)); _initCalled = true; } } From 303e5b41434873af16665619edf36bf077ce6185 Mon Sep 17 00:00:00 2001 From: lianggao Date: Mon, 20 Feb 2017 09:39:50 +0800 Subject: [PATCH 4/4] Fix #444 BLEPeripheral::connected() always returns false 1. Root casue: the stack need use connected device to get the state. The current code used local address to get the link and get an error. 2. Solution: Use central's address to get connection state. --- libraries/CurieBLE/src/BLEPeripheral.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/CurieBLE/src/BLEPeripheral.cpp b/libraries/CurieBLE/src/BLEPeripheral.cpp index 990bd965..ec817f9d 100644 --- a/libraries/CurieBLE/src/BLEPeripheral.cpp +++ b/libraries/CurieBLE/src/BLEPeripheral.cpp @@ -146,7 +146,8 @@ BLECentral BLEPeripheral::central(void) bool BLEPeripheral::connected(void) { - return BLE.connected(); + BLEDevice centralBle = BLE.central(); + return centralBle.connected(); } void BLEPeripheral::init()