aboutsummaryrefslogtreecommitdiff
path: root/lib/libbluetooth
diff options
context:
space:
mode:
authorVladimir Kondratyev <wulf@FreeBSD.org>2018-04-30 10:24:50 +0000
committerVladimir Kondratyev <wulf@FreeBSD.org>2018-04-30 10:24:50 +0000
commit3ee5c55415a7b08c6c4c403cc6b96e30d768e1c9 (patch)
tree0fd1f605ffbc446c2623037338ccb74f3c799a40 /lib/libbluetooth
parent515bb54c9f5929ce78dc9dff41edcae337e9bb14 (diff)
downloadsrc-3ee5c55415a7b08c6c4c403cc6b96e30d768e1c9.tar.gz
src-3ee5c55415a7b08c6c4c403cc6b96e30d768e1c9.zip
Notes
Diffstat (limited to 'lib/libbluetooth')
-rw-r--r--lib/libbluetooth/bluetooth.357
-rw-r--r--lib/libbluetooth/bluetooth.h10
-rw-r--r--lib/libbluetooth/hci.c80
3 files changed, 145 insertions, 2 deletions
diff --git a/lib/libbluetooth/bluetooth.3 b/lib/libbluetooth/bluetooth.3
index 482c73285936..c7012d8fd27b 100644
--- a/lib/libbluetooth/bluetooth.3
+++ b/lib/libbluetooth/bluetooth.3
@@ -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.
diff --git a/lib/libbluetooth/bluetooth.h b/lib/libbluetooth/bluetooth.h
index ea97ab01ab37..a19828f1036c 100644
--- a/lib/libbluetooth/bluetooth.h
+++ b/lib/libbluetooth/bluetooth.h
@@ -182,9 +182,19 @@ void bt_devfilter_evt_clr(struct bt_devfilter *filter, uint8_t event);
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)
*/
diff --git a/lib/libbluetooth/hci.c b/lib/libbluetooth/hci.c
index 9f0bdbe75969..3a524cebc3ae 100644
--- a/lib/libbluetooth/hci.c
+++ b/lib/libbluetooth/hci.c
@@ -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 nnlen)
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);
+}