haraldh / iconsole

Reverse engineering of the iconsole+ bike computer serial protocol. Broadcasts the power and speed on the ANT network.
MIT License
32 stars 5 forks source link

"discover_devices" not detecting "i-CONSOLE" #2

Open mamora01 opened 6 years ago

mamora01 commented 6 years ago

Hi, I am new to bluetooth (especially BLE) but want to gather data from my new Cardiostrong Ergometer BX70i. Works perfect with the IOS App iConsole+ ... Other IOS BT sniffer work also. My goal is to connect with a raspberry 3 and log performance data into a csv file like (timestamp;power level;rpm;heartrate,etc ...) approx. every 5 or 10 secs in order to track the exercise. I want to use your script to connect and communicate with the iConsole (not interested in the ANT part) Other bluetooth devices (e.g. my Samsung Galaxy phone) are detected by your script. My Bose Speaker in range is not shown, so it seem to be low energy devices are ignored. Raspberry 3 Stretch version 9 (internal Bluetooth), HCI 4.1 Rev 0X145, bluetoothctl, bluez 5.48

haraldh commented 6 years ago
    devs = discover_devices(duration=2, lookup_names = True)
    for (addr, name) in devs:
        if name.startswith("i-CONSOLE"):
            break
        addr = None

Your device might have another name... I don't know.. discover_devices()is from pybluez. Not my expertise.

haraldh commented 6 years ago

Otherwise find out the address and hardcode it.

vmedea commented 4 years ago

It appears that the iConsole bluetooth-LE models (at least mine) use the Microchip RN4870/71 proprietary protocol to expose the UART over BLE instead of classic bluetooth. As the current script uses bluez and classic bluetooth, I think a few changes are needed to support this.

The chip is described here: http://ww1.microchip.com/downloads/en/DeviceDoc/RN4870-71-Bluetooth-Low-Energy-Module-Data-Sheet-DS50002489D.pdf http://ww1.microchip.com/downloads/en/DeviceDoc/RN4870-71-Bluetooth-Low-Energy-Module-User-Guide-DS50002466C.pdf (see Appendix B.1)

The serial interface uses the following BLE characteristics:

49535343-1E4D-4BD9-BA61-23C647249616  UUIDSTR_ISSC_TRANS_TX  Transparent UART TX
49535343-8841-43F4-A8D4-ECBE34729BB3  UUIDSTR_ISSC_TRANS_RX  Transparent UART RX

I have not yet checked whether the underlying serial protocol is the same. I might at some point, but in any case I did a lot of googling to figure this out so I hope this helps anyone.

Edit: I see newer versions of pybluez do support BLE, through a separate module bluetooth.ble.

haraldh commented 4 years ago

Too bad I can't test it, as I don't own such a device, so pull requests are welcome.

vmedea commented 4 years ago

What is currently holding me back from trying is not being able to find a library for Python that provides an UART-like abstraction over the Microchip BLE UART protocol. It's not too involved so I might have a go at doing so myself at some point, but it's hard to test if it is correct (a bit of a chicken-egg problem) with the exercise bike being the only such device I have :slightly_smiling_face:

john270 commented 4 years ago

Will be interested to see if you manage to get anything working with the ble. Ive been toying with the android code to also make it work for ble iconsole bike. Can get the code to connect, read default characteristics and enroll for notifications on the custom ones but the bike doesn't go into the 'bluetooth' state so just times out and powers off after a while

vmedea commented 4 years ago

Here's an adapted version that (I've only quickly tested) works over BLE by emulating an UART over pygatt: https://gist.github.com/vmedea/bd064b49c00d040d6a673a8d04f1f919

pip3 install pygatt
hcitool -i hci0 lescan # find the MAC address
python3 iConsole.py 12:34:56:78:9a:bc  # insert your own MAC address

It creates a log file /tmp/log with UART debugging output (can be disabled by setting LOG to None). I've removed the ANT networking and ported it to Python 3.

It seems to work. It does some negotiation, the bike goes into bluetooth state (display turns off, buttons no longer respond), and the tool reports some information!

john270 commented 4 years ago

Cheers! I'll take a look. I'm not used to python but it's the negotiation bit that I'm obviously lacking in my java attempt. Thought it'd be as simple as enrolling to the notification characteristic but theres clearly a little more to it

vmedea commented 4 years ago

Subscribing to the UART_TX (49535343-1e4d-4bd9-ba61-23c647249616) is the first step. But it seems that the device will never send notifications by itself. It only replies to requests (correctly formatted packets) that are sent to UART_RX (49535343-8841-43f4-a8d4-ecbe34729bb3) with such notifications.

vmedea commented 4 years ago

I got around to trying around with this a bit today and it works great. Thanks a lot @haraldh for doing the grunt work in reverse engineering.

Some observations:

john270 commented 4 years ago

Thanks again for the useful comments. I've still not managed to get it set up properly. I can now start the proper pairing process going through the various send and receives, however I never get a reply to the Init_A3 send. Don't suppose you have any ideas why - or any more details on what these exchanges are, or how to check them for my device?

vmedea commented 4 years ago

My guess for the misc initialization packets is that INIT_A0 gets the software/interface version. For my device it responds with

f0:b7:01:01:04

STATUS gets the maximum level. As for INIT_A3 and INIT_A4 these look suspiciously as if they provide starting values for the various numbers that are read out (time, calories, etc…). I have however not experimented with different values yet!

however I never get a reply to the Init_A3 send. Don't suppose you have any ideas why

Glad to hear you got it so far. It's my experience that packets are ignored if the checksum (the last byte) is not correct. It might also be that they changed the length of the packet for your version. You could skip A3/A4 completely and try what happens.

john270 commented 4 years ago

Thanks. I'll play around with it some more. I have already tried sending A3 then moving onto A4 but I don't get a reply to that either or the Read request

vmedea commented 4 years ago

It seems like the A3 causes synchronization to be lost completely, then. If it's really this packet jamming things up, this definitely points at a wrong length issue. A wrong checksum would still make it respond to new packets, I think.

Just curious, what is the (version?) response to INIT_A0 for you?

john270 commented 4 years ago

Hi, I definitely get a different response to InitA0 send. I am getting F0 B0 00 C8 68 (the same as for the pings). [Sorry took me 2 edits to write that out right - brain fail today!]
Below is logcat of my send and receives:

2020-11-17 11:45:33.329 2963-3456/org.surfsite.iconsole D/BluetoothLeService: : comm F0 A0 01 01 92 | PING 2020-11-17 11:45:33.454 2963-3040/org.surfsite.iconsole D/BluetoothLeService: Change string: F0 B0 00 C8 68 |   2020-11-17 11:45:37.662 2963-3456/org.surfsite.iconsole D/BluetoothLeService: : comm F0 A0 01 01 92 | PING 2020-11-17 11:45:37.808 2963-3040/org.surfsite.iconsole D/BluetoothLeService: Change string: F0 B0 00 C8 68 |   2020-11-17 11:45:43.317 2963-3456/org.surfsite.iconsole D/BluetoothLeService: : comm F0 A0 01 01 92 | PING 2020-11-17 11:45:43.454 2963-3040/org.surfsite.iconsole D/BluetoothLeService: Change string: F0 B0 00 C8 68 |   2020-11-17 11:45:46.129 2963-3456/org.surfsite.iconsole D/BluetoothLeService: : comm F0 A0 02 02 94 | INIT_A0 2020-11-17 11:45:46.272 2963-3040/org.surfsite.iconsole D/BluetoothLeService: Change string: F0 B0 00 C8 68 |   2020-11-17 11:45:47.732 2963-3456/org.surfsite.iconsole D/BluetoothLeService: : comm F0 A1 01 01 93 | STATUS 2020-11-17 11:45:47.874 2963-3040/org.surfsite.iconsole D/BluetoothLeService: Change string: F0 B1 00 C8 07 50 C0 |   2020-11-17 11:45:49.366 2963-3456/org.surfsite.iconsole D/BluetoothLeService: : comm F0 A0 01 01 92 | PING 2020-11-17 11:45:49.494 2963-3040/org.surfsite.iconsole D/BluetoothLeService: Change string: F0 B0 00 C8 68 |   2020-11-17 11:45:51.220 2963-3456/org.surfsite.iconsole D/BluetoothLeService: : comm F0 A3 01 01 01 96 | INIT_A3

vmedea commented 4 years ago

Hi, I definitely get a different response to InitA0 send. I am getting F0 B0 00 C8 68 (the same as for the pings). [Sorry took me 2 edits to write that out right - brain fail today!]

Yup. That does look like a slightly different protocol, similar enough, but also different enough to be a challenge.

I'm surprised how often 0xC8 (200) comes back in the responses (really in every single one). Also 0x00 appears which doesn't ever appear in the responses from my device.

john270 commented 4 years ago

Out of interest what type of exercise machine is yours? I've got a spin bike (with manual control resistance) - I'm guessing that different equipment will have different features and therefore protocols?

On Tue, 17 Nov 2020, 16:35 mara, notifications@github.com wrote:

Hi, I definitely get a different response to InitA0 send. I am getting F0 B0 00 C8 68 (the same as for the pings). [Sorry took me 2 edits to write that out right - brain fail today!]

Yup. That does look like a slightly different protocol, similar enough, but also different enough to be a challenge.

I'm surprised how often 0xC8 (200) comes back in the responses (really in every single one). Also 0x00 appears which doesn't ever appear in the responses from my device.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://nam10.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fharaldh%2Ficonsole%2Fissues%2F2%23issuecomment-729048018&data=04%7C01%7C%7C26bbab741a3343a060a708d88b16ceba%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637412277351544400%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=XXO6xju36E72lq92RwUGQbqN5%2FVmROTQ2ikGKxUcEl4%3D&reserved=0, or unsubscribe https://nam10.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAEXU2GS2OZKXSH2VROG7K3TSQKQ5NANCNFSM4FLKOALQ&data=04%7C01%7C%7C26bbab741a3343a060a708d88b16ceba%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637412277351544400%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=YO9LDnyBsWKJBWgD8xHVnozrDwbxucCsfwWazZJmJeY%3D&reserved=0 .

sackschlangen commented 4 years ago

Hi, I was reading silently since a couple of days now. I have a Asviva rowing machine which also has a iConsole Terminal. But this one uses a Microchip BM70/71 module rather than a RN4870/71. @vmedea python script seems to communicate somehow, but not as supposed.

I compared the user's guides of each and they seem to have different command sets. I will go into this deeper the next days. I just want to say thank you for your effort and free information for now, it's very helpful.

john270 commented 4 years ago

Great thanks. It's interesting you mention BM70/71 because if I read the generic characteristic "model number string" of my machine it returns BM70. So that could explain things

On Tue, 17 Nov 2020, 21:37 sackschlangen, notifications@github.com wrote:

Hi, I was reading silently since a couple of days now. I have a Asviva rowing machine which also has a iConsole Terminal. But this one uses a Microchip BM70/71 module rather than a RN4870/71. @vmedea https://eur04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fvmedea&data=04%7C01%7C%7C4881328ed045407843ef08d88b40e291%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637412458072064736%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=nnGqK%2FnZphncG8tWdhF4Som4P5JxPGRYYMldPcKgjvs%3D&reserved=0 python script seems to communicate somehow, but not as supposed.

I compared the user's guides of each and they seem to have different command sets. I will go into this deeper the next days. I just want to say thank you for your effort and free information for now, it's very helpful.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://eur04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fharaldh%2Ficonsole%2Fissues%2F2%23issuecomment-729228548&data=04%7C01%7C%7C4881328ed045407843ef08d88b40e291%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637412458072074730%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=Tpls5jg%2BGGxYE%2FuCGKceYbMALkIutEKVfhBmXNnnKBA%3D&reserved=0, or unsubscribe https://eur04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAEXU2GQI4H3TDJPEZMO5GS3SQLUG3ANCNFSM4FLKOALQ&data=04%7C01%7C%7C4881328ed045407843ef08d88b40e291%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637412458072074730%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=OUiNIY9Kyp1JPVn9EKKvngR2PQ6Z7Uc3lh3%2F3Xi1rUM%3D&reserved=0 .

vmedea commented 4 years ago

Out of interest what type of exercise machine is yours? I've got a spin bike (with manual control resistance) - I'm guessing that different equipment will have different features and therefore protocols?

Mine is a crosstrainer "Focus Fitness Fox 5 iPlus". It has the SET_LEVEL 0..31 difficulty setting, which works automatically. Some information I could collect through Linux gatttool and cross-reference:

    attr handle: 0x0001, end grp handle: 0x0005 uuid: 00001800-0000-1000-8000-00805f9b34fb  = Generic Access
    attr handle: 0x0010, end grp handle: 0x0020 uuid: 0000180a-0000-1000-8000-00805f9b34fb  = Device Information
    attr handle: 0x0030, end grp handle: 0x0033 uuid: 49535343-5d82-6099-9348-7aac4d5fbc51  = ISSC-...
    attr handle: 0x0040, end grp handle: 0x0043 uuid: 49535343-c9d0-cc83-a44a-6fe238d06d33  = ISSC-...
    attr handle: 0x0050, end grp handle: 0x0058 uuid: 49535343-fe7d-4ae5-8fa9-9fafd205e455  = ISSC-...

    handle: 0x0001, uuid: 00002800-0000-1000-8000-00805f9b34fb  = Primary Service
    handle: 0x0002, uuid: 00002803-0000-1000-8000-00805f9b34fb  = Characteristic
    handle: 0x0003, uuid: 00002a00-0000-1000-8000-00805f9b34fb  = Device Name
    handle: 0x0004, uuid: 00002803-0000-1000-8000-00805f9b34fb  = Characteristic
    handle: 0x0005, uuid: 00002a01-0000-1000-8000-00805f9b34fb  = Appearance

    handle: 0x0010, uuid: 00002800-0000-1000-8000-00805f9b34fb  = Primary Service
    handle: 0x0011, uuid: 00002803-0000-1000-8000-00805f9b34fb  = Characteristic
    handle: 0x0012, uuid: 00002a29-0000-1000-8000-00805f9b34fb  = Manufacturer Name String
    handle: 0x0013, uuid: 00002803-0000-1000-8000-00805f9b34fb  = Characteristic
    handle: 0x0014, uuid: 00002a24-0000-1000-8000-00805f9b34fb  = Model Number String
    handle: 0x0015, uuid: 00002803-0000-1000-8000-00805f9b34fb  = Characteristic
    handle: 0x0016, uuid: 00002a25-0000-1000-8000-00805f9b34fb  = Serial Number String
    handle: 0x0017, uuid: 00002803-0000-1000-8000-00805f9b34fb  = Characteristic
    handle: 0x0018, uuid: 00002a27-0000-1000-8000-00805f9b34fb  = Hardware Revision String
    handle: 0x0019, uuid: 00002803-0000-1000-8000-00805f9b34fb  = Characteristic
    handle: 0x001a, uuid: 00002a26-0000-1000-8000-00805f9b34fb  = Firmware Revision String
    handle: 0x001b, uuid: 00002803-0000-1000-8000-00805f9b34fb  = Characteristic
    handle: 0x001c, uuid: 00002a28-0000-1000-8000-00805f9b34fb  = Software Revision String
    handle: 0x001d, uuid: 00002803-0000-1000-8000-00805f9b34fb  = Characteristic
    handle: 0x001e, uuid: 00002a23-0000-1000-8000-00805f9b34fb  = System ID
    handle: 0x001f, uuid: 00002803-0000-1000-8000-00805f9b34fb  = Characteristic
    handle: 0x0020, uuid: 00002a2a-0000-1000-8000-00805f9b34fb  = IEEE 11073-20601 Regulatory Certification Data List 

    handle: 0x0030, uuid: 00002800-0000-1000-8000-00805f9b34fb  = Primary Service
    handle: 0x0031, uuid: 00002803-0000-1000-8000-00805f9b34fb  = Characteristic
    handle: 0x0032, uuid: 0000e26e-0000-1000-8000-00805f9b34fb
    handle: 0x0033, uuid: 00002902-0000-1000-8000-00805f9b34fb  = Client Characteristic Configuration

    handle: 0x0040, uuid: 00002800-0000-1000-8000-00805f9b34fb  = Primary Service
    handle: 0x0041, uuid: 00002803-0000-1000-8000-00805f9b34fb  = Characteristic
    handle: 0x0042, uuid: 00000318-0000-1000-8000-00805f9b34fb
    handle: 0x0043, uuid: 00002902-0000-1000-8000-00805f9b34fb  = Client Characteristic Configuration

    handle: 0x0050, uuid: 00002800-0000-1000-8000-00805f9b34fb  = Primary Service
    handle: 0x0051, uuid: 00002803-0000-1000-8000-00805f9b34fb  = Characteristic
    handle: 0x0052, uuid: 00009616-0000-1000-8000-00805f9b34fb
    handle: 0x0053, uuid: 00002902-0000-1000-8000-00805f9b34fb  = Client Characteristic Configuration
    handle: 0x0054, uuid: 00002803-0000-1000-8000-00805f9b34fb  = Characteristic
    handle: 0x0055, uuid: 00009bb3-0000-1000-8000-00805f9b34fb
    handle: 0x0056, uuid: 00002803-0000-1000-8000-00805f9b34fb  = Characteristic
    handle: 0x0057, uuid: 00003b7e-0000-1000-8000-00805f9b34fb
    handle: 0x0058, uuid: 00002902-0000-1000-8000-00805f9b34fb  = Client Characteristic Configuration

    handle: 0xffff, uuid: 0000ffff-0000-1000-8000-00805f9b34fb

properties:
    handle: 0x0031, char properties: 0x18, char value handle: 0x0032, uuid: 49535343-026e-3a9b-954c-97daef17e26e
    handle: 0x0041, char properties: 0x18, char value handle: 0x0042, uuid: 49535343-aca3-481c-91ec-d85e28a60318 = UUIDSTR_ISSC_MP
    handle: 0x0051, char properties: 0x1c, char value handle: 0x0052, uuid: 49535343-1e4d-4bd9-ba61-23c647249616 = Transparent UART TX
    handle: 0x0054, char properties: 0x0c, char value handle: 0x0055, uuid: 49535343-8841-43f4-a8d4-ecbe34729bb3 = Transparent UART RX
    handle: 0x0056, char properties: 0x18, char value handle: 0x0057, uuid: 49535343-4c8a-39b3-2f49-511cff073b7e

Going down the BLE rabbit hole:

> char-read-uuid 00002a29-0000-1000-8000-00805f9b34fb = Manufacturer Name String
handle: 0x0012   value: 49 53 53 43 = ISSC
> char-read-uuid 00002a24-0000-1000-8000-00805f9b34fb = Model Number String 
handle: 0x0014   value: 42 4d 37 30 = BM70 
> char-read-uuid 00002a25-0000-1000-8000-00805f9b34fb = Serial Number String
handle: 0x0016   value: 30 30 30 30 = 0000
> char-read-uuid 00002a27-0000-1000-8000-00805f9b34fb = Hardware Revision String
handle: 0x0018   value: 35 35 30 35 20 31 30 32 5f 42 4c 44 4b 33 = 5505 102_BLDK3
> char-read-uuid 00002a26-0000-1000-8000-00805f9b34fb = Firmware Revision String
handle: 0x001a   value: 30 30 39 35 30 30 = 009500
> char-read-uuid 00002a28-0000-1000-8000-00805f9b34fb = Software Revision String
handle: 0x001c   value: 30 30 30 30 = 0000
> char-read-uuid 00002a23-0000-1000-8000-00805f9b34fb = System ID
handle: 0x001e   value: 00 00 00 00 00 00 00 00 
> char-read-uuid 00002a2a-0000-1000-8000-00805f9b34fb = IEEE 11073-20601 Regulatory Certification Data List  
handle: 0x0020   value: 00 00 00 00 01 00 00 00 

All this seems to reveal is information about the UART / BLE communication chip used, and nothing about the underlying device.

But this one uses a Microchip BM70/71 module rather than a RN4870/71

Seems you are right in my case too ! RN was just a guess but the information in that datasheet worked for me. The difference is probably not at the level of the UART chip but what it communicates with.

sackschlangen commented 4 years ago

Hi, well, OK, I was hoping, this might be my problem. When I start your script it goes to line

139 send_ack(PING)

(I can read "OK" but nothing else) and runs this function repeatingly because got == None doesn't change

However the LOG-file is filled with stuff like this

Startng adapter Started adapter, connecting Connected to device Subscribed to UART TX UART sending b'\xf0\xa0\x01\x01\x92' Received data: b'f0b701e70493' recv returning: b'f0b701e704' UART sending b'\xf0\xa0\x01\x01\x92' Received data: b'f0b701e70493' recv returning: b'93f0b701e7' UART sending b'\xf0\xa0\x01\x01\x92' Received data: b'f0b701e70493' recv returning: b'0493f0b701' UART sending b'\xf0\xa0\x01\x01\x92' recv returning: b'e70493' Received data: b'f0b701e70493' recv returning: b'f0b701e704' UART sending b'\xf0\xa0\x01\x01\x92' Received data: b'f0b701e70493' recv returning: b'93f0b701e7' UART sending b'\xf0\xa0\x01\x01\x92' Received data: b'f0b701e70493' recv returning: b'0493f0b701'

vmedea commented 4 years ago

Well, the good news is that the UART emulation is working. The bad news is that the iConsole specific code gets a longer packet back than expected:

UART sending b'\xf0\xa0\x01\x01\x92'
Received data: b'f0b701e70493'
recv returning: b'f0b701e704'

The PING packet gets you back the expected INIT_A0 response of 0xb7 (6 bytes) instead of a PONG.

The following would work to get past:

    got = send_recv(sock, PING , expect=0xb7, plen=6)

Though it's hard to say which other packets will differ in responses.

sackschlangen commented 4 years ago

Hi, so I did a little more digging, I ripped your script ;) so that it simply sends hex-strings and prints out the response strings, the response of my machine is quite boring by now: to any of your commands INIT_A0 ... READ except for PONG and INIT_A4 the response is

Received data: b'f0b701e70493'

as soon as I try other hex strings (e.g. modifying the PING command by changing random values +-1) I did not get a response string (as with PONG and INIT_A4). Thus I assume it accepts these strings as commands in some way. Where did this strings come from? I did not find any references in the user guides?!

P.S. the response does not change if I pull the rower during data transfer

vmedea commented 4 years ago

commands in some way. Where did this strings come from? I did not find any references in the user guides?!

Yea, the problem is that this protocol, no version of it, is documented anywhere at least that I know. My luck was that @haraldh's worked for me as-is.

Trying strings will only get you so far if the protocol differs enough. At some point the only way to get something working is to intercept the traffic between the original app and the rower somehow, as that's bound to be valid. Maybe there is some way to intercept it at the android system level, or a way to emulate the app. Another option would be to reverse engineer the app and figure out the calls to bluetooth API. Alternatively there is probably some way to sniff BLE traffic drectly from the air (it's not encrypted in/ this case), but it might require special equipment.

sackschlangen commented 4 years ago

I went through the documents for BM70/71 and RN4870/71 and I think I finally understood. These provide the GATT server and UART interface for the underlying fitness console (aka iConsole). The BT Characteristics and GAP/GATT Services are provided by the BM/RN but the command strings communicate with the console which is not documented.

Just for the fun of it I ordered the hardware as described here

https://www.polidea.com/blog/bluetooth-low-energy-sniffing-guide/

and see what this brings...

haraldh commented 4 years ago

I turned on bluetooth logging in the android developer settings back in the days and ran the original iconsole app.

https://www.bluetooth.com/blog/debugging-bluetooth-with-an-android-app/

haraldh commented 4 years ago

https://medium.com/@charlie.d.anderson/how-to-get-the-bluetooth-host-controller-interface-logs-from-a-modern-android-phone-d23bde00b9fa

haraldh commented 4 years ago

wireshark is your friend to look into the contents of the network packets.

vmedea commented 4 years ago

I went through the documents for BM70/71 and RN4870/71 and I think I finally understood. These provide the GATT server and UART interface for the underlying fitness console (aka iConsole). The BT Characteristics and GAP/GATT Services are provided by the BM/RN but the command strings communicate with the console which is not documented.

Yes, exactly. The UART can best be considered a dumb pipe, it can be the Nordic UART module (over classic bluetooth), Microchip UART module (over BLE), or even a serial cable. These hold no mysteries. But the application-specific wire protocol over it is undocumented, and clearly has a few variants. Good luck!

haraldh commented 3 years ago

I also opened up the discussion forums https://github.com/haraldh/iconsole/discussions/ https://github.com/haraldh/iconsole-android/discussions

tomitrescak commented 3 years ago

@vmedea @haraldh do you have any code we could look at? We are a research team working with brain injury patients and we are working on a small gamified prototype to increase their workout motivation. We bough the iConsole powered bike Head S330, but we are unable to connect or read data from it. I read through your conversation but I am unsure if you have succeeded. Thank you kindly.

vmedea commented 3 years ago

@tomitrescak I've uploaded my current code. It works for my BLE iConsole device, hope it works for the one you are using, but there seem to be different protocols so YMMV.

tomitrescak commented 3 years ago

@vmedea thank you! It gives me a lot to go on ... now I have to make it work on Windows in UWP ;)

awc3003 commented 3 years ago

@vmedea & @haraldh thank you for the work you are doing on this! I tried connecting today (I have a spinning bike with manual resistance control) and get a timeout in the INIT_A0 step. Log reads as:

Connected to device RX handle: 85 Subscribed to UART TX ping done f0b000c8 Timed out Retransmit Timed out .....

Any thoughts?