aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/bluetooth
diff options
context:
space:
mode:
authorHans Petter Selasky <hselasky@FreeBSD.org>2020-04-24 08:07:59 +0000
committerHans Petter Selasky <hselasky@FreeBSD.org>2020-04-24 08:07:59 +0000
commitc3f60abc3046fd893dfbcbd84f05c3b5d3b883b6 (patch)
tree835f671b2004a98d45f69877fc600633d50250b3 /usr.sbin/bluetooth
parent36b9e628315ba11c259a6c49f318d5acaedc9ec5 (diff)
downloadsrc-c3f60abc3046fd893dfbcbd84f05c3b5d3b883b6.tar.gz
src-c3f60abc3046fd893dfbcbd84f05c3b5d3b883b6.zip
Add support for LE advertising to hccontrol(8).
Submitted by: Marc Veldman <marc@bumblingdork.com> PR: 245848 MFC after: 1 week Sponsored by: Mellanox Technologies
Notes
Notes: svn path=/head/; revision=360243
Diffstat (limited to 'usr.sbin/bluetooth')
-rw-r--r--usr.sbin/bluetooth/hccontrol/hccontrol.825
-rw-r--r--usr.sbin/bluetooth/hccontrol/le.c194
2 files changed, 218 insertions, 1 deletions
diff --git a/usr.sbin/bluetooth/hccontrol/hccontrol.8 b/usr.sbin/bluetooth/hccontrol/hccontrol.8
index 8e12f312a19b..a31118b66895 100644
--- a/usr.sbin/bluetooth/hccontrol/hccontrol.8
+++ b/usr.sbin/bluetooth/hccontrol/hccontrol.8
@@ -25,7 +25,7 @@
.\" $Id: hccontrol.8,v 1.6 2003/08/06 21:26:38 max Exp $
.\" $FreeBSD$
.\"
-.Dd February 7, 2015
+.Dd April 24, 2020
.Dt HCCONTROL 8
.Os
.Sh NAME
@@ -133,6 +133,8 @@ are:
.It Cm Write_Page_Scan_Period_Mode
.It Cm Read_Page_Scan_Mode
.It Cm Write_Page_Scan_Mode
+.It Cm Read_LE_Host_Support
+.It Cm Write_LE_Host_Support
.It Cm Read_Local_Version_Information
.It Cm Read_Local_Supported_Commands
.It Cm Read_Local_Supported_Features
@@ -143,6 +145,15 @@ are:
.It Cm Reset_Failed_Contact_Counter
.It Cm Get_Link_Quality
.It Cm Read_RSSI
+.It Cm LE_Read_Local_Supported_Features
+.It Cm LE_Set_Advertising_Parameters
+.It Cm LE_Read_Advertising_Physical_Channel_Tx_Power
+.It Cm LE_Set_Advertising_Data
+.It Cm LE_Set_Scan_Response_Data
+.It Cm LE_Set_Advertising_Enable
+.It Cm LE_Set_Scan_Parameters
+.It Cm LE_Set_Scan_Enable
+.It Cm LE_Read_Supported_States
.El
.Pp
The currently supported node commands in
@@ -170,6 +181,18 @@ are:
.It Cm Write_Node_Role_Switch
.It Cm Read_Node_List
.El
+.Sh EXAMPLES
+Make the blutooth LE host, ubt0hci, scannable through
+.Xr hccontrol 8 commands:
+.Pp
+.Bd -literal -offset indent
+hccontrol -n ubt0hci le_set_advertising_enable disable
+hccontrol -n ubt0hci le_set_advertising_param
+hccontrol -n ubt0hci le_read_advertising_channel_tx_power
+hccontrol -n ubt0hci le_set_advertising_data
+hccontrol -n ubt0hci le_set_scan_response -n FBSD_Host
+hccontrol -n ubt0hci le_set_advertising_enable enable
+.Ed
.Sh EXIT STATUS
.Ex -std
.Sh SEE ALSO
diff --git a/usr.sbin/bluetooth/hccontrol/le.c b/usr.sbin/bluetooth/hccontrol/le.c
index d49026b53e1c..236ce7896f9e 100644
--- a/usr.sbin/bluetooth/hccontrol/le.c
+++ b/usr.sbin/bluetooth/hccontrol/le.c
@@ -57,6 +57,9 @@ static int le_read_local_supported_features(int s, int argc ,char *argv[]);
static int set_le_event_mask(int s, uint64_t mask);
static int set_event_mask(int s, uint64_t mask);
static int le_enable(int s, int argc, char *argv[]);
+static int le_set_advertising_enable(int s, int argc, char *argv[]);
+static int le_set_advertising_param(int s, int argc, char *argv[]);
+static int le_read_advertising_channel_tx_power(int s, int argc, char *argv[]);
static int
le_set_scan_param(int s, int argc, char *argv[])
@@ -339,6 +342,170 @@ int le_enable(int s, int argc, char *argv[])
return OK;
}
+static int
+le_set_advertising_enable(int s, int argc, char *argv[])
+{
+ ng_hci_le_set_advertise_enable_cp cp;
+ ng_hci_le_set_advertise_enable_rp rp;
+ int n, enable = 0;
+
+ if (argc != 1)
+ return USAGE;
+
+ if (strcmp(argv[0], "enable") == 0)
+ enable = 1;
+ else if (strcmp(argv[0], "disable") != 0)
+ return USAGE;
+
+ n = sizeof(rp);
+ cp.advertising_enable = enable;
+ if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LE,
+ NG_HCI_OCF_LE_SET_ADVERTISE_ENABLE),
+ (void *)&cp, sizeof(cp), (void *)&rp, &n) == ERROR)
+ return (ERROR);
+
+ if (rp.status != 0x00) {
+ fprintf(stdout, "Status: %s [%#02x]\n",
+ hci_status2str(rp.status), rp.status);
+ return (FAILED);
+ }
+ fprintf(stdout, "LE Advertising %s\n", (enable ? "enabled" : "disabled"));
+
+ return (OK);
+}
+
+static int
+le_set_advertising_param(int s, int argc, char *argv[])
+{
+ ng_hci_le_set_advertising_parameters_cp cp;
+ ng_hci_le_set_advertising_parameters_rp rp;
+
+ int n, ch;
+
+ cp.advertising_interval_min = 0x800;
+ cp.advertising_interval_max = 0x800;
+ cp.advertising_type = 0;
+ cp.own_address_type = 0;
+ cp.direct_address_type = 0;
+
+ cp.advertising_channel_map = 7;
+ cp.advertising_filter_policy = 0;
+
+ optreset = 1;
+ optind = 0;
+ while ((ch = getopt(argc, argv , "m:M:t:o:p:a:c:f:")) != -1) {
+ switch(ch) {
+ case 'm':
+ cp.advertising_interval_min =
+ (uint16_t)(strtod(optarg, NULL)/0.625);
+ break;
+ case 'M':
+ cp.advertising_interval_max =
+ (uint16_t)(strtod(optarg, NULL)/0.625);
+ break;
+ case 't':
+ cp.advertising_type =
+ (uint8_t)strtod(optarg, NULL);
+ break;
+ case 'o':
+ cp.own_address_type =
+ (uint8_t)strtod(optarg, NULL);
+ break;
+ case 'p':
+ cp.direct_address_type =
+ (uint8_t)strtod(optarg, NULL);
+ break;
+ case 'a':
+ if (!bt_aton(optarg, &cp.direct_address)) {
+ struct hostent *he = NULL;
+
+ if ((he = bt_gethostbyname(optarg)) == NULL)
+ return (USAGE);
+
+ memcpy(&cp.direct_address, he->h_addr, sizeof(cp.direct_address));
+ }
+ break;
+ case 'c':
+ cp.advertising_channel_map =
+ (uint8_t)strtod(optarg, NULL);
+ break;
+ case 'f':
+ cp.advertising_filter_policy =
+ (uint8_t)strtod(optarg, NULL);
+ break;
+ }
+ }
+
+ n = sizeof(rp);
+ if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LE,
+ NG_HCI_OCF_LE_SET_ADVERTISING_PARAMETERS),
+ (void *)&cp, sizeof(cp), (void *)&rp, &n) == ERROR)
+ return (ERROR);
+
+ if (rp.status != 0x00) {
+ fprintf(stdout, "Status: %s [%#02x]\n",
+ hci_status2str(rp.status), rp.status);
+ return (FAILED);
+ }
+
+ return (OK);
+}
+
+static int
+le_read_advertising_channel_tx_power(int s, int argc, char *argv[])
+{
+ ng_hci_le_read_advertising_channel_tx_power_rp rp;
+ int n;
+
+ n = sizeof(rp);
+
+ if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LE,
+ NG_HCI_OCF_LE_READ_ADVERTISING_CHANNEL_TX_POWER),
+ (void *)&rp, &n) == ERROR)
+ return (ERROR);
+
+ if (rp.status != 0x00) {
+ fprintf(stdout, "Status: %s [%#02x]\n",
+ hci_status2str(rp.status), rp.status);
+ return (FAILED);
+ }
+
+ fprintf(stdout, "Advertising transmit power level: %d dBm\n",
+ (int8_t)rp.transmit_power_level);
+
+ return (OK);
+}
+
+static int
+le_set_advertising_data(int s, int argc, char *argv[])
+{
+ ng_hci_le_set_advertising_data_cp cp;
+ ng_hci_le_set_advertising_data_rp rp;
+ int n, len;
+
+ n = sizeof(rp);
+
+ char buf[NG_HCI_ADVERTISING_DATA_SIZE];
+
+ len = sizeof(buf);
+ parse_param(argc, argv, buf, &len);
+ memset(cp.advertising_data, 0, sizeof(cp.advertising_data));
+ cp.advertising_data_length = len;
+
+ if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LE,
+ NG_HCI_OCF_LE_SET_ADVERTISING_DATA),
+ (void *)&cp, sizeof(cp), (void *)&rp, &n) == ERROR)
+ return (ERROR);
+
+ if (rp.status != 0x00) {
+ fprintf(stdout, "Status: %s [%#02x]\n",
+ hci_status2str(rp.status), rp.status);
+ return (FAILED);
+ }
+
+ return (OK);
+}
+
struct hci_command le_commands[] = {
{
"le_enable",
@@ -378,4 +545,31 @@ struct hci_command le_commands[] = {
"set LE device scan parameter",
&le_set_scan_param
},
+ {
+ "le_set_advertising_enable",
+ "le_set_advertising_enable [enable|disable] \n"
+ "start or stop advertising",
+ &le_set_advertising_enable
+ },
+ {
+ "le_read_advertising_channel_tx_power",
+ "le_read_advertising_channel_tx_power\n"
+ "read host advertising transmit poser level (dBm)",
+ &le_read_advertising_channel_tx_power
+ },
+ {
+ "le_set_advertising_param",
+ "le_set_advertising_param [-m min_interval(ms)] [-M max_interval(ms)]\n"
+ "[-t advertising_type] [-o own_address_type] [-p peer_address_type]\n"
+ "[-c advertising_channel_map] [-f advertising_filter_policy]\n"
+ "[-a peer_address]\n"
+ "set LE device advertising parameters",
+ &le_set_advertising_param
+ },
+ {
+ "le_set_advertising_data",
+ "le_set_advertising_data -n $name -f $flag -u $uuid16,$uuid16 \n"
+ "set LE device advertising packed data",
+ &le_set_advertising_data
+ },
};