thewierdnut / asha_pipewire_sink

Asha audio protocol implementation for linux.
The Unlicense
28 stars 3 forks source link

Device volume control #6

Open thewierdnut opened 3 months ago

thewierdnut commented 3 months ago

I would like to be able to add a device-specific volume control, independent from the asha audio volume. My worry is that different hearing device manufacturers will all use different mechanisms to control this volume.

If anybody can reverse engineer their hearing devices to determine what the device volume control is, please let me know and I will add it to the below table.

Device Type Characteristic range
Audibel Arc AI 1200 f3f594f9-e210-48f3-85e2-4b0cf235a9d3 0x00 - 0xff
Oticon More 1 f3f594f9-e210-48f3-85e2-4b0cf235a9d3 0x00 - 0xff
Signia Styletto 7AX f3f594f9-e210-48f3-85e2-4b0cf235a9d3 0x00 - 0xff

To find the volume control on my hearing aids, I used bluetoothctl to explore the available characteristics. This is can be tedious, as there were about 90 characteristics to check, and reading some of them caused my hearing aids to stop responding until I restarted them.

First, attach your hearing device via bluetooth, then run bluetoothctl.

$ bluetoothctl
[Hearing Aids]# menu gatt
[Hearing Aids]# list-attributes

At this point, bluetoothctl will dump lots of output to the screen. You will want to copy and paste the output for reference. The Attributes we are looking for are Characteristics that are Vendor specific, like this:

Characteristic (Handle 0x0000)
        /org/bluez/hci0/dev_9C_9C_1D_96_2F_5E/service00ec/char0106
        f3f594f9-e210-48f3-85e2-4b0cf235a9d3
        Vendor specific

To check this characteristic, check its value, and see if it has the notification flag.

[Hearing Aids]# attribute-info f3f594f9-e210-48f3-85e2-4b0cf235a9d3
Characteristic - Vendor specific
        UUID: f3f594f9-e210-48f3-85e2-4b0cf235a9d3
        Service: /org/bluez/hci0/dev_9C_9C_1D_96_2F_5E/service00ec
        Value:
  36                                               6               
        Notifying: no
        Flags: read
        Flags: write
        Flags: notify
        MTU: 0x0200

If it says Flags: notify, then you can optionally enable notifications this way:

[Hearing Aids]# select-attribute f3f594f9-e210-48f3-85e2-4b0cf235a9d3
[Hearing Aids:/service00ec/char0106]# notify on
Notify started

Now, change the volume of your device. If you have notifications enabled, and it is the right characteristic, you should see a message like this:

[CHG] Attribute /org/bluez/hci0/dev_9C_9C_1D_96_2F_5E/service00ec/char0106 Value:

If you don't have notifications, then just run the attribute-info command again, and see if the Value: has changed.

barolo commented 3 months ago

Do the flags give any hint which one should it be? Should it have write for example? I have some which have write-without-response

thewierdnut commented 3 months ago

It will need to have one of write or write-without-response. I also assume that whatever bluetooth apps interact with the device will want to read the current volume state, which means it needs read, and also be notified if you press a volume button on the device, which would have notify.

I think you need, at a minimum, read, write, but you should prioritize testing of devices that have read, write, notify. All of the volume controls I have seen so far have been a single byte as well.

barolo commented 3 months ago

It will need to have one of write or write-without-response. I also assume that whatever bluetooth apps interact with the device will want to read the current volume state, which means it needs read, and also be notified if you press a volume button on the device, which would have notify.

I think you need, at a minimum, read, write, but you should prioritize testing of devices that have read, write, notify. All of the volume controls I have seen so far have been a single byte as well.

is changing volume via pipewire enough, or should I use asha_stream_test?

thewierdnut commented 3 months ago

is changing volume via pipewire enough, or should I use asha_stream_test?

Neither. Use a button on the hearing device itself, if you have it.

barolo commented 3 months ago

is changing volume via pipewire enough, or should I use asha_stream_test?

Neither. Use a button on the hearing device itself, if you have it.

That would be a problem, mine don't have any. Which means that I have to use the app, then check the value.

thewierdnut commented 3 months ago

That would be a problem, mine don't have any. Which means that I have to use the app, then check the value.

This procedure may not work for you then, as I presume your app has to be connected via bluetooth to your hearing devices (which probably only connect to one thing at a time.)

barolo commented 3 months ago

That would be a problem, mine don't have any. Which means that I have to use the app, then check the value.

This procedure may not work for you then, as I presume your app has to be connected via bluetooth to your hearing devices (which probably only connect to one thing at a time.)

But the volume sticks when I disconnect, so the value is changed.

thewierdnut commented 3 months ago

But the volume sticks when I disconnect, so the value is changed.

True.

An alternative would be to gather an hci dump from your hearing device. If you have an android phone, you can:

  1. enable hci traces using the developer menu,
  2. connect your hearing devices
  3. Make several volume changes
  4. disconnect your hearing devices
  5. use adb to pull the logs off of your phone.

I'm a little fuzzy on the details at the moment, but some googling about "getting a bluetooth log from android" should get you the information you need.

barolo commented 3 months ago

But the volume sticks when I disconnect, so the value is changed.

True.

An alternative would be to gather an hci dump from your hearing device. If you have an android phone, you can:

1. enable hci traces using the developer menu,

2. connect your hearing devices

3. Make several volume changes

4. disconnect your hearing devices

5. use adb to pull the logs off of your phone.

I'm a little fuzzy on the details at the moment, but some googling about "getting a bluetooth log from android" should get you the information you need.

here you go signia_bt.zip It's surprisingly spammy. I've changed the volume to max, min, then changed the volume of each side separately.

thewierdnut commented 3 months ago

Does your hearing device only have 16 volume levels?

I think your volume adjustment is written as two bytes to handle 0x00aa. I see you repeatedly writing the value 040z to that handle, where z is a hex value from 0 to f, and then your hearing device sends a response back as a notification on 0x00b2.

If you saved your output from the bluetoothctl list-attribute command, you should be able to find the UUID by looking for the handle embedded into the last four characters of the path. Once you know the uuid, you should be able to do this:

$ bluetoothctl
[Hearing Aid]# menu gatt
[Hearing Aid]# select-attribute UUID
[Hearing Aid:/service????/char00aa]# write "0x04 0x00"
<At this point, your hearing device should be muted>
[Hearing Aid:/service????/char00aa]# write "0x04 0x07"
<At this point, your hearing device should be at a medium volume>
[Hearing Aid:/service????/char00aa]# write "0x04 0x0f"
<At this point, your hearing device should be at its loudest>

If this doesn't work, then I've completely guessed wrong. The only other packet that I see being sent to your hearing aids is to 0x00c6, which appears to be a much more complex format that varies in size. I doubt I have much chance of decoding that without a lot more context.

barolo commented 3 months ago

Does your hearing device only have 16 volume levels?

Yes, from 0 to 15, if I remember correctly, by default it was less. I've just increased them myself through the fitting software.

Weirdly enough, I don't have any handles with such chars, is it perhaps because both sides are 'joined' as one device? Here's log of just one side btsnoop_hci.zip

barolo commented 3 months ago

wrote a simple bash script to output all attribute infos at once, for me it causes no problems with devices.

Usage example: ./script.sh <device-mac-address> <output-file>
./script.sh "20:3A:EF:BA:5C:BD" ./attribs.txt

#!/bin/bash

# Function to get the list of GATT characteristics
list_gatt_characteristics() {
    local device_mac=$1

    # Use bluetoothctl to list characteristics of the already connected device
    echo -e "menu gatt\nlist-attributes\nexit" | bluetoothctl
}

# Function to get attribute info for each characteristic
get_attribute_info() {
    local characteristic_uuid=$1

    # Use bluetoothctl to get attribute info
    echo -e "menu gatt\nattribute-info $characteristic_uuid\nexit" | bluetoothctl
}

# Main function to list characteristics and their attribute info
main() {
    local device_mac=$1
    local output_file=$2

    if [ -z "$device_mac" ] || [ -z "$output_file" ]; then
        echo "Usage: $0 <device-mac-address> <output-file>"
        exit 1
    fi

    characteristics=$(list_gatt_characteristics "$device_mac")

    while IFS= read -r line; do
        # Extract the characteristic UUID from the line
        if [[ $line =~ ([0-9a-fA-F\-]{36}) ]]; then
            characteristic_uuid=${BASH_REMATCH[1]}
            attribute_info=$(get_attribute_info "$characteristic_uuid")
            # Write only the attribute info part to the file, excluding unnecessary lines
            echo "$attribute_info" | grep -E "Characteristic|UUID|Service|Value|Flags|MTU" | grep -vE "menu|Available commands|clone|mselect-attribute|attribute-info|register|unregister|release|acquire|exit" >> "$output_file"
        fi
    done <<< "$characteristics"
}

# Call the main function with the provided arguments
main "$@"
barolo commented 3 months ago

There's also log from manufacturer's Android app, unsure if it's of any use. [changing volume of left side when only left is connected] AppLog_20240611_074425_bb0b8953-2918-4db0-a127-9eaa13b727a4.zip

thewierdnut commented 3 months ago

There's also log from manufacturer's Android app, unsure if it's of any use. [changing volume of left side when only left is connected] AppLog_20240611_074425_bb0b8953-2918-4db0-a127-9eaa13b727a4.zip

Wow.... this level of context is fantastic. If you captured this log along with the bluetooth log, and also did something where you waited a minute in between button presses, and noted the exact time you changed each control, we could completely decode this protocol.

thewierdnut commented 3 months ago

wrote a simple bash script to output all attribute infos at once, for me it causes no problems with devices.

That looks like it would easily provide the mappings from UUID's to handles we need to interpret the snoop file.

I also posted a tool here that dump all values of all attributes, and will subscribe to every notification available. It is interesting to see what values change over time. It will be less useful for you since your devices are entirely controlled via your app, and you can't connect to both the phone and the computer.

barolo commented 3 months ago

There's also log from manufacturer's Android app, unsure if it's of any use. [changing volume of left side when only left is connected] AppLog_20240611_074425_bb0b8953-2918-4db0-a127-9eaa13b727a4.zip

Wow.... this level of context is fantastic. If you captured this log along with the bluetooth log, and also did something where you waited a minute in between button presses, and noted the exact time you changed each control, we could completely decode this protocol.

I'll do that later in the day.

thewierdnut commented 3 months ago

Weirdly enough, I don't have any handles with such chars, is it perhaps because both sides are 'joined' as one device?

The 'joined' as one device is just a gui abstraction. Under the hood, they are always viewed as separate devices.

I still don't understand how the handles are mapped to bluez paths (having a grand sample size of 1 to study), but if you give me the output of the bluetoothctl gatt.list-attributes command, I'll see if I can find it.

barolo commented 3 months ago

Weirdly enough, I don't have any handles with such chars, is it perhaps because both sides are 'joined' as one device?

The 'joined' as one device is just a gui abstraction. Under the hood, they are always viewed as separate devices.

I still don't understand how the handles are mapped to bluez paths (having a grand sample size of 1 to study), but if you give me the output of the bluetoothctl gatt.list-attributes command, I'll see if I can find it.

attributes.zip

barolo commented 3 months ago

There's also log from manufacturer's Android app, unsure if it's of any use. [changing volume of left side when only left is connected] AppLog_20240611_074425_bb0b8953-2918-4db0-a127-9eaa13b727a4.zip

Wow.... this level of context is fantastic. If you captured this log along with the bluetooth log, and also did something where you waited a minute in between button presses, and noted the exact time you changed each control, we could completely decode this protocol.

They left the debug pages, which I've triggered accidentally [6 clicks on the Volume text above the slider...]

Also, there's a lot to do, since there's so called assistant which has a slightly nerfed reprogramming capabilities [meaning that through some AI chat abstractions you can do reprogramming which is usually reserved to a fitting software] and it actually has an entire separate debug page.

thewierdnut commented 3 months ago

Lol... starkey's app includes.... a volume control. That's it. The rest of the app is dedicated to helping old people stay active.

barolo commented 3 months ago

Lol... starkey's app includes.... a volume control. That's it. The rest of the app is dedicated to helping old people stay active.

🫨 It's abhorrently slow though, it's built on xamarin and uses 300~ libs [also visible through debug pages..] Probably because it also has inbuilt remote video Telecare.

thewierdnut commented 3 months ago

I'm not sure this project is the one to do it, but I would like to create a new project that documents these controls, and perhaps provides a gui of some kind to control them.

barolo commented 3 months ago

I'm not sure this project is the one to do it, but I would like to create a new project that documents these controls, and perhaps provides a gui of some kind to control them.

I don't think that they're universal across devices though, perhaps some basic ones, For more advanced stuff you'd have to reverse engineer NOAH wireless programming protocol which is universal, but again fitting softwares are not.

thewierdnut commented 3 months ago

There would have to be some abstraction and documentation of what controls are available. I can already tell you that your volume controls don't look anything like mine.

thewierdnut commented 3 months ago

Lol... starkey's app includes.... a volume control. That's it. The rest of the app is dedicated to helping old people stay active.

Wow... I just reinstalled the starkey app, and it has a lot more features than it used to. I can actually make some headway at decoding a lot of this now.

I've made a wiki entry documenting everything I have figured out for my hearing aids. We can probably do the same for you if you like. Hopefully even if this app ends up dying the slow death I hope it does after mainstream asha support makes its way into bluez, the knowledge gained here won't be wasted.

barolo commented 3 months ago

Lol... starkey's app includes.... a volume control. That's it. The rest of the app is dedicated to helping old people stay active.

Wow... I just reinstalled the starkey app, and it has a lot more features than it used to. I can actually make some headway at decoding a lot of this now.

I've made a wiki entry documenting everything I have figured out for my hearing aids. We can probably do the same for you if you like. Hopefully even if this app ends up dying the slow death I hope it does after mainstream asha support makes its way into bluez, the knowledge gained here won't be wasted.

For sure it won't be wasted, we would actually have some decent coverage with just two or three manufacturers. (we had someone with Oticons/Philips here which would boost coverage significantly, Phonak isn't using ASHA) I'll do the same tomorrow, don't have much time today.

With something like this making a speedy universal app for basics doesn't seem too insane.

MadSpindel commented 3 months ago

I'm not sure if I understood how to use gatt_dump, but I compiled and started it, then at the end of this log, I used the volume up button 5 times on my left ear and the volume button down 4 times on my right ear. So the last 4 entries should be volume down:

./gatt_dump 
(process:22641): GLib-GIO-DEBUG: 13:29:17.186: Using cross-namespace EXTERNAL authentication (this will deadlock if server is GDBus < 2.73.3)
** INFO: 13:29:17.196: Adding bluetooth device Fredrik
Fredrik with 9 services
   00001801-0000-1000-8000-00805f9b34fb
      00002b2a-0000-1000-8000-00805f9b34fb [read] a0 ba f2 a9 2f 35 59 56 b3 72 ac d4 fe b0 8a 18 "\240\272\362\251/5YV\263r\254\324\376\260\212\030"
      00002b29-0000-1000-8000-00805f9b34fb [read, write] 01 "\001"
      00002a05-0000-1000-8000-00805f9b34fb [indicate] 
   0000180a-0000-1000-8000-00805f9b34fb
      00002a28-0000-1000-8000-00805f9b34fb [read] 31 2e 34 2e 34 "1.4.4"
      00002a27-0000-1000-8000-00805f9b34fb [read]  ""
      00002a26-0000-1000-8000-00805f9b34fb [read] 72 65 6c 5f 35 2e 34 5f 33 34 2e 30 "rel_5.4_34.0"
      00002a29-0000-1000-8000-00805f9b34fb [read] 4f 74 69 63 6f 6e "Oticon"
      00002a24-0000-1000-8000-00805f9b34fb [read] 4d 6f 72 65 20 31 "More 1"
   ba50125d-0806-42ab-8bf1-22e0b954a8fa
      80911332-ead5-4da0-9bfa-4d6286032e25 [notify] [subscribed] 
      ed5f901b-fb08-452c-8d01-46b6c9c1bcc5 [notify] [subscribed] 
      5eb7ff93-ebeb-479c-85ab-526f25482545 [notify] [subscribed] 
      f6c47754-8bd2-4cc2-bf0b-fdee78fa812e [write, write-without-response] 
      6d6a8b8f-544e-4ef1-be91-c60db8e70884 [write, write-without-response] 
      855c8579-17b7-40a8-be4f-ad574357f797 [write, write-without-response] 
      43c8465e-ba80-451d-8098-57716b4fdbe5 [notify, write] [subscribed] 
      e6c02a45-a0e5-41f2-9cd1-c1fab9ec0c3e [read] 01 01 01 00 00 f4 05 03 80 80 80 00 "\001\001\001\0\0\364\005\003\200\200\200\0"
   8341f2b4-c013-4f04-8197-c4cdb42e26dc
      30e69638-3752-4feb-a3aa-3226bcd05ace [notify, read, write] [subscribed]  <not read>
      2bdcaebe-8746-45df-a841-96b840980fb8 [read]  <not read>
      2bdcaebe-8746-45df-a841-96b840980fb7 [read]  <not read>
      0188bf66-463a-405d-91fd-0b8940b92254 [read] 00 03 "\0\003"
   7d74f4bd-c74a-4431-862c-cce884371592
      61d1b37d-94d5-4281-a88f-9b67f8f96314 [notify, read] [subscribed] 01 00 00 00 "\001\0\0\0"
      8e750bb1-40c1-48df-b450-97f245c57e0c [read] 00 "\0"
      98924a39-6559-40a8-b302-3c8e40dbf834 [read] 00 "\0"
      76b3db1f-44c4-46cc-a7b5-e9ce7dfbef50 [read] 00 "\0"
      4656d3ac-c2df-4096-96e7-713580b69ccd [notify, read, write] [subscribed] 00 "\0"
      16438c66-e95a-4c6f-8117-a6b745bd86fc [read] 01 00 00 00 "\001\0\0\0"
      9c12a3db-9ce8-4865-a217-d394b3bc9311 [read, write] ff "\377"
      7be94a55-8d91-4592-bc0f-ea3664ccd3a9 [read, write] 52 65 6d 6f 74 65 20 4d 69 63 20 31 "Remote Mic 1"
      a28b6be1-2fa4-42f8-aeb2-b15a1dbd837a [read, write] 05 "\005"
      adc3023d-bfd2-43fd-86f6-7ae05a619092 [notify, read] [subscribed] bf 03 00 00 "\277\003\0\0"
      a391c6f1-20bb-495a-abbf-2017098fbc61 [notify, read, write] [subscribed] 00 "\0"
      21ff4275-c41d-4486-a0e3-dc11138bcde6 [read] 31 "1"
      6ac46200-24ea-46d8-a136-81133c65840a [notify, read, write] [subscribed] 00 "\0"
      f3f594f9-e210-48f3-85e2-4b0cf235a9d3 [notify, read, write] [subscribed] a2 "\242"
      497eeb9e-b194-4f35-bc82-36fd300482a6 [read] 51 41 52 34 2d 27 "QAR4-'"
      c97d21d3-d79d-4df8-9230-bb33fa805f4e [read] 51 41 52 60 3c 37 "QAR`<7"
      8d17ac2f-1d54-4742-a49a-ef4b20784eb3 [read] 00 "\0"
      24e1dff3-ae90-41bf-bfbd-2cf8df42bf87 [notify, read] [subscribed] 08 "\b"
   56772eaf-2153-4f74-acf3-4368d99fbf5a
      d5d0affb-35b8-4fdc-a50b-f777c90293b8 [notify, read] [subscribed] 4c 63 56 "LcV"
      786ff607-774d-49d6-80a5-a17e08823d91 [write, write-without-response] 
      51939bb6-a635-4b1e-903b-76cd9dff3fac [notify, read, write, write-without-response] [subscribed] 16 "\026"
      bc6829c4-b750-48e6-b6f4-48ec866a1efb [read] 00 00 4e 80 00 1f 40 7c "\0\0N\200\0\037@|"
      d01ab591-d282-4ef5-b83b-538e0bf32d85 [notify, read] [subscribed] 00 ff 01 fa 7b 43 8e 19 00 04 "\0\377\001\372{C\216\031\0\004"
      58bbccc5-5a57-4e00-98d5-18c6a0408dfd [notify, read] [subscribed] f8 04 00 12 fb 00 "\370\004\0\022\373\0"
      50632720-4c0f-4bc4-960a-2404bdfdfbca [notify, read, write, write-without-response] [subscribed] 0f 00 "\017\0"
      6e557876-ccc4-40e0-8c2d-651542c5ad3d [notify, read, write, write-without-response] [subscribed] 34 ff 53 48 35 18 aa ae 9f c2 00 00 4a 00 00 05 ee 0c f3 2f "4\377SH5\030\252\256\237\302\0\0J\0\0\005\356\f\363/"
      9215a295-b813-483f-9f85-b700d0b7bc75 [notify, read, write, write-without-response] [subscribed] 00 00 01 02 02 02 02 02 03 "\0\0\001\002\002\002\002\002\003"
      60415e72-c345-417a-bb2b-bbba95b2c9a3 [notify, read, write, write-without-response] [subscribed] 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
      e5892ebe-97d0-4f97-8f8e-cb85d16a4cc1 [notify, read, write, write-without-response] [subscribed] 00 01 "\0\001"
      1454e9d6-f658-4190-8589-22aa9e3021eb [notify, read, write, write-without-response] [subscribed] 00 01 "\0\001"
      535442f7-0ff7-4fec-9780-742f3eb00eda [notify, read, write, write-without-response] [subscribed] 00 "\0"
      42e940ef-98c8-4ccd-a557-30425295af89 [notify, read] [subscribed] bf 03 00 00 "\277\003\0\0"
      bba1c7f1-b445-4657-90c3-8dbd97361a0c [read] 00 "\0"
      68bfa64e-3209-4172-b117-f7eafce17414 [notify, read, write] [subscribed] ff "\377"
      dcbe7a3e-a742-4527-aeb5-cd8dee63167f [read] 31 "1"
      6d5758a1-d4af-4b32-b95e-1e6992454f4f [write, write-without-response] 
      353ecc73-4d2c-421b-ac1c-8dcb35cd4477 [read] 51 41 52 34 2d 27 "QAR4-'"
      5f35c43d-e0f4-4da9-87e6-9719982cd25e [read] 51 41 52 60 3c 37 "QAR`<7"
      d28617fe-0ad5-40c5-a04a-bc89051ff755 [read] 00 "\0"
      e24fac83-b5a8-4b9b-8fda-803fffb0c21c [read] 01 "\001"
   0a23ae62-c4c2-43d1-87b1-e8c83839a063
      62dcc92f-59c2-4228-9a11-c85f18773530 [write, write-without-response] 
      ebee6f69-70b6-4bb9-b13b-9ba84953c233 [notify, read, write, write-without-response] [subscribed] 00 "\0"
      34dfc7cb-5252-430b-ba6d-df2fe87914e7 [notify] [subscribed] 
      6efab52e-3002-4764-9430-016cef4dfc87 [write-without-response] 
   0000fdf0-0000-1000-8000-00805f9b34fb
      2d410339-82b6-42aa-b34e-e2e01df8cc1a [read] 80 00 "\200\0"
      00e4ca9e-ab14-41e4-8823-f9e70c7e91df [write-without-response] 
      38663f1a-e711-4cac-b641-326b56404837 [notify, read] [subscribed] 00 "\0"
      f0d4de7e-4a88-476c-9d9f-1937b0996cc0 [write, write-without-response] 
      6333651e-c481-4a3e-9169-7c902aad37bb [read] 01 02 07 01 51 41 52 60 3c 37 01 59 00 00 00 02 00 "\001\002\a\001QAR`<7\001Y\0\0\0\002\0"
   4f6cf751-176c-4de1-a25e-d218f1901ccf
      6c9bb68d-1e4e-4073-944f-6b06d849446d [notify] [subscribed] 
      19d82b8b-f66f-43df-a843-8508e2da564a [write] 
      c7e127d3-0215-43e6-bc26-3f331d3747a2 [read] 01 00 "\001\0"
** INFO: 13:29:20.932: Adding bluetooth device Fredrik
Notify: 61d1b37d-94d5-4281-a88f-9b67f8f96314 01 00 00 00
Notify: 4656d3ac-c2df-4096-96e7-713580b69ccd 00
Notify: adc3023d-bfd2-43fd-86f6-7ae05a619092 bf 03 00 00
Notify: a391c6f1-20bb-495a-abbf-2017098fbc61 00
Notify: 6ac46200-24ea-46d8-a136-81133c65840a 00
Notify: f3f594f9-e210-48f3-85e2-4b0cf235a9d3 a2
Notify: 24e1dff3-ae90-41bf-bfbd-2cf8df42bf87 08
Notify: d5d0affb-35b8-4fdc-a50b-f777c90293b8 4c 63 56
Notify: 51939bb6-a635-4b1e-903b-76cd9dff3fac 16
Notify: d01ab591-d282-4ef5-b83b-538e0bf32d85 00 ff 01 fa 7b 43 8e 19 00 04
Notify: 58bbccc5-5a57-4e00-98d5-18c6a0408dfd f8 04 00 12 fb 00
Notify: 50632720-4c0f-4bc4-960a-2404bdfdfbca 0f 00
Notify: 6e557876-ccc4-40e0-8c2d-651542c5ad3d 34 ff 53 48 35 18 aa ae 9f c2 00 00 4a 00 00 05 ee 0c f3 2f
Notify: 9215a295-b813-483f-9f85-b700d0b7bc75 00 00 01 02 02 02 02 02 03
Notify: 60415e72-c345-417a-bb2b-bbba95b2c9a3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Notify: e5892ebe-97d0-4f97-8f8e-cb85d16a4cc1 00 01
Notify: 1454e9d6-f658-4190-8589-22aa9e3021eb 00 01
Notify: 535442f7-0ff7-4fec-9780-742f3eb00eda 00
Notify: 42e940ef-98c8-4ccd-a557-30425295af89 bf 03 00 00
Notify: 68bfa64e-3209-4172-b117-f7eafce17414 ff
Notify: ebee6f69-70b6-4bb9-b13b-9ba84953c233 00
Notify: 38663f1a-e711-4cac-b641-326b56404837 00
Notify: d5d0affb-35b8-4fdc-a50b-f777c90293b8 4b 63 56
Notify: 51939bb6-a635-4b1e-903b-76cd9dff3fac 15
Notify: 1454e9d6-f658-4190-8589-22aa9e3021eb 01 01
Notify: f3f594f9-e210-48f3-85e2-4b0cf235a9d3 b5
Notify: 51939bb6-a635-4b1e-903b-76cd9dff3fac 15
Notify: 1454e9d6-f658-4190-8589-22aa9e3021eb 02 01
Notify: f3f594f9-e210-48f3-85e2-4b0cf235a9d3 c8
Notify: 51939bb6-a635-4b1e-903b-76cd9dff3fac 15
Notify: 1454e9d6-f658-4190-8589-22aa9e3021eb 03 01
Notify: f3f594f9-e210-48f3-85e2-4b0cf235a9d3 db
Notify: 51939bb6-a635-4b1e-903b-76cd9dff3fac 15
Notify: 1454e9d6-f658-4190-8589-22aa9e3021eb 04 01
Notify: f3f594f9-e210-48f3-85e2-4b0cf235a9d3 ff
Notify: 51939bb6-a635-4b1e-903b-76cd9dff3fac 17
Notify: 1454e9d6-f658-4190-8589-22aa9e3021eb 04 01
Notify: f3f594f9-e210-48f3-85e2-4b0cf235a9d3 ff
Notify: 51939bb6-a635-4b1e-903b-76cd9dff3fac 15
Notify: 1454e9d6-f658-4190-8589-22aa9e3021eb 03 01
Notify: f3f594f9-e210-48f3-85e2-4b0cf235a9d3 db
Notify: 51939bb6-a635-4b1e-903b-76cd9dff3fac 15
Notify: 1454e9d6-f658-4190-8589-22aa9e3021eb 02 01
Notify: f3f594f9-e210-48f3-85e2-4b0cf235a9d3 c8
Notify: 51939bb6-a635-4b1e-903b-76cd9dff3fac 15
Notify: 1454e9d6-f658-4190-8589-22aa9e3021eb 01 01
Notify: f3f594f9-e210-48f3-85e2-4b0cf235a9d3 b5
Notify: 51939bb6-a635-4b1e-903b-76cd9dff3fac 16
Notify: 1454e9d6-f658-4190-8589-22aa9e3021eb 00 01
Notify: f3f594f9-e210-48f3-85e2-4b0cf235a9d3 a2
thewierdnut commented 3 months ago

I'm not sure if I understood how to use gatt_dump, but I compiled and started it, then at the end of this log, I used the volume up button 5 times on my left ear and the volume button down 4 times on my right ear. So the last 4 entries should be volume down:

gatt_dump will only connect with one device, and in this case it looks like it was your left ear.

Interesting. You have the same service id 7d74f4bd-c74a-4431-862c-cce884371592 that I do, and the characteristics all appear to have the same meanings. That includes your volume control at f3f594f9-e210-48f3-85e2-4b0cf235a9d3.

thewierdnut commented 3 months ago

Nice, it looks like you also have 24e1dff3-ae90-41bf-bfbd-2cf8df42bf87, which is a battery level from 0 to 10

MadSpindel commented 3 months ago

00002a28-0000-1000-8000-00805f9b34fb [read] 31 2e 34 2e 34 "1.4.4" 1.4.4 is the firmware version.

I know they are using Zephyr RTOS for Bluetooth LE connectivity: https://www.zephyrproject.org/zephyr-on-a-hearing-aid-oticon-more/

Not sure if the same service id could indicate that yours are also using Zephyr RTOS?

thewierdnut commented 3 months ago

Not sure if the same service id could indicate that yours are also using Zephyr RTOS?

Not necessarily. I have two versions of the service, where the values are formatted slightly differently. Its like starkey had its own version, then implemented a common version later. The rest of the services are different.

barolo commented 3 months ago

@thewierdnut I've made parallel and timed logs from manufactuer's app and btsnoop. Let me know if they're usefull. Logs.zip

- Volume slider
16:00: left set to max, val 15
16:01: right set to max, val 15 
16:02: left set to min vol
16:03: right set to  min vol
16:04: joined sliders together and volume set to val 8/default
- Balance slider soft---sharp
16:05: set sharpness to max
16:06: set softness to max
16:07: set to neutral/middle position
- Directionality 
16:08: set mics to omnidirectional mode | 360°
16:09: set mics to front focus | 180°
16:10: set mics to auto
- Battery
16:11: open battery panel

Also, I've realized just now that I've been gathering the btsnoop logs wrong.

barolo commented 3 months ago

It's this one isn't it? c8f747ac-21b2-45b8-87f8-bd49a13eff49

thewierdnut commented 3 months ago

It's this one isn't it? c8f747ac-21b2-45b8-87f8-bd49a13eff49

I can't tell from the information you have given me. I either need the output from bluetoothct gatt.list-attributes, or you can try the gatt_dump utility, which I just updated to post the dbus path of each attribute (which embeds the bluetooth handles)

thewierdnut commented 3 months ago

I'm not sure if I understood how to use gatt_dump, but I compiled and started it, then at the end of this log, I used the volume up button 5 times on my left ear and the volume button down 4 times on my right ear. So the last 4 entries should be volume down:

gatt_dump will only connect with one device, and in this case it looks like it was your left ear.

Interesting. You have the same service id 7d74f4bd-c74a-4431-862c-cce884371592 that I do, and the characteristics all appear to have the same meanings. That includes your volume control at f3f594f9-e210-48f3-85e2-4b0cf235a9d3.

I've added a wiki entry for the Oticon More 1. Let me know if you see anything incorrect or if you want to add anything there.

barolo commented 3 months ago

It's this one isn't it? c8f747ac-21b2-45b8-87f8-bd49a13eff49

I can't tell from the information you have given me. I either need the output from bluetoothct gatt.list-attributes, or you can try the gatt_dump utility, which I just updated to post the dbus path of each attribute (which embeds the bluetooth handles)

I though that I could correlate things looking at timings and logs snopp and app. Here's what gatt_dump outputs: gatt.dump.txt

thewierdnut commented 3 months ago

I though that I could correlate things looking at timings and logs snopp and app. Here's what gatt_dump outputs: gatt.dump.txt

Interesting. You also have the 7d74f4bd-c74a-4431-862c-cce884371592 service, with its battery level and volume control. That dump is your left hearing aid and your battery level reads as 100% and your volume reads at about 53%. Is that right?

barolo commented 3 months ago

and this one is after changing volume to 14: gatt.dump.txt

barolo commented 3 months ago

I though that I could correlate things looking at timings and logs snopp and app. Here's what gatt_dump outputs: gatt.dump.txt

Interesting. You also have the 7d74f4bd-c74a-4431-862c-cce884371592 service, with its battery level and volume control. That dump is your left hearing aid and your battery level reads as 100% and your volume reads at about 53%. Is that right?

correct

thewierdnut commented 3 months ago

and this one is after changing volume to 14: gatt.dump.txt

That changed your volume to 93%, which matches since your max volume is 15.

thewierdnut commented 3 months ago

This is great. I should be able to implement the characteristics in service 7d74f4bd-c74a-4431-862c-cce884371592, and it seems to handle all of our devices so far.

thewierdnut commented 3 months ago

@barolo I'm thinking that your log dumps may be less useful now because they seem to control the volume via a different, more complicated interface than the common one. If you would like, you can try controlling your volume using the common interface, just to make sure that it works. The argument is number from 0 to 255, written in the example using hexidecimal.

$ bluetoothctl
[Hearing Aids]# gatt.select-attribute f3f594f9-e210-48f3-85e2-4b0cf235a9d3
[Hearing Aids:/service00ec/char0106]# gatt.write 0x00
[Hearing Aids:/service00ec/char0106]# gatt.write 0x80
[Hearing Aids:/service00ec/char0106]# gatt.write 0xf0
barolo commented 3 months ago

@barolo I'm thinking that your log dumps may be less useful now because they seem to control the volume via a different, more complicated interface than the common one. If you would like, you can try controlling your volume using the common interface, just to make sure that it works. The argument is number from 0 to 255, written in the example using hexidecimal.

$ bluetoothctl
[Hearing Aids]# gatt.select-attribute f3f594f9-e210-48f3-85e2-4b0cf235a9d3
[Hearing Aids:/service00ec/char0106]# gatt.write 0x00
[Hearing Aids:/service00ec/char0106]# gatt.write 0x80
[Hearing Aids:/service00ec/char0106]# gatt.write 0xf0

Amazing... this worked, changed the volume of my left side.

Just making sure, we're figuring out the volume unrelated to streaming [well, it slightly related since you can mute the outside mics basically], as this controls environmental volume, right?

thewierdnut commented 3 months ago

Just making sure, we're figuring out the volume unrelated to streaming [well, it slightly related since you can mute the outside mics basically], as this controls environmental volume, right?

Yes. I want to add a separate volume control for it if I can figure out how, and perhaps an option to mute the microphone when audio is streaming.

barolo commented 3 months ago

It's so freaking quick to change the volume, I'm amazed. It can be a real pain sometimes with the app. Which matters to me since I don't have physical volume buttons. Also, am I getting it right, the volume has 250 steps? I've just tried 0xb4 and 0xc8 and it works.

thewierdnut commented 3 months ago

Interestingly, this is exact service uuid, 7d74f4bd-c74a-4431-862c-cce884371592, is embedded in the le extended advertisement packets sent by my hearing aids.

shermp commented 3 months ago

Note, the service 7d74f4bd-c74a-4431-862c-cce884371592 appears to be the MFI service. At least according to Android: https://cs.android.com/android/platform/superproject/main/+/main:packages/modules/Bluetooth/framework/java/android/bluetooth/BluetoothUuid.java;l=271?q=7d74f4bd-c74a-4431-862c-cce884371592&ss=android%2Fplatform%2Fsuperproject%2Fmain

barolo commented 3 months ago

Note, the service 7d74f4bd-c74a-4431-862c-cce884371592 appears to be the MFI service. At least according to Android: https://cs.android.com/android/platform/superproject/main/+/main:packages/modules/Bluetooth/framework/java/android/bluetooth/BluetoothUuid.java;l=271?q=7d74f4bd-c74a-4431-862c-cce884371592&ss=android%2Fplatform%2Fsuperproject%2Fmain

I was suspecting something like this, as I've noticed mentions of MFi. And it's the simple one, since it's directly integrated into system bypassing the apps. So we're using MFi actually? xD

shermp commented 3 months ago

Pretty sure Android uses it too, as I can control my HA volume from the system settings as well as the Oticon app.

barolo commented 3 months ago

Pretty sure Android uses it too, as I can control my HA volume from the system settings as well as the Oticon app.

Interesting, I don't think that I have such option [Android 13]