Skip to content

Commit f597c81

Browse files
committed
Bluetooth: controller: Add LE Read Chan Map command
Implement the LE Read Channel Map HCI command, along with making the reading of the multi-byte channel map value from the connection pointer thread-safe in case the ISR triggers while we are reading the value. Signed-off-by: Carles Cufi <[email protected]>
1 parent a5fcafa commit f597c81

File tree

4 files changed

+31
-5
lines changed

4 files changed

+31
-5
lines changed

include/bluetooth/hci.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -822,7 +822,7 @@ struct bt_hci_cp_le_set_host_chan_classif {
822822
struct bt_hci_cp_le_read_chan_map {
823823
u16_t handle;
824824
} __packed;
825-
struct bt_hci_rp_le_read_ch_map {
825+
struct bt_hci_rp_le_read_chan_map {
826826
u8_t status;
827827
u16_t handle;
828828
u8_t ch_map[5];

subsys/bluetooth/controller/hci/hci.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -506,8 +506,8 @@ static void read_supported_commands(struct net_buf *buf, struct net_buf **evt)
506506
#if defined(CONFIG_BT_CONN)
507507
/* Disconnect. */
508508
rp->commands[0] |= BIT(5);
509-
/* LE Connection Update, LE Read Remote Features */
510-
rp->commands[27] |= BIT(2) | BIT(5);
509+
/* LE Connection Update, LE Read Channel Map, LE Read Remote Features */
510+
rp->commands[27] |= BIT(2) | BIT(4) | BIT(5);
511511
/* LE Remote Conn Param Req and Neg Reply */
512512
rp->commands[33] |= BIT(4) | BIT(5);
513513
#if defined(CONFIG_BT_CTLR_LE_PING)
@@ -1029,6 +1029,21 @@ static void le_read_remote_features(struct net_buf *buf, struct net_buf **evt)
10291029

10301030
*evt = cmd_status((!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED);
10311031
}
1032+
static void le_read_chan_map(struct net_buf *buf, struct net_buf **evt)
1033+
{
1034+
struct bt_hci_cp_le_read_chan_map *cmd = (void *)buf->data;
1035+
struct bt_hci_rp_le_read_chan_map *rp;
1036+
u32_t status;
1037+
u16_t handle;
1038+
1039+
handle = sys_le16_to_cpu(cmd->handle);
1040+
1041+
rp = cmd_complete(evt, sizeof(*rp));
1042+
status = ll_chm_get(handle, rp->ch_map);
1043+
1044+
rp->status = (!status) ? 0x00 : BT_HCI_ERR_UNKNOWN_CONN_ID;
1045+
rp->handle = sys_le16_to_cpu(handle);
1046+
}
10321047

10331048
static void le_conn_update(struct net_buf *buf, struct net_buf **evt)
10341049
{
@@ -1441,6 +1456,10 @@ static int controller_cmd_handle(u16_t ocf, struct net_buf *cmd,
14411456
#endif /* CONFIG_BT_CTLR_LE_ENC */
14421457
#endif /* CONFIG_BT_PERIPHERAL */
14431458

1459+
case BT_OCF(BT_HCI_OP_LE_READ_CHAN_MAP):
1460+
le_read_chan_map(cmd, evt);
1461+
break;
1462+
14441463
case BT_OCF(BT_HCI_OP_LE_READ_REMOTE_FEATURES):
14451464
le_read_remote_features(cmd, evt);
14461465
break;

subsys/bluetooth/controller/ll_sw/ctrl.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6317,6 +6317,7 @@ static inline void event_ch_map_prep(struct connection *conn,
63176317
conn->data_chan_count =
63186318
util_ones_count_get(&conn->data_chan_map[0],
63196319
sizeof(conn->data_chan_map));
6320+
conn->chm_update = 1;
63206321
}
63216322

63226323
}
@@ -9577,8 +9578,13 @@ u32_t ll_chm_get(u16_t handle, u8_t *chm)
95779578
return 1;
95789579
}
95799580

9580-
/** @todo make reading context-safe */
9581-
memcpy(chm, conn->data_chan_map, sizeof(conn->data_chan_map));
9581+
/* Iterate until we are sure the ISR did not modify the value while
9582+
* we were reading it from memory.
9583+
*/
9584+
do {
9585+
conn->chm_update = 0;
9586+
memcpy(chm, conn->data_chan_map, sizeof(conn->data_chan_map));
9587+
} while (conn->chm_update);
95829588

95839589
return 0;
95849590
}

subsys/bluetooth/controller/ll_sw/ctrl_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ struct connection {
4141
u8_t access_addr[4];
4242
u8_t crc_init[3];
4343
u8_t data_chan_map[5];
44+
u8_t chm_update;
4445

4546
u8_t data_chan_count:6;
4647
u8_t data_chan_sel:1;

0 commit comments

Comments
 (0)