wireless/bluetooth: Implementat SIOCGBTINFO IOCTL command. Eliminated some redundancy.

This commit is contained in:
Gregory Nutt
2018-04-06 10:39:12 -06:00
parent cab7ba8b8f
commit 5009c22f85
2 changed files with 84 additions and 132 deletions
+22 -38
View File
@@ -118,54 +118,38 @@
/* NuttX-specific IOCTL commands. *******************************************/ /* NuttX-specific IOCTL commands. *******************************************/
/* All of the following use an argument of type struct btreg_s: */ /* All of the following use an argument of type struct btreg_s: */
/* SIOCBTADVSTART /* Advertisement
* Description: Set advertisement data, scan response data, *
* advertisement parameters and start advertising. * SIOCBTADVSTART
* Input: Pointer to read-btreq_s instance of struct btreq_s. * Set advertisement data, scan response data, advertisement parameters
* Output: None * and start advertising.
* SIOCBTADVSTOP
* Stop advertising.
*/ */
#define SIOCBTADVSTART _WLIOC(WL_BLUETOOTHFIRST + 9) #define SIOCBTADVSTART _WLIOC(WL_BLUETOOTHFIRST + 9)
/* SIOCBTADVSTOP
* Description: Stop advertising.
* Input: A reference to a write-able instance of struct btreq_s.
* Output: None
*/
#define SIOCBTADVSTOP _WLIOC(WL_BLUETOOTHFIRST + 10) #define SIOCBTADVSTOP _WLIOC(WL_BLUETOOTHFIRST + 10)
/* SIOCBTSCANSTART /* Scanning
* Description: Start LE scanning. Buffered scan results may be *
* obtained via SIOCBTSCANGET * SIOCBTSCANSTART
* Input: A read-only referent to struct btreq_s. * Start LE scanning. Buffered scan results may be obtained via
* Output: None * SIOCBTSCANGET
* SIOCBTSCANGET
* Return scan results buffered since the call time that the
* SIOCBTSCANGET command was invoked.
* SIOCBTSCANSTOP
* Stop LE scanning and discard any buffered results.
*/ */
#define SIOCBTSCANSTART _WLIOC(WL_BLUETOOTHFIRST + 11) #define SIOCBTSCANSTART _WLIOC(WL_BLUETOOTHFIRST + 11)
/* SIOCBTSCANGET
* Description: Return scan results buffered since the call time that
* the SIOCBTSCANGET command was invoked.
* Input: A reference to a write-able instance of struct btreq_s.
* Output: Buffered scan result results are returned in the user-
* provided buffer space.
*/
#define SIOCBTSCANGET _WLIOC(WL_BLUETOOTHFIRST + 12) #define SIOCBTSCANGET _WLIOC(WL_BLUETOOTHFIRST + 12)
/* SIOCBTSCANSTOP
* Description: Stop LE scanning and discard any buffered results.
* Input: A reference to a read-only instance of struct btreq_s.
* Output: None
*/
#define SIOCBTSCANSTOP _WLIOC(WL_BLUETOOTHFIRST + 13) #define SIOCBTSCANSTOP _WLIOC(WL_BLUETOOTHFIRST + 13)
/* SIOCBTSECURITY /* Security
* Description: Enable security for a connection. *
* Input: A reference to a write-able instance of struct btreq_s. * SIOCBTSECURITY
* Output: None * Enable security for a connection.
*/ */
#define SIOCBTSECURITY _WLIOC(WL_BLUETOOTHFIRST + 14) #define SIOCBTSECURITY _WLIOC(WL_BLUETOOTHFIRST + 14)
@@ -173,8 +157,8 @@
/* Definitions associated with struct btreg_s *******************************/ /* Definitions associated with struct btreg_s *******************************/
/* struct btreq_s union field accessors */ /* struct btreq_s union field accessors */
#define btr_flags btru.btri.btri_flags
#define btr_bdaddr btru.btri.btri_bdaddr #define btr_bdaddr btru.btri.btri_bdaddr
#define btr_flags btru.btri.btri_flags
#define btr_num_cmd btru.btri.btri_num_cmd #define btr_num_cmd btru.btri.btri_num_cmd
#define btr_num_acl btru.btri.btri_num_acl #define btr_num_acl btru.btri.btri_num_acl
#define btr_num_sco btru.btri.btri_num_sco #define btr_num_sco btru.btri.btri_num_sco
+62 -94
View File
@@ -47,6 +47,7 @@
#include <nuttx/wqueue.h> #include <nuttx/wqueue.h>
#include <nuttx/semaphore.h> #include <nuttx/semaphore.h>
#include <nuttx/net/netdev.h> #include <nuttx/net/netdev.h>
#include <nuttx/net/bluetooth.h>
#include <nuttx/wireless/bt_core.h> #include <nuttx/wireless/bt_core.h>
#include <nuttx/wireless/bt_hci.h> #include <nuttx/wireless/bt_hci.h>
#include <nuttx/wireless/bt_ioctl.h> #include <nuttx/wireless/bt_ioctl.h>
@@ -266,45 +267,58 @@ static int btnet_scan_result(FAR struct bt_scanresponse_s *result,
int btnet_ioctl(FAR struct net_driver_s *dev, int cmd, unsigned long arg) int btnet_ioctl(FAR struct net_driver_s *dev, int cmd, unsigned long arg)
{ {
FAR struct btreq_s *btreq = (FAR struct btreq_s *)((uintptr_t)arg);
int ret; int ret;
wlinfo("cmd=%04x arg=%ul\n", cmd, arg); wlinfo("cmd=%04x arg=%ul\n", cmd, arg);
DEBUGASSERT(dev != NULL && dev->d_private != NULL); DEBUGASSERT(dev != NULL && dev->d_private != NULL);
if (btreq == NULL)
{
return -EINVAL;
}
wlinfo("ifname: %s\n", btreq->btr_name);
/* Process the command */
switch (cmd) switch (cmd)
{ {
/* SIOCBTADVSTART /* SIOCGBTINFO: Get Bluetooth device Info. Given the device name,
* Description: Set advertisement data, scan response data, * fill in the btreq_s structure.
* advertisement parameters and start advertising. *
* Input: Pointer to read-only instance of struct btreq_s. * REVISIT: Little more than a stub at present. It does return the
* Output: None * device address associated with the device name which in itself is
* important.
*/
case SIOCGBTINFO:
{
memset(&btreq->btru.btri, 0, sizeof(btreq->btru.btri));
BLUETOOTH_ADDRCOPY(btreq->btr_bdaddr.val, g_btdev.bdaddr.val);
btreq->btr_num_cmd = CONFIG_BLUETOOTH_BUFFER_PREALLOC;
btreq->btr_num_acl = CONFIG_BLUETOOTH_BUFFER_PREALLOC;
btreq->btr_acl_mtu = BLUETOOTH_MAX_MTU;
btreq->btr_sco_mtu = BLUETOOTH_MAX_MTU;
btreq->btr_max_acl = CONFIG_IOB_NBUFFERS;
ret = OK;
}
break;
/* SIOCBTADVSTART: Set advertisement data, scan response data,
* advertisement parameters and start advertising.
*/ */
case SIOCBTADVSTART: case SIOCBTADVSTART:
{ {
FAR struct btreq_s *btreq = ret = bt_start_advertising(btreq->btr_advtype,
(FAR struct btreq_s *)((uintptr_t)arg); btreq->btr_advad,
btreq->btr_advad);
if (btreq == NULL) wlinfo("Start advertising: %d\n", ret);
{
ret = -EINVAL;
}
else
{
ret = bt_start_advertising(btreq->btr_advtype,
btreq->btr_advad,
btreq->btr_advad);
wlinfo("Start advertising: %d\n", ret);
}
} }
break; break;
/* SIOCBTADVSTOP /* SIOCBTADVSTOP: Stop advertising. */
* Description: Stop advertising.
* Input: A reference to a write-able instance of struct
* btreq_s.
* Output: None
*/
case SIOCBTADVSTOP: case SIOCBTADVSTOP:
{ {
@@ -314,26 +328,15 @@ int btnet_ioctl(FAR struct net_driver_s *dev, int cmd, unsigned long arg)
} }
break; break;
/* SIOCBTSCANSTART /* SIOCBTSCANSTART: Start LE scanning. Buffered scan results may be
* Description: Start LE scanning. Buffered scan results may be * obtained via SIOCBTSCANGET
* obtained via SIOCBTSCANGET
* Input: A read-only referent to struct btreq_s.
* Output: None
*/ */
case SIOCBTSCANSTART: case SIOCBTSCANSTART:
{ {
FAR struct btreq_s *btreq =
(FAR struct btreq_s *)((uintptr_t)arg);
if (btreq == NULL)
{
ret = -EINVAL;
}
/* Are we already scanning? */ /* Are we already scanning? */
else if (g_scanstate.bs_scanning) if (g_scanstate.bs_scanning)
{ {
ret = -EBUSY; ret = -EBUSY;
} }
@@ -359,44 +362,24 @@ int btnet_ioctl(FAR struct net_driver_s *dev, int cmd, unsigned long arg)
} }
break; break;
/* SIOCBTSCANGET /* SIOCBTSCANGET: Return scan results buffered since the call time
* Description: Return scan results buffered since the call time * that the SIOCBTSCANGET command was invoked.
* that the SIOCBTSCANGET command was invoked.
* Input: A reference to a write-able instance of struct
* btreq_s.
* Output: Buffered scan result results are returned in the
* user-provided buffer space.
*/ */
case SIOCBTSCANGET: case SIOCBTSCANGET:
{ {
FAR struct btreq_s *btreq = ret = btnet_scan_result(btreq->btr_rsp, btreq->btr_nrsp);
(FAR struct btreq_s *)((uintptr_t)arg); wlinfo("Get scan results: %d\n", ret);
if (btreq == NULL) if (ret >= 0)
{ {
ret = -EINVAL; btreq->btr_nrsp = ret;
} ret = OK;
else
{
ret = btnet_scan_result(btreq->btr_rsp, btreq->btr_nrsp);
wlinfo("Get scan results: %d\n", ret);
if (ret >= 0)
{
btreq->btr_nrsp = ret;
ret = OK;
}
} }
} }
break; break;
/* SIOCBTSCANSTOP /* SIOCBTSCANSTOP: Stop LE scanning and discard any buffered results. */
* Description: Stop LE scanning and discard any buffered results.
* Input: A reference to a read-only instance of struct
* btreq_s.
* Output: None
*/
case SIOCBTSCANSTOP: case SIOCBTSCANSTOP:
{ {
@@ -410,44 +393,29 @@ int btnet_ioctl(FAR struct net_driver_s *dev, int cmd, unsigned long arg)
} }
break; break;
/* SIOCBTSECURITY /* SIOCBTSECURITY: Enable security for a connection. */
* Description: Enable security for a connection.
* Input: A reference to a write-able instance of struct
* btreq_s.
* Output: None
*/
case SIOCBTSECURITY: case SIOCBTSECURITY:
{ {
FAR struct btreq_s *btreq = FAR struct bt_conn_s *conn;
(FAR struct btreq_s *)((uintptr_t)arg);
if (btreq == NULL) /* Get the connection associated with the provided LE address */
conn = bt_conn_lookup_addr_le(&btreq->btr_secaddr);
if (conn == NULL)
{ {
ret = -EINVAL; wlwarn("WARNING: Peer not connected\n");
ret = -ENOTCONN;
} }
else else
{ {
FAR struct bt_conn_s *conn; ret = bt_conn_security(conn, btreq->btr_seclevel);
if (ret < 0)
/* Get the connection associated with the provided LE address */
conn = bt_conn_lookup_addr_le(&btreq->btr_secaddr);
if (conn == NULL)
{ {
wlwarn("WARNING: Peer not connected\n"); wlerr("ERROR: Security setting failed: %d\n", ret);
ret = -ENOTCONN;
} }
else
{
ret = bt_conn_security(conn, btreq->btr_seclevel);
if (ret < 0)
{
wlerr("ERROR: Security setting failed: %d\n", ret);
}
bt_conn_release(conn); bt_conn_release(conn);
}
} }
} }
break; break;