bthidd(8): Add internal support for user-friendly name of remote devices.

Extend bthidd.conf format to store name of remote Bluetooth HID devices and
implement querying of this information with bthidcontrol(8) "Query" command.

Reviewed by:		emax
Differential Revision:	https://reviews.freebsd.org/D13456
This commit is contained in:
Vladimir Kondratyev 2018-04-30 10:49:29 +00:00
parent 4b58fa1240
commit e650806966
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=333112
6 changed files with 58 additions and 8 deletions

View File

@ -7,7 +7,8 @@ PROG= bthidcontrol
MAN= bthidcontrol.8
SRCS= bthidcontrol.c hid.c lexer.l parser.y sdp.c
WARNS?= 1
CFLAGS+= -DBTHIDCONTROL=1 -I${.CURDIR:H}/bthidd
CFLAGS+= -DBTHIDCONTROL=1 -I${.CURDIR:H}/bthidd -I${SRCTOP}/lib/libsdp \
-I${SRCTOP}/lib/libbluetooth
LIBADD+= bluetooth sdp usbhid

View File

@ -31,7 +31,9 @@
* $FreeBSD$
*/
#include <sys/types.h>
#include <sys/queue.h>
#include <sys/sysctl.h>
#define L2CAP_SOCKET_CHECKED
#include <bluetooth.h>
#include <dev/usb/usb.h>
@ -114,13 +116,15 @@ hid_init_return_values() {
static int32_t
hid_sdp_query(bdaddr_t const *local, struct hid_device *hd, int32_t *error)
{
void *ss = NULL;
uint8_t *hid_descriptor = NULL, *v;
int32_t i, control_psm = -1, interrupt_psm = -1,
reconnect_initiate = -1,
normally_connectable = 0, battery_power = 0,
hid_descriptor_length = -1, type;
int16_t vendor_id = 0, product_id = 0, version = 0;
void *ss = NULL;
uint8_t *hid_descriptor = NULL, *v;
int32_t i, control_psm = -1, interrupt_psm = -1,
reconnect_initiate = -1,
normally_connectable = 0, battery_power = 0,
hid_descriptor_length = -1, type;
int16_t vendor_id = 0, product_id = 0, version = 0;
bdaddr_t sdp_local;
char devname[HCI_DEVNAME_SIZE];
if (local == NULL)
local = NG_HCI_BDADDR_ANY;
@ -175,6 +179,11 @@ hid_sdp_query(bdaddr_t const *local, struct hid_device *hd, int32_t *error)
if (sdp_search(ss, 1, &service_devid, 1, &attrs_devid, nvalues, values) != 0)
hid_sdp_query_exit(sdp_error(ss));
/* Try extract HCI bdaddr from opened SDP session */
if (sdp_get_lcaddr(ss, &sdp_local) != 0 ||
bt_devname(devname, &sdp_local) == 0)
hid_sdp_query_exit(ENOATTR);
sdp_close(ss);
ss = NULL;
@ -212,6 +221,7 @@ hid_sdp_query(bdaddr_t const *local, struct hid_device *hd, int32_t *error)
reconnect_initiate == -1 ||
hid_descriptor == NULL || hid_descriptor_length == -1)
hid_sdp_query_exit(ENOATTR);
hd->name = bt_devremote_name_gen(devname, &hd->bdaddr);
hd->vendor_id = vendor_id;
hd->product_id = product_id;
hd->version = version;

View File

@ -42,6 +42,7 @@
struct hid_device
{
bdaddr_t bdaddr; /* HID device BDADDR */
char * name; /* HID device name */
uint16_t control_psm; /* control PSM */
uint16_t interrupt_psm; /* interrupt PSM */
uint16_t vendor_id; /* primary vendor id */

View File

@ -2,6 +2,7 @@
device {
bdaddr 00:50:f2:e5:68:84;
name "Bluetooth Mouse";
vendor_id 0x0000;
product_id 0x0000;
version 0x0000;
@ -27,6 +28,7 @@ device {
device {
bdaddr 00:50:f2:e3:fb:e1;
name "Bluetooth Keyboard";
vendor_id 0x0000;
product_id 0x0000;
version 0x0000;

View File

@ -56,6 +56,7 @@ hexword {hexdigit}{hexdigit}?{hexdigit}?{hexdigit}?
device_word device
bdaddr_word bdaddr
name_word name
vendor_id_word vendor_id
product_id_word product_id
version_word version
@ -71,6 +72,7 @@ false_word false
bdaddrstring {hexbyte}:{hexbyte}:{hexbyte}:{hexbyte}:{hexbyte}:{hexbyte}
hexbytestring 0x{hexbyte}
hexwordstring 0x{hexword}
string \".+\"
%%
@ -85,6 +87,7 @@ hexwordstring 0x{hexword}
{device_word} return (T_DEVICE);
{bdaddr_word} return (T_BDADDR);
{name_word} return (T_NAME);
{vendor_id_word} return (T_VENDOR_ID);
{product_id_word} return (T_PRODUCT_ID);
{version_word} return (T_VERSION);
@ -118,6 +121,12 @@ hexwordstring 0x{hexword}
return (*ep == '\0'? T_HEXWORD : T_ERROR);
}
{string} {
yytext[strlen(yytext) - 1] = 0;
yylval.string = &yytext[1];
return (T_STRING);
}
. return (T_ERROR);
%%

View File

@ -63,6 +63,8 @@
#define EOL "\n"
#endif /* ndef BTHIDCONTROL */
#define NAMELESS_DEVICE "No Name"
#include "bthid_config.h"
int yylex (void);
@ -85,11 +87,14 @@ static LIST_HEAD(, hid_device) hid_devices;
%union {
bdaddr_t bdaddr;
int32_t num;
char *string;
}
%token <bdaddr> T_BDADDRSTRING
%token <num> T_HEXBYTE
%token <num> T_HEXWORD
%token <string> T_STRING
%token T_NAME
%token T_DEVICE T_BDADDR T_VENDOR_ID T_PRODUCT_ID T_VERSION T_CONTROL_PSM
%token T_INTERRUPT_PSM T_RECONNECT_INITIATE T_BATTERY_POWER
%token T_NORMALLY_CONNECTABLE T_HID_DESCRIPTOR
@ -128,6 +133,7 @@ options: option ';'
;
option: bdaddr
| name
| vendor_id
| product_id
| version
@ -146,6 +152,24 @@ bdaddr: T_BDADDR T_BDADDRSTRING
}
;
name: T_NAME T_STRING
{
if (hid_device->name != NULL) {
free(hid_device->name);
hid_device->name = NULL;
}
if (strcmp($2, NAMELESS_DEVICE)) {
hid_device->name = strdup($2);
if (hid_device->name == NULL) {
SYSLOG(LOGCRIT, "Could not allocate new " \
"device name" EOL);
YYABORT;
}
}
}
;
vendor_id: T_VENDOR_ID T_HEXWORD
{
hid_device->vendor_id = $2;
@ -332,6 +356,7 @@ print_hid_device(hid_device_p d, FILE *f)
fprintf(f,
"device {\n" \
" bdaddr %s;\n" \
" name \"%s\";\n" \
" vendor_id 0x%04x;\n" \
" product_id 0x%04x;\n" \
" version 0x%04x;\n" \
@ -342,6 +367,7 @@ print_hid_device(hid_device_p d, FILE *f)
" normally_connectable %s;\n" \
" hid_descriptor {",
bt_ntoa(&d->bdaddr, NULL),
(d->name != NULL)? d->name : NAMELESS_DEVICE,
d->vendor_id, d->product_id, d->version,
d->control_psm, d->interrupt_psm,
d->reconnect_initiate? "true" : "false",
@ -419,6 +445,7 @@ free_hid_device(hid_device_p d)
if (d->desc != NULL)
hid_dispose_report_desc(d->desc);
free(d->name);
memset(d, 0, sizeof(*d));
free(d);
}