Date: Mon, 30 Apr 2018 10:24:50 +0000 (UTC) From: Vladimir Kondratyev <wulf@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r333110 - head/lib/libbluetooth Message-ID: <201804301024.w3UAOoIq006240@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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); +}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201804301024.w3UAOoIq006240>