eculocate

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit a892593ea5248ec9a474b999f98ce1fe545149e7
parent 671c2a382cc4b2a53803c1fe7509c3e96e84e50a
Author: Daniel Barlow <dan@telent.net>
Date:   Wed,  4 Feb 2026 18:59:46 +0000

sense-check docs and comments

Diffstat:
MREADME.md | 24+++++++++++++-----------
Mclient/README.md | 40++++++++++++++++++++++++++++++++--------
Mecu-esp32/src/main.rs | 5+++++
Mecu-esp32/src/wifi.rs | 23++++++++---------------
4 files changed, 58 insertions(+), 34 deletions(-)

diff --git a/README.md b/README.md @@ -7,7 +7,7 @@ Comprises: * some code for an ESP32-C3 wich can be connected (via level shifters and other electronics, don't plug it straight in) to the -bike's ECU, +bike's ECU, * a very PoC implementation of an android client, using Termux @@ -30,20 +30,22 @@ The ESP32 is connected to the diagnostic port of the ECU and can interrogate it to dump its "tables". This is based on "K-line", a 1 wire 10400 baud serial connection operating with 12V logic. -It connects to a wifi network (wifi credentials are presently -hardcoded) and listens on a UDP socket for incoming subscription -requests. When it receives a subscription request, it starts to -periodically query the ECU for the requested tables and sends the -value using UDP back to the subscriber. +On first boot, or if it can't connect to a Wifi network, it will +function as a Bluetooth LE peripheral: you can connect to it, +choose a wifi network and provide the password. + +In normal operation it will connect to the configured Wifi network and +open TCP and UDP sockets, The client connects first to TCP and +provides a digitally signed session key, then (provided the signature +is valid) to the UDP socket to send a subscription requests. When the +device receives a subscription request, it starts to periodically +query the ECU for the requested tables and sends the value using UDP +back to the subscriber. To avoid using hardcoded IP addresses, it uses multicast DNS/DNS service discovery to advertise itself as providing the `_keihin._udp.local" service, so a client can use zeroconf/bonjour/avahi to find where it is. -For the moment, there is no security on the UDP service. Until and -unless that canges, you probably shouldn't tell it to connect to -untrusted wifi networks. - -There is a prototype/example client in android-termux-client/. Consult +There is a prototype/example client in client/. Consult the README in that directory for details. diff --git a/client/README.md b/client/README.md @@ -1,12 +1,39 @@ # Client -In the absence of an actual proper Android app, this is a Python -script that runs in Termux. +## Wifi configuration -## Setup +To choose a wifi network and send the password, run -* You will need to (manually, because this -is Android) install Termux and Termux:Gui from the F-Droid repository, +```sh +$ PASSWORD="my wifi passphrase" python client/ble.py my_network_name +``` + +The device will reboot once the wifi details have been saved + + +## Data logging + +Once the wifi is operational, you can run + +```sh +$ python client/eculocate.py Bike 120 +``` + +to collect data for 120 seconds. + +## Android + +If you want to log data while actually, y'know, *riding the bike*, you +might wish to do that without balancing a laptop on the pillion. +There isn't an actual proper Android app (yet, anyway) but we do have +a Python script that runs in Termux. + +### Setup + +* You will need to (manually, because this is Android) install Termux +and Termux:Gui from the F-Droid repository, + +* You also need to copy `privkey.bin` from wherever you built the Rust app onto the phone * in a Termux shell, run @@ -16,6 +43,3 @@ $ termux-setup-storage $ pkg install binutils make libsodium $ SODIUM_INSTALL=system pip install pynacl zeroconf ``` - -* you also need to copy `privkey.bin` from wherever you built the -Rust app onto the phone diff --git a/ecu-esp32/src/main.rs b/ecu-esp32/src/main.rs @@ -47,6 +47,11 @@ extern crate alloc; esp_bootloader_esp_idf::esp_app_desc!(); const BUILD_ID: &str = env!("BUILD_ID"); + +// If the device has valid wifi credentials but you need to change them, +// build with FORCE_WIFI_CHOOSER. +// We should figure out some way to let the end-user do this (add a button?) + const FORCE_WIFI_CHOOSER : bool = option_env!("FORCE_WIFI_CHOOSER").is_some(); diff --git a/ecu-esp32/src/wifi.rs b/ecu-esp32/src/wifi.rs @@ -1,8 +1,5 @@ -//! Set SSID and PASSWORD env variable before running this example. -//! //! This gets an ip address via DHCP and advertises it with mdns -// use alloc::vec; use alloc::vec::Vec; use alloc::string::String; use alloc::format; @@ -27,17 +24,14 @@ use esp_hal::{ rng::Rng, }; use esp_println::println; -use esp_radio::{ -// Controller, - wifi::{ - ScanConfig, - WifiController, - WifiDevice, - WifiEvent, - WifiStaState, - WifiError, - AccessPointInfo - }, +use esp_radio::wifi::{ + ScanConfig, + WifiController, + WifiDevice, + WifiEvent, + WifiStaState, + WifiError, + AccessPointInfo }; use embassy_net::Stack; @@ -254,7 +248,6 @@ async fn net_task(mut runner: Runner<'static, WifiDevice<'static>>) { runner.run().await } - async fn run_tcp_handler(stack : Stack<'_>, sessions : &SessionStore, mut flasher : crate::ota::Flasher<'_>) {