diary @ telent

A joke about UDP#

Sat Jan 17 08:30:09 2026

Topics: rust eculocate esp32

I'll tell you a joke about UDP, but you might not get it.


We have a new name. "Thing I can plug into my motorbike ECU to log the data (rpm, speed, throttle position, temperatures etc etc) it produces" is Leonard-of-Quirm-level naming. I'd provisionally been calling it "eculogical" which I didn't like, and now it's called "eculocate" which I ... can tolerate.

And I've got it to the point where it (kind of) works - but, now I've decided I need to semi-fundamentally break it again. I'll get to that.

On the server side we have a UDP socket that listens for subscription message containing [(interval, table-number, start, end), ...] (actually binary encoded) and then sends back the requested table data once every interval milliseconds for the next minute. Then it stops, because this is UDP and we can't reliably tell when the peer has gone away, so the peer should send another subscription message in the meantime if it wants to carry on receiving.

For now we're just offering the raw tables, because I'm going to need much more example data to figure out the structure. Eventually we'll do some processing on device so that clients can query "RPM" or "TPS" without having to know their table/offset - as that varies between bike models.

Notes:

And we have an Android client. Well, it's Android insofar as it runs on my phone, but I don't think it'd qualify for Android Market or the Play Store or whatever it's called now. I sidestepped the whole android app development slog, by installing Termux and Termux:GUI on my phone and writing the client side as a Python script. I don't even like Python and I still found this preferable to the Android Studio build/run process: I simply sshed into my phone and used tramp to edit the script. I believe that Termux:GUI doesn't support the full range of Android widgets but it has buttons and labels and text boxes and LinearLayouts which is enough for me. Adding dns-sd (zeronconf) support was the work of about 20 minutes, which was nice.

Having achieved that milestone I made a list of what's left before I can plug it into my motorbike and take it for a ride (cable, power supply, some form of protective casing) and realised that once I detach it from its USB umbilical I will no longer be able to release new versions simply by invoking cargo run. So, it needs a mechanism for OTA updates, and this should probably come with some kind of auth[nz] so that not just any Tom, Dick or Harry on the same wifi network could flash random crap onto it. Then I considered that if we're not trusting the wifi, the actual UDP service (which is currently read-only but maybe some day might include a means of writing to (and therefore probably bricking) the ecu) is also sensitive.

Here's the plan:

Additionally, we need to change the dns-sd stuff to advertise a TCP service, the client to register a session key when it starts, the subscription message format to include the session key, and the UDP listener to check it. Which is what I meant when I said "semi-fundamentally break it".

If this were commercial/proprietary software then we'd have separate keys for the firmware signing and for the client. That seems less of an issue when it's most likely the same person building the software as is using the client, but it might be worth doing anyway.

Current status: bodged together a TCP listener, haven't touched on crypto yet, and so far it only pretends to do the OTA update.