Experimental bluetooth headset battery monitoring application for MacOS

611
24
Swift

⚠️ IMPORTANT ⚠️

MacOS monterey now supports 3rd party bluetooth headsets by itself!
I have therefore decided to stop development on this project.

This app will not work on Monterey, I have no plans on adding adding compatibility with Monterey, and I recommend not using it at all on Monterey to begin with.
You can read my full announcement here.


Akku

The missing macOS bluetooth headset battery indicator app.

Build Status
GitHub pre-release
GitHub release

What does it do?

  • Displays headset battery status, which can’t be viewed on macOS at all (only for Apple accessories).
  • (Optionally) notifies you when headset battery gets low.
  • Menu bar icon.

Download

DMG

Get the latest .DMG here.

brew cask

Coming soon once app goes stable.

Compatibility

It will work with any headset that conforms to the Apple bluetooth spec*

Translation:
If your Android device can read it’s battery status, it will very likely work.
If your iPhone device can read your headset’s battery status, it will work.


* = You read that correctly, Apple did not bother to implement their own specifications on the Mac.

FAQ

My device doesn’t work!

Whilst we’re still in beta, it might be possible that Akku reports that it can’t find any battery status for your device.
Before opening an issue, check the following:

  • If you have a iPhone/Android device, please confirm that it shows you the battery status.
    If not, chances are high that your device simply doesn’t support battery statuses.
  • If you just installed Akku, reconnect at least once.
  • If your phone can read the status, but Akku can’t, please follow this guide that tells you what data you need to provide in order for us to fix the issue.

I don’t want Akku in my menubar all the time!

Use Bartender to hide it, and configure it to only show Akku on changes.
I recommend the following config:

Will this app be in the App Store?

No. Like most of my apps, it uses pretty unorthodox API’s that will very likely not work in the app sandbox and/or be approved by Apple.
However, Akku contains a automatic updater that will keep it up to date, and additionally, you can manually check by clicking ‘Check for updates’ from it’s menu.

How does it work?

The simple explanation:
You give it root, and it will monitor all bluetooth communication that goes through the system to intercept battery indicator commands.

The hard explanation:
You give it root, and it will install a helper application.
The helper proceeds to communicate to the app through XPC
Once the helper is activated, it will communicate with the IOBluetoothHCIController driver through IOKit
It will map a region of memory from the kernel to Akku, and scan through the raw bluetooth data.
Akku can currently decode HCI events, L2CAP packets and RFCOMM packets (RFCOMM is build upon L2CAP).
Once it has exhausted said bluetooth data, it will poll and instruct the system to dump any new data to Akku’s mapped memory every 5 seconds.
The only communication that goes back to the non-privileged process is the normalized battery indication signals.
Both Akku and it’s helper verify their signatures to ensure no unauthorized access is made.
Both are codesigned with a valid Apple developer cert.

Inspirations / Shoutouts

  • Jeff Reiner // @mirshko
    Icon Design, moral support 😍
  • SwiftPrivilegedHelper
    Great starting point to implement helper installation & XPC communication, thanks @ekkrik!
  • cocoapods-amimono
    Needed to embed the pods into the helper itself, which is not really something cocoapods is designed to do.
    Luckily amimono was there, despite needing a few more patches to make it do what I wanted.
  • Android’s BluetoothHeadset.java
    Gives some good information on the vendor specific AT commands that Android accepts.
  • Wireshark
    Wouldn’t have gotten anywhere with figuring out the raw bluetooth data without wireshark.