Skip to content

Reverse Engineering the Pavlok 2 Communications Protocols

ztrayl3 edited this page Feb 4, 2020 · 1 revision

The officialy Pavlok API exists, but it does not allow direct connection and control of the device. The entire process is routed through an online service, and that wouldn't do. Since the officialy API is web hosted, there was no documentation for the functioning of the device. Thanks to a piece of software called btlejuice and some spare Raspberry Pi's I had lying around, I was able to effectively perform a MITM "attack" on my phone and log all the packets running from the Pavlok app to the device itself.

The device communicates with its host via the BLE GATT protocol, wherein specific "handles" are assigned to functions in the device. Packets are more-or-less sent to these handle addresses and the device executes the command if it fits the correct syntax (I am no expert on GATT, but for further reading, see this page. While some GATT attributes have standardized handles (such as battery and firmware), most are proprietary and not advertised by the Pavlok device. However, thanks to the android tool nRF connect, I was able to see every attribute open to recieving packets on the Pavlok, all of their handles, and with human readable names. From there, I went back to my MITM setup and executed every function the official Pavlok app had, and at every intensity level and possible configuration. With all possible data logged between the app and the device, I went to breaking down the packets.

Not every part of the communication protocol is figured out, as I am again no expert in any of this, but for better or for worse a solid pattern exists for all stimuli commands. Data is formatted as "8(number of repetitions)0c(level of intensity)(duration_on)(gap between repetitions)", all values being integers converted to hexidecimal values. The "8" and the "0c" are still a work in progress. Shock only utilises count and level, for some reason sending a much shorter packet than the other stimuli. Other handles such as "Button Assign" and "Clock" have specific formats as well, but those were a bit easier to figure out by just figitting with settings in the Pavlok app and seeing what it communicated to the device.

In short, the PyPav2 module simply offers a python wrapper for a gatttool interface. It establishes a BLE connection with the Pavlok 2 (pairing your linux computer with the Pavlok may be a bit of a hassle but I got it eventually and it hasn't offered me trouble since) and then takes human input, converts it to hex packets, and sends it through gatttool to the correct address on the device.

The project has been loads of fun and a great challenge in terms of my computer science abilities. Follow any updates on the progress of our official Pavlok research study on the Pavlok official subreddit! Please note that this project is in no way funded or supported by the Pavlok company (if only) and is entirely a personal and non-profit endeavor.

Video example using a Raspberry Pi Zero w https://youtu.be/dpEqDgbgF_0

Clone this wiki locally