Skip to content

Commit 7856de7

Browse files
authoredApr 22, 2021
BLE5 features to use with C3/S3 (espressif#5085)
Added new BLE5 features to use on C3/S3 family: extended scan, extended/multi advertising New code is not fancy (no feedback from events), but i think it is functional. To get feedback from events i am suggesting to use custom GAP callback, which is already implemented in BLEDevice.
1 parent e62ff6d commit 7856de7

File tree

17 files changed

+909
-1
lines changed

17 files changed

+909
-1
lines changed
 

‎libraries/BLE/examples/BLE5_extended_scan/.skip.esp32

Whitespace-only changes.

‎libraries/BLE/examples/BLE5_extended_scan/.skip.esp32s2

Whitespace-only changes.
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
BLE5 extended scan example for esp32 C3 and S3
3+
with this code it is simple to scan legacy (BLE4) compatible advertising,
4+
and BLE5 extended advertising. New coded added in BLEScan is not changing old behavior,
5+
which can be used with old esp32, but is adding functionality to use on C3/S3.
6+
With this new API advertised device wont be stored in API, it is now user responsibility
7+
8+
author: chegewara
9+
*/
10+
#ifndef CONFIG_BT_BLE_50_FEATURES_SUPPORTED
11+
#warning "Not compatible hardware"
12+
#else
13+
#include <BLEDevice.h>
14+
#include <BLEUtils.h>
15+
#include <BLEScan.h>
16+
#include <BLEAdvertisedDevice.h>
17+
18+
uint32_t scanTime = 100; //In 10ms (1000ms)
19+
BLEScan* pBLEScan;
20+
21+
/**
22+
* @brief extend adv report parameters
23+
*/
24+
//typedef struct {
25+
// esp_ble_gap_adv_type_t event_type; /*!< extend advertising type */
26+
// uint8_t addr_type; /*!< extend advertising address type */
27+
// esp_bd_addr_t addr; /*!< extend advertising address */
28+
// esp_ble_gap_pri_phy_t primary_phy; /*!< extend advertising primary phy */
29+
// esp_ble_gap_phy_t secondly_phy; /*!< extend advertising secondary phy */
30+
// uint8_t sid; /*!< extend advertising sid */
31+
// uint8_t tx_power; /*!< extend advertising tx power */
32+
// int8_t rssi; /*!< extend advertising rssi */
33+
// uint16_t per_adv_interval; /*!< periodic advertising interval */
34+
// uint8_t dir_addr_type; /*!< direct address type */
35+
// esp_bd_addr_t dir_addr; /*!< direct address */
36+
// esp_ble_gap_ext_adv_data_status_t data_status; /*!< data type */
37+
// uint8_t adv_data_len; /*!< extend advertising data length */
38+
// uint8_t adv_data[251]; /*!< extend advertising data */
39+
//} esp_ble_gap_ext_adv_reprot_t;
40+
41+
class MyBLEExtAdvertisingCallbacks: public BLEExtAdvertisingCallbacks {
42+
void onResult(esp_ble_gap_ext_adv_reprot_t report) {
43+
if(report.event_type & ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY){
44+
// here we can receive regular advertising data from BLE4.x devices
45+
Serial.println("BLE4.2");
46+
} else {
47+
// here we will get extended advertising data that are advertised over data channel by BLE5 divices
48+
Serial.printf("Ext advertise: data_le: %d, data_status: %d \n", report.adv_data_len, report.data_status);
49+
}
50+
}
51+
};
52+
53+
void setup() {
54+
Serial.begin(115200);
55+
Serial.println("Scanning...");
56+
57+
BLEDevice::init("");
58+
pBLEScan = BLEDevice::getScan(); //create new scan
59+
pBLEScan->setExtendedScanCallback(new MyBLEExtAdvertisingCallbacks());
60+
pBLEScan->setExtScanParams(); // use with pre-defined/default values, overloaded function allows to pass parameters
61+
delay(1000); // it is just for simplicity this example, to let ble stack to set extended scan params
62+
pBLEScan->startExtScan(scanTime, 3); // scan duration in n * 10ms, period - repeat after n seconds (period >= duration)
63+
}
64+
65+
void loop() {
66+
// put your main code here, to run repeatedly:
67+
delay(2000);
68+
}
69+
#endif // CONFIG_BT_BLE_50_FEATURES_SUPPORTED

‎libraries/BLE/examples/BLE5_multi_advertising/.skip.esp32

Whitespace-only changes.

‎libraries/BLE/examples/BLE5_multi_advertising/.skip.esp32s2

Whitespace-only changes.
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
/*
2+
Simple BLE5 multi advertising example on esp32 C3/S3
3+
only ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_IND is backward compatible
4+
and can be scanned with BLE4.2 devices
5+
6+
author: chegewara
7+
*/
8+
9+
#include <BLEDevice.h>
10+
#include <BLEAdvertising.h>
11+
12+
esp_ble_gap_ext_adv_params_t ext_adv_params_1M = {
13+
.type = ESP_BLE_GAP_SET_EXT_ADV_PROP_CONNECTABLE,
14+
.interval_min = 0x30,
15+
.interval_max = 0x30,
16+
.channel_map = ADV_CHNL_ALL,
17+
.own_addr_type = BLE_ADDR_TYPE_RANDOM,
18+
.filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
19+
.primary_phy = ESP_BLE_GAP_PHY_CODED,
20+
.max_skip = 0,
21+
.secondary_phy = ESP_BLE_GAP_PHY_1M,
22+
.sid = 0,
23+
.scan_req_notif = false,
24+
};
25+
26+
esp_ble_gap_ext_adv_params_t ext_adv_params_2M = {
27+
.type = ESP_BLE_GAP_SET_EXT_ADV_PROP_SCANNABLE,
28+
.interval_min = 0x40,
29+
.interval_max = 0x40,
30+
.channel_map = ADV_CHNL_ALL,
31+
.own_addr_type = BLE_ADDR_TYPE_RANDOM,
32+
.filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
33+
.primary_phy = ESP_BLE_GAP_PHY_1M,
34+
.max_skip = 0,
35+
.secondary_phy = ESP_BLE_GAP_PHY_2M,
36+
.sid = 1,
37+
.scan_req_notif = false,
38+
};
39+
40+
esp_ble_gap_ext_adv_params_t legacy_adv_params = {
41+
.type = ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_IND,
42+
.interval_min = 0x45,
43+
.interval_max = 0x45,
44+
.channel_map = ADV_CHNL_ALL,
45+
.own_addr_type = BLE_ADDR_TYPE_RANDOM,
46+
.filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
47+
.primary_phy = ESP_BLE_GAP_PHY_1M,
48+
.max_skip = 0,
49+
.secondary_phy = ESP_BLE_GAP_PHY_1M,
50+
.sid = 2,
51+
.scan_req_notif = false,
52+
};
53+
54+
esp_ble_gap_ext_adv_params_t ext_adv_params_coded = {
55+
.type = ESP_BLE_GAP_SET_EXT_ADV_PROP_SCANNABLE,
56+
.interval_min = 0x50,
57+
.interval_max = 0x50,
58+
.channel_map = ADV_CHNL_ALL,
59+
.own_addr_type = BLE_ADDR_TYPE_RANDOM,
60+
.filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
61+
.primary_phy = ESP_BLE_GAP_PHY_1M,
62+
.max_skip = 0,
63+
.secondary_phy = ESP_BLE_GAP_PHY_CODED,
64+
.sid = 3,
65+
.scan_req_notif = false,
66+
};
67+
68+
static uint8_t raw_adv_data_1m[] = {
69+
0x02, 0x01, 0x06,
70+
0x02, 0x0a, 0xeb,
71+
0x12, 0x09, 'E', 'S', 'P', '_', 'M', 'U', 'L', 'T', 'I', '_', 'A',
72+
'D', 'V', '_', '1', 'M', 0X0
73+
};
74+
75+
static uint8_t raw_scan_rsp_data_2m[] = {
76+
0x02, 0x01, 0x06,
77+
0x02, 0x0a, 0xeb,
78+
0x12, 0x09, 'E', 'S', 'P', '_', 'M', 'U', 'L', 'T', 'I', '_', 'A',
79+
'D', 'V', '_', '2', 'M', 0X0
80+
};
81+
82+
static uint8_t legacy_adv_data[] = {
83+
0x02, 0x01, 0x06,
84+
0x02, 0x0a, 0xeb,
85+
0x15, 0x09, 'E', 'S', 'P', '_', 'M', 'U', 'L', 'T', 'I', '_', 'A',
86+
'D', 'V', '_', 'C', 'O', 'D', 'E', 'D', 0X0
87+
};
88+
89+
static uint8_t legacy_scan_rsp_data[] = {
90+
0x02, 0x01, 0x06,
91+
0x02, 0x0a, 0xeb,
92+
0x16, 0x09, 'E', 'S', 'P', '_', 'M', 'U', 'L', 'T', 'I', '_', 'A',
93+
'D', 'V', '_', 'L', 'E', 'G', 'A', 'C', 'Y', 0X0
94+
};
95+
96+
static uint8_t raw_scan_rsp_data_coded[] = {
97+
0x37, 0x09, 'V', 'E', 'R', 'Y', '_', 'L', 'O', 'N', 'G', '_', 'D', 'E', 'V', 'I', 'C', 'E', '_', 'N', 'A', 'M', 'E', '_',
98+
'S', 'E', 'N', 'T', '_', 'U', 'S', 'I', 'N', 'G', '_', 'E', 'X', 'T', 'E', 'N', 'D', 'E', 'D', '_', 'A', 'D', 'V', 'E', 'R', 'T', 'I', 'S', 'I', 'N', 'G', 0X0
99+
};
100+
101+
102+
uint8_t addr_1m[6] = {0xc0, 0xde, 0x52, 0x00, 0x00, 0x01};
103+
uint8_t addr_2m[6] = {0xc0, 0xde, 0x52, 0x00, 0x00, 0x02};
104+
uint8_t addr_legacy[6] = {0xc0, 0xde, 0x52, 0x00, 0x00, 0x03};
105+
uint8_t addr_coded[6] = {0xc0, 0xde, 0x52, 0x00, 0x00, 0x04};
106+
107+
BLEMultiAdvertising advert(4); // max number of advertisement data
108+
109+
void setup() {
110+
Serial.begin(115200);
111+
Serial.println("Multi-Advertising...");
112+
113+
BLEDevice::init("");
114+
115+
advert.setAdvertisingParams(0, &ext_adv_params_1M);
116+
advert.setAdvertisingData(0, sizeof(raw_adv_data_1m), &raw_adv_data_1m[0]);
117+
advert.setInstanceAddress(0, addr_1m);
118+
advert.setDuration(0);
119+
120+
advert.setAdvertisingParams(1, &ext_adv_params_2M);
121+
advert.setScanRspData(1, sizeof(raw_scan_rsp_data_2m), &raw_scan_rsp_data_2m[0]);
122+
advert.setInstanceAddress(1, addr_2m);
123+
advert.setDuration(1);
124+
125+
advert.setAdvertisingParams(2, &legacy_adv_params);
126+
advert.setAdvertisingData(2, sizeof(legacy_adv_data), &legacy_adv_data[0]);
127+
advert.setScanRspData(2, sizeof(legacy_scan_rsp_data), &legacy_scan_rsp_data[0]);
128+
advert.setInstanceAddress(2, addr_legacy);
129+
advert.setDuration(2);
130+
131+
advert.setAdvertisingParams(3, &ext_adv_params_coded);
132+
advert.setDuration(3);
133+
advert.setScanRspData(3, sizeof(raw_scan_rsp_data_coded), &raw_scan_rsp_data_coded[0]);
134+
advert.setInstanceAddress(3, addr_coded);
135+
136+
delay(1000);
137+
advert.start(4, 0);
138+
}
139+
140+
void loop() {
141+
delay(2000);
142+
}

‎libraries/BLE/examples/BLE5_periodic_advertising/.skip.esp32

Whitespace-only changes.

‎libraries/BLE/examples/BLE5_periodic_advertising/.skip.esp32s2

Whitespace-only changes.
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
Simple BLE5 multi advertising example on esp32 C3/S3
3+
only ESP_BLE_GAP_SET_EXT_ADV_PROP_NONCONN_NONSCANNABLE_UNDIRECTED can be used for periodic advertising
4+
5+
author: chegewara
6+
*/
7+
8+
#include <BLEDevice.h>
9+
#include <BLEAdvertising.h>
10+
11+
12+
esp_ble_gap_ext_adv_params_t ext_adv_params_2M = {
13+
.type = ESP_BLE_GAP_SET_EXT_ADV_PROP_NONCONN_NONSCANNABLE_UNDIRECTED,
14+
.interval_min = 0x40,
15+
.interval_max = 0x40,
16+
.channel_map = ADV_CHNL_ALL,
17+
.own_addr_type = BLE_ADDR_TYPE_RANDOM,
18+
.filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
19+
.primary_phy = ESP_BLE_GAP_PHY_1M,
20+
.max_skip = 0,
21+
.secondary_phy = ESP_BLE_GAP_PHY_2M,
22+
.sid = 1,
23+
.scan_req_notif = false,
24+
};
25+
26+
static uint8_t raw_scan_rsp_data_2m[] = {
27+
0x02, 0x01, 0x06,
28+
0x02, 0x0a, 0xeb,
29+
0x12, 0x09, 'E', 'S', 'P', '_', 'M', 'U', 'L', 'T', 'I', '_', 'A',
30+
'D', 'V', '_', '2', 'M', 0X0
31+
};
32+
33+
static esp_ble_gap_periodic_adv_params_t periodic_adv_params = {
34+
.interval_min = 0x320, // 1000 ms interval
35+
.interval_max = 0x640,
36+
.properties = 0, // Do not include TX power
37+
};
38+
39+
static uint8_t periodic_adv_raw_data[] = {
40+
0x02, 0x01, 0x06,
41+
0x02, 0x0a, 0xeb,
42+
0x03, 0x03, 0xab, 0xcd,
43+
0x11, 0x09, 'E', 'S', 'P', '_', 'P', 'E', 'R', 'I', 'O', 'D', 'I',
44+
'C', '_', 'A', 'D', 'V'
45+
};
46+
47+
48+
uint8_t addr_2m[6] = {0xc0, 0xde, 0x52, 0x00, 0x00, 0x02};
49+
50+
BLEMultiAdvertising advert(1); // max number of advertisement data
51+
52+
void setup() {
53+
Serial.begin(115200);
54+
Serial.println("Multi-Advertising...");
55+
56+
BLEDevice::init("");
57+
58+
advert.setAdvertisingParams(0, &ext_adv_params_2M);
59+
advert.setAdvertisingData(0, sizeof(raw_scan_rsp_data_2m), &raw_scan_rsp_data_2m[0]);
60+
advert.setInstanceAddress(0, addr_2m);
61+
advert.setDuration(0, 0, 0);
62+
63+
delay(100);
64+
advert.start();
65+
advert.setPeriodicAdvertisingParams(0, &periodic_adv_params);
66+
advert.setPeriodicAdvertisingData(0, sizeof(periodic_adv_raw_data), &periodic_adv_raw_data[0]);
67+
advert.startPeriodicAdvertising(0);
68+
}
69+
70+
void loop() {
71+
delay(2000);
72+
}

‎libraries/BLE/examples/BLE5_periodic_sync/.skip.esp32

Whitespace-only changes.

‎libraries/BLE/examples/BLE5_periodic_sync/.skip.esp32s2

Whitespace-only changes.
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/*
2+
BLE5 extended scan example for esp32 C3 and S3
3+
with this code it is simple to scan legacy (BLE4) compatible advertising,
4+
and BLE5 extended advertising. New coded added in BLEScan is not changing old behavior,
5+
which can be used with old esp32, but is adding functionality to use on C3/S3.
6+
With this new API advertised device wont be stored in API, it is now user responsibility
7+
8+
author: chegewara
9+
*/
10+
#ifndef CONFIG_BT_BLE_50_FEATURES_SUPPORTED
11+
#warning "Not compatible hardware"
12+
#else
13+
#include <BLEDevice.h>
14+
#include <BLEUtils.h>
15+
#include <BLEScan.h>
16+
17+
BLEScan *pBLEScan;
18+
static bool periodic_sync = false;
19+
20+
static esp_ble_gap_periodic_adv_sync_params_t periodic_adv_sync_params = {
21+
.filter_policy = 0,
22+
.sid = 0,
23+
.addr_type = BLE_ADDR_TYPE_RANDOM,
24+
.skip = 10,
25+
.sync_timeout = 1000, // timeout: 1000 * 10ms
26+
};
27+
28+
/**
29+
* @brief extend adv report parameters
30+
*/
31+
//typedef struct {
32+
// esp_ble_gap_adv_type_t event_type; /*!< extend advertising type */
33+
// uint8_t addr_type; /*!< extend advertising address type */
34+
// esp_bd_addr_t addr; /*!< extend advertising address */
35+
// esp_ble_gap_pri_phy_t primary_phy; /*!< extend advertising primary phy */
36+
// esp_ble_gap_phy_t secondly_phy; /*!< extend advertising secondary phy */
37+
// uint8_t sid; /*!< extend advertising sid */
38+
// uint8_t tx_power; /*!< extend advertising tx power */
39+
// int8_t rssi; /*!< extend advertising rssi */
40+
// uint16_t per_adv_interval; /*!< periodic advertising interval */
41+
// uint8_t dir_addr_type; /*!< direct address type */
42+
// esp_bd_addr_t dir_addr; /*!< direct address */
43+
// esp_ble_gap_ext_adv_data_status_t data_status; /*!< data type */
44+
// uint8_t adv_data_len; /*!< extend advertising data length */
45+
// uint8_t adv_data[251]; /*!< extend advertising data */
46+
//} esp_ble_gap_ext_adv_reprot_t;
47+
48+
class MyBLEExtAdvertisingCallbacks : public BLEExtAdvertisingCallbacks
49+
{
50+
void onResult(esp_ble_gap_ext_adv_reprot_t params)
51+
{
52+
uint8_t *adv_name = NULL;
53+
uint8_t adv_name_len = 0;
54+
adv_name = esp_ble_resolve_adv_data(params.adv_data, ESP_BLE_AD_TYPE_NAME_CMPL, &adv_name_len);
55+
if ((adv_name != NULL) && (memcmp(adv_name, "ESP_MULTI_ADV_2M", adv_name_len) == 0) && !periodic_sync)
56+
{
57+
periodic_sync = true;
58+
char adv_temp_name[60] = {'0'};
59+
memcpy(adv_temp_name, adv_name, adv_name_len);
60+
log_i("Start create sync with the peer device %s", adv_temp_name);
61+
periodic_adv_sync_params.sid = params.sid;
62+
// periodic_adv_sync_params.addr_type = params.addr_type;
63+
memcpy(periodic_adv_sync_params.addr, params.addr, sizeof(esp_bd_addr_t));
64+
esp_ble_gap_periodic_adv_create_sync(&periodic_adv_sync_params);
65+
}
66+
}
67+
};
68+
69+
class MyPeriodicScan : public BLEPeriodicScanCallbacks
70+
{
71+
// void onCreateSync(esp_bt_status_t status){}
72+
// void onCancelSync(esp_bt_status_t status){}
73+
// void onTerminateSync(esp_bt_status_t status){}
74+
75+
void onStop(esp_bt_status_t status)
76+
{
77+
log_i("ESP_GAP_BLE_EXT_SCAN_STOP_COMPLETE_EVT");
78+
periodic_sync = false;
79+
pBLEScan->startExtScan(0, 0); // scan duration in n * 10ms, period - repeat after n seconds (period >= duration)
80+
}
81+
82+
void onLostSync(uint16_t sync_handle)
83+
{
84+
log_i("ESP_GAP_BLE_PERIODIC_ADV_SYNC_LOST_EVT");
85+
esp_ble_gap_stop_ext_scan();
86+
}
87+
88+
void onSync(esp_ble_periodic_adv_sync_estab_param_t params)
89+
{
90+
log_i("ESP_GAP_BLE_PERIODIC_ADV_SYNC_ESTAB_EVT, status %d", params.status);
91+
// esp_log_buffer_hex("sync addr", param->periodic_adv_sync_estab.adv_addr, 6);
92+
log_i("sync handle %d sid %d perioic adv interval %d adv phy %d", params.sync_handle,
93+
params.sid,
94+
params.period_adv_interval,
95+
params.adv_phy);
96+
}
97+
98+
void onReport(esp_ble_gap_periodic_adv_report_t params)
99+
{
100+
log_i("periodic adv report, sync handle %d data status %d data len %d rssi %d", params.sync_handle,
101+
params.data_status,
102+
params.data_length,
103+
params.rssi);
104+
}
105+
};
106+
107+
void setup()
108+
{
109+
Serial.begin(115200);
110+
Serial.println("Periodic scan...");
111+
112+
BLEDevice::init("");
113+
pBLEScan = BLEDevice::getScan(); //create new scan
114+
pBLEScan->setExtendedScanCallback(new MyBLEExtAdvertisingCallbacks());
115+
pBLEScan->setExtScanParams(); // use with pre-defined/default values, overloaded function allows to pass parameters
116+
pBLEScan->setPeriodicScanCallback(new MyPeriodicScan());
117+
delay(100); // it is just for simplicity this example, to let ble stack to set extended scan params
118+
pBLEScan->startExtScan(0, 0);
119+
120+
}
121+
122+
void loop()
123+
{
124+
delay(2000);
125+
}
126+
127+
#endif // CONFIG_BT_BLE_50_FEATURES_SUPPORTED

‎libraries/BLE/src/BLEAdvertisedDevice.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,5 +124,20 @@ class BLEAdvertisedDeviceCallbacks {
124124
virtual void onResult(BLEAdvertisedDevice advertisedDevice) = 0;
125125
};
126126

127+
#ifdef CONFIG_BT_BLE_50_FEATURES_SUPPORTED
128+
class BLEExtAdvertisingCallbacks {
129+
public:
130+
virtual ~BLEExtAdvertisingCallbacks() {}
131+
/**
132+
* @brief Called when a new scan result is detected.
133+
*
134+
* As we are scanning, we will find new devices. When found, this call back is invoked with a reference to the
135+
* device that was found. During any individual scan, a device will only be detected one time.
136+
*/
137+
virtual void onResult(esp_ble_gap_ext_adv_reprot_t report) = 0;
138+
};
139+
#endif // CONFIG_BT_BLE_50_FEATURES_SUPPORTED
140+
141+
127142
#endif /* CONFIG_BLUEDROID_ENABLED */
128143
#endif /* COMPONENTS_CPP_UTILS_BLEADVERTISEDDEVICE_H_ */

‎libraries/BLE/src/BLEAdvertising.cpp

Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,5 +528,242 @@ void BLEAdvertising::handleGAPEvent(
528528
}
529529
}
530530

531+
#ifdef CONFIG_BT_BLE_50_FEATURES_SUPPORTED
532+
533+
/**
534+
* @brief Creator
535+
*
536+
* @param[in] instance : number of multi advertising instances
537+
*
538+
*
539+
*/
540+
BLEMultiAdvertising::BLEMultiAdvertising(uint8_t num)
541+
{
542+
params_arrays = (esp_ble_gap_ext_adv_params_t*)calloc(num, sizeof(esp_ble_gap_ext_adv_params_t));
543+
ext_adv = (esp_ble_gap_ext_adv_t*)calloc(num, sizeof(esp_ble_gap_ext_adv_t));
544+
count = num;
545+
}
546+
547+
/**
548+
* @brief This function is used by the Host to set the advertising parameters.
549+
*
550+
* @param[in] instance : identifies the advertising set whose parameters are being configured.
551+
* @param[in] params : advertising parameters
552+
*
553+
* @return - true : success
554+
* - false : failed
555+
*
556+
*/
557+
bool BLEMultiAdvertising::setAdvertisingParams(uint8_t instance, const esp_ble_gap_ext_adv_params_t* params)
558+
{
559+
if (params->type == ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_IND && params->primary_phy == ESP_BLE_GAP_PHY_2M) return false;
560+
esp_err_t rc;
561+
rc = esp_ble_gap_ext_adv_set_params(instance, params);
562+
563+
return ESP_OK == rc;
564+
}
565+
566+
/**
567+
* @brief This function is used to set the data used in advertising PDUs that have a data field
568+
*
569+
* @param[in] instance : identifies the advertising set whose data are being configured
570+
* @param[in] length : data length
571+
* @param[in] data : data information
572+
*
573+
* @return - true : success
574+
* - false : failed
575+
*
576+
*/
577+
bool BLEMultiAdvertising::setAdvertisingData(uint8_t instance, uint16_t length, const uint8_t* data)
578+
{
579+
esp_err_t rc;
580+
rc = esp_ble_gap_config_ext_adv_data_raw(instance, length, data);
581+
if (rc) log_e("set advertising data err: %d", rc);
582+
583+
return ESP_OK == rc;
584+
}
585+
586+
bool BLEMultiAdvertising::setScanRspData(uint8_t instance, uint16_t length, const uint8_t* data)
587+
{
588+
esp_err_t rc;
589+
rc = esp_ble_gap_config_ext_scan_rsp_data_raw(instance, length, data);
590+
if (rc) log_e("set scan resp data err: %d", rc);
591+
592+
return ESP_OK == rc;
593+
}
594+
595+
/**
596+
* @brief This function is used to request the Controller to disable one or more
597+
* advertising sets using the advertising sets identified by the instance parameter.
598+
*
599+
* @return - true : success
600+
* - false : failed
601+
*
602+
*/
603+
bool BLEMultiAdvertising::start()
604+
{
605+
return start(count, 0);
606+
}
607+
608+
/**
609+
* @brief This function is used to request the Controller to disable one or more
610+
* advertising sets using the advertising sets identified by the instance parameter.
611+
*
612+
* @param[in] num : Number of advertising sets to enable or disable
613+
* @param[in] from : first sxt adv set to use
614+
*
615+
* @return - true : success
616+
* - false : failed
617+
*
618+
*/
619+
bool BLEMultiAdvertising::start(uint8_t num, uint8_t from)
620+
{
621+
if (num > count || from >= count) return false;
622+
623+
esp_err_t rc;
624+
rc = esp_ble_gap_ext_adv_start(num, &ext_adv[from]);
625+
if (rc) log_e("start extended advertising err: %d", rc);
626+
627+
return ESP_OK == rc;
628+
}
629+
630+
/**
631+
* @brief This function is used to request the Controller to disable one or more
632+
* advertising sets using the advertising sets identified by the instance parameter.
633+
*
634+
* @param[in] num_adv : Number of advertising sets to enable or disable
635+
* @param[in] ext_adv_inst : ext adv instance
636+
*
637+
* @return - ESP_OK : success
638+
* - other : failed
639+
*
640+
*/
641+
bool BLEMultiAdvertising::stop(uint8_t num_adv, const uint8_t* ext_adv_inst)
642+
{
643+
esp_err_t rc;
644+
rc = esp_ble_gap_ext_adv_stop(num_adv, ext_adv_inst);
645+
if (rc) log_e("stop extended advertising err: %d", rc);
646+
647+
return ESP_OK == rc;
648+
}
649+
650+
/**
651+
* @brief This function is used to remove an advertising set from the Controller.
652+
*
653+
* @param[in] instance : Used to identify an advertising set
654+
*
655+
* @return - ESP_OK : success
656+
* - other : failed
657+
*
658+
*/
659+
bool BLEMultiAdvertising::remove(uint8_t instance)
660+
{
661+
esp_err_t rc;
662+
rc = esp_ble_gap_ext_adv_set_remove(instance);
663+
if (rc) log_e("remove extended advertising err: %d", rc);
664+
665+
return ESP_OK == rc;
666+
}
667+
668+
/**
669+
* @brief This function is used to remove all existing advertising sets from the Controller.
670+
*
671+
*
672+
* @return - ESP_OK : success
673+
* - other : failed
674+
*
675+
*/
676+
bool BLEMultiAdvertising::clear()
677+
{
678+
esp_err_t rc;
679+
rc = esp_ble_gap_ext_adv_set_clear();
680+
if (rc) log_e("clear extended advertising err: %d", rc);
681+
682+
return ESP_OK == rc;
683+
}
684+
685+
/**
686+
* @brief This function is used by the Host to set the random device address specified by the Random_Address parameter.
687+
*
688+
* @param[in] instance : Used to identify an advertising set
689+
* @param[in] addr_legacy : Random Device Address
690+
*
691+
* @return - true : success
692+
* - false : failed
693+
*
694+
*/
695+
bool BLEMultiAdvertising::setInstanceAddress(uint8_t instance, uint8_t* addr_legacy)
696+
{
697+
esp_err_t rc;
698+
rc = esp_ble_gap_ext_adv_set_rand_addr(instance, addr_legacy);
699+
if (rc) log_e("set random address err: %d", rc);
700+
701+
return ESP_OK == rc;
702+
}
703+
704+
/**
705+
* @brief This function is used by the Host to set the parameters for periodic advertising.
706+
*
707+
* @param[in] instance : identifies the advertising set whose periodic advertising parameters are being configured.
708+
* @param[in] params : periodic adv parameters
709+
*
710+
* @return - true : success
711+
* - false : failed
712+
*
713+
*/
714+
bool BLEMultiAdvertising::setPeriodicAdvertisingParams(uint8_t instance, const esp_ble_gap_periodic_adv_params_t* params)
715+
{
716+
esp_err_t rc;
717+
rc = esp_ble_gap_periodic_adv_set_params(instance, params);
718+
if (rc) log_e("set periodic advertising params err: %d", rc);
719+
720+
return ESP_OK == rc;
721+
}
722+
723+
/**
724+
* @brief This function is used to set the data used in periodic advertising PDUs.
725+
*
726+
* @param[in] instance : identifies the advertising set whose periodic advertising parameters are being configured.
727+
* @param[in] length : the length of periodic data
728+
* @param[in] data : periodic data information
729+
*
730+
* @return - true : success
731+
* - false : failed
732+
*
733+
*/
734+
bool BLEMultiAdvertising::setPeriodicAdvertisingData(uint8_t instance, uint16_t length, const uint8_t* data)
735+
{
736+
esp_err_t rc;
737+
rc = esp_ble_gap_config_periodic_adv_data_raw(instance, length, data);
738+
if (rc) log_e("set periodic advertising raw data err: %d", rc);
739+
740+
return ESP_OK == rc;
741+
}
742+
743+
/**
744+
* @brief This function is used to request the Controller to enable the periodic advertising for the advertising set specified
745+
*
746+
* @param[in] instance : Used to identify an advertising set
747+
*
748+
* @return - true : success
749+
* - false : failed
750+
*
751+
*/
752+
bool BLEMultiAdvertising::startPeriodicAdvertising(uint8_t instance)
753+
{
754+
esp_err_t rc;
755+
rc = esp_ble_gap_periodic_adv_start(instance);
756+
if (rc) log_e("start periodic advertising err: %d", rc);
757+
758+
return ESP_OK == rc;
759+
}
760+
761+
void BLEMultiAdvertising::setDuration(uint8_t instance, int duration, int max_events)
762+
{
763+
ext_adv[instance] = { instance, duration, max_events };
764+
}
765+
766+
#endif // CONFIG_BT_BLE_50_FEATURES_SUPPORTED
767+
531768

532769
#endif /* CONFIG_BLUEDROID_ENABLED */

‎libraries/BLE/src/BLEAdvertising.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,5 +78,36 @@ class BLEAdvertising {
7878
bool m_scanResp = true;
7979

8080
};
81+
82+
#ifdef CONFIG_BT_BLE_50_FEATURES_SUPPORTED
83+
84+
class BLEMultiAdvertising
85+
{
86+
private:
87+
esp_ble_gap_ext_adv_params_t* params_arrays;
88+
esp_ble_gap_ext_adv_t* ext_adv;
89+
uint8_t count;
90+
91+
public:
92+
BLEMultiAdvertising(uint8_t num = 1);
93+
~BLEMultiAdvertising() {}
94+
95+
bool setAdvertisingParams(uint8_t instance, const esp_ble_gap_ext_adv_params_t* params);
96+
bool setAdvertisingData(uint8_t instance, uint16_t length, const uint8_t* data);
97+
bool setScanRspData(uint8_t instance, uint16_t length, const uint8_t* data);
98+
bool start();
99+
bool start(uint8_t num, uint8_t from);
100+
void setDuration(uint8_t instance, int duration = 0, int max_events = 0);
101+
bool setInstanceAddress(uint8_t instance, esp_bd_addr_t rand_addr);
102+
bool stop(uint8_t num_adv, const uint8_t* ext_adv_inst);
103+
bool remove(uint8_t instance);
104+
bool clear();
105+
bool setPeriodicAdvertisingParams(uint8_t instance, const esp_ble_gap_periodic_adv_params_t* params);
106+
bool setPeriodicAdvertisingData(uint8_t instance, uint16_t length, const uint8_t* data);
107+
bool startPeriodicAdvertising(uint8_t instance);
108+
};
109+
110+
#endif // CONFIG_BT_BLE_50_FEATURES_SUPPORTED
111+
81112
#endif /* CONFIG_BLUEDROID_ENABLED */
82113
#endif /* COMPONENTS_CPP_UTILS_BLEADVERTISING_H_ */

‎libraries/BLE/src/BLEScan.cpp

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
*
44
* Created on: Jul 1, 2017
55
* Author: kolban
6+
*
7+
* Update: April, 2021
8+
* add BLE5 support
69
*/
710
#include "sdkconfig.h"
811
#if defined(CONFIG_BLUEDROID_ENABLED)
@@ -142,6 +145,98 @@ void BLEScan::handleGAPEvent(
142145

143146
break;
144147
} // ESP_GAP_BLE_SCAN_RESULT_EVT
148+
#ifdef CONFIG_BT_BLE_50_FEATURES_SUPPORTED
149+
case ESP_GAP_BLE_EXT_ADV_REPORT_EVT: {
150+
if (param->ext_adv_report.params.event_type & ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY) {
151+
log_v("legacy adv, adv type 0x%x data len %d", param->ext_adv_report.params.event_type, param->ext_adv_report.params.adv_data_len);
152+
}
153+
else {
154+
log_v("extend adv, adv type 0x%x data len %d, data status: %d", param->ext_adv_report.params.event_type, param->ext_adv_report.params.adv_data_len, param->ext_adv_report.params.data_status);
155+
}
156+
157+
if (m_pExtendedScanCb != nullptr)
158+
{
159+
m_pExtendedScanCb->onResult(param->ext_adv_report.params);
160+
}
161+
162+
break;
163+
}
164+
165+
case ESP_GAP_BLE_SET_EXT_SCAN_PARAMS_COMPLETE_EVT: {
166+
if (param->set_ext_scan_params.status != ESP_BT_STATUS_SUCCESS) {
167+
log_e("extend scan parameters set failed, error status = %x", param->set_ext_scan_params.status);
168+
break;
169+
}
170+
log_v("extend scan params set successfully");
171+
break;
172+
}
173+
174+
case ESP_GAP_BLE_EXT_SCAN_START_COMPLETE_EVT:
175+
if (param->ext_scan_start.status != ESP_BT_STATUS_SUCCESS) {
176+
log_e("scan start failed, error status = %x", param->scan_start_cmpl.status);
177+
break;
178+
}
179+
log_v("Scan start success");
180+
break;
181+
182+
case ESP_GAP_BLE_EXT_SCAN_STOP_COMPLETE_EVT:
183+
if (m_pPeriodicScanCb != nullptr)
184+
{
185+
m_pPeriodicScanCb->onStop(param->ext_scan_stop.status);
186+
}
187+
188+
if (param->ext_scan_stop.status != ESP_BT_STATUS_SUCCESS){
189+
log_e("extend Scan stop failed, error status = %x", param->ext_scan_stop.status);
190+
break;
191+
}
192+
log_v("Stop extend scan successfully");
193+
break;
194+
195+
case ESP_GAP_BLE_PERIODIC_ADV_CREATE_SYNC_COMPLETE_EVT:
196+
if (m_pPeriodicScanCb != nullptr)
197+
{
198+
m_pPeriodicScanCb->onCreateSync(param->period_adv_create_sync.status);
199+
}
200+
201+
log_v("ESP_GAP_BLE_PERIODIC_ADV_CREATE_SYNC_COMPLETE_EVT, status %d", param->period_adv_create_sync.status);
202+
break;
203+
case ESP_GAP_BLE_PERIODIC_ADV_SYNC_CANCEL_COMPLETE_EVT:
204+
if (m_pPeriodicScanCb != nullptr)
205+
{
206+
m_pPeriodicScanCb->onCancelSync(param->period_adv_sync_cancel.status);
207+
}
208+
log_v("ESP_GAP_BLE_PERIODIC_ADV_SYNC_CANCEL_COMPLETE_EVT, status %d", param->period_adv_sync_cancel.status);
209+
break;
210+
case ESP_GAP_BLE_PERIODIC_ADV_SYNC_TERMINATE_COMPLETE_EVT:
211+
if (m_pPeriodicScanCb != nullptr)
212+
{
213+
m_pPeriodicScanCb->onTerminateSync(param->period_adv_sync_term.status);
214+
}
215+
log_v("ESP_GAP_BLE_PERIODIC_ADV_SYNC_TERMINATE_COMPLETE_EVT, status %d", param->period_adv_sync_term.status);
216+
break;
217+
case ESP_GAP_BLE_PERIODIC_ADV_SYNC_LOST_EVT:
218+
if (m_pPeriodicScanCb != nullptr)
219+
{
220+
m_pPeriodicScanCb->onLostSync(param->periodic_adv_sync_lost.sync_handle);
221+
}
222+
log_v("ESP_GAP_BLE_PERIODIC_ADV_SYNC_LOST_EVT, sync handle %d", param->periodic_adv_sync_lost.sync_handle);
223+
break;
224+
case ESP_GAP_BLE_PERIODIC_ADV_SYNC_ESTAB_EVT:
225+
if (m_pPeriodicScanCb != nullptr)
226+
{
227+
m_pPeriodicScanCb->onSync(*(esp_ble_periodic_adv_sync_estab_param_t*)&param->periodic_adv_sync_estab);
228+
}
229+
log_v("ESP_GAP_BLE_PERIODIC_ADV_SYNC_ESTAB_EVT, status %d", param->periodic_adv_sync_estab.status);
230+
break;
231+
232+
case ESP_GAP_BLE_PERIODIC_ADV_REPORT_EVT:
233+
if (m_pPeriodicScanCb != nullptr)
234+
{
235+
m_pPeriodicScanCb->onReport(param->period_adv_report.params);
236+
}
237+
break;
238+
239+
#endif // CONFIG_BT_BLE_50_FEATURES_SUPPORTED
145240

146241
default: {
147242
break;
@@ -177,6 +272,89 @@ void BLEScan::setAdvertisedDeviceCallbacks(BLEAdvertisedDeviceCallbacks* pAdvert
177272
m_shouldParse = shouldParse;
178273
} // setAdvertisedDeviceCallbacks
179274

275+
#ifdef CONFIG_BT_BLE_50_FEATURES_SUPPORTED
276+
277+
void BLEScan::setExtendedScanCallback(BLEExtAdvertisingCallbacks* cb)
278+
{
279+
m_pExtendedScanCb = cb;
280+
}
281+
282+
/**
283+
* @brief This function is used to set the extended scan parameters to be used on the advertising channels.
284+
*
285+
*
286+
* @return - ESP_OK : success
287+
* - other : failed
288+
*
289+
*/
290+
esp_err_t BLEScan::setExtScanParams()
291+
{
292+
esp_ble_ext_scan_params_t ext_scan_params = {
293+
.own_addr_type = BLE_ADDR_TYPE_PUBLIC,
294+
.filter_policy = BLE_SCAN_FILTER_ALLOW_ALL,
295+
.scan_duplicate = BLE_SCAN_DUPLICATE_DISABLE,
296+
.cfg_mask = ESP_BLE_GAP_EXT_SCAN_CFG_UNCODE_MASK | ESP_BLE_GAP_EXT_SCAN_CFG_CODE_MASK,
297+
.uncoded_cfg = {BLE_SCAN_TYPE_ACTIVE, 40, 40},
298+
.coded_cfg = {BLE_SCAN_TYPE_ACTIVE, 40, 40},
299+
};
300+
301+
esp_err_t rc = esp_ble_gap_set_ext_scan_params(&ext_scan_params);
302+
if (rc) {
303+
log_e("set extend scan params error, error code = %x", rc);
304+
}
305+
return rc;
306+
}
307+
308+
/**
309+
* @brief This function is used to set the extended scan parameters to be used on the advertising channels.
310+
*
311+
* @param[in] params : scan parameters
312+
*
313+
* @return - ESP_OK : success
314+
* - other : failed
315+
*
316+
*/
317+
esp_err_t BLEScan::setExtScanParams(esp_ble_ext_scan_params_t* ext_scan_params)
318+
{
319+
esp_err_t rc = esp_ble_gap_set_ext_scan_params(ext_scan_params);
320+
if (rc) {
321+
log_e("set extend scan params error, error code = %x", rc);
322+
}
323+
return rc;
324+
}
325+
326+
/**
327+
* @brief This function is used to enable scanning.
328+
*
329+
* @param[in] duration : Scan duration
330+
* @param[in] period : Time interval from when the Controller started its last Scan Duration until it begins the subsequent Scan Duration.
331+
*
332+
* @return - ESP_OK : success
333+
* - other : failed
334+
*
335+
*/
336+
esp_err_t BLEScan::startExtScan(uint32_t duration, uint16_t period)
337+
{
338+
esp_err_t rc = esp_ble_gap_start_ext_scan(duration, period);
339+
if(rc) log_e("extended scan start failed: %d", rc);
340+
return rc;
341+
}
342+
343+
344+
esp_err_t BLEScan::stopExtScan()
345+
{
346+
esp_err_t rc;
347+
rc = esp_ble_gap_stop_ext_scan();
348+
349+
return rc;
350+
}
351+
352+
void BLEScan::setPeriodicScanCallback(BLEPeriodicScanCallbacks* cb)
353+
{
354+
m_pPeriodicScanCb = cb;
355+
}
356+
357+
#endif // CONFIG_BT_BLE_50_FEATURES_SUPPORTED
180358
/**
181359
* @brief Set the interval to scan.
182360
* @param [in] The interval in msecs.

‎libraries/BLE/src/BLEScan.h

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,21 @@
1919

2020
class BLEAdvertisedDevice;
2121
class BLEAdvertisedDeviceCallbacks;
22+
class BLEExtAdvertisingCallbacks;
2223
class BLEClient;
2324
class BLEScan;
25+
class BLEPeriodicScanCallbacks;
2426

27+
struct esp_ble_periodic_adv_sync_estab_param_t {
28+
uint8_t status; /*!< periodic advertising sync status */
29+
uint16_t sync_handle; /*!< periodic advertising sync handle */
30+
uint8_t sid; /*!< periodic advertising sid */
31+
esp_ble_addr_type_t adv_addr_type; /*!< periodic advertising address type */
32+
esp_bd_addr_t adv_addr; /*!< periodic advertising address */
33+
esp_ble_gap_phy_t adv_phy; /*!< periodic advertising phy type */
34+
uint16_t period_adv_interval; /*!< periodic advertising interval */
35+
uint8_t adv_clk_accuracy; /*!< periodic advertising clock accuracy */
36+
};
2537

2638
/**
2739
* @brief The result of having performed a scan.
@@ -62,13 +74,25 @@ class BLEScan {
6274
BLEScanResults getResults();
6375
void clearResults();
6476

77+
#ifdef CONFIG_BT_BLE_50_FEATURES_SUPPORTED
78+
void setExtendedScanCallback(BLEExtAdvertisingCallbacks* cb);
79+
void setPeriodicScanCallback(BLEPeriodicScanCallbacks* cb);
80+
81+
esp_err_t stopExtScan();
82+
esp_err_t setExtScanParams();
83+
esp_err_t setExtScanParams(esp_ble_ext_scan_params_t* ext_scan_params);
84+
esp_err_t startExtScan(uint32_t duration, uint16_t period);
85+
private:
86+
BLEExtAdvertisingCallbacks* m_pExtendedScanCb = nullptr;
87+
BLEPeriodicScanCallbacks* m_pPeriodicScanCb = nullptr;
88+
#endif // CONFIG_BT_BLE_50_FEATURES_SUPPORTED
89+
6590
private:
6691
BLEScan(); // One doesn't create a new instance instead one asks the BLEDevice for the singleton.
6792
friend class BLEDevice;
6893
void handleGAPEvent(
6994
esp_gap_ble_cb_event_t event,
7095
esp_ble_gap_cb_param_t* param);
71-
void parseAdvertisement(BLEClient* pRemoteDevice, uint8_t *payload);
7296

7397

7498
esp_ble_scan_params_t m_scan_params;
@@ -81,5 +105,18 @@ class BLEScan {
81105
void (*m_scanCompleteCB)(BLEScanResults scanResults);
82106
}; // BLEScan
83107

108+
class BLEPeriodicScanCallbacks {
109+
public:
110+
virtual ~BLEPeriodicScanCallbacks() {}
111+
112+
virtual void onCreateSync(esp_bt_status_t status) {}
113+
virtual void onCancelSync(esp_bt_status_t status) {}
114+
virtual void onTerminateSync(esp_bt_status_t status) {}
115+
virtual void onLostSync(uint16_t sync_handle) {}
116+
virtual void onSync(esp_ble_periodic_adv_sync_estab_param_t) {}
117+
virtual void onReport(esp_ble_gap_periodic_adv_report_t params) {}
118+
virtual void onStop(esp_bt_status_t status) {}
119+
};
120+
84121
#endif /* CONFIG_BLUEDROID_ENABLED */
85122
#endif /* COMPONENTS_CPP_UTILS_BLESCAN_H_ */

0 commit comments

Comments
 (0)
Please sign in to comment.