Schermate della scheda
Prima accensione, accesso, PIN di blocco, impostazioni: come sono fatte e come si collegano all'abbinamento.
Prima accensione, blocco con il PIN e impostazioni: schermate intere sopra la shell, in ui/src/
(onboarding.c, lock.c, settings.c, i pezzi comuni in screens.c). Uno screenshot di ognuna, in
tema chiaro e scuro, è in shots/schermate.
Prima accensione
Si apre da sola sulla scheda finché non è collegata (jz_onboarding_boot in firmware/main/main.c),
e da Impostazioni › Collegamento › Cambia collegamento. "Più tardi" la rimanda alla prossima accensione.
Se mentre è aperta il cervello si presenta dal cavo (HOST), salta da sola alla conferma "Abbinare a
<nome>?": così anche una scheda già usata via cavo prima dell'aggiornamento si sistema con un tocco.
"Annulla" torna alla scelta, e la conferma non si ripropone finché il cavo resta attaccato.
| Strada | Passi |
|---|---|
| Wi-Fi | reti (scansione) → password con la tastiera → collegamento (errori: password, rete che non risponde, niente indirizzo; una rete aperta non torna mai alla tastiera) → "Come la usi?" |
| Bluetooth | QR e codice per l'app ESP BLE Provisioning (wifi_provisioning, sicurezza 2: il codice a 6 cifre è la prova di possesso; vale 2 minuti e 5 tentativi, poi il Bluetooth si ferma e "Nuovo codice" riparte) → "Come la usi?" |
| Cavo | "Collega il cavo USB" → il cervello si presenta con HOST → "Abbinare a <nome>?" → fatto |
"Come la usi?": con il cervello sul computer (i cervelli trovati con mDNS, _jzdesk._tcp; scelto
uno, il codice a 6 cifre da scrivere nel configuratore) oppure da sola (codice e QR verso
JZ_PORTAL_URL/attiva?codice=…; relay e portale arrivano dalla build, vedi .env.example alla radice).
Il modo scelto si salva in jz.collegamento (jz_link_mode_t).
Il confine con l'abbinamento
L'abbinamento crittografico (CPace, canale cifrato) è di packages/pairing e ui/src/pair*.c.
ui/include/jz/onboarding.h dice chi chiama chi:
- la prima accensione chiama
jz_pairing_start_net,jz_pairing_start_cable,jz_pairing_start_portal,jz_pairing_cancel; le impostazionijz_pairing_listejz_pairing_revoke; - il modulo risponde con
jz_onboarding_show_code,jz_onboarding_ask_confirm,jz_onboarding_paired,jz_onboarding_pair_failed,jz_onboarding_activated,jz_onboarding_show_activation_lock.
Il collegamento sta in ui/src/pairing_ui.c: le jz_pairing_* usano lo strato vero (jz/pair.h) e i
suoi callback (codice, domanda via cavo, esiti) aprono le schermate. Con un cervello scelto in rete la
scheda apre il collegamento Wi-Fi (jz_platform_brain_connect) e mostra il codice; sul cavo è il
cervello a chiedere e la scheda domanda conferma. Il portale (standalone) è ancora provvisorio: il codice
si mostra, ma finché non c'è il relay non arriva a nessuno.
PIN di blocco
Da 4 a 8 cifre (ui/src/pin.c, la parte pura, con i test in ui/tests; ui/src/lock.c, la schermata).
- Impronta Argon2id (Monocypher), 1 MiB e 3 passaggi, sale casuale di 16 byte:
jz.pin. Un record con parametri fuori dai limiti (memoria da 8 KiB a 4 MiB, da 1 a 10 passaggi) non vale. - Dopo 5 errori di fila: 30 s, 1 min, 5 min, poi 15 min a ogni errore. L'attesa si conta col tempo
monotono e si salva ogni 5 s in
jz.pin_try: un riavvio non la azzera, spostare l'orologio non serve. L'errore si salva prima di calcolare l'impronta (se il PIN è giusto si azzera dopo): staccare la corrente a metà verifica non lo cancella. Sejz.pin_trymanca con un PIN impostato, il prossimo errore fa già aspettare. jz.pin,jz.pin_trye le altre chiavijz.*sono di sistema: stanno nello stesso archivio dei widget ma conSTOREviaggiano solo le chiavi dei widget (<id>.<nome>,ui/src/sync.c, provato inui/tests/test_sync.c). Un host qualunque sul cavo non legge l'impronta e non azzera gli errori.- Si blocca all'accensione, dopo l'inattività scelta (
jz.blocco_auto: mai, 1, 5, 15 minuti), quando PWR spegne lo schermo e a mano. - Bloccata mostra solo l'ora: niente widget, niente tocchi verso la shell, niente scorciatoie né scene. Passano PWR (schermo e spegnimento) e BOOT tenuto (muto ovunque).
jz_lock_reset()toglie il PIN: lo chiameranno il cervello abbinato e il portale (da collegare). Finché non lo fanno, "PIN dimenticato?" offre solo il ripristino di fabbrica e non promette altro.
Impostazioni
Dall'ingranaggio nella testata del mission control. Collegamento (stato, Wi-Fi e Bluetooth accesi o spenti, dimentica la rete, cambia collegamento), Sicurezza (PIN, blocco automatico, blocca adesso), Cervelli abbinati (con revoca), Informazioni (id, firmware, protocollo, cervello, rete), Ripristino di fabbrica (due conferme; cancella l'NVS e riavvia, il blocco attivazione resta).
Piattaforma
Le funzioni nuove sono in fondo a ui/include/jz/platform.h (sezione "Collegamento"):
Scheda (firmware/main/platform_net.c) | Simulatore (sim/platform_sim.c) | |
|---|---|---|
| Wi-Fi | esp_wifi, rete salvata in NVS solo se il collegamento riesce; con una rete salvata riprova da sola dopo 5 s, 30 s, 2 min, poi ogni 5 min; la scansione ferma un collegamento in corso e poi lo riprende | 8 reti d'esempio, ~2 s di scansione, ~3 s di collegamento, stessi nuovi tentativi |
| Bluetooth | wifi_provisioning su NimBLE, sicurezza 2 (SRP6a calcolato sulla scheda dal codice), nome PROV_jz-desk-xxxx; dopo 5 codici sbagliati si ferma; la copia della rete che lascia nell'NVS del driver si svuota | il "telefono" manda la rete dopo 12 s; con JZ_SIM_BLE_WRONG=n prima sbaglia il codice n volte |
| Cervelli | componente espressif/mdns, _jzdesk._tcp | uno: "MacBook Air di Jacopo" |
| Ripristino | nvs_flash_erase e riavvio | svuota ~/.jz-desk-sim (o il localStorage) tranne l'id |
| Numeri casuali | RNG hardware (con la radio spenta, la fonte di rumore dell'ADC) | getentropy |
Nel simulatore: JZ_SIM_WIFI_PASS=… accetta solo quella password; le reti sotto -82 dBm non rispondono.
Test automatici dei moduli puri (pin.c, e sync.c con archivio e invio in memoria):
cmake -G Ninja -B ui/tests/build ui/tests && ninja -C ui/tests/build && ctest --test-dir ui/tests/buildProvarle nel simulatore
./sim/build/jz_sim --first-boot # la prima accensione
./sim/build/jz_sim --locked # bloccata (senza PIN salvato: 1234, solo in memoria)
./sim/build/jz_sim --screen impostazioni # una schermata per nome
./sim/build/jz_sim --screens docs/shots/schermate # tutte, tema scuro
./sim/build/jz_sim --screens docs/shots/schermate --light # tutte, tema chiaroNel simulatore web: ?first-boot e ?locked nell'indirizzo. --screens usa un archivio vuoto in una
cartella temporanea, come una scheda nuova, e non tocca quello del simulatore.
Da sapere
- Il cervello deve annunciarsi via mDNS come
_jzdesk._tcp(nome dell'istanza = nome del cervello): finché non lo fa, la scheda in rete non lo trova. - La password del Wi-Fi e l'impronta del PIN stanno nell'NVS in chiaro finché non arriva la memoria cifrata (NVS encryption e flash encryption, nel piano).
- Wi-Fi e NimBLE allocano in PSRAM dove possono (
sdkconfig.defaults): da verificare sulla scheda vera. - Il nome Bluetooth comincia con
PROV_perché con le impostazioni predefinite l'app ESP BLE Provisioning elenca solo quei nomi; dal QR la trova per nome intero. Da provare con l'app vera, come il conteggio dei codici sbagliati (eventoPROTOCOMM_SECURITY_SESSION_CREDENTIALS_MISMATCH) e i nuovi tentativi del Wi-Fi con un router che si riavvia.