- 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.
@ -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: 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 <500ms).
- [ ] 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
@ -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.