Skip to content

Commit 000efea

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 272bbf4 commit 000efea

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
@@ -338,110 +338,132 @@ void BLEDeviceManager::setAppearance(unsigned short appearance)
338338
_appearance = appearance;
339339
}
340340

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

348397
/* Add flags */
349398
_adv_type = (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR);
350-
_adv_data[_adv_data_idx].type = BT_DATA_FLAGS;
351-
_adv_data[_adv_data_idx].data = &_adv_type;
352-
_adv_data[_adv_data_idx].data_len = 1;
353-
_adv_data_idx++;
399+
ret = setAdvertiseData (BT_DATA_FLAGS, &_adv_type, sizeof(_adv_type));
354400

355-
if (_has_service_uuid)
401+
if (_has_service_solicit_uuid &&
402+
(BLE_STATUS_SUCCESS == ret))
356403
{
357404
uint8_t type;
358405
uint8_t length;
359406
uint8_t *data = NULL;
360407

361-
pr_info(LOG_MODULE_BLE, "ADV Type-%d", _service_uuid.uuid.type);
362-
if (BT_UUID_TYPE_16 == _service_uuid.uuid.type)
408+
pr_info(LOG_MODULE_BLE, "ADV Type-%d", _service_solicit_uuid.uuid.type);
409+
if (BT_UUID_TYPE_16 == _service_solicit_uuid.uuid.type)
363410
{
364-
//UINT16_TO_LESTREAM(adv_tmp, uuid.uuid16);
365-
data = (uint8_t *)&(((bt_uuid_16_t *)&_service_uuid)->val);
411+
data = (uint8_t *)&(((bt_uuid_16_t *)&_service_solicit_uuid)->val);
366412
length = UUID_SIZE_16;
367-
type = BT_DATA_UUID16_ALL;
413+
type = BT_DATA_SOLICIT16;
368414
}
369-
else // Sid. KW, default is BT_UUID_TYPE_128
415+
else // Sid. KW, default is BT_UUID_TYPE_128
370416
{
371-
data = _service_uuid.val;
417+
data = _service_solicit_uuid.val;
372418
length = UUID_SIZE_128;
373-
type = BT_DATA_UUID128_ALL;
374-
}
375-
376-
// if (data) // Sid. KW, data is always initialized
377-
{
378-
_adv_data[_adv_data_idx].type = type;
379-
_adv_data[_adv_data_idx].data = data;
380-
_adv_data[_adv_data_idx].data_len = length;
381-
_adv_data_idx++;
382-
lengthTotal += length;
383-
384-
pr_info(LOG_MODULE_BLE, "Service UUID Len -%d", length);
419+
type = BT_DATA_SOLICIT128;
385420
}
421+
422+
ret = setAdvertiseData(type, data, length);
386423
}
387424

388-
if (_has_service_solicit_uuid)
425+
if (_has_service_uuid &&
426+
(BLE_STATUS_SUCCESS == ret))
389427
{
390428
uint8_t type;
391429
uint8_t length;
392430
uint8_t *data = NULL;
393431

394-
pr_info(LOG_MODULE_BLE, "ADV Type-%d", _service_solicit_uuid.uuid.type);
395-
if (BT_UUID_TYPE_16 == _service_solicit_uuid.uuid.type)
432+
pr_info(LOG_MODULE_BLE, "ADV Type-%d", _service_uuid.uuid.type);
433+
if (BT_UUID_TYPE_16 == _service_uuid.uuid.type)
396434
{
397-
//UINT16_TO_LESTREAM(adv_tmp, uuid.uuid16);
398-
data = (uint8_t *)&(((bt_uuid_16_t *)&_service_solicit_uuid)->val);
435+
data = (uint8_t *)&(((bt_uuid_16_t *)&_service_uuid)->val);
399436
length = UUID_SIZE_16;
400-
type = BT_DATA_SOLICIT16;
437+
type = BT_DATA_UUID16_ALL;
401438
}
402-
else // Sid. KW, default is BT_UUID_TYPE_128
439+
else // Sid. KW, default is BT_UUID_TYPE_128
403440
{
404-
data = _service_solicit_uuid.val;
441+
data = _service_uuid.val;
405442
length = UUID_SIZE_128;
406-
type = BT_DATA_SOLICIT128;
407-
}
408-
// Sid. KW, data is always initialized. if (data)
409-
{
410-
_adv_data[_adv_data_idx].type = type;
411-
_adv_data[_adv_data_idx].data = data;
412-
_adv_data[_adv_data_idx].data_len = length;
413-
_adv_data_idx++;
414-
lengthTotal += length;
415-
416-
pr_info(LOG_MODULE_BLE, "Service UUID Len -%d", length);
443+
type = BT_DATA_UUID128_ALL;
417444
}
445+
ret = setAdvertiseData(type, data, length);
418446
}
419-
420-
if (_local_name.length() > 0)
447+
448+
if (_manufacturer_data_length > 0 &&
449+
(BLE_STATUS_SUCCESS == ret))
421450
{
422-
/* Add device name (truncated if too long) */
423-
_adv_data[_adv_data_idx].type = BT_DATA_NAME_COMPLETE;
424-
_adv_data[_adv_data_idx].data = (const uint8_t*)_local_name.c_str();
425-
_adv_data[_adv_data_idx].data_len = _local_name.length();
426-
_adv_data_idx++;
427-
428-
lengthTotal += _local_name.length();
429-
pr_info(LOG_MODULE_BLE, "Local Name -%s", _local_name.c_str());
430-
pr_info(LOG_MODULE_BLE, "Local Name Len -%d", _local_name.length());
451+
ret = setAdvertiseData (BT_DATA_MANUFACTURER_DATA,
452+
_manufacturer_data,
453+
_manufacturer_data_length);
431454
}
432-
433-
if (_manufacturer_data_length > 0)
455+
456+
if (_local_name.length() > 0 &&
457+
(BLE_STATUS_SUCCESS == ret))
434458
{
435-
// Add manufacturer data
436-
_adv_data[_adv_data_idx].type = BT_DATA_MANUFACTURER_DATA;
437-
_adv_data[_adv_data_idx].data = _manufacturer_data;
438-
_adv_data[_adv_data_idx].data_len = _manufacturer_data_length;
439-
_adv_data_idx++;
440-
441-
lengthTotal += _manufacturer_data_length;
459+
uint8_t length = _local_name.length();
460+
ret = setAdvertiseData (BT_DATA_NAME_COMPLETE,
461+
(const uint8_t*)_local_name.c_str(),
462+
length);
442463
}
443464

444-
if (_service_data_length > 0)
465+
if (_service_data_length > 0 &&
466+
(BLE_STATUS_SUCCESS == ret))
445467
{
446468
/* Add Service Data (if it will fit) */
447469

@@ -459,29 +481,18 @@ BLEDeviceManager::_advDataInit(void)
459481
return BLE_STATUS_ERROR_PARAMETER;
460482
}
461483

462-
_adv_data[_adv_data_idx].type = BT_DATA_SVC_DATA16;
463-
_adv_data[_adv_data_idx].data = _service_data_buf;
464-
_adv_data[_adv_data_idx].data_len = block_len;
465-
_adv_data_idx++;
484+
ret = setAdvertiseData (BT_DATA_SVC_DATA16,
485+
_service_data_buf,
486+
block_len);
466487

467488
uint8_t *adv_tmp = _service_data_buf;
468489

469-
//UINT16_TO_LESTREAM(adv_tmp, (((bt_uuid_16_t *)&_service_data_uuid)->val));
470490
memcpy(adv_tmp, &((bt_uuid_16_t*)&_service_data_uuid)->val, sizeof(uint16_t));
471491
adv_tmp += 2;
472492
memcpy(adv_tmp, _service_data, _service_data_length);
473-
474-
lengthTotal += block_len;
475-
pr_info(LOG_MODULE_BLE, "SVC Len -%d", block_len);
476-
}
477-
478-
if (lengthTotal > BLE_MAX_ADV_SIZE)
479-
{
480-
pr_error(LOG_MODULE_BLE, "ADV Total length-%d", lengthTotal);
481-
// Service data block is too large.
482-
return BLE_STATUS_ERROR_PARAMETER;
483493
}
484-
return BLE_STATUS_SUCCESS;
494+
495+
return ret;
485496
}
486497

487498
BLE_STATUS_T BLEDeviceManager::startAdvertising()
@@ -498,7 +509,9 @@ BLE_STATUS_T BLEDeviceManager::startAdvertising()
498509
if (_state != BLE_PERIPH_STATE_READY)
499510
return BLE_STATUS_WRONG_STATE;
500511

501-
ret = bt_le_adv_start(&_adv_param, _adv_data, _adv_data_idx, _scan_rsp_data, _scan_rsp_data_idx);
512+
ret = bt_le_adv_start(&_adv_param,
513+
_adv_data, _adv_data_idx,
514+
_scan_rsp_data, _scan_rsp_data_idx);
502515
if (0 != ret)
503516
{
504517
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)