From e4e29aa5dd35bd75038db953af09de58d3378f36 Mon Sep 17 00:00:00 2001 From: samuelzielke Date: Thu, 22 Oct 2026 10:57:05 +0200 Subject: [PATCH] docs: M4 implemented, intercom ports, phone test steps Co-Authored-By: Claude Opus 5.5 --- docs/04-fahrplan.md | 16 +++++++++++++--- docs/05-testplan-hardware.md | 12 ++++++++++-- docs/06-netzwerk.md | 11 +++++++++++ 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/docs/04-fahrplan.md b/docs/04-fahrplan.md index 0139ecf..297d144 100644 --- a/docs/04-fahrplan.md +++ b/docs/04-fahrplan.md @@ -48,9 +48,10 @@ Jeder Meilenstein endet mit einem Abnahmetest. Erst wenn er bestanden ist, begin - **Abnahme:** Beide Macs neu starten – die Szene „OP-Live“ stellt sich ohne Eingriff wieder her. ## M4 – Intercom Stufe 1 -- [ ] Web-Server nur auf der Klinik-Schnittstelle -- [ ] QR-Code mit Adresse in der App -- [ ] Handy-Seite: Name/Rolle, Talkback hören, PGM-Vorschau (WebRTC) +- [x] Web-Server nur auf der Klinik-Schnittstelle +- [x] QR-Code mit Adresse in der App +- [x] Handy-Seite: Name/Rolle, Talkback hören, PGM-Vorschau (WebRTC) +- **Stand 2026-10-22:** umgesetzt, mit Chrome (headless) am Mac geprüft; Abnahme mit iPhone und Android offen. - **Abnahme:** iPhone und Android im Heimnetz, Verzögerung der Vorschau gemessen < 0,5 s. ## M5 – Intercom Stufe 2 @@ -95,6 +96,15 @@ _(nach jedem Meilenstein ergänzen)_ - Entfernte Routen werden 2 s auf dem Main Thread geparkt, damit der Render-Thread nie den letzten Verweis loslässt (sonst `free` im Callback). - Sprechtaste global per Carbon-Hotkey (⌃⌥ Leertaste) – braucht keine Bedienungshilfen-Freigabe und meldet Drücken und Loslassen. +### M4 – Intercom Stufe 1 (umgesetzt 2026-10-22, Abnahme offen) +- WebRTC ohne Drittanbieter (Entscheidung 2026-10-21): Musubi ist ICE-lite-Gegenstelle und DTLS-Server. Eigene, schmale Umsetzung auf CryptoKit/CommonCrypto: STUN (RFC 5389/8445), DTLS 1.2 mit genau einer Cipher-Suite (ECDHE-ECDSA-AES128-GCM-SHA256) + `use_srtp`, SRTP AES-CM-HMAC-SHA1-80. Network.framework/Security bieten kein DTLS-SRTP. +- Geprüft gegen RFC-Testvektoren (5769, 3711), OpenSSL (`s_client -dtls1_2 -use_srtp`, gleiche exportierte SRTP-Schlüssel, fremdes Zertifikat wird abgelehnt) und headless Chrome (Ende-zu-Ende: verbunden in ~12 ms, H.264 dekodiert, Opus empfangen). Opt-in-Test: `MUSUBI_E2E=1 swift test --filter BrowserEndToEnd`. +- Das Client-Zertifikat des Browsers wird gegen den Fingerprint aus dem SDP-Angebot geprüft; ohne Übereinstimmung kein Schlüssel. +- Signalisierung per HTTP-POST (Angebot rein, Antwort raus), keine Kandidaten vom Handy nötig: ICE-lite lernt die Adresse aus der ersten STUN-Prüfung (mDNS-Kandidaten der Browser stören nicht). +- Vorschau: NDI-Proxy-Stream (`bandwidth lowest`) → 960×540, 25 fps, H.264 Constrained Baseline, ~1,2 Mbit/s, Keyframe alle 2 s und auf PLI. +- Talkback: Abgriff am Headset-Mikro (`AudioMatrix.addInputTap`), Sprechtaste schaltet; sonst Stille, damit der Ton-Takt der Handys weiterläuft. Opus über AudioToolbox, 20 ms, 32 kbit/s. +- Ohne verbundenes Handy wird nichts kodiert. + ### M3 – Szenen und Fernsteuerung (bestanden 2026-10-21) - Szene = Konfiguration der Regie + Konfiguration je Knoten. Bildschirme werden über den **Namen** erkannt (Position nur bei gleichnamigen Monitoren), weil `CGDirectDisplayID` je Rechner/Neustart wechselt. - Musubi speichert den Live-Stand laufend (`~/Library/Application Support/Musubi/live-state.json`) und stellt ihn beim Start wieder her – nicht die zuletzt gespeicherte Szene. Ausgaben für fehlende Bildschirme bleiben vorgemerkt und starten, sobald der Bildschirm erscheint. diff --git a/docs/05-testplan-hardware.md b/docs/05-testplan-hardware.md index ce1d5d3..279d95b 100644 --- a/docs/05-testplan-hardware.md +++ b/docs/05-testplan-hardware.md @@ -47,9 +47,17 @@ Sobald die bestellte Hardware da ist, wird der echte Aufbau zu Hause nachgestell - [ ] M3 Vorbereitung Knoten (Mac mini): Musubi in `/Applications` (nicht `~/Applications`, sonst kein Bonjour), Rolle Knoten (`defaults write studio.zielke.musubi role node`), Technik-Schnittstelle (`defaults write studio.zielke.musubi interfaceName en7`), Autostart (`open /Applications/Musubi.app --args --login-item on`), automatische Anmeldung an, FileVault aus, „Nach Stromausfall neu starten“ an - [ ] M3 Vorbereitung Regie (MacBook): Musubi in `/Applications`, Einstellungen (⌘,): Rolle Regie, Technik-Netz, „Beim Anmelden starten“ - [x] M3: Mac mini neu starten → Musubi startet ohne Fenster, stellt beide Ausgaben wieder her, Regie verbindet sich (2026-10-21) -- [ ] M3: Szene „OP-Live“ übersteht Neustart beider Macs (Durchlauf in einem Stück; Regie = MacBook) +- [x] M3: Szene „OP-Live“ übersteht Neustart beider Macs (Durchlauf in einem Stück; Regie = MacBook) (2026-10-21) - [ ] M3: Netzwerkkabel zwischen den Macs 30 s ziehen → Knoten zeigt weiter, Regie verbindet sich danach von selbst -- [ ] M4/M5: Handy über zweite Schnittstelle: Hören, Sprechen, Vorschau +- [ ] M4 Vorbereitung (MacBook, Heimnetz): Einstellungen (⌘,) → Klinik-Netz = WLAN-Schnittstelle (z. B. `en0`). Zum Testen darf es dieselbe wie das Technik-Netz sein (Hinweis in Bernstein ist dann richtig). Ansicht „Intercom“: Vorschau = PGM-Quelle (OBS „pgm“ oder Test Patterns), Talkback = Headset-Mikro. +- [ ] M4: macOS-Firewall (falls an): Musubi eingehende Verbindungen erlauben. Ports: TCP 8080 (Seite), UDP 50000 (Ton/Bild). +- [ ] M4: iPhone (Safari) im selben WLAN: QR-Code scannen → Seite lädt, Name/Rolle eintragen, „Verbinden“ → Bild erscheint, Musubi listet das Handy unter „Verbunden“ mit grünem Punkt. +- [ ] M4: Android (Chrome) dasselbe, gleichzeitig mit dem iPhone verbunden. +- [ ] M4: Talkback: Sprechtaste (⌃⌥ Leertaste) halten und sprechen → beide Handys hören dich; loslassen → still. Falls iOS „Ton einschalten“ zeigt, einmal tippen. +- [ ] M4: Vorschau-Verzögerung messen: Uhr mit Millisekunden als NDI-Quelle (z. B. OBS-Browserquelle mit Uhr) als Vorschau wählen, Monitor mit der Quelle und Handy nebeneinander fotografieren; Differenz = Verzögerung: iPhone ___ ms, Android ___ ms (Ziel < 500 ms). +- [ ] M4: WLAN am Handy 10 s aus → Seite meldet „Neuer Versuch in 3 s“ und verbindet sich von selbst wieder; Musubi entfernt das alte Handy nach spätestens 30 s. +- [ ] M4: Handy-Display sperren und entsperren → Verbindung kommt zurück (sonst notieren, wie sich iOS/Android verhalten). +- [ ] M5: Handy über zweite Schnittstelle: Sprechen - [ ] M6: Tally auf dem Handy folgt dem Micro Panel ## Messwerte diff --git a/docs/06-netzwerk.md b/docs/06-netzwerk.md index 4869ba0..2df324b 100644 --- a/docs/06-netzwerk.md +++ b/docs/06-netzwerk.md @@ -25,6 +25,17 @@ Keine Internetfreigabe, kein Routing zwischen den Netzen. Musubi bindet jeden Di Maske 255.255.255.0, kein Gateway. +## Intercom: Ports und Bindung + +Musubi bindet beide Dienste ausschließlich an die Klinik-Schnittstelle (Einstellungen → Klinik-Netz); über das Technik-Netz oder Loopback sind sie nicht erreichbar. + +| Port | Protokoll | Zweck | +|---|---|---| +| 8080 | TCP (HTTP, ab M5 HTTPS) | Handy-Seite und Signalisierung (SDP-Angebot/-Antwort) | +| 50000 | UDP | WebRTC: ICE-lite, DTLS, SRTP (Talkback Opus, PGM-Vorschau H.264), alle Handys auf einem Port | + +Für die Klinik-IT: Handys müssen den Mac auf diesen beiden Ports direkt erreichen (keine Client-Isolation im WLAN). + ## Intercom: Reihenfolge der Wege 1. **Eigenes Netz der Klinik-IT** – lokal, schnellster Weg. Bevorzugt.