diff --git a/drivers/wireless/bluetooth/bt_null.c b/drivers/wireless/bluetooth/bt_null.c index 59dd9c9604d..b3b4afc708f 100644 --- a/drivers/wireless/bluetooth/bt_null.c +++ b/drivers/wireless/bluetooth/bt_null.c @@ -114,8 +114,6 @@ static void btnull_format_cmdcomplete(FAR struct bt_buf_s *buf, static void btnull_format_local_features_rsp(FAR struct bt_buf_s *buf, uint16_t opcode) { - struct bt_hci_evt_hdr_s evt; - struct hci_evt_cmd_complete_s cmd; struct bt_hci_rp_le_read_local_features_s features; FAR uint8_t *data = buf->frame->io_data; int ndx; @@ -123,23 +121,22 @@ static void btnull_format_local_features_rsp(FAR struct bt_buf_s *buf, /* Return local features */ - len = sizeof(struct bt_hci_evt_hdr_s) + - sizeof(struct hci_evt_cmd_complete_s) + + btnull_format_cmdcomplete(buf, opcode); + + len = buf->len + sizeof(struct bt_hci_rp_le_read_local_features_s); - ndx = 0; - - evt.evt = BT_HCI_EVT_CMD_COMPLETE; - evt.len = len; - memcpy(&data[ndx], &evt, sizeof(struct bt_hci_evt_hdr_s)); - ndx += sizeof(struct bt_hci_evt_hdr_s); - - cmd.ncmd = 1; - cmd.opcode = opcode; - memcpy(&data[ndx], &cmd, sizeof(struct hci_evt_cmd_complete_s)); - ndx += sizeof(struct hci_evt_cmd_complete_s); + ndx = buf->len; memset(&features, 0, sizeof(struct bt_hci_rp_le_read_local_features_s)); - features.features[4] = BT_LMP_LE; + if (opcode == BT_HCI_OP_READ_LOCAL_FEATURES) + { + features.features[4] = BT_LMP_LE; + } + else /* if opcode == BT_HCI_OP_LE_READ_LOCAL_FEATURES */ + { + features.features[0] = BT_HCI_LE_ENCRYPTION; + } + memcpy(&data[ndx], &features, sizeof(struct bt_hci_rp_le_read_local_features_s)); ndx += sizeof(struct bt_hci_rp_le_read_local_features_s); @@ -151,29 +148,16 @@ static void btnull_format_local_features_rsp(FAR struct bt_buf_s *buf, static void btnull_format_bdaddr_rsp(FAR struct bt_buf_s *buf, uint16_t opcode) { - struct bt_hci_evt_hdr_s evt; - struct hci_evt_cmd_complete_s cmd; struct bt_hci_rp_read_bd_addr_s bdaddr; FAR uint8_t *data = buf->frame->io_data; int ndx; int len; - /* Return BDAddr */ + btnull_format_cmdcomplete(buf, opcode); - len = sizeof(struct bt_hci_evt_hdr_s) + - sizeof(struct hci_evt_cmd_complete_s) + + len = buf->len + sizeof(struct bt_hci_rp_read_bd_addr_s); - ndx = 0; - - evt.evt = BT_HCI_EVT_CMD_COMPLETE; - evt.len = len; - memcpy(&data[ndx], &evt, sizeof(struct bt_hci_evt_hdr_s)); - ndx += sizeof(struct bt_hci_evt_hdr_s); - - cmd.ncmd = 1; - cmd.opcode = opcode; - memcpy(&data[ndx], &cmd, sizeof(struct hci_evt_cmd_complete_s)); - ndx += sizeof(struct hci_evt_cmd_complete_s); + ndx = buf->len; BLUETOOTH_ADDRCOPY(bdaddr.bdaddr.val, g_bt_addr.val); bdaddr.status = 0; @@ -184,10 +168,34 @@ static void btnull_format_bdaddr_rsp(FAR struct bt_buf_s *buf, buf->len = len; } +static void btnull_format_buffersize_rsp(FAR struct bt_buf_s *buf, + uint16_t opcode) +{ + struct bt_hci_rp_le_read_buffer_size_s bufsize; + FAR uint8_t *data = buf->frame->io_data; + int ndx; + int len; + + btnull_format_cmdcomplete(buf, opcode); + + len = buf->len + + sizeof(struct bt_hci_rp_le_read_buffer_size_s); + ndx = buf->len; + + bufsize.status = 0; + bufsize.le_max_len = BLUETOOTH_MAX_FRAMELEN; + bufsize.le_max_num = 1; + memcpy(&data[ndx], &bufsize, sizeof(struct bt_hci_rp_le_read_buffer_size_s)); + ndx += sizeof(struct bt_hci_rp_le_read_buffer_size_s); + + buf->frame->io_len = len; + buf->len = len; +} + static int btnull_send(FAR const struct bt_driver_s *dev, FAR struct bt_buf_s *buf) { - wlinfo("Bit buffer: length %d\n", (int)buf->len); + wlinfo("Bit bucket: length %d\n", (int)buf->len); /* Is the Bluetooth stack waiting for an event? */ @@ -209,6 +217,7 @@ static int btnull_send(FAR const struct bt_driver_s *dev, switch (opcode) { case BT_HCI_OP_READ_LOCAL_FEATURES: + case BT_HCI_OP_LE_READ_LOCAL_FEATURES: btnull_format_local_features_rsp(outbuf, opcode); break; @@ -216,6 +225,10 @@ static int btnull_send(FAR const struct bt_driver_s *dev, btnull_format_bdaddr_rsp(outbuf, opcode); break; + case BT_HCI_OP_LE_READ_BUFFER_SIZE: + btnull_format_buffersize_rsp(outbuf, opcode); + break; + default: btnull_format_cmdcomplete(outbuf, opcode); break; diff --git a/include/nuttx/wireless/bt_hci.h b/include/nuttx/wireless/bt_hci.h index b633a0984b3..ff2f807b9f6 100644 --- a/include/nuttx/wireless/bt_hci.h +++ b/include/nuttx/wireless/bt_hci.h @@ -97,6 +97,7 @@ #define BT_LMP_LE 0x40 /* LE features */ + #define BT_HCI_LE_ENCRYPTION 0x01 /* OpCode Group Fields */ diff --git a/include/nuttx/wireless/bt_ioctl.h b/include/nuttx/wireless/bt_ioctl.h index ee6cb894883..2c383edaeb6 100644 --- a/include/nuttx/wireless/bt_ioctl.h +++ b/include/nuttx/wireless/bt_ioctl.h @@ -58,12 +58,13 @@ /* Bluetooth network device IOCTL commands. */ -#ifndef WL_BLUETOOTHCMDS != 15 +#ifndef WL_BLUETOOTHCMDS != 16 # error Incorrect setting for number of Bluetooth IOCTL commands #endif -/* NetBSD IOCTL commands ****************************************************/ -/* All of the following use an argument of type struct btreg_s: +/* IOCTL Commands *********************************************************** + * Many derive from NetBSD, at least in name. + * All of the following use an argument of type struct btreg_s: * * Bluetooth Information Queries * @@ -79,15 +80,24 @@ * will be returned. Otherwise, the next device will be returned until * no more devices are found when the call will fail, with error ENXIO. * Thus, you can cycle through all devices in the system. - * SIOCGBTFEAT - * Get Bluetooth device Features. This returns the cached basic (page 0) - * and extended (page 1 & 2) features. */ #define SIOCGBTINFO _WLIOC(WL_BLUETOOTHFIRST + 0) #define SIOCGBTINFOA _WLIOC(WL_BLUETOOTHFIRST + 1) #define SIOCNBTINFO _WLIOC(WL_BLUETOOTHFIRST + 2) + +/* Features + * + * SIOCGBTFEAT + * Get Bluetooth BR/BDR device Features. This returns the cached basic + * (page 0) and extended (page 1 & 2) features. Only page 0 is valid. + * SIOCGBTLEFEAT + * Get Bluetooth LE device Features. This returns the cached page 0-2 + * features. Only page 0 is value. + */ + #define SIOCGBTFEAT _WLIOC(WL_BLUETOOTHFIRST + 3) +#define SIOCGBTLEFEAT _WLIOC(WL_BLUETOOTHFIRST + 4) /* Set Flags, Link Policy, and Packet Types * @@ -100,9 +110,9 @@ * the device supports. */ -#define SIOCSBTFLAGS _WLIOC(WL_BLUETOOTHFIRST + 4) -#define SIOCSBTPOLICY _WLIOC(WL_BLUETOOTHFIRST + 5) -#define SIOCSBTPTYPE _WLIOC(WL_BLUETOOTHFIRST + 6) +#define SIOCSBTFLAGS _WLIOC(WL_BLUETOOTHFIRST + 5) +#define SIOCSBTPOLICY _WLIOC(WL_BLUETOOTHFIRST + 6) +#define SIOCSBTPTYPE _WLIOC(WL_BLUETOOTHFIRST + 7) /* Get Statistics: * @@ -112,11 +122,8 @@ * Read device statistics, and zero them. */ -#define SIOCGBTSTATS _WLIOC(WL_BLUETOOTHFIRST + 7) -#define SIOCZBTSTATS _WLIOC(WL_BLUETOOTHFIRST + 8) - -/* NuttX-specific IOCTL commands. *******************************************/ -/* All of the following use an argument of type struct btreg_s: */ +#define SIOCGBTSTATS _WLIOC(WL_BLUETOOTHFIRST + 8) +#define SIOCZBTSTATS _WLIOC(WL_BLUETOOTHFIRST + 9) /* Advertisement * @@ -127,8 +134,8 @@ * Stop advertising. */ -#define SIOCBTADVSTART _WLIOC(WL_BLUETOOTHFIRST + 9) -#define SIOCBTADVSTOP _WLIOC(WL_BLUETOOTHFIRST + 10) +#define SIOCBTADVSTART _WLIOC(WL_BLUETOOTHFIRST + 10) +#define SIOCBTADVSTOP _WLIOC(WL_BLUETOOTHFIRST + 11) /* Scanning * @@ -142,9 +149,9 @@ * Stop LE scanning and discard any buffered results. */ -#define SIOCBTSCANSTART _WLIOC(WL_BLUETOOTHFIRST + 11) -#define SIOCBTSCANGET _WLIOC(WL_BLUETOOTHFIRST + 12) -#define SIOCBTSCANSTOP _WLIOC(WL_BLUETOOTHFIRST + 13) +#define SIOCBTSCANSTART _WLIOC(WL_BLUETOOTHFIRST + 12) +#define SIOCBTSCANGET _WLIOC(WL_BLUETOOTHFIRST + 13) +#define SIOCBTSCANSTOP _WLIOC(WL_BLUETOOTHFIRST + 14) /* Security * @@ -152,7 +159,7 @@ * Enable security for a connection. */ -#define SIOCBTSECURITY _WLIOC(WL_BLUETOOTHFIRST + 14) +#define SIOCBTSECURITY _WLIOC(WL_BLUETOOTHFIRST + 15) /* Definitions associated with struct btreg_s *******************************/ /* struct btreq_s union field accessors */ @@ -261,9 +268,9 @@ struct btreq_s struct { - uint8_t btrf_page0[HCI_FEATURES_SIZE]; /* basic */ - uint8_t btrf_page1[HCI_FEATURES_SIZE]; /* extended page 1 */ - uint8_t btrf_page2[HCI_FEATURES_SIZE]; /* extended page 2 */ + uint8_t btrf_page0[HCI_FEATURES_SIZE]; /* Basic */ + uint8_t btrf_page1[HCI_FEATURES_SIZE]; /* Extended page 1 */ + uint8_t btrf_page2[HCI_FEATURES_SIZE]; /* Extended page 2 */ } btrf; /* Read-only data that accompanies the SIOCBTADVSTART IOCTL command. diff --git a/include/nuttx/wireless/wireless.h b/include/nuttx/wireless/wireless.h index 2c9e62f59ca..5566c8e55d0 100644 --- a/include/nuttx/wireless/wireless.h +++ b/include/nuttx/wireless/wireless.h @@ -162,7 +162,7 @@ /* Reserved for Bluetooth network devices (see bt_ioctls.h) */ #define WL_BLUETOOTHFIRST (WL_NETFIRST + WL_NNETCMDS) -#define WL_BLUETOOTHCMDS (15) +#define WL_BLUETOOTHCMDS (16) #define WL_IBLUETOOTHCMD(cmd) (_WLIOCVALID(cmd) && \ _IOC_NR(cmd) >= WL_BLUETOOTHFIRST && \ _IOC_NR(cmd) < (WL_BLUETOOTHFIRST + WL_BLUETOOTHCMDS)) diff --git a/wireless/bluetooth/bt_buf.c b/wireless/bluetooth/bt_buf.c index 7ba8a4f0435..b1c819b3b8d 100644 --- a/wireless/bluetooth/bt_buf.c +++ b/wireless/bluetooth/bt_buf.c @@ -405,7 +405,7 @@ void bt_buf_release(FAR struct bt_buf_s *buf) * pool. */ - if (buf->frame == NULL) + if (buf->frame != NULL) { iob_free(buf->frame); buf->frame = NULL; diff --git a/wireless/bluetooth/bt_ioctl.c b/wireless/bluetooth/bt_ioctl.c index 557596b0f8f..3e8a7bddb7a 100644 --- a/wireless/bluetooth/bt_ioctl.c +++ b/wireless/bluetooth/bt_ioctl.c @@ -305,6 +305,35 @@ int btnet_ioctl(FAR struct net_driver_s *dev, int cmd, unsigned long arg) } break; + /* SIOCGBTFEAT + * Get Bluetooth BR/BDR device Features. This returns the cached + * basic (page 0) and extended (page 1 & 2) features. Only page 0 + * is valid. + * SIOCGBTLEFEAT + * Get Bluetooth LE device Features. This returns the cached page + * 0-2 features. Only page 0 is value. + */ + + case SIOCGBTFEAT: + case SIOCGBTLEFEAT: + { + FAR const uint8_t *src; + + memset(&btreq->btru.btrf, 0, sizeof(btreq->btru.btrf)); + if (cmd == SIOCGBTFEAT) + { + src = g_btdev.features; + } + else + { + src = g_btdev.le_features; + } + + memcpy(btreq->btr_features0, src, 8); + ret = OK; + } + break; + /* SIOCBTADVSTART: Set advertisement data, scan response data, * advertisement parameters and start advertising. */ diff --git a/wireless/bluetooth/bt_smp.c b/wireless/bluetooth/bt_smp.c index a68fa24cc48..2882526f6a0 100644 --- a/wireless/bluetooth/bt_smp.c +++ b/wireless/bluetooth/bt_smp.c @@ -1536,11 +1536,6 @@ static int smp_self_test(void) return 0; } -#else -static inline int smp_self_test(void) -{ - return 0; -} #endif /****************************************************************************