Rynk Protocol Reference

Current protocol version: 0.1.

Every transport (USB CDC, BLE GATT, BLE HID) carries the same frame — a 5-byte header plus a postcard-encoded payload:

┌──────────────┬───────────┬────────────────────┐
│ CMD u16 LE   │ SEQ u8    │ LEN u16 LE         │  ← 5-byte header
├──────────────┴───────────┴────────────────────┤
│              postcard-encoded payload         │  ← LEN bytes
└───────────────────────────────────────────────┘
  • Requests use CMD 0x0000..=0x7FFF. The response echoes CMD and SEQ and wraps its payload in postcard Result<T, RynkError> (T = () for Set*).
  • Topics use CMD 0x8000..=0xFFFF (server → host push, SEQ 0, bare payload).

Which commands a firmware answers depends on the RMK Cargo features it was built with: a row with no Feature is present once rynk is on, and the rest need their feature (_ble, split, …) compiled in. A command the firmware wasn't built with answers UnknownCmd.

Endpoints

CMDNameRequestResponseFeatureNotes
0x0001GetVersion()ProtocolVersion
0x0002GetCapabilities()DeviceCapabilities
0x0003Reboot()()
0x0004BootloaderJump()()
0x0005StorageResetStorageResetMode()
0x0006GetLockStatus()LockStatusPure read of the current lock state — no side effects.
0x0007UnlockPoll()LockStatusArms/refreshes the unlock attempt and samples the held challenge keys.
0x0008Lock()()Relock immediately.
0x0009GetLayoutu32LayoutChunkGet layout blob chunk. u32 is the byte offset.
0x000AGetDeviceInfo()DeviceInfoIdentity strings and USB ids; feature gating stays in GetCapabilities.
0x0101GetKeyActionKeyPositionKeyAction
0x0102SetKeyActionSetKeyRequest()
0x0103GetDefaultLayer()u8
0x0104SetDefaultLayeru8()
0x0105GetEncoderActionGetEncoderRequestEncoderAction
0x0106SetEncoderActionSetEncoderRequest()
0x0107GetKeymapBulkGetKeymapBulkRequestGetKeymapBulkResponse
0x0108SetKeymapBulkSetKeymapBulkRequest()
0x0201GetMacroGetMacroRequestMacroData
0x0202SetMacroSetMacroRequest()
0x0301GetCombou8Combo
0x0302SetComboSetComboRequest()
0x0303GetComboBulkGetComboBulkRequestGetComboBulkResponse
0x0304SetComboBulkSetComboBulkRequest()
0x0401GetMorseu8Morse
0x0402SetMorseSetMorseRequest()
0x0403GetMorseBulkGetMorseBulkRequestGetMorseBulkResponse
0x0404SetMorseBulkSetMorseBulkRequest()
0x0501GetForku8Fork
0x0502SetForkSetForkRequest()
0x0601GetBehaviorConfig()BehaviorConfig
0x0602SetBehaviorConfigBehaviorConfig()
0x0701GetConnectionType()ConnectionType
0x0702GetConnectionStatus()ConnectionStatusFull ConnectionStatus snapshot.
0x0703GetBleStatus()BleStatus_ble
0x0704SwitchBleProfileu8()_ble
0x0705ClearBleProfileu8()_ble
0x0801GetCurrentLayer()u8
0x0802GetMatrixState()MatrixState
0x0803GetBatteryStatus()BatteryStatus_ble
0x0804GetPeripheralStatusu8PeripheralStatussplit
0x0805GetWpm()u16Latest WPM, sourced from the WpmUpdate topic snapshot.
0x0806GetSleepState()boolLatest sleep flag, sourced from the SleepState topic snapshot.
0x0807GetLedIndicator()LedIndicatorLatest HID LED bitmap, sourced from the LedIndicatorChange topic snapshot.

Topics

Topics are best-effort pushes; the Get* endpoints above mirror their payloads so a host can recover a missed push.

CMDNamePayloadFeatureNotes
0x8001LayerChangeu8
0x8002WpmUpdateu16
0x8003ConnectionChangeConnectionStatus
0x8004SleepStatebool
0x8005LedIndicatorChangeLedIndicator
0x8006BatteryStatusChangeBatteryStatus_ble

Compatibility

  • GetVersion (0x0001) and its Result<ProtocolVersion, RynkError> reply are frozen across all versions.
  • Within a major version, adding a CMD or topic is a minor bump: old firmware answers UnknownCmd, old hosts ignore unknown topics.
  • Reshaping an existing request/response — including appending a field — is a major bump.