A few months back SRAM released the Shockwiz , a device to connect to your air sprung mountain bike suspension. The device pairs to an Android/iOS app on your phone to give you suggestions on what settings to adjust on your forks and shock to improve there performance.
Sadly there is no way at the moment to export this data, so I thought I’d have a look at reverse engineering the product to see what I could get out. According to the Shockwiz docs “All data collection and analysis is performed within the ShockWiz device itself”. The Shockwiz connects to your phone using Bluetooth LE, so the first step was to connect the Shockwiz to the bike, connect to the Shockiz via the app andtry and grab some logs.
I thought it would be most interesting to try and get the Air Pressure and Shock Travel values:
On Android 4+ you can enable Bluetooth HCI Snoop log in the developer options which will log out all the connections and packets sent/received.
With that done I connected to the Shockwiz and cycled the suspension a few times to get some data. Loading the file into Wireshark revelaed the initial handshake and then a load of ATT frames.
These frames seemed to just have a UUID and then a value. I spent a while trying to decrypt which UUID’s did what. I really just wanted to find the current shock pressure and travel level. I eventually managed to narrow it down to UUID: 00:00:15:32:74:b9:c1:e2:15:35:78:5f:ea:bc:d8:af as being the most active so assumed this was the PSI figure seen in the Android app.
I still couldn’t really work out what was what with this frame, so installed nRF Connect and nRF Logger on my ‘phone to try and get a live picture of what was going on without having to keep running to the desktop.
nRF Connect revealed some better information:
From the logs we can see this is the message we are interested in, based purely on its update frequency
I 14:09:21.372 Notification received from 00001532-74b9-c1e2-1535-785feabcd8af, value: (0x) 00-02-95-04-8E-00-0E-3B-88-31-27
A 14:09:21.372 “(0x) 00-02-95-04-8E-00-0E-3B-88-31-27” received
I 14:09:21.968 Notification received from 00001532-74b9-c1e2-1535-785feabcd8af, value: (0x) 00-02-BF-07-65-00-0E-3B-A6-24-DE
A 14:09:21.968 “(0x) 00-02-BF-07-65-00-0E-3B-A6-24-DE” received
I 14:09:22.365 Notification received from 00001532-74b9-c1e2-1535-785feabcd8af, value: (0x) 00-03-A2-12-70-00-0E-3B-88-F5-C3
A 14:09:22.365 “(0x) 00-03-A2-12-70-00-0E-3B-88-F5-C3” received
I 14:09:22.962 Notification received from 00001532-74b9-c1e2-1535-785feabcd8af, value: (0x) 00-02-94-04-82-00-0E-3B-87-2B-02
A 14:09:22.962 “(0x) 00-02-94-04-82-00-0E-3B-87-2B-02” received
I’m kind of guessing that the value covers both the pressure and the travel, with the 00 being the delimter.
However, at idle I should be expecting the air pressure to be ~50psi, or 3.39bar or 339 kPa, and the travel to be around 5% but neither of these values seem to match up. So far I’ve tried splitting the hex out into groups of 2, 3 ,4 and 5 and converting to:
- Float Big Endian
- Float Little Endian
- UINT32 Big Endian
- UINT32 Little Endian
- INT32 Big Endian
- INT32 Little Endian
- INT16 Big Endian
- INT16 Little Endian
But they don’t seem to relate to what is shown on the app. More work is needed!