Skip to content

Commit

Permalink
Bluetooth: Add timeout to event & ACL buffer allocation functions
Browse files Browse the repository at this point in the history
Not all users are in an ISR context where we can't block, so give the
callers the freedom to choose if they want to block or not.

Jira: ZEP-1481

Change-Id: I19bd7e2df94c4eeb60886a17a78f872bd7bea887
Signed-off-by: Johan Hedberg <[email protected]>
  • Loading branch information
Johan Hedberg committed Dec 24, 2016
1 parent 3cbce90 commit f3c632b
Show file tree
Hide file tree
Showing 7 changed files with 27 additions and 22 deletions.
4 changes: 2 additions & 2 deletions drivers/bluetooth/hci/h4.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ static struct net_buf *h4_evt_recv(int *remaining)

*remaining = hdr.len;

buf = bt_buf_get_evt(hdr.evt);
buf = bt_buf_get_evt(hdr.evt, K_NO_WAIT);
if (buf) {
memcpy(net_buf_add(buf, sizeof(hdr)), &hdr, sizeof(hdr));
} else {
Expand All @@ -114,7 +114,7 @@ static struct net_buf *h4_acl_recv(int *remaining)
/* We can ignore the return value since we pass len == min */
h4_read(h4_dev, (void *)&hdr, sizeof(hdr), sizeof(hdr));

buf = bt_buf_get_acl();
buf = bt_buf_get_acl(K_NO_WAIT);
if (buf) {
memcpy(net_buf_add(buf, sizeof(hdr)), &hdr, sizeof(hdr));
} else {
Expand Down
4 changes: 2 additions & 2 deletions drivers/bluetooth/hci/h5.c
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ static void bt_uart_isr(struct device *unused)

switch (H5_HDR_PKT_TYPE(hdr)) {
case HCI_EVENT_PKT:
h5.rx_buf = bt_buf_get_evt(0x00);
h5.rx_buf = bt_buf_get_evt(0x00, K_NO_WAIT);
if (!h5.rx_buf) {
BT_WARN("No available event buffers");
h5_reset_rx();
Expand All @@ -485,7 +485,7 @@ static void bt_uart_isr(struct device *unused)
h5.rx_state = PAYLOAD;
break;
case HCI_ACLDATA_PKT:
h5.rx_buf = bt_buf_get_acl();
h5.rx_buf = bt_buf_get_acl(K_NO_WAIT);
if (!h5.rx_buf) {
BT_WARN("No available data buffers");
h5_reset_rx();
Expand Down
8 changes: 6 additions & 2 deletions include/drivers/bluetooth/hci_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,23 @@ extern "C" {
* CONFIG_BLUETOOTH_HOST_BUFFERS has been selected.
*
* @param opcode HCI event opcode or 0 if not known
* @param timeout Timeout in milliseconds, or one of the special values
* K_NO_WAIT and K_FOREVER.
* @return A new buffer with the BT_BUF_EVT type.
*/
struct net_buf *bt_buf_get_evt(uint8_t opcode);
struct net_buf *bt_buf_get_evt(uint8_t opcode, int32_t timeout);

/** Allocate a buffer for incoming ACL data
*
* This will set the BT_BUF_ACL_IN buffer type so bt_buf_set_type()
* doesn't need to be explicitly called. Only available when
* CONFIG_BLUETOOTH_HOST_BUFFERS has been selected.
*
* @param timeout Timeout in milliseconds, or one of the special values
* K_NO_WAIT and K_FOREVER.
* @return A new buffer with the BT_BUF_ACL_IN type.
*/
struct net_buf *bt_buf_get_acl(void);
struct net_buf *bt_buf_get_acl(int32_t timeout);

/* Receive data from the controller/HCI driver */
int bt_recv(struct net_buf *buf);
Expand Down
9 changes: 5 additions & 4 deletions subsys/bluetooth/controller/hci/hci_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,8 @@ static void recv_thread(void *p1, void *p2, void *p3)

while ((num_cmplt = radio_rx_get(&node_rx, &handle))) {

buf = bt_buf_get_evt(BT_HCI_EVT_NUM_COMPLETED_PACKETS);
buf = bt_buf_get_evt(BT_HCI_EVT_NUM_COMPLETED_PACKETS,
K_FOREVER);
if (buf) {
hci_num_cmplt_encode(buf, handle, num_cmplt);
BT_DBG("Num Complete: 0x%04x:%u", handle,
Expand All @@ -183,15 +184,15 @@ static void recv_thread(void *p1, void *p2, void *p3)
if (node_rx->hdr.type != NODE_RX_TYPE_DC_PDU ||
pdu_data->ll_id == PDU_DATA_LLID_CTRL) {
/* generate a (non-priority) HCI event */
buf = bt_buf_get_evt(0);
buf = bt_buf_get_evt(0, K_FOREVER);
if (buf) {
hci_evt_encode(node_rx, buf);
} else {
BT_ERR("Cannot allocate RX event");
}
} else {
/* generate ACL data */
buf = bt_buf_get_acl();
buf = bt_buf_get_acl(K_FOREVER);
if (buf) {
hci_acl_encode(node_rx, buf);
} else {
Expand Down Expand Up @@ -235,7 +236,7 @@ static int cmd_handle(struct net_buf *buf)
* actual point is to retrieve the event from the priority
* queue
*/
evt = bt_buf_get_evt(BT_HCI_EVT_CMD_COMPLETE);
evt = bt_buf_get_evt(BT_HCI_EVT_CMD_COMPLETE, K_FOREVER);
if (!evt) {
BT_ERR("No available event buffers");
return -ENOMEM;
Expand Down
10 changes: 5 additions & 5 deletions subsys/bluetooth/host/hci_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -4024,20 +4024,20 @@ int bt_le_scan_stop(void)
}

#if defined(CONFIG_BLUETOOTH_HOST_BUFFERS)
struct net_buf *bt_buf_get_evt(uint8_t opcode)
struct net_buf *bt_buf_get_evt(uint8_t opcode, int32_t timeout)
{
struct net_buf *buf;

switch (opcode) {
case BT_HCI_EVT_CMD_COMPLETE:
case BT_HCI_EVT_CMD_STATUS:
case BT_HCI_EVT_NUM_COMPLETED_PACKETS:
buf = net_buf_alloc(&hci_evt_prio_pool, K_NO_WAIT);
buf = net_buf_alloc(&hci_evt_prio_pool, timeout);
break;
default:
buf = net_buf_alloc(&hci_evt_pool, K_NO_WAIT);
if (!buf && opcode == 0x00) {
buf = net_buf_alloc(&hci_evt_prio_pool, K_NO_WAIT);
buf = net_buf_alloc(&hci_evt_prio_pool, timeout);
}
break;
}
Expand All @@ -4050,12 +4050,12 @@ struct net_buf *bt_buf_get_evt(uint8_t opcode)
return buf;
}

struct net_buf *bt_buf_get_acl(void)
struct net_buf *bt_buf_get_acl(int32_t timeout)
{
#if defined(CONFIG_BLUETOOTH_CONN)
struct net_buf *buf;

buf = net_buf_alloc(&acl_in_pool, K_NO_WAIT);
buf = net_buf_alloc(&acl_in_pool, timeout);
if (buf) {
net_buf_reserve(buf, CONFIG_BLUETOOTH_HCI_RECV_RESERVE);
bt_buf_set_type(buf, BT_BUF_ACL_IN);
Expand Down
6 changes: 3 additions & 3 deletions subsys/bluetooth/host/hci_ecc.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ static void send_cmd_status(uint16_t opcode, uint8_t status)

BT_DBG("opcode %x status %x", opcode, status);

buf = bt_buf_get_evt(BT_HCI_EVT_CMD_STATUS);
buf = bt_buf_get_evt(BT_HCI_EVT_CMD_STATUS, K_FOREVER);
if (!buf) {
BT_ERR("No available event buffers!");
return;
Expand Down Expand Up @@ -137,7 +137,7 @@ static void emulate_le_p256_public_key_cmd(struct net_buf *buf)

send_cmd_status(BT_HCI_OP_LE_P256_PUBLIC_KEY, 0);

buf = bt_buf_get_evt(BT_HCI_EVT_LE_META_EVENT);
buf = bt_buf_get_evt(BT_HCI_EVT_LE_META_EVENT, K_FOREVER);
if (!buf) {
BT_ERR("No available event buffers!");
return;
Expand Down Expand Up @@ -178,7 +178,7 @@ static void emulate_le_generate_dhkey(struct net_buf *buf)

net_buf_unref(buf);

buf = bt_buf_get_evt(BT_HCI_EVT_LE_META_EVENT);
buf = bt_buf_get_evt(BT_HCI_EVT_LE_META_EVENT, K_FOREVER);
if (!buf) {
BT_ERR("No available event buffers!");
return;
Expand Down
8 changes: 4 additions & 4 deletions subsys/bluetooth/host/hci_raw.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,23 +64,23 @@ void bt_hci_driver_unregister(struct bt_hci_driver *drv)
bt_dev.drv = NULL;
}

struct net_buf *bt_buf_get_evt(uint8_t opcode)
struct net_buf *bt_buf_get_evt(uint8_t opcode, int timeout)
{
struct net_buf *buf;

buf = net_buf_alloc(&hci_evt_pool, K_NO_WAIT);
buf = net_buf_alloc(&hci_evt_pool, timeout);
if (buf) {
bt_buf_set_type(buf, BT_BUF_EVT);
}

return buf;
}

struct net_buf *bt_buf_get_acl(void)
struct net_buf *bt_buf_get_acl(int32_t timeout)
{
struct net_buf *buf;

buf = net_buf_alloc(&acl_in_pool, K_NO_WAIT);
buf = net_buf_alloc(&acl_in_pool, timeout);
if (buf) {
bt_buf_set_type(buf, BT_BUF_ACL_IN);
}
Expand Down

0 comments on commit f3c632b

Please sign in to comment.