>ridedaemon 

If you have some basic programming knowledge and no interest in understanding the guts of CFMoto's infotainment systems, I've made a library you can use to stream whatever your heart desires to your motorcycle's dash, as long as it's properly encoded.

T-Box Basics

CFMoto's infotainment and GPS system, the T-Box, has two basic user-facing interfaces. BLE has its own simple auth protocol and controls things like alert events, alarm triggers, and media commands. The WiFi interface is in charge of displaying navigation data on the motorcycle's TFT display.

Why Not Android Auto or CarPlay?

Officially, there's no per-model licensing fee to support CarPlay or Android Auto. Apple only charges a one-time, nominal fee to join their Made for iPhone program, and Android Auto's phone-projection mode is free to implement. So it's not that CFMoto would be paying a toll per unit sold.

What they'd be signing up for instead is the engineering cost and ongoing maintenance of a proper CarPlay/Android Auto integration, on top of the fact that Apple and Google's ecosystems just aren't as dominant in CFMoto's home market. A local, budget-friendly third-party provider that already does this for a dozen other Chinese vehicle brands is a much faster, cheaper path to "phone mirrors to the dash" than building and maintaining that integration in-house. That's the route CFMoto took, with a provider called EasyConn, who make software like CarBit to enable navigation on dashboards for several Chinese vehicle brands, and who are the actual manufacturer of the T-Box itself.

The navigation system runs as a non-buffered, GOP-sensitive, intra-tolerant, predictive H.264 encoder with externally supplied timing control, streaming at 15-30 fps and 2-5 Mbps.

For an aspiring dev, that means:

  • You need to provide the navigation data (map tiles, screen share, etc.), if the OS allows it.
  • You need to properly encode the frames you feed to the TFT display.

T-Box Nav Limitations: Why MotoPlay Sucks on iOS

The T-Box expects display frames to be provided over a local network stream inside its AP, meaning the device has to actively push map tiles. The official app does this by drawing tiles from another third-party provider onto a virtual surface, then encoding and streaming that surface to the TFT display over the T-Box's WiFi AP. If the app's state changes, say, you lock your phone, that connection can get downgraded or closed, so you usually need to keep the phone unlocked on iOS, and on some Android devices too.

For an aspiring dev, that means two things:

  • Your app needs to handle state changes cleanly.
  • If you go the screen-share route, some platforms restrict that functionality when the phone is locked.

The Ridedaemon Library

The library I wrote handles most of the annoying parts of this interaction:

  • Discovery, finding the EasyConn service inside the AP's network.
  • Connection, the handshake between devices and encryption.
  • Media control & streaming, the command channel and media frame polling.

It's all wrapped in a simple API an app can use like this:

val session = Api.newMobileSession(config, callback)
session.discoverHost()
session.setECHost(host)
session.startSession()
// on each encoded frame from MediaCodec:
session.pushFrame(avccBytes)
Desktop demo streaming a video feed to a CFMoto head unit over the ridedaemon library

the desktop demo, streaming a screen capture straight to the dash

The Ridedaemon App

The sample Android app is a simple app that implements a basic 2D scene rendering engine, drawing onto a surface and streaming it to the TFT display. Right now it only displays text, a dynamically generated sine wave, and a live timestamp. To use it, you'll need to build the library, embed it in the app, and install it on your device.

Ridedaemon Android app connecting and streaming to a CFMoto head unit

the Android app pushing a live scene to the dash over WiFi

Hopes & Dreams

I started this project last year, hoping to build my own nav app. I ended up selling the bike, so I shelved it. Then I saw that u/Co1337z had also been reverse-engineering the protocol, and realized more people are independently working on the same problem, each starting from scratch and burning time on the same low-level comms code.

I'm hoping this makes that part easier, and that it eventually leads to an open source nav app, one where people can pick their own map tile provider/API keys and get a private nav app, or even build their own custom riding dashboards. I get CFMoto's position on the subscription service (map tile providers charge monthly fees, and I'd assume EasyConn charges CFMoto too), but there's no reason to wall users out of their own motorcycle's systems. They already paid for the whole bike.

AI Use & Implementation Notes

I used AI to help narrow down and implement the stream encoding parts of the library, since I had no prior experience with video streaming at this level. The Android app is partly vibe-coded, since my only goal there was to test the library's functionality. The library itself is a compilation and refinement of all my research from testing the T-Box.

License

Both repos are GPL-3.0. Full text lives in each one's LICENSE file. Short version:

You can

  • Use, study, and modify the code, commercially too
  • Redistribute it, modified or not
  • Ship it inside a larger project

You can't

  • Redistribute it closed source, derivatives stay GPL-3.0
  • Hold this project or its contributors liable
  • Sublicense it under stricter terms