wireless/bluetooth: Add IOCTL commands to support MTU exchange.

This commit is contained in:
Gregory Nutt 2018-04-19 15:51:40 -06:00
parent 0a8dd2a778
commit 71b8d408e2
3 changed files with 122 additions and 17 deletions

View File

@ -60,7 +60,7 @@
/* Bluetooth network device IOCTL commands. */
#if !defined(WL_BLUETOOTHCMDS) || WL_BLUETOOTHCMDS != 18
#if !defined(WL_BLUETOOTHCMDS) || WL_BLUETOOTHCMDS != 20
# error Incorrect setting for number of Bluetooth IOCTL commands
#endif
@ -165,6 +165,10 @@
/* GATT
*
* SIOCBTEXCHANGE
* Exchange MTUs
* SIOCBTEXRESULT
* Get the result of the MTU exchange
* SIOCBTDISCOVER
* Starts GATT discovery
* SIOCBTDISCGET
@ -172,8 +176,10 @@
* SIOCBTDISCGET command was invoked.
*/
#define SIOCBTDISCOVER _WLIOC(WL_BLUETOOTHFIRST + 16)
#define SIOCBTDISCGET _WLIOC(WL_BLUETOOTHFIRST + 17)
#define SIOCBTEXCHANGE _WLIOC(WL_BLUETOOTHFIRST + 16)
#define SIOCBTEXRESULT _WLIOC(WL_BLUETOOTHFIRST + 17)
#define SIOCBTDISCOVER _WLIOC(WL_BLUETOOTHFIRST + 18)
#define SIOCBTDISCGET _WLIOC(WL_BLUETOOTHFIRST + 19)
/* Definitions associated with struct btreg_s *******************************/
/* struct btreq_s union field accessors */
@ -206,6 +212,11 @@
#define btr_secaddr btru.btrse.btrse_secaddr
#define btr_seclevel btru.btrse.btrse_seclevel
#define btr_expeer btru.btmx.btmx_expeer
#define btr_expending btru.btmxr.mx_pending
#define btr_exresult btru.btmxr.mx_result
#define btr_dtype btru.btrds.btrds_dtype
#define btr_dpeer btru.btrds.btrds_dpeer
#define btr_duuid16 btru.btrds.btrds_duuid16
@ -263,6 +274,14 @@ struct bt_discresonse_s
uint8_t dr_perm; /* Permissions */
};
/* MTU exchange state variables. */
struct bt_exchangeresult_s
{
bool mx_pending; /* True: We have not yet received the result */
uint8_t mx_result; /* The result of the MTU exchange */
};
/* Bluetooth statistics */
struct bt_stats_s
@ -362,6 +381,17 @@ struct btreq_s
enum bt_security_e btrse_seclevel; /* Security level */
} btrse;
/* Read-only data that accompanies SIOCBTEXCHANGE command */
struct
{
bt_addr_le_t btmx_expeer; /* Peer address for MTU exchange */
} btmx;
/* Write result that accompanies SIOCBTEXRESULT command */
struct bt_exchangeresult_s btmxr;
/* Read-only data that accompanies SIOCBTDISCOVER command */
struct

View File

@ -160,7 +160,7 @@
/* Reserved for Bluetooth network devices (see bt_ioctls.h) */
#define WL_BLUETOOTHFIRST (WL_NETFIRST + WL_NNETCMDS)
#define WL_BLUETOOTHCMDS (18)
#define WL_BLUETOOTHCMDS (20)
#define WL_IBLUETOOTHCMD(cmd) (_WLIOCVALID(cmd) && \
_IOC_NR(cmd) >= WL_BLUETOOTHFIRST && \
_IOC_NR(cmd) < (WL_BLUETOOTHFIRST + WL_BLUETOOTHCMDS))

View File

@ -68,8 +68,8 @@
struct btnet_scanstate_s
{
sem_t bs_exclsem; /* Manages exclusive access */
bool bs_scanning; /* True: Scanning in progress */
uint8_t bs_head; /* Head of circular list (for removal) */
volatile bool bs_scanning; /* True: Scanning in progress */
volatile uint8_t bs_head; /* Head of circular list (for removal) */
uint8_t bs_tail; /* Tail of circular list (for addition) */
struct bt_scanresponse_s bs_rsp[CONFIG_BLUETOOTH_MAXSCANRESULT];
@ -84,9 +84,9 @@ struct btnet_discoverstate_s
struct bt_gatt_discover_params_s bd_params;
struct bt_uuid_s bd_uuid; /* Discovery UUID */
sem_t bd_exclsem; /* Manages exclusive access */
bool bd_discovering; /* True: Discovery in progress */
uint8_t bd_head; /* Head of circular list (for removal) */
uint8_t bd_tail; /* Tail of circular list (for addition) */
volatile bool bd_discovering; /* True: Discovery in progress */
volatile uint8_t bd_head; /* Head of circular list (for removal) */
volatile uint8_t bd_tail; /* Tail of circular list (for addition) */
struct bt_discresonse_s bd_rsp[CONFIG_BLUETOOTH_MAXDISCOVER];
};
@ -96,14 +96,15 @@ struct btnet_discoverstate_s
****************************************************************************/
/* At present only a single Bluetooth device is supported. So we can simply
* maintain the scan and the discovery state as globals.
* maintain the scan, MTU exchange, and discovery states as globals.
*
* NOTE: This limits to a single Bluetooth device with one concurrent scan
* action and one concurrent discovery action.
* action, one concurrent MTU exchange, and one concurrent discovery action.
*/
static struct btnet_scanstate_s g_scanstate;
static struct btnet_discoverstate_s g_discoverstate;
static struct bt_exchangeresult_s g_exchangeresult;
/****************************************************************************
* Private Functions
@ -219,15 +220,17 @@ static int btnet_scan_result(FAR struct bt_scanresponse_s *result,
uint8_t head;
uint8_t tail;
uint8_t nrsp;
bool scanning;
int ret;
wlinfo("Scanning? %s\n", g_scanstate.bs_scanning ? "YES" : "NO");
scanning = g_scanstate.bs_scanning;
wlinfo("Scanning? %s\n", scanning ? "YES" : "NO");
/* Get exclusive access to the scan data while we are actively scanning.
* The semaphore is uninitialized in other cases.
*/
if (g_scanstate.bs_scanning)
if (scanning)
{
/* Get exclusive access to the scan data */
@ -265,7 +268,7 @@ static int btnet_scan_result(FAR struct bt_scanresponse_s *result,
g_scanstate.bs_head = head;
if (g_scanstate.bs_scanning)
if (scanning)
{
nxsem_post(&g_scanstate.bs_exclsem);
}
@ -273,6 +276,28 @@ static int btnet_scan_result(FAR struct bt_scanresponse_s *result,
return nrsp;
}
/****************************************************************************
* Name: bt_exchange_rsp
*
* Description:
* Result of MTU exchange.
*
* Input Parameters:
* conn - The address of the peer in the MTU exchange
* result - The result of the MTU exchange
*
* Returned Value:
* None
*
****************************************************************************/
static void bt_exchange_rsp(FAR struct bt_conn_s *conn, uint8_t result)
{
wlinfo("Exchange %s\n", result == 0 ? "succeeded" : "failed");
g_exchangeresult.mx_pending = true;
g_exchangeresult.mx_result = result;
}
/****************************************************************************
* Name: bt_discover_func
*
@ -405,15 +430,17 @@ static int btnet_discover_result(FAR struct bt_discresonse_s *result,
uint8_t head;
uint8_t tail;
uint8_t nrsp;
bool discovering;
int ret;
wlinfo("Discovering? %s\n", g_discoverstate.bd_discovering ? "YES" : "NO");
discovering = g_discoverstate.bd_discovering;
wlinfo("Discovering? %s\n", discovering ? "YES" : "NO");
/* Get exclusive access to the discovery data while we are actively
* discovering. The semaphore is uninitialized in other cases.
*/
if (g_discoverstate.bd_discovering)
if (discovering)
{
ret = nxsem_wait(&g_discoverstate.bd_exclsem);
if (ret < 0)
@ -445,7 +472,7 @@ static int btnet_discover_result(FAR struct bt_discresonse_s *result,
g_discoverstate.bd_head = head;
if (g_discoverstate.bd_discovering)
if (discovering)
{
nxsem_post(&g_discoverstate.bd_exclsem);
}
@ -658,6 +685,54 @@ int btnet_ioctl(FAR struct net_driver_s *netdev, int cmd, unsigned long arg)
}
break;
/* SIOCBTEXCHANGE: Exchange MTUs */
case SIOCBTEXCHANGE:
{
/* Check if we are still waiting for the result of the last exchange */
if (g_exchangeresult.mx_pending)
{
wlwarn("WARNING: Last exchange not yet complete\n");
ret = -EBUSY;
}
else
{
FAR struct bt_conn_s *conn;
/* Get the connection associated with the provided LE address */
conn = bt_conn_lookup_addr_le(&btreq->btr_expeer);
if (conn == NULL)
{
wlwarn("WARNING: Peer not connected\n");
ret = -ENOTCONN;
}
else
{
ret = bt_gatt_exchange_mtu(conn, bt_exchange_rsp);
if (ret == OK)
{
g_exchangeresult.mx_pending = true;
g_exchangeresult.mx_result = EBUSY;
}
bt_conn_release(conn);
}
}
}
break;
/* SIOCBTEXRESULT: Get the result of the MTU exchange */
case SIOCBTEXRESULT:
{
btreq->btr_expending = g_exchangeresult.mx_pending;
btreq->btr_exresult = g_exchangeresult.mx_result;
ret = OK;
}
break;
/* SIOCBTDISCOVER: Starts GATT discovery */
case SIOCBTDISCOVER: