Ir al contenido

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).

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.

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.

JSON con al menos:

{
"device_id": "",
"commercialName": "",
"manufacturerName": "",
"firmwareVersion": "",
"ethernet_connected": false
}
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.

  • 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.

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 === 0 resetea el ensamblado.
  • index debe ser secuencial; total constante en la sesión.
  • Al completar todos los chunks, el firmware parsea el JSON y aplica la 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 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.

  1. Firmware guarda credenciales en NVS.
  2. Conecta STA/Ethernet sin reiniciar.
  3. Notifica connecting_wifiregisteringPOST /devices/register.
  4. Con registro OK y red OK → phase: registered.
  5. 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.

  1. Scan por prefijo AlertIA.
  2. Conectar, emparejar, negociar MTU 247.
  3. Leer Info; suscribirse a notify de Status.
  4. Fragmentar el JSON y escribir Provision solo con enlace cifrado.
  5. Esperar registered (o error) y confirmar en nube si aplica (GET /devices/exists/... en la app oficial).

Detalle de uso diario: App de campo.