A joke about UDP#
Sat Jan 17 08:30:09 2026
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:
- the embassy-net IP stack (actually smoltcp) requires you to statically declare how many sockets you're going to use which is fine once you know you have to.
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:
- we'll make an EdDSA key pair at build time and embed the public key in the binary
- build tooling will sign the release artefact with the key
- a TCP socket will listen for OTA update requests and verify the signature before writing to the flash
- the TCP socket will also listen for session key registrations (signed in the same way) and remember them for x hours (or until the ignition is turned off and we lose power)
- the UDP listener will reject subscription requests unless they come with a valid session key
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.