23
23
#include < esp_err.h>
24
24
#include " BLEUtils.h"
25
25
#include " GeneralUtils.h"
26
+ #include " string.h"
27
+ #include " mbedtls/md.h"
28
+ #include " mbedtls/entropy.h"
29
+ #include " mbedtls/ctr_drbg.h"
30
+
31
+
32
+ #define BLOCK_SIZE 64
33
+ #define HMAC MBEDTLS_MD_SHA256
26
34
27
35
#ifdef ARDUINO_ARCH_ESP32
28
36
#include " esp32-hal-log.h"
29
37
#endif
30
-
38
+ static bool is_advertising = false ;
31
39
static const char * LOG_TAG = " BLEAdvertising" ;
32
40
33
-
34
41
/* *
35
42
* @brief Construct a default advertising object.
36
43
*
37
44
*/
38
45
BLEAdvertising::BLEAdvertising () {
39
46
m_advData.set_scan_rsp = false ;
40
47
m_advData.include_name = true ;
41
- m_advData.include_txpower = true ;
48
+ m_advData.include_txpower = false ;
42
49
m_advData.min_interval = 0x20 ;
43
50
m_advData.max_interval = 0x40 ;
44
51
m_advData.appearance = 0x00 ;
@@ -61,6 +68,65 @@ BLEAdvertising::BLEAdvertising() {
61
68
m_customScanResponseData = false ; // No custom scan response data
62
69
} // BLEAdvertising
63
70
71
+ void BLEAdvertising::setPrivateAddress (esp_ble_addr_type_t type) {
72
+ esp_bd_addr_t addr;
73
+ m_advParams.own_addr_type = type;
74
+
75
+ if (type == BLE_ADDR_TYPE_RPA_PUBLIC) {
76
+ esp_ble_gap_config_local_privacy (true );
77
+ return ;
78
+ }
79
+ else {
80
+ mbedtls_ctr_drbg_context ctr_drbg;
81
+ mbedtls_entropy_context entropy;
82
+ mbedtls_md_context_t ctx;
83
+
84
+ char pers[] = " aes generate key" ;
85
+ int ret;
86
+ unsigned char key[BLOCK_SIZE] = {0 };
87
+ const char inp[] = " random static address" ;
88
+ unsigned char outp[BLOCK_SIZE/2 ];
89
+
90
+ mbedtls_entropy_init ( &entropy );
91
+ mbedtls_ctr_drbg_init ( &ctr_drbg );
92
+
93
+ if ( ( ret = mbedtls_ctr_drbg_seed ( &ctr_drbg, mbedtls_entropy_func, &entropy,
94
+ (unsigned char *) pers, strlen ( pers ) ) ) != 0 )
95
+ {
96
+ printf ( " failed\n ! mbedtls_ctr_drbg_init returned -0x%04x\n " , -ret );
97
+ goto exit;
98
+ }
99
+
100
+ if ( ( ret = mbedtls_ctr_drbg_random ( &ctr_drbg, key, BLOCK_SIZE ) ) != 0 )
101
+ {
102
+ printf ( " failed\n ! mbedtls_ctr_drbg_random returned -0x%04x\n " , -ret );
103
+ goto exit;
104
+ }
105
+
106
+ mbedtls_md_init (&ctx);
107
+ mbedtls_md_setup (&ctx, mbedtls_md_info_from_type (HMAC), true );
108
+ mbedtls_md_hmac_starts (&ctx, (const unsigned char *)key, BLOCK_SIZE);
109
+ mbedtls_md_hmac_update (&ctx, (const unsigned char *)inp, strlen (inp));
110
+ mbedtls_md_hmac_finish (&ctx, outp);
111
+ mbedtls_md_free (&ctx);
112
+ ESP_LOG_BUFFER_HEX (" random key" , key, BLOCK_SIZE);
113
+ ESP_LOG_BUFFER_HEX (" HASH step 2" , outp, BLOCK_SIZE/2 );
114
+
115
+ memcpy (addr, outp, 6 );
116
+ }
117
+ if (type == BLE_ADDR_TYPE_RANDOM) {
118
+ addr[0 ] &= 0x3F ; // <--- Format of non-resolvable private address 00xx xxxx
119
+ }
120
+ else {
121
+ addr[0 ] |= 0xC0 ; // <--- Format of static address 11xx xxxx
122
+ }
123
+
124
+ esp_ble_gap_set_rand_addr (addr);
125
+ ESP_LOG_BUFFER_HEX (" random address" , addr, 6 );
126
+ exit:
127
+ return ;
128
+ }
129
+
64
130
65
131
/* *
66
132
* @brief Add a service uuid to exposed list of services.
@@ -107,7 +173,7 @@ void BLEAdvertising::setMaxInterval(uint16_t maxinterval) {
107
173
* @param [in] scanRequestWhitelistOnly If true, only allow scan requests from those on the white list.
108
174
* @param [in] connectWhitelistOnly If true, only allow connections from those on the white list.
109
175
*/
110
- void BLEAdvertising::setScanFilter (bool scanRequestWhitelistOnly, bool connectWhitelistOnly) {
176
+ void BLEAdvertising::setScanFilter (bool scanRequestWhitelistOnly, bool connectWhitelistOnly) {
111
177
ESP_LOGD (LOG_TAG, " >> setScanFilter: scanRequestWhitelistOnly: %d, connectWhitelistOnly: %d" , scanRequestWhitelistOnly, connectWhitelistOnly);
112
178
if (!scanRequestWhitelistOnly && !connectWhitelistOnly) {
113
179
m_advParams.adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY;
@@ -173,20 +239,21 @@ void BLEAdvertising::setScanResponseData(BLEAdvertisementData& advertisementData
173
239
void BLEAdvertising::start () {
174
240
ESP_LOGD (LOG_TAG, " >> start: customAdvData: %d, customScanResponseData: %d" , m_customAdvData, m_customScanResponseData);
175
241
242
+
176
243
// We have a vector of service UUIDs that we wish to advertise. In order to use the
177
244
// ESP-IDF framework, these must be supplied in a contiguous array of their 128bit (16 byte)
178
245
// representations. If we have 1 or more services to advertise then we allocate enough
179
246
// storage to host them and then copy them in one at a time into the contiguous storage.
180
247
int numServices = m_serviceUUIDs.size ();
181
248
if (numServices > 0 ) {
182
- m_advData.service_uuid_len = 16 * numServices;
183
- m_advData.p_service_uuid = new uint8_t [m_advData.service_uuid_len ];
249
+ m_advData.service_uuid_len = 16 * numServices;
250
+ m_advData.p_service_uuid = new uint8_t [m_advData.service_uuid_len ];
184
251
uint8_t * p = m_advData.p_service_uuid ;
185
- for (int i = 0 ; i < numServices; i++) {
252
+ for (int i= 0 ; i< numServices; i++) {
186
253
ESP_LOGD (LOG_TAG, " - advertising service: %s" , m_serviceUUIDs[i].toString ().c_str ());
187
254
BLEUUID serviceUUID128 = m_serviceUUIDs[i].to128 ();
188
255
memcpy (p, serviceUUID128.getNative ()->uuid .uuid128 , 16 );
189
- p += 16 ;
256
+ p+= 16 ;
190
257
}
191
258
} else {
192
259
m_advData.service_uuid_len = 0 ;
@@ -195,36 +262,45 @@ void BLEAdvertising::start() {
195
262
196
263
esp_err_t errRc;
197
264
198
- if (!m_customAdvData) {
265
+ if (!is_advertising){
266
+
267
+ // m_semaphoreSetAdv.take("config_adv");
268
+ if (m_customAdvData == false ) {
199
269
// Set the configuration for advertising.
200
- m_advData.set_scan_rsp = false ;
201
- errRc = ::esp_ble_gap_config_adv_data (&m_advData);
202
- if (errRc != ESP_OK) {
203
- ESP_LOGE (LOG_TAG, " << esp_ble_gap_config_adv_data: rc=%d %s" , errRc, GeneralUtils::errorToString (errRc));
204
- return ;
270
+ m_advData.set_scan_rsp = false ;
271
+ errRc = ::esp_ble_gap_config_adv_data (&m_advData);
272
+ if (errRc != ESP_OK) {
273
+ ESP_LOGE (LOG_TAG, " << esp_ble_gap_config_adv_data: rc=%d %s" , errRc, GeneralUtils::errorToString (errRc));
274
+ // m_semaphoreSetAdv.give();
275
+ return ;
276
+ }
205
277
}
206
- }
207
278
208
- if (!m_customScanResponseData) {
209
- m_advData.set_scan_rsp = true ;
210
- errRc = ::esp_ble_gap_config_adv_data (&m_advData);
211
- if (errRc != ESP_OK) {
212
- ESP_LOGE (LOG_TAG, " << esp_ble_gap_config_adv_data (Scan response): rc=%d %s" , errRc, GeneralUtils::errorToString (errRc));
213
- return ;
279
+ // m_semaphoreSetAdv.take("config_rsp");
280
+ if (m_customScanResponseData == false ) {
281
+ m_advData.set_scan_rsp = true ;
282
+ errRc = ::esp_ble_gap_config_adv_data (&m_advData);
283
+ if (errRc != ESP_OK) {
284
+ ESP_LOGE (LOG_TAG, " << esp_ble_gap_config_adv_data (Scan response): rc=%d %s" , errRc, GeneralUtils::errorToString (errRc));
285
+ // m_semaphoreSetAdv.give();
286
+ return ;
287
+ }
214
288
}
215
289
}
216
-
217
290
// If we had services to advertise then we previously allocated some storage for them.
218
291
// Here we release that storage.
219
292
if (m_advData.service_uuid_len > 0 ) {
220
293
delete[] m_advData.p_service_uuid ;
221
294
m_advData.p_service_uuid = nullptr ;
222
295
}
296
+ is_advertising = true ;
223
297
298
+ // m_semaphoreSetAdv.take("start");
224
299
// Start advertising.
225
300
errRc = ::esp_ble_gap_start_advertising (&m_advParams);
226
301
if (errRc != ESP_OK) {
227
302
ESP_LOGE (LOG_TAG, " << esp_ble_gap_start_advertising: rc=%d %s" , errRc, GeneralUtils::errorToString (errRc));
303
+ // m_semaphoreSetAdv.give();
228
304
return ;
229
305
}
230
306
ESP_LOGD (LOG_TAG, " << start" );
@@ -238,6 +314,7 @@ void BLEAdvertising::start() {
238
314
*/
239
315
void BLEAdvertising::stop () {
240
316
ESP_LOGD (LOG_TAG, " >> stop" );
317
+ // m_semaphoreSetAdv.take("stop");
241
318
esp_err_t errRc = ::esp_ble_gap_stop_advertising ();
242
319
if (errRc != ESP_OK) {
243
320
ESP_LOGE (LOG_TAG, " esp_ble_gap_stop_advertising: rc=%d %s" , errRc, GeneralUtils::errorToString (errRc));
@@ -269,7 +346,8 @@ void BLEAdvertisementData::setAppearance(uint16_t appearance) {
269
346
char cdata[2 ];
270
347
cdata[0 ] = 3 ;
271
348
cdata[1 ] = ESP_BLE_AD_TYPE_APPEARANCE; // 0x19
272
- addData (std::string (cdata, 2 ) + std::string ((char *) &appearance, 2 ));
349
+ addData (std::string (cdata, 2 ) + std::string ((char *)&appearance,2 ));
350
+ esp_ble_gap_config_local_icon (appearance);
273
351
} // setAppearance
274
352
275
353
@@ -279,28 +357,28 @@ void BLEAdvertisementData::setAppearance(uint16_t appearance) {
279
357
*/
280
358
void BLEAdvertisementData::setCompleteServices (BLEUUID uuid) {
281
359
char cdata[2 ];
282
- switch (uuid.bitSize ()) {
360
+ switch (uuid.bitSize ()) {
283
361
case 16 : {
284
362
// [Len] [0x02] [LL] [HH]
285
363
cdata[0 ] = 3 ;
286
364
cdata[1 ] = ESP_BLE_AD_TYPE_16SRV_CMPL; // 0x03
287
- addData (std::string (cdata, 2 ) + std::string ((char *) &uuid.getNative ()->uuid .uuid16 , 2 ));
365
+ addData (std::string (cdata, 2 ) + std::string ((char *) &uuid.getNative ()->uuid .uuid16 ,2 ));
288
366
break ;
289
367
}
290
368
291
369
case 32 : {
292
370
// [Len] [0x04] [LL] [LL] [HH] [HH]
293
371
cdata[0 ] = 5 ;
294
372
cdata[1 ] = ESP_BLE_AD_TYPE_32SRV_CMPL; // 0x05
295
- addData (std::string (cdata, 2 ) + std::string ((char *) &uuid.getNative ()->uuid .uuid32 , 4 ));
373
+ addData (std::string (cdata, 2 ) + std::string ((char *) &uuid.getNative ()->uuid .uuid32 ,4 ));
296
374
break ;
297
375
}
298
376
299
377
case 128 : {
300
378
// [Len] [0x04] [0] [1] ... [15]
301
379
cdata[0 ] = 17 ;
302
380
cdata[1 ] = ESP_BLE_AD_TYPE_128SRV_CMPL; // 0x07
303
- addData (std::string (cdata, 2 ) + std::string ((char *) uuid.getNative ()->uuid .uuid128 , 16 ));
381
+ addData (std::string (cdata, 2 ) + std::string ((char *) uuid.getNative ()->uuid .uuid128 ,16 ));
304
382
break ;
305
383
}
306
384
@@ -340,7 +418,7 @@ void BLEAdvertisementData::setManufacturerData(std::string data) {
340
418
char cdata[2 ];
341
419
cdata[0 ] = data.length () + 1 ;
342
420
cdata[1 ] = ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE; // 0xff
343
- addData (std::string (cdata, 2 ) + data);
421
+ addData (std::string (cdata, 2 ) + data);
344
422
ESP_LOGD (" BLEAdvertisementData" , " << setManufacturerData" );
345
423
} // setManufacturerData
346
424
@@ -354,7 +432,7 @@ void BLEAdvertisementData::setName(std::string name) {
354
432
char cdata[2 ];
355
433
cdata[0 ] = name.length () + 1 ;
356
434
cdata[1 ] = ESP_BLE_AD_TYPE_NAME_CMPL; // 0x09
357
- addData (std::string (cdata, 2 ) + name);
435
+ addData (std::string (cdata, 2 ) + name);
358
436
ESP_LOGD (" BLEAdvertisementData" , " << setName" );
359
437
} // setName
360
438
@@ -365,28 +443,28 @@ void BLEAdvertisementData::setName(std::string name) {
365
443
*/
366
444
void BLEAdvertisementData::setPartialServices (BLEUUID uuid) {
367
445
char cdata[2 ];
368
- switch (uuid.bitSize ()) {
446
+ switch (uuid.bitSize ()) {
369
447
case 16 : {
370
448
// [Len] [0x02] [LL] [HH]
371
449
cdata[0 ] = 3 ;
372
450
cdata[1 ] = ESP_BLE_AD_TYPE_16SRV_PART; // 0x02
373
- addData (std::string (cdata, 2 ) + std::string ((char *) &uuid.getNative ()->uuid .uuid16 , 2 ));
451
+ addData (std::string (cdata, 2 ) + std::string ((char *)&uuid.getNative ()->uuid .uuid16 ,2 ));
374
452
break ;
375
453
}
376
454
377
455
case 32 : {
378
456
// [Len] [0x04] [LL] [LL] [HH] [HH]
379
457
cdata[0 ] = 5 ;
380
458
cdata[1 ] = ESP_BLE_AD_TYPE_32SRV_PART; // 0x04
381
- addData (std::string (cdata, 2 ) + std::string ((char *) &uuid.getNative ()->uuid .uuid32 , 4 ));
459
+ addData (std::string (cdata, 2 ) + std::string ((char *)&uuid.getNative ()->uuid .uuid32 ,4 ));
382
460
break ;
383
461
}
384
462
385
463
case 128 : {
386
464
// [Len] [0x04] [0] [1] ... [15]
387
465
cdata[0 ] = 17 ;
388
466
cdata[1 ] = ESP_BLE_AD_TYPE_128SRV_PART; // 0x06
389
- addData (std::string (cdata, 2 ) + std::string ((char *) & uuid.getNative ()->uuid .uuid128 , 16 ));
467
+ addData (std::string (cdata, 2 ) + std::string ((char *)uuid.getNative ()->uuid .uuid128 ,16 ));
390
468
break ;
391
469
}
392
470
@@ -403,28 +481,28 @@ void BLEAdvertisementData::setPartialServices(BLEUUID uuid) {
403
481
*/
404
482
void BLEAdvertisementData::setServiceData (BLEUUID uuid, std::string data) {
405
483
char cdata[2 ];
406
- switch (uuid.bitSize ()) {
484
+ switch (uuid.bitSize ()) {
407
485
case 16 : {
408
486
// [Len] [0x16] [UUID16] data
409
487
cdata[0 ] = data.length () + 3 ;
410
488
cdata[1 ] = ESP_BLE_AD_TYPE_SERVICE_DATA; // 0x16
411
- addData (std::string (cdata, 2 ) + std::string ((char *) &uuid.getNative ()->uuid .uuid16 , 2 ) + data);
489
+ addData (std::string (cdata, 2 ) + std::string ((char *) &uuid.getNative ()->uuid .uuid16 ,2 ) + data);
412
490
break ;
413
491
}
414
492
415
493
case 32 : {
416
494
// [Len] [0x20] [UUID32] data
417
495
cdata[0 ] = data.length () + 5 ;
418
496
cdata[1 ] = ESP_BLE_AD_TYPE_32SERVICE_DATA; // 0x20
419
- addData (std::string (cdata, 2 ) + std::string ((char *) &uuid.getNative ()->uuid .uuid32 , 4 ) + data);
497
+ addData (std::string (cdata, 2 ) + std::string ((char *) &uuid.getNative ()->uuid .uuid32 ,4 ) + data);
420
498
break ;
421
499
}
422
500
423
501
case 128 : {
424
502
// [Len] [0x21] [UUID128] data
425
503
cdata[0 ] = data.length () + 17 ;
426
504
cdata[1 ] = ESP_BLE_AD_TYPE_128SERVICE_DATA; // 0x21
427
- addData (std::string (cdata, 2 ) + std::string ((char *) & uuid.getNative ()->uuid .uuid128 , 16 ) + data);
505
+ addData (std::string (cdata, 2 ) + std::string ((char *) uuid.getNative ()->uuid .uuid128 ,16 ) + data);
428
506
break ;
429
507
}
430
508
@@ -443,11 +521,12 @@ void BLEAdvertisementData::setShortName(std::string name) {
443
521
char cdata[2 ];
444
522
cdata[0 ] = name.length () + 1 ;
445
523
cdata[1 ] = ESP_BLE_AD_TYPE_NAME_SHORT; // 0x08
446
- addData (std::string (cdata, 2 ) + name);
524
+ addData (std::string (cdata, 2 ) + name);
447
525
ESP_LOGD (" BLEAdvertisementData" , " << setShortName" );
448
526
} // setShortName
449
527
450
528
529
+
451
530
/* *
452
531
* @brief Retrieve the payload that is to be advertised.
453
532
* @return The payload that is to be advertised.
@@ -456,5 +535,34 @@ std::string BLEAdvertisementData::getPayload() {
456
535
return m_payload;
457
536
} // getPayload
458
537
538
+ void BLEAdvertising::gapEventHandler (
539
+ esp_gap_ble_cb_event_t event,
540
+ esp_ble_gap_cb_param_t * param) {
541
+
542
+ ESP_LOGD (LOG_TAG, " gapEventHandler [event no: %d]" , (int )event);
543
+
544
+ switch (event) {
545
+ case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT: {
546
+ // m_semaphoreSetAdv.give();
547
+ break ;
548
+ }
549
+ case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT: {
550
+ // m_semaphoreSetAdv.give();
551
+ break ;
552
+ }
553
+ case ESP_GAP_BLE_ADV_START_COMPLETE_EVT: {
554
+ // m_semaphoreSetAdv.give();
555
+ break ;
556
+ }
557
+ case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT: {
558
+ ESP_LOGI (LOG_TAG, " STOP advertising" );
559
+ start ();
560
+ break ;
561
+ }
562
+ default :
563
+ break ;
564
+ }
565
+ }
566
+
459
567
460
- #endif /* CONFIG_BT_ENABLED */
568
+ #endif /* CONFIG_BT_ENABLED */
0 commit comments