mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-07 00:50:50 +00:00
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
This commit is contained in:
parent
515bb54c9f
commit
3ee5c55415
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=333110
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
*/
|
||||
|
|
|
@ -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 @@ bt_devinquiry(char const *devname, time_t length, int num_rsp,
|
|||
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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue