@@ -488,16 +488,17 @@ bool BLEClient::connect(BLEAddress address, uint8_t type, uint32_t timeoutMs) {
488488
489489/* *
490490 * @brief Disconnect from the peer.
491- * @return N/A .
491+ * @return error code from bluedroid, 0 = success .
492492 */
493- void BLEClient::disconnect () {
493+ int BLEClient::disconnect (uint8_t reason ) {
494494 log_v (" >> disconnect()" );
495495 esp_err_t errRc = ::esp_ble_gattc_close (getGattcIf (), getConnId ());
496496 if (errRc != ESP_OK) {
497497 log_e (" esp_ble_gattc_close: rc=%d %s" , errRc, GeneralUtils::errorToString (errRc));
498- return ;
498+ return errRc ;
499499 }
500500 log_v (" << disconnect()" );
501+ return ESP_OK;
501502} // disconnect
502503
503504/* *
@@ -1241,6 +1242,52 @@ int BLEClient::handleGAPEvent(struct ble_gap_event *event, void *arg) {
12411242 return 0 ;
12421243} // handleGAPEvent
12431244
1245+ /* *
1246+ * @brief Disconnect from the peer.
1247+ * @return Error code from NimBLE stack, 0 = success.
1248+ */
1249+ int BLEClient::disconnect (uint8_t reason) {
1250+ log_d (" >> disconnect()" );
1251+ int rc = 0 ;
1252+ if (isConnected ()) {
1253+ // If the timer was already started, ignore this call.
1254+ if (ble_npl_callout_is_active (&m_dcTimer)) {
1255+ log_i (" Already disconnecting, timer started" );
1256+ return BLE_HS_EALREADY;
1257+ }
1258+
1259+ ble_gap_conn_desc desc;
1260+ if (ble_gap_conn_find (m_conn_id, &desc) != 0 ){
1261+ log_i (" Connection ID not found" );
1262+ return BLE_HS_EALREADY;
1263+ }
1264+
1265+ // We use a timer to detect a controller error in the event that it does
1266+ // not inform the stack when disconnection is complete.
1267+ // This is a common error in certain esp-idf versions.
1268+ // The disconnect timeout time is the supervison timeout time + 1 second.
1269+ // In the case that the event happenss shortly after the supervision timeout
1270+ // we don't want to prematurely reset the host.
1271+ ble_npl_time_t ticks;
1272+ ble_npl_time_ms_to_ticks ((desc.supervision_timeout + 100 ) * 10 , &ticks);
1273+ ble_npl_callout_reset (&m_dcTimer, ticks);
1274+
1275+ rc = ble_gap_terminate (m_conn_id, reason);
1276+ if (rc != 0 ) {
1277+ if (rc != BLE_HS_EALREADY) {
1278+ ble_npl_callout_stop (&m_dcTimer);
1279+ }
1280+ log_e (" ble_gap_terminate failed: rc=%d %s" , rc, BLEUtils::returnCodeToString (rc));
1281+ } else {
1282+ log_d (" Not connected to any peers" );
1283+ }
1284+ }
1285+
1286+ log_d (" << disconnect()" );
1287+ m_lastErr = rc;
1288+ return rc;
1289+ } // disconnect
1290+
12441291bool BLEClientCallbacks::onConnParamsUpdateRequest (BLEClient *pClient, const ble_gap_upd_params *params) {
12451292 log_d (" BLEClientCallbacks" , " onConnParamsUpdateRequest: default" );
12461293 return true ;
0 commit comments