Skip to content

leonobitech/hardware

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

34 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

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