feat: add ESP32 embedded agent + namespace VRF reference docs + update android-agent submodule
- 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
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
# 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)
|
||||
Reference in New Issue
Block a user