userx14 / omblepy

Cli tool to read records from omron blood-pressure bluetooth-low-energy measurement instruments

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

writeNewPairingKey for an HEM-7151T

chrisg123 opened this issue · comments

commented

I am trying to get this to work with an OMRON HEM-7151T

Scanning for BLE devices...
+----+-------------------+-------------------------------+------+
| ID | MAC               | NAME                          | RSSI |
+----+-------------------+-------------------------------+------+
| 0  | 28:FF:B2:73:5F:EF | BLEsmart_0000016028FFB2735FEF | -56  |
+----+-------------------+-------------------------------+------+
Enter ID or just press Enter to rescan.
0
Attempt connecting to 28:FF:B2:73:5F:EF.
Traceback (most recent call last):
  File "/data/data4/src/omblepy/omblepy.py", line 344, in <module>
    asyncio.run(main())
  File "/usr/lib/python3.9/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/usr/lib/python3.9/asyncio/base_events.py", line 647, in run_until_complete
    return future.result()
  File "/data/data4/src/omblepy/omblepy.py", line 337, in main
    await bluetoothTxRxObj.writeNewPairingKey()
  File "/data/data4/src/omblepy/omblepy.py", line 201, in writeNewPairingKey
    raise ValueError(f"Could not enter key programming mode. Has the device been started in pairing mode?")
ValueError: Could not enter key programming mode. Has the device been started in pairing mode?

I threw some print statements in the writeNewPairingKey function:

deviceResponse == bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
deviceResponse[:2] == bytearray(b'\x00\x00')

I always seem to get an empty byte array as a response.

I took a look at an example in the bleak source code and was able to grab this info off the device:

[Service] 00001801-0000-1000-8000-00805f9b34fb (Handle: 256): Generic Attribute Profile
    [Characteristic] 00002a05-0000-1000-8000-00805f9b34fb (Handle: 272): Service Changed (indicate), Value: None
[Service] 0000180a-0000-1000-8000-00805f9b34fb (Handle: 512): Device Information
    [Characteristic] 00002a23-0000-1000-8000-00805f9b34fb (Handle: 528): System ID (read), Value: None
    [Characteristic] 00002a24-0000-1000-8000-00805f9b34fb (Handle: 544): Model Number String (read), Value: None
    [Characteristic] 00002a25-0000-1000-8000-00805f9b34fb (Handle: 560): Serial Number String (read), Value: None
    [Characteristic] 00002a26-0000-1000-8000-00805f9b34fb (Handle: 576): Firmware Revision String (read), Value: None
    [Characteristic] 00002a27-0000-1000-8000-00805f9b34fb (Handle: 592): Hardware Revision String (read), Value: None
    [Characteristic] 00002a28-0000-1000-8000-00805f9b34fb (Handle: 608): Software Revision String (read), Value: None
    [Characteristic] 00002a29-0000-1000-8000-00805f9b34fb (Handle: 624): Manufacturer Name String (read), Value: None
    [Characteristic] 00002a2a-0000-1000-8000-00805f9b34fb (Handle: 640): IEEE 11073-20601 Regulatory Cert. Data List (read), Value: None
[Service] ecbe3980-c9a2-11e1-b1bd-0002a5d5c51b (Handle: 768): Unknown
    [Characteristic] b305b680-aee7-11e1-a730-0002a5d5c51b (Handle: 784): Unknown (read,write-without-response,write,notify), Value: None
    [Characteristic] db5b55e0-aee7-11e1-965e-0002a5d5c51b (Handle: 800): Unknown (write-without-response,write), Value: None
    [Characteristic] e0b8a060-aee7-11e1-92f4-0002a5d5c51b (Handle: 816): Unknown (write-without-response,write), Value: None
    [Characteristic] 0ae12b00-aee8-11e1-a192-0002a5d5c51b (Handle: 832): Unknown (write-without-response,write), Value: None
    [Characteristic] 10e1ba60-aee8-11e1-89e5-0002a5d5c51b (Handle: 848): Unknown (write-without-response,write), Value: None
    [Characteristic] 49123040-aee8-11e1-a74d-0002a5d5c51b (Handle: 864): Unknown (read,notify), Value: None
    [Characteristic] 4d0bf320-aee8-11e1-a0d9-0002a5d5c51b (Handle: 880): Unknown (read,notify), Value: None
    [Characteristic] 5128ce60-aee8-11e1-b84b-0002a5d5c51b (Handle: 896): Unknown (read,notify), Value: None
    [Characteristic] 560f1420-aee8-11e1-8184-0002a5d5c51b (Handle: 912): Unknown (read,notify), Value: None
    [Characteristic] 8858eb40-aee8-11e1-bb67-0002a5d5c51b (Handle: 928): Unknown (notify), Value: None
[Service] 0000180f-0000-1000-8000-00805f9b34fb (Handle: 1024): Battery Service
    [Characteristic] 00002a19-0000-1000-8000-00805f9b34fb (Handle: 1040): Battery Level (read,notify), Value: None
[Service] 00001805-0000-1000-8000-00805f9b34fb (Handle: 1280): Current Time Service
    [Characteristic] 00002a2b-0000-1000-8000-00805f9b34fb (Handle: 1296): Current Time (read,write,notify), Value: None
[Service] 5df5e817-a945-4f81-89c0-3d4e9759c07c (Handle: 1536): Unknown
    [Characteristic] 00002a52-0000-1000-8000-00805f9b34fb (Handle: 1552): Record Access Control Point (write,indicate), Value: None
    [Characteristic] c195da8a-0e23-4582-acd8-d446c77c45de (Handle: 1568): Unknown (indicate), Value: None
[Service] 0000181c-0000-1000-8000-00805f9b34fb (Handle: 1792): User Data
    [Characteristic] 00002a99-0000-1000-8000-00805f9b34fb (Handle: 1808): Database Change Increment (read,write,notify), Value: None
    [Characteristic] 00002a9a-0000-1000-8000-00805f9b34fb (Handle: 1824): User Index (read), Value: None
    [Characteristic] 00002a9f-0000-1000-8000-00805f9b34fb (Handle: 1840): User Control Point (write,indicate), Value: None
    [Characteristic] 00002a85-0000-1000-8000-00805f9b34fb (Handle: 1856): Date of Birth (read,write), Value: None
[Service] 00001810-0000-1000-8000-00805f9b34fb (Handle: 2048): Blood Pressure
    [Characteristic] 00002a35-0000-1000-8000-00805f9b34fb (Handle: 2064): Blood Pressure Measurement (indicate), Value: None
    [Characteristic] 00002a49-0000-1000-8000-00805f9b34fb (Handle: 2080): Blood Pressure Feature (read), Value: None

Any idea what I might try to get past this error in writeNewPairingKey ?.

UPDATE:

@userx14 I saw your comment about using btmgmt and bluetoothctl manually but after the write 0x02 its still all zeros

I tried with an android phone and the nRF Connect app and it seems i was able to get a response of 82-0F-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 but I am not sure what that means. I then wrote 0x00fedcba9876543210fedcba9876543210 and got the response 80-04-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00

Hi @chrisg123,

can you tell me more about your test setup?

  • which distribution / version of linux and which version of bluez are you testing with?
  • do you have multiple bluetooth adapters connected?
  • are you using the latest version (released 21 days ago) of the python tool?
  • have you tested with the blueZero branch yet?

I always seem to get an empty byte array as a response.

If your device is simmilar to the other devices I have tested with, then the response 0x0000... means that the device did not pair correctely (where with pair I am refering to the pairing feature in the bluetooth protocol layer which is not related to the pairing mode with the blinking -P- on the omron device) with your pc. I also got this response when I messed up some timing and did not use notify for reads in older versions of the tool, but that should be fixed with this commit.

Any idea what I might try to get past this error in writeNewPairingKey ?.

Did you see a bluetooth pairing request from your os pop up, or when you open bluetoothctl in a second terminal window while running the python code?
I can recommend to test with other bluetooth adapters / devices / linux distributions / linux vs windows. I also had issues on current ubuntu versions.

I tried with an android phone and the nRF Connect app and it seems i was able to get a response of 82-0F-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 but I am not sure what that means.

I have also seen 0x820F... which seems to occur if the device is paired on the bluetooth layer, but did reject the switch to key programming mode. The first byte of the response seems to indicate the command type 0x82 for "switch to key programming mode" and 0x80 for "keywrite command". The second byte of the response seems to be an error code or if the command was successful will be 0x00.
As for what causes this error I could think of the following:

  • the omron device is started in its normal mode and not in "pairing mode" (blinking P), which should better be called "key programming mode"
  • the state of the device is messed up by previous attempts, without power cycling the device with the "Start Stop" key.
  • the device is just different and needs some different commands, maybe try 0x02 (16* 0x00) to the b305b680-aee7-11e1-a730-0002a5d5c51b characteristic, maybe the zeros at the end are not optional afterall 😄.

If it is not working on android after this, you could capture the bluetooth traffic between your phone an a certain app on Android 4.4+ by enabling the bluetooth hci snoop log.
The process of gettings the logs from the phone to a pc can be a bit painfull on non rooted Android devices.

I took a look at an example in the bleak source code and was able to grab this info off the device

The characteristics for unlocking and the tx and rx channels all seem to be there.
So I would guess that it is a bluetooth pairing issue.

Best,
Benjamin

commented
  • Gentoo Linux Kernel 5.16.3

  • Bluez 5.64

  • MPOW Bluetooth 5.1 USB Dongle Model BH519A

I decided to get the OMRON app (the thing I was trying to avoid) and generate
a Bluetooth hci snoop log for the initial pairing of the Omron app to the device.

Android phone is rooted so extracting is no issue. I will update on this one when
I have some time to pull out wireshark and go through it.

I did notice that after setting up with the OMRON app, When trying again with the
nRF Connect app I now get a successfull response to 0x02 of
80-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00

When I then send the 0x00fedcba9876543210fedcba9876543210 it returns
80-01-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 and the app
indicated its connected and bonded so I assume this means it works.

I also gave @LazyT's https://codeberg.org/LazyT/ubpm app a try.
It seems to connect and grab device info but pops up the following warning
when trying to import:

No answer from the device.
Did you use the Bluetooth controller with the cloned MAC address?

Not sure what that that means but maybe cloning the MAC address of my
Android phone.

I did try your bluezeroVersion yesterday with no luck.
As I was typing this message I gave it a second go and it seems to
have worked?

Attempt to import module for device hem-7361t-d
+----+-------------------+------------+---------+
| ID | MAC               | NAME       | POWERED |
+----+-------------------+------------+---------+
| 0  | 0C:CF:89:61:BE:70 | BlueZ 5.64 | 1       |
+----+-------------------+------------+---------+
Enter ID or just press Enter to rescan.
0
Scanning for BLE devices...
+----+-------------------+-------------------------------+------+
| ID | MAC               | NAME                          | RSSI |
+----+-------------------+-------------------------------+------+
| 0  | 28:FF:B2:73:5F:EF | BLEsmart_0000016028FFB2735FEF | None |
+----+-------------------+-------------------------------+------+
Enter ID or just press Enter to rescan.
0
Connection succesfull, wait for pairing.
BT Pairing successfull, Encrypted connection established
got notify change

It didnt seem to do anything after this though. Also failed on a second
attempt to connect.

I did at least get past the part I was originally inquiring about.

When I then send the 0x00fedcba9876543210fedcba9876543210 it returns
80-01-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 and the app
indicated its connected and bonded so I assume this means it works.

The display on the omron should change from "-P" to the square when the key write was successful.

It seems to connect and grab device info but pops up the following warning
when trying to import:

I think you can grab this device info without unlocking with the key, but not the stored measurements.
It will grab the device info and when you press import, the unlock will fail because the mac address is not the one that was last paired to the omron,
and you will get the "No answer from the device." message.

Not sure what that that means but maybe cloning the MAC address of my
Android phone.

Instead of writing a new pairing key and using this to be able to initiate the read from an arbitrary bluetooth dongle, one can also do the pairing once with the official app on android, and use a bluetooth adapter where one can alter the mac address like the "CSR 8510" based dongles.
Then one can use "0x0100..." to unlock the device, but only when using the same mac address as the device that has unlocked the device previousely (the mac of the android phone in this case).
This is the method UBPM uses, but I have not tested that extensiveley and do not know if it works with all devices.
https://codeberg.org/LazyT/ubpm/src/commit/c5f6d3f54cde95669e31ecd7b452345a6c594493/sources/plugins/vendor/omron/hem-7361t/DialogImport.cpp#L339

As I was typing this message I gave it a second go and it seems to
have worked?
I am going to assume I did at least get past the part I was originally
inquiring about.

That unfortunatelly still looks like going into key write mode did not work.
The last message you get "got notify change" indicates that the unlock key characteristic has now an activated "notify on change callback" but the programm freezing after that would mean that there was no response to either the "0x0200" or "0x00keybytes" being sent.
It should print something if it worked:

omblepy/omblepy.py

Lines 255 to 256 in 9114e31

print(f"Paired device successfully with new key {newKeyByteArray}.")
print("From now on you can connect ommit the -p flag, even on other PCs with different Bluetooth-MAC-addresses.")

Android phone is rooted so extracting is no issue. I will update on this one when
I have some time to pull out wireshark and go through it.

A fast way to find the key unlock in the bt snoop log is to use "btatt" as the filter in wireshark and look for packets where the length is 29. They should go to handle 0x0311.

I decided to get the OMRON app (the thing I was trying to avoid) and generate
a Bluetooth hci snoop log for the initial pairing of the Omron app to the device.

If you do not want to create an account, you can select a country like "Albania" and it will skip the account creation dialog.
Just a nice timesaver when you need to reset the stored data of the app for some testing.

Adding support for the record format for the HEM-7151T should be straightforward. It is basically an HEM-7361T with 80 instead of 100 entries for user1 and no entries for user2. But getting the key write process working might be difficult.

Please let me know if you made some progress or need some assistance 😃.