diff --git a/drivers/wireless/bluetooth/bt_uart.c b/drivers/wireless/bluetooth/bt_uart.c index 26baf4b7e4f..1f062db1b05 100644 --- a/drivers/wireless/bluetooth/bt_uart.c +++ b/drivers/wireless/bluetooth/bt_uart.c @@ -148,10 +148,10 @@ static FAR struct bt_buf_s *btuart_evt_recv(FAR struct btuart_upperhalf_s *upper *remaining = hdr.len; - buf = bt_buf_get(BT_EVT, 0); + buf = bt_buf_alloc(BT_EVT, 0); if (buf != NULL) { - memcpy(bt_buf_add(buf, sizeof(struct bt_hci_evt_hdr_s)), &hdr, + memcpy(bt_buf_extend(buf, sizeof(struct bt_hci_evt_hdr_s)), &hdr, sizeof(struct bt_hci_evt_hdr_s)); } else @@ -181,10 +181,10 @@ static FAR struct bt_buf_s *btuart_acl_recv(FAR struct btuart_upperhalf_s *upper return NULL; } - buf = bt_buf_get(BT_ACL_IN, 0); + buf = bt_buf_alloc(BT_ACL_IN, 0); if (buf) { - memcpy(bt_buf_add(buf, sizeof(struct bt_hci_acl_hdr_s)), &hdr, + memcpy(bt_buf_extend(buf, sizeof(struct bt_hci_acl_hdr_s)), &hdr, sizeof(struct bt_hci_acl_hdr_s)); } else @@ -268,14 +268,14 @@ static void btuart_interrupt(FAR const struct btuart_lowerhalf_s *lower, /* Pass buffer to the stack */ - bt_input(buf); + bt_hci_receive(buf); buf = NULL; } return; failed: - bt_buf_put(buf); + bt_buf_release(buf); remaining = 0; buf = NULL; return; @@ -299,7 +299,7 @@ static int btuart_send(FAR const struct bt_driver_s *dev, return -EINVAL; } - type = bt_buf_push(buf, 1); + type = bt_buf_provide(buf, 1); switch (buf->type) { diff --git a/include/netpacket/bluetooth.h b/include/netpacket/bluetooth.h index f61673d7952..cac7ea7f646 100644 --- a/include/netpacket/bluetooth.h +++ b/include/netpacket/bluetooth.h @@ -99,7 +99,7 @@ #define BTPROTO_HIDP 6 #define BTPROTO_AVDTP 7 -/* HCI socket options: +/* HCI socket options (SOL_HCI, see include/sys/socket.h): * * SO_HCI_EVT_FILTER * Controls which events will be received at the socket. By default, @@ -116,7 +116,7 @@ #define SO_HCI_PKT_FILTER (__SO_PROTOCOL + 1) #define SO_HCI_DIRECTION (__SO_PROTOCOL + 2) -/* L2CAP socket options: +/* L2CAP socket options (SOL_L2CAP, see include/sys/socket.h): * SO_L2CAP_IMTU [uint16_t] * Incoming MTU @@ -145,7 +145,7 @@ # define L2CAP_LM_ENCRYPT (1 << 1) # define L2CAP_LM_SECURE (1 << 2) -/* RFCOMM socket options: +/* RFCOMM socket options (SOL_RFCOMM, see include/sys/socket.h): * * SO_RFCOMM_MTU [uint16_t] * Maximum Frame Size to use for this link. @@ -171,7 +171,7 @@ # define RFCOMM_LM_ENCRYPT (1 << 1) # define RFCOMM_LM_SECURE (1 << 2) -/* SCO socket options: +/* SCO socket options (SOL_SCO, see include/sys/socket.h): * * SO_SCO_MTU [uint16_t] * Maximum packet size for use on this link. This is read-only and will @@ -184,6 +184,78 @@ #define SO_SCO_MTU (__SO_PROTOCOL + 8) #define SO_SCO_HANDLE (__SO_PROTOCOL + 9) +/* The CID name space for the ACL-U, ASB-C, and AMP-U logical links is as + * follows: + */ + +#define BT_CID_NULL 0x0000 /* Null identifier */ +#define BT_CID_L2CAP 0x0001 /* L2CAP Signaling channel */ +#define BT_CID_CONNECTIONLESS 0x0002 /* Connectionless channel */ +#define BT_CID_AMP 0x0003 /* AMP Manager Protocol */ + /* 0x0004-0x0006 Reserved for future + * use */ +#define BT_CID_BREDR 0x0007 /* BR/EDR Security Manager */ + /* 0x0008-0x003e Reserved for future + * use */ +#define BT_CID_AMPTEST 0x003f /* AMP Test Manager */ + /* 0x0040-0xffff Dynamically + * allocated */ + +/* The CID name space for the LE-U logical link is as follows: + * + * NOTE: 0x0004, 0x0005, and 0x0006 are used internally by ATT, L2CAP, and + * and SMP. These are unavailable for use use in socket connection. + */ + +#define BT_LE_CID_NULL 0x0000 /* Null identifier */ + /* 0x0001-0x0003 Reserved for future + * use */ +#define BT_LE_CID_ATT 0x0004 /* Attribute Protocol */ +#define BT_LE_CID_L2CAP 0x0005 /* Low Energy L2CAP Signaling channel */ +#define BT_LE_CID_SMP 0x0006 /* Security Manager Protocol + /* 0x0007-0x001f Reserved for future + /* 0x0020-0x003e Assigned Numbers + /* 0x003f Reserved for future use */ + /* 0x0040-0x007f Dynamically allocated + * using the L2CAP LE credit based + * connection mechanism + /* Others reserved for future use */ + +/* Protocol and Service Multiplexers (PSMs) */ + +#define BT_PSM_SDP 0x0001 /* Bluetooth Service Discovery + * Protocol (SDP), Bluetooth SIG */ +#define BT_PSM_RFCOMM 0x0003 /* RFCOMM with TS 07.10, Bluetooth + * SIG */ +#define BT_PSM_TCS_BIN 0x0005 /* Bluetooth Telephony Control + * Specification / TCS Binary, + * Bluetooth SIG */ +#define BT_PSM_TCS_BIN_CORDLESS 0x0007 /* Bluetooth Telephony Control + * Specification / TCS Binary, + * Bluetooth SIG */ +#define BT_PSM_BNEP 0x000f /* Bluetooth Network Encapsulation + * Protocol, Bluetooth SIG */ +#define BT_PSM_HID_CTRL 0x0011 /* Human Interface Device, Bluetooth + * SIG */ +#define BT_PSM_HID_INT 0x0013 /* Human Interface Device, Bluetooth + * SIG */ +#define BT_PSM_UPnP 0x0015 /* [ESDP] , Bluetooth SIG */ +#define BT_PSM_AVCTP 0x0017 /* Audio/Video Control Transport + * Protocol, Bluetooth SIG */ +#define BT_PSM_AVDTP 0x0019 /* Audio/Video Distribution Transport + * Protocol, Bluetooth SIG */ +#define BT_PSM_AVCTP_BROWSING 0x001b /* Audio/Video Remote Control + * Profile, Bluetooth SIG */ +#define BT_PSM_UDI_CPLANE 0x001d /* Unrestricted Digital Information + * Profile [UDI], Bluetooth SIG */ +#define BT_PSM_ATT 0x001f /* Bluetooth Core Specification */ +#define BT_PSM_3DSP 0x0021 /* 3D Synchronization Profile, + * Bluetooth SIG. */ +#define BT_PSM_LE_PSM_IPSP 0x0023 /* Internet Protocol Support Profile + * (IPSP), Bluetooth SIG */ +#define BT_PSM_OTS 0x0025 /* Object Transfer Service (OTS), + * Bluetooth SIG */ + /**************************************************************************** * Public Type Definitions ****************************************************************************/ @@ -204,9 +276,9 @@ struct sockaddr_bt_s { - sa_family_t bt_family; - bt_addr_t bt_bdaddr; - uint8_t bt_channel; + sa_family_t bt_family; /* Must be AF_BLUETOOTH */ + bt_addr_t bt_bdaddr; /* 6-byte Bluetooth address */ + uint8_t bt_channel; /* Channel identifier (CID) */ }; /**************************************************************************** diff --git a/include/nuttx/wireless/bt_buf.h b/include/nuttx/wireless/bt_buf.h index cb3cc265893..8630e50ef04 100644 --- a/include/nuttx/wireless/bt_buf.h +++ b/include/nuttx/wireless/bt_buf.h @@ -1,5 +1,5 @@ /**************************************************************************** - * wireless/bluetooth/bt_att.h + * include/nuttx/wireless/bt_buf.h * Bluetooth buffer management. * * Copyright (C) 2018 Gregory Nutt. All rights reserved. @@ -105,7 +105,8 @@ struct bt_buf_acl_data_s struct bt_buf_s { - FAR struct iob_s *iob; /* IOB container of the buffer */ + FAR struct bt_buf_s *flink; + union { struct bt_buf_hci_data_s hci; @@ -114,12 +115,13 @@ struct bt_buf_s FAR uint8_t *data; /* Start of data in the buffer */ uint8_t len; /* Length of data in the buffer */ - uint8_t ref : 5; /* Reference count */ - uint8_t type : 3; /* Type of data contained in the buffer */ + uint8_t pool; /* Memory pool */ + uint8_t ref; /* Reference count */ + uint8_t type; /* Type of data contained in the buffer */ /* The full available buffer. */ - uint8_t buf[BT_BUF_MAX_DATA]; + FAR struct iob_s *frame; }; /**************************************************************************** @@ -127,43 +129,55 @@ struct bt_buf_s ****************************************************************************/ /**************************************************************************** - * Name: bt_buf_get + * Name: bt_buf_alloc * * Description: - * Get buffer from the available buffers pool with specified type and - * reserved headroom. + * The bt_buf_alloc function will get a free buffer for use by the + * Bluetooth stack with specified type and reserved headroom. The + * reference count is initially set to one. + * + * Interrupt handling logic will first attempt to allocate from the + * g_buf_free list. If that list is empty, it will attempt to allocate + * from its reserve, g_buf_free_irq. If that list is empty, then the + * allocation fails (NULL is returned). + * + * Non-interrupt handler logic will attempt to allocate from g_buf_free + * list. If that the list is empty, then the buffer structure will be + * allocated from the dynamic memory pool with some performance hit. * * Input Parameters: * type - Buffer type. * reserve_head - How much headroom to reserve. * * Returned Value: - * New buffer or NULL if out of buffers. - * - * WARNING: If there are no available buffers and the function is - * called from a task or thread the call will block until a buffer - * becomes available in the pool. + * A reference to the allocated buffer structure. All user fields in this + * structure have been zeroed. On a failure to allocate, NULL is + * returned. * ****************************************************************************/ -FAR struct bt_buf_s *bt_buf_get(enum bt_buf_type_e type, size_t reserve_head); +FAR struct bt_buf_s *bt_buf_alloc(enum bt_buf_type_e type, + size_t reserve_head); /**************************************************************************** - * Name: bt_buf_put + * Name: bt_buf_release * * Description: - * Decrements the reference count of a buffer and puts it back into the - * pool if the count reaches zero. + * Decrements the reference count of a buffer and returns the buffer to the + * memory pool if the count decrements zero. * * Input Parameters: * buf - Buffer. * + * Returned Value: + * None + * ****************************************************************************/ -void bt_buf_put(FAR struct bt_buf_s *buf); +void bt_buf_release(FAR struct bt_buf_s *buf); /**************************************************************************** - * Name: bt_buf_hold + * Name: bt_buf_addref * * Description: * Increment the reference count of a buffer. @@ -173,14 +187,14 @@ void bt_buf_put(FAR struct bt_buf_s *buf); * ****************************************************************************/ -FAR struct bt_buf_s *bt_buf_hold(FAR struct bt_buf_s *buf); +FAR struct bt_buf_s *bt_buf_addref(FAR struct bt_buf_s *buf); /**************************************************************************** - * Name: bt_buf_add + * Name: bt_buf_extend * * Description: * Increments the data length of a buffer to account for more data - * at the end. + * at the end of the buffer. * * Input Parameters: * buf - Buffer to update. @@ -191,10 +205,10 @@ FAR struct bt_buf_s *bt_buf_hold(FAR struct bt_buf_s *buf); * ****************************************************************************/ -FAR void *bt_buf_add(FAR struct bt_buf_s *buf, size_t len); +FAR void *bt_buf_extend(FAR struct bt_buf_s *buf, size_t len); /**************************************************************************** - * Name: bt_buf_add_le16 + * Name: bt_buf_put_le16 * * Description: * Adds 16-bit value in little endian format at the end of buffer. @@ -210,10 +224,10 @@ FAR void *bt_buf_add(FAR struct bt_buf_s *buf, size_t len); * ****************************************************************************/ -void bt_buf_add_le16(FAR struct bt_buf_s *buf, uint16_t value); +void bt_buf_put_le16(FAR struct bt_buf_s *buf, uint16_t value); /**************************************************************************** - * Name: bt_buf_push + * Name: bt_buf_provide * * Description: * Modifies the data pointer and buffer length to account for more data @@ -228,10 +242,10 @@ void bt_buf_add_le16(FAR struct bt_buf_s *buf, uint16_t value); * ****************************************************************************/ -FAR void *bt_buf_push(FAR struct bt_buf_s *buf, size_t len); +FAR void *bt_buf_provide(FAR struct bt_buf_s *buf, size_t len); /**************************************************************************** - * Name: bt_buf_pull + * Name: bt_buf_consume * * Description: * Removes data from the beginning of the buffer by modifying the data @@ -245,10 +259,10 @@ FAR void *bt_buf_push(FAR struct bt_buf_s *buf, size_t len); * ****************************************************************************/ -FAR void *bt_buf_pull(FAR struct bt_buf_s *buf, size_t len); +FAR void *bt_buf_consume(FAR struct bt_buf_s *buf, size_t len); /**************************************************************************** - * Name: bt_buf_pull_le16 + * Name: bt_buf_get_le16 * * Description: * Same idea as with bt_buf_pull(), but a helper for operating on @@ -262,7 +276,7 @@ FAR void *bt_buf_pull(FAR struct bt_buf_s *buf, size_t len); * ****************************************************************************/ -uint16_t bt_buf_pull_le16(FAR struct bt_buf_s *buf); +uint16_t bt_buf_get_le16(FAR struct bt_buf_s *buf); /**************************************************************************** * Name: bt_buf_tailroom @@ -306,22 +320,4 @@ size_t bt_buf_headroom(FAR struct bt_buf_s *buf); #define bt_buf_tail(buf) ((buf)->data + (buf)->len) -/**************************************************************************** - * Name: bt_buf_init - * - * Description: - * Initialize the buffers with specified amount of incoming and outgoing - * ACL buffers. The HCI command and event buffers will be allocated from - * whatever is left over. - * - * Input Parameters: - * None. - * - * Returned Value: - * Zero on success or (negative) error code on failure. - * - ****************************************************************************/ - -int bt_buf_init(void); - #endif /* __INCLUDE_NUTTX_WIRELESS_BT_BUF_H */ diff --git a/include/nuttx/wireless/bt_driver.h b/include/nuttx/wireless/bt_driver.h index 6f6fbf729d0..1dfa60d4ca6 100644 --- a/include/nuttx/wireless/bt_driver.h +++ b/include/nuttx/wireless/bt_driver.h @@ -111,7 +111,7 @@ int bt_driver_register(FAR const struct bt_driver_s *dev); void bt_driver_unregister(FAR const struct bt_driver_s *dev); /**************************************************************************** - * Name: bt_input + * Name: bt_hci_receive * * Description: * Called by the Bluetooth low-level driver when new data is received from @@ -126,6 +126,6 @@ void bt_driver_unregister(FAR const struct bt_driver_s *dev); * ****************************************************************************/ -void bt_input(FAR struct bt_buf_s *buf); +void bt_hci_receive(FAR struct bt_buf_s *buf); #endif /* __INCLUDE_NUTTX_WIRELESS_BT_DRIVER_H */ diff --git a/wireless/bluetooth/Kconfig b/wireless/bluetooth/Kconfig index 7ff71b36557..3998911f6c1 100644 --- a/wireless/bluetooth/Kconfig +++ b/wireless/bluetooth/Kconfig @@ -96,6 +96,53 @@ config BLUETOOTH_MAXSCANRESULT This contributes to a static memory allocation that will be greater than CONFIG_BLUETOOTH_MAXSCANDATA * CONFIG_BLUETOOTH_MAXSCANRESULT +#if !defined(CONFIG_BLUETOOTH_BUFFER_PREALLOC) || \ + CONFIG_BLUETOOTH_BUFFER_PREALLOC < 0 +# undef CONFIG_BLUETOOTH_BUFFER_PREALLOC +# define CONFIG_BLUETOOTH_BUFFER_PREALLOC 20 +#endif + +#if !defined(CONFIG_) || \ + CONFIG_BLUETOOTH_BUFFER_IRQRESERVE < 0 +# undef CONFIG_BLUETOOTH_BUFFER_IRQRESERVE +# define CONFIG_BLUETOOTH_BUFFER_IRQRESERVE 0 +#endif + +config BLUETOOTH_BUFFER_PREALLOC + int "Number of pre-allocated buffer structures" + default 20 + ---help--- + This specifies the total number of preallocated buffer structures. + This is for performance optimization. If additional buffer structures + are needed, they will be allocated dynamically at some loss of + performance. + +config BLUETOOTH_BUFFER_IRQRESERVE + int "Reserved pre-allocated primitive structures" + default 0 + depends on EXPERIMENTAL + ---help--- + If buffer structures can be allocated from interrupt handlers, then + this specifies the number of pre-allocated structures that are + reserved for for use only by interrupt handlers. This may be set + zero to reserve no buffers for interrupt handlers. In that case, + the allocation will fail if tasking logic has allocated them all. + + Interrupt logic will first attempt to allocate from the general, + pre-allocated buffer pool that will contain up to (size + CONFIG_BLUETOOTH_BUFFER_PREALLOC - BLUETOOTH_BUFFER_IRQRESERVE) + entries. If that fails, then it will try to take a buffer from + the reserve (size CONFIG_BLUETOOTH_BUFFER_IRQRESERVE). + + Non-interrupt logic will also first attempt to allocate from the + general, pre-allocated buffer pool. If that fails, it will + dynamically allocate the buffer with an additional cost in + performance. + + NOTE: Currently marked as experimental and with a default of zero + because there are no interrupt level allocations performed by the + current Bluetooth stack. + menu "Kernel Thread Configuration" config BLUETOOTH_RXTHREAD_STACKSIZE diff --git a/wireless/bluetooth/bt_att.c b/wireless/bluetooth/bt_att.c index 786dd597a4e..0540f0c7ea2 100644 --- a/wireless/bluetooth/bt_att.c +++ b/wireless/bluetooth/bt_att.c @@ -276,10 +276,12 @@ static uint8_t att_handle_read_mult_rsp(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf); static uint8_t att_handle_write_rsp(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf); -static void bt_att_recv(FAR struct bt_conn_s *conn, - FAR struct bt_buf_s *buf); -static void bt_att_connected(FAR struct bt_conn_s *conn); -static void bt_att_disconnected(FAR struct bt_conn_s *conn); +static void bt_att_receive(FAR struct bt_conn_s *conn, + FAR struct bt_buf_s *buf, FAR void *context, uint16_t cid); +static void bt_att_connected(FAR struct bt_conn_s *conn, FAR void *context, + uint16_t cid); +static void bt_att_disconnected(FAR struct bt_conn_s *conn, + FAR void *context, uint16_t cid); /**************************************************************************** * Private Data @@ -451,7 +453,7 @@ static void send_err_rsp(struct bt_conn_s *conn, uint8_t req, uint16_t handle, return; } - rsp = bt_buf_add(buf, sizeof(*rsp)); + rsp = bt_buf_extend(buf, sizeof(*rsp)); rsp->request = req; rsp->handle = BT_HOST2LE16(handle); rsp->error = err; @@ -499,7 +501,7 @@ static uint8_t att_mtu_req(struct bt_conn_s *conn, struct bt_buf_s *data) att->mtu = mtu; - rsp = bt_buf_add(buf, sizeof(*rsp)); + rsp = bt_buf_extend(buf, sizeof(*rsp)); rsp->mtu = BT_HOST2LE16(mtu); bt_l2cap_send(conn, BT_L2CAP_CID_ATT, buf); @@ -610,7 +612,7 @@ static uint8_t find_info_cb(FAR const struct bt_gatt_attr_s *attr, if (!data->rsp) { - data->rsp = bt_buf_add(data->buf, sizeof(*data->rsp)); + data->rsp = bt_buf_extend(data->buf, sizeof(*data->rsp)); data->rsp->format = (attr->uuid->type == BT_UUID_16) ? BT_ATT_INFO_16 : BT_ATT_INFO_128; } @@ -625,7 +627,7 @@ static uint8_t find_info_cb(FAR const struct bt_gatt_attr_s *attr, /* Fast foward to next item position */ - data->u.info16 = bt_buf_add(data->buf, sizeof(*data->u.info16)); + data->u.info16 = bt_buf_extend(data->buf, sizeof(*data->u.info16)); data->u.info16->handle = BT_HOST2LE16(attr->handle); data->u.info16->uuid = BT_HOST2LE16(attr->uuid->u.u16); @@ -640,7 +642,7 @@ static uint8_t find_info_cb(FAR const struct bt_gatt_attr_s *attr, /* Fast foward to next item position */ - data->u.info128 = bt_buf_add(data->buf, sizeof(*data->u.info128)); + data->u.info128 = bt_buf_extend(data->buf, sizeof(*data->u.info128)); data->u.info128->handle = BT_HOST2LE16(attr->handle); memcpy(data->u.info128->uuid, attr->uuid->u.u128, sizeof(data->u.info128->uuid)); @@ -670,7 +672,7 @@ static uint8_t att_find_info_rsp(FAR struct bt_conn_s *conn, if (!data.rsp) { - bt_buf_put(data.buf); + bt_buf_release(data.buf); /* Respond since handle is set */ @@ -759,7 +761,7 @@ static uint8_t find_type_cb(FAR const struct bt_gatt_attr_s *attr, /* Fast foward to next item position */ - data->group = bt_buf_add(data->buf, sizeof(*data->group)); + data->group = bt_buf_extend(data->buf, sizeof(*data->group)); data->group->start_handle = BT_HOST2LE16(attr->handle); data->group->end_handle = BT_HOST2LE16(attr->handle); @@ -791,7 +793,7 @@ static uint8_t att_find_type_rsp(FAR struct bt_conn_s *conn, if (!data.group) { - bt_buf_put(data.buf); + bt_buf_release(data.buf); /* Respond since handle is set */ @@ -819,7 +821,7 @@ static uint8_t att_find_type_req(FAR struct bt_conn_s *conn, start_handle = BT_LE162HOST(req->start_handle); end_handle = BT_LE162HOST(req->end_handle); type = BT_LE162HOST(req->type); - value = bt_buf_pull(data, sizeof(*req)); + value = bt_buf_consume(data, sizeof(*req)); wlinfo("start_handle 0x%04x end_handle 0x%04x type %u\n", start_handle, end_handle, type); @@ -858,7 +860,7 @@ static bool uuid_create(FAR struct bt_uuid_s *uuid, FAR struct bt_buf_s *data) { case 2: uuid->type = BT_UUID_16; - uuid->u.u16 = bt_buf_pull_le16(data); + uuid->u.u16 = bt_buf_get_le16(data); return true; case 16: @@ -888,7 +890,7 @@ static uint8_t read_type_cb(FAR const struct bt_gatt_attr_s *attr, /* Fast foward to next item position */ - data->item = bt_buf_add(data->buf, sizeof(*data->item)); + data->item = bt_buf_extend(data->buf, sizeof(*data->item)); data->item->handle = BT_HOST2LE16(attr->handle); /* Read attribute value and store in the buffer */ @@ -916,7 +918,7 @@ static uint8_t read_type_cb(FAR const struct bt_gatt_attr_s *attr, return BT_GATT_ITER_STOP; } - bt_buf_add(data->buf, read); + bt_buf_extend(data->buf, read); /* Return true only if there are still space for more items */ @@ -941,14 +943,14 @@ static uint8_t att_read_type_rsp(FAR struct bt_conn_s *conn, } data.uuid = uuid; - data.rsp = bt_buf_add(data.buf, sizeof(*data.rsp)); + data.rsp = bt_buf_extend(data.buf, sizeof(*data.rsp)); data.rsp->len = 0; bt_gatt_foreach_attr(start_handle, end_handle, read_type_cb, &data); if (!data.rsp->len) { - bt_buf_put(data.buf); + bt_buf_release(data.buf); /* Response here since handle is set */ @@ -981,7 +983,7 @@ static uint8_t att_read_type_req(FAR struct bt_conn_s *conn, req = (FAR void *)data->data; start_handle = BT_LE162HOST(req->start_handle); end_handle = BT_LE162HOST(req->end_handle); - bt_buf_pull(data, sizeof(*req)); + bt_buf_consume(data, sizeof(*req)); if (!uuid_create(&uuid, data)) { @@ -1062,7 +1064,7 @@ static uint8_t read_cb(FAR const struct bt_gatt_attr_s *attr, wlinfo("handle 0x%04x\n", attr->handle); - data->rsp = bt_buf_add(data->buf, sizeof(*data->rsp)); + data->rsp = bt_buf_extend(data->buf, sizeof(*data->rsp)); if (!attr->read) { @@ -1088,7 +1090,7 @@ static uint8_t read_cb(FAR const struct bt_gatt_attr_s *attr, return BT_GATT_ITER_STOP; } - bt_buf_add(data->buf, read); + bt_buf_extend(data->buf, read); return BT_GATT_ITER_CONTINUE; } @@ -1119,7 +1121,7 @@ static uint8_t att_read_rsp(FAR struct bt_conn_s *conn, uint8_t op, if (data.err) { - bt_buf_put(data.buf); + bt_buf_release(data.buf); /* Respond here since handle is set */ @@ -1181,7 +1183,7 @@ static uint8_t att_read_mult_req(FAR struct bt_conn_s *conn, while (buf->len >= sizeof(uint16_t)) { - handle = bt_buf_pull_le16(buf); + handle = bt_buf_get_le16(buf); wlinfo("handle 0x%04x \n", handle); @@ -1191,7 +1193,7 @@ static uint8_t att_read_mult_req(FAR struct bt_conn_s *conn, if (data.err) { - bt_buf_put(data.buf); + bt_buf_release(data.buf); /* Respond here since handle is set */ @@ -1235,7 +1237,7 @@ static uint8_t read_group_cb(FAR const struct bt_gatt_attr_s *attr, /* Fast forward to next group position */ - data->group = bt_buf_add(data->buf, sizeof(*data->group)); + data->group = bt_buf_extend(data->buf, sizeof(*data->group)); /* Initialize group handle range */ @@ -1267,7 +1269,7 @@ static uint8_t read_group_cb(FAR const struct bt_gatt_attr_s *attr, return false; } - bt_buf_add(data->buf, read); + bt_buf_extend(data->buf, read); /* Continue to find the end handle */ @@ -1292,14 +1294,14 @@ static uint8_t att_read_group_rsp(FAR struct bt_conn_s *conn, data.conn = conn; data.uuid = uuid; - data.rsp = bt_buf_add(data.buf, sizeof(*data.rsp)); + data.rsp = bt_buf_extend(data.buf, sizeof(*data.rsp)); data.rsp->len = 0; bt_gatt_foreach_attr(start_handle, end_handle, read_group_cb, &data); if (!data.rsp->len) { - bt_buf_put(data.buf); + bt_buf_release(data.buf); /* Respond here since handle is set */ @@ -1332,7 +1334,7 @@ static uint8_t att_read_group_req(FAR struct bt_conn_s *conn, req = (FAR void *)data->data; start_handle = BT_LE162HOST(req->start_handle); end_handle = BT_LE162HOST(req->end_handle); - bt_buf_pull(data, sizeof(*req)); + bt_buf_consume(data, sizeof(*req)); if (!uuid_create(&uuid, data)) { @@ -1456,7 +1458,7 @@ static uint8_t att_write_rsp(FAR struct bt_conn_s *conn, uint8_t op, { if (rsp) { - bt_buf_put(data.buf); + bt_buf_release(data.buf); /* Respond here since handle is set */ @@ -1474,10 +1476,10 @@ static uint8_t att_write_rsp(FAR struct bt_conn_s *conn, uint8_t op, { FAR struct bt_att_prepare_write_rsp_s *wrrsp; - wrrsp = bt_buf_add(data.buf, sizeof(*wrrsp)); + wrrsp = bt_buf_extend(data.buf, sizeof(*wrrsp)); wrrsp->handle = BT_HOST2LE16(handle); wrrsp->offset = BT_HOST2LE16(offset); - bt_buf_add(data.buf, len); + bt_buf_extend(data.buf, len); memcpy(wrrsp->value, value, len); } @@ -1496,7 +1498,7 @@ static uint8_t att_write_req(FAR struct bt_conn_s *conn, req = (FAR void *)data->data; handle = BT_LE162HOST(req->handle); - bt_buf_pull(data, sizeof(*req)); + bt_buf_consume(data, sizeof(*req)); wlinfo("handle 0x%04x\n", handle); @@ -1514,7 +1516,7 @@ static uint8_t att_prepare_write_req(FAR struct bt_conn_s *conn, req = (FAR void *)data->data; handle = BT_LE162HOST(req->handle); offset = BT_LE162HOST(req->offset); - bt_buf_pull(data, sizeof(*req)); + bt_buf_consume(data, sizeof(*req)); wlinfo("handle 0x%04x offset %u\n", handle, offset); @@ -1577,7 +1579,7 @@ static uint8_t att_exec_write_rsp(FAR struct bt_conn_s *conn, uint8_t flags) if (data.err) { - bt_buf_put(data.buf); + bt_buf_release(data.buf); return data.err; } @@ -1628,7 +1630,7 @@ static uint8_t att_signed_write_cmd(FAR struct bt_conn_s *conn, req = (FAR void *)data->data; handle = BT_LE162HOST(req->handle); - bt_buf_pull(data, sizeof(*req)); + bt_buf_consume(data, sizeof(*req)); wlinfo("handle 0x%04x\n", handle); @@ -1712,7 +1714,9 @@ static uint8_t att_handle_write_rsp(FAR struct bt_conn_s *conn, return att_handle_rsp(conn, buf->data, buf->len, 0); } -static void bt_att_recv(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf) +static void bt_att_receive(FAR struct bt_conn_s *conn, + FAR struct bt_buf_s *buf, FAR void *context, + uint16_t cid) { FAR struct bt_att_hdr_s *hdr = (FAR void *)buf->data; uint8_t err = BT_ATT_ERR_NOT_SUPPORTED; @@ -1728,7 +1732,7 @@ static void bt_att_recv(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf) wlinfo("Received ATT code 0x%02x len %u\n", hdr->code, buf->len); - bt_buf_pull(buf, sizeof(*hdr)); + bt_buf_consume(buf, sizeof(*hdr)); for (i = 0; i < NHANDLERS; i++) { @@ -1763,10 +1767,11 @@ static void bt_att_recv(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf) } done: - bt_buf_put(buf); + bt_buf_release(buf); } -static void bt_att_connected(FAR struct bt_conn_s *conn) +static void bt_att_connected(FAR struct bt_conn_s *conn, FAR void *context, + uint16_t cid) { int i; @@ -1789,7 +1794,8 @@ static void bt_att_connected(FAR struct bt_conn_s *conn) wlerr("ERROR: No available ATT context for conn %p\n", conn); } -static void bt_att_disconnected(FAR struct bt_conn_s *conn) +static void bt_att_disconnected(FAR struct bt_conn_s *conn, + FAR void *context, uint16_t cid) { FAR struct bt_att_s *att = conn->att; @@ -1809,12 +1815,12 @@ static void bt_att_disconnected(FAR struct bt_conn_s *conn) * Public Functions ****************************************************************************/ -void bt_att_init(void) +void bt_att_initialize(void) { static struct bt_l2cap_chan_s chan = { .cid = BT_L2CAP_CID_ATT, - .recv = bt_att_recv, + .receive = bt_att_receive, .connected = bt_att_connected, .disconnected = bt_att_disconnected, }; @@ -1841,7 +1847,7 @@ FAR struct bt_buf_s *bt_att_create_pdu(FAR struct bt_conn_s *conn, uint8_t op, return NULL; } - hdr = bt_buf_add(buf, sizeof(*hdr)); + hdr = bt_buf_extend(buf, sizeof(*hdr)); hdr->code = op; return buf; diff --git a/wireless/bluetooth/bt_att.h b/wireless/bluetooth/bt_att.h index b4b150685b9..1050f46364b 100644 --- a/wireless/bluetooth/bt_att.h +++ b/wireless/bluetooth/bt_att.h @@ -434,7 +434,7 @@ typedef void (*bt_att_destroy_t)(FAR void *user_data); * Public Function Prototypes ****************************************************************************/ -void bt_att_init(void); +void bt_att_initialize(void); struct bt_buf_s *bt_att_create_pdu(FAR struct bt_conn_s *conn, uint8_t op, size_t len); diff --git a/wireless/bluetooth/bt_buf.c b/wireless/bluetooth/bt_buf.c index 5611949574b..2ab0d833efe 100644 --- a/wireless/bluetooth/bt_buf.c +++ b/wireless/bluetooth/bt_buf.c @@ -51,6 +51,7 @@ #include #include +#include #include #include #include @@ -58,99 +59,446 @@ #include "bt_hcicore.h" +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* NOTE: The CONFIG_BLUETOOTH_BUFFER_IRQRESERVE options is marked as marked + * 'experimental' and with the default 0 zero because there are no interrupt + * level allocations performed by the current Bluetooth code. + */ + +#if !defined(CONFIG_BLUETOOTH_BUFFER_PREALLOC) || \ + CONFIG_BLUETOOTH_BUFFER_PREALLOC < 1 +# undef CONFIG_BLUETOOTH_BUFFER_PREALLOC +# define CONFIG_BLUETOOTH_BUFFER_PREALLOC 20 +#endif + +#if !defined(CONFIG_BLUETOOTH_BUFFER_IRQRESERVE) || \ + CONFIG_BLUETOOTH_BUFFER_IRQRESERVE < 0 +# undef CONFIG_BLUETOOTH_BUFFER_IRQRESERVE +# define CONFIG_BLUETOOTH_BUFFER_IRQRESERVE 0 +#endif + +#if CONFIG_BLUETOOTH_BUFFER_IRQRESERVE > CONFIG_BLUETOOTH_BUFFER_PREALLOC +# undef CONFIG_BLUETOOTH_BUFFER_IRQRESERVE +# define CONFIG_BLUETOOTH_BUFFER_IRQRESERVE CONFIG_BLUETOOTH_BUFFER_PREALLOC +#endif + +/* Memory Pools */ + +#define POOL_BUFFER_GENERAL 0 +#define POOL_BUFFER_IRQ 1 +#define POOL_BUFFER_DYNAMIC 2 + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#if CONFIG_BLUETOOTH_BUFFER_PREALLOC > CONFIG_BLUETOOTH_BUFFER_IRQRESERVE +/* g_buf_free is a list of buffers that are available for general use. The + * number of messages in this list is a system configuration item. + */ + +static struct bt_buf_s *g_buf_free; +#endif + +#if CONFIG_BLUETOOTH_BUFFER_IRQRESERVE > 0 +/* The g_buf_free_irq is a list of buffer structures that are reserved for + * use by only by interrupt handlers. + */ + +static struct bt_buf_s *g_buf_free_irq; +#endif + +/* Pool of pre-allocated buffer structures */ + +static struct bt_buf_s + g_buf_pool[CONFIG_BLUETOOTH_BUFFER_PREALLOC]; + +static bool g_poolinit = false; + /**************************************************************************** * Public Functions ****************************************************************************/ -FAR struct bt_buf_s *bt_buf_get(enum bt_buf_type_e type, size_t reserve_head) +/**************************************************************************** + * Name: bt_buf_initialize + * + * Description: + * This function initializes the buffer allocator. This function must + * be called early in the initialization sequence before any radios + * begin operation. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void bt_buf_initialize(void) { - FAR struct bt_buf_s *buf; - FAR struct iob_s *iob; + FAR struct bt_buf_s *pool = g_buf_pool; + int remaining = CONFIG_BLUETOOTH_BUFFER_PREALLOC; - wlinfo("type %d reserve %u\n", type, reserve_head); + /* Only allow the pool to be initialized once */ - iob = iob_alloc(false); - if (iob == NULL) + if (g_poolinit) { - if (up_interrupt_context()) - { - wlerr("ERROR: Failed to get free buffer\n"); - return NULL; - } - - wlwarn("WARNING: Low on buffers. Waiting (type %d)\n", type); - iob = iob_alloc(false); + return; } - iob->io_len = sizeof(struct bt_buf_s); - iob->io_offset = 0; - iob->io_pktlen = sizeof(struct bt_buf_s); + g_poolinit = true; - buf = (FAR struct bt_buf_s *)iob->io_data; - memset(buf, 0, sizeof(struct bt_buf_s)); +#if CONFIG_BLUETOOTH_BUFFER_PREALLOC > CONFIG_BLUETOOTH_BUFFER_IRQRESERVE + /* Initialize g_buf_free, the list of buffer structures that are available + * for general use. + */ - buf->iob = iob; - buf->ref = 1; - buf->type = type; - buf->data = buf->buf + reserve_head; + g_buf_free = NULL; + while (remaining > CONFIG_BLUETOOTH_BUFFER_IRQRESERVE) + { + FAR struct bt_buf_s *buf = pool; - wlinfo("buf %p type %d reserve %u\n", buf, buf->type, reserve_head); - return buf; + /* Add the next meta data structure from the pool to the list of + * general structures. + */ + + buf->flink = g_buf_free; + g_buf_free = buf; + + /* Set up for the next structure from the pool */ + + pool++; + remaining--; + } +#endif + +#if CONFIG_BLUETOOTH_BUFFER_IRQRESERVE > 0 + /* Initialize g_buf_free_irq is a list of buffer structures reserved for + * use by only by interrupt handlers. + */ + + g_buf_free_irq = NULL; + while (remaining > 0) + { + FAR struct bt_buf_s *buf = pool; + + /* Add the next meta data structure from the pool to the list of + * general structures. + */ + + buf->flink = g_buf_free_irq; + g_buf_free_irq = buf; + + /* Set up for the next structure from the pool */ + + pool++; + remaining--; + } +#endif } -void bt_buf_put(FAR struct bt_buf_s *buf) +/**************************************************************************** + * Name: bt_buf_alloc + * + * Description: + * The bt_buf_alloc function will get a free buffer for use by the + * Bluetooth stack with specified type and reserved headroom. The + * reference count is initially set to one. + * + * Interrupt handling logic will first attempt to allocate from the + * g_buf_free list. If that list is empty, it will attempt to allocate + * from its reserve, g_buf_free_irq. If that list is empty, then the + * allocation fails (NULL is returned). + * + * Non-interrupt handler logic will attempt to allocate from g_buf_free + * list. If that the list is empty, then the buffer structure will be + * allocated from the dynamic memory pool with some performance hit. + * + * Input Parameters: + * type - Buffer type. + * reserve_head - How much headroom to reserve. + * + * Returned Value: + * A reference to the allocated buffer structure. All user fields in this + * structure have been zeroed. On a failure to allocate, NULL is + * returned. + * + ****************************************************************************/ + +FAR struct bt_buf_s *bt_buf_alloc(enum bt_buf_type_e type, size_t + reserve_head) +{ + FAR struct bt_buf_s *buf; + irqstate_t flags; + uint8_t pool; + + /* If we were called from an interrupt handler, then try to get the meta- + * data structure from generally available list of messages. If this fails, + * then try the list of messages reserved for interrupt handlers + */ + + flags = enter_critical_section(); /* Always necessary in SMP mode */ + if (up_interrupt_context()) + { +#if CONFIG_BLUETOOTH_BUFFER_PREALLOC > CONFIG_BLUETOOTH_BUFFER_IRQRESERVE + /* Try the general free list */ + + if (g_buf_free != NULL) + { + buf = g_buf_free; + g_buf_free = buf->flink; + + leave_critical_section(flags); + pool = POOL_BUFFER_GENERAL; + } + else +#endif +#if CONFIG_BLUETOOTH_BUFFER_IRQRESERVE > 0 + /* Try the list list reserved for interrupt handlers */ + + if (g_buf_free_irq != NULL) + { + buf = g_buf_free_irq; + g_buf_free_irq = buf->flink; + + leave_critical_section(flags); + pool = POOL_BUFFER_IRQ; + } + else +#endif + { + leave_critical_section(flags); + return NULL; + } + } + + /* We were not called from an interrupt handler. */ + + else + { +#if CONFIG_BLUETOOTH_BUFFER_PREALLOC > CONFIG_BLUETOOTH_BUFFER_IRQRESERVE + /* Try the general free list */ + + if (g_buf_free != NULL) + { + buf = g_buf_free; + g_buf_free = buf->flink; + + leave_critical_section(flags); + pool = POOL_BUFFER_GENERAL; + } + else +#endif + { + /* If we cannot get a buffer structure from the free list, then we + * will have to allocate one from the kernel memory pool. + */ + + leave_critical_section(flags); + buf = (FAR struct bt_buf_s *)kmm_malloc((sizeof (struct bt_buf_s))); + + /* Check if we successfully allocated the buffer structure */ + + if (buf == NULL) + { + /* No.. memory not available */ + + wlerr("ERROR: Failed to allocate buffer.\n"); + return NULL; + } + + /* Remember that this buffer structure was dynamically allocated */ + + pool = POOL_BUFFER_DYNAMIC; + } + } + + /* We have successfully allocated memory from some source. Now allocate + * an IOB to hold the actual frame data. This call will normally block + * in the event that there is no available IOB memory. It will return + * NULL is called from an interrupt handler with no available buffers. + */ + + memset(buf, 0, sizeof(struct bt_buf_s)); + buf->frame = iob_alloc(false); + if (!buf->frame) + { + bt_buf_release(buf); + return NULL; + } + + /* Initialize the allocated buffer structure. */ + + buf->pool = pool; + buf->ref = 1; + buf->type = type; + buf->data = buf->frame->io_data + reserve_head; + + buf->frame->io_offset = reserve_head; + buf->frame->io_len = reserve_head; + buf->frame->io_pktlen = reserve_head; + + wlinfo("buf %p type %d reserve %u\n", buf, buf->type, reserve_head); + + return buf; +} +/**************************************************************************** + * Name: bt_buf_release + * + * Description: + * The bt_buf_release function will return a buffer structure to + * the free pool of buffers if it was a pre-allocated buffer structure. + * If the buffer structure was allocated dynamically it will be + * deallocated. + * + * Input Parameters: + * buf - Buffer structure to free + * + * Returned Value: + * None + * + ****************************************************************************/ + +void bt_buf_release(FAR struct bt_buf_s *buf) { - FAR struct bt_hci_cp_host_num_completed_packets_s *cp; - FAR struct bt_hci_handle_count_s *hc; enum bt_buf_type_e type; + irqstate_t flags; uint16_t handle; wlinfo("buf %p ref %u type %d\n", buf, buf->ref, buf->type); if (--buf->ref > 0) { + wlinfo("Remaining references: %d\n", buf->ref); return; } handle = buf->u.acl.handle; type = buf->type; - DEBUGASSERT(buf->iob != NULL); - iob_free(buf->iob); + /* Free the contained frame and return the container to the correct memory + * pool. + */ - if (type != BT_ACL_IN) + if (buf->frame == NULL) { - return; + iob_free(buf->frame); + buf->frame = NULL; } - wlinfo("Reporting completed packet for handle %u\n", handle); +#if CONFIG_BLUETOOTH_BUFFER_PREALLOC > CONFIG_BLUETOOTH_BUFFER_IRQRESERVE + /* If this is a generally available pre-allocated buffer structure, + * then just put it back in the free list. + */ - buf = bt_hci_cmd_create(BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS, - sizeof(*cp) + sizeof(*hc)); - if (!buf) + if (buf->pool == POOL_BUFFER_GENERAL) { - wlerr("ERROR: Unable to allocate new HCI command\n"); - return; + /* Make sure we avoid concurrent access to the free + * list from interrupt handlers. + */ + + flags = enter_critical_section(); + buf->flink = g_buf_free; + g_buf_free = buf; + leave_critical_section(flags); + } + else +#endif + +#if CONFIG_BLUETOOTH_BUFFER_IRQRESERVE > 0 + /* If this is a buffer structure pre-allocated for interrupts, + * then put it back in the correct free list. + */ + + if (buf->pool == POOL_BUFFER_IRQ) + { + /* Make sure we avoid concurrent access to the free + * list from interrupt handlers. + */ + + flags = enter_critical_section(); + buf->flink = g_buf_free_irq; + g_buf_free_irq = buf; + leave_critical_section(flags); + } + else +#endif + + { + /* Otherwise, deallocate it. */ + + DEBUGASSERT(buf->pool == POOL_BUFFER_DYNAMIC); + sched_kfree(buf); } - cp = bt_buf_add(buf, sizeof(*cp)); - cp->num_handles = BT_HOST2LE16(1); + wlinfo("Buffer freed: %p\n", buf); - hc = bt_buf_add(buf, sizeof(*hc)); - hc->handle = BT_HOST2LE16(handle); - hc->count = BT_HOST2LE16(1); + if (type == BT_ACL_IN) + { + FAR struct bt_hci_cp_host_num_completed_packets_s *cp; + FAR struct bt_hci_handle_count_s *hc; - bt_hci_cmd_send(BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS, buf); + wlinfo("Reporting completed packet for handle %u\n", handle); + + buf = bt_hci_cmd_create(BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS, + sizeof(*cp) + sizeof(*hc)); + if (buf == NULL) + { + wlerr("ERROR: Unable to allocate new HCI command\n"); + return; + } + + cp = bt_buf_extend(buf, sizeof(*cp)); + cp->num_handles = BT_HOST2LE16(1); + + hc = bt_buf_extend(buf, sizeof(*hc)); + hc->handle = BT_HOST2LE16(handle); + hc->count = BT_HOST2LE16(1); + + bt_hci_cmd_send(BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS, buf); + } } -FAR struct bt_buf_s *bt_buf_hold(FAR struct bt_buf_s *buf) +/**************************************************************************** + * Name: bt_buf_addref + * + * Description: + * Increment the reference count of a buffer. + * + * Input Parameters: + * buf - Buffer. + * + ****************************************************************************/ + +FAR struct bt_buf_s *bt_buf_addref(FAR struct bt_buf_s *buf) { wlinfo("buf %p (old) ref %u type %d\n", buf, buf->ref, buf->type); + buf->ref++; return buf; } -FAR void *bt_buf_add(FAR struct bt_buf_s *buf, size_t len) +/**************************************************************************** + * Name: bt_buf_extend + * + * Description: + * Increments the data length of a buffer to account for more data + * at the end of the buffer. + * + * Input Parameters: + * buf - Buffer to update. + * len - Number of bytes to increment the length with. + * + * Returned Value: + * The original tail of the buffer. + * + ****************************************************************************/ + +FAR void *bt_buf_extend(FAR struct bt_buf_s *buf, size_t len) { FAR uint8_t *tail = bt_buf_tail(buf); @@ -162,26 +510,75 @@ FAR void *bt_buf_add(FAR struct bt_buf_s *buf, size_t len) return tail; } -void bt_buf_add_le16(FAR struct bt_buf_s *buf, uint16_t value) +/**************************************************************************** + * Name: bt_buf_put_le16 + * + * Description: + * Adds 16-bit value in little endian format at the end of buffer. + * Increments the data length of a buffer to account for more data + * at the end. + * + * Input Parameters: + * buf - Buffer to update. + * value - 16-bit value to be added. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void bt_buf_put_le16(FAR struct bt_buf_s *buf, uint16_t value) { wlinfo("buf %p value %u\n", buf, value); value = BT_HOST2LE16(value); - memcpy(bt_buf_add(buf, sizeof(value)), &value, sizeof(value)); + memcpy(bt_buf_extend(buf, sizeof(value)), &value, sizeof(value)); } -FAR void *bt_buf_push(FAR struct bt_buf_s *buf, size_t len) +/**************************************************************************** + * Name: bt_buf_provide + * + * Description: + * Modifies the data pointer and buffer length to account for more data + * in the beginning of the buffer. + * + * Input Parameters: + * buf - Buffer to update. + * len - Number of bytes to add to the beginning. + * + * Returned Value: + * The new beginning of the buffer data. + * + ****************************************************************************/ + +FAR void *bt_buf_provide(FAR struct bt_buf_s *buf, size_t len) { wlinfo("buf %p len %u\n", buf, len); - DEBUGASSERT(bt_buf_headroom(buf) >= len); + DEBUGASSERT(buf != NULL && buf->frame != NULL && + bt_buf_headroom(buf) >= len); buf->data -= len; buf->len += len; return buf->data; } -FAR void *bt_buf_pull(FAR struct bt_buf_s *buf, size_t len) +/**************************************************************************** + * Name: bt_buf_consume + * + * Description: + * Removes data from the beginning of the buffer by modifying the data + * pointer and buffer length. + * + * Input Parameters: + * len - Number of bytes to remove. + * + * Returned Value: + * New beginning of the buffer data. + * + ****************************************************************************/ + +FAR void *bt_buf_consume(FAR struct bt_buf_s *buf, size_t len) { wlinfo("buf %p len %u\n", buf, len); @@ -191,31 +588,60 @@ FAR void *bt_buf_pull(FAR struct bt_buf_s *buf, size_t len) return buf->data += len; } -uint16_t bt_buf_pull_le16(FAR struct bt_buf_s * buf) +/**************************************************************************** + * Name: bt_buf_get_le16 + * + * Description: + * Same idea as with bt_buf_pull(), but a helper for operating on + * 16-bit little endian data. + * + * Input Parameters: + * buf - Buffer. + * + * Returned Value: + * 16-bit value converted from little endian to host endian. + * + ****************************************************************************/ + +uint16_t bt_buf_get_le16(FAR struct bt_buf_s * buf) { uint16_t value; value = BT_GETUINT16((FAR uint8_t *)buf->data); - bt_buf_pull(buf, sizeof(value)); + bt_buf_consume(buf, sizeof(value)); return BT_LE162HOST(value); } -size_t bt_buf_headroom(FAR struct bt_buf_s * buf) +/**************************************************************************** + * Name: bt_buf_headroom + * + * Description: + * Check how much free space there is in the beginning of the buffer. + * + * Returned Value: + * Number of bytes available in the beginning of the buffer. + * + ****************************************************************************/ + +size_t bt_buf_headroom(FAR struct bt_buf_s *buf) { - return buf->data - buf->buf; + DEBUGASSERT(buf != NULL && buf->frame != NULL); + return buf->data - buf->frame->io_data; } +/**************************************************************************** + * Name: bt_buf_tailroom + * + * Description: + * Check how much free space there is at the end of the buffer. + * + * Returned Value: + * Number of bytes available at the end of the buffer. + * + ****************************************************************************/ + size_t bt_buf_tailroom(FAR struct bt_buf_s * buf) { return BT_BUF_MAX_DATA - bt_buf_headroom(buf) - buf->len; } - -int bt_buf_init(void) -{ - wlinfo("Configured IOBs: IOBs: %u size: %u (%u)\n", - CONFIG_IOB_NBUFFERS, CONFIG_IOB_BUFSIZE, sizeof(struct bt_buf_s)); - - DEBUGASSERT(sizeof(struct bt_buf_s) <= CONFIG_IOB_BUFSIZE); - return 0; -} diff --git a/wireless/bluetooth/bt_buf.h b/wireless/bluetooth/bt_buf.h new file mode 100644 index 00000000000..1d1236bad4b --- /dev/null +++ b/wireless/bluetooth/bt_buf.h @@ -0,0 +1,74 @@ +/**************************************************************************** + * wireless/bluetooth/bt_buf.h + * Bluetooth buffer management. + * + * Copyright (C) 2018 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Ported from the Intel/Zephyr arduino101_firmware_source-v1.tar package + * where the code was released with a compatible 3-clause BSD license: + * + * Copyright (c) 2016, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __WIRELESS_BLUETOOTH_BT_BUF_H +#define __WIRELESS_BLUETOOTH_BT_BUF_H 1 + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: bt_buf_initialize + * + * Description: + * This function initializes the buffer allocator. This function must + * be called early in the initialization sequence before any radios + * begin operation. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void bt_buf_initialize(void); + +#endif /* __WIRELESS_BLUETOOTH_BT_BUF_H */ diff --git a/wireless/bluetooth/bt_conn.c b/wireless/bluetooth/bt_conn.c index 9b18e90999f..493304df965 100644 --- a/wireless/bluetooth/bt_conn.c +++ b/wireless/bluetooth/bt_conn.c @@ -123,7 +123,7 @@ static void bt_conn_reset_rx_state(FAR struct bt_conn_s *conn) return; } - bt_buf_put(conn->rx); + bt_buf_release(conn->rx); conn->rx = NULL; conn->rx_len = 0; } @@ -166,20 +166,20 @@ static int conn_tx_kthread(int argc, FAR char *argv[]) /* Get next ACL packet for connection */ - ret = bt_queue_recv(conn->tx_queue, &buf); + ret = bt_queue_receive(conn->tx_queue, &buf); DEBUGASSERT(ret >= 0 && buf != NULL); UNUSED(ret); if (conn->state != BT_CONN_CONNECTED) { nxsem_post(&g_btdev.le_pkts_sem); - bt_buf_put(buf); + bt_buf_release(buf); break; } wlinfo("passing buf %p len %u to driver\n", buf, buf->len); g_btdev.dev->send(g_btdev.dev, buf); - bt_buf_put(buf); + bt_buf_release(buf); } wlinfo("handle %u disconnected - cleaning up\n", conn->handle); @@ -189,11 +189,11 @@ static int conn_tx_kthread(int argc, FAR char *argv[]) do { buf = NULL; - ret = bt_queue_recv(conn->tx_queue, &buf); + ret = bt_queue_receive(conn->tx_queue, &buf); if (ret >= 0) { DEBUGASSERT(buf != NULL); - bt_buf_put(buf); + bt_buf_release(buf); } } while (ret >= OK); @@ -217,7 +217,7 @@ static int bt_hci_disconnect(FAR struct bt_conn_s *conn, uint8_t reason) return -ENOBUFS; } - disconn = bt_buf_add(buf, sizeof(*disconn)); + disconn = bt_buf_extend(buf, sizeof(*disconn)); disconn->handle = BT_HOST2LE16(conn->handle); disconn->reason = reason; @@ -249,7 +249,7 @@ static int bt_hci_connect_le_cancel(FAR struct bt_conn_s *conn) ****************************************************************************/ /**************************************************************************** - * Name: bt_conn_input + * Name: bt_conn_receive * * Description: * Receive packets from the HCI core on a registered connection. @@ -264,8 +264,8 @@ static int bt_hci_connect_le_cancel(FAR struct bt_conn_s *conn) * ****************************************************************************/ -void bt_conn_input(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf, - uint8_t flags) +void bt_conn_receive(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf, + uint8_t flags) { FAR struct bt_l2cap_hdr_s *hdr; uint16_t len; @@ -307,7 +307,7 @@ void bt_conn_input(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf, { wlerr("ERROR: Unexpected L2CAP continuation\n"); bt_conn_reset_rx_state(conn); - bt_buf_put(buf); + bt_buf_release(buf); return; } @@ -315,7 +315,7 @@ void bt_conn_input(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf, { wlerr("ERROR: L2CAP data overflow\n"); bt_conn_reset_rx_state(conn); - bt_buf_put(buf); + bt_buf_release(buf); return; } @@ -325,13 +325,13 @@ void bt_conn_input(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf, { wlerr("ERROR: Not enough buffer space for L2CAP data\n"); bt_conn_reset_rx_state(conn); - bt_buf_put(buf); + bt_buf_release(buf); return; } - memcpy(bt_buf_add(conn->rx, buf->len), buf->data, buf->len); + memcpy(bt_buf_extend(conn->rx, buf->len), buf->data, buf->len); conn->rx_len -= buf->len; - bt_buf_put(buf); + bt_buf_release(buf); if (conn->rx_len) { @@ -347,7 +347,7 @@ void bt_conn_input(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf, default: wlerr("ERROR: Unexpected ACL flags (0x%02x)\n", flags); bt_conn_reset_rx_state(conn); - bt_buf_put(buf); + bt_buf_release(buf); return; } @@ -357,13 +357,13 @@ void bt_conn_input(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf, if (sizeof(*hdr) + len != buf->len) { wlerr("ERROR: ACL len mismatch (%u != %u)\n", len, buf->len); - bt_buf_put(buf); + bt_buf_release(buf); return; } wlinfo("Successfully parsed %u byte L2CAP packet\n", buf->len); - bt_l2cap_recv(conn, buf); + bt_l2cap_receive(conn, buf); } /**************************************************************************** @@ -385,7 +385,6 @@ void bt_conn_send(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf) { FAR struct bt_hci_acl_hdr_s *hdr; sq_queue_t fraglist; - sq_entry_t *fragment; uint16_t len; uint16_t remaining = buf->len; FAR uint8_t *ptr; @@ -405,7 +404,7 @@ void bt_conn_send(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf) len = g_btdev.le_mtu; } - hdr = bt_buf_push(buf, sizeof(*hdr)); + hdr = bt_buf_provide(buf, sizeof(*hdr)); hdr->handle = BT_HOST2LE16(conn->handle); hdr->len = BT_HOST2LE16(len); @@ -414,10 +413,7 @@ void bt_conn_send(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf) /* Add the fragment to the end of the list */ - fragment = (FAR sq_entry_t *)buf->iob; - DEBUGASSERT(fragment != NULL); - sq_addlast(fragment, &fraglist); - + sq_addlast((FAR sq_entry_t *)buf, &fraglist); remaining -= len; while (remaining) @@ -432,27 +428,23 @@ void bt_conn_send(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf) /* Copy from original buffer */ - memcpy(bt_buf_add(buf, len), ptr, len); + memcpy(bt_buf_extend(buf, len), ptr, len); ptr += len; - hdr = bt_buf_push(buf, sizeof(*hdr)); + hdr = bt_buf_provide(buf, sizeof(*hdr)); hdr->handle = BT_HOST2LE16(conn->handle | (1 << 12)); hdr->len = BT_HOST2LE16(len); /* Add the fragment to the end of the list */ - fragment = (FAR sq_entry_t *)buf->iob; - DEBUGASSERT(fragment != NULL); - sq_addlast(fragment, &fraglist); - + sq_addlast((FAR sq_entry_t *)buf, &fraglist); remaining -= len; } /* Then send each fragment in the correct order */ - while ((fragment = sq_remfirst(&fraglist)) != NULL) + while ((buf = (FAR struct bt_buf_s *)sq_remfirst(&fraglist)) != NULL) { - buf = (FAR struct bt_buf_s *)(((FAR struct iob_s *)fragment)->io_data); bt_queue_send(conn->tx_queue, buf, BT_NORMAL_PRIO); } } @@ -596,7 +588,7 @@ void bt_conn_set_state(FAR struct bt_conn_s *conn, if (old_state == BT_CONN_CONNECTED || old_state == BT_CONN_DISCONNECT) { - bt_queue_send(conn->tx_queue, bt_buf_get(BT_DUMMY, 0), BT_NORMAL_PRIO); + bt_queue_send(conn->tx_queue, bt_buf_alloc(BT_DUMMY, 0), BT_NORMAL_PRIO); } /* Release the reference we took for the very first state transition. */ @@ -1009,7 +1001,7 @@ FAR struct bt_conn_s *bt_conn_create_le(FAR const bt_addr_le_t *peer) * Input Parameters: * conn - The connection to send the command on. * rand, ediv - Values to use for the encryption key - * ltk - + * ltk - * * Returned Value: * Zero is returned on success; a negated errno value is returned on any @@ -1029,7 +1021,7 @@ int bt_conn_le_start_encryption(FAR struct bt_conn_s *conn, uint64_t rand, return -ENOBUFS; } - cp = bt_buf_add(buf, sizeof(*cp)); + cp = bt_buf_extend(buf, sizeof(*cp)); cp->handle = BT_HOST2LE16(conn->handle); cp->rand = rand; cp->ediv = ediv; @@ -1050,7 +1042,7 @@ int bt_conn_le_conn_update(FAR struct bt_conn_s *conn, uint16_t min, return -ENOBUFS; } - conn_update = bt_buf_add(buf, sizeof(*conn_update)); + conn_update = bt_buf_extend(buf, sizeof(*conn_update)); memset(conn_update, 0, sizeof(*conn_update)); conn_update->handle = BT_HOST2LE16(conn->handle); conn_update->conn_interval_min = BT_HOST2LE16(min); diff --git a/wireless/bluetooth/bt_conn.h b/wireless/bluetooth/bt_conn.h index b53efe5a60c..87d0f5aad54 100644 --- a/wireless/bluetooth/bt_conn.h +++ b/wireless/bluetooth/bt_conn.h @@ -111,11 +111,11 @@ struct bt_conn_s }; /**************************************************************************** - * Public Data + * Public Functions ****************************************************************************/ /**************************************************************************** - * Name: bt_conn_input + * Name: bt_conn_receive * * Description: * Receive packets from the HCI core on a registered connection. @@ -130,8 +130,8 @@ struct bt_conn_s * ****************************************************************************/ -void bt_conn_input(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf, - uint8_t flags); +void bt_conn_receive(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf, + uint8_t flags); /**************************************************************************** * Name: bt_conn_send diff --git a/wireless/bluetooth/bt_gatt.c b/wireless/bluetooth/bt_gatt.c index c0ed2782d73..6f466bf7a45 100644 --- a/wireless/bluetooth/bt_gatt.c +++ b/wireless/bluetooth/bt_gatt.c @@ -442,10 +442,10 @@ static uint8_t notify_cb(FAR const struct bt_gatt_attr_s *attr, wlinfo("conn %p handle 0x%04x\n", conn, data->handle); - nfy = bt_buf_add(buf, sizeof(*nfy)); + nfy = bt_buf_extend(buf, sizeof(*nfy)); nfy->handle = BT_HOST2LE16(data->handle); - bt_buf_add(buf, data->len); + bt_buf_extend(buf, data->len); memcpy(nfy->value, data->data, data->len); bt_l2cap_send(conn, BT_L2CAP_CID_ATT, buf); @@ -595,7 +595,7 @@ static int gatt_send(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf, if (err) { wlerr("ERROR: Error sending ATT PDU: %d\n", err); - bt_buf_put(buf); + bt_buf_release(buf); } return err; @@ -627,7 +627,7 @@ int bt_gatt_exchange_mtu(FAR struct bt_conn_s *conn, wlinfo("Client MTU %u\n", mtu); - req = bt_buf_add(buf, sizeof(*req)); + req = bt_buf_extend(buf, sizeof(*req)); req->mtu = BT_HOST2LE16(mtu); return gatt_send(conn, buf, gatt_mtu_rsp, func, NULL); @@ -721,7 +721,7 @@ int bt_gatt_discover(FAR struct bt_conn_s *conn, return -ENOMEM; } - req = bt_buf_add(buf, sizeof(*req)); + req = bt_buf_extend(buf, sizeof(*req)); req->start_handle = BT_HOST2LE16(params->start_handle); req->end_handle = BT_HOST2LE16(params->end_handle); req->type = BT_HOST2LE16(BT_UUID_GATT_PRIMARY); @@ -732,18 +732,18 @@ int bt_gatt_discover(FAR struct bt_conn_s *conn, switch (params->uuid->type) { case BT_UUID_16: - value = bt_buf_add(buf, sizeof(*value)); + value = bt_buf_extend(buf, sizeof(*value)); *value = BT_HOST2LE16(params->uuid->u.u16); break; case BT_UUID_128: - bt_buf_add(buf, sizeof(params->uuid->u.u128)); + bt_buf_extend(buf, sizeof(params->uuid->u.u128)); memcpy(req->value, params->uuid->u.u128, sizeof(params->uuid->u.u128)); break; default: wlerr("ERROR: Unkown UUID type %u\n", params->uuid->type); - bt_buf_put(buf); + bt_buf_release(buf); return -EINVAL; } @@ -885,11 +885,11 @@ int bt_gatt_discover_characteristic(FAR struct bt_conn_s *conn, return -ENOMEM; } - req = bt_buf_add(buf, sizeof(*req)); + req = bt_buf_extend(buf, sizeof(*req)); req->start_handle = BT_HOST2LE16(params->start_handle); req->end_handle = BT_HOST2LE16(params->end_handle); - value = bt_buf_add(buf, sizeof(*value)); + value = bt_buf_extend(buf, sizeof(*value)); *value = BT_HOST2LE16(BT_UUID_GATT_CHRC); wlinfo("start_handle 0x%04x end_handle 0x%04x\n", params->start_handle, @@ -1031,7 +1031,7 @@ int bt_gatt_discover_descriptor(FAR struct bt_conn_s *conn, return -ENOMEM; } - req = bt_buf_add(buf, sizeof(*req)); + req = bt_buf_extend(buf, sizeof(*req)); req->start_handle = BT_HOST2LE16(params->start_handle); req->end_handle = BT_HOST2LE16(params->end_handle); @@ -1070,7 +1070,7 @@ static int gatt_read_blob(FAR struct bt_conn_s *conn, uint16_t handle, return -ENOMEM; } - req = bt_buf_add(buf, sizeof(*req)); + req = bt_buf_extend(buf, sizeof(*req)); req->handle = BT_HOST2LE16(handle); req->offset = BT_HOST2LE16(offset); @@ -1101,7 +1101,7 @@ int bt_gatt_read(FAR struct bt_conn_s *conn, uint16_t handle, return -ENOMEM; } - req = bt_buf_add(buf, sizeof(*req)); + req = bt_buf_extend(buf, sizeof(*req)); req->handle = BT_HOST2LE16(handle); wlinfo("handle 0x%04x\n", handle); @@ -1132,10 +1132,10 @@ static int gatt_write_cmd(FAR struct bt_conn_s *conn, uint16_t handle, return -ENOMEM; } - cmd = bt_buf_add(buf, sizeof(*cmd)); + cmd = bt_buf_extend(buf, sizeof(*cmd)); cmd->handle = BT_HOST2LE16(handle); memcpy(cmd->value, data, length); - bt_buf_add(buf, length); + bt_buf_extend(buf, length); wlinfo("handle 0x%04x length %u\n", handle, length); @@ -1165,10 +1165,10 @@ int bt_gatt_write(FAR struct bt_conn_s *conn, uint16_t handle, return -ENOMEM; } - req = bt_buf_add(buf, sizeof(*req)); + req = bt_buf_extend(buf, sizeof(*req)); req->handle = BT_HOST2LE16(handle); memcpy(req->value, data, length); - bt_buf_add(buf, length); + bt_buf_extend(buf, length); wlinfo("handle 0x%04x length %u\n", handle, length); @@ -1206,7 +1206,7 @@ int bt_gatt_read_multiple(FAR struct bt_conn_s *conn, for (i = 0; i < count; i++) { - bt_buf_add_le16(buf, handles[i]); + bt_buf_put_le16(buf, handles[i]); } return gatt_send(conn, buf, att_read_rsp, func, NULL); diff --git a/wireless/bluetooth/bt_hcicore.c b/wireless/bluetooth/bt_hcicore.c index 3b85aec69e7..dde7f7d8919 100644 --- a/wireless/bluetooth/bt_hcicore.c +++ b/wireless/bluetooth/bt_hcicore.c @@ -58,10 +58,11 @@ #include #include "bt_queue.h" -#include "bt_hcicore.h" +#include "bt_buf.h" #include "bt_keys.h" #include "bt_conn.h" #include "bt_l2cap.h" +#include "bt_hcicore.h" /**************************************************************************** * Pre-processor Definitions @@ -95,11 +96,11 @@ static void bt_connected(FAR struct bt_conn_s *conn) { FAR struct bt_conn_cb_s *cb; - for (cb = g_callback_list; cb; cb = cb->next) + for (cb = g_callback_list; cb; cb = cb->flink) { if (cb->connected) { - cb->connected(conn); + cb->connected(conn, cb->context); } } } @@ -108,11 +109,11 @@ static void bt_disconnected(FAR struct bt_conn_s *conn) { FAR struct bt_conn_cb_s *cb; - for (cb = g_callback_list; cb; cb = cb->next) + for (cb = g_callback_list; cb; cb = cb->flink) { if (cb->disconnected) { - cb->disconnected(conn); + cb->disconnected(conn, cb->context); } } } @@ -131,14 +132,14 @@ static void hci_acl(FAR struct bt_buf_s *buf) flags = (handle >> 12); buf->u.acl.handle = bt_acl_handle(handle); - bt_buf_pull(buf, sizeof(*hdr)); + bt_buf_consume(buf, sizeof(*hdr)); wlinfo("handle %u len %u flags %u\n", buf->u.acl.handle, len, flags); if (buf->len != len) { wlerr("ERROR: ACL data length mismatch (%u != %u)\n", buf->len, len); - bt_buf_put(buf); + bt_buf_release(buf); return; } @@ -146,11 +147,11 @@ static void hci_acl(FAR struct bt_buf_s *buf) if (!conn) { wlerr("ERROR: Unable to find conn for handle %u\n", buf->u.acl.handle); - bt_buf_put(buf); + bt_buf_release(buf); return; } - bt_conn_input(conn, buf, flags); + bt_conn_receive(conn, buf, flags); bt_conn_release(conn); } @@ -229,14 +230,14 @@ static void hci_cmd_done(uint16_t opcode, uint8_t status, } else { - sent->u.hci.sync = bt_buf_hold(buf); + sent->u.hci.sync = bt_buf_addref(buf); } nxsem_post(sem); } else { - bt_buf_put(sent); + bt_buf_release(sent); } } @@ -248,7 +249,7 @@ static void hci_cmd_complete(FAR struct bt_buf_s *buf) wlinfo("opcode %x\n", opcode); - bt_buf_pull(buf, sizeof(*evt)); + bt_buf_consume(buf, sizeof(*evt)); /* All command return parameters have a 1-byte status in the beginning, so we * can safely make this generalization. @@ -285,7 +286,7 @@ static void hci_cmd_status(FAR struct bt_buf_s *buf) wlinfo("opcode %x\n", opcode); - bt_buf_pull(buf, sizeof(*evt)); + bt_buf_consume(buf, sizeof(*evt)); switch (opcode) { @@ -392,7 +393,7 @@ static int bt_hci_start_scanning(uint8_t scan_type, uint8_t scan_filter) return -ENOBUFS; } - set_param = bt_buf_add(buf, sizeof(*set_param)); + set_param = bt_buf_extend(buf, sizeof(*set_param)); memset(set_param, 0, sizeof(*set_param)); set_param->scan_type = scan_type; @@ -412,7 +413,7 @@ static int bt_hci_start_scanning(uint8_t scan_type, uint8_t scan_filter) return -ENOBUFS; } - scan_enable = bt_buf_add(buf, sizeof(*scan_enable)); + scan_enable = bt_buf_extend(buf, sizeof(*scan_enable)); memset(scan_enable, 0, sizeof(*scan_enable)); scan_enable->filter_dup = scan_filter; scan_enable->enable = BT_LE_SCAN_ENABLE; @@ -431,7 +432,7 @@ static int bt_hci_start_scanning(uint8_t scan_type, uint8_t scan_filter) g_btdev.scan_enable = BT_LE_SCAN_ENABLE; } - bt_buf_put(rsp); + bt_buf_release(rsp); return err; } @@ -453,7 +454,7 @@ static int bt_hci_stop_scanning(void) return -ENOBUFS; } - scan_enable = bt_buf_add(buf, sizeof(*scan_enable)); + scan_enable = bt_buf_extend(buf, sizeof(*scan_enable)); memset(scan_enable, 0x0, sizeof(*scan_enable)); scan_enable->filter_dup = 0x00; scan_enable->enable = BT_LE_SCAN_DISABLE; @@ -472,7 +473,7 @@ static int bt_hci_stop_scanning(void) g_btdev.scan_enable = BT_LE_SCAN_DISABLE; } - bt_buf_put(rsp); + bt_buf_release(rsp); return err; } @@ -487,7 +488,7 @@ static int hci_le_create_conn(FAR const bt_addr_le_t *addr) return -ENOBUFS; } - cp = bt_buf_add(buf, sizeof(*cp)); + cp = bt_buf_extend(buf, sizeof(*cp)); memset(cp, 0x0, sizeof(*cp)); bt_addr_le_copy(&cp->peer_addr, addr); cp->conn_interval_max = BT_HOST2LE16(0x0028); @@ -538,7 +539,7 @@ static void hci_disconn_complete(FAR struct bt_buf_s *buf) buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_ADV_ENABLE, 1); if (buf) { - memcpy(bt_buf_add(buf, 1), &g_btdev.adv_enable, 1); + memcpy(bt_buf_extend(buf, 1), &g_btdev.adv_enable, 1); bt_hci_cmd_send(BT_HCI_OP_LE_SET_ADV_ENABLE, buf); } } @@ -665,7 +666,7 @@ static void le_adv_report(FAR struct bt_buf_s *buf) wlinfo("Adv number of reports %u\n", num_reports); - info = bt_buf_pull(buf, sizeof(num_reports)); + info = bt_buf_consume(buf, sizeof(num_reports)); while (num_reports--) { @@ -701,7 +702,7 @@ static void le_adv_report(FAR struct bt_buf_s *buf) * according to spec 4.2, Vol 2, Part E, 7.7.65.2. */ - info = bt_buf_pull(buf, sizeof(*info) + info->length + sizeof(rssi)); + info = bt_buf_consume(buf, sizeof(*info) + info->length + sizeof(rssi)); } } @@ -740,7 +741,7 @@ static void le_ltk_request(FAR struct bt_buf_s *buf) goto done; } - cp = bt_buf_add(buf, sizeof(*cp)); + cp = bt_buf_extend(buf, sizeof(*cp)); cp->handle = evt->handle; memcpy(cp->ltk, conn->keys->slave_ltk.val, 16); @@ -757,7 +758,7 @@ static void le_ltk_request(FAR struct bt_buf_s *buf) goto done; } - cp = bt_buf_add(buf, sizeof(*cp)); + cp = bt_buf_extend(buf, sizeof(*cp)); cp->handle = evt->handle; bt_hci_cmd_send(BT_HCI_OP_LE_LTK_REQ_NEG_REPLY, buf); @@ -771,7 +772,7 @@ static void hci_le_meta_event(FAR struct bt_buf_s *buf) { FAR struct bt_hci_evt_le_meta_event_s *evt = (FAR void *)buf->data; - bt_buf_pull(buf, sizeof(*evt)); + bt_buf_consume(buf, sizeof(*evt)); switch (evt->subevent) { @@ -799,7 +800,7 @@ static void hci_event(FAR struct bt_buf_s *buf) wlinfo("event %u\n", hdr->evt); - bt_buf_pull(buf, sizeof(*hdr)); + bt_buf_consume(buf, sizeof(*hdr)); switch (hdr->evt) { @@ -836,7 +837,7 @@ static void hci_event(FAR struct bt_buf_s *buf) break; } - bt_buf_put(buf); + bt_buf_release(buf); } static int hci_tx_kthread(int argc, FAR char *argv[]) @@ -863,7 +864,7 @@ static int hci_tx_kthread(int argc, FAR char *argv[]) /* Get next command - wait if necessary */ buf = NULL; - ret = bt_queue_recv(g_btdev.tx_queue, &buf); + ret = bt_queue_receive(g_btdev.tx_queue, &buf); DEBUGASSERT(ret >= 0 && buf != NULL); UNUSED(ret); @@ -879,7 +880,7 @@ static int hci_tx_kthread(int argc, FAR char *argv[]) if (g_btdev.sent_cmd) { wlerr("ERROR: Uncleared pending sent_cmd\n"); - bt_buf_put(g_btdev.sent_cmd); + bt_buf_release(g_btdev.sent_cmd); g_btdev.sent_cmd = NULL; } @@ -898,10 +899,10 @@ static int hci_rx_kthread(int argc, FAR char *argv[]) while (1) { - ret = bt_queue_recv(g_btdev.rx_queue, &buf); + ret = bt_queue_receive(g_btdev.rx_queue, &buf); if (ret < 0) { - wlerr("ERROR: bt_queue_recv() failed: %d\n", ret); + wlerr("ERROR: bt_queue_receive() failed: %d\n", ret); continue; } @@ -919,7 +920,7 @@ static int hci_rx_kthread(int argc, FAR char *argv[]) default: wlerr("ERROR: Unknown buf type %u\n", buf->type); - bt_buf_put(buf); + bt_buf_release(buf); break; } } @@ -1014,7 +1015,7 @@ static int hci_init(void) } read_local_features_complete(rsp); - bt_buf_put(rsp); + bt_buf_release(rsp); /* Read Local Version Information */ @@ -1025,7 +1026,7 @@ static int hci_init(void) } read_local_ver_complete(rsp); - bt_buf_put(rsp); + bt_buf_release(rsp); /* Read Bluetooth Address */ @@ -1036,7 +1037,7 @@ static int hci_init(void) } read_bdaddr_complete(rsp); - bt_buf_put(rsp); + bt_buf_release(rsp); /* For now we only support LE capable controllers */ @@ -1055,7 +1056,7 @@ static int hci_init(void) } read_le_features_complete(rsp); - bt_buf_put(rsp); + bt_buf_release(rsp); /* Read LE Buffer Size */ @@ -1066,7 +1067,7 @@ static int hci_init(void) } le_read_buffer_size_complete(rsp); - bt_buf_put(rsp); + bt_buf_release(rsp); buf = bt_hci_cmd_create(BT_HCI_OP_SET_EVENT_MASK, sizeof(*ev)); if (!buf) @@ -1074,7 +1075,7 @@ static int hci_init(void) return -ENOBUFS; } - ev = bt_buf_add(buf, sizeof(*ev)); + ev = bt_buf_extend(buf, sizeof(*ev)); memset(ev, 0, sizeof(*ev)); ev->events[0] |= 0x10; /* Disconnection Complete */ ev->events[1] |= 0x08; /* Read Remote Version Information Complete */ @@ -1099,7 +1100,7 @@ static int hci_init(void) return -ENOBUFS; } - hbs = bt_buf_add(buf, sizeof(*hbs)); + hbs = bt_buf_extend(buf, sizeof(*hbs)); memset(hbs, 0, sizeof(*hbs)); hbs->acl_mtu = BT_HOST2LE16(BT_BUF_MAX_DATA - sizeof(struct bt_hci_acl_hdr_s) - @@ -1118,7 +1119,7 @@ static int hci_init(void) return -ENOBUFS; } - enable = bt_buf_add(buf, sizeof(*enable)); + enable = bt_buf_extend(buf, sizeof(*enable)); *enable = 0x01; err = bt_hci_cmd_send_sync(BT_HCI_OP_SET_CTL_TO_HOST_FLOW, buf, NULL); @@ -1142,7 +1143,7 @@ static int hci_init(void) } read_buffer_size_complete(rsp); - bt_buf_put(rsp); + bt_buf_release(rsp); } buf = bt_hci_cmd_create(BT_HCI_OP_LE_WRITE_LE_HOST_SUPP, sizeof(*cp)); @@ -1153,7 +1154,7 @@ static int hci_init(void) /* Explicitly enable LE for dual-mode controllers */ - cp = bt_buf_add(buf, sizeof *cp); + cp = bt_buf_extend(buf, sizeof *cp); cp->le = 0x01; cp->simul = 0x00; @@ -1205,8 +1206,8 @@ static void rx_queue_init(void) pid_t pid; int ret; - /* When a buffer is received from the Bluetooth driver via bt_input() on - * the Rx queue and received by logic on the Rx kernel thread. + /* When a buffer is received from the Bluetooth driver via bt_hci_receive() + * on the Rx queue and received by logic on the Rx kernel thread. */ g_btdev.rx_queue = NULL; @@ -1243,7 +1244,7 @@ int bt_initialize(void) int err; DEBUGASSERT(dev != NULL); - bt_buf_init(); + bt_buf_initialize(); cmd_queue_init(); rx_queue_init(); @@ -1317,7 +1318,7 @@ void bt_driver_unregister(FAR const struct bt_driver_s *dev) } /**************************************************************************** - * Name: bt_input + * Name: bt_hci_receive * * Description: * Called by the Bluetooth low-level driver when new data is received from @@ -1332,7 +1333,7 @@ void bt_driver_unregister(FAR const struct bt_driver_s *dev) * ****************************************************************************/ -void bt_input(FAR struct bt_buf_s *buf) +void bt_hci_receive(FAR struct bt_buf_s *buf) { FAR struct bt_hci_evt_hdr_s *hdr; int prio = BT_NORMAL_PRIO; @@ -1345,7 +1346,7 @@ void bt_input(FAR struct bt_buf_s *buf) if (buf->type != BT_EVT) { wlerr("ERROR: Invalid buf type %u\n", buf->type); - bt_buf_put(buf); + bt_buf_release(buf); return; } @@ -1386,7 +1387,7 @@ FAR struct bt_buf_s *bt_hci_cmd_create(uint16_t opcode, uint8_t param_len) wlinfo("opcode %x param_len %u\n", opcode, param_len); - buf = bt_buf_get(BT_CMD, g_btdev.dev->head_reserve); + buf = bt_buf_alloc(BT_CMD, g_btdev.dev->head_reserve); if (!buf) { wlerr("ERROR: Cannot get free buffer\n"); @@ -1398,7 +1399,7 @@ FAR struct bt_buf_s *bt_hci_cmd_create(uint16_t opcode, uint8_t param_len) buf->u.hci.opcode = opcode; buf->u.hci.sync = NULL; - hdr = bt_buf_add(buf, sizeof(*hdr)); + hdr = bt_buf_extend(buf, sizeof(*hdr)); hdr->opcode = BT_HOST2LE16(opcode); hdr->param_len = param_len; @@ -1426,7 +1427,7 @@ int bt_hci_cmd_send(uint16_t opcode, FAR struct bt_buf_s *buf) if (opcode == BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS) { g_btdev.dev->send(g_btdev.dev, buf); - bt_buf_put(buf); + bt_buf_release(buf); return 0; } @@ -1500,10 +1501,10 @@ int bt_hci_cmd_send_sync(uint16_t opcode, FAR struct bt_buf_s *buf, } else if (buf->u.hci.sync) { - bt_buf_put(buf->u.hci.sync); + bt_buf_release(buf->u.hci.sync); } - bt_buf_put(buf); + bt_buf_release(buf); return ret; } @@ -1544,7 +1545,7 @@ int bt_start_advertising(uint8_t type, FAR const struct bt_eir_s *ad, return -ENOBUFS; } - set_data = bt_buf_add(buf, sizeof(*set_data)); + set_data = bt_buf_extend(buf, sizeof(*set_data)); memset(set_data, 0, sizeof(*set_data)); @@ -1576,7 +1577,7 @@ send_scan_rsp: return -ENOBUFS; } - scan_rsp = bt_buf_add(buf, sizeof(*scan_rsp)); + scan_rsp = bt_buf_extend(buf, sizeof(*scan_rsp)); memset(scan_rsp, 0, sizeof(*scan_rsp)); @@ -1603,7 +1604,7 @@ send_set_param: return -ENOBUFS; } - set_param = bt_buf_add(buf, sizeof(*set_param)); + set_param = bt_buf_extend(buf, sizeof(*set_param)); memset(set_param, 0, sizeof(*set_param)); set_param->min_interval = BT_HOST2LE16(0x0800); @@ -1620,7 +1621,7 @@ send_set_param: } g_btdev.adv_enable = 0x01; - memcpy(bt_buf_add(buf, 1), &g_btdev.adv_enable, 1); + memcpy(bt_buf_extend(buf, 1), &g_btdev.adv_enable, 1); return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_ADV_ENABLE, buf, NULL); } @@ -1652,7 +1653,7 @@ int bt_stop_advertising(void) } g_btdev.adv_enable = 0x00; - memcpy(bt_buf_add(buf, 1), &g_btdev.adv_enable, 1); + memcpy(bt_buf_extend(buf, 1), &g_btdev.adv_enable, 1); return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_ADV_ENABLE, buf, NULL); } @@ -1776,7 +1777,7 @@ int bt_le_scan_update(void) void bt_conn_cb_register(FAR struct bt_conn_cb_s *cb) { - cb->next = g_callback_list; + cb->flink = g_callback_list; g_callback_list = cb; } diff --git a/wireless/bluetooth/bt_hcicore.h b/wireless/bluetooth/bt_hcicore.h index 61c19f7d6b3..5c4a9c393cf 100644 --- a/wireless/bluetooth/bt_hcicore.h +++ b/wireless/bluetooth/bt_hcicore.h @@ -144,9 +144,11 @@ struct bt_dev_s struct bt_conn_s; /* Forward reference */ struct bt_conn_cb_s { - CODE void (*connected)(FAR struct bt_conn_s *conn); - CODE void (*disconnected)(FAR struct bt_conn_s *conn); - FAR struct bt_conn_cb_s *next; + FAR struct bt_conn_cb_s *flink; + FAR void *context; + + CODE void (*connected)(FAR struct bt_conn_s *conn, FAR void *context); + CODE void (*disconnected)(FAR struct bt_conn_s *conn, FAR void *context); }; /**************************************************************************** diff --git a/wireless/bluetooth/bt_l2cap.c b/wireless/bluetooth/bt_l2cap.c index 2176e93d8d3..d86463f3d13 100644 --- a/wireless/bluetooth/bt_l2cap.c +++ b/wireless/bluetooth/bt_l2cap.c @@ -75,6 +75,7 @@ ****************************************************************************/ static FAR struct bt_l2cap_chan_s *g_channels; +static FAR struct bt_l2cap_chan_s *g_default; /**************************************************************************** * Private Functions @@ -98,47 +99,82 @@ void bt_l2cap_chan_register(FAR struct bt_l2cap_chan_s *chan) { wlinfo("CID 0x%04x\n", chan->cid); - chan->next = g_channels; + chan->flink = g_channels; g_channels = chan; } +void bt_l2cap_chan_default(FAR struct bt_l2cap_chan_s *chan) +{ + g_default = chan; +} + void bt_l2cap_connected(FAR struct bt_conn_s *conn) { FAR struct bt_l2cap_chan_s *chan; - for (chan = g_channels; chan; chan = chan->next) + /* Notify all registered channels of the connection event */ + + for (chan = g_channels; chan; chan = chan->flink) { - if (chan->connected) + if (chan->connected != NULL) { - chan->connected(conn); + chan->connected(conn, chan->context, chan->cid); } } + + /* Notify any default listener of the connection event */ + + chan = g_default; + if (chan != NULL && chan->connected != NULL) + { + chan->connected(conn, chan->context, chan->cid); + } } void bt_l2cap_disconnected(FAR struct bt_conn_s *conn) { FAR struct bt_l2cap_chan_s *chan; - for (chan = g_channels; chan; chan = chan->next) + /* Notify all registered channels of the disconnection event */ + + for (chan = g_channels; chan; chan = chan->flink) { - if (chan->disconnected) + if (chan->disconnected != NULL) { - chan->disconnected(conn); + chan->disconnected(conn, chan->context, chan->cid); } } + + /* Notify any default listener of the disconnection event */ + + chan = g_default; + if (chan != NULL && chan->disconnected != NULL) + { + chan->disconnected(conn, chan->context, chan->cid); + } } void bt_l2cap_encrypt_change(FAR struct bt_conn_s *conn) { FAR struct bt_l2cap_chan_s *chan; - for (chan = g_channels; chan; chan = chan->next) + /* Notify all registered channels of the encryption change event */ + + for (chan = g_channels; chan; chan = chan->flink) { - if (chan->encrypt_change) + if (chan->encrypt_change != NULL) { - chan->encrypt_change(conn); + chan->encrypt_change(conn, chan->context, chan->cid); } } + + /* Notify any default listener of the encryption change event */ + + chan = g_default; + if (chan != NULL && chan->encrypt_change != NULL) + { + chan->encrypt_change(conn, chan->context, chan->cid); + } } struct bt_buf_s *bt_l2cap_create_pdu(FAR struct bt_conn_s *conn) @@ -146,7 +182,7 @@ struct bt_buf_s *bt_l2cap_create_pdu(FAR struct bt_conn_s *conn) size_t head_reserve = sizeof(struct bt_l2cap_hdr_s) + sizeof(struct bt_hci_acl_hdr_s) + g_btdev.dev->head_reserve; - return bt_buf_get(BT_ACL_OUT, head_reserve); + return bt_buf_alloc(BT_ACL_OUT, head_reserve); } void bt_l2cap_send(FAR struct bt_conn_s *conn, uint16_t cid, @@ -154,7 +190,7 @@ void bt_l2cap_send(FAR struct bt_conn_s *conn, uint16_t cid, { FAR struct bt_l2cap_hdr_s *hdr; - hdr = bt_buf_push(buf, sizeof(*hdr)); + hdr = bt_buf_provide(buf, sizeof(*hdr)); hdr->len = BT_HOST2LE16(buf->len - sizeof(*hdr)); hdr->cid = BT_HOST2LE16(cid); @@ -173,12 +209,12 @@ static void rej_not_understood(FAR struct bt_conn_s *conn, uint8_t ident) return; } - hdr = bt_buf_add(buf, sizeof(*hdr)); + hdr = bt_buf_extend(buf, sizeof(*hdr)); hdr->code = BT_L2CAP_CMD_REJECT; hdr->ident = ident; hdr->len = BT_HOST2LE16(sizeof(*rej)); - rej = bt_buf_add(buf, sizeof(*rej)); + rej = bt_buf_extend(buf, sizeof(*rej)); rej->reason = BT_HOST2LE16(BT_L2CAP_REJ_NOT_UNDERSTOOD); bt_l2cap_send(conn, BT_L2CAP_CID_LE_SIG, buf); @@ -266,12 +302,12 @@ static void le_conn_param_update_req(FAR struct bt_conn_s *conn, result = le_validate_conn_params(min, max, latency, timeout); - hdr = bt_buf_add(buf, sizeof(*hdr)); + hdr = bt_buf_extend(buf, sizeof(*hdr)); hdr->code = BT_L2CAP_CONN_PARAM_RSP; hdr->ident = ident; hdr->len = BT_HOST2LE16(sizeof(*rsp)); - rsp = bt_buf_add(buf, sizeof(*rsp)); + rsp = bt_buf_extend(buf, sizeof(*rsp)); memset(rsp, 0, sizeof(*rsp)); rsp->result = BT_HOST2LE16(result); @@ -283,7 +319,8 @@ static void le_conn_param_update_req(FAR struct bt_conn_s *conn, } } -static void le_sig(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf) +static void le_sig(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf, + FAR void *context, uint16_t cid) { struct bt_l2cap_sig_hdr_s *hdr = (FAR void *)buf->data; uint16_t len; @@ -295,7 +332,7 @@ static void le_sig(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf) } len = BT_LE162HOST(hdr->len); - bt_buf_pull(buf, sizeof(*hdr)); + bt_buf_consume(buf, sizeof(*hdr)); wlinfo("LE signaling code 0x%02x ident %u len %u\n", hdr->code, hdr->ident, len); @@ -329,10 +366,10 @@ static void le_sig(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf) } drop: - bt_buf_put(buf); + bt_buf_release(buf); } -void bt_l2cap_recv(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf) +void bt_l2cap_receive(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf) { FAR struct bt_l2cap_hdr_s *hdr = (FAR void *)buf->data; FAR struct bt_l2cap_chan_s *chan; @@ -341,16 +378,18 @@ void bt_l2cap_recv(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf) if (buf->len < sizeof(*hdr)) { wlerr("ERROR: Too small L2CAP PDU received\n"); - bt_buf_put(buf); + bt_buf_release(buf); return; } cid = BT_LE162HOST(hdr->cid); - bt_buf_pull(buf, sizeof(*hdr)); + bt_buf_consume(buf, sizeof(*hdr)); wlinfo("Packet for CID %u len %u\n", cid, buf->len); - for (chan = g_channels; chan; chan = chan->next) + /* Search for a subscriber to this channel */ + + for (chan = g_channels; chan != NULL; chan = chan->flink) { if (chan->cid == cid) { @@ -358,14 +397,23 @@ void bt_l2cap_recv(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf) } } - if (!chan) + /* If there is no subscriber, then send all received frames to the default + * listener (if one is registered). + */ + + if (chan == NULL) { - wlwarn("Ignoring data for unknown CID 0x%04x\n", cid); - bt_buf_put(buf); + chan = g_default; + } + + if (chan == NULL) + { + wlwarn("WARNING: No subscriber to CID 0x%04x\n", cid); + bt_buf_release(buf); return; } - chan->recv(conn, buf); + chan->receive(conn, buf, chan->context, chan->cid); } void bt_l2cap_update_conn_param(FAR struct bt_conn_s *conn) @@ -388,12 +436,12 @@ void bt_l2cap_update_conn_param(FAR struct bt_conn_s *conn) return; } - hdr = bt_buf_add(buf, sizeof(*hdr)); + hdr = bt_buf_extend(buf, sizeof(*hdr)); hdr->code = BT_L2CAP_CONN_PARAM_REQ; hdr->ident = get_ident(conn); hdr->len = BT_HOST2LE16(sizeof(*req)); - req = bt_buf_add(buf, sizeof(*req)); + req = bt_buf_extend(buf, sizeof(*req)); req->min_interval = BT_HOST2LE16(LE_CONN_MIN_INTERVAL); req->max_interval = BT_HOST2LE16(LE_CONN_MAX_INTERVAL); req->latency = BT_HOST2LE16(LE_CONN_LATENCY); @@ -404,22 +452,22 @@ void bt_l2cap_update_conn_param(FAR struct bt_conn_s *conn) int bt_l2cap_init(void) { - int err; + int ret; static struct bt_l2cap_chan_s chan = { - .cid = BT_L2CAP_CID_LE_SIG, - .recv = le_sig, + .cid = BT_L2CAP_CID_LE_SIG, + .receive = le_sig, }; - bt_att_init(); + bt_att_initialize(); - err = bt_smp_init(); - if (err) + ret = bt_smp_initialize(); + if (ret < 0) { - return err; + return ret; } bt_l2cap_chan_register(&chan); - return 0; + return ret; } diff --git a/wireless/bluetooth/bt_l2cap.h b/wireless/bluetooth/bt_l2cap.h index a816c84c3b1..5e213aba171 100644 --- a/wireless/bluetooth/bt_l2cap.h +++ b/wireless/bluetooth/bt_l2cap.h @@ -100,24 +100,32 @@ begin_packed_struct struct bt_l2cap_conn_param_rsp_s struct bt_l2cap_chan_s { + FAR struct bt_l2cap_chan_s *flink; + FAR void *context; uint16_t cid; - CODE void (*connected)(FAR struct bt_conn_s *conn); - CODE void (*disconnected)(FAR struct bt_conn_s *conn); - CODE void (*encrypt_change)(FAR struct bt_conn_s *conn); - CODE void (*recv)(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf); - - FAR struct bt_l2cap_chan_s *next; + CODE void (*connected)(FAR struct bt_conn_s *conn, + FAR void *context, uint16_t cid); + CODE void (*disconnected)(FAR struct bt_conn_s *conn, FAR void *context, + uint16_t cid); + CODE void (*encrypt_change)(FAR struct bt_conn_s *conn, + FAR void *context, uint16_t cid); + CODE void (*receive)(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf, + FAR void *context, uint16_t cid); }; /**************************************************************************** * Public Function Prototypes ****************************************************************************/ -/* Register a fixed L2CAP channel for L2CAP */ +/* Register a fixed L2CAP channel handler for L2CAP */ void bt_l2cap_chan_register(FAR struct bt_l2cap_chan_s *chan); +/* Register a default L2CAP channel handle for L2CAP */ + +void bt_l2cap_chan_default(FAR struct bt_l2cap_chan_s *chan); + /* Notify L2CAP channels of a new connection */ void bt_l2cap_connected(FAR struct bt_conn_s *conn); @@ -141,7 +149,7 @@ void bt_l2cap_send(FAR struct bt_conn_s *conn, uint16_t cid, /* Receive a new L2CAP PDU from a connection */ -void bt_l2cap_recv(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf); +void bt_l2cap_receive(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf); /* Perform connection parameter update request */ diff --git a/wireless/bluetooth/bt_netdev.c b/wireless/bluetooth/bt_netdev.c index 6dd364702c1..df05348dcce 100644 --- a/wireless/bluetooth/bt_netdev.c +++ b/wireless/bluetooth/bt_netdev.c @@ -62,8 +62,11 @@ #include #include #include +#include #include "bt_hcicore.h" +#include "bt_l2cap.h" +#include "bt_conn.h" #include "bt_ioctl.h" #if defined(CONFIG_NET_6LOWPAN) || defined(CONFIG_NET_BLUETOOTH) @@ -113,16 +116,17 @@ struct btnet_driver_s { /* This holds the information visible to the NuttX network */ - struct radio_driver_s bd_dev; /* Interface understood by the network */ - /* Cast compatible with struct btnet_driver_s */ + struct radio_driver_s bd_dev; /* Interface understood by the network */ + /* Cast compatible with struct btnet_driver_s */ /* For internal use by this driver */ - sem_t bd_exclsem; /* Exclusive access to struct */ - bool bd_bifup; /* true:ifup false:ifdown */ - WDOG_ID bd_txpoll; /* TX poll timer */ - struct work_s bd_pollwork; /* Defer poll work to the work queue */ - FAR struct bt_conn_cb_s bd_hcicb; /* Connection status callbacks */ + sem_t bd_exclsem; /* Exclusive access to struct */ + bool bd_bifup; /* true:ifup false:ifdown */ + WDOG_ID bd_txpoll; /* TX poll timer */ + struct work_s bd_pollwork; /* Defer poll work to the work queue */ + struct bt_conn_cb_s bd_hcicb; /* HCI connection status callbacks */ + struct bt_l2cap_chan_s bd_l2capcb; /* L2CAP status callbacks */ }; /**************************************************************************** @@ -136,10 +140,23 @@ static inline void btnet_netmask(FAR struct net_driver_s *dev); /* Bluetooth callback functions ***************************************/ -static int btnet_rxframe(FAR struct btnet_driver_s *maccb, - FAR struct bluetooth_frame_meta_s *meta); -static void btnet_connected(FAR struct bt_conn_s *conn); -static void btnet_disconnected(FAR struct bt_conn_s *conn); +/* L2CAP callbacks */ + +static void btnet_l2cap_connected(FAR struct bt_conn_s *conn, + FAR void *context, uint16_t cid); +static void btnet_l2cap_disconnected(FAR struct bt_conn_s *conn, + FAR void *context, uint16_t cid); +static void btnet_l2cap_encrypt_change(FAR struct bt_conn_s *conn, + FAR void *context, uint16_t cid); +static void btnet_l2cap_receive(FAR struct bt_conn_s *conn, + FAR struct bt_buf_s *buf, FAR void *context, uint16_t cid); + +/* HCI callbacks */ + +static void btnet_hci_connected(FAR struct bt_conn_s *conn, + FAR void *context); +static void btnet_hci_disconnected(FAR struct bt_conn_s *conn, + FAR void *context); /* Network interface support ************************************************/ /* Common TX logic */ @@ -252,10 +269,50 @@ static inline void btnet_netmask(FAR struct net_driver_s *dev) } /**************************************************************************** - * Name: btnet_rxframe + * Name: btnet_hci_connect/disconnect/encrypt_change * * Description: - * Handle received frames forward by the Bluetooth stack. + * There are callbacks that are involved by the core HCI layer when a + * change is detected in the connection status or encryption. + * + * Input Parameters: + * conn - The connection whose + * + * Returned Value: + * None + * + * Assumptions: + * No assumption should be made about the thread of execution that these + * are called from + * + ****************************************************************************/ + +static void btnet_l2cap_connected(FAR struct bt_conn_s *conn, + FAR void *context, uint16_t cid) +{ + wlinfo("Connected\n"); +#warning Missing logic +} + +static void btnet_l2cap_disconnected(FAR struct bt_conn_s *conn, + FAR void *context, uint16_t cid) +{ + wlinfo("Disconnected\n"); +#warning Missing logic +} + +static void btnet_l2cap_encrypt_change(FAR struct bt_conn_s *conn, + FAR void *context, uint16_t cid) +{ + wlinfo("Encryption change\n"); +#warning Missing logic +} + +/**************************************************************************** + * Name: btnet_l2cap_receive + * + * Description: + * Handle received frames forward by the Bluetooth L2CAP layer. * * Returned Value: * Zero (OK) is returned on success; a negated errno value is returned on @@ -265,24 +322,55 @@ static inline void btnet_netmask(FAR struct net_driver_s *dev) * ****************************************************************************/ -static int btnet_rxframe(FAR struct btnet_driver_s *priv, - FAR struct bluetooth_frame_meta_s *meta) +static void btnet_l2cap_receive(FAR struct bt_conn_s *conn, + FAR struct bt_buf_s *buf, + FAR void *context, uint16_t cid) { - FAR struct iob_s *iob; - int ret; + FAR struct btnet_driver_s *priv; + FAR struct iob_s *frame; + struct bluetooth_frame_meta_s meta; + int ret = -ENODEV; - DEBUGASSERT(priv != NULL && meta != NULL); + wlinfo("Received frame\n"); + + DEBUGASSERT(conn != NULL && buf != NULL && buf->frame != NULL && + context != NULL && cid < UINT8_MAX); + + /* Detach the IOB frame from the buffer structure */ + + frame = buf->frame; + buf->frame = NULL; /* Ignore the frame if the network is not up */ + priv = (FAR struct btnet_driver_s *)context; if (!priv->bd_bifup) { wlwarn("WARNING: Dropped... Network is down\n"); - return -ENETDOWN; + goto drop; } + /* Make sure that the size/offset data matches the buffer structure data. + * REVISIT: Wouldn't it be better to just have one copy rather than having + * to synchronize? + */ + + frame->io_len = buf->len; + frame->io_pktlen = buf->len; + frame->io_offset = (unsigned int) + ((uintptr_t)buf->data - (uintptr_t)frame->io_data); + + DEBUGASSERT(frame->io_len <= CONFIG_IOB_BUFSIZE); + DEBUGASSERT(frame->io_offset < CONFIG_IOB_BUFSIZE); + + /* Construct the frame meta data. + * REVISIT: Where do we get the channel number? + */ + + BLUETOOTH_ADDRCOPY(meta.bm_raddr.val, conn->src.val); + meta.bm_channel = cid; + /* Transfer the frame to the network logic */ -#warning Missing logic net_lock(); @@ -292,14 +380,13 @@ static int btnet_rxframe(FAR struct btnet_driver_s *priv, * frame and return success. */ - ret = bluetooth_input(&priv->bd_dev, iob, (FAR void *)meta); - if (ret < 0) + ret = bluetooth_input(&priv->bd_dev, frame, (FAR void *)&meta); #endif #ifdef CONFIG_NET_6LOWPAN + if (ret < 0) { - /* If the frame is not a 6LoWPAN frame, then return an error. The - * first byte following the MAC head at the io_offset should be a - * valid IPHC header. + /* If the frame is not a 6LoWPAN frame, then thefirst byte at the + * io_offset should be a valid IPHC header. */ if ((iob->io_data[iob->io_offset] & SIXLOWPAN_DISPATCH_NALP_MASK) == @@ -320,25 +407,36 @@ static int btnet_rxframe(FAR struct btnet_driver_s *priv, ret = sixlowpan_input(&priv->bd_dev, iob, (FAR void *)meta); } } +#endif + +drop: + + /* Handle errors */ if (ret < 0) -#endif { - net_unlock(); - return ret; + iob_free(frame); + + /* Increment statistics */ + + NETDEV_RXDROPPED(&priv->bd_dev.r_dev); + } + else + { + /* Increment statistics */ + + NETDEV_RXPACKETS(&priv->bd_dev.r_dev); + NETDEV_RXIPV6(&priv->bd_dev.r_dev); } - /* Increment statistics */ - - NETDEV_RXPACKETS(&priv->bd_dev.r_dev); - NETDEV_RXIPV6(&priv->bd_dev.r_dev); + /* Release our reference on the buffer */ + bt_buf_release(buf); net_unlock(); - return OK; } /**************************************************************************** - * Name: btnet_txpoll_callback + * Name: btnet_hci_connect/disconnect * * Description: * There are callbacks that are involved by the core HCI layer when a @@ -356,13 +454,17 @@ static int btnet_rxframe(FAR struct btnet_driver_s *priv, * ****************************************************************************/ -static void btnet_connected(FAR struct bt_conn_s *conn) +static void btnet_hci_connected(FAR struct bt_conn_s *conn, + FAR void *context) { + wlinfo("Connected\n"); #warning Missing logic } -static void btnet_disconnected(FAR struct bt_conn_s *conn) +static void btnet_hci_disconnected(FAR struct bt_conn_s *conn, + FAR void *context) { + wlinfo("Disconnected\n"); #warning Missing logic } @@ -914,6 +1016,7 @@ int bt_netdev_register(void) FAR struct radio_driver_s *radio; FAR struct net_driver_s *dev; FAR struct bt_conn_cb_s *hcicb; + FAR struct bt_l2cap_chan_s *l2capcb; int ret; /* Get the interface structure associated with this interface number. */ @@ -946,13 +1049,22 @@ int bt_netdev_register(void) /* Connection status change callbacks */ hcicb = &priv->bd_hcicb; - hcicb->connected = btnet_connected; - hcicb->disconnected = btnet_disconnected; + hcicb->context = priv; + hcicb->connected = btnet_hci_connected; + hcicb->disconnected = btnet_hci_disconnected; bt_conn_cb_register(hcicb); - /* REVISIT: When and where to we register to get frames on a connection? */ -#warning Missing logic + /* L2CAP status change callbacks */ + + l2capcb = &priv->bd_l2capcb; + l2capcb->context = priv; + l2capcb->connected = btnet_l2cap_connected; + l2capcb->disconnected = btnet_l2cap_disconnected; + l2capcb->encrypt_change = btnet_l2cap_encrypt_change; + l2capcb->receive = btnet_l2cap_receive; + + bt_l2cap_chan_default(l2capcb); /* Create a watchdog for timing polling for and timing of transmissions */ diff --git a/wireless/bluetooth/bt_queue.c b/wireless/bluetooth/bt_queue.c index f807347a9dd..9271b92daa3 100644 --- a/wireless/bluetooth/bt_queue.c +++ b/wireless/bluetooth/bt_queue.c @@ -64,9 +64,11 @@ * Private Types ****************************************************************************/ +/* A message is just a buffer structure */ + struct bt_bufmsg_s { - FAR struct iob_s *iob; + FAR struct bt_buf_s *buf; }; /**************************************************************************** @@ -119,7 +121,7 @@ int bt_queue_open(FAR const char *name, int oflags, int nmsgs, } /**************************************************************************** - * Name: bt_queue_recv + * Name: bt_queue_receive * * Description: * Block until the next buffer is received on the queue. @@ -134,7 +136,7 @@ int bt_queue_open(FAR const char *name, int oflags, int nmsgs, * ****************************************************************************/ -int bt_queue_recv(mqd_t mqd, FAR struct bt_buf_s **buf) +int bt_queue_receive(mqd_t mqd, FAR struct bt_buf_s **buf) { union { @@ -142,7 +144,6 @@ int bt_queue_recv(mqd_t mqd, FAR struct bt_buf_s **buf) char msgbuf[BT_MSGSIZE]; } u; - FAR struct bt_buf_s *retbuf; ssize_t msgsize; int priority; int ret; @@ -158,17 +159,16 @@ int bt_queue_recv(mqd_t mqd, FAR struct bt_buf_s **buf) return ret; } - /* Only message buffer messages are expected */ + /* Only buffers are expected as messages and all messages should have an + * attached IOB frame. + */ DEBUGASSERT(msgsize == sizeof(struct bt_bufmsg_s)); - DEBUGASSERT(u.msg.iob != NULL); + DEBUGASSERT(u.msg.buf->frame != NULL); - /* A few more sanity checks, then return the buffer */ + /* Return the buffer */ - retbuf = (FAR struct bt_buf_s *)u.msg.iob->io_data; - DEBUGASSERT(retbuf->iob == u.msg.iob); - - *buf = retbuf; + *buf = u.msg.buf; return OK; } @@ -197,11 +197,11 @@ int bt_queue_send(mqd_t mqd, FAR struct bt_buf_s *buf, int priority) struct bt_bufmsg_s msg; int ret; - DEBUGASSERT(mqd != NULL && buf != NULL && buf->iob != NULL); + DEBUGASSERT(mqd != NULL && buf != NULL && buf->frame != NULL); /* Format and send the buffer message */ - msg.iob = buf->iob; + msg.buf = buf; ret = nxmq_send(mqd, (FAR const char *)&msg, sizeof(struct bt_bufmsg_s), priority); if (ret < 0) diff --git a/wireless/bluetooth/bt_queue.h b/wireless/bluetooth/bt_queue.h index 3c4719c2d80..492e68e7799 100644 --- a/wireless/bluetooth/bt_queue.h +++ b/wireless/bluetooth/bt_queue.h @@ -105,7 +105,7 @@ int bt_queue_open(FAR const char *name, int oflags, int nmsgs, FAR mqd_t *mqd); /**************************************************************************** - * Name: bt_queue_recv + * Name: bt_queue_receive * * Description: * Block until the next buffer is received on the queue. @@ -120,7 +120,7 @@ int bt_queue_open(FAR const char *name, int oflags, int nmsgs, * ****************************************************************************/ -int bt_queue_recv(mqd_t mqd, FAR struct bt_buf_s **buf); +int bt_queue_receive(mqd_t mqd, FAR struct bt_buf_s **buf); /**************************************************************************** * Name: bt_queue_send diff --git a/wireless/bluetooth/bt_smp.c b/wireless/bluetooth/bt_smp.c index fa8e1187b21..a68fa24cc48 100644 --- a/wireless/bluetooth/bt_smp.c +++ b/wireless/bluetooth/bt_smp.c @@ -179,11 +179,15 @@ static uint8_t smp_ident_addr_info(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf); static uint8_t smp_security_request(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf); -static void bt_smp_recv(FAR struct bt_conn_s *conn, - FAR struct bt_buf_s *buf); -static void bt_smp_connected(FAR struct bt_conn_s *conn); -static void bt_smp_disconnected(FAR struct bt_conn_s *conn); -static void bt_smp_encrypt_change(FAR FAR struct bt_conn_s *conn); +static void bt_smp_receive(FAR struct bt_conn_s *conn, + FAR struct bt_buf_s *buf, FAR void *context, + uint16_t cid); +static void bt_smp_connected(FAR struct bt_conn_s *conn, + FAR void *context, uint16_t cid); +static void bt_smp_disconnected(FAR struct bt_conn_s *conn, + FAR void *context, uint16_t cid); +static void bt_smp_encrypt_change(FAR FAR struct bt_conn_s *conn, + FAR void *context, uint16_t cid); #ifdef CONFIG_BLUETOOTH_SMP_SELFTEST static void swap_buf(FAR const uint8_t *src, FAR uint8_t *dst, uint16_t len); @@ -373,7 +377,7 @@ static int le_encrypt(const uint8_t key[16], const uint8_t plaintext[16], return -ENOBUFS; } - cp = bt_buf_add(buf, sizeof(*cp)); + cp = bt_buf_extend(buf, sizeof(*cp)); memcpy(cp->key, key, sizeof(cp->key)); memcpy(cp->plaintext, plaintext, sizeof(cp->plaintext)); @@ -385,7 +389,7 @@ static int le_encrypt(const uint8_t key[16], const uint8_t plaintext[16], rp = (void *)rsp->data; memcpy(enc_data, rp->enc_data, sizeof(rp->enc_data)); - bt_buf_put(rsp); + bt_buf_release(rsp); wlinfo("enc_data %s\n", h(enc_data, 16)); @@ -418,7 +422,7 @@ static int le_rand(FAR void *buf, size_t len) } memcpy(ptr, rp->rand, copy); - bt_buf_put(rsp); + bt_buf_release(rsp); len -= copy; ptr += copy; @@ -532,7 +536,7 @@ static FAR struct bt_buf_s *bt_smp_create_pdu(FAR struct bt_conn_s *conn, return NULL; } - hdr = bt_buf_add(buf, sizeof(*hdr)); + hdr = bt_buf_extend(buf, sizeof(*hdr)); hdr->code = op; return buf; @@ -549,7 +553,7 @@ static void send_err_rsp(FAR struct bt_conn_s *conn, uint8_t reason) return; } - rsp = bt_buf_add(buf, sizeof(*rsp)); + rsp = bt_buf_extend(buf, sizeof(*rsp)); rsp->reason = reason; bt_l2cap_send(conn, BT_L2CAP_CID_SMP, buf); @@ -603,7 +607,7 @@ static uint8_t smp_pairing_req(FAR struct bt_conn_s *conn, return BT_SMP_ERR_UNSPECIFIED; } - rsp = bt_buf_add(rsp_buf, sizeof(*rsp)); + rsp = bt_buf_extend(rsp_buf, sizeof(*rsp)); /* For JustWorks pairing simplify rsp parameters. TODO: needs to be reworked * later on. @@ -652,7 +656,7 @@ static uint8_t smp_send_pairing_confirm(FAR struct bt_conn_s *conn) return BT_SMP_ERR_UNSPECIFIED; } - req = bt_buf_add(rsp_buf, sizeof(*req)); + req = bt_buf_extend(rsp_buf, sizeof(*req)); if (conn->role == BT_HCI_ROLE_MASTER) { @@ -668,7 +672,7 @@ static uint8_t smp_send_pairing_confirm(FAR struct bt_conn_s *conn) err = smp_c1(smp->tk, smp->prnd, smp->preq, smp->prsp, ia, ra, req->val); if (err) { - bt_buf_put(rsp_buf); + bt_buf_release(rsp_buf); return BT_SMP_ERR_UNSPECIFIED; } @@ -715,7 +719,7 @@ static uint8_t smp_send_pairing_random(FAR struct bt_conn_s *conn) return BT_SMP_ERR_UNSPECIFIED; } - req = bt_buf_add(rsp_buf, sizeof(*req)); + req = bt_buf_extend(rsp_buf, sizeof(*req)); memcpy(req->val, smp->prnd, sizeof(req->val)); bt_l2cap_send(conn, BT_L2CAP_CID_SMP, rsp_buf); @@ -895,7 +899,7 @@ static void bt_smp_distribute_keys(FAR struct bt_conn_s *conn) return; } - info = bt_buf_add(buf, sizeof(struct bt_smp_encrypt_info_s)); + info = bt_buf_extend(buf, sizeof(struct bt_smp_encrypt_info_s)); memcpy(info->ltk, keys->slave_ltk.val, sizeof(info->ltk)); bt_l2cap_send(conn, BT_L2CAP_CID_SMP, buf); @@ -908,7 +912,7 @@ static void bt_smp_distribute_keys(FAR struct bt_conn_s *conn) return; } - ident = bt_buf_add(buf, sizeof(struct bt_smp_master_ident_s)); + ident = bt_buf_extend(buf, sizeof(struct bt_smp_master_ident_s)); ident->rand = keys->slave_ltk.rand; ident->ediv = keys->slave_ltk.ediv; @@ -1080,8 +1084,9 @@ pair: return 0; } -static void bt_smp_recv(FAR struct bt_conn_s *conn, - FAR struct bt_buf_s *buf) +static void bt_smp_receive(FAR struct bt_conn_s *conn, + FAR struct bt_buf_s *buf, FAR void *context, + uint16_t cid) { FAR struct bt_smp_hdr_s *hdr = (FAR void *)buf->data; FAR struct bt_smp_s *smp = conn->smp; @@ -1095,7 +1100,7 @@ static void bt_smp_recv(FAR struct bt_conn_s *conn, wlinfo("Received SMP code 0x%02x len %u\n", hdr->code, buf->len); - bt_buf_pull(buf, sizeof(*hdr)); + bt_buf_consume(buf, sizeof(*hdr)); if (hdr->code >= NHANDLERS || !g_smp_handlers[hdr->code].func) { @@ -1138,10 +1143,11 @@ static void bt_smp_recv(FAR struct bt_conn_s *conn, } done: - bt_buf_put(buf); + bt_buf_release(buf); } -static void bt_smp_connected(FAR struct bt_conn_s *conn) +static void bt_smp_connected(FAR struct bt_conn_s *conn, FAR void *context, + uint16_t cid) { int i; @@ -1176,7 +1182,8 @@ static void bt_smp_connected(FAR struct bt_conn_s *conn) wlerr("ERROR: No available SMP context for conn %p\n", conn); } -static void bt_smp_disconnected(FAR struct bt_conn_s *conn) +static void bt_smp_disconnected(FAR struct bt_conn_s *conn, + FAR void *context, uint16_t cid) { struct bt_smp_s *smp = conn->smp; @@ -1191,7 +1198,8 @@ static void bt_smp_disconnected(FAR struct bt_conn_s *conn) memset(smp, 0, sizeof(*smp)); } -static void bt_smp_encrypt_change(FAR FAR struct bt_conn_s *conn) +static void bt_smp_encrypt_change(FAR FAR struct bt_conn_s *conn, + FAR void *context, uint16_t cid) { struct bt_smp_s *smp = conn->smp; @@ -1539,12 +1547,12 @@ static inline int smp_self_test(void) * Public Functions ****************************************************************************/ -int bt_smp_init(void) +int bt_smp_initialize(void) { static struct bt_l2cap_chan_s chan = { .cid = BT_L2CAP_CID_SMP, - .recv = bt_smp_recv, + .receive = bt_smp_receive, .connected = bt_smp_connected, .disconnected = bt_smp_disconnected, .encrypt_change = bt_smp_encrypt_change, @@ -1569,7 +1577,7 @@ int bt_smp_send_security_req(FAR struct bt_conn_s *conn) return -ENOBUFS; } - req = bt_buf_add(req_buf, sizeof(struct bt_smp_security_request_s)); + req = bt_buf_extend(req_buf, sizeof(struct bt_smp_security_request_s)); req->auth_req = BT_SMP_AUTH_BONDING; bt_l2cap_send(conn, BT_L2CAP_CID_SMP, req_buf); @@ -1595,7 +1603,7 @@ int bt_smp_send_pairing_req(FAR struct bt_conn_s *conn) return -ENOBUFS; } - req = bt_buf_add(req_buf, sizeof(*req)); + req = bt_buf_extend(req_buf, sizeof(*req)); /* For JustWorks pairing simplify req parameters. TODO: needs to be reworked * later on diff --git a/wireless/bluetooth/bt_smp.h b/wireless/bluetooth/bt_smp.h index 317cff08dbd..12c4bab8404 100644 --- a/wireless/bluetooth/bt_smp.h +++ b/wireless/bluetooth/bt_smp.h @@ -172,8 +172,8 @@ begin_packed_struct struct bt_smp_security_request_s ****************************************************************************/ bool bt_smp_irk_matches(FAR const uint8_t irk[16], FAR const bt_addr_t *addr); -int bt_smp_send_pairing_req(FAR struct bt_conn_s *conn); -int bt_smp_send_security_req(FAR struct bt_conn_s *conn); -int bt_smp_init(void); +int bt_smp_send_pairing_req(FAR struct bt_conn_s *conn); +int bt_smp_send_security_req(FAR struct bt_conn_s *conn); +int bt_smp_initialize(void); #endif /* __WIRELESS_BLUETOOTH_BT_SMP_H */ diff --git a/wireless/ieee802154/Kconfig b/wireless/ieee802154/Kconfig index fd3e0cd56e1..6d53df082bc 100644 --- a/wireless/ieee802154/Kconfig +++ b/wireless/ieee802154/Kconfig @@ -29,8 +29,8 @@ config IEEE802154_PRIMITIVE_IRQRESERVE default 0 depends on EXPERIMENTAL ---help--- - If primitves can be allocated from interrupt handlers, then this - specifies the number of pre-allocatd meta-data structures that are + If primitives can be allocated from interrupt handlers, then this + specifies the number of pre-allocated meta-data structures that are reserved for for use only by interrupt handlers. This may be zero to reserve no meta-data structures for interrupt handlers. In that case, the allocation will fail if tasking logic has allocated them all. diff --git a/wireless/ieee802154/ieee802154_primitive.c b/wireless/ieee802154/ieee802154_primitive.c index 318bed1bbd6..b4e53960b08 100644 --- a/wireless/ieee802154/ieee802154_primitive.c +++ b/wireless/ieee802154/ieee802154_primitive.c @@ -159,7 +159,7 @@ void ieee802154_primitivepool_initialize(void) int remaining = CONFIG_IEEE802154_PRIMITIVE_PREALLOC; #if CONFIG_IEEE802154_PRIMITIVE_PREALLOC > CONFIG_IEEE802154_PRIMITIVE_IRQRESERVE - /* Initialize g_primfree, thelist of primitive structures that are available + /* Initialize g_primfree, the list of primitive structures that are available * for general use. */ @@ -324,7 +324,7 @@ FAR struct ieee802154_primitive_s *ieee802154_primitive_allocate(void) } /* We have successfully allocated memory from some source. - * Zero and tag the alloated primitive structure. + * Zero and tag the allocated primitive structure. */ prim->pool = pool;