Date: Fri, 10 Oct 2008 17:43:22 +0000 (UTC) From: Rui Paulo <rpaulo@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r183747 - user/rpaulo/ubthidctl Message-ID: <200810101743.m9AHhMD2097003@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rpaulo Date: Fri Oct 10 17:43:21 2008 New Revision: 183747 URL: http://svn.freebsd.org/changeset/base/183747 Log: USB Bluetooth HID<->HCI control utility. Changes a USB dongle from HID mode to Bluetooth HCI mode. Imported from P4. Added: user/rpaulo/ubthidctl/ user/rpaulo/ubthidctl/Makefile (contents, props changed) user/rpaulo/ubthidctl/ubthidctl.1 (contents, props changed) user/rpaulo/ubthidctl/ubthidctl.c (contents, props changed) user/rpaulo/ubthidctl/ubthidtbl Added: user/rpaulo/ubthidctl/Makefile ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ user/rpaulo/ubthidctl/Makefile Fri Oct 10 17:43:21 2008 (r183747) @@ -0,0 +1,6 @@ +# $FreeBSD$ + +PROG= ubthidctl +WARNS?= 6 + +.include <bsd.prog.mk> Added: user/rpaulo/ubthidctl/ubthidctl.1 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ user/rpaulo/ubthidctl/ubthidctl.1 Fri Oct 10 17:43:21 2008 (r183747) @@ -0,0 +1,93 @@ +.\" +.\" Copyright (c) 2007 Rui Paulo <rpaulo@fnop.net> +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +.\" DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd July 30, 2007 +.Dt UBTHIDCTL 1 +.Sh NAME +.Nm ubthidctl +.Nd "Bluetooth USB HID-HCI proxy switcher" +.Sh SYNOPSIS +.Nm +.Fl f Ar device +.Fl a Ar addr +.Op Fl m Ar mode +.Nm +.Fl t Ar tablefile +.Sh DESCRIPTION +The +.Nm +utility changes Bluetooth controllers from HID (Human Interface Device) +to HCI (Host Controller Interface) and vice-versa. +HCI is the interface used by Bluetooth devices and HID is the interface +used by some USB devices. The device will reattach every time you switch +modes. +.Pp +Some Bluetooth controllers present themselves to the BIOS as +an +.Xr uhid 4 +device. +This is done so that the user can use a Bluetooth keyboard and a Bluetooth +mouse with BIOS implementations that already support USB. +After the operating system boots, it's the system administrator's +responsibility to switch the device to HCI mode. +.Pp +This utility supports two modes of operation. +In the first one you run the utility with the exact location of the +device (device entry, address and an optional mode). +In the other mode, the utility reads a filename with several vendors +and product identifiers. If your system has a device listed in +.Pa tablefile +it will be switched to the appropriate mode automatically. +.Sh FILES +.Bl -tag -width indent +.It Pa /usr/share/misc/ubthidtbl +The location of the table file. +.El +.Sh EXAMPLES +First mode of operation: +.Bd -literal -offset indent +ubthidctl -f /dev/usb3 -a 2 +.Ed +.Pp +Second mode of operation: +.Bd -literal -offset indent +ubthidctl -t /usr/share/misc/ubthidtbl +.Ed +.Sh SEE ALSO +.Xr ng_ubt 4 , +.Xr uhid 4 , +.Xr usb 4 +.Sh HISTORY +The +.Nm +utility first appeared in +.Fx 8.0 . +.Pp +It was based on the hid2hci utility for Linux written by +.An Marcel Holtmann Aq marcel@holtmann.org +.Sh AUTHORS +.An Rui Paulo Aq rpaulo@fnop.net Added: user/rpaulo/ubthidctl/ubthidctl.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ user/rpaulo/ubthidctl/ubthidctl.c Fri Oct 10 17:43:21 2008 (r183747) @@ -0,0 +1,249 @@ +/*- + * Copyright (c) 2007 Rui Paulo <rpaulo@fnop.net> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + * + */ + +/* + * Based on bluez-utils hid2hci tool written by + * Marcel Holtmann <marcel@holtmann.org> + */ + +#include <sys/cdefs.h> +#ifdef __FreeBSD__ +__FBSDID("$FreeBSD$"); +#endif + +#include <err.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <sys/ioctl.h> + +#include <dev/usb/usb.h> + +typedef enum { + HCI = 0, + HID = 1 +} hidmode_t; + +typedef struct { + hidmode_t mode; + uint16_t vendor; + uint16_t product; +} tblentry_t; + +typedef struct { + int devno; + int devaddr; +} devinfo_t; + + +static void switchmode(const char *dev, const int devaddr, hidmode_t mode); + + +static devinfo_t +finddevice(tblentry_t tblentry) +{ + struct usb_device_info usbdev; + char filename[16]; + devinfo_t dev; + int i; + int j; + int fd; + + dev.devno = -1; + + for (i = 0; i < 20; i++) { + snprintf(filename, sizeof(filename) - 1, "/dev/usb%d", i); + fd = open(filename, O_RDONLY); + if (fd < 0) + return dev; + + for (j = USB_START_ADDR; j < USB_MAX_DEVICES; j++) { + memset(&usbdev, 0, sizeof(usbdev)); + usbdev.udi_addr = j; + ioctl(fd, USB_DEVICEINFO, &usbdev); + if (tblentry.vendor == usbdev.udi_vendorNo && + tblentry.product == usbdev.udi_productNo) { + dev.devno = i; + dev.devaddr = j; + close(fd); + + return dev; + } + } + + close(fd); + } + + return dev; +} + +static void +parsetable(const char *filename) +{ + FILE *fp; + tblentry_t tblentry; + unsigned int vendor; + unsigned int product; + char modestr[4]; + devinfo_t dev; + char usbname[16]; + char buf[1024]; + char *p; + + fp = fopen(filename, "r"); + if (!fp) + err(1, "fopen %s", filename); + + while (!feof(fp)) { + fgets(buf, sizeof(buf) - 1, fp); + for (p = buf; *p == ' '; p++); + if (*p == '#' || *p == '\n') + continue; + + sscanf(p, "%3s 0x%x 0x%x\n", modestr, &vendor, &product); + + tblentry.vendor = vendor; + tblentry.product = product; + + if (!strncmp(modestr, "HCI", 3)) + tblentry.mode = HCI; + else if (!strncmp(modestr, "HID", 3)) + tblentry.mode = HID; + else { + warnx("invalid mode: %s", modestr); + continue; + } + dev = finddevice(tblentry); + if (dev.devno != -1) { + snprintf(usbname, sizeof(usbname) - 1, "/dev/usb%d", + dev.devno); + switchmode(usbname, dev.devaddr, tblentry.mode); + } + + } + + fclose(fp); + +} + +static void +switchmode(const char *dev, const int devaddr, hidmode_t mode) +{ + int fd; + struct usb_ctl_request req; + + fd = open(dev, O_RDWR, 0); + if (fd < 0) + err(1, "open %s", dev); + + memset(&req, 0, sizeof(req)); + req.ucr_addr = devaddr; + USETW(req.ucr_request.wValue, mode); + USETW(req.ucr_request.wIndex, 0); + USETW(req.ucr_request.wLength, 0); + req.ucr_data = NULL; + req.ucr_flags = USBD_SHORT_XFER_OK; + req.ucr_request.bmRequestType = UT_VENDOR; + req.ucr_request.bRequest = 0; + + ioctl(fd, USB_REQUEST, &req); + + /* + * The return value of ioctl() will always be EIO, so it's up + * to the user to check whether the device was switched sucessfuly. + */ + + close(fd); +} + +static void +usage(void) +{ + fprintf(stderr, "usage:\t%s -f device -a addr [-m mode]\n" + "\t%s -t tablefile\n", getprogname(), getprogname()); + + exit(1); +} + +int +main(int argc, char *argv[]) +{ + char ch; + char *dev; + char *tablefile; + int devaddr; + int mode; + + dev = NULL; + devaddr = -1; + mode = HCI; + tablefile = NULL; + + while ((ch = getopt(argc, argv, "f:m:a:t:?")) != -1) + switch (ch) { + case 'f': + dev = optarg; + break; + case 'm': + mode = atoi(optarg); + if (mode < 0 || mode > 1) + usage(); + break; + case 'a': + devaddr = atoi(optarg); + if (devaddr < 0) + usage(); + break; + case 't': + tablefile = optarg; + break; + case '?': + default: + usage(); + /* NOTREACHED */ + } + + argc -= optind; + argv += optind; + + if (tablefile) { + parsetable(tablefile); + return 0; + } + + if (dev == NULL || devaddr == -1) + usage(); + + switchmode(dev, devaddr, mode); + + return 0; +} Added: user/rpaulo/ubthidctl/ubthidtbl ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ user/rpaulo/ubthidctl/ubthidtbl Fri Oct 10 17:43:21 2008 (r183747) @@ -0,0 +1,15 @@ +# +# $FreeBSD$ +# +# The following table lists the devices that ubthidctl(1) should switch +# from HID to HCI and vice versa. +# + +# Apple +HID 0x05ac 0x1000 + +# Cambridge Silicon Radio +HID 0x0a12 0x1000 + +# KYE Systems +HID 0x0458 0x1000
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200810101743.m9AHhMD2097003>