hmmwhatsthisdo / BLEPS

PowerShell module for interacting with Bluetooth Low Energy (BLE) devices implementing the Generic Attribute Profile (GATT/GAP)
7 stars 4 forks source link

Read and decode advertisement beacon data? #1

Open ilgrank opened 1 year ago

ilgrank commented 1 year ago

First of all, let me thank you for BLEPS, it has been very ispirational!

I've tried BLEPS and I've managed to use it to read BLE beacons, but as far as I understand, there is no way (limit of Powershell 5) to have working WinRT events trigger, so I've resorted to listening for a few seconds and then trying to parse the received payload.. but I only get a few bytes of not very meaningful data out of Read-BleCharacteristic pointed at the serviceUUID I'm monitoring.

(I've been trying to to parse sensor data from Mi Thermometers that is sent passively in BLE advertisement beacons., the data format is described here )

it seems to me that the data I'm receiving is signed (and possibly little-endian), while Read-Blecharacteristic returns and unsigned bytearray...

On a side note, I've read that using Powershell 7 it is now possible to have working UWP events trigger (tested, and it works!), so I've used

add-type -path ".\Microsoft.Windows.SDK.NET.dll"

$Watcher=[Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementWatcher]::new()
Register-ObjectEvent -InputObject $Watcher -EventName Received -Action {
    $Global:Event=$Event
}
$Watcher.Start()
sleep 5
$Watcher.Stop()

(library can be found here ) and it indeed works, but the returned data $event.SourceArgs[1].Advertisement.DataSections seem to output the same unsigned bytearray (even tho this time, the object has additional DataType property that maybe could be used to dictate the format of each bytearray.. maybe?)

hmmwhatsthisdo commented 1 year ago

So, it's been a very long time since I looked at this code (oops!) - Read-BLECharacteristic is a thin wrapper around GattCharacteristic.ReadValueAsync(), which only returns an IBuffer. I don't think there's a generic, guaranteed way to infer data types on read GATT characteristics through this code-path. My assumption is that you'd generally cast bytes out of that IBuffer into your preferred type on your own.

Other BLE debug tools seem to correctly differentiate between byte arrays and strings on characteristics, though. I seem to remember there being a descriptor or similar for basic type inference, but it's been north of 2 years since I've worked with BLE in any meaningful fashion.

The repo you linked defines the advertisement schema in the readme - are you seeing a different byte count?

ilgrank commented 1 year ago

thanks for your reply! The byte count seems to be ok, i.e., probably as you say the only way is to manually cast every byte to the appropriate type. (unless using PS7 and Windows.SDK.NET.dll, but that breaks a whole lot of other code alas in my scenario) I was curious if you managed to have events working in PS5 eventually... but If you haven't used this code since you posted it, I fear not :(

hmmwhatsthisdo commented 1 year ago

I was curious if you managed to have events working in PS5 eventually

No, I didn't have any BLE advert-heavy products at my disposal, so I can't say I had a chance to try. /r/powershell might have some suggestions on how to receive UWP events in NetFX - my guess is that you likely have to do some funny delegate marshaling and hand UWP an event handler through COM.

(That being said, you're welcome to cut a PR to add new functions for collecting adverts if you'd like!)