Skip to content

Device support: Yiciyuan YCY-FJB-01 (cup, JieLi SoC) #887

@SanJerry007

Description

@SanJerry007

Per CONTRIBUTING in CLAUDE.md, filing this issue before submitting a PR.

Device

Yiciyuan FJB-01 (役次元): white gen-2 BLE-controlled stroker built on a JieLi SoC.

  • Adv name: YCY-FJB-01
  • MAC pattern: 0C:A5:E2:* (JieLi OUI)
  • Adv service UUID: 0xFF40
  • Mfr data magic: JLAISDK (JieLi AI SDK)
  • Product listing: sold on the official 役次元 site / Taobao under "FJB-01"

This is the cup, not the DG-LAB powerbox clone — addressing the question left open in #688. Stroke is an oscillating linear actuator (back-and-forth motion driven by 0..=0x14 level on a single byte), plus two separate vibration motors.

Why now

PR #688 attempted to add support for this vendor in 2024 and was closed in April 2026 for inactivity — CLA was signed but the reviewer's questions (oscillate vs vibrate? product link? full test coverage?) were never answered. I've reverse-engineered the protocol independently and have a working implementation ready that addresses each of those points.

Protocol (verified against firmware reporting 02 07 07)

GATT layout:

Service Char UUID Properties
0xFF40 cmd in 0000ff41-0000-1000-8000-00805f9b34fb write, write-without-response
0xFF40 status out 0000ff42-0000-1000-8000-00805f9b34fb read, notify

Control packet (always 16 bytes):

[0] 0x35       vendor magic
[1] 0x12       "set motor levels" sub-command
[2] stroke     0..=0x14 — linear oscillation
[3] vibe       0..=0x14 — vibration motor
[4] axis_c     0..=0x14 — third haptic motor (driven by app patterns)
[5..15] 0x00   reserved

Battery push arrives unprompted on the notify char as 35 13 01 <pct>, mixed with 10 Hz uptime ticks (35 14 ..) we filter out by prefix.

Buttplug v4 mapping

Index Description OutputType Range
0 stroke Oscillate 0..=100
1 vibe Vibrate 0..=100
2 axis_c Vibrate 0..=100
3 battery Input::Battery (Read + Subscribe) 0..=100

Same shape as Galaku G317 / TFF1 (oscillate + 2×vibrate + battery), so the data model is already proven in tree.

Implementation status

Done and locally verified — branch SanJerry007/buttplug:add-yiciyuan-fjb-01:

  • device-config-v4/protocols/yiciyuan.yml
  • protocol_impl/yiciyuan.rs (atomic per-axis state, single 16-byte frame per call, prefix-filtered battery read)
  • device_test_case/test_yiciyuan_protocol.yaml (Scalar/Stop gated on v3+ since v0–v2 single-axis Vibrate semantics don't map cleanly to a multi-actuator device)
  • Test case registered in all 10 test_device_protocols slots (v0–v4 × embedded/json)
  • cargo test -p buttplug_tests --test test_device_protocols818/818 pass
  • cargo build → clean (no new warnings)
  • CLA already signed on prior account

Happy to open the PR if this is welcome. ~470 lines, 7 files (+2 build artifacts: regenerated config JSON + minor version bump). No regressions, no changes to unrelated files.

Future incremental work (separately, if desired)

  • Reverse-direction stroke (firmware accepts signed -20..+20 on byte 2; out of scope for this PR — Buttplug's Oscillate is unsigned)
  • Additional model identifiers as they appear (currently only FJB-01 is verified; the YAML structure makes adding more straightforward)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions