Bluetooth: Controller: Use net_buf for CC/CS TX
Preallocate a response event net_buf buffer before processing an incoming command and provide it to hci.c so that it populates the event directly, instead of using a temporary buffer than must then be copied into the return net_buf. This applies exclusively to Command Complete and Command Status, since those are the only events that are sent in direct respone to an incoming command. Jira: ZEP-726 Change-Id: Ia3ea71ac497690af929c44308760f68491ea829e Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
This commit is contained in:
parent
6877651a30
commit
0a720c4771
3 changed files with 273 additions and 337 deletions
File diff suppressed because it is too large
Load diff
|
@ -265,34 +265,65 @@ static void recv_fiber(int unused0, int unused1)
|
|||
}
|
||||
}
|
||||
|
||||
static int cmd_handle(struct net_buf *buf)
|
||||
{
|
||||
struct net_buf *evt;
|
||||
int err;
|
||||
|
||||
/* Preallocate the response event so that there is no need for
|
||||
* memory checking in hci_cmd_handle().
|
||||
* this might actually be CMD_COMPLETE or CMD_STATUS, but the
|
||||
* actual point is to retrieve the event from the priority
|
||||
* queue
|
||||
*/
|
||||
evt = bt_buf_get_evt(BT_HCI_EVT_CMD_COMPLETE);
|
||||
if (!evt) {
|
||||
BT_ERR("No available event buffers");
|
||||
return -ENOMEM;
|
||||
}
|
||||
err = hci_cmd_handle(buf, evt);
|
||||
if (!err && evt->len) {
|
||||
BT_DBG("Replying with event of %u bytes", evt->len);
|
||||
bt_recv(evt);
|
||||
} else {
|
||||
net_buf_unref(evt);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int hci_driver_send(struct net_buf *buf)
|
||||
{
|
||||
uint8_t evt_len;
|
||||
uint8_t *in;
|
||||
uint8_t type;
|
||||
int err;
|
||||
|
||||
BT_DBG("enter");
|
||||
|
||||
evt_len = 0;
|
||||
err = hci_handle(buf, &evt_len, &in);
|
||||
|
||||
if (err) {
|
||||
return err;
|
||||
if (!buf->len) {
|
||||
BT_ERR("Empty HCI packet");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
BT_DBG("hci_handle returned %u bytes", evt_len);
|
||||
if (evt_len) {
|
||||
err = evt_acl_create(evt_len, in);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
type = bt_buf_get_type(buf);
|
||||
switch (type) {
|
||||
case BT_BUF_ACL_OUT:
|
||||
err = hci_acl_handle(buf);
|
||||
break;
|
||||
case BT_BUF_CMD:
|
||||
err = cmd_handle(buf);
|
||||
break;
|
||||
default:
|
||||
BT_ERR("Unknown HCI type %u", type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
net_buf_unref(buf);
|
||||
if (!err) {
|
||||
net_buf_unref(buf);
|
||||
}
|
||||
|
||||
BT_DBG("exit");
|
||||
BT_DBG("exit: %d", err);
|
||||
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int hci_driver_open(void)
|
||||
|
|
|
@ -18,9 +18,8 @@
|
|||
#ifndef _HCI_CONTROLLER_H_
|
||||
#define _HCI_CONTROLLER_H_
|
||||
|
||||
#include <net/buf.h>
|
||||
|
||||
int hci_handle(struct net_buf *buf, uint8_t *len, uint8_t **out);
|
||||
int hci_cmd_handle(struct net_buf *cmd, struct net_buf *evt);
|
||||
int hci_acl_handle(struct net_buf *acl);
|
||||
void hcic_encode(uint8_t *buf, uint8_t *len, uint8_t **out);
|
||||
void hcic_encode_num_cmplt(uint16_t instance, uint8_t num, uint8_t *len,
|
||||
uint8_t **out);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue