buttplugio / stpihkal

Repo deprecated, STPIHKAL moved to docs.buttplug.io repo
https://docs.buttplug.io/
93 stars 21 forks source link

Document Pavlok-S Protocol #137

Open TapGhoul opened 3 years ago

TapGhoul commented 3 years ago

This is for the S series of pavloks (2 and 3). Note: firmware versions 5.4.73 and later (inc. 6.x.x) use the time calculation listed below. Prior versions just use a fixed value of 0xfa/250.

Protocol negotiation

To ensure the correct protocol is used (that is, it's the S series of devices), the app checks the following characteristic contains the phrase "Pavlok-S":

Service UUID: 0000180a-0000-1000-8000-00805f9b34fb (Device Information) Characteristic UUID: 00002a24-0000-1000-8000-00805f9b34fb (Model Number String)

Applicable characteristics

Service UUID: 156e1000-a300-4fea-897b-86f698d74461 Characteristic UUIDs:

This list is non-exhaustive as for what the pavlok 3 exposes, however it is all that is possible to be utilized by the stimuli operations. Other operations relate to the RTC for the alarm, battery level, and other features.

Stimuli packet format

To send a vibration or a beep: RR 0c II TA TO

To send a zap: RR II

LED protocol unknown, however it takes 4 bytes and seems to run a pattern - none of which are used or detailed in-app. Incorrect/invalid patterns seem to just no-op.

Time calculation

Calculation for time, for firmware versions 5.4.73 and later:

public static int timeCodeForPavlok2(long timeCode) {
  if (timeCode > 10000L) {
    return 62;
  } else if (timeCode >= 3000L) {
    return (int)((timeCode - 3000L) / 500L) | 48;
  } else if (timeCode >= 1000L) {
    return (int)((timeCode - 1000L) / 100L) | 32;
  } else {
    return timeCode >= 200L ? (int)((timeCode - 200L) / 50L) | 16 : (int)(timeCode / 10L) | 0;
  }
}

Default value fed in is 0x280L/640L, which results in 0x18/24 The app hard-codes this value, however, it can be freely varied and will work accordingly.

Sample messages

Silvenga commented 2 years ago

So my own reverse engineering attempt isn't lost to the void. Maybe it'll help someone. Did this months ago, but never ended up writing anything fit for public consumption, these are some resulting notes.

If someone knows how to enable streaming of the motion sensor, I would be very interested to know how.


BLE scan with commentary:

attr handle: 0x0001, end grp handle: 0x0009 uuid: 00001800-0000-1000-8000-00805f9b34fb (Unknown)
    handle: 0x0002, char properties: 0x02 (0b000010), char value handle: 0x0003, uuid: 00002a00-0000-1000-8000-00805f9b34fb (Device name, i.e. "Pavlok-3-F282")
        handle: 0x0003, uuid: 00002a00-0000-1000-8000-00805f9b34fb
    handle: 0x0004, char properties: 0x02 (0b000010), char value handle: 0x0005, uuid: 00002a01-0000-1000-8000-00805f9b34fb
        handle: 0x0005, uuid: 00002a01-0000-1000-8000-00805f9b34fb
    handle: 0x0006, char properties: 0x02 (0b000010), char value handle: 0x0007, uuid: 00002a04-0000-1000-8000-00805f9b34fb
        handle: 0x0007, uuid: 00002a04-0000-1000-8000-00805f9b34fb
    handle: 0x0008, char properties: 0x02 (0b000010), char value handle: 0x0009, uuid: 00002aa6-0000-1000-8000-00805f9b34fb
        handle: 0x0009, uuid: 00002aa6-0000-1000-8000-00805f9b34fb

attr handle: 0x000a, end grp handle: 0x000d uuid: 00001801-0000-1000-8000-00805f9b34fb (Unknown)
    handle: 0x000b, char properties: 0x20 (0b100000), char value handle: 0x000c, uuid: 00002a05-0000-1000-8000-00805f9b34fb
        handle: 0x000c, uuid: 00002a05-0000-1000-8000-00805f9b34fb
        handle: 0x000d, uuid: 00002902-0000-1000-8000-00805f9b34fb (Notify)

attr handle: 0x000e, end grp handle: 0x0027 uuid: 156e1000-a300-4fea-897b-86f698d74461 (Unknown)
    handle: 0x000f, char properties: 0x0a (0b001010), char value handle: 0x0010, uuid: 00001001-0000-1000-8000-00805f9b34fb (Vibrate)
        handle: 0x0010, uuid: 00001001-0000-1000-8000-00805f9b34fb
        handle: 0x0011, uuid: 00002901-0000-1000-8000-00805f9b34fb ("Vibe")
    handle: 0x0012, char properties: 0x0a (0b001010), char value handle: 0x0013, uuid: 00001002-0000-1000-8000-00805f9b34fb (Beep)
        handle: 0x0013, uuid: 00001002-0000-1000-8000-00805f9b34fb
        handle: 0x0014, uuid: 00002901-0000-1000-8000-00805f9b34fb ("Beep")
    handle: 0x0015, char properties: 0x1a (0b011010), char value handle: 0x0016, uuid: 00001003-0000-1000-8000-00805f9b34fb (Zap)
        handle: 0x0016, uuid: 00001003-0000-1000-8000-00805f9b34fb
        handle: 0x0017, uuid: 00002902-0000-1000-8000-00805f9b34fb (Notify)
        handle: 0x0018, uuid: 00002901-0000-1000-8000-00805f9b34fb ("Zap")
    handle: 0x0019, char properties: 0x0a (0b001010), char value handle: 0x001a, uuid: 00001004-0000-1000-8000-00805f9b34fb (LED)
        handle: 0x001a, uuid: 00001004-0000-1000-8000-00805f9b34fb
        handle: 0x001b, uuid: 00002901-0000-1000-8000-00805f9b34fb ("LED")
    handle: 0x001c, char properties: 0x0a (0b001010), char value handle: 0x001d, uuid: 00001005-0000-1000-8000-00805f9b34fb (Set RTC, really complex looking)
        handle: 0x001d, uuid: 00001005-0000-1000-8000-00805f9b34fb
        handle: 0x001e, uuid: 00002901-0000-1000-8000-00805f9b34fb ("Time")
    handle: 0x001f, char properties: 0x0a (0b001010), char value handle: 0x0020, uuid: 00001006-0000-1000-8000-00805f9b34fb (Hand detection, also double tap?)
        handle: 0x0020, uuid: 00001006-0000-1000-8000-00805f9b34fb
        handle: 0x0021, uuid: 00002901-0000-1000-8000-00805f9b34fb ("HD")
    handle: 0x0022, char properties: 0x0a (0b001010), char value handle: 0x0023, uuid: 00001007-0000-1000-8000-00805f9b34fb (Buttons, pavlok 2?)
        handle: 0x0023, uuid: 00001007-0000-1000-8000-00805f9b34fb
        handle: 0x0024, uuid: 00002901-0000-1000-8000-00805f9b34fb ("Button")
    handle: 0x0025, char properties: 0x0a (0b001010), char value handle: 0x0026, uuid: 00001008-0000-1000-8000-00805f9b34fb (Enable Sleep tracking?)
        handle: 0x0026, uuid: 00001008-0000-1000-8000-00805f9b34fb
        handle: 0x0027, uuid: 00002901-0000-1000-8000-00805f9b34fb ("DAQ")

attr handle: 0x0028, end grp handle: 0x0050 uuid: 156e2000-a300-4fea-897b-86f698d74461 (Unknown)
    handle: 0x0029, char properties: 0x12 (0b010010), char value handle: 0x002a, uuid: 00002001-0000-1000-8000-00805f9b34fb
        handle: 0x002a, uuid: 00002001-0000-1000-8000-00805f9b34fb
        handle: 0x002b, uuid: 00002902-0000-1000-8000-00805f9b34fb (Notify)
        handle: 0x002c, uuid: 00002901-0000-1000-8000-00805f9b34fb ("Get Time")
    handle: 0x002d, char properties: 0x18 (0b011000), char value handle: 0x002e, uuid: 00002002-0000-1000-8000-00805f9b34fb (Used for stopwatch?)
        handle: 0x002e, uuid: 00002002-0000-1000-8000-00805f9b34fb
        handle: 0x002f, uuid: 00002902-0000-1000-8000-00805f9b34fb (Notify)
        handle: 0x0030, uuid: 00002901-0000-1000-8000-00805f9b34fb ("Events")
    handle: 0x0031, char properties: 0x1a (0b011010), char value handle: 0x0032, uuid: 00002003-0000-1000-8000-00805f9b34fb (Timer?)
        handle: 0x0032, uuid: 00002003-0000-1000-8000-00805f9b34fb
        handle: 0x0033, uuid: 00002902-0000-1000-8000-00805f9b34fb (Notify)
        handle: 0x0034, uuid: 00002901-0000-1000-8000-00805f9b34fb ("Events")
    handle: 0x0035, char properties: 0x12 (0b010010), char value handle: 0x0036, uuid: 00002004-0000-1000-8000-00805f9b34fb (Any button press, no idea how to reset the count)
        handle: 0x0036, uuid: 00002004-0000-1000-8000-00805f9b34fb (int)
        handle: 0x0037, uuid: 00002902-0000-1000-8000-00805f9b34fb (Notify)
        handle: 0x0038, uuid: 00002901-0000-1000-8000-00805f9b34fb ("Button Count")
    handle: 0x0039, char properties: 0x12 (0b010010), char value handle: 0x003a, uuid: 00002005-0000-1000-8000-00805f9b34fb
        handle: 0x003a, uuid: 00002005-0000-1000-8000-00805f9b34fb
        handle: 0x003b, uuid: 00002902-0000-1000-8000-00805f9b34fb (Notify)
        handle: 0x003c, uuid: 00002901-0000-1000-8000-00805f9b34fb ("Zap Count")
    handle: 0x003d, char properties: 0x12 (0b010010), char value handle: 0x003e, uuid: 00002006-0000-1000-8000-00805f9b34fb
        handle: 0x003e, uuid: 00002006-0000-1000-8000-00805f9b34fb
        handle: 0x003f, uuid: 00002902-0000-1000-8000-00805f9b34fb (Notify)
        handle: 0x0040, uuid: 00002901-0000-1000-8000-00805f9b34fb ("Beep Count")
    handle: 0x0041, char properties: 0x12 (0b010010), char value handle: 0x0042, uuid: 00002007-0000-1000-8000-00805f9b34fb
        handle: 0x0042, uuid: 00002007-0000-1000-8000-00805f9b34fb
        handle: 0x0043, uuid: 00002902-0000-1000-8000-00805f9b34fb (Notify)
        handle: 0x0044, uuid: 00002901-0000-1000-8000-00805f9b34fb ("Vibe Count")
    handle: 0x0045, char properties: 0x12 (0b010010), char value handle: 0x0046, uuid: 00002008-0000-1000-8000-00805f9b34fb
        handle: 0x0046, uuid: 00002008-0000-1000-8000-00805f9b34fb
        handle: 0x0047, uuid: 00002902-0000-1000-8000-00805f9b34fb (Notify)
        handle: 0x0048, uuid: 00002901-0000-1000-8000-00805f9b34fb ("LED Count")
    handle: 0x0049, char properties: 0x18 (0b011000), char value handle: 0x004a, uuid: 00002009-0000-1000-8000-00805f9b34fb (Sleep tracking data? Also steps?)
        handle: 0x004a, uuid: 00002009-0000-1000-8000-00805f9b34fb
        handle: 0x004b, uuid: 00002902-0000-1000-8000-00805f9b34fb (Notify)
        handle: 0x004c, uuid: 00002901-0000-1000-8000-00805f9b34fb ("Files")
    handle: 0x004d, char properties: 0x12 (0b010010), char value handle: 0x004e, uuid: 0000200a-0000-1000-8000-00805f9b34fb
        handle: 0x004e, uuid: 0000200a-0000-1000-8000-00805f9b34fb
        handle: 0x004f, uuid: 00002902-0000-1000-8000-00805f9b34fb (Notify)
        handle: 0x0050, uuid: 00002901-0000-1000-8000-00805f9b34fb ("Alarm Time")

attr handle: 0x0051, end grp handle: 0x0057 uuid: 156e4000-a300-4fea-897b-86f698d74461 (Unknown)
    handle: 0x0052, char properties: 0x12 (0b010010), char value handle: 0x0053, uuid: 00004001-0000-1000-8000-00805f9b34fb (Training data, maybe used for internal testing?)
        handle: 0x0053, uuid: 00004001-0000-1000-8000-00805f9b34fb
        handle: 0x0054, uuid: 00002902-0000-1000-8000-00805f9b34fb (Notify)
    handle: 0x0055, char properties: 0x1a (0b011010), char value handle: 0x0056, uuid: 00004002-0000-1000-8000-00805f9b34fb (Training data control byte)
        handle: 0x0056, uuid: 00004002-0000-1000-8000-00805f9b34fb
        handle: 0x0057, uuid: 00002902-0000-1000-8000-00805f9b34fb (Notify)

attr handle: 0x0058, end grp handle: 0x0064 uuid: 156e5000-a300-4fea-897b-86f698d74461 (Unknown)
    handle: 0x0059, char properties: 0x1a (0b011010), char value handle: 0x005a, uuid: 00005001-0000-1000-8000-00805f9b34fb (Application control?)
        handle: 0x005a, uuid: 00005001-0000-1000-8000-00805f9b34fb
        handle: 0x005b, uuid: 00002902-0000-1000-8000-00805f9b34fb (Notify)
        handle: 0x005c, uuid: 00002901-0000-1000-8000-00805f9b34fb ("App Control")
    handle: 0x005d, char properties: 0x1e (0b011110), char value handle: 0x005e, uuid: 00005002-0000-1000-8000-00805f9b34fb (Application download?)
        handle: 0x005e, uuid: 00005002-0000-1000-8000-00805f9b34fb
        handle: 0x005f, uuid: 00002902-0000-1000-8000-00805f9b34fb (Notify)
        handle: 0x0060, uuid: 00002901-0000-1000-8000-00805f9b34fb ("App Write")
    handle: 0x0061, char properties: 0x12 (0b010010), char value handle: 0x0062, uuid: 00005003-0000-1000-8000-00805f9b34fb (Alarm info?)
        handle: 0x0062, uuid: 00005003-0000-1000-8000-00805f9b34fb
        handle: 0x0063, uuid: 00002902-0000-1000-8000-00805f9b34fb (Notify)
        handle: 0x0064, uuid: 00002901-0000-1000-8000-00805f9b34fb ("Alarm Ntfy")

attr handle: 0x0065, end grp handle: 0x0068 uuid: 156e6000-a300-4fea-897b-86f698d74461 (OTA for PAVLOK2?)
    handle: 0x0066, char properties: 0x1a (0b011010), char value handle: 0x0067, uuid: 00006002-0000-1000-8000-00805f9b34fb
        handle: 0x0067, uuid: 00006002-0000-1000-8000-00805f9b34fb
        handle: 0x0068, uuid: 00002902-0000-1000-8000-00805f9b34fb (Notify)

attr handle: 0x0069, end grp handle: 0x006c uuid: 0000180f-0000-1000-8000-00805f9b34fb (Battery Service)
    handle: 0x006a, char properties: 0x12 (0b010010), char value handle: 0x006b, uuid: 00002a19-0000-1000-8000-00805f9b34fb (Battery Level, int)
        handle: 0x006b, uuid: 00002a19-0000-1000-8000-00805f9b34fb (int)
        handle: 0x006c, uuid: 00002902-0000-1000-8000-00805f9b34fb (Notify)

attr handle: 0x006d, end grp handle: 0x0079 uuid: 0000180a-0000-1000-8000-00805f9b34fb (Device Information Service)
    handle: 0x006e, char properties: 0x02 (0b000010), char value handle: 0x006f, uuid: 00002a29-0000-1000-8000-00805f9b34fb (Manufacturer Name, string, i.e. "Behavioral Technolo")
        handle: 0x006f, uuid: 00002a29-0000-1000-8000-00805f9b34fb
    handle: 0x0070, char properties: 0x02 (0b000010), char value handle: 0x0071, uuid: 00002a24-0000-1000-8000-00805f9b34fb (Model Number, string, i.e "Pavlok-S")
        handle: 0x0071, uuid: 00002a24-0000-1000-8000-00805f9b34fb
    handle: 0x0072, char properties: 0x02 (0b000010), char value handle: 0x0073, uuid: 00002a25-0000-1000-8000-00805f9b34fb (Serial Number, string, i.e. "FD0000AEF000")
        handle: 0x0073, uuid: 00002a25-0000-1000-8000-00805f9b34fb
    handle: 0x0074, char properties: 0x02 (0b000010), char value handle: 0x0075, uuid: 00002a27-0000-1000-8000-00805f9b34fb (Hardware version, string, i.e. "6.0.0")
        handle: 0x0075, uuid: 00002a27-0000-1000-8000-00805f9b34fb
    handle: 0x0076, char properties: 0x02 (0b000010), char value handle: 0x0077, uuid: 00002a26-0000-1000-8000-00805f9b34fb (Firmware version, string i.e. "6.4.0")
        handle: 0x0077, uuid: 00002a26-0000-1000-8000-00805f9b34fb
    handle: 0x0078, char properties: 0x02 (0b000010), char value handle: 0x0079, uuid: 00002a28-0000-1000-8000-00805f9b34fb (Unknown, maybe string?, i.e. "+0")
        handle: 0x0079, uuid: 00002a28-0000-1000-8000-00805f9b34fb

attr handle: 0x007a, end grp handle: 0x008d uuid: 156e0000-a300-4fea-897b-86f698d74461 (Placeholder for device type?)
    handle: 0x007b, char properties: 0x12 (0b010010), char value handle: 0x007c, uuid: 00000001-0000-1000-8000-00805f9b34fb
        handle: 0x007c, uuid: 00000001-0000-1000-8000-00805f9b34fb
        handle: 0x007d, uuid: 00002902-0000-1000-8000-00805f9b34fb (Notify)
    handle: 0x007e, char properties: 0x02 (0b000010), char value handle: 0x007f, uuid: 00000002-0000-1000-8000-00805f9b34fb
        handle: 0x007f, uuid: 00000002-0000-1000-8000-00805f9b34fb
    handle: 0x0080, char properties: 0x02 (0b000010), char value handle: 0x0081, uuid: 00000003-0000-1000-8000-00805f9b34fb
        handle: 0x0081, uuid: 00000003-0000-1000-8000-00805f9b34fb
    handle: 0x0082, char properties: 0x02 (0b000010), char value handle: 0x0083, uuid: 00000004-0000-1000-8000-00805f9b34fb
        handle: 0x0083, uuid: 00000004-0000-1000-8000-00805f9b34fb
    handle: 0x0084, char properties: 0x02 (0b000010), char value handle: 0x0085, uuid: 00000005-0000-1000-8000-00805f9b34fb
        handle: 0x0085, uuid: 00000005-0000-1000-8000-00805f9b34fb
    handle: 0x0086, char properties: 0x02 (0b000010), char value handle: 0x0087, uuid: 00000006-0000-1000-8000-00805f9b34fb
        handle: 0x0087, uuid: 00000006-0000-1000-8000-00805f9b34fb
    handle: 0x0088, char properties: 0x18 (0b011000), char value handle: 0x0089, uuid: 00000007-0000-1000-8000-00805f9b34fb
        handle: 0x0089, uuid: 00000007-0000-1000-8000-00805f9b34fb
        handle: 0x008a, uuid: 00002902-0000-1000-8000-00805f9b34fb (Notify)
    handle: 0x008b, char properties: 0x18 (0b011000), char value handle: 0x008c, uuid: 00000008-0000-1000-8000-00805f9b34fb (Diagnostic command)
        handle: 0x008c, uuid: 00000008-0000-1000-8000-00805f9b34fb (Hard reset [1, 90, -16], enable sleep [2,1], disable sleep [2,0])
        handle: 0x008d, uuid: 00002902-0000-1000-8000-00805f9b34fb (Notify)

attr handle: 0x008e, end grp handle: 0xffff uuid: 156e7000-a300-4fea-897b-86f698d74461 (Unknown)
    handle: 0x008f, char properties: 0x1e (0b011110), char value handle: 0x0090, uuid: 00007001-0000-1000-8000-00805f9b34fb (Update buttons, pavlok 3?)
        handle: 0x0090, uuid: 00007001-0000-1000-8000-00805f9b34fb
        handle: 0x0091, uuid: 00002902-0000-1000-8000-00805f9b34fb (Notify)
    handle: 0x0092, char properties: 0x0e (0b001110), char value handle: 0x0093, uuid: 00007999-0000-1000-8000-00805f9b34fb
        handle: 0x0093, uuid: 00007999-0000-1000-8000-00805f9b34fb

Training data, appears to work as a motion/position sensor, but I can't find a way to enable the notification. Guessing this is for dev work? Characteristic: 00004001-0000-1000-8000-00805f9b34fb

int x = ((data[0] & 255) << 8) | (data[1] & 255);
int y = (data[3] & 255) | ((data[2] & 255) << 8);
int z = (data[5] & 255) | ((data[4] & 255) << 8);

How to enable?


Update buttons (only for pavlok 3?) 00007001-0000-1000-8000-00805f9b34fb

0 2 (hard coded)
1 1/2/3 (top/middle/bottom)
2 2/1/3 (beep/vibrate/zap)

if(zap) {
    3 (number + 64) stimulusCountRemote?
    4 (percent 1-100)
} else {
    3 (number + 64) stimulusCountRemote?
    4 12 (hard coded)
    5 (percent 1-100)
    6 time code (time active)
    7 time code (time sleeping)
}

Almost appears to match (first byte is double for button presses) the data packet for sending stimuli https://github.com/buttplugio/stpihkal/issues/137