@@ -54,6 +54,7 @@ struct esp32_gatts_session_entry {
54
54
55
55
struct esp32_gatts_connection_entry {
56
56
struct esp32_bt_connection bc ;
57
+ bool need_auth ;
57
58
SLIST_HEAD (sessions , esp32_gatts_session_entry ) sessions ;
58
59
SLIST_ENTRY (esp32_gatts_connection_entry ) next ;
59
60
};
@@ -267,6 +268,55 @@ static void run_on_mgos_task(esp_gatt_if_t gatts_if,
267
268
mgos_invoke_cb (gatts_ev_mgos , ei , false /* from_isr */ );
268
269
}
269
270
271
+ static bool is_paired (const esp_bd_addr_t addr ) {
272
+ bool result = false;
273
+ int num = esp_ble_get_bond_device_num ();
274
+ esp_ble_bond_dev_t * list = (esp_ble_bond_dev_t * ) calloc (num , sizeof (* list ));
275
+ if (list != NULL && esp_ble_get_bond_device_list (& num , list ) == ESP_OK ) {
276
+ for (int i = 0 ; i < num ; i ++ ) {
277
+ if (mgos_bt_addr_cmp (addr , list [i ].bd_addr ) == 0 ) {
278
+ result = true;
279
+ break ;
280
+ }
281
+ }
282
+ }
283
+ free (list );
284
+ return result ;
285
+ }
286
+
287
+ static void create_sessions (struct esp32_gatts_connection_entry * ce ) {
288
+ /* Create a session for each of the currently registered services. */
289
+ struct esp32_bt_service_entry * se ;
290
+ esp_ble_gatts_cb_param_t ep ;
291
+ ep .connect .conn_id = ce -> bc .conn_id ;
292
+ memcpy (ep .connect .remote_bda , ce -> bc .peer_addr , ESP_BD_ADDR_LEN );
293
+ SLIST_FOREACH (se , & s_svcs , next ) {
294
+ struct esp32_gatts_session_entry * sse =
295
+ (struct esp32_gatts_session_entry * ) calloc (1 , sizeof (* sse ));
296
+ sse -> se = se ;
297
+ sse -> bs .bc = & ce -> bc ;
298
+ SLIST_INSERT_HEAD (& ce -> sessions , sse , next );
299
+ run_on_mgos_task (ce -> bc .gatt_if , sse , sse -> se , ESP_GATTS_CONNECT_EVT , & ep );
300
+ }
301
+ esp_ble_conn_update_params_t conn_params = {0 };
302
+ memcpy (conn_params .bda , ce -> bc .peer_addr , ESP_BD_ADDR_LEN );
303
+ conn_params .latency = 0 ;
304
+ conn_params .max_int = 0x50 ; /* max_int = 0x50*1.25ms = 100ms */
305
+ conn_params .min_int = 0x30 ; /* min_int = 0x30*1.25ms = 60ms */
306
+ conn_params .timeout = 400 ; /* timeout = 400*10ms = 4000ms */
307
+ esp_ble_gap_update_conn_params (& conn_params );
308
+ }
309
+
310
+ void esp32_bt_gatts_auth_cmpl (const esp_bd_addr_t addr ) {
311
+ struct esp32_gatts_connection_entry * ce , * ct ;
312
+ SLIST_FOREACH_SAFE (ce , & s_conns , next , ct ) {
313
+ if (mgos_bt_addr_cmp (ce -> bc .peer_addr , addr ) == 0 && ce -> need_auth ) {
314
+ ce -> need_auth = false;
315
+ create_sessions (ce );
316
+ }
317
+ }
318
+ }
319
+
270
320
static void esp32_bt_gatts_ev (esp_gatts_cb_event_t ev , esp_gatt_if_t gatts_if ,
271
321
esp_ble_gatts_cb_param_t * ep ) {
272
322
char buf [BT_UUID_STR_LEN ];
@@ -436,47 +486,62 @@ static void esp32_bt_gatts_ev(esp_gatts_cb_event_t ev, esp_gatt_if_t gatts_if,
436
486
const struct gatts_connect_evt_param * p = & ep -> connect ;
437
487
LOG (LL_INFO , ("CONNECT cid %d addr %s" , p -> conn_id ,
438
488
mgos_bt_addr_to_str (p -> remote_bda , buf )));
439
- esp_ble_conn_update_params_t conn_params = {0 };
440
- memcpy (conn_params .bda , p -> remote_bda , ESP_BD_ADDR_LEN );
441
- conn_params .latency = 0 ;
442
- conn_params .max_int = 0x50 ; /* max_int = 0x50*1.25ms = 100ms */
443
- conn_params .min_int = 0x30 ; /* min_int = 0x30*1.25ms = 60ms */
444
- conn_params .timeout = 400 ; /* timeout = 400*10ms = 4000ms */
445
- esp_ble_gap_update_conn_params (& conn_params );
446
489
/* Connect disables advertising. Resume, if it's enabled. */
447
490
esp32_bt_set_is_advertising (false);
448
491
mgos_bt_gap_set_adv_enable (mgos_bt_gap_get_adv_enable ());
492
+ bool disconnect = false;
493
+ esp_ble_sec_act_t sec = 0 ;
449
494
switch (mgos_sys_config_get_bt_gatts_min_sec_level ()) {
450
495
case MGOS_BT_GATT_PERM_LEVEL_NONE :
451
496
break ;
452
497
case MGOS_BT_GATT_PERM_LEVEL_ENCR :
453
- LOG (LL_DEBUG , ("%s: Requesting encryption" ,
454
- mgos_bt_addr_to_str (p -> remote_bda , buf )));
455
- esp_ble_set_encryption ((uint8_t * ) p -> remote_bda ,
456
- ESP_BLE_SEC_ENCRYPT_NO_MITM );
498
+ sec = ESP_BLE_SEC_ENCRYPT_NO_MITM ;
457
499
break ;
458
500
case MGOS_BT_GATT_PERM_LEVEL_ENCR_MITM :
459
- LOG (LL_DEBUG , ("%s: Requesting encryption + MITM protection" ,
460
- mgos_bt_addr_to_str (p -> remote_bda , buf )));
461
- esp_ble_set_encryption ((uint8_t * ) p -> remote_bda ,
462
- ESP_BLE_SEC_ENCRYPT_MITM );
501
+ sec = ESP_BLE_SEC_ENCRYPT_MITM ;
463
502
break ;
464
503
}
504
+ if (mgos_sys_config_get_bt_gatts_require_pairing ()) {
505
+ mgos_bt_addr_to_str (p -> remote_bda , buf );
506
+ int max_devices = mgos_sys_config_get_bt_max_paired_devices ();
507
+ if (is_paired (p -> remote_bda )) {
508
+ LOG (LL_INFO , ("%s: Already paired" , buf ));
509
+ } else if (!mgos_bt_gap_get_pairing_enable ()) {
510
+ LOG (LL_ERROR , ("%s: pairing required but is not allowed" , buf ));
511
+ disconnect = true;
512
+ } else if (max_devices >= 0 &&
513
+ mgos_bt_ble_get_num_paired_devices () >= max_devices ) {
514
+ LOG (LL_ERROR ,
515
+ ("%s: pairing required but max num devices (%d) reached" , buf ,
516
+ max_devices ));
517
+ disconnect = true;
518
+ } else {
519
+ LOG (LL_INFO , ("%s: Begin pairing" , buf ));
520
+ if (sec == 0 ) sec = ESP_BLE_SEC_ENCRYPT_NO_MITM ;
521
+ }
522
+ }
523
+ if (disconnect ) {
524
+ LOG (LL_ERROR , ("%s: dropping connection" ,
525
+ mgos_bt_addr_to_str (p -> remote_bda , buf )));
526
+ esp_ble_gap_disconnect ((uint8_t * ) p -> remote_bda );
527
+ break ;
528
+ }
465
529
struct esp32_gatts_connection_entry * ce =
466
530
(struct esp32_gatts_connection_entry * ) calloc (1 , sizeof (* ce ));
467
531
ce -> bc .gatt_if = gatts_if ;
468
532
ce -> bc .conn_id = p -> conn_id ;
469
533
ce -> bc .mtu = ESP_GATT_DEF_BLE_MTU_SIZE ;
470
534
memcpy (ce -> bc .peer_addr , p -> remote_bda , ESP_BD_ADDR_LEN );
471
- /* Create a session for each of the currently registered services. */
472
- struct esp32_bt_service_entry * se ;
473
- SLIST_FOREACH (se , & s_svcs , next ) {
474
- struct esp32_gatts_session_entry * sse =
475
- (struct esp32_gatts_session_entry * ) calloc (1 , sizeof (* sse ));
476
- sse -> se = se ;
477
- sse -> bs .bc = & ce -> bc ;
478
- SLIST_INSERT_HEAD (& ce -> sessions , sse , next );
479
- run_on_mgos_task (gatts_if , sse , sse -> se , ev , ep );
535
+ if (sec != 0 ) {
536
+ LOG (LL_DEBUG ,
537
+ ("%s: Requesting encryption%s" ,
538
+ mgos_bt_addr_to_str (p -> remote_bda , buf ),
539
+ (sec == ESP_BLE_SEC_ENCRYPT_MITM ? " + MITM protection" : "" )));
540
+ esp_ble_set_encryption ((uint8_t * ) p -> remote_bda , sec );
541
+ ce -> need_auth = true;
542
+ /* Wait for AUTH_CMPL */
543
+ } else {
544
+ create_sessions (ce );
480
545
}
481
546
SLIST_INSERT_HEAD (& s_conns , ce , next );
482
547
break ;
0 commit comments