Luminescent Dreams

Weekly Ramblings for June 9th, 2022

June 09, 2022
Geese!, 2018-11

Been a while, y’all! No sooner did I make my website multilingual than I ran out of any energy to actually do any writing. Nevertheless, I am back and it’s time to ramble a bit.


Over the course of the last year and a few months, I’ve gotten vaguely on the Zettlekasten (or Second Brain) bandwagon. I’ve actually been sticking to it, though I’m pretty terrible at actually processing my backlog of information. Yet even with my backlog continuing to pile up, I’m finding it an invaluable tool for organizing information and making sure that I can actually find things afterwards.

Obsidian is my tool of choice, though for the most part I’m keeping it vanilla. I like the ease of flipping between raw Markdown mode and nicely rendered mode. Since I can trivially link a new file and trivially follow those links, I have become much more inclined to break my notes apart into smaller bits.

Over the next few months, I intend to draw the veil back with real information. Most of the videos and explanations that I find on the internet are pretty generalized and rarely ever talk about anything other than the philosophy of the Zettlekasten. So, I should actually reveal some concrete work.


I have a huge number of interests and gather new ones on a regular basis. I finally grabbed hold of the BlueR library for Rust and started trying to probe the knock-off fitness tracking watch that I bought a few years ago. In so doing, I also had to start learning about Bluetooth itself.

The core Bluetooth spec is over 3000 pages long. I find this mind-boggling. Actually, it seems vastly excessive to me. There is no way for any person, or even small group of people, to actually understand the whole document. And perhaps that is okay, since some hundreds of those pages specify the physical link layers, but damn. Basically, I haven’t figured out some of the basic concepts because this is a huge document for me to dig through.

But here are the basic components that I can see:

  • Device
  • Profile
  • Service
  • Service Class
  • Characteristic
  • Property
  • GATT

Then there are a lot of defined services which follow a set of standards. For instance, I grabbed the Battery Service document and read a bit of it. Just enough to be able to connect to my headset and read the battery level from it.

In any case, here’s the descriptor I can read from my fitness tracker watch:

device: Device { adapter_name: hci0, address: E3:09:3A:69:A9:9E }
    address_type:         LeRandom
    name:                 Some("ID115Pro")
    uuids:                Some({00001800-0000-1000-8000-00805f9b34fb, 00000af0-0000-1000-8000-00805f9b34fb, 00001801-0000-1000-8000-00805f9b34fb})
    paired:               false
    connected:            true
    trusted:              false
UUID processing
    Ok(GenericAttribute)    Ok(GenericAttrib)
    Err(00000af0-0000-1000-8000-00805f9b34fb)    Err(00000af0-0000-1000-8000-00805f9b34fb)
    Ok(GenericAccess)    Ok(GenericAccess)

It’s not entirely clear to me what all of this means. To some degree, I believe that the uuids on the device are supposed to indicate service UUIDs. It appears that some of the UUIDs aren’t registered and so aren’t known to anything else.

Long story short, I was unable to find anything comprehensible on the watch. I believe that all of the useful information I would want on the watch is actually stored in the GenericAccess attributes.

I’ve largely hit a roadblock here, but I have also found a Bluetooth sniffer application for Android, and so I may just install that and see if I can use it to record a transaction in progress when the knock-off software that can communicate with the watch actually pulls data from it. However, that is research for another time.

However, here is a similar output for my headset, which is itself a bit more interesting since I was able to grab the battery level from it:

device: Device { adapter_name: hci0, address: 00:1B:66:CD:B0:82 }
    address_type:         LePublic
    name:                 Some("LE-MOMENTUM 3")
    icon:                 Some("audio-headset")
    class:                Some(2360324)
    uuids:                Some({0000feed-0000-1000-8000-00805f9b34fb, 00001108-0000-1000-8000-00805f9b34fb, 00001200-0000-1000-8000-00805f9b34fb, 0000111e-0000-1000-8000-00805f9b34fb, 0000180a-0000-1000-8000-00805f9b34fb, 0000fdce-0000-1000-8000-00805f9b34fb, 0000110d-0000-1000-8000-00805f9b34fb, 931c7e8a-540f-4686-b798-e8df0a2ad9f7, 0000180f-0000-1000-8000-00805f9b34fb, 00001801-0000-1000-8000-00805f9b34fb, 0000110e-0000-1000-8000-00805f9b34fb, 00000000-deca-fade-deca-deafdecacaff, 0000110c-0000-1000-8000-00805f9b34fb, 1ddce62a-ecb1-4455-8153-0743c87aec9f, 0000110b-0000-1000-8000-00805f9b34fb, 0000fe03-0000-1000-8000-00805f9b34fb, 00001800-0000-1000-8000-00805f9b34fb})
    paired:               true
    connected:            true
    trusted:              true
UUID processing
    Ok(GenericAttribute)    Ok(GenericAttrib)
    Err(0000110c-0000-1000-8000-00805f9b34fb)    Ok(AvRemoteTarget)
    Err(0000110b-0000-1000-8000-00805f9b34fb)    Ok(AudioSink)
    Err(0000111e-0000-1000-8000-00805f9b34fb)    Ok(Handsfree)
    Err(00001200-0000-1000-8000-00805f9b34fb)    Ok(PnpInfo)
    Ok(DeviceInformation)    Err(0000180a-0000-1000-8000-00805f9b34fb)
    Ok(BatteryService)    Err(0000180f-0000-1000-8000-00805f9b34fb)
    Ok(GenericAccess)    Ok(GenericAccess)
    Err(0000110e-0000-1000-8000-00805f9b34fb)    Ok(AvRemote)
    Err(00001108-0000-1000-8000-00805f9b34fb)    Ok(Headset)
    Err(0000110d-0000-1000-8000-00805f9b34fb)    Ok(AdvancedAudio)

battery service detected: Service { adapter_name: hci0, device_address: 00:1B:66:CD:B0:82, id: 35 }
characteristic: Characteristic { adapter_name: hci0, device_address: 00:1B:66:CD:B0:82, service_id: 35, id: 36 }

Some are services, others are service classes. There are additional ones that I’ve deleted that don’t correspond to anything.

What I can do with this I don’t know. One thing interesting that it shows, though, is that an audio headset, which does not require any special software, implements a lot of standard services that get involved with hooking the headset into the Linux device drivers.

I purposely set myself a time limit on this post so that I could be sure to actually get it written, and I have run out of time. I have so much additional research to do and so much more to learn. I’ll be sure to share it as I learn to make sense of things.