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)
|
static int hci_driver_send(struct net_buf *buf)
|
||||||
{
|
{
|
||||||
uint8_t evt_len;
|
uint8_t type;
|
||||||
uint8_t *in;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
BT_DBG("enter");
|
BT_DBG("enter");
|
||||||
|
|
||||||
evt_len = 0;
|
if (!buf->len) {
|
||||||
err = hci_handle(buf, &evt_len, &in);
|
BT_ERR("Empty HCI packet");
|
||||||
|
return -EINVAL;
|
||||||
if (err) {
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BT_DBG("hci_handle returned %u bytes", evt_len);
|
type = bt_buf_get_type(buf);
|
||||||
if (evt_len) {
|
switch (type) {
|
||||||
err = evt_acl_create(evt_len, in);
|
case BT_BUF_ACL_OUT:
|
||||||
if (err) {
|
err = hci_acl_handle(buf);
|
||||||
return err;
|
break;
|
||||||
}
|
case BT_BUF_CMD:
|
||||||
|
err = cmd_handle(buf);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BT_ERR("Unknown HCI type %u", type);
|
||||||
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!err) {
|
||||||
net_buf_unref(buf);
|
net_buf_unref(buf);
|
||||||
|
}
|
||||||
|
|
||||||
BT_DBG("exit");
|
BT_DBG("exit: %d", err);
|
||||||
|
|
||||||
return 0;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hci_driver_open(void)
|
static int hci_driver_open(void)
|
||||||
|
|
|
@ -18,9 +18,8 @@
|
||||||
#ifndef _HCI_CONTROLLER_H_
|
#ifndef _HCI_CONTROLLER_H_
|
||||||
#define _HCI_CONTROLLER_H_
|
#define _HCI_CONTROLLER_H_
|
||||||
|
|
||||||
#include <net/buf.h>
|
int hci_cmd_handle(struct net_buf *cmd, struct net_buf *evt);
|
||||||
|
int hci_acl_handle(struct net_buf *acl);
|
||||||
int hci_handle(struct net_buf *buf, uint8_t *len, uint8_t **out);
|
|
||||||
void hcic_encode(uint8_t *buf, uint8_t *len, uint8_t **out);
|
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,
|
void hcic_encode_num_cmplt(uint16_t instance, uint8_t num, uint8_t *len,
|
||||||
uint8_t **out);
|
uint8_t **out);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue