From da29d1a03293bcf8d6e2082aef45cf6388e78f31 Mon Sep 17 00:00:00 2001 From: Koda YeenBean Date: Mon, 13 Jul 2026 20:48:06 +0100 Subject: [PATCH] Added agent.md to make ai workflows more efficient and save tokens (#15) Reviewed-on: https://git.ascheu.de/Koda/OpenUniFi/pulls/15 --- .gitignore | 3 +- AGENTS.md | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 31 ++++++++++++++----- 3 files changed, 116 insertions(+), 9 deletions(-) create mode 100644 AGENTS.md diff --git a/.gitignore b/.gitignore index 845959d..1af687e 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -**/.env \ No newline at end of file +**/.env +/openuf diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..da7763e --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,91 @@ +# Agent guide + +Use this file as the first-pass context for changes in this package. Read only +the module(s) relevant to the task; the public interfaces in `src/*.h` usually +provide enough context before opening an implementation. + +## Project in one paragraph + +openUF is a single-process C daemon for OpenWrt. It makes an OpenWrt access +point look like a UniFi AP: `main.c` periodically sends L2 discovery, LLDP, and +encrypted HTTP inform packets. Controller responses can update persistent +adoption state and apply WiFi configuration through UCI. There is no internal +threading or event framework; the main loop runs once per second. + +## Source map + +| Concern | Start here | Responsibility | +| --- | --- | --- | +| Lifecycle and scheduling | `src/main.c` | Load config/state, choose model, run announce/inform/LLDP timers | +| User configuration | `src/config.[ch]`, `files/openuf.conf` | Parse static daemon settings and defaults | +| Persistent controller state | `src/state.[ch]` | Read/write `/etc/openuf/state.json` | +| Inform/adoption protocol | `src/inform.[ch]` | Build telemetry, encode TNBU packets, handle controller commands | +| Transport and encryption | `src/http.[ch]`, `src/crypto.[ch]` | Raw HTTP/1.0 client and AES-CBC/AES-GCM helpers | +| WiFi provisioning | `src/wlan.[ch]` | Translate controller config to UCI and report VAP state | +| Device telemetry | `src/sysinfo.[ch]`, `src/clients.[ch]` | Read proc/sysfs/`iw`/bridge/dnsmasq data | +| Discovery/topology | `src/announce.[ch]`, `src/lldp.[ch]` | UniFi UDP announce and LLDP send/read | +| Emulated hardware | `src/models.c`, `src/ufmodel.h` | Model registry, radios, ports, and band-to-radio mapping | +| Packaging/service | `Makefile`, `files/openuf.init` | OpenWrt package recipe and procd service | + +Runtime flow: `main()` -> `inform_send()` -> build telemetry -> encrypt -> +`http_post()` -> decrypt response -> `handle_response()` -> optionally +`wlan_apply_config()`/`wlan_apply_system_cfg()` and `state_save()`. + +## Important invariants + +- Treat the TNBU packet layout, byte order, flags, and key selection as protocol + compatibility constraints. An unadopted device must use `DEFAULT_AUTH_KEY`. +- `cfgversion` means successfully applied controller configuration. On an apply + failure it is reset to `"0"` so the controller retries. +- Increment `OPENUF_CONFIG_SCHEMA` when a persisted configuration must be + reapplied after an upgrade. +- Only WiFi sections managed by this daemon may be removed. Their names start + with `openuf_`; preserve unrelated UCI sections. +- Keep model-specific radio and port assumptions in `models.c`, not scattered + across protocol or WLAN code. +- Logging is opt-in because persistent writes wear flash. Debug level 2 may log + decrypted credentials; never enable it by default or expose full auth keys. +- This daemon runs as root and can change network config, send raw frames, and + reboot. Do not run it on a development host as a test. +- The target uses OpenWrt/musl and constrained hardware. Prefer bounded buffers, + explicit ownership, no new heavy dependency, and no background thread unless + the design requires one. + +## Build and validation + +The primary validation is the package cross-build. From the OpenWrt root (two +directories above this package), run: + +```sh +make package/OpenUniFi/compile +``` + +Use `V=s` when compiler diagnostics need more context. Avoid a top-level +`make clean`; if a clean rebuild is necessary, use: + +```sh +make package/OpenUniFi/clean +make package/OpenUniFi/compile +``` + +`Makefile.standalone` is for compiling on an OpenWrt device with development +packages installed; it is not a host-side substitute for the cross-build. +There is currently no automated test suite. For documentation-only changes, +check paths and commands against the source and package Makefile. For C changes, +the cross-build is the minimum verification; report any device/controller +behavior that still needs manual testing. + +## Change discipline + +- Keep headers as the concise contract and implementation detail in `.c` files. +- Update `Makefile` and `Makefile.standalone` together when adding/removing a + source file or library. +- Update `files/openuf.conf`, `config.[ch]`, and the README together when changing + a user-facing setting. +- Update `ufmodel.h`, every affected model entry, and telemetry/WLAN consumers + together when changing model data. +- Preserve controller compatibility unless the task explicitly changes it. + Call out changes to payload fields, encryption, adoption, UCI, or persistent + state in the handoff. +- Do not commit generated binaries, OpenWrt build output, runtime state, logs, or + captured protocol payloads. diff --git a/README.md b/README.md index d6f8038..a755657 100644 --- a/README.md +++ b/README.md @@ -20,19 +20,30 @@ Daemon that makes an OpenWrt router appear as a UniFi AP to UniFi Network contro | **LLDP Send** | Custom frames via AF_PACKET raw socket | `lldp.c` → `lldp_send_frame()` | | **LLDP Read** | Neighbors for UniFi topology | `lldp.c` → `lldpctl -f json` | -## Using the dev container +## Building in the dev container ```shell -# OpenWRT build directory +# From the OpenWrt build root cd /home/openwrt/openwrt -# clean Previous builds -make clean +# Build only this package +make package/OpenUniFi/compile -# Compile -make +# For a clean package rebuild +make package/OpenUniFi/clean +make package/OpenUniFi/compile ``` +`Makefile.standalone` is an alternative for compiling directly on an OpenWrt +device that has the development dependencies installed: + +```shell +make -f Makefile.standalone +``` + +Contributors and AI agents should read [`AGENTS.md`](AGENTS.md) for the concise +architecture map, invariants, and validation checklist. + ## Changing Compiler Settings ```shell @@ -52,7 +63,7 @@ make menuconfig ## Configuration -On The Accesspoint Run this to install the package: +On the access point, run the following to install the package: ```shell # Install dependencies @@ -77,13 +88,17 @@ lan_if = br-lan # Default Lan interface Name ufmodel = u6-inwall # emulated model inform_interval = 10 # inform interval enable_announce = 1 -enable_inform = 1 # Enable logging to /var/log/openuf.log if set to 1 +enable_inform = 1 # Enable adoption and telemetry requests enable_logging = 1 # Write diagnostics to /var/log/openuf.log protocol_debug_level = 0 # 0=off, 1=safe response details, # 2=full decrypted JSON (contains secrets) ``` +Daemon settings live in `/etc/openuf/openuf.conf`. Adoption and controller state +are persisted separately in `/etc/openuf/state.json`; do not copy that file +between devices because it contains the device authentication key. + --- ## Glossary