e523398fa8
- apps/device-agent-embedded/: ESP32 WireGuard agent (C, ESP-IDF, mbedTLS) - reference/namespace-vrf/: Linux namespace/VRF network isolation docs - apps/android-agent: VPN permission check, StartResult sealed class
135 lines
4.3 KiB
Markdown
135 lines
4.3 KiB
Markdown
# PROJECT KNOWLEDGE BASE
|
|
|
|
**Generated:** 2026-06-26
|
|
**Repository:** `nexus-agent-embedded`
|
|
|
|
## OVERVIEW
|
|
NexusGuard Embedded Agent: ESP32-based WireGuard client for IoT/edge devices. Runs on FreeRTOS + ESP-IDF, connects to NexusGuard Server Core via HTTP provisioning + heartbeat, manages WireGuard tunnel via lwIP stack.
|
|
|
|
## STRUCTURE
|
|
```
|
|
nexus-agent-embedded/
|
|
├── main/
|
|
│ ├── main.c # Entry point, initialization
|
|
│ ├── provision.c/.h # HTTP provisioning (POST /api/v1/provision)
|
|
│ ├── heartbeat.c/.h # HTTP heartbeat loop (POST /api/v1/heartbeat)
|
|
│ ├── tunnel.c/.h # WireGuard tunnel management via lwIP
|
|
│ ├── crypto.c/.h # AES-256-GCM decrypt (mbedtls)
|
|
│ ├── config.c/.h # NVS config storage
|
|
│ └── wifi.c/.h # WiFi STA management
|
|
├── components/
|
|
│ └── wireguard-esp32/ # WireGuard library (lwIP-based)
|
|
├── docs/
|
|
│ ├── DESIGN.md # Technical design document
|
|
│ ├── API_COMPAT.md # Server API compatibility
|
|
│ └── HARDWARE.md # ESP32/LW840X hardware reference
|
|
├── CMakeLists.txt # ESP-IDF build system
|
|
├── sdkconfig.defaults # ESP-IDF configuration
|
|
├── AGENTS.md # This file
|
|
└── README.md
|
|
```
|
|
|
|
## API PROTOCOL (Shared with Server)
|
|
|
|
### Provisioning
|
|
- **Endpoint**: `POST /api/v1/provision`
|
|
- **Request**: `{ "token": "string", "hwid": "string" }`
|
|
- **Response**: `{ "encrypted_config": "base64-bytes" }`
|
|
- **ConfigPayload** (decrypted): device_id, private_key, preshared_key, internal_ip, server_pub, endpoint, dns, allowed_ips, server_wg_ip
|
|
|
|
### Heartbeat
|
|
- **Endpoint**: `POST /api/v1/heartbeat`
|
|
- **Request**: `{ "device_id": "UUID", "status": "connected|recovering|stopped", "tunnel_up": bool, "last_handshake": "ISO8601" }`
|
|
- **Response**: Full config sync (same fields as ConfigPayload + forwards_hash)
|
|
- **Interval**: 30 seconds
|
|
|
|
### Crypto
|
|
- **Algorithm**: AES-256-GCM
|
|
- **Key Derivation**: SHA256(hwid + salt)
|
|
- **Format**: nonce (12 bytes) + ciphertext
|
|
- **Implementation**: mbedtls (built-in ESP-IDF)
|
|
|
|
## HARDWARE PLATFORM
|
|
|
|
### Target: ESP32 (LW840X)
|
|
- **MCU**: ESP32 Xtensa LX7 dual-core
|
|
- **RAM**: 320KB SRAM
|
|
- **Flash**: 4MB
|
|
- **WiFi**: 802.11 b/g/n
|
|
- **OS**: FreeRTOS via ESP-IDF
|
|
- **Network Stack**: lwIP
|
|
|
|
### Build Toolchain
|
|
- **ESP-IDF**: v5.2+
|
|
- **Compiler**: Xtensa GCC
|
|
- **Build System**: CMake
|
|
- **Debug**: JTAG + OpenOCD
|
|
|
|
## CONVENTIONS
|
|
|
|
### Code Style
|
|
- C99 standard
|
|
- Snake_case for functions and variables
|
|
- UPPER_SNAKE_CASE for macros and constants
|
|
- Doxygen-style comments for public API
|
|
- Error handling: return esp_err_t or NULL on failure
|
|
|
|
### Memory Management
|
|
- Use `heap_caps_malloc(MALLOC_CAP_SPIRAM)` for large buffers
|
|
- Free all allocated memory in error paths
|
|
- No static buffers > 1KB on stack
|
|
|
|
### Network
|
|
- Use `esp_http_client` for HTTP requests
|
|
- Timeout: 10s connect, 30s read
|
|
- Retry: 3 attempts with exponential backoff
|
|
- TLS: Skip verify for now (internal network only)
|
|
|
|
### Storage
|
|
- NVS namespace: "nexusguard"
|
|
- Keys: "device_id", "private_key", "preshared_key", "internal_ip", "server_pub", "endpoint", "dns", "allowed_ips"
|
|
- Max key size: 15 chars (NVS limit)
|
|
|
|
## ANTI-PATTERNS
|
|
|
|
- **NEVER** store WireGuard keys in plaintext on flash (always encrypted via NVS)
|
|
- **NEVER** use `printf` for sensitive data (keys, tokens)
|
|
- **NEVER** hardcode WiFi credentials (use menuconfig or provisioning)
|
|
- **NEVER** block main task for > 100ms (use timers or tasks)
|
|
- **NEVER** use `malloc()` in interrupt context
|
|
|
|
## COMMANDS
|
|
|
|
```bash
|
|
# Build
|
|
idf.py set-target esp32
|
|
idf.py build
|
|
|
|
# Flash & Monitor
|
|
idf.py -p /dev/ttyUSB0 flash monitor
|
|
|
|
# Clean
|
|
idf.py fullclean
|
|
|
|
# Menuconfig
|
|
idf.py menuconfig
|
|
```
|
|
|
|
## DEPENDENCIES
|
|
|
|
- **ESP-IDF**: v5.2+ (framework)
|
|
- **mbedtls**: AES-256-GCM, SHA-256 (built-in)
|
|
- **lwIP**: TCP/IP stack (built-in)
|
|
- **FreeRTOS**: RTOS (built-in)
|
|
- **wireguard-esp32**: WireGuard tunnel library (component)
|
|
|
|
## NOTES
|
|
|
|
- ESP32 uses FreeRTOS, NOT Zephyr RTOS
|
|
- lwIP is the network stack, NOT kernel networking
|
|
- WireGuard runs in userspace via lwIP socket API
|
|
- Config is stored in NVS (flash), not filesystem
|
|
- No gRPC support (too heavy for ESP32) — HTTP only
|
|
- No port forwarding (userspace agent only)
|
|
- Agent version: 1.0.0 (initial release)
|