Skip to content

Commit aae69c3

Browse files
sgbihuSidLeung
authored andcommitted
Jira 824, BLE Peripheral to create Scan Response Data
Feature added: - Arduino request that the BLE library, in Peripheral mode, to support Scan Response Data request from a Central. - Arduino expects the reply similar to an Apple device. They have provide a policy for the construction of the Scan Response data message. Code mods: 1. BLEDeviceManager.cpp: - Added setAdvertiseData() for the creation of the Scan Response Data message. - In advDataInit(), follows the policy (defined by Arduino) to add Adv data to the Scan Response Data message using setAdvertiseData(). 2. BLEDeviceManager.h: - prototypeing.
1 parent 75dc565 commit aae69c3

File tree

2 files changed

+98
-82
lines changed

2 files changed

+98
-82
lines changed

libraries/CurieBLE/src/internal/BLEDeviceManager.cpp

+95-82
Original file line numberDiff line numberDiff line change
@@ -335,110 +335,132 @@ void BLEDeviceManager::setAppearance(unsigned short appearance)
335335
_appearance = appearance;
336336
}
337337

338+
BLE_STATUS_T
339+
BLEDeviceManager::setAdvertiseData(uint8_t type, const uint8_t* data, uint8_t length)
340+
{
341+
uint8_t lengthOfAdv = 0; // Flags data length
342+
uint8_t lengthOfScanRsp = 0; // Flags data length
343+
bt_data_t *fill_area = NULL;
344+
345+
// Get the length of the Advertisement
346+
for (uint8_t i = 0; i < _adv_data_idx; i++)
347+
{
348+
lengthOfAdv += _adv_data[i].data_len + 2;
349+
}
350+
351+
for (uint8_t i = 0; i < _scan_rsp_data_idx; i++)
352+
{
353+
lengthOfAdv += _scan_rsp_data[i].data_len + 2;
354+
}
355+
356+
357+
if (((length + lengthOfAdv) < BLE_MAX_ADV_SIZE) &&
358+
(_adv_data_idx < ARRAY_SIZE(_adv_data)))
359+
{
360+
fill_area = &_adv_data[_adv_data_idx];
361+
_adv_data_idx++;
362+
}
363+
else if ((length + lengthOfScanRsp) < BLE_MAX_ADV_SIZE &&
364+
(_scan_rsp_data_idx < ARRAY_SIZE(_scan_rsp_data)))
365+
{
366+
fill_area = &_scan_rsp_data[_scan_rsp_data_idx];
367+
_scan_rsp_data_idx++;
368+
}
369+
else
370+
{
371+
// Service data block is too large.
372+
return BLE_STATUS_ERROR_PARAMETER;
373+
}
374+
375+
if (fill_area)
376+
{
377+
fill_area->type = type;
378+
fill_area->data = data;
379+
fill_area->data_len = length;
380+
381+
pr_info(LOG_MODULE_BLE, "ADV type %d Len - %d",type, length);
382+
}
383+
return BLE_STATUS_SUCCESS;
384+
}
385+
338386
BLE_STATUS_T
339387
BLEDeviceManager::_advDataInit(void)
340388
{
341-
uint8_t lengthTotal = 2; // Flags data length
389+
BLE_STATUS_T ret = BLE_STATUS_SUCCESS;
390+
// Clear the indexs
342391
_adv_data_idx = 0;
343392
_scan_rsp_data_idx = 0;
344393

345394
/* Add flags */
346395
_adv_type = (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR);
347-
_adv_data[_adv_data_idx].type = BT_DATA_FLAGS;
348-
_adv_data[_adv_data_idx].data = &_adv_type;
349-
_adv_data[_adv_data_idx].data_len = 1;
350-
_adv_data_idx++;
396+
ret = setAdvertiseData (BT_DATA_FLAGS, &_adv_type, sizeof(_adv_type));
351397

352-
if (_has_service_uuid)
398+
if (_has_service_solicit_uuid &&
399+
(BLE_STATUS_SUCCESS == ret))
353400
{
354401
uint8_t type;
355402
uint8_t length;
356403
uint8_t *data = NULL;
357404

358-
pr_info(LOG_MODULE_BLE, "ADV Type-%d", _service_uuid.uuid.type);
359-
if (BT_UUID_TYPE_16 == _service_uuid.uuid.type)
405+
pr_info(LOG_MODULE_BLE, "ADV Type-%d", _service_solicit_uuid.uuid.type);
406+
if (BT_UUID_TYPE_16 == _service_solicit_uuid.uuid.type)
360407
{
361-
//UINT16_TO_LESTREAM(adv_tmp, uuid.uuid16);
362-
data = (uint8_t *)&(((bt_uuid_16_t *)&_service_uuid)->val);
408+
data = (uint8_t *)&(((bt_uuid_16_t *)&_service_solicit_uuid)->val);
363409
length = UUID_SIZE_16;
364-
type = BT_DATA_UUID16_ALL;
410+
type = BT_DATA_SOLICIT16;
365411
}
366-
else // Sid. KW, default is BT_UUID_TYPE_128
412+
else // Sid. KW, default is BT_UUID_TYPE_128
367413
{
368-
data = _service_uuid.val;
414+
data = _service_solicit_uuid.val;
369415
length = UUID_SIZE_128;
370-
type = BT_DATA_UUID128_ALL;
371-
}
372-
373-
// if (data) // Sid. KW, data is always initialized
374-
{
375-
_adv_data[_adv_data_idx].type = type;
376-
_adv_data[_adv_data_idx].data = data;
377-
_adv_data[_adv_data_idx].data_len = length;
378-
_adv_data_idx++;
379-
lengthTotal += length;
380-
381-
pr_info(LOG_MODULE_BLE, "Service UUID Len -%d", length);
416+
type = BT_DATA_SOLICIT128;
382417
}
418+
419+
ret = setAdvertiseData(type, data, length);
383420
}
384421

385-
if (_has_service_solicit_uuid)
422+
if (_has_service_uuid &&
423+
(BLE_STATUS_SUCCESS == ret))
386424
{
387425
uint8_t type;
388426
uint8_t length;
389427
uint8_t *data = NULL;
390428

391-
pr_info(LOG_MODULE_BLE, "ADV Type-%d", _service_solicit_uuid.uuid.type);
392-
if (BT_UUID_TYPE_16 == _service_solicit_uuid.uuid.type)
429+
pr_info(LOG_MODULE_BLE, "ADV Type-%d", _service_uuid.uuid.type);
430+
if (BT_UUID_TYPE_16 == _service_uuid.uuid.type)
393431
{
394-
//UINT16_TO_LESTREAM(adv_tmp, uuid.uuid16);
395-
data = (uint8_t *)&(((bt_uuid_16_t *)&_service_solicit_uuid)->val);
432+
data = (uint8_t *)&(((bt_uuid_16_t *)&_service_uuid)->val);
396433
length = UUID_SIZE_16;
397-
type = BT_DATA_SOLICIT16;
434+
type = BT_DATA_UUID16_ALL;
398435
}
399-
else // Sid. KW, default is BT_UUID_TYPE_128
436+
else // Sid. KW, default is BT_UUID_TYPE_128
400437
{
401-
data = _service_solicit_uuid.val;
438+
data = _service_uuid.val;
402439
length = UUID_SIZE_128;
403-
type = BT_DATA_SOLICIT128;
404-
}
405-
// Sid. KW, data is always initialized. if (data)
406-
{
407-
_adv_data[_adv_data_idx].type = type;
408-
_adv_data[_adv_data_idx].data = data;
409-
_adv_data[_adv_data_idx].data_len = length;
410-
_adv_data_idx++;
411-
lengthTotal += length;
412-
413-
pr_info(LOG_MODULE_BLE, "Service UUID Len -%d", length);
440+
type = BT_DATA_UUID128_ALL;
414441
}
442+
ret = setAdvertiseData(type, data, length);
415443
}
416-
417-
if (_local_name.length() > 0)
444+
445+
if (_manufacturer_data_length > 0 &&
446+
(BLE_STATUS_SUCCESS == ret))
418447
{
419-
/* Add device name (truncated if too long) */
420-
_adv_data[_adv_data_idx].type = BT_DATA_NAME_COMPLETE;
421-
_adv_data[_adv_data_idx].data = (const uint8_t*)_local_name.c_str();
422-
_adv_data[_adv_data_idx].data_len = _local_name.length();
423-
_adv_data_idx++;
424-
425-
lengthTotal += _local_name.length();
426-
pr_info(LOG_MODULE_BLE, "Local Name -%s", _local_name.c_str());
427-
pr_info(LOG_MODULE_BLE, "Local Name Len -%d", _local_name.length());
448+
ret = setAdvertiseData (BT_DATA_MANUFACTURER_DATA,
449+
_manufacturer_data,
450+
_manufacturer_data_length);
428451
}
429-
430-
if (_manufacturer_data_length > 0)
452+
453+
if (_local_name.length() > 0 &&
454+
(BLE_STATUS_SUCCESS == ret))
431455
{
432-
// Add manufacturer data
433-
_adv_data[_adv_data_idx].type = BT_DATA_MANUFACTURER_DATA;
434-
_adv_data[_adv_data_idx].data = _manufacturer_data;
435-
_adv_data[_adv_data_idx].data_len = _manufacturer_data_length;
436-
_adv_data_idx++;
437-
438-
lengthTotal += _manufacturer_data_length;
456+
uint8_t length = _local_name.length();
457+
ret = setAdvertiseData (BT_DATA_NAME_COMPLETE,
458+
(const uint8_t*)_local_name.c_str(),
459+
length);
439460
}
440461

441-
if (_service_data_length > 0)
462+
if (_service_data_length > 0 &&
463+
(BLE_STATUS_SUCCESS == ret))
442464
{
443465
/* Add Service Data (if it will fit) */
444466

@@ -456,29 +478,18 @@ BLEDeviceManager::_advDataInit(void)
456478
return BLE_STATUS_ERROR_PARAMETER;
457479
}
458480

459-
_adv_data[_adv_data_idx].type = BT_DATA_SVC_DATA16;
460-
_adv_data[_adv_data_idx].data = _service_data_buf;
461-
_adv_data[_adv_data_idx].data_len = block_len;
462-
_adv_data_idx++;
481+
ret = setAdvertiseData (BT_DATA_SVC_DATA16,
482+
_service_data_buf,
483+
block_len);
463484

464485
uint8_t *adv_tmp = _service_data_buf;
465486

466-
//UINT16_TO_LESTREAM(adv_tmp, (((bt_uuid_16_t *)&_service_data_uuid)->val));
467487
memcpy(adv_tmp, &((bt_uuid_16_t*)&_service_data_uuid)->val, sizeof(uint16_t));
468488
adv_tmp += 2;
469489
memcpy(adv_tmp, _service_data, _service_data_length);
470-
471-
lengthTotal += block_len;
472-
pr_info(LOG_MODULE_BLE, "SVC Len -%d", block_len);
473-
}
474-
475-
if (lengthTotal > BLE_MAX_ADV_SIZE)
476-
{
477-
pr_error(LOG_MODULE_BLE, "ADV Total length-%d", lengthTotal);
478-
// Service data block is too large.
479-
return BLE_STATUS_ERROR_PARAMETER;
480490
}
481-
return BLE_STATUS_SUCCESS;
491+
492+
return ret;
482493
}
483494

484495
BLE_STATUS_T BLEDeviceManager::startAdvertising()
@@ -495,7 +506,9 @@ BLE_STATUS_T BLEDeviceManager::startAdvertising()
495506
if (_state != BLE_PERIPH_STATE_READY)
496507
return BLE_STATUS_WRONG_STATE;
497508

498-
ret = bt_le_adv_start(&_adv_param, _adv_data, _adv_data_idx, _scan_rsp_data, _scan_rsp_data_idx);
509+
ret = bt_le_adv_start(&_adv_param,
510+
_adv_data, _adv_data_idx,
511+
_scan_rsp_data, _scan_rsp_data_idx);
499512
if (0 != ret)
500513
{
501514
pr_error(LOG_MODULE_APP, "[ADV] Start failed. Error: %d", ret);

libraries/CurieBLE/src/internal/BLEDeviceManager.h

+3
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,9 @@ class BLEDeviceManager
350350
protected:
351351

352352
private:
353+
BLE_STATUS_T setAdvertiseData (uint8_t type,
354+
const uint8_t* data,
355+
uint8_t length);
353356
BLE_STATUS_T _advDataInit(void);
354357
bool advertiseDataProc(uint8_t type,
355358
const uint8_t *dataPtr,

0 commit comments

Comments
 (0)