Bluetooth: Controller: Use net_buf for evt and ACL RX
Use the net_buf structure directly when populating incoming ACL data or asynchronous events. This ensures that no additional memcpy() operations are required and removes completely the statically allocated buffers in hci.c. Jira: ZEP-726 Change-Id: I6ac8bd0becb7037ce8ecfac109f44832d23fcfd2 Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
This commit is contained in:
parent
36b8e8cdc8
commit
2f33724017
3 changed files with 165 additions and 331 deletions
|
@ -42,54 +42,19 @@
|
||||||
|
|
||||||
#define HCI_PACKET_SIZE_MAX 255
|
#define HCI_PACKET_SIZE_MAX 255
|
||||||
|
|
||||||
enum {
|
|
||||||
HCI_CMD = 0x01,
|
|
||||||
HCI_DATA = 0x02,
|
|
||||||
HCI_EVT = 0x04,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* opcode of the HCI command currently being processed. The opcode is stored
|
/* opcode of the HCI command currently being processed. The opcode is stored
|
||||||
* by hci_cmd_handle() and then used during the creation of cmd complete and
|
* by hci_cmd_handle() and then used during the creation of cmd complete and
|
||||||
* cmd status events to avoid passing it up the call chain.
|
* cmd status events to avoid passing it up the call chain.
|
||||||
*/
|
*/
|
||||||
static uint16_t _opcode;
|
static uint16_t _opcode;
|
||||||
|
|
||||||
static struct {
|
static void evt_create(struct net_buf *buf, uint8_t evt, uint8_t len)
|
||||||
uint8_t tx[HCI_PACKET_SIZE_MAX];
|
|
||||||
} hci_context;
|
|
||||||
|
|
||||||
/* event packet length */
|
|
||||||
#define HCI_EVT_LEN(evt) ((uint8_t)(1 + sizeof(struct bt_hci_evt_hdr) + \
|
|
||||||
evt->len))
|
|
||||||
|
|
||||||
/* data packet length */
|
|
||||||
#define HCI_DATA_LEN(data_hdr) ((uint8_t)(1 + sizeof(struct bt_hci_acl_hdr) + \
|
|
||||||
data_hdr->len))
|
|
||||||
|
|
||||||
/* le meta event length */
|
|
||||||
#define HCI_ME_LEN(type) ((uint8_t)(sizeof(struct bt_hci_evt_le_meta_event) + \
|
|
||||||
sizeof(type)))
|
|
||||||
|
|
||||||
/* direct access to the event parameters */
|
|
||||||
#define HCI_EVTP(evt_hdr) ((void *)((uint8_t *)evt_hdr + \
|
|
||||||
sizeof(struct bt_hci_evt_hdr)))
|
|
||||||
|
|
||||||
/* direct access to the LE meta event parameters */
|
|
||||||
#define HCI_ME(evt_hdr) ((struct bt_hci_evt_le_meta_event *)HCI_EVTP(evt_hdr))
|
|
||||||
|
|
||||||
/* direct access to the meta event subevent */
|
|
||||||
#define HCI_SE(evt_hdr) ((void *)(((uint8_t *)HCI_EVTP(evt_hdr)) + \
|
|
||||||
sizeof(struct bt_hci_evt_le_meta_event)))
|
|
||||||
|
|
||||||
static void *evt_create(struct net_buf *buf, uint8_t evt, uint8_t len)
|
|
||||||
{
|
{
|
||||||
struct bt_hci_evt_hdr *hdr;
|
struct bt_hci_evt_hdr *hdr;
|
||||||
|
|
||||||
hdr = net_buf_add(buf, sizeof(*hdr));
|
hdr = net_buf_add(buf, sizeof(*hdr));
|
||||||
hdr->evt = evt;
|
hdr->evt = evt;
|
||||||
hdr->len = len;
|
hdr->len = len;
|
||||||
|
|
||||||
return buf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *cmd_complete(struct net_buf *buf, uint8_t plen)
|
static void *cmd_complete(struct net_buf *buf, uint8_t plen)
|
||||||
|
@ -116,6 +81,17 @@ static void cmd_status(struct net_buf *buf, uint8_t status)
|
||||||
cs->opcode = sys_cpu_to_le16(_opcode);
|
cs->opcode = sys_cpu_to_le16(_opcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *meta_evt(struct net_buf *buf, uint8_t subevt, uint8_t melen)
|
||||||
|
{
|
||||||
|
struct bt_hci_evt_le_meta_event *me;
|
||||||
|
|
||||||
|
evt_create(buf, BT_HCI_EVT_LE_META_EVENT, sizeof(*me) + melen);
|
||||||
|
me = net_buf_add(buf, sizeof(*me));
|
||||||
|
me->subevent = subevt;
|
||||||
|
|
||||||
|
return net_buf_add(buf, melen);
|
||||||
|
}
|
||||||
|
|
||||||
static void disconnect(struct net_buf *buf, struct net_buf *evt)
|
static void disconnect(struct net_buf *buf, struct net_buf *evt)
|
||||||
{
|
{
|
||||||
struct bt_hci_cp_disconnect *cmd = (void *)buf->data;
|
struct bt_hci_cp_disconnect *cmd = (void *)buf->data;
|
||||||
|
@ -918,56 +894,55 @@ int hci_acl_handle(struct net_buf *buf)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void le_advertising_report(struct pdu_data *pdu_data, uint8_t *buf,
|
static void le_advertising_report(struct pdu_data *pdu_data, uint8_t *b,
|
||||||
struct bt_hci_evt_hdr *evt)
|
struct net_buf *buf)
|
||||||
{
|
{
|
||||||
const uint8_t c_adv_type[] = { 0x00, 0x01, 0x03, 0xff, 0x04,
|
const uint8_t c_adv_type[] = { 0x00, 0x01, 0x03, 0xff, 0x04,
|
||||||
0xff, 0x02 };
|
0xff, 0x02 };
|
||||||
struct bt_hci_ev_le_advertising_report *sep = HCI_SE(evt);
|
struct bt_hci_ev_le_advertising_report *sep;
|
||||||
struct pdu_adv *adv = (struct pdu_adv *)pdu_data;
|
struct pdu_adv *adv = (struct pdu_adv *)pdu_data;
|
||||||
struct bt_hci_ev_le_advertising_info *adv_info;
|
struct bt_hci_ev_le_advertising_info *adv_info;
|
||||||
uint8_t data_len;
|
uint8_t data_len;
|
||||||
uint8_t *rssi;
|
uint8_t *rssi;
|
||||||
|
uint8_t info_len;
|
||||||
|
|
||||||
adv_info = (void *)(((uint8_t *)sep) + sizeof(*sep));
|
|
||||||
|
|
||||||
evt->evt = BT_HCI_EVT_LE_META_EVENT;
|
|
||||||
evt->len = HCI_ME_LEN(*sep);
|
|
||||||
|
|
||||||
HCI_ME(evt)->subevent = BT_HCI_EVT_LE_ADVERTISING_REPORT;
|
|
||||||
|
|
||||||
sep->num_reports = 1;
|
|
||||||
|
|
||||||
adv_info->evt_type = c_adv_type[adv->type];
|
|
||||||
adv_info->addr.type = adv->tx_addr;
|
|
||||||
memcpy(&adv_info->addr.a.val[0], &adv->payload.adv_ind.addr[0],
|
|
||||||
sizeof(bt_addr_t));
|
|
||||||
if (adv->type != PDU_ADV_TYPE_DIRECT_IND) {
|
if (adv->type != PDU_ADV_TYPE_DIRECT_IND) {
|
||||||
data_len = (adv->len - BDADDR_SIZE);
|
data_len = (adv->len - BDADDR_SIZE);
|
||||||
} else {
|
} else {
|
||||||
data_len = 0;
|
data_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info_len = sizeof(struct bt_hci_ev_le_advertising_info) + data_len +
|
||||||
|
sizeof(*rssi);
|
||||||
|
sep = meta_evt(buf, BT_HCI_EVT_LE_ADVERTISING_REPORT,
|
||||||
|
sizeof(*sep) + info_len);
|
||||||
|
|
||||||
|
sep->num_reports = 1;
|
||||||
|
adv_info = (void *)(((uint8_t *)sep) + sizeof(*sep));
|
||||||
|
|
||||||
|
adv_info->evt_type = c_adv_type[adv->type];
|
||||||
|
adv_info->addr.type = adv->tx_addr;
|
||||||
|
memcpy(&adv_info->addr.a.val[0], &adv->payload.adv_ind.addr[0],
|
||||||
|
sizeof(bt_addr_t));
|
||||||
|
|
||||||
adv_info->length = data_len;
|
adv_info->length = data_len;
|
||||||
memcpy(&adv_info->data[0], &adv->payload.adv_ind.data[0], data_len);
|
memcpy(&adv_info->data[0], &adv->payload.adv_ind.data[0], data_len);
|
||||||
/* RSSI */
|
/* RSSI */
|
||||||
rssi = &adv_info->data[0] + data_len;
|
rssi = &adv_info->data[0] + data_len;
|
||||||
*rssi = buf[offsetof(struct radio_pdu_node_rx, pdu_data) +
|
*rssi = b[offsetof(struct radio_pdu_node_rx, pdu_data) +
|
||||||
offsetof(struct pdu_adv, payload) + adv->len];
|
offsetof(struct pdu_adv, payload) + adv->len];
|
||||||
|
|
||||||
evt->len += sizeof(struct bt_hci_ev_le_advertising_info) + data_len + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void le_conn_complete(struct pdu_data *pdu_data, uint16_t handle,
|
static void le_conn_complete(struct pdu_data *pdu_data, uint16_t handle,
|
||||||
struct bt_hci_evt_hdr *evt)
|
struct net_buf *buf)
|
||||||
{
|
{
|
||||||
struct bt_hci_evt_le_conn_complete *sep = HCI_SE(evt);
|
struct bt_hci_evt_le_conn_complete *sep;
|
||||||
struct radio_le_conn_cmplt *radio_cc;
|
struct radio_le_conn_cmplt *radio_cc;
|
||||||
|
|
||||||
radio_cc = (struct radio_le_conn_cmplt *) (pdu_data->payload.lldata);
|
radio_cc = (struct radio_le_conn_cmplt *) (pdu_data->payload.lldata);
|
||||||
|
|
||||||
evt->evt = BT_HCI_EVT_LE_META_EVENT;
|
sep = meta_evt(buf, BT_HCI_EVT_LE_CONN_COMPLETE, sizeof(*sep));
|
||||||
evt->len = HCI_ME_LEN(*sep);
|
|
||||||
HCI_ME(evt)->subevent = BT_HCI_EVT_LE_CONN_COMPLETE;
|
|
||||||
|
|
||||||
sep->status = radio_cc->status;
|
sep->status = radio_cc->status;
|
||||||
sep->handle = sys_cpu_to_le16(handle);
|
sep->handle = sys_cpu_to_le16(handle);
|
||||||
|
@ -981,12 +956,12 @@ static void le_conn_complete(struct pdu_data *pdu_data, uint16_t handle,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void disconn_complete(struct pdu_data *pdu_data, uint16_t handle,
|
static void disconn_complete(struct pdu_data *pdu_data, uint16_t handle,
|
||||||
struct bt_hci_evt_hdr *evt)
|
struct net_buf *buf)
|
||||||
{
|
{
|
||||||
struct bt_hci_evt_disconn_complete *ep = HCI_EVTP(evt);
|
struct bt_hci_evt_disconn_complete *ep;
|
||||||
|
|
||||||
evt->evt = BT_HCI_EVT_DISCONN_COMPLETE;
|
evt_create(buf, BT_HCI_EVT_DISCONN_COMPLETE, sizeof(*ep));
|
||||||
evt->len = sizeof(*ep);
|
ep = net_buf_add(buf, sizeof(*ep));
|
||||||
|
|
||||||
ep->status = 0x00;
|
ep->status = 0x00;
|
||||||
ep->handle = sys_cpu_to_le16(handle);
|
ep->handle = sys_cpu_to_le16(handle);
|
||||||
|
@ -994,17 +969,15 @@ static void disconn_complete(struct pdu_data *pdu_data, uint16_t handle,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void le_conn_update_complete(struct pdu_data *pdu_data, uint16_t handle,
|
static void le_conn_update_complete(struct pdu_data *pdu_data, uint16_t handle,
|
||||||
struct bt_hci_evt_hdr *evt)
|
struct net_buf *buf)
|
||||||
{
|
{
|
||||||
struct bt_hci_evt_le_conn_update_complete *sep = HCI_SE(evt);
|
struct bt_hci_evt_le_conn_update_complete *sep;
|
||||||
struct radio_le_conn_update_cmplt *radio_cu;
|
struct radio_le_conn_update_cmplt *radio_cu;
|
||||||
|
|
||||||
radio_cu = (struct radio_le_conn_update_cmplt *)
|
radio_cu = (struct radio_le_conn_update_cmplt *)
|
||||||
(pdu_data->payload.lldata);
|
(pdu_data->payload.lldata);
|
||||||
|
|
||||||
evt->evt = BT_HCI_EVT_LE_META_EVENT;
|
sep = meta_evt(buf, BT_HCI_EVT_LE_CONN_UPDATE_COMPLETE, sizeof(*sep));
|
||||||
evt->len = HCI_ME_LEN(*sep);
|
|
||||||
HCI_ME(evt)->subevent = BT_HCI_EVT_LE_CONN_UPDATE_COMPLETE;
|
|
||||||
|
|
||||||
sep->status = radio_cu->status;
|
sep->status = radio_cu->status;
|
||||||
sep->handle = sys_cpu_to_le16(handle);
|
sep->handle = sys_cpu_to_le16(handle);
|
||||||
|
@ -1014,60 +987,59 @@ static void le_conn_update_complete(struct pdu_data *pdu_data, uint16_t handle,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void enc_refresh_complete(struct pdu_data *pdu_data, uint16_t handle,
|
static void enc_refresh_complete(struct pdu_data *pdu_data, uint16_t handle,
|
||||||
struct bt_hci_evt_hdr *evt)
|
struct net_buf *buf)
|
||||||
{
|
{
|
||||||
struct bt_hci_evt_encrypt_key_refresh_complete *ep = HCI_EVTP(evt);
|
struct bt_hci_evt_encrypt_key_refresh_complete *ep;
|
||||||
|
|
||||||
evt->evt = BT_HCI_EVT_ENCRYPT_KEY_REFRESH_COMPLETE;
|
evt_create(buf, BT_HCI_EVT_ENCRYPT_KEY_REFRESH_COMPLETE, sizeof(*ep));
|
||||||
evt->len = sizeof(*ep);
|
ep = net_buf_add(buf, sizeof(*ep));
|
||||||
|
|
||||||
ep->status = 0x00;
|
ep->status = 0x00;
|
||||||
ep->handle = sys_cpu_to_le16(handle);
|
ep->handle = sys_cpu_to_le16(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void auth_payload_timeout_exp(struct pdu_data *pdu_data, uint16_t handle,
|
static void auth_payload_timeout_exp(struct pdu_data *pdu_data, uint16_t handle,
|
||||||
struct bt_hci_evt_hdr *evt)
|
struct net_buf *buf)
|
||||||
{
|
{
|
||||||
struct bt_hci_evt_auth_payload_timeout_exp *ep = HCI_EVTP(evt);
|
struct bt_hci_evt_auth_payload_timeout_exp *ep;
|
||||||
|
|
||||||
evt->evt = BT_HCI_EVT_AUTH_PAYLOAD_TIMEOUT_EXP;
|
evt_create(buf, BT_HCI_EVT_AUTH_PAYLOAD_TIMEOUT_EXP, sizeof(*ep));
|
||||||
evt->len = sizeof(*ep);
|
ep = net_buf_add(buf, sizeof(*ep));
|
||||||
|
|
||||||
ep->handle = sys_cpu_to_le16(handle);
|
ep->handle = sys_cpu_to_le16(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void encode_control(struct radio_pdu_node_rx *radio_pdu_node_rx,
|
static void encode_control(struct radio_pdu_node_rx *node_rx,
|
||||||
struct pdu_data *pdu_data, uint8_t *len,
|
struct pdu_data *pdu_data, struct net_buf *buf)
|
||||||
struct bt_hci_evt_hdr *evt)
|
|
||||||
{
|
{
|
||||||
uint8_t *buf = (uint8_t *)radio_pdu_node_rx;
|
uint8_t *b = (uint8_t *)node_rx;
|
||||||
uint16_t handle;
|
uint16_t handle;
|
||||||
|
|
||||||
handle = radio_pdu_node_rx->hdr.handle;
|
handle = node_rx->hdr.handle;
|
||||||
|
|
||||||
switch (radio_pdu_node_rx->hdr.type) {
|
switch (node_rx->hdr.type) {
|
||||||
case NODE_RX_TYPE_REPORT:
|
case NODE_RX_TYPE_REPORT:
|
||||||
le_advertising_report(pdu_data, buf, evt);
|
le_advertising_report(pdu_data, b, buf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_RX_TYPE_CONNECTION:
|
case NODE_RX_TYPE_CONNECTION:
|
||||||
le_conn_complete(pdu_data, handle, evt);
|
le_conn_complete(pdu_data, handle, buf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_RX_TYPE_TERMINATE:
|
case NODE_RX_TYPE_TERMINATE:
|
||||||
disconn_complete(pdu_data, handle, evt);
|
disconn_complete(pdu_data, handle, buf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_RX_TYPE_CONN_UPDATE:
|
case NODE_RX_TYPE_CONN_UPDATE:
|
||||||
le_conn_update_complete(pdu_data, handle, evt);
|
le_conn_update_complete(pdu_data, handle, buf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_RX_TYPE_ENC_REFRESH:
|
case NODE_RX_TYPE_ENC_REFRESH:
|
||||||
enc_refresh_complete(pdu_data, handle, evt);
|
enc_refresh_complete(pdu_data, handle, buf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_RX_TYPE_APTO:
|
case NODE_RX_TYPE_APTO:
|
||||||
auth_payload_timeout_exp(pdu_data, handle, evt);
|
auth_payload_timeout_exp(pdu_data, handle, buf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_RX_TYPE_RSSI:
|
case NODE_RX_TYPE_RSSI:
|
||||||
|
@ -1082,18 +1054,14 @@ static void encode_control(struct radio_pdu_node_rx *radio_pdu_node_rx,
|
||||||
BT_ASSERT(0);
|
BT_ASSERT(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
*len = HCI_EVT_LEN(evt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void le_ltk_request(struct pdu_data *pdu_data, uint16_t handle,
|
static void le_ltk_request(struct pdu_data *pdu_data, uint16_t handle,
|
||||||
struct bt_hci_evt_hdr *evt)
|
struct net_buf *buf)
|
||||||
{
|
{
|
||||||
struct bt_hci_evt_le_ltk_request *sep = HCI_SE(evt);
|
struct bt_hci_evt_le_ltk_request *sep;
|
||||||
|
|
||||||
evt->evt = BT_HCI_EVT_LE_META_EVENT;
|
sep = meta_evt(buf, BT_HCI_EVT_LE_LTK_REQUEST, sizeof(*sep));
|
||||||
evt->len = HCI_ME_LEN(*sep);
|
|
||||||
HCI_ME(evt)->subevent = BT_HCI_EVT_LE_LTK_REQUEST;
|
|
||||||
|
|
||||||
sep->handle = sys_cpu_to_le16(handle);
|
sep->handle = sys_cpu_to_le16(handle);
|
||||||
memcpy(&sep->rand, pdu_data->payload.llctrl.ctrldata.enc_req.rand,
|
memcpy(&sep->rand, pdu_data->payload.llctrl.ctrldata.enc_req.rand,
|
||||||
|
@ -1103,12 +1071,12 @@ static void le_ltk_request(struct pdu_data *pdu_data, uint16_t handle,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void encrypt_change(uint8_t err, uint16_t handle,
|
static void encrypt_change(uint8_t err, uint16_t handle,
|
||||||
struct bt_hci_evt_hdr *evt)
|
struct net_buf *buf)
|
||||||
{
|
{
|
||||||
struct bt_hci_evt_encrypt_change *ep = HCI_EVTP(evt);
|
struct bt_hci_evt_encrypt_change *ep;
|
||||||
|
|
||||||
evt->evt = BT_HCI_EVT_ENCRYPT_CHANGE;
|
evt_create(buf, BT_HCI_EVT_ENCRYPT_CHANGE, sizeof(*ep));
|
||||||
evt->len = sizeof(*ep);
|
ep = net_buf_add(buf, sizeof(*ep));
|
||||||
|
|
||||||
ep->status = err;
|
ep->status = err;
|
||||||
ep->handle = sys_cpu_to_le16(handle);
|
ep->handle = sys_cpu_to_le16(handle);
|
||||||
|
@ -1116,13 +1084,11 @@ static void encrypt_change(uint8_t err, uint16_t handle,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void le_remote_feat_complete(struct pdu_data *pdu_data, uint16_t handle,
|
static void le_remote_feat_complete(struct pdu_data *pdu_data, uint16_t handle,
|
||||||
struct bt_hci_evt_hdr *evt)
|
struct net_buf *buf)
|
||||||
{
|
{
|
||||||
struct bt_hci_ev_le_remote_feat_complete *sep = HCI_SE(evt);
|
struct bt_hci_ev_le_remote_feat_complete *sep;
|
||||||
|
|
||||||
evt->evt = BT_HCI_EVT_LE_META_EVENT;
|
sep = meta_evt(buf, BT_HCI_EV_LE_REMOTE_FEAT_COMPLETE, sizeof(*sep));
|
||||||
evt->len = HCI_ME_LEN(*sep);
|
|
||||||
HCI_ME(evt)->subevent = BT_HCI_EV_LE_REMOTE_FEAT_COMPLETE;
|
|
||||||
|
|
||||||
sep->status = 0x00;
|
sep->status = 0x00;
|
||||||
sep->handle = sys_cpu_to_le16(handle);
|
sep->handle = sys_cpu_to_le16(handle);
|
||||||
|
@ -1132,12 +1098,12 @@ static void le_remote_feat_complete(struct pdu_data *pdu_data, uint16_t handle,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void remote_version_info(struct pdu_data *pdu_data, uint16_t handle,
|
static void remote_version_info(struct pdu_data *pdu_data, uint16_t handle,
|
||||||
struct bt_hci_evt_hdr *evt)
|
struct net_buf *buf)
|
||||||
{
|
{
|
||||||
struct bt_hci_evt_remote_version_info *ep = HCI_EVTP(evt);
|
struct bt_hci_evt_remote_version_info *ep;
|
||||||
|
|
||||||
evt->evt = BT_HCI_EVT_REMOTE_VERSION_INFO;
|
evt_create(buf, BT_HCI_EVT_REMOTE_VERSION_INFO, sizeof(*ep));
|
||||||
evt->len = sizeof(*ep);
|
ep = net_buf_add(buf, sizeof(*ep));
|
||||||
|
|
||||||
ep->status = 0x00;
|
ep->status = 0x00;
|
||||||
ep->handle = sys_cpu_to_le16(handle);
|
ep->handle = sys_cpu_to_le16(handle);
|
||||||
|
@ -1150,13 +1116,11 @@ static void remote_version_info(struct pdu_data *pdu_data, uint16_t handle,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void le_conn_param_req(struct pdu_data *pdu_data, uint16_t handle,
|
static void le_conn_param_req(struct pdu_data *pdu_data, uint16_t handle,
|
||||||
struct bt_hci_evt_hdr *evt)
|
struct net_buf *buf)
|
||||||
{
|
{
|
||||||
struct bt_hci_evt_le_conn_param_req *sep = HCI_SE(evt);
|
struct bt_hci_evt_le_conn_param_req *sep;
|
||||||
|
|
||||||
evt->evt = BT_HCI_EVT_LE_META_EVENT;
|
sep = meta_evt(buf, BT_HCI_EVT_LE_CONN_PARAM_REQ, sizeof(*sep));
|
||||||
evt->len = HCI_ME_LEN(*sep);
|
|
||||||
HCI_ME(evt)->subevent = BT_HCI_EVT_LE_CONN_PARAM_REQ;
|
|
||||||
|
|
||||||
sep->handle = sys_cpu_to_le16(handle);
|
sep->handle = sys_cpu_to_le16(handle);
|
||||||
sep->interval_min =
|
sep->interval_min =
|
||||||
|
@ -1168,13 +1132,11 @@ static void le_conn_param_req(struct pdu_data *pdu_data, uint16_t handle,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void le_data_len_change(struct pdu_data *pdu_data, uint16_t handle,
|
static void le_data_len_change(struct pdu_data *pdu_data, uint16_t handle,
|
||||||
struct bt_hci_evt_hdr *evt)
|
struct net_buf *buf)
|
||||||
{
|
{
|
||||||
struct bt_hci_evt_le_data_len_change *sep = HCI_SE(evt);
|
struct bt_hci_evt_le_data_len_change *sep;
|
||||||
|
|
||||||
evt->evt = BT_HCI_EVT_LE_META_EVENT;
|
sep = meta_evt(buf, BT_HCI_EVT_LE_DATA_LEN_CHANGE, sizeof(*sep));
|
||||||
evt->len = HCI_ME_LEN(*sep);
|
|
||||||
HCI_ME(evt)->subevent = BT_HCI_EVT_LE_DATA_LEN_CHANGE;
|
|
||||||
|
|
||||||
sep->handle = sys_cpu_to_le16(handle);
|
sep->handle = sys_cpu_to_le16(handle);
|
||||||
sep->max_tx_octets =
|
sep->max_tx_octets =
|
||||||
|
@ -1185,82 +1147,66 @@ static void le_data_len_change(struct pdu_data *pdu_data, uint16_t handle,
|
||||||
pdu_data->payload.llctrl.ctrldata.length_rsp.max_rx_octets;
|
pdu_data->payload.llctrl.ctrldata.length_rsp.max_rx_octets;
|
||||||
sep->max_rx_time =
|
sep->max_rx_time =
|
||||||
pdu_data->payload.llctrl.ctrldata.length_rsp.max_rx_time;
|
pdu_data->payload.llctrl.ctrldata.length_rsp.max_rx_time;
|
||||||
#if (TEST_DATA_LENGTH && TEST_TX)
|
|
||||||
{
|
|
||||||
extern uint16_t g_data_length;
|
|
||||||
|
|
||||||
g_data_length = pdu_data->payload.llctrl.ctrldata.
|
|
||||||
length_rsp.max_tx_octets;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void encode_data_ctrl(struct radio_pdu_node_rx *radio_pdu_node_rx,
|
static void encode_data_ctrl(struct radio_pdu_node_rx *node_rx,
|
||||||
struct pdu_data *pdu_data, uint8_t *len,
|
struct pdu_data *pdu_data, struct net_buf *buf)
|
||||||
struct bt_hci_evt_hdr *evt)
|
|
||||||
{
|
{
|
||||||
uint16_t handle = radio_pdu_node_rx->hdr.handle;
|
uint16_t handle = node_rx->hdr.handle;
|
||||||
|
|
||||||
switch (pdu_data->payload.llctrl.opcode) {
|
switch (pdu_data->payload.llctrl.opcode) {
|
||||||
case PDU_DATA_LLCTRL_TYPE_ENC_REQ:
|
case PDU_DATA_LLCTRL_TYPE_ENC_REQ:
|
||||||
le_ltk_request(pdu_data, handle, evt);
|
le_ltk_request(pdu_data, handle, buf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PDU_DATA_LLCTRL_TYPE_START_ENC_RSP:
|
case PDU_DATA_LLCTRL_TYPE_START_ENC_RSP:
|
||||||
encrypt_change(0x00, handle, evt);
|
encrypt_change(0x00, handle, buf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PDU_DATA_LLCTRL_TYPE_FEATURE_RSP:
|
case PDU_DATA_LLCTRL_TYPE_FEATURE_RSP:
|
||||||
le_remote_feat_complete(pdu_data, handle, evt);
|
le_remote_feat_complete(pdu_data, handle, buf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PDU_DATA_LLCTRL_TYPE_VERSION_IND:
|
case PDU_DATA_LLCTRL_TYPE_VERSION_IND:
|
||||||
remote_version_info(pdu_data, handle, evt);
|
remote_version_info(pdu_data, handle, buf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PDU_DATA_LLCTRL_TYPE_REJECT_IND:
|
case PDU_DATA_LLCTRL_TYPE_REJECT_IND:
|
||||||
encrypt_change(pdu_data->payload.llctrl.ctrldata.reject_ind.
|
encrypt_change(pdu_data->payload.llctrl.ctrldata.reject_ind.
|
||||||
error_code,
|
error_code,
|
||||||
handle, evt);
|
handle, buf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PDU_DATA_LLCTRL_TYPE_CONN_PARAM_REQ:
|
case PDU_DATA_LLCTRL_TYPE_CONN_PARAM_REQ:
|
||||||
le_conn_param_req(pdu_data, handle, evt);
|
le_conn_param_req(pdu_data, handle, buf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PDU_DATA_LLCTRL_TYPE_LENGTH_REQ:
|
case PDU_DATA_LLCTRL_TYPE_LENGTH_REQ:
|
||||||
case PDU_DATA_LLCTRL_TYPE_LENGTH_RSP:
|
case PDU_DATA_LLCTRL_TYPE_LENGTH_RSP:
|
||||||
le_data_len_change(pdu_data, handle, evt);
|
le_data_len_change(pdu_data, handle, buf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
BT_ASSERT(0);
|
BT_ASSERT(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
*len = HCI_EVT_LEN(evt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void encode_data(uint8_t *buf, uint8_t *len, uint8_t **out)
|
void hci_acl_encode(struct radio_pdu_node_rx *node_rx, struct net_buf *buf)
|
||||||
{
|
{
|
||||||
struct radio_pdu_node_rx *radio_pdu_node_rx;
|
|
||||||
struct bt_hci_acl_hdr *acl;
|
struct bt_hci_acl_hdr *acl;
|
||||||
struct pdu_data *pdu_data;
|
struct pdu_data *pdu_data;
|
||||||
uint16_t handle_flags;
|
uint16_t handle_flags;
|
||||||
uint16_t handle;
|
uint16_t handle;
|
||||||
|
uint8_t *data;
|
||||||
|
|
||||||
radio_pdu_node_rx = (struct radio_pdu_node_rx *)buf;
|
pdu_data = (struct pdu_data *)node_rx->pdu_data;
|
||||||
pdu_data = (struct pdu_data *)radio_pdu_node_rx->pdu_data;
|
handle = node_rx->hdr.handle;
|
||||||
handle = radio_pdu_node_rx->hdr.handle;
|
|
||||||
|
|
||||||
switch (pdu_data->ll_id) {
|
switch (pdu_data->ll_id) {
|
||||||
case PDU_DATA_LLID_DATA_CONTINUE:
|
case PDU_DATA_LLID_DATA_CONTINUE:
|
||||||
case PDU_DATA_LLID_DATA_START:
|
case PDU_DATA_LLID_DATA_START:
|
||||||
#if !TEST_DROP_RX
|
acl = (void *)net_buf_add(buf, sizeof(*acl));
|
||||||
hci_context.tx[0] = HCI_DATA;
|
|
||||||
|
|
||||||
acl = (struct bt_hci_acl_hdr *)&hci_context.tx[1];
|
|
||||||
if (pdu_data->ll_id == PDU_DATA_LLID_DATA_START) {
|
if (pdu_data->ll_id == PDU_DATA_LLID_DATA_START) {
|
||||||
handle_flags = bt_acl_handle_pack(handle, BT_ACL_START);
|
handle_flags = bt_acl_handle_pack(handle, BT_ACL_START);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1268,27 +1214,8 @@ static void encode_data(uint8_t *buf, uint8_t *len, uint8_t **out)
|
||||||
}
|
}
|
||||||
acl->handle = sys_cpu_to_le16(handle_flags);
|
acl->handle = sys_cpu_to_le16(handle_flags);
|
||||||
acl->len = sys_cpu_to_le16(pdu_data->len);
|
acl->len = sys_cpu_to_le16(pdu_data->len);
|
||||||
memcpy(((uint8_t *)acl) + sizeof(struct bt_hci_acl_hdr),
|
data = (void *)net_buf_add(buf, pdu_data->len);
|
||||||
&pdu_data->payload.lldata[0], pdu_data->len);
|
memcpy(data, &pdu_data->payload.lldata[0], pdu_data->len);
|
||||||
|
|
||||||
*len = HCI_DATA_LEN(acl);
|
|
||||||
*out = &hci_context.tx[0];
|
|
||||||
#else
|
|
||||||
if (s_rx_cnt != pdu_data->payload.lldata[0]) {
|
|
||||||
s_rx_cnt = pdu_data->payload.lldata[0];
|
|
||||||
|
|
||||||
BT_ASSERT(0);
|
|
||||||
} else {
|
|
||||||
uint8_t index;
|
|
||||||
|
|
||||||
for (index = 0; index < pdu_data->len; index++) {
|
|
||||||
BT_ASSERT(pdu_data->payload.lldata[index] ==
|
|
||||||
(uint8_t)(s_rx_cnt + index));
|
|
||||||
}
|
|
||||||
|
|
||||||
s_rx_cnt++;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -1298,59 +1225,34 @@ static void encode_data(uint8_t *buf, uint8_t *len, uint8_t **out)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void hcic_encode(uint8_t *buf, uint8_t *len, uint8_t **out)
|
void hci_evt_encode(struct radio_pdu_node_rx *node_rx, struct net_buf *buf)
|
||||||
{
|
{
|
||||||
struct radio_pdu_node_rx *radio_pdu_node_rx;
|
|
||||||
struct pdu_data *pdu_data;
|
struct pdu_data *pdu_data;
|
||||||
struct bt_hci_evt_hdr *evt;
|
|
||||||
|
|
||||||
radio_pdu_node_rx = (struct radio_pdu_node_rx *)buf;
|
pdu_data = (struct pdu_data *)node_rx->pdu_data;
|
||||||
pdu_data = (struct pdu_data *)radio_pdu_node_rx->pdu_data;
|
|
||||||
*len = 0;
|
|
||||||
*out = NULL;
|
|
||||||
|
|
||||||
/* Check if we need to generate an HCI event or ACL data */
|
if (node_rx->hdr.type != NODE_RX_TYPE_DC_PDU) {
|
||||||
if (radio_pdu_node_rx->hdr.type != NODE_RX_TYPE_DC_PDU ||
|
encode_control(node_rx, pdu_data, buf);
|
||||||
pdu_data->ll_id == PDU_DATA_LLID_CTRL) {
|
|
||||||
/* generate an HCI event */
|
|
||||||
hci_context.tx[0] = HCI_EVT;
|
|
||||||
evt = (void *)&hci_context.tx[1];
|
|
||||||
|
|
||||||
if (radio_pdu_node_rx->hdr.type != NODE_RX_TYPE_DC_PDU) {
|
|
||||||
encode_control(radio_pdu_node_rx, pdu_data, len, evt);
|
|
||||||
} else {
|
|
||||||
encode_data_ctrl(radio_pdu_node_rx, pdu_data, len, evt);
|
|
||||||
}
|
|
||||||
*out = &hci_context.tx[0];
|
|
||||||
} else {
|
} else {
|
||||||
/* generate ACL data */
|
encode_data_ctrl(node_rx, pdu_data, buf);
|
||||||
encode_data(buf, len, out);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hcic_encode_num_cmplt(uint16_t handle, uint8_t num, uint8_t *len,
|
void hci_num_cmplt_encode(struct net_buf *buf, uint16_t handle, uint8_t num)
|
||||||
uint8_t **out)
|
|
||||||
{
|
{
|
||||||
struct bt_hci_evt_num_completed_packets *ep;
|
struct bt_hci_evt_num_completed_packets *ep;
|
||||||
struct bt_hci_handle_count *hc;
|
struct bt_hci_handle_count *hc;
|
||||||
struct bt_hci_evt_hdr *evt;
|
|
||||||
uint8_t num_handles;
|
uint8_t num_handles;
|
||||||
|
uint8_t len;
|
||||||
|
|
||||||
num_handles = 1;
|
num_handles = 1;
|
||||||
|
|
||||||
hci_context.tx[0] = HCI_EVT;
|
len = (sizeof(*ep) + (sizeof(*hc) * num_handles));
|
||||||
|
evt_create(buf, BT_HCI_EVT_NUM_COMPLETED_PACKETS, len);
|
||||||
evt = (struct bt_hci_evt_hdr *)&hci_context.tx[1];
|
|
||||||
ep = HCI_EVTP(evt);
|
|
||||||
evt->evt = BT_HCI_EVT_NUM_COMPLETED_PACKETS;
|
|
||||||
evt->len = (sizeof(struct bt_hci_evt_num_completed_packets) +
|
|
||||||
(sizeof(struct bt_hci_handle_count) * num_handles));
|
|
||||||
|
|
||||||
|
ep = net_buf_add(buf, len);
|
||||||
ep->num_handles = num_handles;
|
ep->num_handles = num_handles;
|
||||||
hc = &ep->h[0];
|
hc = &ep->h[0];
|
||||||
hc->handle = sys_cpu_to_le16(handle);
|
hc->handle = sys_cpu_to_le16(handle);
|
||||||
hc->count = sys_cpu_to_le16(num);
|
hc->count = sys_cpu_to_le16(num);
|
||||||
|
|
||||||
*len = HCI_EVT_LEN(evt);
|
|
||||||
*out = &hci_context.tx[0];
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,137 +126,69 @@ static void swi5_nrf5_isr(void *arg)
|
||||||
work_run(NRF52_IRQ_SWI5_EGU5_IRQn);
|
work_run(NRF52_IRQ_SWI5_EGU5_IRQn);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct net_buf *evt_create(uint8_t *remaining, uint8_t **in)
|
|
||||||
{
|
|
||||||
struct bt_hci_evt_hdr hdr;
|
|
||||||
struct net_buf *buf;
|
|
||||||
|
|
||||||
/* TODO: check available length */
|
|
||||||
memcpy(&hdr, *in, sizeof(hdr));
|
|
||||||
*in += sizeof(hdr);
|
|
||||||
|
|
||||||
*remaining = hdr.len;
|
|
||||||
|
|
||||||
buf = bt_buf_get_evt(0);
|
|
||||||
if (buf) {
|
|
||||||
memcpy(net_buf_add(buf, sizeof(hdr)), &hdr, sizeof(hdr));
|
|
||||||
} else {
|
|
||||||
BT_ERR("No available event buffers!");
|
|
||||||
}
|
|
||||||
|
|
||||||
BT_DBG("len %u", hdr.len);
|
|
||||||
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct net_buf *acl_create(uint8_t *remaining, uint8_t **in)
|
|
||||||
{
|
|
||||||
struct bt_hci_acl_hdr hdr;
|
|
||||||
struct net_buf *buf;
|
|
||||||
|
|
||||||
/* TODO: check available length */
|
|
||||||
memcpy(&hdr, *in, sizeof(hdr));
|
|
||||||
*in += sizeof(hdr);
|
|
||||||
|
|
||||||
buf = bt_buf_get_acl();
|
|
||||||
if (buf) {
|
|
||||||
memcpy(net_buf_add(buf, sizeof(hdr)), &hdr, sizeof(hdr));
|
|
||||||
} else {
|
|
||||||
BT_ERR("No available ACL buffers!");
|
|
||||||
}
|
|
||||||
|
|
||||||
*remaining = sys_le16_to_cpu(hdr.len);
|
|
||||||
|
|
||||||
BT_DBG("len %u", *remaining);
|
|
||||||
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int evt_acl_create(uint8_t remaining, uint8_t *in)
|
|
||||||
{
|
|
||||||
struct net_buf *buf;
|
|
||||||
uint8_t type;
|
|
||||||
|
|
||||||
type = *in++;
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case HCI_EVT:
|
|
||||||
buf = evt_create(&remaining, &in);
|
|
||||||
break;
|
|
||||||
case HCI_ACL:
|
|
||||||
buf = acl_create(&remaining, &in);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
BT_ERR("Unknown HCI type %u", type);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
BT_DBG("remaining %u bytes", remaining);
|
|
||||||
|
|
||||||
if (buf && remaining > net_buf_tailroom(buf)) {
|
|
||||||
BT_ERR("Not enough space in buffer");
|
|
||||||
net_buf_unref(buf);
|
|
||||||
buf = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buf) {
|
|
||||||
memcpy(net_buf_tail(buf), in, remaining);
|
|
||||||
buf->len += remaining;
|
|
||||||
|
|
||||||
BT_DBG("bt_recv");
|
|
||||||
|
|
||||||
bt_recv(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void recv_fiber(int unused0, int unused1)
|
static void recv_fiber(int unused0, int unused1)
|
||||||
{
|
{
|
||||||
while (1) {
|
while (1) {
|
||||||
uint16_t handle;
|
struct radio_pdu_node_rx *node_rx;
|
||||||
|
struct pdu_data *pdu_data;
|
||||||
|
struct net_buf *buf;
|
||||||
uint8_t num_cmplt;
|
uint8_t num_cmplt;
|
||||||
struct radio_pdu_node_rx *radio_pdu_node_rx;
|
uint16_t handle;
|
||||||
|
|
||||||
while ((num_cmplt =
|
while ((num_cmplt = radio_rx_get(&node_rx, &handle))) {
|
||||||
radio_rx_get(&radio_pdu_node_rx, &handle))) {
|
|
||||||
uint8_t len;
|
|
||||||
uint8_t *buf;
|
|
||||||
int retval;
|
|
||||||
|
|
||||||
hcic_encode_num_cmplt(handle, num_cmplt, &len, &buf);
|
buf = bt_buf_get_evt(BT_HCI_EVT_NUM_COMPLETED_PACKETS);
|
||||||
BT_ASSERT(len);
|
if (buf) {
|
||||||
|
hci_num_cmplt_encode(buf, handle, num_cmplt);
|
||||||
retval = evt_acl_create(len, buf);
|
BT_DBG("Num Complete: 0x%04x:%u", handle,
|
||||||
BT_ASSERT(!retval);
|
num_cmplt);
|
||||||
|
bt_recv(buf);
|
||||||
|
} else {
|
||||||
|
BT_ERR("Cannot allocate Num Complete");
|
||||||
|
}
|
||||||
|
|
||||||
fiber_yield();
|
fiber_yield();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (radio_pdu_node_rx) {
|
if (node_rx) {
|
||||||
uint8_t len;
|
|
||||||
uint8_t *buf;
|
|
||||||
int retval;
|
|
||||||
|
|
||||||
hcic_encode((uint8_t *)radio_pdu_node_rx, &len, &buf);
|
pdu_data = (void *)node_rx->pdu_data;
|
||||||
|
/* Check if we need to generate an HCI event or ACL
|
||||||
/* Not all radio_rx_get are translated to HCI!,
|
* data
|
||||||
* hence just dequeue.
|
|
||||||
*/
|
*/
|
||||||
if (len) {
|
if (node_rx->hdr.type != NODE_RX_TYPE_DC_PDU ||
|
||||||
retval = evt_acl_create(len, buf);
|
pdu_data->ll_id == PDU_DATA_LLID_CTRL) {
|
||||||
BT_ASSERT(!retval);
|
/* generate a (non-priority) HCI event */
|
||||||
|
buf = bt_buf_get_evt(0);
|
||||||
|
if (buf) {
|
||||||
|
hci_evt_encode(node_rx, buf);
|
||||||
|
} else {
|
||||||
|
BT_ERR("Cannot allocate RX event");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* generate ACL data */
|
||||||
|
buf = bt_buf_get_acl();
|
||||||
|
if (buf) {
|
||||||
|
hci_acl_encode(node_rx, buf);
|
||||||
|
} else {
|
||||||
|
BT_ERR("Cannot allocate RX ACL");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf && buf->len) {
|
||||||
|
BT_DBG("Incoming packet: type:%u len:%u",
|
||||||
|
bt_buf_get_type(buf), buf->len);
|
||||||
|
bt_recv(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
radio_rx_dequeue();
|
radio_rx_dequeue();
|
||||||
radio_rx_fc_set(radio_pdu_node_rx->hdr.handle, 0);
|
radio_rx_fc_set(node_rx->hdr.handle, 0);
|
||||||
radio_pdu_node_rx->hdr.onion.next = 0;
|
node_rx->hdr.onion.next = 0;
|
||||||
radio_rx_mem_release(&radio_pdu_node_rx);
|
radio_rx_mem_release(&node_rx);
|
||||||
|
|
||||||
fiber_yield();
|
fiber_yield();
|
||||||
} else {
|
} else {
|
||||||
nano_fiber_sem_take(&nano_sem_recv,
|
nano_fiber_sem_take(&nano_sem_recv, TICKS_UNLIMITED);
|
||||||
TICKS_UNLIMITED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stack_analyze("recv fiber stack",
|
stack_analyze("recv fiber stack",
|
||||||
|
@ -328,7 +260,7 @@ static int hci_driver_send(struct net_buf *buf)
|
||||||
|
|
||||||
static int hci_driver_open(void)
|
static int hci_driver_open(void)
|
||||||
{
|
{
|
||||||
uint32_t retval;
|
uint32_t err;
|
||||||
|
|
||||||
clock_k32src_start(1);
|
clock_k32src_start(1);
|
||||||
|
|
||||||
|
@ -347,15 +279,15 @@ static int hci_driver_open(void)
|
||||||
|
|
||||||
rand_init(_rand_context, sizeof(_rand_context));
|
rand_init(_rand_context, sizeof(_rand_context));
|
||||||
|
|
||||||
retval = radio_init(7, /* 20ppm = 7 ... 250ppm = 1, 500ppm = 0 */
|
err = radio_init(7, /* 20ppm = 7 ... 250ppm = 1, 500ppm = 0 */
|
||||||
RADIO_CONNECTION_CONTEXT_MAX,
|
RADIO_CONNECTION_CONTEXT_MAX,
|
||||||
RADIO_PACKET_COUNT_RX_MAX,
|
RADIO_PACKET_COUNT_RX_MAX,
|
||||||
RADIO_PACKET_COUNT_TX_MAX,
|
RADIO_PACKET_COUNT_TX_MAX,
|
||||||
RADIO_LL_LENGTH_OCTETS_RX_MAX, &_radio[0],
|
RADIO_LL_LENGTH_OCTETS_RX_MAX, &_radio[0],
|
||||||
sizeof(_radio)
|
sizeof(_radio)
|
||||||
);
|
);
|
||||||
if (retval) {
|
if (err) {
|
||||||
BT_ERR("Required RAM size: %d, supplied: %u.", retval,
|
BT_ERR("Required RAM size: %d, supplied: %u.", err,
|
||||||
sizeof(_radio));
|
sizeof(_radio));
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
|
|
||||||
int hci_cmd_handle(struct net_buf *cmd, struct net_buf *evt);
|
int hci_cmd_handle(struct net_buf *cmd, struct net_buf *evt);
|
||||||
int hci_acl_handle(struct net_buf *acl);
|
int hci_acl_handle(struct net_buf *acl);
|
||||||
void hcic_encode(uint8_t *buf, uint8_t *len, uint8_t **out);
|
void hci_evt_encode(struct radio_pdu_node_rx *node_rx, struct net_buf *buf);
|
||||||
void hcic_encode_num_cmplt(uint16_t instance, uint8_t num, uint8_t *len,
|
void hci_acl_encode(struct radio_pdu_node_rx *node_rx, struct net_buf *buf);
|
||||||
uint8_t **out);
|
void hci_num_cmplt_encode(struct net_buf *buf, uint16_t handle, uint8_t num);
|
||||||
|
|
||||||
#endif /* _HCI_CONTROLLER_H_ */
|
#endif /* _HCI_CONTROLLER_H_ */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue