Files
OpenUniFi/AGENTS.md
T
KodaandKoda 4f30a031bb
Build and publish release / metadata (push) Canceled after 0s
Build and publish release / create-release (push) Canceled after 0s
Build and publish release / build (push) Canceled after 0s
Build and publish release / publish-release (push) Canceled after 0s
Generate and publish developer Wiki / generated-wiki (push) Failing after 43s
fixing wiki generation (#38)
Reviewed-on: #38
Co-authored-by: Koda YeenBean <n122330@gmail.com>
2026-07-19 22:34:26 +01:00

6.6 KiB

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 exchange src/inform/inform.c, src/inform.h Orchestrate payload, TNBU, HTTP, and response stages
Inform internals src/inform/{payload,packet,response}.c Build telemetry, encode TNBU packets, handle 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/{provision,legacy,radio,uci}.c, src/wlan.h Translate controller config to UCI
WiFi telemetry/helpers src/wlan/{telemetry,common}.c Report VAP state and share translations
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 -> inform_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:

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:

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.

Architecture pages for the Gitea Wiki are generated from the recursive C source tree into a separate checkout. After source or architecture changes, run:

./scripts/docs/generate-wiki.py --output /path/to/openunifi.wiki
./scripts/docs/generate-wiki.py --check --output /path/to/openunifi.wiki

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.

Environment pitfalls and shared discoveries

  • In this workspace, the Codex apply_patch helper is currently unusable. It fails with bwrap: No permissions to create a new namespace, including when invoked from an approved command outside the normal sandbox. Do not spend time retrying it or tracing its symlink after seeing this known error.
  • For repository edits, use git apply --recount with a focused unified diff as the fallback. --recount avoids failures caused by manually miscounted hunk lengths. Review the resulting git diff and run git diff --check afterward. Preserve unrelated worktree changes exactly as with any other editing method.
  • Ordinary read-only commands may fail with the same bwrap namespace error. When the command is safe and required, rerun it using the environment's normal escalation/approval mechanism instead of investigating the namespace setup.

Agents must preserve useful environment knowledge for later agents. When a new pitfall or workaround is verified to be deterministic or repeatedly encountered, add a short entry to this section before handoff. Keep these entries actionable and specific: include the recognizable failure, the confirmed workaround, and any validation required afterward.

Do not record transient command failures, guesses, lengthy logs, credentials, auth keys, host secrets, or details that only apply to a single task. If a discovery could weaken safety controls or requires broader permissions, report it to the user instead of documenting a bypass.