Skip to content

leonobitech/hardware

Repository files navigation

ESP32-C3 IoT Firmware - Leonobitech

CI

Firmware seguro para dispositivos IoT basado en ESP32-C3, escrito en Rust con ESP-IDF.

Arquitectura

┌─────────────────────────────────────────────────────────────────┐
│                         ESP32-C3                                │
├─────────────────────────────────────────────────────────────────┤
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────────┐  │
│  │   WiFi      │  │  Secure     │  │    Device Client        │  │
│  │  Module     │  │  Storage    │  │   (HTTP Polling)        │  │
│  │             │  │   (NVS)     │  │                         │  │
│  └──────┬──────┘  └──────┬──────┘  └───────────┬─────────────┘  │
│         │                │                     │                │
│         └────────────────┼─────────────────────┘                │
│                          │                                      │
│  ┌───────────────────────┴───────────────────────────────────┐  │
│  │                    Main Loop                              │  │
│  │  - Poll commands cada 5s                                  │  │
│  │  - Enviar telemetria cada 60s                             │  │
│  │  - Ejecutar comandos recibidos                            │  │
│  └───────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────┘
                              │
                              │ HTTPS
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                   core.leonobitech.com                          │
├─────────────────────────────────────────────────────────────────┤
│  POST /api/devices/register          - Registrar dispositivo    │
│  POST /api/devices/:id/telemetry     - Enviar telemetria        │
│  GET  /api/devices/:id/commands/pending - Obtener comandos      │
│  POST /api/devices/:id/commands/:id/ack - Confirmar comando     │
│  POST /api/devices/:id/status        - Enviar estado            │
└─────────────────────────────────────────────────────────────────┘

Flujo de Operacion

1. Primer Arranque (Provisioning)

┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│   ESP32-C3   │     │   Usuario    │     │   Backend    │
│  (Sin config)│     │  (Movil/PC)  │     │              │
└──────┬───────┘     └──────┬───────┘     └──────┬───────┘
       │                    │                    │
       │ Inicia SoftAP      │                    │
       │ "Leonobitech-Setup"│                    │
       │ Pass: "setup1234"  │                    │
       │◄───────────────────┤                    │
       │    Conecta WiFi    │                    │
       │                    │                    │
       │◄───────────────────┤                    │
       │  GET 192.168.4.1   │                    │
       │                    │                    │
       │────────────────────►                    │
       │   Portal HTML      │                    │
       │                    │                    │
       │◄───────────────────┤                    │
       │  POST /configure   │                    │
       │  {ssid, password,  │                    │
       │   deviceId, apiKey}│                    │
       │                    │                    │
       │ Guarda en NVS      │                    │
       │ (encriptado)       │                    │
       │                    │                    │
       │ ══════ RESTART ════│                    │
       │                    │                    │

2. Operacion Normal

┌──────────────┐                              ┌──────────────┐
│   ESP32-C3   │                              │   Backend    │
└──────┬───────┘                              └──────┬───────┘
       │                                             │
       │ Conecta WiFi (credenciales NVS)             │
       │                                             │
       │─────── POST /register ──────────────────────►
       │        {device_id, firmware_version}        │
       │◄────────────────────────────────────────────│
       │        {status: "success"}                  │
       │                                             │
       │                                             │
       │ ══════════ LOOP PRINCIPAL ══════════        │
       │                                             │
       │ [Cada 5s]                                   │
       │─────── GET /commands/pending ───────────────►
       │◄────────────────────────────────────────────│
       │        {commands: [...]}                    │
       │                                             │
       │ [Si hay comando]                            │
       │        Ejecuta comando                      │
       │─────── POST /commands/:id/ack ──────────────►
       │        {success: true, message: "..."}      │
       │                                             │
       │ [Cada 60s]                                  │
       │─────── POST /telemetry ─────────────────────►
       │        {free_heap, wifi_rssi, uptime}       │
       │                                             │

Estructura del Proyecto

hardware/
├── .cargo/
│   └── config.toml          # Configuracion de Cargo para ESP32
├── .github/
│   └── workflows/
│       └── rust_ci.yml      # CI/CD con GitHub Actions
├── src/
│   ├── main.rs              # Entry point y loop principal
│   ├── wifi.rs              # Conexion WiFi WPA2/WPA3
│   ├── provisioning.rs      # Portal SoftAP para configuracion
│   ├── secure_storage.rs    # NVS encriptado para credenciales
│   ├── device_client.rs     # Cliente HTTP para backend
│   └── http_client.rs       # Cliente HTTP generico (legacy)
├── Cargo.toml               # Dependencias Rust
├── build.rs                 # Script de build
├── sdkconfig.defaults       # Configuracion ESP-IDF
├── rust-toolchain.toml      # Version de Rust (nightly)
└── README.md

Comandos Soportados

Comando Descripcion Parametros
get_status Solicita estado completo del dispositivo -
led_on Enciende LED -
led_off Apaga LED -
set_brightness Ajusta brillo {level: 0-100}
restart Reinicia dispositivo -
factory_reset Borra credenciales y reinicia -

Seguridad

Modos de Build

Modo Config Secure Boot Flash Encryption Uso
Development sdkconfig.defaults No No CI, desarrollo local
Production sdkconfig.defaults.production Si Si Dispositivos finales

Secure Boot v2 (Solo Produccion)

  • Verifica firma del firmware antes de ejecutar
  • Previene ejecucion de firmware no autorizado
  • Generar clave: espsecure.py generate_signing_key --version 2 secure_boot_signing_key.pem
  • IMPORTANTE: secure_boot_signing_key.pem NO debe commitearse

Flash Encryption (Solo Produccion)

  • Encripta contenido de la flash
  • Protege firmware y datos almacenados
  • Habilitado solo con sdkconfig.defaults.production

NVS Encryption

  • Credenciales WiFi encriptadas en NVS
  • API Key hasheada antes de almacenar
  • Zeroization de credenciales en memoria despues de uso

Comunicacion

  • Solo HTTPS con certificados de CA bundle
  • Headers x-device-id y x-api-key para autenticacion
  • API Key hasheada con HMAC-SHA512 en backend

Desarrollo

Requisitos

# Instalar Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Instalar toolchain ESP32
cargo install espup
espup install

# Configurar variables de entorno
. $HOME/export-esp.sh

Build

# Build debug (development)
cargo build

# Build release (development/CI - sin Secure Boot)
cargo build --release

# Build release PRODUCTION (con Secure Boot)
# Requiere: secure_boot_signing_key.pem
SDKCONFIG_DEFAULTS=sdkconfig.defaults.production cargo build --release

# Flash al dispositivo
cargo run --release

Configuracion

Editar sdkconfig.defaults para ajustar:

  • Tamano de particiones
  • Configuracion WiFi
  • Opciones de seguridad

Telemetria

Datos enviados cada 60 segundos:

{
  "device_id": "esp32-001",
  "free_heap": 245760,
  "wifi_rssi": -52,
  "uptime_secs": 3600,
  "sensors": null
}

Integracion con Backend

El firmware se comunica con core.leonobitech.com:

Endpoint Metodo Descripcion
/api/devices/register POST Registro inicial
/api/devices/:id/telemetry POST Envio de telemetria
/api/devices/:id/commands/pending GET Obtener comandos
/api/devices/:id/commands/:cmdId/ack POST Confirmar ejecucion
/api/devices/:id/status POST Enviar estado completo

Repositorios Relacionados

Licencia

Propietario - Leonobitech

About

ESP32-C3 IoT Firmware - Rust/ESP-IDF with Secure Boot

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages