Apple Magic Mouse
Dirk Engling
erdgeist at erdgeist.org
Sat Sep 12 14:26:57 UTC 2015
On 09.08.15 21:47, plunky at ogmig.net (Iain Hibbert) wrote:
> I'd say that using the NetBSD driver (I am the author) is not really
> possible on FreeBSD, since FreeBSD does things related to Bluetooth HIDs
> differently. It should be simple enough to add the Magic Mouse handling to
> the bthidd(8) daemon though, but I don't know how easy that would be, or a
> separate daemon could be written instead.
I've taken a look and there's several obstacles in the way. But first
the good news, once I add
if (fd == srv->ctrl) {
static uint8_t rep[] = { 0x53, 0xd7, 0x01 };
write(new_fd, rep, 3 );
}
to usr.sbin/bluetooth/bthidd/server.c:272, the hid_interrupt function in
usr.sbin/bluetooth/bthidd/hid.c gets trackpad-events and mouse lift/drop
from the magic mouse.
My problem is now, that this feature report is hard coded and obviously
not every device should be served this. But,
> The way I worked the identification in NetBSD, was that when configuring a
> HID device, I checked the descriptor as normal and also the
> Manufacturer/Product ID via the PNP profile. When the latter matched the
> Apple Magic Mouse, then it just attaches a different driver.
it looks like the Manufacturer/Product ID is ignored on the hci level
and thus not available at higher layers. Maybe I'm missing something here?
> The Magic Mouse then needs an initialization command to be sent via the
> standard HID protocol "SET_REPORT(FEATURE, 0xd7) = 0x01" once connected to
> enable the special extra functionality that it provides.
Also I noticed that the reports sent by the magic mouse are not reported
in their hid descriptor. I get the following reports there (see attachment)
09 02 (LOCAL) USAGE Mouse (CA=Application Collection)
85 10 (GLOBAL) REPORT_ID 0x10 (16)
09 20 (LOCAL) USAGE Battery Strength
85 47 (GLOBAL) REPORT_ID 0x47 (71) 'G'
09 55 (LOCAL) USAGE 0xFF020055
85 55 (GLOBAL) REPORT_ID 0x55 (85) 'U'
But when enabling the magic mouse modes as seen above, I see reports:
HID Interrupt: A1 60 01
HID Interrupt: A1 61 01
Which is 0x60 and 0x61, corresponding with mouse surface lift and drop.
When touching the trackpad area on the mouse, I get
HID Interrupt: A1 29 00 00 80 D0 6B 9F E3 11 4D 16 83 80 32
which is report 0x29 and corresponds to the magic trackpad messages
handled in the NetBSD [1] and Linux driver [2].
Problem is, that the bthidd code does not handle reports not announced
in hid descriptors at all. So I would need to either manually inject the
report id in hid_device->desc and add handler code, handle magic mouse
in a completely different code path, or write my own driver.
Maybe Maksim has some ideas, the daemon is his code, after all.
Regards,
erdgeist
[1]
http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/dev/bluetooth/btmagic.c?rev=1.14&content-type=text/x-cvsweb-markup
[2] http://lxr.free-electrons.com/source/drivers/hid/hid-magicmouse.c
-------------- next part --------------
//--------------------------------------------------------------------------------
// Decoded Application Collection
//--------------------------------------------------------------------------------
/*
05 01 (GLOBAL) USAGE_PAGE 0x0001 Generic Desktop Page
09 02 (LOCAL) USAGE 0x00010002 Mouse (CA=Application Collection)
A1 01 (MAIN) COLLECTION 0x01 Application (Usage=0x00010002: Page=Generic Desktop Page, Usage=Mouse, Type=CA)
85 10 (GLOBAL) REPORT_ID 0x10 (16)
05 09 (GLOBAL) USAGE_PAGE 0x0009 Button Page
19 01 (LOCAL) USAGE_MINIMUM 0x00090001 Button 1 Primary/trigger (MULTI=Selector, On/Off, Momentary, or One Shot)
29 02 (LOCAL) USAGE_MAXIMUM 0x00090002 Button 2 Secondary (MULTI=Selector, On/Off, Momentary, or One Shot)
15 00 (GLOBAL) LOGICAL_MINIMUM 0x00 (0) <-- Redundant: LOGICAL_MINIMUM is already 0
25 01 (GLOBAL) LOGICAL_MAXIMUM 0x01 (1)
95 02 (GLOBAL) REPORT_COUNT 0x02 (2) Number of fields
75 01 (GLOBAL) REPORT_SIZE 0x01 (1) Number of bits per field
81 02 (MAIN) INPUT 0x00000002 (2 fields x 1 bit) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap
95 01 (GLOBAL) REPORT_COUNT 0x01 (1) Number of fields
75 06 (GLOBAL) REPORT_SIZE 0x06 (6) Number of bits per field
81 03 (MAIN) INPUT 0x00000003 (1 field x 6 bits) 1=Constant 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap
05 01 (GLOBAL) USAGE_PAGE 0x0001 Generic Desktop Page
09 01 (LOCAL) USAGE 0x00010001 Pointer (CP=Physical Collection)
A1 00 (MAIN) COLLECTION 0x00 Physical (Usage=0x00010001: Page=Generic Desktop Page, Usage=Pointer, Type=CP)
16 01FE (GLOBAL) LOGICAL_MINIMUM 0xFE01 (-511)
26 FF01 (GLOBAL) LOGICAL_MAXIMUM 0x01FF (511)
36 C0FE (GLOBAL) PHYSICAL_MINIMUM 0xFEC0 (-320)
46 4001 (GLOBAL) PHYSICAL_MAXIMUM 0x0140 (320)
65 13 (GLOBAL) UNIT 0x00000013 Distance in inches [1 inch units] (3=System=English Linear, 1=Length=Inch)
55 0D (GLOBAL) UNIT_EXPONENT 0x0D (Unit Value x 10⁻³)
09 30 (LOCAL) USAGE 0x00010030 X (DV=Dynamic Value)
09 31 (LOCAL) USAGE 0x00010031 Y (DV=Dynamic Value)
75 10 (GLOBAL) REPORT_SIZE 0x10 (16) Number of bits per field
95 02 (GLOBAL) REPORT_COUNT 0x02 (2) Number of fields
81 06 (MAIN) INPUT 0x00000006 (2 fields x 16 bits) 0=Data 1=Variable 1=Relative 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap
C0 (MAIN) END_COLLECTION Physical
05 06 (GLOBAL) USAGE_PAGE 0x0006 Generic Device Controls Page
09 20 (LOCAL) USAGE 0x00060020 Battery Strength (DV=Dynamic Value)
85 47 (GLOBAL) REPORT_ID 0x47 (71) 'G'
15 00 (GLOBAL) LOGICAL_MINIMUM 0x00 (0)
25 64 (GLOBAL) LOGICAL_MAXIMUM 0x64 (100)
75 08 (GLOBAL) REPORT_SIZE 0x08 (8) Number of bits per field
95 01 (GLOBAL) REPORT_COUNT 0x01 (1) Number of fields
B1 A2 (MAIN) FEATURE 0x000000A2 (1 field x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 1=NoPrefState 0=NoNull 1=Volatile 0=Bitmap
06 02FF (GLOBAL) USAGE_PAGE 0xFF02 Vendor-defined
09 55 (LOCAL) USAGE 0xFF020055
85 55 (GLOBAL) REPORT_ID 0x55 (85) 'U'
15 00 (GLOBAL) LOGICAL_MINIMUM 0x00 (0) <-- Redundant: LOGICAL_MINIMUM is already 0
26 FF00 (GLOBAL) LOGICAL_MAXIMUM 0x00FF (255)
75 08 (GLOBAL) REPORT_SIZE 0x08 (8) Number of bits per field <-- Redundant: REPORT_SIZE is already 8
95 40 (GLOBAL) REPORT_COUNT 0x40 (64) Number of fields
B1 A2 (MAIN) FEATURE 0x000000A2 (64 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 1=NoPrefState 0=NoNull 1=Volatile 0=Bitmap
C0 (MAIN) END_COLLECTION Application
*/
More information about the freebsd-bluetooth
mailing list