From owner-freebsd-bluetooth@FreeBSD.ORG Tue May 15 07:59:52 2007 Return-Path: X-Original-To: freebsd-bluetooth@freebsd.org Delivered-To: freebsd-bluetooth@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id BC80616A4FC for ; Tue, 15 May 2007 07:59:52 +0000 (UTC) (envelope-from hselasky@c2i.net) Received: from swip.net (mailfe13.swip.net [212.247.155.129]) by mx1.freebsd.org (Postfix) with ESMTP id 2EB0C13C4C3 for ; Tue, 15 May 2007 07:59:51 +0000 (UTC) (envelope-from hselasky@c2i.net) X-Cloudmark-Score: 0.000000 [] Received: from [194.248.135.20] (account mc467741@c2i.net HELO laptop.lan) by mailfe13.swip.net (CommuniGate Pro SMTP 5.1.7) with ESMTPA id 96929481; Tue, 15 May 2007 08:59:49 +0200 From: Hans Petter Selasky To: freebsd-usb@freebsd.org, Markus Brueffer Date: Tue, 15 May 2007 08:59:37 +0200 User-Agent: KMail/1.9.5 References: <20070514233438.GD24803@ice.42.org> In-Reply-To: <20070514233438.GD24803@ice.42.org> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200705150859.37126.hselasky@c2i.net> Cc: freebsd-bluetooth@freebsd.org, Stefan `Sec` Zehl Subject: Re: libusbhid bug? X-BeenThere: freebsd-bluetooth@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Using Bluetooth in FreeBSD environments List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 May 2007 07:59:53 -0000 Hi, I think Markus Brueffer is working on a new HID parser. --HPS On Tuesday 15 May 2007 01:34, Stefan `Sec` Zehl wrote: > Hi, > > I've been playing around with a Bluetooth HID device. Bluetooth uses the > same HID format as USB, so libusbhid is used to parse these messages. > > While debugging, I've found what I think is a mistake in parsing > "Array"-type input messages: > > In my HID descriptor, there is the following snippet: > | 95 06 | Report Count(6) > | 75 08 | Report Size(8) > | 15 00 | Logical Minimum(0) > | 26 a4 00| Logical Maximum(164) > | 05 07 | Usage Page(Key Codes) > | 19 00 | Usage Minimum(0x00) > | 29 a4 | Usage Maximum(0xa4) > | 81 00 | Input(Data,Array,Absolute) > > The current usbhid only parses one item of Report_Size (8bit). According > > to the spec it should parse Report_Count items: > | An array provides an alternate means for > | describing the data returned from a group of > | buttons. Arrays are more efficient, if less flexible > | than variable items. Rather than returning a single > | bit for each button in the group, an array returns an > | index in each field that corresponds to the pressed > | button (like keyboard scan codes). An out-of range > | value in and array field is considered no controls > | asserted. Buttons or keys in an array that are > | simultaneously pressed need to be reported in > | multiple fields. Therefore, the number of fields in > | an array input item (Report Count) dictates the > | maximum number of simultaneous controls that > | can be reported. A keyboard could report up to > | three simultaneous keys using an array with three > | 8-bit fields (Report Size = 8, Report Count = 3). > > I have created a patch which changes that behaviour, and attached it > below. My sample code works fine with these changes, but as I don't have > an USB Keyboard, it would be great if someone could check that this > doesn't break anything. > > --- parse.c.org Wed Feb 11 22:09:13 2004 > +++ parse.c Tue May 15 01:26:08 2007 > @@ -54,6 +54,7 @@ > int multimax; > int kindset; > int reportid; > + int isarray; > > /* > * The start of collection item has no report ID set, so save > @@ -100,6 +101,7 @@ > s->kindset = kindset; > s->reportid = id; > s->hassavedcoll = 0; > + s->isarray = 0; > return (s); > } > > @@ -182,6 +184,16 @@ > hid_clear_local(c); > } > } > + if(s->isarray) { > + REPORT_SAVED_COLL; > + *h = *c; > + h->next = 0; > + h->pos = s->kindpos[c->kind]; > + s->kindpos[c->kind] += c->report_size ; > + if(--s->isarray ==0) > + hid_clear_local(c); > + return(1); > + }; > for (;;) { > p = s->p; > if (p >= s->end) > @@ -262,14 +274,9 @@ > } else { > if (s->minset) > c->usage = c->usage_minimum; > - *h = *c; > - h->next = 0; > - h->pos = s->kindpos[c->kind]; > - s->kindpos[c->kind] += > - c->report_size * c->report_count; > - hid_clear_local(c); > s->minset = 0; > - return (1); > + s->isarray=c->report_count; > + goto top; > } > case 9: /* Output */ > retkind = hid_output; > > CU, > Sec