Provisión BLE
La provisión local oficial es Bluetooth Low Energy. El firmware expone un servicio GATT dedicado; la app de campo escribe el JSON de alta en chunks cifrados y sigue el progreso por notificaciones de Status.
El camino HTTP sobre Access Point quedó fuera de vigencia (ver changelog).
Advertising
Sección titulada «Advertising»| Campo | Valor |
|---|---|
| Prefijo de nombre (scan app) | AlertIA |
| Nombre en advertising | AlertIA-<sufijo> (serial NVS u otros; truncado ~18 chars) |
| Scan response | SSID lógico del equipo (p. ej. AlertIA-MiDevice-<serial>) |
La app filtra por prefijo AlertIA y muestra los dispositivos cercanos.
Servicio GATT
Sección titulada «Servicio GATT»UUID del servicio (solo provisión; no reutilizar para OTA):
6e400001-a1e7-4a00-b1e7-a1e711000035
| Característica | UUID | Propiedades | Uso |
|---|---|---|---|
| Info | 6e400002-a1e7-4a00-b1e7-a1e711000035 |
READ | Identidad del equipo |
| Status | 6e400003-a1e7-4a00-b1e7-a1e711000035 |
READ + NOTIFY | Fase de alta y red |
| Provision | 6e400004-a1e7-4a00-b1e7-a1e711000035 |
WRITE (cifrado) | JSON de provisión fragmentado |
Longitud máxima por valor de característica: 512 bytes.
Info (lectura)
Sección titulada «Info (lectura)»JSON con al menos:
{ "device_id": "…", "commercialName": "…", "manufacturerName": "…", "firmwareVersion": "…", "ethernet_connected": false}Status (lectura + notify)
Sección titulada «Status (lectura + notify)»| Campo | Descripción |
|---|---|
phase |
idle | connecting_wifi | registering | registered | error |
registered |
Si ya hay registro en nube |
network_connected / wifi_connected / ethernet_connected |
Estado de red |
connection_type |
wifi | ethernet | none |
ip_address |
IP actual si hay red |
message |
Texto humano (errores, progreso) |
device_id |
Identificador local / DID cuando exista |
Timeout típico de UI hasta fase terminal: ~120 s.
Seguridad del enlace
Sección titulada «Seguridad del enlace»- Bonding Just Works + LE Secure Connections.
- Sin PIN/OLED (
NO_INPUT_OUTPUT). - La característica Provision rechaza writes si el enlace no está cifrado.
- En Android conviene
createBond()antes del write; el primer intento puede disparar el diálogo de emparejamiento.
Fragmentación del JSON (Provision)
Sección titulada «Fragmentación del JSON (Provision)»Formato de cada write:
[u8 index][u8 total][payload UTF-8]| Límite | Valor |
|---|---|
| JSON total | ≤ 4096 bytes |
| Chunks | ≤ 64 |
| MTU objetivo | 247 (payload útil ≈ MTU − 3 ATT − 2 header) |
| Gap entre writes (app) | ~30 ms |
index === 0resetea el ensamblado.indexdebe ser secuencial;totalconstante en la sesión.- Al completar todos los chunks, el firmware parsea el JSON y aplica la provisión.
Payload JSON de provisión
Sección titulada «Payload JSON de provisión»{ "wifi_ssid": "MiRed", "wifi_pass": "********", "user_secret": "<JWT del técnico>", "customerId": "<uuid del cliente>", "use_eth": false, "lat": "-34.60", "lon": "-58.38", "backend": { "baseUrl": "https://api.ejemplo.alertia" }}| Campo | Obligatorio en alta nueva | Notas |
|---|---|---|
user_secret |
Sí | JWT del técnico autenticado |
customerId |
Sí (alta) | Organización destino |
wifi_ssid / wifi_pass |
Sí, salvo Ethernet | Vacío + use_eth: true o cable detectado |
use_eth |
No | Preferir LAN |
lat / lon |
No | Strings |
backend.baseUrl |
Recomendado | Base URL de la Core API |
- Alta nueva: secret + (WiFi o Ethernet).
- Ya registrado: suele usarse para actualizar solo red.
El escaneo de redes WiFi lo hace el teléfono, no el ESP32.
Flujo post-escritura
Sección titulada «Flujo post-escritura»- Firmware guarda credenciales en NVS.
- Conecta STA/Ethernet sin reiniciar.
- Notifica
connecting_wifi→registering→POST /devices/register. - Con registro OK y red OK →
phase: registered. - Apaga BLE (
stopBleProvision) y continúa MQTT / ping / telemetría.
Si no hay credenciales, falla la red o el registro, el BLE puede permanecer o reabrirse según la política del firmware.
Implementar un cliente compatible
Sección titulada «Implementar un cliente compatible»- Scan por prefijo
AlertIA. - Conectar, emparejar, negociar MTU 247.
- Leer Info; suscribirse a notify de Status.
- Fragmentar el JSON y escribir Provision solo con enlace cifrado.
- Esperar
registered(oerror) y confirmar en nube si aplica (GET /devices/exists/...en la app oficial).
Detalle de uso diario: App de campo.