This is an automated email from the ASF dual-hosted git repository. andk pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git
commit 94d9faf080c91f5e92c5f2677867a16ef94bc089 Author: Andrzej Kaczmarek <[email protected]> AuthorDate: Tue Jan 31 12:38:58 2023 +0100 nimble/ll: Fix global chan_map handling Global channel map should be handled by common code so need to move it out of ble_ll_conn. --- nimble/controller/include/controller/ble_ll_conn.h | 3 ++ nimble/controller/src/ble_ll_conn.c | 20 ++----------- nimble/controller/src/ble_ll_conn_hci.c | 32 --------------------- nimble/controller/src/ble_ll_conn_priv.h | 1 - nimble/controller/src/ble_ll_hci.c | 33 +++++++++++++++++++++- 5 files changed, 37 insertions(+), 52 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index a44e802e..016e5abd 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -459,6 +459,9 @@ struct ble_ll_conn_sm *ble_ll_conn_find_by_handle(uint16_t handle); struct ble_ll_conn_sm *ble_ll_conn_find_by_peer_addr(const uint8_t* addr, uint8_t addr_type); +/* Perform channel map update on all connections (applies to central role) */ +void ble_ll_conn_chan_map_update(void); + /* required for unit testing */ uint8_t ble_ll_conn_calc_dci(struct ble_ll_conn_sm *conn, uint16_t latency); diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 8992c386..0c6530b5 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -4023,29 +4023,13 @@ ble_ll_conn_tx_pkt_in(struct os_mbuf *om, uint16_t handle, uint16_t length) } } #endif -/** - * Called to set the global channel mask that we use for all connections. - * - * @param num_used_chans - * @param chanmap - */ + void -ble_ll_conn_set_global_chanmap(uint8_t num_used_chans, const uint8_t *chanmap) +ble_ll_conn_chan_map_update(void) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) struct ble_ll_conn_sm *connsm; -#endif - /* Do nothing if same channel map */ - if (!memcmp(g_ble_ll_data.chan_map, chanmap, BLE_LL_CHAN_MAP_LEN)) { - return; - } - - /* Change channel map and cause channel map update procedure to start */ - g_ble_ll_data.chan_map_used = num_used_chans; - memcpy(g_ble_ll_data.chan_map, chanmap, BLE_LL_CHAN_MAP_LEN); - -#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) /* Perform channel map update */ SLIST_FOREACH(connsm, &g_ble_ll_conn_active_list, act_sle) { if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index dbda28bb..5010dddb 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -1432,38 +1432,6 @@ ble_ll_conn_hci_rd_chan_map(const uint8_t *cmdbuf, uint8_t len, } #endif -/** - * Called when the host issues the LE command "set host channel classification" - * - * @param cmdbuf - * - * @return int - */ -int -ble_ll_conn_hci_set_chan_class(const uint8_t *cmdbuf, uint8_t len) -{ - const struct ble_hci_le_set_host_chan_class_cp *cmd = (const void *) cmdbuf; - uint8_t num_used_chans; - - if (len != sizeof(*cmd)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - /* - * The HCI command states that the host is allowed to mask in just one - * channel but the Link Layer needs minimum two channels to operate. So - * I will not allow this command if there are less than 2 channels masked. - */ - num_used_chans = ble_ll_utils_chan_map_used_get(cmd->chan_map); - if ((num_used_chans < 2) || ((cmd->chan_map[4] & 0xe0) != 0)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - /* Set the host channel mask */ - ble_ll_conn_set_global_chanmap(num_used_chans, cmd->chan_map); - return BLE_ERR_SUCCESS; -} - #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_DATA_LEN_EXT) diff --git a/nimble/controller/src/ble_ll_conn_priv.h b/nimble/controller/src/ble_ll_conn_priv.h index bb58e4b7..023881d0 100644 --- a/nimble/controller/src/ble_ll_conn_priv.h +++ b/nimble/controller/src/ble_ll_conn_priv.h @@ -182,7 +182,6 @@ int ble_ll_conn_periph_start(uint8_t *rxbuf, uint8_t pat, /* Link Layer interface */ void ble_ll_conn_module_init(void); -void ble_ll_conn_set_global_chanmap(uint8_t num_used_chans, const uint8_t *chanmap); void ble_ll_conn_module_reset(void); void ble_ll_conn_tx_pkt_in(struct os_mbuf *om, uint16_t handle, uint16_t len); int ble_ll_conn_rx_isr_start(struct ble_mbuf_hdr *rxhdr, uint32_t aa); diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index fab30493..695e6533 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -33,6 +33,7 @@ #include "controller/ble_ll_whitelist.h" #include "controller/ble_ll_resolv.h" #include "controller/ble_ll_sync.h" +#include <controller/ble_ll_utils.h> #include "controller/ble_ll_iso.h" #include "ble_ll_priv.h" #include "ble_ll_conn_priv.h" @@ -833,6 +834,36 @@ ble_ll_write_rf_path_compensation(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_SUCCESS; } +static int +ble_ll_hci_le_set_host_chan_class(const uint8_t *cmdbuf, uint8_t len) +{ + const struct ble_hci_le_set_host_chan_class_cp *cmd = (const void *)cmdbuf; + uint8_t chan_map_used; + + if (len != sizeof(*cmd)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + /* HCI command allows only single channel to be enabled, but LL needs at + * least 2 channels to work so let's reject in such case. + */ + chan_map_used = ble_ll_utils_chan_map_used_get(cmd->chan_map); + if ((chan_map_used < 2) || (cmd->chan_map[4] & 0xe0)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + if (!memcmp(g_ble_ll_data.chan_map, cmd->chan_map, BLE_LL_CHAN_MAP_LEN)) { + return BLE_ERR_SUCCESS; + } + + memcpy(g_ble_ll_data.chan_map, cmd->chan_map, BLE_LL_CHAN_MAP_LEN); + g_ble_ll_data.chan_map_used = chan_map_used; + + ble_ll_conn_chan_map_update(); + + return BLE_ERR_SUCCESS; +} + /** * Process a LE command sent from the host to the controller. The HCI command * has a 3 byte command header followed by data. The header is: @@ -957,7 +988,7 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, break; #endif case BLE_HCI_OCF_LE_SET_HOST_CHAN_CLASS: - rc = ble_ll_conn_hci_set_chan_class(cmdbuf, len); + rc = ble_ll_hci_le_set_host_chan_class(cmdbuf, len); break; #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_HCI_OCF_LE_RD_CHAN_MAP:
