From 88a03c8d0148d7fc90fe73b0a91b480a1329aab2 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Thu, 13 Aug 2020 19:41:48 +0200 Subject: [PATCH] gap: request role change for classic connection via `gap_request_role` --- CHANGELOG.md | 2 +- src/gap.h | 11 ++++++++++- src/hci.c | 19 +++++++++++++++++-- src/hci.h | 5 ++++- 4 files changed, 32 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 956750bc6..0f1e5d199 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Added - `btstack_run_loop_base`: added `btstack_run_loop_base_dump_timer` - +- GAP: request role change for classic connection via `gap_request_role` ### Changed diff --git a/src/gap.h b/src/gap.h index 8c3e2848a..ed92e5bf9 100644 --- a/src/gap.h +++ b/src/gap.h @@ -139,6 +139,15 @@ hci_role_t gap_get_role(hci_con_handle_t connection_handle); // Classic +/** + * @brief Request role switch + * @note this only requests the role switch. A HCI_EVENT_ROLE_CHANGE is emitted and its status field will indicate if the switch was succesful + * @param addr + * @param hci_role_t HCI_ROLE_MASTER / HCI_ROLE_SLAVE + * @result status + */ +uint8_t gap_request_role(bd_addr_t addr, hci_role_t role); + /** * @brief Sets local name. * @note has to be done before stack starts up @@ -695,7 +704,7 @@ void gap_le_get_own_address(uint8_t * addr_type, bd_addr_t addr); /** - * @brief Get state of connection re-encryptiong for bonded devices when in central role + * @brief Get state of connection re-encryption for bonded devices when in central role * @note used by gatt_client and att_server to wait for re-encryption * @param con_handle * @return 1 if security setup is active diff --git a/src/hci.c b/src/hci.c index e2f632acb..6ece4d24a 100644 --- a/src/hci.c +++ b/src/hci.c @@ -201,6 +201,7 @@ static hci_connection_t * create_connection_for_bd_addr_and_type(bd_addr_t addr, conn->bonding_flags = 0; conn->requested_security_level = LEVEL_0; #ifdef ENABLE_CLASSIC + conn->request_role = HCI_ROLE_INVALID; btstack_run_loop_set_timer_handler(&conn->timeout, hci_connection_timeout_handler); btstack_run_loop_set_timer_context(&conn->timeout, conn); hci_connection_timestamp(conn); @@ -3737,7 +3738,7 @@ static bool hci_run_general_gap_le(void){ } #endif -static bool hci_run_general_pending_commmands(void){ +static bool hci_run_general_pending_commands(void){ btstack_linked_item_t * it; for (it = (btstack_linked_item_t *) hci_stack->connections; it != NULL; it = it->next){ hci_connection_t * connection = (hci_connection_t *) it; @@ -3960,6 +3961,13 @@ static bool hci_run_general_pending_commmands(void){ hci_send_cmd(&hci_sniff_mode, connection->con_handle, connection->sniff_max_interval, sniff_min_interval, connection->sniff_attempt, connection->sniff_timeout); return true; } + + if (connection->request_role != HCI_ROLE_INVALID){ + hci_role_t role = connection->request_role; + connection->request_role = HCI_ROLE_INVALID; + hci_send_cmd(&hci_switch_role_command, connection->address, role); + return true; + } #endif #ifdef ENABLE_BLE @@ -4030,7 +4038,7 @@ static void hci_run(void){ #endif // send pending HCI commands - done = hci_run_general_pending_commmands(); + done = hci_run_general_pending_commands(); if (done) return; // stack state sub statemachines @@ -5178,6 +5186,13 @@ hci_role_t gap_get_role(hci_con_handle_t connection_handle){ } +uint8_t gap_request_role(bd_addr_t addr, hci_role_t role){ + hci_connection_t * conn = hci_connection_for_bd_addr_and_type(addr, BD_ADDR_TYPE_ACL); + if (!conn) return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; + conn->request_role = role; + hci_run(); +} + #ifdef ENABLE_BLE uint8_t gap_le_set_phy(hci_con_handle_t connection_handle, uint8_t all_phys, uint8_t tx_phys, uint8_t rx_phys, uint8_t phy_options){ diff --git a/src/hci.h b/src/hci.h index 90c859026..d64aaf8cb 100644 --- a/src/hci.h +++ b/src/hci.h @@ -530,7 +530,10 @@ typedef struct { // generate sco can send now based on received packets, using timeout below uint8_t sco_tx_ready; - + + // request role switch + hci_role_t request_role; + btstack_timer_source_t timeout_sco; #endif /* ENABLE_CLASSIC */