diff options
author | gornekich <n.gorbadey@gmail.com> | 2022-01-21 20:32:03 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-21 20:32:03 +0300 |
commit | 23ff6723cf870b999b75caee06b9f95a34c52534 (patch) | |
tree | 1c77c7000ea390bb87960e3dd439fb0d7363d6d0 /firmware | |
parent | d4787e859ee0b1992d645b6f57fb145246c94334 (diff) |
[FL-2204] Bluetooth forget devices (#967)
* bt: update connection parameters
* bt: set correct connection latency and timeout
* gui popup: add clean method
* furi_hal_bt: add connection parameters request, clear database
* bt: add forget bonded devices API
* bt_settings: add forget bonded devices GUI
* bt: rework pin code show with view port to hide view
* bt: support conn parameters for different profiles
* furi_hal_bt: sync f6 target
* target f6: fix build
* bt: format sources
* furi_hal_bt: update connection parameters
* bt: update connection params, fix GUI
* FuriHal: fix spelling
* Refactoring: rename _clean to _reset
Co-authored-by: あく <alleteam@gmail.com>
Diffstat (limited to 'firmware')
-rwxr-xr-x[-rw-r--r--] | firmware/targets/f6/ble_glue/gap.c | 46 | ||||
-rw-r--r-- | firmware/targets/f6/ble_glue/gap.h | 8 | ||||
-rwxr-xr-x[-rw-r--r--] | firmware/targets/f6/furi_hal/furi_hal_bt.c | 25 | ||||
-rw-r--r-- | firmware/targets/f6/target.mk | 1 | ||||
-rwxr-xr-x[-rw-r--r--] | firmware/targets/f7/ble_glue/gap.c | 46 | ||||
-rw-r--r-- | firmware/targets/f7/ble_glue/gap.h | 8 | ||||
-rwxr-xr-x[-rw-r--r--] | firmware/targets/f7/furi_hal/furi_hal_bt.c | 25 | ||||
-rw-r--r-- | firmware/targets/f7/target.mk | 1 | ||||
-rw-r--r-- | firmware/targets/furi_hal_include/furi_hal_bt.h | 6 |
9 files changed, 148 insertions, 18 deletions
diff --git a/firmware/targets/f6/ble_glue/gap.c b/firmware/targets/f6/ble_glue/gap.c index dfcd174e..d9a2096f 100644..100755 --- a/firmware/targets/f6/ble_glue/gap.c +++ b/firmware/targets/f6/ble_glue/gap.c @@ -94,9 +94,17 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { case EVT_LE_META_EVENT: meta_evt = (evt_le_meta_event*)event_pckt->data; switch(meta_evt->subevent) { - case EVT_LE_CONN_UPDATE_COMPLETE: - FURI_LOG_D(TAG, "Connection update event"); + case EVT_LE_CONN_UPDATE_COMPLETE: { + hci_le_connection_update_complete_event_rp0* event = + (hci_le_connection_update_complete_event_rp0*)meta_evt->data; + FURI_LOG_I( + TAG, + "Connection interval: %d, latency: %d, supervision timeout: %d", + event->Conn_Interval, + event->Conn_Latency, + event->Supervision_Timeout); break; + } case EVT_LE_PHY_UPDATE_COMPLETE: evt_le_phy_update_complete = (hci_le_phy_update_complete_event_rp0*)meta_evt->data; @@ -129,6 +137,15 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { // Update connection status and handle gap->state = GapStateConnected; gap->service.connection_handle = connection_complete_event->Connection_Handle; + GapConnectionParams* params = &gap->config->conn_param; + if(aci_l2cap_connection_parameter_update_req( + gap->service.connection_handle, + params->conn_int_min, + params->conn_int_max, + params->slave_latency, + params->supervisor_timeout)) { + FURI_LOG_W(TAG, "Failed to request connection parameters update"); + } // Start pairing by sending security request aci_gap_slave_security_req(connection_complete_event->Connection_Handle); @@ -184,28 +201,28 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { } break; case EVT_BLUE_GAP_AUTHORIZATION_REQUEST: - FURI_LOG_I(TAG, "Authorization request event"); + FURI_LOG_D(TAG, "Authorization request event"); break; case EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED: - FURI_LOG_I(TAG, "Slave security initiated"); + FURI_LOG_D(TAG, "Slave security initiated"); break; case EVT_BLUE_GAP_BOND_LOST: - FURI_LOG_I(TAG, "Bond lost event. Start rebonding"); + FURI_LOG_D(TAG, "Bond lost event. Start rebonding"); aci_gap_allow_rebond(gap->service.connection_handle); break; case EVT_BLUE_GAP_DEVICE_FOUND: - FURI_LOG_I(TAG, "Device found event"); + FURI_LOG_D(TAG, "Device found event"); break; case EVT_BLUE_GAP_ADDR_NOT_RESOLVED: - FURI_LOG_I(TAG, "Address not resolved event"); + FURI_LOG_D(TAG, "Address not resolved event"); break; case EVT_BLUE_GAP_KEYPRESS_NOTIFICATION: - FURI_LOG_I(TAG, "Key press notification event"); + FURI_LOG_D(TAG, "Key press notification event"); break; case EVT_BLUE_GAP_NUMERIC_COMPARISON_VALUE: { @@ -234,8 +251,19 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { break; case EVT_BLUE_GAP_PROCEDURE_COMPLETE: - FURI_LOG_I(TAG, "Procedure complete event"); + FURI_LOG_D(TAG, "Procedure complete event"); break; + + case EVT_BLUE_L2CAP_CONNECTION_UPDATE_RESP: { + uint16_t result = + ((aci_l2cap_connection_update_resp_event_rp0*)(blue_evt->data))->Result; + if(result == 0) { + FURI_LOG_D(TAG, "Connection parameters accepted"); + } else if(result == 1) { + FURI_LOG_D(TAG, "Connection parameters denied"); + } + break; + } } default: break; diff --git a/firmware/targets/f6/ble_glue/gap.h b/firmware/targets/f6/ble_glue/gap.h index 635a4c3c..1a2e7962 100644 --- a/firmware/targets/f6/ble_glue/gap.h +++ b/firmware/targets/f6/ble_glue/gap.h @@ -56,12 +56,20 @@ typedef enum { } GapPairing; typedef struct { + uint16_t conn_int_min; + uint16_t conn_int_max; + uint16_t slave_latency; + uint16_t supervisor_timeout; +} GapConnectionParams; + +typedef struct { uint16_t adv_service_uuid; uint16_t appearance_char; bool bonding_mode; GapPairing pairing_method; uint8_t mac_address[GAP_MAC_ADDR_SIZE]; char adv_name[FURI_HAL_VERSION_DEVICE_NAME_LENGTH]; + GapConnectionParams conn_param; } GapConfig; bool gap_init(GapConfig* config, GapEventCallback on_event_cb, void* context); diff --git a/firmware/targets/f6/furi_hal/furi_hal_bt.c b/firmware/targets/f6/furi_hal/furi_hal_bt.c index 7147c7f0..4465f15e 100644..100755 --- a/firmware/targets/f6/furi_hal/furi_hal_bt.c +++ b/firmware/targets/f6/furi_hal/furi_hal_bt.c @@ -42,6 +42,13 @@ FuriHalBtProfileConfig profile_config[FuriHalBtProfileNumber] = { .bonding_mode = true, .pairing_method = GapPairingPinCodeShow, .mac_address = FURI_HAL_BT_DEFAULT_MAC_ADDR, + .conn_param = + { + .conn_int_min = 0x08, + .conn_int_max = 0x18, + .slave_latency = 0, + .supervisor_timeout = 50, + }, }, }, [FuriHalBtProfileHidKeyboard] = @@ -55,6 +62,14 @@ FuriHalBtProfileConfig profile_config[FuriHalBtProfileNumber] = { .bonding_mode = true, .pairing_method = GapPairingPinCodeVerifyYesNo, .mac_address = FURI_HAL_BT_DEFAULT_MAC_ADDR, + // TODO optimize + .conn_param = + { + .conn_int_min = 0x12, + .conn_int_max = 0x1e, + .slave_latency = 6, + .supervisor_timeout = 700, + }, }, }, }; @@ -277,6 +292,16 @@ void furi_hal_bt_nvm_sram_sem_release() { HAL_HSEM_Release(CFG_HW_BLE_NVM_SRAM_SEMID, 0); } +bool furi_hal_bt_clear_white_list() { + furi_hal_bt_nvm_sram_sem_acquire(); + tBleStatus status = aci_gap_clear_security_db(); + if(status) { + FURI_LOG_E(TAG, "Clear while list failed with status %d", status); + } + furi_hal_bt_nvm_sram_sem_release(); + return status != BLE_STATUS_SUCCESS; +} + void furi_hal_bt_dump_state(string_t buffer) { if(furi_hal_bt_is_alive()) { uint8_t HCI_Version; diff --git a/firmware/targets/f6/target.mk b/firmware/targets/f6/target.mk index 029c8f40..0c9bd182 100644 --- a/firmware/targets/f6/target.mk +++ b/firmware/targets/f6/target.mk @@ -112,6 +112,7 @@ C_SOURCES += \ $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/ble/core/auto/ble_gap_aci.c \ $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/ble/core/auto/ble_gatt_aci.c \ $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/ble/core/auto/ble_hal_aci.c \ + $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/ble/core/auto/ble_l2cap_aci.c \ $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/tl_mbox.c \ $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/hci_tl.c \ $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/hci_tl_if.c \ diff --git a/firmware/targets/f7/ble_glue/gap.c b/firmware/targets/f7/ble_glue/gap.c index dfcd174e..d9a2096f 100644..100755 --- a/firmware/targets/f7/ble_glue/gap.c +++ b/firmware/targets/f7/ble_glue/gap.c @@ -94,9 +94,17 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { case EVT_LE_META_EVENT: meta_evt = (evt_le_meta_event*)event_pckt->data; switch(meta_evt->subevent) { - case EVT_LE_CONN_UPDATE_COMPLETE: - FURI_LOG_D(TAG, "Connection update event"); + case EVT_LE_CONN_UPDATE_COMPLETE: { + hci_le_connection_update_complete_event_rp0* event = + (hci_le_connection_update_complete_event_rp0*)meta_evt->data; + FURI_LOG_I( + TAG, + "Connection interval: %d, latency: %d, supervision timeout: %d", + event->Conn_Interval, + event->Conn_Latency, + event->Supervision_Timeout); break; + } case EVT_LE_PHY_UPDATE_COMPLETE: evt_le_phy_update_complete = (hci_le_phy_update_complete_event_rp0*)meta_evt->data; @@ -129,6 +137,15 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { // Update connection status and handle gap->state = GapStateConnected; gap->service.connection_handle = connection_complete_event->Connection_Handle; + GapConnectionParams* params = &gap->config->conn_param; + if(aci_l2cap_connection_parameter_update_req( + gap->service.connection_handle, + params->conn_int_min, + params->conn_int_max, + params->slave_latency, + params->supervisor_timeout)) { + FURI_LOG_W(TAG, "Failed to request connection parameters update"); + } // Start pairing by sending security request aci_gap_slave_security_req(connection_complete_event->Connection_Handle); @@ -184,28 +201,28 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { } break; case EVT_BLUE_GAP_AUTHORIZATION_REQUEST: - FURI_LOG_I(TAG, "Authorization request event"); + FURI_LOG_D(TAG, "Authorization request event"); break; case EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED: - FURI_LOG_I(TAG, "Slave security initiated"); + FURI_LOG_D(TAG, "Slave security initiated"); break; case EVT_BLUE_GAP_BOND_LOST: - FURI_LOG_I(TAG, "Bond lost event. Start rebonding"); + FURI_LOG_D(TAG, "Bond lost event. Start rebonding"); aci_gap_allow_rebond(gap->service.connection_handle); break; case EVT_BLUE_GAP_DEVICE_FOUND: - FURI_LOG_I(TAG, "Device found event"); + FURI_LOG_D(TAG, "Device found event"); break; case EVT_BLUE_GAP_ADDR_NOT_RESOLVED: - FURI_LOG_I(TAG, "Address not resolved event"); + FURI_LOG_D(TAG, "Address not resolved event"); break; case EVT_BLUE_GAP_KEYPRESS_NOTIFICATION: - FURI_LOG_I(TAG, "Key press notification event"); + FURI_LOG_D(TAG, "Key press notification event"); break; case EVT_BLUE_GAP_NUMERIC_COMPARISON_VALUE: { @@ -234,8 +251,19 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { break; case EVT_BLUE_GAP_PROCEDURE_COMPLETE: - FURI_LOG_I(TAG, "Procedure complete event"); + FURI_LOG_D(TAG, "Procedure complete event"); break; + + case EVT_BLUE_L2CAP_CONNECTION_UPDATE_RESP: { + uint16_t result = + ((aci_l2cap_connection_update_resp_event_rp0*)(blue_evt->data))->Result; + if(result == 0) { + FURI_LOG_D(TAG, "Connection parameters accepted"); + } else if(result == 1) { + FURI_LOG_D(TAG, "Connection parameters denied"); + } + break; + } } default: break; diff --git a/firmware/targets/f7/ble_glue/gap.h b/firmware/targets/f7/ble_glue/gap.h index 635a4c3c..1a2e7962 100644 --- a/firmware/targets/f7/ble_glue/gap.h +++ b/firmware/targets/f7/ble_glue/gap.h @@ -56,12 +56,20 @@ typedef enum { } GapPairing; typedef struct { + uint16_t conn_int_min; + uint16_t conn_int_max; + uint16_t slave_latency; + uint16_t supervisor_timeout; +} GapConnectionParams; + +typedef struct { uint16_t adv_service_uuid; uint16_t appearance_char; bool bonding_mode; GapPairing pairing_method; uint8_t mac_address[GAP_MAC_ADDR_SIZE]; char adv_name[FURI_HAL_VERSION_DEVICE_NAME_LENGTH]; + GapConnectionParams conn_param; } GapConfig; bool gap_init(GapConfig* config, GapEventCallback on_event_cb, void* context); diff --git a/firmware/targets/f7/furi_hal/furi_hal_bt.c b/firmware/targets/f7/furi_hal/furi_hal_bt.c index 7147c7f0..4465f15e 100644..100755 --- a/firmware/targets/f7/furi_hal/furi_hal_bt.c +++ b/firmware/targets/f7/furi_hal/furi_hal_bt.c @@ -42,6 +42,13 @@ FuriHalBtProfileConfig profile_config[FuriHalBtProfileNumber] = { .bonding_mode = true, .pairing_method = GapPairingPinCodeShow, .mac_address = FURI_HAL_BT_DEFAULT_MAC_ADDR, + .conn_param = + { + .conn_int_min = 0x08, + .conn_int_max = 0x18, + .slave_latency = 0, + .supervisor_timeout = 50, + }, }, }, [FuriHalBtProfileHidKeyboard] = @@ -55,6 +62,14 @@ FuriHalBtProfileConfig profile_config[FuriHalBtProfileNumber] = { .bonding_mode = true, .pairing_method = GapPairingPinCodeVerifyYesNo, .mac_address = FURI_HAL_BT_DEFAULT_MAC_ADDR, + // TODO optimize + .conn_param = + { + .conn_int_min = 0x12, + .conn_int_max = 0x1e, + .slave_latency = 6, + .supervisor_timeout = 700, + }, }, }, }; @@ -277,6 +292,16 @@ void furi_hal_bt_nvm_sram_sem_release() { HAL_HSEM_Release(CFG_HW_BLE_NVM_SRAM_SEMID, 0); } +bool furi_hal_bt_clear_white_list() { + furi_hal_bt_nvm_sram_sem_acquire(); + tBleStatus status = aci_gap_clear_security_db(); + if(status) { + FURI_LOG_E(TAG, "Clear while list failed with status %d", status); + } + furi_hal_bt_nvm_sram_sem_release(); + return status != BLE_STATUS_SUCCESS; +} + void furi_hal_bt_dump_state(string_t buffer) { if(furi_hal_bt_is_alive()) { uint8_t HCI_Version; diff --git a/firmware/targets/f7/target.mk b/firmware/targets/f7/target.mk index 029c8f40..0c9bd182 100644 --- a/firmware/targets/f7/target.mk +++ b/firmware/targets/f7/target.mk @@ -112,6 +112,7 @@ C_SOURCES += \ $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/ble/core/auto/ble_gap_aci.c \ $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/ble/core/auto/ble_gatt_aci.c \ $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/ble/core/auto/ble_hal_aci.c \ + $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/ble/core/auto/ble_l2cap_aci.c \ $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/tl_mbox.c \ $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/hci_tl.c \ $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/hci_tl_if.c \ diff --git a/firmware/targets/furi_hal_include/furi_hal_bt.h b/firmware/targets/furi_hal_include/furi_hal_bt.h index cacf33a3..e10901b0 100644 --- a/firmware/targets/furi_hal_include/furi_hal_bt.h +++ b/firmware/targets/furi_hal_include/furi_hal_bt.h @@ -121,6 +121,12 @@ void furi_hal_bt_nvm_sram_sem_acquire(); */ void furi_hal_bt_nvm_sram_sem_release(); +/** Clear key storage + * + * @return true on success +*/ +bool furi_hal_bt_clear_white_list(); + /** Set key storage change callback * * @param callback BleGlueKeyStorageChangedCallback instance |