svn commit: r333110 - head/lib/libbluetooth

Vladimir Kondratyev wulf at FreeBSD.org
Mon Apr 30 10:24:51 UTC 2018


Author: wulf
Date: Mon Apr 30 10:24:50 2018
New Revision: 333110
URL: https://svnweb.freebsd.org/changeset/base/333110

Log:
  bluetooth(3): Add helper functions that performs Bluetooth Remote Name Request
  procedure to obtain the user-friendly name of another Bluetooth unit.
  
  Reviewed by:	emax, wblock (docs)
  Differential Revision:	https://reviews.freebsd.org/D13456

Modified:
  head/lib/libbluetooth/bluetooth.3
  head/lib/libbluetooth/bluetooth.h
  head/lib/libbluetooth/hci.c

Modified: head/lib/libbluetooth/bluetooth.3
==============================================================================
--- head/lib/libbluetooth/bluetooth.3	Mon Apr 30 10:15:58 2018	(r333109)
+++ head/lib/libbluetooth/bluetooth.3	Mon Apr 30 10:24:50 2018	(r333110)
@@ -25,7 +25,7 @@
 .\" $Id: bluetooth.3,v 1.5 2003/05/20 23:04:30 max Exp $
 .\" $FreeBSD$
 .\"
-.Dd April 9, 2009
+.Dd April 30, 2018
 .Dt BLUETOOTH 3
 .Os
 .Sh NAME
@@ -58,6 +58,8 @@
 .Nm bt_devfilter_evt_clr ,
 .Nm bt_devfilter_evt_tst ,
 .Nm bt_devinquiry ,
+.Nm bt_devremote_name ,
+.Nm bt_devremote_name_gen ,
 .Nm bdaddr_same ,
 .Nm bdaddr_any ,
 .Nm bdaddr_copy
@@ -126,6 +128,11 @@
 .Fn bt_devfilter_evt_tst "struct bt_devfilter const *filter" "uint8_t event"
 .Ft int
 .Fn bt_devinquiry "char const *devname" "time_t length" "int num_rsp" "struct bt_devinquiry **ii"
+.Ft char *
+.Fn bt_devremote_name "char const *devname" "const bdaddr_t *remote" \
+"time_t to" "uint16_t clk_off" "uint8_t ps_rep_mode" "uint8_t ps_mode"
+.Ft char *
+.Fn bt_devremote_name_gen "char const *devname" "const bdaddr_t *remote"
 .Ft int
 .Fn bdaddr_same "const bdaddr_t *a" "const bdaddr_t *b"
 .Ft int
@@ -589,8 +596,54 @@ struct bt_devinquiry {
 .Ed
 .Pp
 The
+.Fn bt_devremote_name
+function performs Bluetooth Remote Name Request procedure to obtain the
+user-friendly name of another Bluetooth unit.
+The
+.Fa devname
+parameter specifies which local Bluetooth device should perform the request.
+If not specified
+.Dv ( NULL ) ,
+the first available device is used.
+The
+.Fa remote
+parameter specifies the Bluetooth BD_ADDR of the remote device to query.
+The
+.Fa to
+parameter specifies response timeout in seconds.
+If not specified (0), the default value is taken from the
+net.bluetooth.hci.command_timeout
+.Xr sysctl 8
+value.
+The
+.Fa clk_off ,
+.Fa ps_rep_mode ,
+and
+.Fa ps_mode
+parameters specify Clock_Offset, Page_Scan_Repetition_Mode, and Page_Scan_Mode
+fields of HCI_Remote_Name_Request respectively.
+On success, the function returns a pointer to dynamically allocated
+NUL-terminated string or
+.Dv NULL
+if an error occurred.
+It is up to the caller to release returned string using
+.Xr free 3 .
+.Pp
+The
+.Fn bt_devremote_name_gen
+function is a shortcut to
+.Fn bt_devremote_name
+that passes generic defaults for
+.Fa to ,
+.Fa clk_off ,
+.Fa ps_rep_mode ,
+and
+.Fa ps_mode
+parameters.
+.Pp
+The
 .Fn bdaddr_same ,
-.Fn bdaddr_any
+.Fn bdaddr_any ,
 and
 .Fn bdaddr_copy
 are handy shorthand Bluetooth address utility functions.

Modified: head/lib/libbluetooth/bluetooth.h
==============================================================================
--- head/lib/libbluetooth/bluetooth.h	Mon Apr 30 10:15:58 2018	(r333109)
+++ head/lib/libbluetooth/bluetooth.h	Mon Apr 30 10:24:50 2018	(r333110)
@@ -182,8 +182,18 @@ void		bt_devfilter_evt_clr(struct bt_devfilter *filter
 int		bt_devfilter_evt_tst(struct bt_devfilter const *filter, uint8_t event);
 int		bt_devinquiry(char const *devname, time_t length, int num_rsp,
 			      struct bt_devinquiry **ii);
+char *		bt_devremote_name(char const *devname, const bdaddr_t *remote,
+				  time_t to, uint16_t clk_off,
+				  uint8_t ps_rep_mode, uint8_t ps_mode);
 int		bt_devinfo (struct bt_devinfo *di);
 int		bt_devenum (bt_devenum_cb_t cb, void *arg);
+
+static __inline char *
+bt_devremote_name_gen(char const *devname, const bdaddr_t *remote)
+{
+	return (bt_devremote_name(devname, remote, 0, 0x0000,
+		NG_HCI_SCAN_REP_MODE0, NG_HCI_MANDATORY_PAGE_SCAN_MODE));
+}
 
 /*
  * bdaddr utility functions (from NetBSD)

Modified: head/lib/libbluetooth/hci.c
==============================================================================
--- head/lib/libbluetooth/hci.c	Mon Apr 30 10:15:58 2018	(r333109)
+++ head/lib/libbluetooth/hci.c	Mon Apr 30 10:24:50 2018	(r333110)
@@ -32,6 +32,9 @@
  * $FreeBSD$
  */
 
+#include <sys/types.h>
+#include <sys/sysctl.h>
+
 #include <assert.h>
 #define L2CAP_SOCKET_CHECKED
 #include <bluetooth.h>
@@ -39,6 +42,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <time.h>
 #include <unistd.h>
 
 #undef	MIN
@@ -46,6 +50,7 @@
 
 static int    bt_devany_cb(int s, struct bt_devinfo const *di, void *xdevname);
 static char * bt_dev2node (char const *devname, char *nodename, int nnlen);
+static time_t bt_get_default_hci_command_timeout(void);
 
 int
 bt_devopen(char const *devname)
@@ -534,6 +539,63 @@ wait_for_more:
 	return (i - *ii);
 }
 
+char *
+bt_devremote_name(char const *devname, const bdaddr_t *remote, time_t to,
+    uint16_t clk_off, uint8_t ps_rep_mode, uint8_t ps_mode)
+{
+	char				 _devname[HCI_DEVNAME_SIZE];
+	struct bt_devreq		 r;
+	ng_hci_remote_name_req_cp	 cp;
+	ng_hci_remote_name_req_compl_ep	 ep;
+	int				 s;
+	char				*remote_name = NULL;
+
+	if (remote == NULL || to < 0) {
+		errno = EINVAL;
+		goto out;
+	}
+
+	if (to == 0) {
+		to = bt_get_default_hci_command_timeout();
+		if (to < 0)
+			goto out;
+	}
+	to++;
+
+	if (devname == NULL) {
+		memset(_devname, 0, sizeof(_devname));
+		devname = _devname;
+		if (bt_devenum(bt_devany_cb, _devname) <= 0)
+			goto out;
+        }
+
+	memset(&r, 0, sizeof(r));
+	memset(&cp, 0, sizeof(cp));
+	memset(&ep, 0, sizeof(ep));
+	cp.clock_offset = htole16(clk_off);
+	cp.page_scan_rep_mode = ps_rep_mode;
+	cp.page_scan_mode = ps_mode;
+	bdaddr_copy(&cp.bdaddr, remote);
+	r.opcode = NG_HCI_OPCODE(NG_HCI_OGF_LINK_CONTROL,
+				 NG_HCI_OCF_REMOTE_NAME_REQ);
+	r.event = NG_HCI_EVENT_REMOTE_NAME_REQ_COMPL;
+	r.cparam = &cp;
+	r.clen = sizeof(cp);
+	r.rparam = &ep;
+	r.rlen = sizeof(ep);
+
+	s = bt_devopen(devname);
+	if (s < 0)
+		goto out;
+
+	if (bt_devreq(s, &r, to) == 0 || ep.status == 0x00)
+		remote_name = strndup((const char *)&ep.name, sizeof(ep.name));
+
+	bt_devclose(s);
+out:
+	return (remote_name);
+}
+
 int
 bt_devinfo(struct bt_devinfo *di)
 {
@@ -735,3 +797,21 @@ bt_dev2node(char const *devname, char *nodename, int n
 	return (NULL);
 }
 
+static time_t
+bt_get_default_hci_command_timeout(void)
+{
+	int	to;
+	size_t	to_size = sizeof(to);
+
+	if (sysctlbyname("net.bluetooth.hci.command_timeout",
+			 &to, &to_size, NULL, 0) < 0)
+		return (-1);
+
+	/* Should not happen */
+	if (to <= 0) {
+		errno = ERANGE;
+		return (-1);
+	}
+
+	return ((time_t)to);
+}


More information about the svn-src-head mailing list