Преглед изворни кода

Merge branch 'feature/rainmaker_BT_configurable' into 'master'

Doc: Made bluetooth configurable after wifi provisioning is completed

See merge request espressif/esp-idf!18014
Isha Pardikar пре 3 година
родитељ
комит
2cfcae8d41

+ 10 - 0
components/protocomm/src/simple_ble/simple_ble.c

@@ -23,6 +23,7 @@ static simple_ble_cfg_t *g_ble_cfg_p;
 static uint16_t *g_gatt_table_map;
 
 static uint8_t adv_config_done;
+static esp_bd_addr_t s_cached_remote_bda = {0x0,};
 #define adv_config_flag      (1 << 0)
 #define scan_rsp_config_flag (1 << 1)
 
@@ -133,6 +134,7 @@ static void gatts_profile_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_
         g_ble_cfg_p->connect_fn(event, gatts_if, param);
         esp_ble_conn_update_params_t conn_params = {0};
         memcpy(conn_params.bda, param->connect.remote_bda, sizeof(esp_bd_addr_t));
+	memcpy(s_cached_remote_bda, param->connect.remote_bda, sizeof(esp_bd_addr_t));
         /* For the iOS system, please refer the official Apple documents about BLE connection parameters restrictions. */
         conn_params.latency = 0;
         conn_params.max_int = 0x20;    // max_int = 0x20*1.25ms = 40ms
@@ -143,6 +145,7 @@ static void gatts_profile_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_
     case ESP_GATTS_DISCONNECT_EVT:
         ESP_LOGD(TAG, "ESP_GATTS_DISCONNECT_EVT, reason = %d", param->disconnect.reason);
         g_ble_cfg_p->disconnect_fn(event, gatts_if, param);
+        memset(s_cached_remote_bda, 0, sizeof(esp_bd_addr_t));
         esp_ble_gap_start_advertising(&g_ble_cfg_p->adv_params);
         break;
     case ESP_GATTS_CREAT_ATTR_TAB_EVT: {
@@ -320,3 +323,10 @@ esp_err_t simple_ble_stop(void)
     ESP_LOGD(TAG, "Free mem at end of simple_ble_stop %d", esp_get_free_heap_size());
     return ESP_OK;
 }
+
+#ifdef CONFIG_WIFI_PROV_DISCONNECT_AFTER_PROV
+esp_err_t simple_ble_disconnect(void)
+{
+    return esp_ble_gap_disconnect(s_cached_remote_bda);
+}
+#endif

+ 9 - 0
components/protocomm/src/simple_ble/simple_ble.h

@@ -104,4 +104,13 @@ esp_err_t simple_ble_stop(void);
  */
 const uint8_t *simple_ble_get_uuid128(uint16_t handle);
 
+#ifdef CONFIG_WIFI_PROV_DISCONNECT_AFTER_PROV
+/** Terminates connection
+ *
+ * This API is called to initiate disconnection
+ *
+ * @return ESP_OK on success, and appropriate error code for failure
+ */
+esp_err_t simple_ble_disconnect(void);
+#endif
 #endif /* _SIMPLE_BLE_ */

+ 23 - 1
components/protocomm/src/transports/protocomm_ble.c

@@ -318,6 +318,15 @@ static void transport_simple_ble_disconnect(esp_gatts_cb_event_t event, esp_gatt
 {
     esp_err_t ret;
     ESP_LOGD(TAG, "Inside disconnect w/ session - %d", param->disconnect.conn_id);
+
+#ifdef CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV
+    /* Ignore BLE events received after protocomm layer is stopped */
+    if (protoble_internal == NULL) {
+        ESP_LOGI(TAG,"Protocomm layer has already stopped");
+        return;
+    }
+#endif
+
     if (protoble_internal->pc_ble->sec &&
             protoble_internal->pc_ble->sec->close_transport_session) {
         ret = protoble_internal->pc_ble->sec->close_transport_session(protoble_internal->pc_ble->sec_inst,
@@ -572,11 +581,24 @@ esp_err_t protocomm_ble_stop(protocomm_t *pc)
             (protoble_internal != NULL ) &&
             (pc == protoble_internal->pc_ble)) {
         esp_err_t ret = ESP_OK;
+
+#ifndef CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV
+	/* If flag is not enabled, stop the stack. */
         ret = simple_ble_stop();
         if (ret) {
             ESP_LOGE(TAG, "BLE stop failed");
         }
-        simple_ble_deinit();
+#else
+#ifdef CONFIG_WIFI_PROV_DISCONNECT_AFTER_PROV
+        /* Keep BT stack on, but terminate the connection after provisioning */
+	ret = simple_ble_disconnect();
+	if (ret) {
+	    ESP_LOGE(TAG, "BLE disconnect failed");
+	}
+	simple_ble_deinit();
+#endif  // CONFIG_WIFI_PROV_DISCONNECT_AFTER_PROV
+#endif  // CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV
+
         protocomm_ble_cleanup();
         return ret;
     }

+ 23 - 2
components/protocomm/src/transports/protocomm_nimble.c

@@ -25,6 +25,7 @@ static const char *TAG = "protocomm_nimble";
 int ble_uuid_flat(const ble_uuid_t *, void *);
 static uint8_t ble_uuid_base[BLE_UUID128_VAL_LENGTH];
 static int num_chr_dsc;
+static uint16_t s_cached_conn_handle;
 
 /*  Standard 16 bit UUID for characteristic User Description*/
 #define BLE_GATT_UUID_CHAR_DSC              0x2901
@@ -225,6 +226,7 @@ simple_ble_gap_event(struct ble_gap_event *event, void *arg)
                 ESP_LOGE(TAG, "No open connection with the specified handle");
                 return rc;
             }
+	    s_cached_conn_handle = event->connect.conn_handle;
         } else {
             /* Connection failed; resume advertising. */
             simple_ble_advertise();
@@ -234,7 +236,7 @@ simple_ble_gap_event(struct ble_gap_event *event, void *arg)
     case BLE_GAP_EVENT_DISCONNECT:
         ESP_LOGD(TAG, "disconnect; reason=%d ", event->disconnect.reason);
         transport_simple_ble_disconnect(event, arg);
-
+        s_cached_conn_handle = 0; /* Clear conn_handle value */
         /* Connection terminated; resume advertising. */
         simple_ble_advertise();
         return 0;
@@ -536,6 +538,14 @@ static void transport_simple_ble_disconnect(struct ble_gap_event *event, void *a
     esp_err_t ret;
     ESP_LOGD(TAG, "Inside disconnect w/ session - %d",
              event->disconnect.conn.conn_handle);
+
+#ifdef CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV
+    /* Ignore BLE events received after protocomm layer is stopped */
+    if (protoble_internal == NULL) {
+        ESP_LOGI(TAG,"Protocomm layer has already stopped");
+        return;
+    }
+#endif
     if (protoble_internal->pc_ble->sec &&
             protoble_internal->pc_ble->sec->close_transport_session) {
         ret =
@@ -948,12 +958,23 @@ esp_err_t protocomm_ble_stop(protocomm_t *pc)
                      rc);
         }
 
+#ifndef CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV
+	/* If flag is enabled, don't stop the stack. User application can start a new advertising to perform its BT activities */
         ret = nimble_port_stop();
         if (ret == 0) {
             nimble_port_deinit();
         }
+#else
+#ifdef CONFIG_WIFI_PROV_DISCONNECT_AFTER_PROV
+	/* Keep BT stack on, but terminate the connection after provisioning */
+	rc = ble_gap_terminate(s_cached_conn_handle, BLE_ERR_REM_USER_CONN_TERM);
+	if (rc) {
+	    ESP_LOGI(TAG, "Error in terminating connection rc = %d",rc);
+	}
+	free_gatt_ble_misc_memory(ble_cfg_p);
+#endif // CONFIG_WIFI_PROV_DISCONNECT_AFTER_PROV
+#endif // CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV
 
-        free_gatt_ble_misc_memory(ble_cfg_p);
         protocomm_ble_cleanup();
         return ret;
     }

+ 9 - 0
components/wifi_provisioning/Kconfig

@@ -38,4 +38,13 @@ menu "Wi-Fi Provisioning Manager"
         help
             Used to enforce link encryption when attempting to read / write characteristic
 
+    config WIFI_PROV_KEEP_BLE_ON_AFTER_PROV
+        bool "Keep BT on after provisioning is done"
+        depends on BT_ENABLED
+
+    config WIFI_PROV_DISCONNECT_AFTER_PROV
+        bool "Terminate connection after provisioning is done"
+        depends on WIFI_PROV_KEEP_BLE_ON_AFTER_PROV
+        default y
+
 endmenu

+ 4 - 0
components/wifi_provisioning/src/scheme_ble.c

@@ -207,6 +207,7 @@ void wifi_prov_scheme_ble_event_cb_free_btdm(void *user_data, wifi_prov_cb_event
             break;
 
         case WIFI_PROV_DEINIT:
+#ifndef CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV
             /* Release memory used by BLE and Bluedroid host stack */
             err = esp_bt_mem_release(ESP_BT_MODE_BTDM);
             if (err != ESP_OK) {
@@ -214,6 +215,7 @@ void wifi_prov_scheme_ble_event_cb_free_btdm(void *user_data, wifi_prov_cb_event
             } else {
                 ESP_LOGI(TAG, "BTDM memory released");
             }
+#endif
             break;
 
         default:
@@ -247,6 +249,7 @@ void wifi_prov_scheme_ble_event_cb_free_ble(void *user_data, wifi_prov_cb_event_
     esp_err_t err;
     switch (event) {
         case WIFI_PROV_DEINIT:
+#ifndef CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV
             /* Release memory used by BLE stack */
             err = esp_bt_mem_release(ESP_BT_MODE_BLE);
             if (err != ESP_OK) {
@@ -254,6 +257,7 @@ void wifi_prov_scheme_ble_event_cb_free_ble(void *user_data, wifi_prov_cb_event_
             } else {
                 ESP_LOGI(TAG, "BLE memory released");
             }
+#endif
             break;
 
         default: