# Albert Flash V3 — Pré-Requisitos

Sistema de instalação e atualização de Alberts em campo via USB. **O técnico nunca tem firmware plaintext em disco** — o firmware viaja cifrado at-rest no servidor (K1), trafega em RAM Python durante o flash, e é cifrado por hardware (K3) ao gravar na flash do device.

---

## Modelo de segurança em camadas

| Camada | Onde fica | O que protege |
|---|---|---|
| **K1** | Servidor mgtech (em disco) | Cifragem at-rest dos `.bin.k1enc` no AlbertService. Decifrado em RAM do servidor quando algum endpoint serve o firmware. |
| **TLS/HTTPS** | Canal técnico ↔ servidor | Transporte do firmware plaintext (após decifrar K1 no servidor) até a RAM Python do laptop do técnico. Endpoint protegido pelo nginx do AlbertService. |
| **K3** | eFuse BLK1 do ESP32 (per-device) | Cifragem AES-XTS pela hardware engine do ESP32. O stub do esptool grava no flash usando o K3 do device. Atacante com dump da flash sem K3 = bytes opacos. |

Plaintext nunca toca disco do laptop: fica em `bytearray` Python, com chunks zerados conforme enviados ao stub do esptool (~12 segundos de janela em RAM, depois `del + gc.collect()`).

---

## Modelo de uso

| Fase | Onde | Quem | O que faz |
|---|---|---|---|
| **Fábrica** | MGTech (Tacita) | Equipe técnica trusted | Burn eFuses (K3/NYX/HASH no BLK1/BLK3/BLK2). Roda `2_burn_full_v_1_1.bat` + `3_flash_enc_activate_v4.bat`. Grava bootloader + partition table + otadata cifrados. Device vai pro estoque com K3 ativo e encryption ATIVA, mas **sem firmware Albert**. |
| **Bootstrap em campo (cenário B)** | Albert_flash_3 (este pacote) | Técnico de campo | `2_Primeira_Instalacao_Albert.bat` detecta ausência de firmware Albert (whoami não responde) e cai em **bootstrap inline**: pede numSerie + versão alvo, baixa firmware via HTTPS, grava em app0 com esptool encrypted_write. Mesmo fluxo segue automaticamente pra populate NVS. |
| **Primeira Instalação (cenário C)** | Albert_flash_3 | Técnico de campo | `2_Primeira_Instalacao_Albert.bat` detecta Albert rodando (whoami OK) e popula NVS via comando serial `install_from_sd` (lê `/contr.txt` do SD, escreve via Preferences API, K3 cifra ao gravar). |
| **Atualização (campo)** | Albert_flash_3 | Técnico de campo | `3_Atualizacao_Albert.bat`. Baixa firmware plaintext via HTTPS pra RAM, esptool encrypted_write na partição ativa, hard_reset → Albert boota com nova versão. |

A bifurcação entre cenários B e C é **automática** no `2_Primeira_Instalacao_Albert.bat` — operador sempre roda o mesmo script.

---

## Pré-requisitos do PC do técnico

| Item | Por quê | Como obter |
|---|---|---|
| Windows 10/11 | Scripts `.bat` | Padrão |
| Python 3.10+ no PATH | Cliente USB + miniterm monitor | `python --version` deve responder; senão instala do Python.org ou scoop |
| `pyserial` | Comunicação serial USB com Albert | `pip install pyserial` |
| `esptool` 5.x | Lib Python que faz handshake com ROM/stub do ESP32 + grava encrypted via K3 | `pip install --only-binary :all: cryptography` **primeiro** (evita falha de build de Rust), depois `pip install esptool` |
| `cryptography` | Dependência do esptool | Instalado no passo anterior |
| Conectividade HTTPS com `iot.mgconnect.online` | Baixar firmware + registrar target no AlbertService | Acesso direto à internet pública (sem VPN específica) |
| Porta USB-C ao Albert | Comunicação serial + DTR/RTS reset pro esptool | Cabo USB de qualidade (cabos de "só carga" não funcionam) |

Validar instalação Python (uma vez):
```cmd
python -c "import serial, esptool, cryptography; print('OK')"
```

Acesso SSH ao servidor mgtech **não é mais necessário** — o fluxo todo é HTTPS via endpoints do AlbertService.

---

## Pré-requisitos do Albert/ESP32 em campo

### Cenário B — ESP32 saído da Tacita, sem firmware Albert

| Estado | Verificação |
|---|---|
| BLK1 (K3) burnado | `1_Ler_MAC_Albert.bat` ou `espefuse summary` mostra BLK1 com dados ≠ zeros |
| BLK2 (HASH) burnado | Idem |
| BLK3 (NYX) burnado | Idem |
| FLASH_CRYPT_CNT ativa (popcount ímpar) | Confirmado pela Tacita após `3_flash_enc_activate_v4.bat` |
| Bootloader/PT/otadata cifrados gravados | Confirmado pela Tacita |
| Albert **não instalado** | whoami via serial não responde |

Operador precisa em mãos:
- **numSerie** físico do device (label/QR/etiqueta) — vai bater contra o BLK2 (hash de NYX+MAC+numSerie)
- **Versão alvo** do firmware (ex: `v1.8.18.bin`) — `.bin.k1enc` precisa existir no servidor

### Cenário C — Albert já instalado (Primeira Instalação ou Atualização)

| Estado | Verificação |
|---|---|
| Tudo do cenário B | Idem |
| Albert pré-instalado, Sicherung 1 OK no boot | Boot mostra `Sicherung 1` + numSerie correto |
| Firmware ≥ v1.8.17 | whoami inclui campo `running=app0` ou `running=app1` (usado pelo `3_Atualizacao` pra escolher offset) |
| Firmware ≥ v1.8.14 | comando `install_from_sd` disponível |

Se algum pré-requisito falhar, o device **NÃO** passou pela fábrica corretamente. Devolver pra MGTech.

---

## Pré-requisitos do SD (Primeira Instalação)

O SD físico do Albert precisa ter, na raiz, um arquivo `contr.txt` com 26 campos CSV no formato v1.8.x:

```
<canHz>,<comando>,<partidasTotal>,<hab64hex>,<dl64hex>,<hwv>,<swv>,<numSerie>,<sigla>,<placa>,<marca>,<modelo>,<geral>,<modAlbert>,<EDGEV1>,<contrCRC>,<flagWiFi>,<indArq>,<despArq>,<despTot>,<despHist>,<kbat>,<dornro>,<tgToken>,<tgChatId>,<blockIdx>
```

Críticos:
- `canHz`: 250 ou 500
- `numSerie` (field 7): identifica o device fisicamente (5 chars, ex: `20LBE`). **Precisa bater com o BLK2 do device**, senão `Sicherung 0` no boot pós-instalação.
- `EDGEV1` (field 14): payload no formato `EDGEV1|1|<60 hex chars>`
- `contrCRC` (field 15): pode ser vazio
- `tgToken` (field 23): pode ser URL ou string vazia

O conteúdo é gerado pelo Albert admin e baixado pelo técnico autorizado. **Não construir manualmente.**

Validar arquivo no SD antes de inserir no Albert (deve ser ASCII puro, sem BOM UTF-8 no início):
```powershell
Format-Hex C:\caminho\para\contr.txt -Count 16
```

---

## Pré-requisitos do servidor

- `iot.mgconnect.online` acessível via HTTPS
- Endpoints em uso pelos `.bat`:
  - `POST /service/api/ota_target/device/<NS>` — registra/desregistra target
  - `GET /service/api/usb_update_bundle/<NS>` — devolve JSON com `plaintext_url`, `meta_url`, `target_version`
  - `GET /service/api/ota_metadata/<NS>` — devolve `sha256_plain`, `size_plain`
  - `GET /service/api/plaintext_firmware/<NS>/<version>` — entrega `.bin` plaintext via streaming (decifrado de `.bin.k1enc` em RAM no servidor)
- Firmware alvo (`v<X.Y.Z>.bin.k1enc`) precisa existir em `/home/mgtech/albert_service/firmware/<modelo_dir>/` antes do operador iniciar o flash. Quem coloca lá é o admin do AlbertService.

---

## Fluxo recomendado pelo técnico

### Primeira vez no device (cenário B ou C)

1. Cadastre o veículo no Albert admin → gera `/contr.txt` v1.8.x.
2. Baixe `/contr.txt` e grave no SD físico (ASCII, sem BOM).
3. Insira o SD no Albert (verifique numSerie).
4. Conecte USB do Albert ao PC.
5. Rode `2_Primeira_Instalacao_Albert.bat`.
6. **Bifurcação automática**:
   - Se whoami responder → vai direto pro `install_from_sd`.
   - Se whoami não responder → bootstrap inline (pede numSerie + versão alvo, flasha via esptool, valida boot, segue pro `install_from_sd`).
7. Ao final, monitor abre — confirma `Sicherung 1` + `Albert N - num serie XXXXX` + `EDGEV1 aplicado em edgeActive`.
8. Device pronto pra instalação física no veículo.

### Atualizar firmware num device já operacional

1. Conecte USB do Albert ao PC.
2. Rode `3_Atualizacao_Albert.bat`.
3. Script lê `whoami` → identifica versão atual + partição ativa.
4. Operador entra versão alvo (ex: `v1.8.19.bin`).
5. Script registra target, baixa plaintext pra RAM, grava na partição ativa via esptool encrypted_write, hard_reset, desregistra target.
6. Monitor abre — confirma nova versão + `Sicherung 1`.

NVS (`sigla`, `placa`, `hab`, `DL`, `EDGEV1`) preservada na atualização — sobrescreve só o app, não toca outras partições.

---

## Diagnóstico rápido

| Sintoma | Causa provável | Ação |
|---|---|---|
| `whoami nao respondeu` | Outra janela serial aberta, ou Albert em estado quirky após esptool falho anterior, ou ESP32 sem firmware Albert | Fechar Arduino IDE / miniterm; se persistir, é cenário bootstrap (deixe o `.bat` cair no fluxo automático) |
| `Failed to connect to Espressif device: No serial data received` | Esptool não consegue colocar ESP32 em download mode | Verificar cabo USB (alguns só carregam); driver CP210x/CH340/FTDI; tentar de novo (script tem auto-reset+retry) |
| `firmware_not_found` no servidor | `.bin.k1enc` da versão pedida não está em `/home/mgtech/albert_service/firmware/<modelo_dir>/` | Pedir ao admin AlbertService pra subir a versão |
| Boot mostra `Sicherung 0` | numSerie do contr.txt diverge do BLK2 do device | Conferir numSerie físico do device e refazer contr.txt no admin |
| Boot mostra `EDGEV1 invalido` | EDGEV1 mal formado no contr.txt | Gerar novo contr.txt do admin (não editar manualmente) |
| Após USB update, servidor oferta CMD12 redundante | Ciclo CMD12 não fechado antes do Albert mandar CMD1 novo | O `.bat` já desregistra target ao final — se ainda assim aparecer, é janela curta inócua (Albert pega CMD12, baixa via HTTPS, grava na partição inativa, sem dano) |

---

## Estrutura dos arquivos

```
Albert_flash_3/
├── 0_Pre_Requisitos.md              ← este arquivo
├── 1_Ler_MAC_Albert.bat             ← lê MAC do ESP32 via esptool standalone
├── 2_Primeira_Instalacao_Albert.bat ← bootstrap inline + install_from_sd
├── 3_Atualizacao_Albert.bat         ← OTA USB via esptool stub + plaintext HTTPS
├── 4_Monitor_Serial_Albert.bat      ← abre miniterm em 115200
├── esptool.exe                      ← standalone (usado pelo 1_Ler_MAC)
├── bin/                             ← artefatos temporários (ota_target_resp.json etc); pode apagar
└── tools/
    ├── albert_serial.py             ← helpers whoami / install-from-sd / detect-port / reset
    └── usb_esptool_push.py          ← cliente esptool lib Python; modos normal e --bootstrap
```
