mirror of
https://github.com/apache/nuttx.git
synced 2026-06-01 07:45:16 +08:00
drivers/bluetooth: Extend device simulation. Now makes it all the way through initialization without error. wireless/bluetooth: Add support for IOCTL commangs to get BR/EDR and LE features.
This commit is contained in:
@@ -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,
|
static void btnull_format_local_features_rsp(FAR struct bt_buf_s *buf,
|
||||||
uint16_t opcode)
|
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;
|
struct bt_hci_rp_le_read_local_features_s features;
|
||||||
FAR uint8_t *data = buf->frame->io_data;
|
FAR uint8_t *data = buf->frame->io_data;
|
||||||
int ndx;
|
int ndx;
|
||||||
@@ -123,23 +121,22 @@ static void btnull_format_local_features_rsp(FAR struct bt_buf_s *buf,
|
|||||||
|
|
||||||
/* Return local features */
|
/* Return local features */
|
||||||
|
|
||||||
len = sizeof(struct bt_hci_evt_hdr_s) +
|
btnull_format_cmdcomplete(buf, opcode);
|
||||||
sizeof(struct hci_evt_cmd_complete_s) +
|
|
||||||
|
len = buf->len +
|
||||||
sizeof(struct bt_hci_rp_le_read_local_features_s);
|
sizeof(struct bt_hci_rp_le_read_local_features_s);
|
||||||
ndx = 0;
|
ndx = buf->len;
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
memset(&features, 0, sizeof(struct bt_hci_rp_le_read_local_features_s));
|
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,
|
memcpy(&data[ndx], &features,
|
||||||
sizeof(struct bt_hci_rp_le_read_local_features_s));
|
sizeof(struct bt_hci_rp_le_read_local_features_s));
|
||||||
ndx += 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,
|
static void btnull_format_bdaddr_rsp(FAR struct bt_buf_s *buf,
|
||||||
uint16_t opcode)
|
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;
|
struct bt_hci_rp_read_bd_addr_s bdaddr;
|
||||||
FAR uint8_t *data = buf->frame->io_data;
|
FAR uint8_t *data = buf->frame->io_data;
|
||||||
int ndx;
|
int ndx;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
/* Return BDAddr */
|
btnull_format_cmdcomplete(buf, opcode);
|
||||||
|
|
||||||
len = sizeof(struct bt_hci_evt_hdr_s) +
|
len = buf->len +
|
||||||
sizeof(struct hci_evt_cmd_complete_s) +
|
|
||||||
sizeof(struct bt_hci_rp_read_bd_addr_s);
|
sizeof(struct bt_hci_rp_read_bd_addr_s);
|
||||||
ndx = 0;
|
ndx = buf->len;
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
BLUETOOTH_ADDRCOPY(bdaddr.bdaddr.val, g_bt_addr.val);
|
BLUETOOTH_ADDRCOPY(bdaddr.bdaddr.val, g_bt_addr.val);
|
||||||
bdaddr.status = 0;
|
bdaddr.status = 0;
|
||||||
@@ -184,10 +168,34 @@ static void btnull_format_bdaddr_rsp(FAR struct bt_buf_s *buf,
|
|||||||
buf->len = len;
|
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,
|
static int btnull_send(FAR const struct bt_driver_s *dev,
|
||||||
FAR struct bt_buf_s *buf)
|
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? */
|
/* 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)
|
switch (opcode)
|
||||||
{
|
{
|
||||||
case BT_HCI_OP_READ_LOCAL_FEATURES:
|
case BT_HCI_OP_READ_LOCAL_FEATURES:
|
||||||
|
case BT_HCI_OP_LE_READ_LOCAL_FEATURES:
|
||||||
btnull_format_local_features_rsp(outbuf, opcode);
|
btnull_format_local_features_rsp(outbuf, opcode);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -216,6 +225,10 @@ static int btnull_send(FAR const struct bt_driver_s *dev,
|
|||||||
btnull_format_bdaddr_rsp(outbuf, opcode);
|
btnull_format_bdaddr_rsp(outbuf, opcode);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case BT_HCI_OP_LE_READ_BUFFER_SIZE:
|
||||||
|
btnull_format_buffersize_rsp(outbuf, opcode);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
btnull_format_cmdcomplete(outbuf, opcode);
|
btnull_format_cmdcomplete(outbuf, opcode);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -97,6 +97,7 @@
|
|||||||
#define BT_LMP_LE 0x40
|
#define BT_LMP_LE 0x40
|
||||||
|
|
||||||
/* LE features */
|
/* LE features */
|
||||||
|
|
||||||
#define BT_HCI_LE_ENCRYPTION 0x01
|
#define BT_HCI_LE_ENCRYPTION 0x01
|
||||||
|
|
||||||
/* OpCode Group Fields */
|
/* OpCode Group Fields */
|
||||||
|
|||||||
@@ -58,12 +58,13 @@
|
|||||||
|
|
||||||
/* Bluetooth network device IOCTL commands. */
|
/* Bluetooth network device IOCTL commands. */
|
||||||
|
|
||||||
#ifndef WL_BLUETOOTHCMDS != 15
|
#ifndef WL_BLUETOOTHCMDS != 16
|
||||||
# error Incorrect setting for number of Bluetooth IOCTL commands
|
# error Incorrect setting for number of Bluetooth IOCTL commands
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* NetBSD IOCTL commands ****************************************************/
|
/* IOCTL Commands ***********************************************************
|
||||||
/* All of the following use an argument of type struct btreg_s:
|
* Many derive from NetBSD, at least in name.
|
||||||
|
* All of the following use an argument of type struct btreg_s:
|
||||||
*
|
*
|
||||||
* Bluetooth Information Queries
|
* Bluetooth Information Queries
|
||||||
*
|
*
|
||||||
@@ -79,15 +80,24 @@
|
|||||||
* will be returned. Otherwise, the next device will be returned until
|
* will be returned. Otherwise, the next device will be returned until
|
||||||
* no more devices are found when the call will fail, with error ENXIO.
|
* no more devices are found when the call will fail, with error ENXIO.
|
||||||
* Thus, you can cycle through all devices in the system.
|
* 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 SIOCGBTINFO _WLIOC(WL_BLUETOOTHFIRST + 0)
|
||||||
#define SIOCGBTINFOA _WLIOC(WL_BLUETOOTHFIRST + 1)
|
#define SIOCGBTINFOA _WLIOC(WL_BLUETOOTHFIRST + 1)
|
||||||
#define SIOCNBTINFO _WLIOC(WL_BLUETOOTHFIRST + 2)
|
#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 SIOCGBTFEAT _WLIOC(WL_BLUETOOTHFIRST + 3)
|
||||||
|
#define SIOCGBTLEFEAT _WLIOC(WL_BLUETOOTHFIRST + 4)
|
||||||
|
|
||||||
/* Set Flags, Link Policy, and Packet Types
|
/* Set Flags, Link Policy, and Packet Types
|
||||||
*
|
*
|
||||||
@@ -100,9 +110,9 @@
|
|||||||
* the device supports.
|
* the device supports.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define SIOCSBTFLAGS _WLIOC(WL_BLUETOOTHFIRST + 4)
|
#define SIOCSBTFLAGS _WLIOC(WL_BLUETOOTHFIRST + 5)
|
||||||
#define SIOCSBTPOLICY _WLIOC(WL_BLUETOOTHFIRST + 5)
|
#define SIOCSBTPOLICY _WLIOC(WL_BLUETOOTHFIRST + 6)
|
||||||
#define SIOCSBTPTYPE _WLIOC(WL_BLUETOOTHFIRST + 6)
|
#define SIOCSBTPTYPE _WLIOC(WL_BLUETOOTHFIRST + 7)
|
||||||
|
|
||||||
/* Get Statistics:
|
/* Get Statistics:
|
||||||
*
|
*
|
||||||
@@ -112,11 +122,8 @@
|
|||||||
* Read device statistics, and zero them.
|
* Read device statistics, and zero them.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define SIOCGBTSTATS _WLIOC(WL_BLUETOOTHFIRST + 7)
|
#define SIOCGBTSTATS _WLIOC(WL_BLUETOOTHFIRST + 8)
|
||||||
#define SIOCZBTSTATS _WLIOC(WL_BLUETOOTHFIRST + 8)
|
#define SIOCZBTSTATS _WLIOC(WL_BLUETOOTHFIRST + 9)
|
||||||
|
|
||||||
/* NuttX-specific IOCTL commands. *******************************************/
|
|
||||||
/* All of the following use an argument of type struct btreg_s: */
|
|
||||||
|
|
||||||
/* Advertisement
|
/* Advertisement
|
||||||
*
|
*
|
||||||
@@ -127,8 +134,8 @@
|
|||||||
* Stop advertising.
|
* Stop advertising.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define SIOCBTADVSTART _WLIOC(WL_BLUETOOTHFIRST + 9)
|
#define SIOCBTADVSTART _WLIOC(WL_BLUETOOTHFIRST + 10)
|
||||||
#define SIOCBTADVSTOP _WLIOC(WL_BLUETOOTHFIRST + 10)
|
#define SIOCBTADVSTOP _WLIOC(WL_BLUETOOTHFIRST + 11)
|
||||||
|
|
||||||
/* Scanning
|
/* Scanning
|
||||||
*
|
*
|
||||||
@@ -142,9 +149,9 @@
|
|||||||
* Stop LE scanning and discard any buffered results.
|
* Stop LE scanning and discard any buffered results.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define SIOCBTSCANSTART _WLIOC(WL_BLUETOOTHFIRST + 11)
|
#define SIOCBTSCANSTART _WLIOC(WL_BLUETOOTHFIRST + 12)
|
||||||
#define SIOCBTSCANGET _WLIOC(WL_BLUETOOTHFIRST + 12)
|
#define SIOCBTSCANGET _WLIOC(WL_BLUETOOTHFIRST + 13)
|
||||||
#define SIOCBTSCANSTOP _WLIOC(WL_BLUETOOTHFIRST + 13)
|
#define SIOCBTSCANSTOP _WLIOC(WL_BLUETOOTHFIRST + 14)
|
||||||
|
|
||||||
/* Security
|
/* Security
|
||||||
*
|
*
|
||||||
@@ -152,7 +159,7 @@
|
|||||||
* Enable security for a connection.
|
* Enable security for a connection.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define SIOCBTSECURITY _WLIOC(WL_BLUETOOTHFIRST + 14)
|
#define SIOCBTSECURITY _WLIOC(WL_BLUETOOTHFIRST + 15)
|
||||||
|
|
||||||
/* Definitions associated with struct btreg_s *******************************/
|
/* Definitions associated with struct btreg_s *******************************/
|
||||||
/* struct btreq_s union field accessors */
|
/* struct btreq_s union field accessors */
|
||||||
@@ -261,9 +268,9 @@ struct btreq_s
|
|||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
uint8_t btrf_page0[HCI_FEATURES_SIZE]; /* basic */
|
uint8_t btrf_page0[HCI_FEATURES_SIZE]; /* Basic */
|
||||||
uint8_t btrf_page1[HCI_FEATURES_SIZE]; /* extended page 1 */
|
uint8_t btrf_page1[HCI_FEATURES_SIZE]; /* Extended page 1 */
|
||||||
uint8_t btrf_page2[HCI_FEATURES_SIZE]; /* extended page 2 */
|
uint8_t btrf_page2[HCI_FEATURES_SIZE]; /* Extended page 2 */
|
||||||
} btrf;
|
} btrf;
|
||||||
|
|
||||||
/* Read-only data that accompanies the SIOCBTADVSTART IOCTL command.
|
/* Read-only data that accompanies the SIOCBTADVSTART IOCTL command.
|
||||||
|
|||||||
@@ -162,7 +162,7 @@
|
|||||||
/* Reserved for Bluetooth network devices (see bt_ioctls.h) */
|
/* Reserved for Bluetooth network devices (see bt_ioctls.h) */
|
||||||
|
|
||||||
#define WL_BLUETOOTHFIRST (WL_NETFIRST + WL_NNETCMDS)
|
#define WL_BLUETOOTHFIRST (WL_NETFIRST + WL_NNETCMDS)
|
||||||
#define WL_BLUETOOTHCMDS (15)
|
#define WL_BLUETOOTHCMDS (16)
|
||||||
#define WL_IBLUETOOTHCMD(cmd) (_WLIOCVALID(cmd) && \
|
#define WL_IBLUETOOTHCMD(cmd) (_WLIOCVALID(cmd) && \
|
||||||
_IOC_NR(cmd) >= WL_BLUETOOTHFIRST && \
|
_IOC_NR(cmd) >= WL_BLUETOOTHFIRST && \
|
||||||
_IOC_NR(cmd) < (WL_BLUETOOTHFIRST + WL_BLUETOOTHCMDS))
|
_IOC_NR(cmd) < (WL_BLUETOOTHFIRST + WL_BLUETOOTHCMDS))
|
||||||
|
|||||||
@@ -405,7 +405,7 @@ void bt_buf_release(FAR struct bt_buf_s *buf)
|
|||||||
* pool.
|
* pool.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (buf->frame == NULL)
|
if (buf->frame != NULL)
|
||||||
{
|
{
|
||||||
iob_free(buf->frame);
|
iob_free(buf->frame);
|
||||||
buf->frame = NULL;
|
buf->frame = NULL;
|
||||||
|
|||||||
@@ -305,6 +305,35 @@ int btnet_ioctl(FAR struct net_driver_s *dev, int cmd, unsigned long arg)
|
|||||||
}
|
}
|
||||||
break;
|
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,
|
/* SIOCBTADVSTART: Set advertisement data, scan response data,
|
||||||
* advertisement parameters and start advertising.
|
* advertisement parameters and start advertising.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1536,11 +1536,6 @@ static int smp_self_test(void)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
static inline int smp_self_test(void)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|||||||
Reference in New Issue
Block a user