wireless/bluetooth and include/nutt/net: Add support for Bluetooth IOCTL commands.

This commit is contained in:
Gregory Nutt
2018-03-30 10:50:44 -06:00
parent 380d558795
commit d62649757c
13 changed files with 828 additions and 108 deletions
+1 -89
View File
@@ -146,28 +146,6 @@ enum bt_security_e
* encryption. */ * encryption. */
}; };
/****************************************************************************
* Name: bt_le_scan_cb_t
*
* Description:
* A function of this type will be called back when user application
* triggers active LE scan. The caller will populate all needed
* parameters based on data coming from scan result.
* Such function can be set by user when LE active scan API is used.
*
* Input Parameters:
* addr - Advertiser LE address and type.
* rssi - Strength of advertiser signal.
* adv_type - Type of advertising response from advertiser.
* adv_data - Address of buffer containing advertiser data.
* len - Length of advertiser data contained in buffer.
*
****************************************************************************/
typedef CODE void bt_le_scan_cb_t(FAR const bt_addr_le_t *addr, int8_t rssi,
uint8_t adv_type,
FAR const uint8_t *adv_data, uint8_t len);
/**************************************************************************** /****************************************************************************
* Inline Functions * Inline Functions
****************************************************************************/ ****************************************************************************/
@@ -216,7 +194,7 @@ static inline int bt_addr_to_str(FAR const bt_addr_t *addr, FAR char *str,
* *
****************************************************************************/ ****************************************************************************/
static inline int bt_addr_le_to_str(const bt_addr_le_t *addr, char *str, static inline int bt_addr_le_to_str(FAR const bt_addr_le_t *addr, char *str,
size_t len) size_t len)
{ {
char type[7]; char type[7];
@@ -258,70 +236,4 @@ static inline int bt_addr_le_to_str(const bt_addr_le_t *addr, char *str,
int bt_init(void); int bt_init(void);
/****************************************************************************
* Name: bt_start_advertising
*
* Description:
* Set advertisement data, scan response data, advertisement parameters
* and start advertising.
*
* Input Parameters:
* type - Advertising type.
* ad - Data to be used in advertisement packets.
* sd - Data to be used in scan response packets.
*
* Returned Value:
* Zero on success or (negative) error code otherwise.
*
****************************************************************************/
int bt_start_advertising(uint8_t type, FAR const struct bt_eir_s *ad,
FAR const struct bt_eir_s *sd);
/****************************************************************************
* Name: bt_stop_advertising
*
* Description:
* Stops ongoing advertising.
*
* Returned Value:
* Zero on success or (negative) error code otherwise.
*
****************************************************************************/
int bt_stop_advertising(void);
/****************************************************************************
* Name: bt_start_scanning
*
* Description:
* Start LE scanning with and provide results through the specified
* callback.
*
* Input Parameters:
* filter_dups - Enable duplicate filtering (or not).
* cb - Callback to notify scan results.
*
* Returned Value:
* Zero on success or error code otherwise, positive in case
* of protocol error or negative (POSIX) in case of stack internal error
*
****************************************************************************/
int bt_start_scanning(uint8_t filter_dups, bt_le_scan_cb_t cb);
/****************************************************************************
* Name: bt_stop_scanning
*
* Description:
* Stops ongoing LE scanning.
*
* Returned Value:
* Zero on success or error code otherwise, positive in case
* of protocol error or negative (POSIX) in case of stack internal error
*
****************************************************************************/
int bt_stop_scanning(void);
#endif /* __INCLUDE_NUTTX_WIRELESS_BT_CORE_H */ #endif /* __INCLUDE_NUTTX_WIRELESS_BT_CORE_H */
+149
View File
@@ -0,0 +1,149 @@
/****************************************************************************
* wireless/bluetooth/bt_ioctl.h
* Bluetooth Network IOCTL commands.
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 __INCLUDE_NUTTX_WIRELESS_BT_IOCTL_H
#define __INCLUDE_NUTTX_WIRELESS_BT_IOCTL_H 1
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/wireless/bt_core.h>
#include <nuttx/wireless/bt_hci.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Bluetooth network device IOCTL commands. */
#ifndef WL_BLUETOOTHCMDS != 5
# error Incorrect setting for number of Bluetooth IOCTL commands
#endif
/* SIOCBT_ADVERTISESTART
* Description: Set advertisement data, scan response data,
* advertisement parameters and start advertising.
* Input: Pointer to read-write instance of struct
* bt_advertisestart_s.
* Output: None
*/
#define SIOCBT_ADVERTISESTART _WLIOC(WL_BLUETOOTHFIRST + 0)
/* SIOCBT_ADVERTISESTOP
* Description: Stop advertising.
* Input: None
* Output: None
*/
#define SIOCBT_ADVERTISESTOP _WLIOC(WL_BLUETOOTHFIRST + 1)
/* SIOCBT_SCANSTART
* Description: Start LE scanning. Buffered scan results may be
* obtained via SIOCBT_SCANGET
* Input: 1=Duplicate filtering enabled
* Output: None
*/
#define SIOCBT_SCANSTART _WLIOC(WL_BLUETOOTHFIRST + 2)
/* SIOCBT_SCANGET
* Description: Return scan results buffered since the call time that
* the SIOCBT_SCANGET command was invoked.
* Input: A reference to a write-able instance of struct
* bt_scanresult_s.
* Output: Buffered scan result results are returned in the user-
* provided buffer space.
*/
#define SIOCBT_SCANGET _WLIOC(WL_BLUETOOTHFIRST + 3)
/* SIOCBT_SCANSTOP
* Description: Stop LE scanning and discard any buffered results.
* Input: None
* Output: None
*/
#define SIOCBT_SCANSTOP _WLIOC(WL_BLUETOOTHFIRST + 4)
/****************************************************************************
* Public Types
****************************************************************************/
/* Read-only data that accompanies the SIOCBT_ADVERTISESTART IOCTL command.
* Advertising types are defined in bt_hci.h.
*/
struct bt_advertisestart_s
{
uint8_t as_type; /* Advertising type */
FAR const struct bt_eir_s as_ad; /* Data for advertisement packets */
FAR const struct bt_eir_s as_sd; /* Data for scan response packets */
};
/* Write-able data that accompanies the SIOCBT_SCANGET IOCTL command */
struct bt_scanresponse_s
{
bt_addr_le_t sr_addr; /* Advertiser LE address and type */
int8_t sr_rssi; /* Strength of advertiser signal */
uint8_t sr_type; /* Type of advertising response */
uint8_t sr_len; /* Length of advertiser data */
uint8_t sr_data[CONFIG_BLUETOOTH_MAXSCANDATA];
};
struct bt_scanresult_s
{
uint8_t sc_nrsp; /* Input: Max number of responses
* Return: Actual number of responses */
struct bt_scanresponse_s sc_rsp[1];
};
#define SIZEOF_BT_SCANRESULT_S(n) \
(sizeof(struct bt_scanresult_s) + \
((n) - 1) * sizeof(struct bt_scanresponse_s))
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#endif /* __INCLUDE_NUTTX_WIRELESS_BT_IOCTL_H */
+1
View File
@@ -53,6 +53,7 @@
/**************************************************************************** /****************************************************************************
* Public Types * Public Types
****************************************************************************/ ****************************************************************************/
/* This is the type of the Bluetooth UART upper-half driver interrupt /* This is the type of the Bluetooth UART upper-half driver interrupt
* handler used with the struct btuart_lowerhalf_s attach() method. * handler used with the struct btuart_lowerhalf_s attach() method.
*/ */
+22 -14
View File
@@ -2,7 +2,7 @@
* include/nuttx/wireless/wireless.h * include/nuttx/wireless/wireless.h
* Wireless network IOCTL commands * Wireless network IOCTL commands
* *
* Copyright (C) 2011-2013, 2017 Gregory Nutt. All rights reserved. * Copyright (C) 2011-2013, 2017-2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -159,12 +159,20 @@
#define WL_NETFIRST 0x0001 /* First network command */ #define WL_NETFIRST 0x0001 /* First network command */
#define WL_NNETCMDS 0x0032 /* Number of network commands */ #define WL_NNETCMDS 0x0032 /* Number of network commands */
/* Reserved for Bluetooth network devices (see bt_ioctls.h) */
#define WL_BLUETOOTHFIRST (WL_NETFIRST + WL_NNETCMDS)
#define WL_BLUETOOTHCMDS (5)
#define WL_IBLUETOOTHCMD(cmd) (_WLIOCVALID(cmd) && \
_IOC_NR(cmd) >= WL_BLUETOOTHFIRST && \
_IOC_NR(cmd) < (WL_BLUETOOTHFIRST + WL_BLUETOOTHCMDS))
/* Reserved for IEEE802.15.4 wireless network devices /* Reserved for IEEE802.15.4 wireless network devices
* NOTE: Not used. Currently logic uses IOCTL commands from the IEEE802.15.4 * NOTE: Not used. Currently logic uses IOCTL commands from the IEEE802.15.4
* character driver space. * character driver space.
*/ */
#define WL_802154FIRST (WL_NETFIRST + WL_NNETCMDS) #define WL_802154FIRST (WL_BLUETOOTHFIRST + WL_BLUETOOTHCMDS)
#define WL_N802154CMDS (3) #define WL_N802154CMDS (3)
#define WL_IS802154CMD(cmd) (_WLIOCVALID(cmd) && \ #define WL_IS802154CMD(cmd) (_WLIOCVALID(cmd) && \
_IOC_NR(cmd) >= WL_802154FIRST && \ _IOC_NR(cmd) >= WL_802154FIRST && \
@@ -178,25 +186,25 @@
_IOC_NR(cmd) >= WL_PKTRADIOFIRST && \ _IOC_NR(cmd) >= WL_PKTRADIOFIRST && \
_IOC_NR(cmd) < (WL_PKTRADIOFIRST + WL_NPKTRADIOCMDS)) _IOC_NR(cmd) < (WL_PKTRADIOFIRST + WL_NPKTRADIOCMDS))
/* ------------------------------- WIRELESS EVENTS ------------------------------- */ /* ------------------------------ WIRELESS EVENTS -------------------------------- */
/* Those are *NOT* ioctls, do not issue request on them !!! */ /* Those are *NOT* ioctls, do not issue request on them !!! */
/* Most events use the same identifier as ioctl requests */ /* Most events use the same identifier as ioctl requests */
#define IWEVTXDROP 0x8C00 /* Packet dropped to excessive retry */ #define IWEVTXDROP 0x8c00 /* Packet dropped to excessive retry */
#define IWEVQUAL 0x8C01 /* Quality part of statistics (scan) */ #define IWEVQUAL 0x8c01 /* Quality part of statistics (scan) */
#define IWEVCUSTOM 0x8C02 /* Driver specific ascii string */ #define IWEVCUSTOM 0x8c02 /* Driver specific ascii string */
#define IWEVREGISTERED 0x8C03 /* Discovered a new node (AP mode) */ #define IWEVREGISTERED 0x8c03 /* Discovered a new node (AP mode) */
#define IWEVEXPIRED 0x8C04 /* Expired a node (AP mode) */ #define IWEVEXPIRED 0x8c04 /* Expired a node (AP mode) */
#define IWEVGENIE 0x8C05 /* Generic IE (WPA, RSN, WMM, ..) #define IWEVGENIE 0x8c05 /* Generic IE (WPA, RSN, WMM, ..)
* (scan results); This includes id and * (scan results); This includes id and
* length fields. One IWEVGENIE may * length fields. One IWEVGENIE may
* contain more than one IE. Scan * contain more than one IE. Scan
* results may contain one or more * results may contain one or more
* IWEVGENIE events. */ * IWEVGENIE events. */
#define IWEVMICHAELMICFAILURE 0x8C06 /* Michael MIC failure #define IWEVMICHAELMICFAILURE 0x8c06 /* Michael MIC failure
* (struct iw_michaelmicfailure) * (struct iw_michaelmicfailure)
*/ */
#define IWEVASSOCREQIE 0x8C07 /* IEs used in (Re)Association Request. #define IWEVASSOCREQIE 0x8c07 /* IEs used in (Re)Association Request.
* The data includes id and length * The data includes id and length
* fields and may contain more than one * fields and may contain more than one
* IE. This event is required in * IE. This event is required in
@@ -205,18 +213,18 @@
* should be sent just before * should be sent just before
* IWEVREGISTERED event for the * IWEVREGISTERED event for the
* association. */ * association. */
#define IWEVASSOCRESPIE 0x8C08 /* IEs used in (Re)Association #define IWEVASSOCRESPIE 0x8c08 /* IEs used in (Re)Association
* Response. The data includes id and * Response. The data includes id and
* length fields and may contain more * length fields and may contain more
* than one IE. This may be sent * than one IE. This may be sent
* between IWEVASSOCREQIE and * between IWEVASSOCREQIE and
* IWEVREGISTERED events for the * IWEVREGISTERED events for the
* association. */ * association. */
#define IWEVPMKIDCAND 0x8C09 /* PMKID candidate for RSN #define IWEVPMKIDCAND 0x8c09 /* PMKID candidate for RSN
* pre-authentication * pre-authentication
* (struct iw_pmkid_cand) */ * (struct iw_pmkid_cand) */
#define IWEVFIRST 0x8C00 #define IWEVFIRST 0x8c00
#define IW_EVENT_IDX(cmd) ((cmd) - IWEVFIRST) #define IW_EVENT_IDX(cmd) ((cmd) - IWEVFIRST)
/* Other Common Wireless Definitions ***********************************************/ /* Other Common Wireless Definitions ***********************************************/
+4 -2
View File
@@ -59,8 +59,9 @@
#define PF_INET 2 /* IPv4 Internet protocols */ #define PF_INET 2 /* IPv4 Internet protocols */
#define PF_INET6 3 /* IPv6 Internet protocols */ #define PF_INET6 3 /* IPv6 Internet protocols */
#define PF_PACKET 4 /* Low level packet interface */ #define PF_PACKET 4 /* Low level packet interface */
#define PF_IEEE802154 5 /* Low level IEEE 802.15.4 radio frame interface */ #define PF_BLUETOOTH 5 /* Bluetooth sockets */
#define PF_PKTRADIO 6 /* Low level packet radio interface */ #define PF_IEEE802154 6 /* Low level IEEE 802.15.4 radio frame interface */
#define PF_PKTRADIO 7 /* Low level packet radio interface */
/* Supported Address Families. Opengroup.org requires only AF_UNSPEC, /* Supported Address Families. Opengroup.org requires only AF_UNSPEC,
* AF_UNIX, AF_INET and AF_INET6. * AF_UNIX, AF_INET and AF_INET6.
@@ -72,6 +73,7 @@
#define AF_INET PF_INET #define AF_INET PF_INET
#define AF_INET6 PF_INET6 #define AF_INET6 PF_INET6
#define AF_PACKET PF_PACKET #define AF_PACKET PF_PACKET
#define AF_BLUETOOTH PF_BLUETOOTH
#define AF_IEEE802154 PF_IEEE802154 #define AF_IEEE802154 PF_IEEE802154
#define AF_PKTRADIO PF_PKTRADIO #define AF_PKTRADIO PF_PKTRADIO
+24
View File
@@ -72,6 +72,30 @@ config BLUETOOTH_MAX_PAIRED
Maximum number of paired Bluetooth devices. The minimum (and Maximum number of paired Bluetooth devices. The minimum (and
default) number is 1. default) number is 1.
config BLUETOOTH_MAXSCANDATA
int "Max scan data size"
default 64
range 1 255
---help---
Scan results will be buffered in memory until the user requests the
scan results. This parameter specifies the maximum size of the
advertiser data that accompanies the scan result.
This contributes to a static memory allocation that will be greater
than CONFIG_BLUETOOTH_MAXSCANDATA * CONFIG_BLUETOOTH_MAXSCANRESULT
config BLUETOOTH_MAXSCANRESULT
int "Max scan results"
default 8
range 1 255
---help---
Scan results will be buffered in memory until the user requests the
scan results. This parameter specifies the maximum number of
results that can be buffered before scan results are lost.
This contributes to a static memory allocation that will be greater
than CONFIG_BLUETOOTH_MAXSCANDATA * CONFIG_BLUETOOTH_MAXSCANRESULT
menu "Kernel Thread Configuration" menu "Kernel Thread Configuration"
config BLUETOOTH_RXTHREAD_STACKSIZE config BLUETOOTH_RXTHREAD_STACKSIZE
+1 -1
View File
@@ -38,7 +38,7 @@ ifeq ($(CONFIG_WIRELESS_BLUETOOTH),y)
# Include Bluetooth support # Include Bluetooth support
CSRCS += bt_atomic.c bt_att.c bt_buf.c bt_conn.c bt_gatt.c bt_hcicore.c CSRCS += bt_atomic.c bt_att.c bt_buf.c bt_conn.c bt_gatt.c bt_hcicore.c
CSRCS += bt_keys.c bt_l2cap.c bt_queue.c bt_smp.c bt_uuid.c CSRCS += bt_ioctl.c bt_keys.c bt_l2cap.c bt_queue.c bt_smp.c bt_uuid.c
DEPPATH += --dep-path bluetooth DEPPATH += --dep-path bluetooth
VPATH += :bluetooth VPATH += :bluetooth
+1 -1
View File
@@ -44,7 +44,7 @@
#include "bt_atomic.h" #include "bt_atomic.h"
/**************************************************************************** /****************************************************************************
* Public Function * Public Functions
****************************************************************************/ ****************************************************************************/
#ifndef CONFIG_HAVE_INLINE #ifndef CONFIG_HAVE_INLINE
+1 -1
View File
@@ -54,7 +54,7 @@
typedef uint8_t bt_atomic_t; typedef uint8_t bt_atomic_t;
/**************************************************************************** /****************************************************************************
* Inline Prototypes * Inline Functions
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_HAVE_INLINE #ifdef CONFIG_HAVE_INLINE
+57
View File
@@ -1442,6 +1442,23 @@ int bt_init(void)
return bt_l2cap_init(); return bt_l2cap_init();
} }
/****************************************************************************
* Name: bt_start_advertising
*
* Description:
* Set advertisement data, scan response data, advertisement parameters
* and start advertising.
*
* Input Parameters:
* type - Advertising type.
* ad - Data to be used in advertisement packets.
* sd - Data to be used in scan response packets.
*
* Returned Value:
* Zero on success or (negative) error code otherwise.
*
****************************************************************************/
int bt_start_advertising(uint8_t type, FAR const struct bt_eir_s *ad, int bt_start_advertising(uint8_t type, FAR const struct bt_eir_s *ad,
FAR const struct bt_eir_s *sd) FAR const struct bt_eir_s *sd)
{ {
@@ -1543,6 +1560,17 @@ send_set_param:
return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_ADV_ENABLE, buf, NULL); return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_ADV_ENABLE, buf, NULL);
} }
/****************************************************************************
* Name: bt_stop_advertising
*
* Description:
* Stops ongoing advertising.
*
* Returned Value:
* Zero on success or (negative) error code otherwise.
*
****************************************************************************/
int bt_stop_advertising(void) int bt_stop_advertising(void)
{ {
FAR struct bt_buf_s *buf; FAR struct bt_buf_s *buf;
@@ -1564,6 +1592,23 @@ int bt_stop_advertising(void)
return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_ADV_ENABLE, buf, NULL); return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_ADV_ENABLE, buf, NULL);
} }
/****************************************************************************
* Name: bt_start_scanning
*
* Description:
* Start LE scanning with and provide results through the specified
* callback.
*
* Input Parameters:
* filter_dups - Enable duplicate filtering (or not).
* cb - Callback to notify scan results.
*
* Returned Value:
* Zero on success or error code otherwise, positive in case
* of protocol error or negative (POSIX) in case of stack internal error
*
****************************************************************************/
int bt_start_scanning(uint8_t scan_filter, bt_le_scan_cb_t cb) int bt_start_scanning(uint8_t scan_filter, bt_le_scan_cb_t cb)
{ {
/* Return if active scan is already enabled */ /* Return if active scan is already enabled */
@@ -1579,6 +1624,18 @@ int bt_start_scanning(uint8_t scan_filter, bt_le_scan_cb_t cb)
return bt_le_scan_update(); return bt_le_scan_update();
} }
/****************************************************************************
* Name: bt_stop_scanning
*
* Description:
* Stops ongoing LE scanning.
*
* Returned Value:
* Zero on success or error code otherwise, positive in case
* of protocol error or negative (POSIX) in case of stack internal error
*
****************************************************************************/
int bt_stop_scanning(void) int bt_stop_scanning(void)
{ {
/* Return if active scanning is already disabled */ /* Return if active scanning is already disabled */
+88
View File
@@ -139,6 +139,28 @@ struct bt_dev_s
FAR const struct bt_driver_s *dev; FAR const struct bt_driver_s *dev;
}; };
/****************************************************************************
* Name: bt_le_scan_cb_t
*
* Description:
* A function of this type will be called back when user application
* triggers active LE scan. The caller will populate all needed
* parameters based on data coming from scan result.
* Such function can be set by user when LE active scan API is used.
*
* Input Parameters:
* addr - Advertiser LE address and type.
* rssi - Strength of advertiser signal.
* adv_type - Type of advertising response from advertiser.
* adv_data - Address of buffer containing advertiser data.
* len - Length of advertiser data contained in buffer.
*
****************************************************************************/
typedef CODE void bt_le_scan_cb_t(FAR const bt_addr_le_t *addr, int8_t rssi,
uint8_t adv_type,
FAR const uint8_t *adv_data, uint8_t len);
/**************************************************************************** /****************************************************************************
* Public Data * Public Data
****************************************************************************/ ****************************************************************************/
@@ -220,4 +242,70 @@ FAR const char *bt_addr_str(FAR const bt_addr_t *addr);
FAR const char *bt_addr_le_str(FAR const bt_addr_le_t *addr); FAR const char *bt_addr_le_str(FAR const bt_addr_le_t *addr);
#endif #endif
/****************************************************************************
* Name: bt_start_advertising
*
* Description:
* Set advertisement data, scan response data, advertisement parameters
* and start advertising.
*
* Input Parameters:
* type - Advertising type.
* ad - Data to be used in advertisement packets.
* sd - Data to be used in scan response packets.
*
* Returned Value:
* Zero on success or (negative) error code otherwise.
*
****************************************************************************/
int bt_start_advertising(uint8_t type, FAR const struct bt_eir_s *ad,
FAR const struct bt_eir_s *sd);
/****************************************************************************
* Name: bt_stop_advertising
*
* Description:
* Stops ongoing advertising.
*
* Returned Value:
* Zero on success or (negative) error code otherwise.
*
****************************************************************************/
int bt_stop_advertising(void);
/****************************************************************************
* Name: bt_start_scanning
*
* Description:
* Start LE scanning with and provide results through the specified
* callback.
*
* Input Parameters:
* filter_dups - Enable duplicate filtering (or not).
* cb - Callback to notify scan results.
*
* Returned Value:
* Zero on success or error code otherwise, positive in case
* of protocol error or negative (POSIX) in case of stack internal error
*
****************************************************************************/
int bt_start_scanning(uint8_t filter_dups, bt_le_scan_cb_t cb);
/****************************************************************************
* Name: bt_stop_scanning
*
* Description:
* Stops ongoing LE scanning.
*
* Returned Value:
* Zero on success or error code otherwise, positive in case
* of protocol error or negative (POSIX) in case of stack internal error
*
****************************************************************************/
int bt_stop_scanning(void);
#endif /* __WIRELESS_BLUETOOTH_BT_HDICORE_H */ #endif /* __WIRELESS_BLUETOOTH_BT_HDICORE_H */
+406
View File
@@ -0,0 +1,406 @@
/****************************************************************************
* wireless/bluetooth/bt_ioctl.c
* Bluetooth network IOCTL handler
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 NuttX 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 OWNER 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/wqueue.h>
#include <nuttx/semaphore.h>
#include <nuttx/net/netdev.h>
#include <nuttx/wireless/bt_core.h>
#include <nuttx/wireless/bt_hci.h>
#include <nuttx/wireless/bt_ioctl.h>
#include "bt_hcicore.h"
#include "bt_ioctl.h"
#ifdef CONFIG_NETDEV_IOCTL /* Not optional! */
/****************************************************************************
* Public Types
****************************************************************************/
/* This structure encapsulates all globals used by the IOCTL logic */
struct bt_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) */
uint8_t bs_tail; /* Tail of circular list (for addition) */
struct bt_scanresponse_s bs_rsp[CONFIG_BLUETOOTH_MAXSCANRESULT];
};
/****************************************************************************
* Private Data
****************************************************************************/
/* At present only a single Bluetooth device is supported. So we can simply
* maintain the scan state as a global.
*/
static struct bt_scanstate_s g_scanstate;
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: bt_scan_callback
*
* Description:
* This is an HCI callback function. HCI provides scan result data via
* this callback function. The scan result data will be added to the
* cached scan results.
*
* Input Parameters:
* Scan result data
*
* Returned Value:
* None
*
****************************************************************************/
static void bt_scan_callback(FAR const bt_addr_le_t *addr, int8_t rssi,
uint8_t adv_type, FAR const uint8_t *adv_data,
uint8_t len)
{
FAR struct bt_scanresponse_s *rsp;
uint8_t nexttail;
uint8_t head;
uint8_t tail;
int ret;
if (!g_scanstate.bs_scanning)
{
wlerr("ERROR: Results received while not scanning\n");
return;
}
if (len > CONFIG_BLUETOOTH_MAXSCANDATA)
{
wlerr("ERROR: Scan result is too big: %u\n", len);
return;
}
/* Get exclusive access to the scan data */
while ((ret = nxsem_wait(&g_scanstate.bs_exclsem)) < 0)
{
DEBUGASSERT(ret == -EINTR || ret == -ECANCELED);
if (ret != -EINTR)
{
return;
}
}
/* Add the scan data to the cache */
tail = g_scanstate.bs_tail;
nexttail = tail + 1;
if (nexttail >= CONFIG_BLUETOOTH_MAXSCANRESULT)
{
nexttail = 0;
}
/* Is the circular buffer full? */
head = g_scanstate.bs_head;
if (nexttail == head)
{
wlerr("ERROR: Too many scan results\n");
if (++head >= CONFIG_BLUETOOTH_MAXSCANRESULT)
{
head = 0;
}
g_scanstate.bs_head = head;
}
/* Save the new scan result */
rsp = &g_scanstate.bs_rsp[tail];
memcpy(&rsp->sr_addr, addr, sizeof(bt_addr_le_t));
rsp->sr_rssi = rssi;
rsp->sr_type = adv_type;
rsp->sr_len = len;
memcpy(&rsp->sr_data, adv_data, len);
g_scanstate.bs_tail = nexttail;
nxsem_post(&g_scanstate.bs_exclsem);
}
/****************************************************************************
* Name: bt_scan_result
*
* Description:
* This is an HCI callback function. HCI provides scan result data via
* this callback function. The scan result data will be added to the
* cached scan results.
*
* Input Parameters:
* Scan result data
*
* Returned Value:
* None
*
****************************************************************************/
static int bt_scan_result(FAR struct bt_scanresult_s *result)
{
uint8_t head;
uint8_t tail;
uint8_t maxrsp;
uint8_t nrsp;
int ret;
if (!g_scanstate.bs_scanning)
{
wlerr("ERROR: Results received while not scanning\n");
return -EPIPE;
}
/* Get exclusive access to the scan data */
ret = nxsem_wait(&g_scanstate.bs_exclsem);
if (ret < 0)
{
DEBUGASSERT(ret == -EINTR || ret == -ECANCELED);
return ret;
}
/* Copy all available results */
head = g_scanstate.bs_head;
tail = g_scanstate.bs_tail;
maxrsp = result->sc_nrsp;
for (nrsp = 0; nrsp < maxrsp && head != tail; nrsp++)
{
FAR const uint8_t *src;
FAR uint8_t *dest;
/* Copy data from the head index into the user buffer */
src = (FAR const uint8_t *)&g_scanstate.bs_rsp[head];
dest = (FAR uint8_t *)&result->sc_rsp[nrsp];
memcpy(dest, src, sizeof(struct bt_scanresponse_s));
/* Increment the head index */
if (++head >= CONFIG_BLUETOOTH_MAXSCANRESULT)
{
head = 0;
}
}
g_scanstate.bs_head = head;
result->sc_nrsp = nrsp;
nxsem_post(&g_scanstate.bs_exclsem);
return OK;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: bt_ioctl
*
* Description:
* Handle network IOCTL commands directed to this device.
*
* Input Parameters:
* dev - Reference to the NuttX driver state structure
* cmd - The IOCTL command
* arg - The argument for the IOCTL command
*
* Returned Value:
* OK on success; Negated errno on failure.
*
****************************************************************************/
int bt_ioctl(FAR struct net_driver_s *dev, int cmd, unsigned long arg)
{
int ret;
wlinfo("cmd=%04x arg=%ul\n", cmd, arg);
DEBUGASSERT(dev != NULL && dev->d_private != NULL);
switch (cmd)
{
/* SIOCBT_ADVERTISESTART
* Description: Set advertisement data, scan response data,
* advertisement parameters and start advertising.
* Input: Pointer to read-write instance of struct
* bt_advertisestart_s.
* Output: None
*/
case SIOCBT_ADVERTISESTART:
{
FAR struct bt_advertisestart_s *adv =
(FAR struct bt_advertisestart_s *)((uintptr_t)arg);
if (adv == NULL)
{
ret = -EINVAL;
}
else
{
ret = bt_start_advertising(adv->as_type, &adv->as_ad,
&adv->as_sd);
wlinfo("Start advertising: %d\n", ret);
}
}
break;
/* SIOCBT_ADVERTISESTOP
* Description: Stop advertising.
* Input: None
* Output: None
*/
case SIOCBT_ADVERTISESTOP:
{
wlinfo("Stop advertising\n");
bt_stop_advertising();
ret = OK;
}
break;
/* SIOCBT_SCANSTART
* Description: Start LE scanning. Buffered scan results may be
* obtained via SIOCBT_SCANGET
* Input: 1=Duplicate filtering enabled
* Output: None
*/
case SIOCBT_SCANSTART:
{
uint8_t dup_enable = (arg == 0) ? 0 : BT_LE_SCAN_FILTER_DUP_ENABLE;
/* Are we already scanning? */
if (g_scanstate.bs_scanning)
{
ret = -EBUSY;
}
else
{
/* Initialize scan state */
nxsem_init(&g_scanstate.bs_exclsem, 0, 1);
g_scanstate.bs_scanning = true;
g_scanstate.bs_head = 0;
g_scanstate.bs_tail = 0;
ret = bt_start_scanning(dup_enable, bt_scan_callback);
wlinfo("Start scan: %d\n", ret);
if (ret < 0)
{
nxsem_destroy(&g_scanstate.bs_exclsem);
g_scanstate.bs_scanning = false;
}
}
}
break;
/* SIOCBT_SCANGET
* Description: Return scan results buffered since the call time
* that the SIOCBT_SCANGET command was invoked.
* Input: A reference to a write-able instance of struct
* bt_scanresult_s.
* Output: Buffered scan result results are returned in the
* user-provided buffer space.
*/
case SIOCBT_SCANGET:
{
FAR struct bt_scanresult_s *result =
(FAR struct bt_scanresult_s *)((uintptr_t)arg);
if (result == NULL)
{
ret = -EINVAL;
}
else
{
ret = bt_scan_result(result);
wlinfo("Get scan results: %d\n", ret);
}
}
break;
/* SIOCBT_SCANSTOP
* Description: Stop LE scanning and discard any buffered results.
* Input: None
* Output: None
*/
case SIOCBT_SCANSTOP:
{
/* Stop scanning */
ret = bt_stop_scanning();
wlinfo("Stop scanning: %d\n", ret);
nxsem_destroy(&g_scanstate.bs_exclsem);
g_scanstate.bs_scanning = false;
}
break;
default:
wlwarn("WARNING: Unrecognized IOCTL command: %02x\n", cmd);
ret = -ENOTTY;
break;
}
return ret;
}
#endif /* CONFIG_NETDEV_IOCTL */
+73
View File
@@ -0,0 +1,73 @@
/****************************************************************************
* wireless/bluetooth/bt_ioctl.h
* Bluetooth network IOCTL handler
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 NuttX 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 OWNER 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_IOCTL_H
#define __WIRELESS_BLUETOOTH_BT_IOCTL_H 1
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
/****************************************************************************
* Public Types
****************************************************************************/
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: bt_ioctl
*
* Description:
* Handle network IOCTL commands directed to this device.
*
* Input Parameters:
* dev - Reference to the NuttX driver state structure
* cmd - The IOCTL command
* arg - The argument for the IOCTL command
*
* Returned Value:
* OK on success; Negated errno on failure.
*
****************************************************************************/
struct net_driver_s; /* Forward reference */
int bt_ioctl(FAR struct net_driver_s *dev, int cmd, unsigned long arg);
#endif /* __WIRELESS_BLUETOOTH_BT_IOCTL_H */