The crux of finding a HID proxy-capable USB bluetooth adapter

So, for some not very profound reasons (watching demos and putting my spare Ivy Bridge CPU to a use), I ended up having a living room PC again. And as it’s the living room, input devices must be wireless. Since I’m not a fan of running proprietary wireless technologies that jam my Wifi’s 2.4 GHz band and because of increased usability with other devices such as tablets, I wanted a keyboard and a mouse based on Bluetooth technology. Because of design, functionality and good experiences I bought Microsoft’s Wedge mobile keyboard and Sculpt Touch mouse:

Microsoft Wedge Mobile Keyboard (with German layout)
Microsoft Wedge Mobile Keyboard (with German layout)
Microsoft Sculpt Touch Mouse
Microsoft Sculpt Touch Mouse

All nice and sleek and working within an installed OS but it is only when you’re trying to reinstall your operating system or need to enter your BIOS that bluetooth-based input devices still have a large drawback: they do not work without a Bluetooth driver stack. And during both OS installation and BIOS configuration you do not have one yet. Even the modern UEFI world doesn’t change that.

At least in the PC world — Apple has been using Bluetooth-based input devices for over a decade now and admittedly often went a step forward for the sake of user experience. When the Apple Wireless keyboard was introduced in September 2003, a software update was published that allowed for the wireless keyboard to take control of the boot process.

However, this was strictly speaking not Apple’s merit alone: the software update worked with Cambridge Silicon Radio (CSR)-based adapters only because that very company introduced a technique called HID proxy for its adapters in August 2003 (see their press release “CSR saves stranded mice”).

The idea behind HID proxy is that the bluetooth adapter has additional intelligence that allows it to a.) take over responsibility from the host it’s connected to run and run certain software layers itself and b.) run in this special mode until the OS’s bluetooth stack is loaded and tells it to return to “normal” operation. In HID proxy mode, the adapter communicates on its own with previously paired Bluetooth input devices and emulates to its host a USB keyboard and USB mouse through a HID interface instead of exposing the ordinary HCI interface. As the PC industry has at least succeeded in getting broad USB support into BIOS and OS installation software, this means that the Bluetooth keyboard and mouse will magically work in spite of a missing Bluetooth stack.

You see, Apple did not magically invent an Apple-only, HID proxy-capable bluetooth adapter. In fact, in 2003 the internal Bluetooth modules in their Notebooks were software-compatible with certain revisions of the D-Link USB bluetooth adapter DBT-120. They also didn’t ground-breakingly integrate Bluetooth functionality into their EFI firmware. They just made their Bluetooth hardware default to HID proxy mode until Mac OS X tells it to switch to HCI mode, that’s the whole secret.

D-Link DBT-120 USB bluetooth adapter
D-Link DBT-120 USB bluetooth adapter

However, this means that if you use such a Bluetooth adapter in HID proxy mode, the OS must be aware of it and tell it to switch to HCI mode or you will have no Bluetooth functionality once it’s loaded. And to my knowledge no Windows Bluetooth stack does, not even Microsoft’s own stack in the latest Windows 8.1.

For this very reason, Apple, on its Bluetooth Firmware Update 1.2 Download page, warned that applying that update “[…] to a D-Link USB to Bluetooth adapter will make it incompatible with non-Macintosh systems”. Which, back then, yet seems to have been overseen by a number of users, considering this FAQ page by German computer magazine c’t. Yet, this does not mean a DBT-120 flashed with the Apple update is bricked, as Edd Dumbill pointed out among others.

The other problem is: the DBT-120 is an old Bluetooth 1.1 device that’s not produced anymore and by 2014 it is next to impossible to find a HID proxy-capable USB bluetooth adapter on the market. This tonymacx86.com forum post lists four, one of them being the Apple built-in BT module (which apparantly can be modded to be hooked up to an USB port) and one being the mentioned DBT-120 from 2003. The Belkin F8T016NG mentioned seems to be still available at Amazon UK and Amazon Germany despite being listed as being “made anymore”, whereas the fourth adapter, the Belkin F8T016CW, does not seem to be available in Germany at all.

From a hardware perspective, there is no reason for this situation. As this leaked CSR presentation on their BlueCore firmware points out, having HID proxy support is merely a question of enabling it in firmware builds. It doesn’t seem to be a question of firmware size either if only integrating RFCOMM support (which nobody seems to need) requires an 8 MBit flash chip and even the DBT-120 back then could be flashed to support both HID proxy and HCI.

The real reason is the lack of software support instead: as mentioned above, even with CSR-specific drivers Windows bluetooth stacks treat the adapter as an USB HID device and do not know that it can be told to reveal its real nature in form of the HCI interface.

CSR saw that problem and provided a sample Windows command-line application, hid2hci.exe, that does exactly the job (do not confuse it with the Linux executable hid2hci from the BlueZ project). It is a small executable of 44KB size and without any external dependencies. You can optionally tell it the USB vendor ID and product ID of the bluetooth adapter to be addressed, defaulting to a vendor ID of 0x0a12, which is CSR’s ID, and a product ID of 0x1000, which is the product ID a CSR USB bluetooth adapter uses when in HID proxy mode. After running this executable, the adapter will reappear on the USB bus with a different product ID and a HID interface, causing the normal Bluetooth driver stack to take over control. This change is not permanent, so the executable needs to be run after each OS boot and after each plugging out and in the USB bus, but, as a followup post will show, that can be nicely automated.

So to summarize, what it takes to get your Bluetooth input devices working in the BIOS as well is:

  1. a USB bluetooth adapter defaulting to HID proxy mode
  2. the hid2hci.exe tool
  3. some automation magic

As for the first problem, no matter what CSR-based bluetooth adapter you own, you’d need a HID proxy-enabled firmware. The way it looks like Apple’s update is the only one freely available on the Internet, but it’s for the old D-Link DBT-120 only. Maybe you can find one on eBay. As chance would have it, I still had one flying around and tried the update without having a Mac. This followup post has more on this topic.

As for the second problem, I do not know if and in what context CSR distributes hid2hci.exe if at all. This blog post by Stephan Joseph used to have an archive btinstall.zip with it that was even referenced inside a book called “Take control of Windows running on a Mac” but you’ll have to look for yourself. Do not ask me to provide you with a copy.

As for the third problem, look out for a second followup post — I’ve done some cool PowerShell scripting ;)

Published
Categorized as Hardware

5 comments

  1. Hi, have You found any other (i understand that any usb dongle with csr chip onboard is ok) that is provided with firmware that enables HID proxy mode?

  2. i’m not quite sure, but i own a Logitech diNovo Media Desktop, which
    a) comes with keyboard, mouse & numberpad that can be paired with any bluetooth dongle/pc
    b) comes with a bluetooth dongle that windows doesn’t recognize as such & paired with the keyboard works in any bios :)
    if i don’t forget i’ll look into it when i’m at home…

    1. I bought one of those as well and have been trying it out, haven’t had it work in hid proxy mode yet (it shows up as hid proxy, but doesn’t seem to connect to the devices paired to it while in HCI mode).

  3. Download the current firware:


    [hh@viii unpack]$ sudo dfu-util --upload BT-120.dfu
    dfu-util 0.8

    Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
    Copyright 2010-2014 Tormod Volden and Stefan Schmidt
    This program is Free Software and has ABSOLUTELY NO WARRANTY
    Please report bugs to dfu-util@lists.gnumonks.org

    Deducing device DFU version from functional descriptor length
    Opening DFU capable USB device...
    ID 0a12:0001
    Run-time device DFU version 0100
    Claiming USB DFU Runtime Interface...
    Determining device status: state = appIDLE, status = 0
    Device really in Runtime Mode, send DFU detach request...
    Resetting USB...
    Deducing device DFU version from functional descriptor length
    dfu-util: Lost device after RESET?

    Hmmm…. try again:


    $ sudo dfu-util --upload BT-120.dfu
    dfu-util 0.8

    Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
    Copyright 2010-2014 Tormod Volden and Stefan Schmidt
    This program is Free Software and has ABSOLUTELY NO WARRANTY
    Please report bugs to dfu-util@lists.gnumonks.org

    Deducing device DFU version from functional descriptor length
    Opening DFU capable USB device...
    ID 0a12:ffff
    Run-time device DFU version 0100
    Claiming USB DFU Runtime Interface...
    Determining device status: state = dfuIDLE, status = 0
    dfu-util: WARNING: Runtime device already in DFU state ?!?
    Claiming USB DFU Interface...
    Setting Alternate Setting #0 ...
    Determining device status: state = dfuIDLE, status = 0
    dfuIDLE, continuing
    DFU mode device DFU version 0100
    Device returned transfer size 1023
    Copying data from DFU device to PC
    Upload [=========================] 100% 347062 bytes
    Upload done.

    Seems to work, but the filesize in is around 1/3 of GenericCSR.dfu:


    $ ls -lart
    total 4600
    drwxr-xr-x 1 hh hh 186 Feb 12 12:56 ..
    -rwxr-xr-x 1 hh hh 638672 Feb 12 12:56 Portable.dfu
    -rwxr-xr-x 1 hh hh 994866 Feb 12 12:56 GenericCSR.dfu
    -rwxr-xr-x 1 hh hh 638672 Feb 12 12:56 DeskTop.dfu
    -rw-r--r-- 1 root root 347062 Feb 12 13:09 DBT-120.dfu

    I’ll try and upload GenericDSR.dfu now:


    $ sudo dfu-util --download GenericCSR.dfu
    dfu-util 0.8

    Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
    Copyright 2010-2014 Tormod Volden and Stefan Schmidt
    This program is Free Software and has ABSOLUTELY NO WARRANTY
    Please report bugs to dfu-util@lists.gnumonks.org

    Match vendor ID from file: 0a12
    Match product ID from file: 0001
    Deducing device DFU version from functional descriptor length
    Opening DFU capable USB device...
    ID 0a12:0001
    Run-time device DFU version 0100
    Claiming USB DFU Runtime Interface...
    Determining device status: state = appIDLE, status = 0
    Device really in Runtime Mode, send DFU detach request...
    Resetting USB...
    Deducing device DFU version from functional descriptor length
    dfu-util: Lost device after RESET?

    Boo… try again?


    $ sudo dfu-util --download GenericCSR.dfu
    dfu-util 0.8

    Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
    Copyright 2010-2014 Tormod Volden and Stefan Schmidt
    This program is Free Software and has ABSOLUTELY NO WARRANTY
    Please report bugs to dfu-util@lists.gnumonks.org

    Match vendor ID from file: 0a12
    Match product ID from file: 0001
    Deducing device DFU version from functional descriptor length
    dfu-util: No DFU capable USB device available

    A bit at a loss here. Is it possible to do this in linux with dfu-util from bluez5?

Leave a comment