Skip to content

Commit d818a3a

Browse files
sgbihuSidLeung
authored andcommitted
Jira 793 Support Characteristic UUID that is not subset of Service, git 384
Root cause: - Nordic stack does not return long UUID for Characteristic discovery. It is expecting Characteristic UUID is a subset of the Service UUID (eg. a sequential increament of the Service UUID). - In order for the Central mode (to behave like Apple) to discover long Characteristic UUID, the process is now done in two steps (similar to the Service discovery). First, initiate a read of the Characteristic and then discover the long UUID upon successful read. Code Mods: 1. BLECallbacks.cpp: - Added a call back to handle the read Characteristic completion event. 2. BLECallbacks.h: - Prototyping. 3. BLEProfileManager.cpp: - Added getServiceBySubHandle() to enable the call back to locate the Service of a discovered Characteristic. 4. BLEProfileManager.h: - Prototyping. 5. BLEServiceImp.cpp: - This is where the two steps Characteristic discovery is implemented. At discoverAttributes(), reading of Characteristic is first initiated. When the stack completes the operation, extract the UUID thereafter. - To support this two steps process, additional functions, discoverNextCharacteristic and readCharacteristic, are added. 6. BLEServiceImp.h: - Prototyping. - Change the discover process. - Add read operation after discover returned invalid UUID.
1 parent d5bce04 commit d818a3a

File tree

6 files changed

+234
-39
lines changed

6 files changed

+234
-39
lines changed

libraries/CurieBLE/src/internal/BLECallbacks.cpp

+17
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,23 @@ uint8_t profile_service_read_rsp_process(bt_conn_t *conn,
172172
return ret;
173173
}
174174

175+
uint8_t profile_characteristic_read_rsp_process(bt_conn_t *conn,
176+
int err,
177+
bt_gatt_read_params_t *params,
178+
const void *data,
179+
uint16_t length)
180+
{
181+
BLEDevice bleDevice(bt_conn_get_dst(conn));
182+
BLEServiceImp* service_imp = BLEProfileManager::instance()->getServiceBySubHandle(bleDevice, params->single.handle);
183+
184+
uint8_t ret = service_imp->characteristicReadRspProc(conn,
185+
err,
186+
params,
187+
data,
188+
length);
189+
pr_debug(LOG_MODULE_BLE, "%s-%d:ret-%d", __FUNCTION__, __LINE__, ret);
190+
return ret;
191+
}
175192

176193

177194
void bleConnectEventHandler(bt_conn_t *conn,

libraries/CurieBLE/src/internal/BLECallbacks.h

+5
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ uint8_t profile_service_read_rsp_process(bt_conn_t *conn,
7676

7777
void ble_on_write_no_rsp_complete(struct bt_conn *conn, uint8_t err,
7878
const void *data);
79+
uint8_t profile_characteristic_read_rsp_process(bt_conn_t *conn,
80+
int err,
81+
bt_gatt_read_params_t *params,
82+
const void *data,
83+
uint16_t length);
7984

8085
#endif
8186

libraries/CurieBLE/src/internal/BLEProfileManager.cpp

+34
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,40 @@ BLEServiceImp* BLEProfileManager::service(const BLEDevice &bledevice, int index)
507507
return serviceImp;
508508
}
509509

510+
BLEServiceImp* BLEProfileManager::getServiceBySubHandle(const BLEDevice &bledevice, uint16_t handle) const
511+
{
512+
BLEServiceImp* serviceImp = NULL;
513+
uint16_t start_handle;
514+
uint16_t end_handle;
515+
516+
const BLEServiceLinkNodeHeader* serviceHeader = getServiceHeader(bledevice);
517+
if (NULL == serviceHeader)
518+
{
519+
// Doesn't find the service
520+
return NULL;
521+
}
522+
BLEServiceNodePtr node = serviceHeader->next;
523+
524+
while (node != NULL)
525+
{
526+
serviceImp = node->value;
527+
start_handle = serviceImp->startHandle();
528+
end_handle = serviceImp->endHandle();
529+
if (handle >= start_handle && handle <= end_handle)
530+
{
531+
break;
532+
}
533+
node = node->next;
534+
}
535+
536+
if (NULL == node)
537+
{
538+
serviceImp = NULL;
539+
}
540+
541+
return serviceImp;
542+
}
543+
510544
void BLEProfileManager::handleConnectedEvent(const bt_addr_le_t* deviceAddr)
511545
{
512546
int index = getUnusedIndex();

libraries/CurieBLE/src/internal/BLEProfileManager.h

+1
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ class BLEProfileManager{
9898
BLEServiceImp* service(const BLEDevice &bledevice, const char * uuid) const;
9999
BLEServiceImp* service(const BLEDevice &bledevice, int index) const;
100100
BLEServiceImp* service(const BLEDevice &bledevice, const bt_uuid_t* uuid) const;
101+
BLEServiceImp* getServiceBySubHandle(const BLEDevice &bledevice, uint16_t handle) const;
101102
int serviceCount(const BLEDevice &bledevice) const;
102103
int characteristicCount(const BLEDevice &bledevice) const;
103104

libraries/CurieBLE/src/internal/BLEServiceImp.cpp

+161-39
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "BLECharacteristicImp.h"
2727

2828
bt_uuid_16_t BLEServiceImp::_gatt_primary_uuid = {BT_UUID_TYPE_16, BT_UUID_GATT_PRIMARY_VAL};
29+
bt_gatt_read_params_t BLEServiceImp::_read_params;
2930

3031
bt_uuid_t *BLEServiceImp::getPrimayUuid(void)
3132
{
@@ -36,6 +37,7 @@ BLEServiceImp::BLEServiceImp(BLEService& service):
3637
BLEAttribute(service.uuid(), BLETypeService),
3738
_start_handle(0),
3839
_end_handle(0xFFFF),
40+
_reading(false),
3941
_cur_discover_chrc(NULL)
4042
{
4143
memset(&_characteristics_header, 0, sizeof(_characteristics_header));
@@ -46,6 +48,7 @@ BLEServiceImp::BLEServiceImp(const bt_uuid_t* uuid):
4648
BLEAttribute(uuid, BLETypeService),
4749
_start_handle(0),
4850
_end_handle(0xFFFF),
51+
_reading(false),
4952
_cur_discover_chrc(NULL)
5053
{
5154
memset(&_characteristics_header, 0, sizeof(_characteristics_header));
@@ -242,10 +245,17 @@ BLECharacteristicImp* BLEServiceImp::characteristic(const char* uuid)
242245

243246
bool BLEServiceImp::discovering()
244247
{
245-
return (_cur_discover_chrc != NULL);
248+
return (_cur_discover_chrc != NULL || _reading);
246249
}
247250

248251
bool BLEServiceImp::discoverAttributes(BLEDevice* device)
252+
{
253+
return discoverAttributes(device, _start_handle, _end_handle);
254+
}
255+
256+
bool BLEServiceImp::discoverAttributes(BLEDevice* device,
257+
uint16_t start_handle,
258+
uint16_t end_handle)
249259
{
250260
pr_debug(LOG_MODULE_BLE, "%s-%d", __FUNCTION__, __LINE__);
251261
int err;
@@ -273,8 +283,8 @@ bool BLEServiceImp::discoverAttributes(BLEDevice* device)
273283
return false;
274284
}
275285
temp = &_discover_params;
276-
temp->start_handle = _start_handle;
277-
temp->end_handle = _end_handle;
286+
temp->start_handle = start_handle;
287+
temp->end_handle = end_handle;
278288
temp->uuid = NULL;
279289
temp->type = BT_GATT_DISCOVER_CHARACTERISTIC;
280290
temp->func = profile_discover_process;
@@ -309,21 +319,34 @@ uint8_t BLEServiceImp::discoverResponseProc(bt_conn_t *conn,
309319
//const bt_uuid_t* chrc_uuid = attr->uuid;
310320
uint16_t chrc_handle = attr->handle + 1;
311321
struct bt_gatt_chrc* psttemp = (struct bt_gatt_chrc*)attr->user_data;
312-
int retval = (int)addCharacteristic(device,
313-
psttemp->uuid,
314-
chrc_handle,
315-
psttemp->properties);
322+
const bt_uuid_t* chrc_uuid = psttemp->uuid;
316323

317-
//pr_debug(LOG_MODULE_BLE, "%s-%d:handle-%d:%d", __FUNCTION__, __LINE__,attr->handle, chrc_handle);
318-
if (BLE_STATUS_SUCCESS != retval)
324+
uint16_t le16;
325+
memcpy(&le16, &BT_UUID_16(chrc_uuid)->val, sizeof(le16));
326+
if (chrc_uuid->type == BT_UUID_TYPE_16 &&
327+
le16 == 0)
319328
{
320-
pr_error(LOG_MODULE_BLE, "%s-%d: Error-%d",
321-
__FUNCTION__, __LINE__, retval);
322-
errno = ENOMEM;
329+
// Read the UUID
330+
readCharacteristic(device, chrc_handle);
331+
retVal = BT_GATT_ITER_CONTINUE;
323332
}
324333
else
325334
{
326-
retVal = BT_GATT_ITER_CONTINUE;
335+
int retval = (int)addCharacteristic(device,
336+
psttemp->uuid,
337+
chrc_handle,
338+
psttemp->properties);
339+
340+
if (BLE_STATUS_SUCCESS != retval)
341+
{
342+
pr_error(LOG_MODULE_BLE, "%s-%d: Error-%d",
343+
__FUNCTION__, __LINE__, retval);
344+
errno = ENOMEM;
345+
}
346+
else
347+
{
348+
retVal = BT_GATT_ITER_CONTINUE;
349+
}
327350
}
328351
}
329352
break;
@@ -335,8 +358,8 @@ uint8_t BLEServiceImp::discoverResponseProc(bt_conn_t *conn,
335358
if (NULL != _cur_discover_chrc)
336359
{
337360
retVal = _cur_discover_chrc->discoverResponseProc(conn,
338-
attr,
339-
params);
361+
attr,
362+
params);
340363
}
341364
break;
342365
}
@@ -347,44 +370,143 @@ uint8_t BLEServiceImp::discoverResponseProc(bt_conn_t *conn,
347370
}
348371
}
349372

350-
pr_debug(LOG_MODULE_BLE, "%s-%d:ret-%d",__FUNCTION__, __LINE__, retVal);
373+
//pr_debug(LOG_MODULE_BLE, "%s-%d:ret-%d",__FUNCTION__, __LINE__, retVal);
351374
if (retVal == BT_GATT_ITER_STOP)
352375
{
353376
if (errno == ENOMEM)
354377
{
355378
_cur_discover_chrc = NULL;
356379
return retVal;
357380
}
358-
const BLECharacteristicLinkNodeHeader* chrcHeader = &_characteristics_header;
359-
BLECharacteristicImp* chrcCurImp = NULL;
360-
BLECharacteristicNodePtr node = chrcHeader->next;
361381

362-
pr_debug(LOG_MODULE_BLE, "%s-%d: node-%p",__FUNCTION__, __LINE__, node);
363-
// Discover next service
364-
while (node != NULL)
382+
if (false == _reading)
365383
{
366-
chrcCurImp = node->value;
367-
368-
if (NULL == _cur_discover_chrc)
384+
discoverNextCharacteristic(device);
385+
}
386+
}
387+
return retVal;
388+
}
389+
390+
void BLEServiceImp::discoverNextCharacteristic(BLEDevice &bledevice)
391+
{
392+
const BLECharacteristicLinkNodeHeader* chrcHeader = &_characteristics_header;
393+
BLECharacteristicImp* chrcCurImp = NULL;
394+
BLECharacteristicNodePtr node = chrcHeader->next;
395+
396+
//pr_debug(LOG_MODULE_BLE, "%s-%d: node-%p",__FUNCTION__, __LINE__, node);
397+
// Discover next service
398+
while (node != NULL)
399+
{
400+
chrcCurImp = node->value;
401+
402+
if (NULL == _cur_discover_chrc)
403+
{
404+
bool result = chrcCurImp->discoverAttributes(&bledevice);
405+
pr_debug(LOG_MODULE_BLE, "%s-%d",__FUNCTION__, __LINE__);
406+
if (result == true)
369407
{
370-
bool result = chrcCurImp->discoverAttributes(&device);
371-
pr_debug(LOG_MODULE_BLE, "%s-%d",__FUNCTION__, __LINE__);
372-
if (result == true)
373-
{
374-
// Record the current discovering service
375-
_cur_discover_chrc = chrcCurImp;
376-
break;
377-
}
408+
// Record the current discovering service
409+
_cur_discover_chrc = chrcCurImp;
410+
break;
378411
}
379-
else if (_cur_discover_chrc == chrcCurImp)
412+
}
413+
else if (_cur_discover_chrc == chrcCurImp)
414+
{
415+
// Find next discoverable service
416+
_cur_discover_chrc = NULL;
417+
}
418+
node = node->next;
419+
}
420+
}
421+
422+
bool BLEServiceImp::readCharacteristic(const BLEDevice &bledevice, uint16_t handle)
423+
{
424+
int retval = 0;
425+
bt_conn_t* conn = NULL;
426+
427+
if (true == BLEUtils::isLocalBLE(bledevice))
428+
{
429+
// GATT server can't write
430+
return false;
431+
}
432+
433+
if (_reading)
434+
{
435+
return false;
436+
}
437+
438+
_read_params.func = profile_characteristic_read_rsp_process;
439+
_read_params.handle_count = 1;
440+
_read_params.single.handle = handle - 1;
441+
_read_params.single.offset = 0;
442+
443+
if (0 == _read_params.single.handle)
444+
{
445+
// Discover not complete
446+
return false;
447+
}
448+
449+
conn = bt_conn_lookup_addr_le(bledevice.bt_le_address());
450+
if (NULL == conn)
451+
{
452+
return false;
453+
}
454+
// Send read request
455+
retval = bt_gatt_read(conn, &_read_params);
456+
bt_conn_unref(conn);
457+
if (0 == retval)
458+
{
459+
_reading = true;
460+
}
461+
pr_debug(LOG_MODULE_BLE, "%s-%d", __FUNCTION__, __LINE__);
462+
return _reading;
463+
}
464+
465+
uint8_t BLEServiceImp::characteristicReadRspProc(bt_conn_t *conn,
466+
int err,
467+
bt_gatt_read_params_t *params,
468+
const void *data,
469+
uint16_t length)
470+
{
471+
_reading = false;
472+
if (NULL == data)
473+
{
474+
return BT_GATT_ITER_STOP;
475+
}
476+
BLEDevice bleDevice(bt_conn_get_dst(conn));
477+
478+
pr_debug(LOG_MODULE_BLE, "%s-%d:length-%d", __FUNCTION__, __LINE__, length);
479+
if (length == UUID_SIZE_128 + 3)
480+
{
481+
const uint8_t* rspdata = (const uint8_t*) data;
482+
bt_uuid_128_t uuid_tmp;
483+
uint16_t chrc_handle = rspdata[1] | (rspdata[2] << 8);
484+
uuid_tmp.uuid.type = BT_UUID_TYPE_128;
485+
memcpy(uuid_tmp.val, &rspdata[3], UUID_SIZE_128);
486+
int retval = (int)addCharacteristic(bleDevice,
487+
(const bt_uuid_t*)&uuid_tmp,
488+
chrc_handle,
489+
rspdata[0]);
490+
491+
if (BLE_STATUS_SUCCESS != retval)
492+
{
493+
pr_error(LOG_MODULE_BLE, "%s-%d: Error-%d",
494+
__FUNCTION__, __LINE__, retval);
495+
errno = ENOMEM;
496+
}
497+
else
498+
{
499+
if (false == discovering())
380500
{
381-
// Find next discoverable service
382-
_cur_discover_chrc = NULL;
501+
if (false == discoverAttributes(&bleDevice, chrc_handle + 1, _end_handle))
502+
{
503+
discoverNextCharacteristic(bleDevice);
504+
}
383505
}
384-
node = node->next;
385506
}
386507
}
387-
return retVal;
508+
pr_debug(LOG_MODULE_BLE, "%s-%d", __FUNCTION__, __LINE__);
509+
510+
return BT_GATT_ITER_STOP;
388511
}
389512

390-

libraries/CurieBLE/src/internal/BLEServiceImp.h

+16
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ class BLEServiceImp: public BLEAttribute{
7171
uint8_t discoverResponseProc(bt_conn_t *conn,
7272
const bt_gatt_attr_t *attr,
7373
bt_gatt_discover_params_t *params);
74+
75+
uint8_t characteristicReadRspProc(bt_conn_t *conn,
76+
int err,
77+
bt_gatt_read_params_t *params,
78+
const void *data,
79+
uint16_t length);
7480
bool discovering();
7581

7682
static bt_uuid_t *getPrimayUuid(void);
@@ -81,6 +87,13 @@ class BLEServiceImp: public BLEAttribute{
8187

8288

8389
int updateProfile(bt_gatt_attr_t *attr_start, int& index);
90+
91+
private:
92+
void discoverNextCharacteristic(BLEDevice &bledevice);
93+
bool readCharacteristic(const BLEDevice &bledevice, uint16_t handle);
94+
bool discoverAttributes(BLEDevice* device,
95+
uint16_t start_handle,
96+
uint16_t end_handle);
8497
private:
8598
typedef LinkNode<BLECharacteristicImp *> BLECharacteristicLinkNodeHeader;
8699
typedef LinkNode<BLECharacteristicImp *>* BLECharacteristicNodePtr;
@@ -89,6 +102,9 @@ class BLEServiceImp: public BLEAttribute{
89102
uint16_t _start_handle;
90103
uint16_t _end_handle;
91104

105+
static bt_gatt_read_params_t _read_params;
106+
bool _reading;
107+
92108
void releaseCharacteristic();
93109
BLECharacteristicImp *_cur_discover_chrc;
94110

0 commit comments

Comments
 (0)