Note
|
Shell output is omitted for the sake of brevity. |
❯ cargo build --release
❯ cp target/release/blemacd /usr/local/bin/
❯ sudo cp etc/com.github.blemacd.plist /Library/LaunchDaemons/
❯ launchctl load /Library/LaunchDaemons/com.github.blemacd.plist
❯ launchctl start com.github.blemacd
System should request your permission to use Bluetooth.
❯ launchctl stop com.github.blemacd
❯ launchctl unload /Library/LaunchDaemons/com.github.blemacd.plist
❯ launchctl stop com.github.blemacd
❯ launchctl unload /Library/LaunchDaemons/com.github.blemacd.plist
❯ sudo rm /Library/LaunchDaemons/com.github.blemacd.plist
❯ rm /usr/local/bin/blemacd
Starting with Big Sur, apps using Bluetooth needs Info.plist
file with NSBluetoothAlwaysUsageDescription
field.
It can be embedded with embed_plist crate, but it seems not to work on Big Sur.
There is also alternate approach for Rust which I haven’t tried yet or bit-level injection tool which seems not to work too.
In my tests (Big Sur 11.4, 2017 MacBook Pro, Intel) starting application via iTerm2 has failed (log from Console.app):
error 16:29:14.722625+0200 blemacd This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSBluetoothAlwaysUsageDescription key with a string value explaining to the user how the app uses this data.
It is unclear if app should be
code signed
to detect plist file.
I’ve tried ad-hoc code signing
and signing with
self-signed certificate
without any success, although otool -s TEXT info_plist target/release/blemacd | xxd -r
returns correct plist data.
At the same time, application starts just fine via Apple’s Terminal.app or Intellij IDEA Terminal tool window without plist or code signing.
If you have any insight on this, please contact me.
Commands are issued by writing text-based commands to the socket.
I.e. with nc
:
Connect socket and input/output via std.
❯ nc -U /tmp/blemacd.sock
status
-
Returns daemon status
peripherals
-
List of connected peripherals
❯ nc -U /tmp/blemacd.sock <<< peripherals
Whenever input doesn’t match a command, it is treated as a path, <PERIPHERAL_PUBLIC_SERVICE>/<SERVICE>/<CHARACTERISTIC>
.
<peripheral_public_service>/<service>
-
Connect to peripheral with specified advertised public service.
❯ nc -U /tmp/blemacd.sock <<< fe0f
connected to peripheral [472df789-71f0-4d87-a47f-4e818ba79f69] (Hue ambiance lamp) by service UUID [0000fe0f-0000-1000-8000-00805f9b34fb]
<peripheral>/<service>
-
Locate a service at peripheral.
❯ nc -U /tmp/blemacd.sock <<< fe0f/32bd
service found: Service { id: Uuid(932c32bd-0000-47a2-835a-a8d455b859dd), primary: false, service: CBService(0x7ff25b605ae0) }
<peripheral>/<service>/<characteristic>
-
Read a specified characteristic. Result is in hex format.
❯ nc -U /tmp/blemacd.sock <<< fe0f/32bd/0007
01010002017703029900
To specify range for characteristic:
❯ nc -U /tmp/blemacd.sock <<< fe0f/32bd/0007[5]
77
❯ nc -U /tmp/blemacd.sock <<< fe0f/32bd/0007[8..]
9900
<peripheral>/<service>/<characteristic>/<value>
-
Write a value to characteristic.
❯ nc -U /tmp/blemacd.sock <<< fe0f/32bd/0007[5]/10 (1)
❯ nc -U /tmp/blemacd.sock <<< fe0f/32bd/0007[5]/-25 (2)
❯ nc -U /tmp/blemacd.sock <<< fe0f/32bd/0007[8..]/-30[153..454] (3)
-
Like with reading, it is possible to specify a range for writing.
-
Supported operations are
+
- addition,-
- subtraction and!
- negation. -
Values ranges are also supported. Resulting value will be clamped with that range.