mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-09-09 02:30:06 +00:00
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.
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user