Bluetooth: controller: Issue Data Buffer Overflow event
Whenever the HCI ACL flow control is violated by the Host, a Data Buffer Overflow event is now issued by the Controller (if enabled) to notify the Host of the buffer overrun. Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
This commit is contained in:
parent
c4efc11ffd
commit
b77b8e615b
4 changed files with 47 additions and 4 deletions
|
@ -1438,6 +1438,15 @@ struct bt_hci_evt_link_key_notify {
|
|||
u8_t key_type;
|
||||
} __packed;
|
||||
|
||||
/* Overflow link types */
|
||||
#define BT_OVERFLOW_LINK_SYNCH 0x00
|
||||
#define BT_OVERFLOW_LINK_ACL 0x01
|
||||
|
||||
#define BT_HCI_EVT_DATA_BUF_OVERFLOW 0x1a
|
||||
struct bt_hci_evt_data_buf_overflow {
|
||||
u8_t link_type;
|
||||
} __packed;
|
||||
|
||||
#define BT_HCI_EVT_INQUIRY_RESULT_WITH_RSSI 0x22
|
||||
struct bt_hci_evt_inquiry_result_with_rssi {
|
||||
bt_addr_t addr;
|
||||
|
|
|
@ -1811,6 +1811,21 @@ static int vendor_cmd_handle(u16_t ocf, struct net_buf *cmd,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void data_buf_overflow(struct net_buf **buf)
|
||||
{
|
||||
struct bt_hci_evt_data_buf_overflow *ep;
|
||||
|
||||
if (!(event_mask & BT_EVT_MASK_DATA_BUFFER_OVERFLOW)) {
|
||||
return;
|
||||
}
|
||||
|
||||
*buf = bt_buf_get_rx(BT_BUF_EVT, K_FOREVER);
|
||||
evt_create(*buf, BT_HCI_EVT_DATA_BUF_OVERFLOW, sizeof(*ep));
|
||||
ep = net_buf_add(*buf, sizeof(*ep));
|
||||
|
||||
ep->link_type = BT_OVERFLOW_LINK_ACL;
|
||||
}
|
||||
|
||||
struct net_buf *hci_cmd_handle(struct net_buf *cmd)
|
||||
{
|
||||
struct bt_hci_evt_cc_status *ccst;
|
||||
|
@ -1869,7 +1884,7 @@ struct net_buf *hci_cmd_handle(struct net_buf *cmd)
|
|||
return evt;
|
||||
}
|
||||
|
||||
int hci_acl_handle(struct net_buf *buf)
|
||||
int hci_acl_handle(struct net_buf *buf, struct net_buf **evt)
|
||||
{
|
||||
struct radio_pdu_node_tx *radio_pdu_node_tx;
|
||||
struct bt_hci_acl_hdr *acl;
|
||||
|
@ -1878,6 +1893,8 @@ int hci_acl_handle(struct net_buf *buf)
|
|||
u8_t flags;
|
||||
u16_t len;
|
||||
|
||||
*evt = NULL;
|
||||
|
||||
if (buf->len < sizeof(*acl)) {
|
||||
BT_ERR("No HCI ACL header");
|
||||
return -EINVAL;
|
||||
|
@ -1900,6 +1917,7 @@ int hci_acl_handle(struct net_buf *buf)
|
|||
radio_pdu_node_tx = radio_tx_mem_acquire();
|
||||
if (!radio_pdu_node_tx) {
|
||||
BT_ERR("Tx Buffer Overflow");
|
||||
data_buf_overflow(evt);
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
|
|
|
@ -347,6 +347,22 @@ static int cmd_handle(struct net_buf *buf)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_CONN)
|
||||
static int acl_handle(struct net_buf *buf)
|
||||
{
|
||||
struct net_buf *evt;
|
||||
int err;
|
||||
|
||||
err = hci_acl_handle(buf, &evt);
|
||||
if (evt) {
|
||||
BT_DBG("Replying with event of %u bytes", evt->len);
|
||||
bt_recv_prio(evt);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
#endif /* CONFIG_BT_CONN */
|
||||
|
||||
static int hci_driver_send(struct net_buf *buf)
|
||||
{
|
||||
u8_t type;
|
||||
|
@ -363,9 +379,9 @@ static int hci_driver_send(struct net_buf *buf)
|
|||
switch (type) {
|
||||
#if defined(CONFIG_BT_CONN)
|
||||
case BT_BUF_ACL_OUT:
|
||||
err = hci_acl_handle(buf);
|
||||
err = acl_handle(buf);
|
||||
break;
|
||||
#endif
|
||||
#endif /* CONFIG_BT_CONN */
|
||||
case BT_BUF_CMD:
|
||||
err = cmd_handle(buf);
|
||||
break;
|
||||
|
|
|
@ -39,7 +39,7 @@ struct net_buf *hci_cmd_handle(struct net_buf *cmd);
|
|||
void hci_evt_encode(struct radio_pdu_node_rx *node_rx, struct net_buf *buf);
|
||||
s8_t hci_get_class(struct radio_pdu_node_rx *node_rx);
|
||||
#if defined(CONFIG_BT_CONN)
|
||||
int hci_acl_handle(struct net_buf *acl);
|
||||
int hci_acl_handle(struct net_buf *acl, struct net_buf **evt);
|
||||
void hci_acl_encode(struct radio_pdu_node_rx *node_rx, struct net_buf *buf);
|
||||
void hci_num_cmplt_encode(struct net_buf *buf, u16_t handle, u8_t num);
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue