buttplugio / docs.buttplug.io

11 stars 7 forks source link

Document Tremblr BT-R Protocol #13

Open denialtek opened 12 months ago

denialtek commented 12 months ago

Service: 0xfff0 TX: 0xfff1

Message format

{command} 0x64 0x00 0x00 0x00 0x00 0x31 0x32 0x33 0x34 0x00 0x00 0x00 0x00 0x00 0x00 0x00 {crc-8 checksum}

The 0x31 0x32 0x33 0x34 bytes are intended to be used for password functionality but it appears to not be implemented.

Commands

The commands all map to button presses or releases on the UI.

0x01 - On/Off button held down 0x02 - On/Off button released

0x05 - Speed Up button held down 0x06 - Speed Down button held down 0x03 - Speed buttons released

0x07 - Suction Up button held down 0x08 - Suction Down button held down 0x09 - Suction buttons released

ex. Turn on device - Send 0x01 and then 0x02 Turn off device - Send 0x01 and then 0x02 Increase speed - Send 0x05 once. The device will continue slowly speeding up until 0x03 is sent.

There doesn't appear to be a way of reading what the current on/off state, speed, or suction level is of the device.

CRC-8

The CRC-8 checksum formula is non-standard. In JavaScript it looks like:

calcCrc8 (data) {
    let bitCount = 0
    let crc = 0

    for (let i = 0; i < data.length; i++) {
      const byte = data[i]
      for (let j = 0; j < 8; j++) {
        if ((byte & (1 << j)) !== 0) {
          bitCount++
        }
      }
    }

    const remainder = bitCount % 3

    if (remainder === 0) {
      crc = 222 - bitCount
    } else if (remainder === 1) {
      crc = Math.floor(bitCount / 2) + 111
    } else if (remainder === 2) {
      crc = Math.floor(bitCount / 3) + 177
    }

    return crc
}
penaltybush commented 11 months ago

@denialtek Do you have the BLE Name it advertises under?

I'm looking to write a BLE to RF bridge for the Tremblr so that the older model can be used by the new BT-R smart app and any future services. Simular to LVS-Gateway.

My current attempts to emulate it using the information you have already provided doesn't allow for it to be detected by the smart app. If you have any additional information about the way this model presents itself via bluetooth I'd be greatful.

Thanks.

denialtek commented 11 months ago

BLE Name: FM-T

penaltybush commented 11 months ago

@denialtek Thanks that was what I was missing. I was able to grab some data from the iOS app.

From the iOS app I don't seem to receive button release messages, if I hold down a button on the app the message repeats around once per second.

BLE Messages

App

penaltybush commented 11 months ago

I noticed that in the App Store screenshots it also shows a remote marked as 'GIGOLO'. I checked the FCC ID filing for the Tremblr BT-R and the documents mention both the Tremblr and the Gigolo so I suspect there will be an announcement for a Gigolo BT-R at some point.

I tested setting the BLE Name to 'FM-G' and this makes the BLE device show up in the iOS App as GIGOLO and presents the same virtual remote minus the -/+ Suction buttons. I can also confirm that the buttons on the Gigolo remote send exactly the same codes as the Tremblr remote.

penaltybush commented 8 months ago

@denialtek Thanks that was what I was missing. I was able to grab some data from the iOS app.

From the iOS app I don't seem to receive button release messages, if I hold down a button on the app the message repeats around once per second.

An updated version of the iOS app has been published and it no longer functions differently to the Android app. The iOS app now sends a single button press event followed by a button released event once the button is let go.


Also support for a new device has been added "F-machine Alpha" (BLE-Name: FM-A), this device uses the same remote codes as the Trumblr however Suction -/+ codes are used to change stroke depth.

Alpha Commands Capture

penaltybush commented 8 months ago

How F-Machine Connect implements Remote Play.

This information could be useful for adding support to the library.

The app only tracks the state of the device's speed, the suction level is not tracked. The speed is tracked as a value between 0 (off) and 28 (full speed). The speed down command can only reduce the speed to 1 (not zero). When a button is held in the remote UI, Speed Pressed and Speed Release are sent continuously but the value is only considered to change by 1 every 200ms.

On Start

When a remote session is started in the app, the app sends the Speed Press Down, followed by the Speed Release commands 55 times (60ms apart, 110 total commands). This is probably done to ensure that if the machine was currently on level 28, there would be enough commands to bring it down to level 1.

When a Speed Change Button is Pressed (Tapped)

The app sends the Speed Pressed and Speed Release commands twice (60ms apart, 4 total commands).

When a Speed Change Button is Held

The app sends the Speed Pressed and Speed Release commands 60ms apart continuously. However, the internal counters only consider the value to have changed by 1 every 200ms.

When a Suction Change Button is Pressed (Tapped) or Held

The app sends the Suction Pressed signal followed by the Suction Release signal. If the button is held, the Release signal is not sent until the button is released.

When the On/Off Button is Pressed (Tapped) or Held

The app sends the On/Off Pressed signal followed by the On/Off Release signal. If the button is held, the two signals are not sent until the button is released.