rooDial a Wireless Volume Knob for Roon with Microsoft Surface Dial

Current state on research of connection delay issue

Hi guys,
I am investigating the delay issue after the Surface Dial got disconnected.
In one word: It is difficult :sleepy:

All I write now is for technical interested guys. If youā€™re not, just stop here :wink:
My hope is I may get some input of someone of who may be educated in thisā€¦

As I wrote before, I want to get the data directly from the D-Bus. The data for this is provided by Bluez, the process that manages Bluetooth devices on Linux. The D-Bus provides primary services from the device via GATT. I started investigating this with the NUIMO since I know the service UUIDs for this device.

That worked right away. I could connect to Nuimo, register callbacks, and retrieve data when I press or spin the wheel. So it seems I was on the right track.

Next, I tried the same thing with the Surface Dial. It differs in two ways:

  • First: It has to be paired, which the Nuimo didnā€™t need.
  • Second: A kernel driver accesses this device to make it available as an HCI device.

HCI is the interface I currently use to get the press and the rotate events. Exactly this produces the delay issue. This means: If the Surface Dial gets back from sleep (and this happens quickly) it takes a while until the kernel re-initializes the HCI-service. This is where the delay comes from.

This kernel driver hides the HCI services at the D-bus so I could not directly access them. Diving deep I found out that I can disable the HCI kernel driver by adding --noplugin=sap,input,hog starting the Bluetooth service. After that I can see the GATT service 00001812-0000-1000-8000-00805f9b34fb (which is the service for HCI) and its properties.

So far so good.
I could connect to the services and read the properties. But now Iā€™m stuck:

  • Reading the properties there is no change if I interact with the Surface Dial.
  • I canā€™t register a callback as I did with the Nuimo to get the press or rotate events.

This means I currently have no idea how the kernel driver who also accesses this GATT service gets the information about pressing and rotating.

I will continue with further research but if anyone of you has an idea how the HID kernel driver cooperates with GATT to get the events please let me know :pray: :pray: :pray:

Best DrCWO

Hi, @DrCWO. I have very, very limited knowledge of this area. So I did what any modern programmer trying to do something for which they have no foreknowledge does - I asked ChatGPT (GPT-4). Hereā€™s the prompt that produced the best response and the response itself. Perhaps this helps.

Prompt: I am writing code that needs to read input from a bluetooth mouse, such as when the mouse is clicked. How can I do this by reading from the GATT service directly?

Response:

To receive inputs from a Bluetooth mouse (or any HID over GATT (HOGP) device), you need to communicate with the device using the GATT protocol, which is built on top of the Bluetooth Low Energy (BLE) stack. You would generally need to do the following steps:

  1. Scanning and Connecting: First, scan for BLE devices, identify the device you are interested in (your mouse, in this case) and establish a connection. This will involve the discovery of the mouseā€™s advertising data, matching it to a known service (in this case, the HID service), and then sending a connection request.
  2. Service Discovery: After establishing a connection, the next step is to discover the available GATT services on the mouse. One of these should be the HID service. Typically, this service has the UUID 1812 or 128-bit UUID.
  3. Characteristic Discovery: Once youā€™ve found the HID service, you need to discover its characteristics. The one youā€™re interested in for a mouse would usually be the ā€˜Reportā€™ characteristic. Report characteristics contain the actual HID input and output reports - the data that the device is sending or receiving. The UUID for the Report characteristic is 2A4D.
  4. Reading Characteristic: To get the input reports (the data the mouse is sending), you will need to read from the Report characteristic. However, continually polling this characteristic is not efficient.
  5. Setting Up Notifications: Instead of reading the characteristic directly, itā€™s better to set up a GATT notification on the Report characteristic. This way, every time the mouse sends an input report (for example, when a button is clicked or the mouse is moved), your program will receive a notification with the new data. Setting up notifications involves writing to a special ā€œDescriptorā€ for the characteristic, specifically the ā€œClient Characteristic Configuration Descriptorā€ (CCCD). By writing a specific value (0x01 for notifications) to the CCCD, youā€™re telling the device to start sending notifications whenever the characteristic changes.
  6. Handle Notifications: Finally, your code should be set up to handle these notifications as they come in. The exact way to do this depends on your programming environment, but it generally involves setting up a callback function that will be triggered every time a notification is received.

Remember that working with BLE can be complex, particularly because it involves asynchronous operations and because the details can vary between different devices. The exact way to perform these steps depends on what programming language youā€™re using and what libraries or frameworks are available for working with BLE in that language. You should refer to the documentation for the relevant BLE library for specific instructions.

Hi @gTunes, thank you very much :+1:
I already had the same idea but did not ask ChatGPT :sleepy:
And yes, maybe there is really something in its response that I did not know yet.

I played around with the GATT service 1812 and also know about the characteristic 2A4D. I tried to register a notification (callback) to it as proposed by ChatGPT but this was denied.

But what I havenā€™t tested yet :slight_smile:
I did not know that I have to write 0x01 to the Client Characteristic Configuration Descriptorā€ (CCCD) to enable notifications. Maybe this is the key! I hope after doing this I will be able to register the callback and get informed by changes.

Thank you for the valuable input. I think I will have some more dialogs with chatGPT this weekend :blush:

Edit:
BTW, Iā€™m in my sixties and therefre not really a ā€œmodern programmerā€ :stuck_out_tongue_closed_eyes:

Best DrCWO

1 Like

I hope that turns out to be the case. Even if it doesnā€™t, at least you now know that itā€™s possible that notifications need to be explicitly enabled.

I should have said ā€œmodern-day programmerā€. :slight_smile:

It boggles my mind how fearless and entrepreneurial you are. Itā€™s so easy to separate the world into ā€œthings you know how to doā€ and ā€œthings you donā€™t know how to doā€. Most people stick to things in the first category. I appreciate the people, like you, who see the second category as opportunity, not obstacle.

5 Likes

Hi @DrCWO! Iā€™m having some trouble setting up my new Microsoft Surface Dial. When rooDial is set to control my living room system (RPi 3B w/ Allo DigiOne HAT running RoPieeeXL) I can select DSP Volume & everything works great! However, when I set rooDial to control my office system (Pro-Ject Stream Box S2 Ultra) DSP Volume is not one of the options. I can choose from Device Volume, Fixed Volume, & rooControl: Volume. All other functions work, but the volume does not. Is there something I may be missing? I appreciate the help & all the work youā€™ve put into rooExtend. Thanks so much!

I donā€™t know the Pro-Ject implementation but there are streamers out there that donā€™t support DSP volume.
On the other side: If you are able to control the volume setting it to ā€œDevice Volumeā€ by the Slider in the Roon App it also can be controlled by rooDial. Just select the right zone.

Did you know that rooExtend hosts the Roon Bridge Streamer? You also can connect your DAC there and it supports DSP Volume.

Best DrCWO

Hello Dr. I looked at your 4 videos: please, where can I buy the raspberry pi already included the SD card and software already download? Then I only need to buy the Surface Dial and license separately ā€“ ā€“ no other complications.
Please advise.

There is no more ready to run offer with a Raspberry PI. The dealer who offered it went out of this business.

But you can buy the rooExtend-box at https://rooExtend.com which is a ready to run full featured system with all options. It has autoupdate and will receive all Roon Extensions still coming. It is future safe and was made for people who donā€˜t like to tinker.

Th rooExtend Box is plug and play and comes with a 60 days trial license,

Best DrCWO

Hey Doc, just writing to let you know I am rooting for you on the roodial refactor that prevents excessive sleeping by the surface dial.

I initially got you in touch with the surface dial engineer at Microsoft who I believe you did trades messages with at one point in the early days of roodial. If there is any further assistance that you need a long these lines let me know.

Best of luck!

1 Like

Thank you, @DrCWO! I didnā€™t realize ā€œDevice Volumeā€ worked as well. Everything is functioning great now! Thanks again!

1 Like

Just wanna say how much I appreciate rooDial. Itā€™s a game changer for me. So is the watch integration.

Desperately wanna upgrade to the Watch, beta and incompatibility is the only thing holding me back.

We hope Apple will fix the issue that is still in Beta 3ā€¦

Disappointed that it is still not fixed in beta three. Any ongoing updates you could provide would be appreciate it.

Dr, thank you once again for the rooDial.

I am reminded how thankful I am to you, each time I use it to crank up the volume!

Mine has been working properly for a couple years now. Should it ever fail, I may upgrade to the high-end roo6D.

I appreciate sophisticated design, but I donā€™t upgrade just to get something new, unless I just canā€™t live without it, lol. I am 69 years old and retired from the US Air Force. I am still working in my electronics systems repair field on Columbus AFB.

I wish you good day, sir.

1 Like

Thanksā€˜ for our nice words
Best DrCWO

Rob - I have both controls and I donā€™t know that I would refer to Roo6D as an upgrade. They are just different. RooDial is my favorite controller for simplicity, range, and battery lifeā€¦

Roo6D is not something to have in your living room if nicely decorated, has to be charged regularly, has an on/off switch.

2 Likes

It lasts for months until it has to be recharged, even if it is on all the time :slight_smile:
Best DrCWO

2 Likes

My Microsoft Surface Dial (less than a week old) is no longer able to change volume when I rotate it. It can still play/pause and change tracks when I push it. I tried new batteries, did a factory reset of rooExtend, and re-paired the Dial. Iā€™m on rooDial 1.5.4 and rooExtend 3.2.0. Iā€™d be grateful for any suggestions.

Check if you have selected the correct playback zone in rooDial settings. Also remember that volume changes by default only work if the selected zone is playing.

Best DrCWO

The correct zone is selected but the volume control isnā€™t working. The press functions work.