Michael Sauer 2e90b8fd06 fix: kleinere Netzwerk-Härtungen
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.
2026-09-11 23:52:03 +02:00
2026-09-11 23:52:03 +02:00
2026-09-11 23:52:03 +02:00
2026-09-11 23:52:03 +02:00
2026-09-11 12:19:33 +02:00

ninlight

Lokale Firmware für die alten Klyqa-Lampen mit WinnerMicro W600 (E27/E14/GU10 RGB+CW, E27/E14/GU10 CW, G95 Vintage) und das W600-EVK.

Voraussetzungen

  • Docker Desktop (primärer Build-Pfad, erste Ausführung baut das Image ninlight-build)
  • CMake ≥ 3.20, Ninja, host C compiler (für Host-Tests)
  • uv (für die serielle Konsole)
  • ARM GNU Toolchain mit newlib: brew install --cask gcc-arm-embedded (nur Fallback für nativen Build)

Bauen

Docker (empfohlen – kein lokaler ARM-Compiler nötig):

tools/docker.sh cmake -S . -B build/evk -G Ninja -DCMAKE_TOOLCHAIN_FILE=cmake/arm-none-eabi.cmake -DNINLIGHT_DEVICE=evk
tools/docker.sh cmake --build build/evk
tools/docker.sh tools/build_all.sh              # alle 8 Geräte

Für die tägliche Entwicklung: nur das Gerät bauen, das du verwendest (z.B. tools/docker.sh cmake --build build/evk). Der emulierte Docker-Build ist langsam — build_all.sh ist nur für Releases gedacht.

Native Builds (mit lokal installierter ARM-Toolchain):

cmake -S . -B build/evk -G Ninja -DCMAKE_TOOLCHAIN_FILE=cmake/arm-none-eabi.cmake -DNINLIGHT_DEVICE=evk
cmake --build build/evk

Geräte: evk, e27_rgb, e14_rgb, gu10_rgb, e27_cw, e14_cw, gu10_cw, g95_cw.

Lokale Einstellungen (Token, später WLAN): config.local.cmake.example → config.local.cmake.

Tests

Host-basierte Unit-Tests (laufen nativ auf dem Mac):

tools/test_host.sh

Flashen und Konsole

Verfügbare Ports anzeigen:

build/host-tools/wm_tool -l

Firmware flashen (Standard: App-Image):

tools/flash.sh <device> <port>

Das Skript druckt Bitte bei "please manually reset the device" die Reset-Taste drücken. — wenn wm_tool diese Nachricht zeigt, musst du die Reset-Taste am EVK drücken (Baud 460800). Für blank/erased Chips: tools/flash.sh <device> <port> full (flasht stattdessen das Vollbild mit secboot, auf Hardware noch ungetestet).

Serielle Konsole (115200 8N1, lokales Echo):

tools/monitor.sh /dev/cu.<port>

Verfügbare Befehle in der Konsole: help.

Netzwerk & REST

  • WLAN fest einbauen: NINLIGHT_WIFI_SSID / NINLIGHT_WIFI_PASSWORD in config.local.cmake (gespeicherte Einstellungen haben Vorrang).

  • Ohne WLAN-Daten (oder nach Werksreset) öffnet die Lampe den AP ninlight-<mac4> (Passwort NINLIGHT_AP_PASSWORD, Default ninlight) und pulsiert warmweiß. Onboarding:

    curl -X PUT http://192.168.4.1:3333/api/v1/system/settings \
         -d '{"type":"wifi","ssid":"MeinWLAN","password":"geheim123"}'
    curl http://192.168.4.1:3333/api/v1/system/info    # wifi.sta_ip / wifi.error
    

    Nach Erfolg schließt der AP nach 60 s. Ohne Verbindung für 5 min öffnet die Lampe den AP zusätzlich (Fallback).

  • REST auf Port 3333, Präfix /api/v1: GET|POST device/state, GET system/info, GET|PUT system/settings und PUT system/command (beide mit Header Authorization: <token>, Default-Token aabbccddeeff0011223344).

  • Beispiel: curl -X POST http://ninlight-681f.local:3333/api/v1/device/state -d '{"on":true,"brightness":40,"color_temp":2700}'

  • Suchen: dns-sd -B _ninlight._tcp (macOS), Details dns-sd -L ninlight-681f _ninlight._tcp.

  • Bruno: bruno/ninlight.yml importieren, Environment „EVK (mDNS)" bzw. „Onboarding-AP" wählen.

  • Konsole: net zeigt Modus, SSID, IP, RSSI und den letzten Onboarding-Fehler.

Werksreset

Gerät 5× hintereinander einschalten, jeweils kürzer als 5 Sekunden.

Hardwaretests

Manuelle Checkliste: docs/hardware-checklist.md.

S
Description
No description provided
Readme
3.7 MiB
2026-10-02 21:43:38 +02:00
Languages
C 84%
Python 5.8%
Shell 5.2%
C# 4.2%
CMake 0.4%
Other 0.2%