M2: WLAN-Passwort muss leer (offenes Netz) oder 8..64 Zeichen lang sein
(400 "invalid password" bei 1..7 Zeichen). CMake prüft NINLIGHT_WIFI_PASSWORD
ebenso (0 oder 8..63 Zeichen) und der Zeichen-Blacklist-Check bekommt `;`
dazu.
M4: Ein Authorization-Wert, der länger als NL_TOKEN_LEN-1 (64) ist, wird
von nl_http_parse() nicht mehr stillschweigend abgeschnitten, sondern setzt
`auth_too_long` in nl_http_request_t; nl_api_handle() behandelt eine solche
Anfrage als unauthentifiziert (außer bei offenem Zugriff), damit ein
abgeschnittener Wert nie zufällig auf ein kürzeres Token passt.
M5: get_int() prüfte die (long)-Cast-Gleichheit vor dem Bereichscheck -
bei sehr großen oder NaN-Werten ist der Cast von double nach long
undefiniertes Verhalten. Bereichs- und NaN-Check laufen jetzt vor dem Cast.
T1: sdk/Platform/Drivers/internalflash/wm_internal_fls.c: tls_fls_init()
ignorierte den Rückgabewert von tls_os_sem_create(&s_fls2_lock, 1) - jetzt
eine TLS_DBGPRT_ERR-Meldung, falls das fehlschlägt (dokumentiert in
sdk/PATCHES.md).
Tests: test_api.c (Passwortlängen, auth_too_long, 1e300-Brightness),
test_http.c (auth_too_long wird gesetzt). Für M5 zeigt der Host-Test kein
sichtbares RED, weil der (double)->(long)-Cast auf dieser Plattform/diesem
Compiler keinen Crash auslöst (implementation-defined statt UB-Crash) - der
Fix wird trotzdem angewendet, da er auf dem Zielcompiler (arm-none-eabi 4.9)
nicht garantiert sicher ist.
- vApplicationIdleHook() füttert den Watchdog nicht mehr (sdk/Platform/Sys/wm_main.c,
dokumentiert als Patch 4 in sdk/PATCHES.md). Bisher fütterte der Idle-Task den
Watchdog bei jedem Leerlauf, auch wenn ein Task deadlockt (z.B. nl_app_lock() hält
und nie freigibt) - der Watchdog konnte so nie greifen.
- Neues Konsolenkommando `wdtest` (Parser in nl_console_cmd.c/.h, Ausführung in
nl_console.c, Host-Test in test_console_cmd.c): hält nl_app_lock() für immer, damit
light_task und app_task blockieren und nur der Watchdog-Reset den Chip retten kann.
- nl_app_request_factory_reset() (nl_app.h) setzt nur ein volatile Flag; app_task
prüft es in der Hauptschleife und ruft nl_app_factory_reset() selbst auf, da nur der
App-Task die Flash-Stores besitzt. Das Konsolenkommando `factory` ruft jetzt diese
Funktion statt nl_app_factory_reset() direkt aufzurufen, um die Race mit
nl_state_log_append()/nl_resetcnt_clear() im App-Task zu vermeiden. Der Bootpfad
(Bootzähler >= 5) ruft weiterhin direkt nl_app_factory_reset() auf.
- nl_resetcnt_clear() wird nur noch als erledigt markiert, wenn es 0 zurückgibt, damit
ein fehlgeschlagener Clear in der nächsten Schleifeniteration erneut versucht wird.