diff options
author | Vladimir Kondratyev <wulf@FreeBSD.org> | 2018-04-30 10:24:50 +0000 |
---|---|---|
committer | Vladimir Kondratyev <wulf@FreeBSD.org> | 2018-04-30 10:24:50 +0000 |
commit | 3ee5c55415a7b08c6c4c403cc6b96e30d768e1c9 (patch) | |
tree | 0fd1f605ffbc446c2623037338ccb74f3c799a40 /lib/libbluetooth | |
parent | 515bb54c9f5929ce78dc9dff41edcae337e9bb14 (diff) | |
download | src-3ee5c55415a7b08c6c4c403cc6b96e30d768e1c9.tar.gz src-3ee5c55415a7b08c6c4c403cc6b96e30d768e1c9.zip |
Notes
Diffstat (limited to 'lib/libbluetooth')
-rw-r--r-- | lib/libbluetooth/bluetooth.3 | 57 | ||||
-rw-r--r-- | lib/libbluetooth/bluetooth.h | 10 | ||||
-rw-r--r-- | lib/libbluetooth/hci.c | 80 |
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); +} |