Path: blob/main/usr.sbin/bluetooth/bthidcontrol/hid.c
103381 views
/*-1* hid.c2*3* SPDX-License-Identifier: BSD-2-Clause4*5* Copyright (c) 2004 Maksim Yevmenkin <[email protected]>6* All rights reserved.7*8* Redistribution and use in source and binary forms, with or without9* modification, are permitted provided that the following conditions10* are met:11* 1. Redistributions of source code must retain the above copyright12* notice, this list of conditions and the following disclaimer.13* 2. Redistributions in binary form must reproduce the above copyright14* notice, this list of conditions and the following disclaimer in the15* documentation and/or other materials provided with the distribution.16*17* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND18* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE19* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE20* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE21* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL22* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS23* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)24* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT25* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY26* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF27* SUCH DAMAGE.28*29* $Id: hid.c,v 1.3 2004/02/17 22:14:57 max Exp $30*/3132#include <sys/queue.h>33#define L2CAP_SOCKET_CHECKED34#include <bluetooth.h>35#include <dev/usb/usb.h>36#include <dev/usb/usbhid.h>37#include <stdio.h>38#include <string.h>39#include <usbhid.h>40#include "bthid_config.h"41#include "bthidcontrol.h"4243extern uint32_t verbose;4445static void hid_dump_descriptor (report_desc_t r);46static void hid_dump_item (char const *label, struct hid_item *h);4748static int49hid_dump(bdaddr_t *bdaddr, int argc, char **argv)50{51struct hid_device *hd = NULL;52int e = FAILED;5354if (read_config_file() == 0) {55if ((hd = get_hid_device(bdaddr)) != NULL) {56hid_dump_descriptor(hd->desc);57e = OK;58}5960clean_config();61}6263return (e);64}6566static int67hid_forget(bdaddr_t *bdaddr, int argc, char **argv)68{69struct hid_device *hd = NULL;70int e = FAILED;7172if (read_config_file() == 0) {73if (read_hids_file() == 0) {74if ((hd = get_hid_device(bdaddr)) != NULL) {75hd->new_device = 1;76if (write_hids_file() == 0)77e = OK;78}79}8081clean_config();82}8384return (e);85}8687static int88hid_known(bdaddr_t *bdaddr, int argc, char **argv)89{90struct hid_device *hd = NULL;91struct hostent *he = NULL;92int e = FAILED;9394if (read_config_file() == 0) {95if (read_hids_file() == 0) {96e = OK;9798for (hd = get_next_hid_device(hd);99hd != NULL;100hd = get_next_hid_device(hd)) {101if (hd->new_device)102continue;103104he = bt_gethostbyaddr((char *) &hd->bdaddr,105sizeof(hd->bdaddr),106AF_BLUETOOTH);107108fprintf(stdout,109"%s %s\n", bt_ntoa(&hd->bdaddr, NULL),110(he != NULL && he->h_name != NULL)?111he->h_name : "");112}113}114115clean_config();116}117118return (e);119}120121static void122hid_dump_descriptor(report_desc_t r)123{124struct hid_data *d = NULL;125struct hid_item h;126127for (d = hid_start_parse(r, ~0, -1); hid_get_item(d, &h); ) {128switch (h.kind) {129case hid_collection:130fprintf(stdout,131"Collection page=%s usage=%s\n", hid_usage_page(HID_PAGE(h.usage)),132hid_usage_in_page(h.usage));133break;134135case hid_endcollection:136fprintf(stdout, "End collection\n");137break;138139case hid_input:140hid_dump_item("Input ", &h);141break;142143case hid_output:144hid_dump_item("Output ", &h);145break;146147case hid_feature:148hid_dump_item("Feature", &h);149break;150}151}152153hid_end_parse(d);154}155156static void157hid_dump_item(char const *label, struct hid_item *h)158{159if ((h->flags & HIO_CONST) && !verbose)160return;161162fprintf(stdout,163"%s id=%u size=%u count=%u page=%s usage=%s%s%s%s%s%s%s%s%s%s",164label, (uint8_t) h->report_ID, h->report_size, h->report_count,165hid_usage_page(HID_PAGE(h->usage)),166hid_usage_in_page(h->usage),167h->flags & HIO_CONST ? " Const" : "",168h->flags & HIO_VARIABLE ? " Variable" : "",169h->flags & HIO_RELATIVE ? " Relative" : "",170h->flags & HIO_WRAP ? " Wrap" : "",171h->flags & HIO_NONLINEAR ? " NonLinear" : "",172h->flags & HIO_NOPREF ? " NoPref" : "",173h->flags & HIO_NULLSTATE ? " NullState" : "",174h->flags & HIO_VOLATILE ? " Volatile" : "",175h->flags & HIO_BUFBYTES ? " BufBytes" : "");176177fprintf(stdout,178", logical range %d..%d",179h->logical_minimum, h->logical_maximum);180181if (h->physical_minimum != h->physical_maximum)182fprintf(stdout,183", physical range %d..%d",184h->physical_minimum, h->physical_maximum);185186if (h->unit)187fprintf(stdout,188", unit=0x%02x exp=%d", h->unit, h->unit_exponent);189190fprintf(stdout, "\n");191}192193struct bthid_command hid_commands[] = {194{195"Dump",196"Dump HID descriptor for the specified device in human readable form. The\n" \197"device must have an entry in the Bluetooth HID daemon configuration file.\n",198hid_dump199},200{201"Known",202"List all known to the Bluetooth HID daemon devices.\n",203hid_known204},205{206"Forget",207"Forget (mark as new) specified HID device. This command is useful when it\n" \208"is required to remove device from the known HIDs file. This should be done\n" \209"when reset button was pressed on the device or the battery was changed. The\n"\210"Bluetooth HID daemon should be restarted.\n",211hid_forget212},213{ NULL, NULL, NULL }214};215216217218