@rohanmondal0505/open-dash-sdk
v0.1.0
Published
Unofficial Node.js SDK for the Royal Enfield Tripper Dash K1G control protocol (connect, authenticate, stream video). Reverse-engineered, not affiliated with Royal Enfield.
Maintainers
Readme
open-dash-sdk
Unofficial Node.js SDK for the Royal Enfield Tripper Dash K1G control protocol.
This is a from-scratch Node/TypeScript port of the protocol behavior documented
in open-dash's
PROTOCOL_FREEZE.md —
connection sequencing, socket targets, auth flow shape, frame-ACK handling, and
RTP packetization rules.
Not affiliated with, endorsed by, or supported by Royal Enfield. The Tripper Dash protocol is unofficial and reverse-engineered. Use at your own risk, and only against your own hardware.
What this is (and isn't)
This SDK runs in Node.js — a CLI tool, an Electron app, a Raspberry Pi,
a backend service. It is not a React Native package: React Native's JS
runtime has no raw UDP socket API, so this can't run directly inside a phone
app. If you're building a phone app, you'll want an Android native module
(Kotlin) for the actual socket I/O, and you can use this codebase as a
reference for the protocol logic (packet shapes, sequencing) when you port it.
For convenience, an initial native Kotlin scaffold has been provided in the android-reference/ folder of this repository.
What's confirmed vs. placeholder
The publicly documented PROTOCOL_FREEZE.md describes the behavioral
rules of the protocol (ordering, ports, lengths, cadences) but not every
exact byte layout. This SDK is honest about that split:
Confirmed / implemented for real:
- Control socket ports and targets (TX
:2000→broadcast, RX:2002, RTP→dash:5000). - The 10-phase connection sequence (open sockets → auth → nav mode → READY → streaming).
- Rolling K1G sequence byte on every send.
- Auth handshake shape:
q3c.erequest → dash RSA challenge → 128-byte ciphertext reply → confirm. - Frame-decoded ACKs (
09 06 55/09 04 55) and button ACK echoing — handled in the RX path for the full session. - RTP packetization: payload type 96, 90 kHz clock, 1380-byte max payload, FU-A fragmentation (no STAP-A), marker bit only on the last packet of an access unit, incrementing sequence numbers.
- Media (
05 0D) and caller (05 22) card encoding as NUL-separated fields.
Placeholder — confirm against your own packet capture before trusting on real hardware:
- The exact RSA ciphertext content for the auth reply (
keyDeriver— you must supply this; the SDK throws rather than guessing). - Exact byte layouts for
navContext,emptyLists,projectionFrame,navPlaceholder,navStart, the status heartbeat, and the route-card template fields. - Heartbeat/keep-alive cadence values (defaults are reasonable guesses, exposed as constructor options so you can tune them).
If you have access to a real dash, capturing traffic (e.g. with tcpdump/Wireshark
on the host that's bridging to the dash's Wi-Fi) and comparing it against these
placeholders is the natural next step before relying on this for real rides.
Install
npm install open-dash-sdkThe one thing this SDK can't do for you: Wi-Fi association
Your machine needs to already be connected to the dash's RE_* Wi-Fi network
before calling connect(). Node has no built-in Wi-Fi scan/join API on any
platform — on Android, OpenDash uses WifiNetworkSpecifier for this, which has
no Node equivalent. Connect manually via your OS's Wi-Fi settings, or shell out
to a platform tool (nmcli, netsh wlan, networksetup) from your own code.
checkDashSubnet() is provided as a sanity check (confirms you're on
192.168.1.0/24), not a way to join the network.
Quick start
import { DashSession, checkDashSubnet } from "open-dash-sdk";
const { onDashSubnet } = checkDashSubnet();
if (!onDashSubnet) {
console.warn("Connect to the dash's RE_* Wi-Fi network first.");
}
const session = new DashSession({
ssid: "RE_TRIPPER_1234", // the exact confirmed SSID you discovered
// keyDeriver: ... // REQUIRED for real auth, see "Auth" below
});
session.on("stateChange", (state) => console.log("state:", state));
session.on("buttonEvent", (code) => console.log("button:", code));
session.on("error", (err) => console.error("error:", err));
await session.connect(); // runs phases 1-9: sockets → auth → nav mode → READY
// session.startStreaming(); // phase 10, once you're sending real video framesSee examples/connect.ts for a runnable version.
Auth: you must supply a keyDeriver
The RSA ciphertext content sent back to the dash isn't published at the byte level anywhere we could verify, so this SDK refuses to guess it. Pass your own:
import type { KeyDeriver } from "open-dash-sdk";
const myKeyDeriver: KeyDeriver = (dashPublicKeyPayload) => {
// Your confirmed encryption logic here, returning exactly 128 bytes.
// ...
};
const session = new DashSession({ ssid: "RE_TRIPPER_1234", keyDeriver: myKeyDeriver });Without this, connect() will throw as soon as the dash sends its auth
challenge — by design, so you don't silently send wrong bytes to real hardware.
API surface
DashSession— the connection state machine (connect(),startStreaming(),sendRtpPacket(),disconnect(), events:stateChange,buttonEvent,error).DashSocket— low-level UDP transport (control TX/RX + RTP send).DashAuth— auth handshake state machine.DashCommands— builds individual K1G command packets.RtpPacketizer— H.264 NAL unit → RTP packet fragmentation (FU-A).checkDashSubnet()— sanity-checks local network state.NETWORK,RTP,TLV,AUTH,DASH_RESOLUTION— protocol constants.
Full type definitions ship with the package (dist/index.d.ts).
Video streaming
This SDK packetizes H.264 into RTP correctly, but Node has no built-in
hardware H.264 encoder (unlike Android's MediaCodec, which is what OpenDash
uses). To actually stream video you'll need to bring your own H.264 elementary
stream — e.g. from ffmpeg, GStreamer, or a hardware encoder — and feed NAL
units into RtpPacketizer.packetizeNalUnit(), then send the resulting packets
via session.sendRtpPacket().
Building from source
git clone <your-repo-url>
cd open-dash-sdk
npm install
npm run buildRun the protocol-logic sanity checks (no real dash required):
npx tsx test/sanity-test.tsCredit
Protocol behavior reverse-engineered by the open-dash project, which itself builds on reverse-engineering from better-dash. This package is an independent Node.js re-implementation based on their published protocol documentation, not a copy of their Kotlin source.
License
Apache-2.0
