# SIP Softphone Desktop-SIP-Softphone für FreePBX/Asterisk auf Linux (KDE/PipeWire). Basiert auf **PJSUA2** (SIP-Stack) und **PySide6** (Qt-GUI). Verbindet sich über SIP/UDP direkt mit der Telefonanlage. ## Features - **SIP-Telefonie**: Anrufe tätigen/annehmen, DTMF, Halten, Transfer, Konferenz - **Kontaktverwaltung**: Lokale Kontakte + CardDAV-Sync (Nextcloud, Multi-Account) - **CardDAV Write-Back**: Kontakte bearbeiten und auf den Server zurückschreiben - **Anrufliste**: Verlauf mit Richtung, Dauer, Kontaktnamens-Auflösung - **Favoriten**: Manuelle Favoriten + häufig angerufene Nummern (automatisch) - **BLF-Panel**: Besetzt-Lampenfeld (Presence-Monitoring via SIP SUBSCRIBE) - **Kontaktsuche**: Live-Suche im Wählfeld nach Name/Firma - **Responsives Layout**: Kompakt (nur Wählfeld) oder Breit (Wählfeld + Tabs) - **Click-to-Call**: `tel:` und `sip:` URI-Handler via D-Bus Single-Instance - **KDE-Integration**: System-Tray, D-Bus-Benachrichtigungen mit Annehmen/Ablehnen - **Autostart**: Automatisch beim Systemstart starten (XDG-konform) - **Minimiert starten**: Optional direkt in den System-Tray starten - **PipeWire-Audio**: Natives PipeWire/PulseAudio-Routing, separates Klingelton-Gerät - **AppImage**: Komplett unabhängiges Paket (kein Python/Qt auf dem Zielsystem nötig) ## Screenshots ``` ┌──────────────────────────────────────────────┐ │ [Registriert] 00:42 SIP Softphone │ ├──────────────┬───────────────────────────────┤ │ │ Favoriten│Verlauf│Kontakte│BLF │ │ [Nummer...] ├───────────────────────────────┤ │ │ ★ Max Mustermann │ │ [1] [2] [3]│ +49 40 555 1234 │ │ [4] [5] [6]│ ★ Büro Hauptnummer │ │ [7] [8] [9]│ +49 40 555 0000 │ │ [*] [0] [#]│ │ │ │ Häufig angerufen │ │ │ Lieferant Meyer │ ├──────────────┴───────────────────────────────┤ │ [ Anrufen ] │ │ Mik: ═══════════ Lsp: ═══════════ │ └──────────────────────────────────────────────┘ ``` ## Voraussetzungen ### System - Linux x86_64 (getestet: Manjaro KDE) - PipeWire oder PulseAudio - Python 3.10+ (für Entwicklung) ### Python-Pakete ``` PySide6>=6.6.0 vobject>=0.9.6 # vCard-Parsing für CardDAV requests>=2.28.0 # HTTP-Client für CardDAV ``` ### pjsua2 (SIP-Stack) Auf Arch/Manjaro via AUR: ```bash yay -S python-pjproject ``` ### Optional - `dbus-python`: Vorinstalliert auf KDE-Systemen (für Benachrichtigungen + Click-to-Call) ## Installation ### Aus Quellcode (Entwicklung) ```bash git clone https://git.data-it-solution.de/data/linux.sipsoftphone.git cd linux.sipsoftphone pip install -r requirements.txt python3 main.py ``` ### Als AppImage (empfohlen) ```bash # AppImage bauen ./build_appimage.sh # Starten chmod +x dist/SipSoftphone-x86_64.AppImage ./dist/SipSoftphone-x86_64.AppImage ``` Das AppImage bündelt Python, Qt, pjsua2 und alle Abhängigkeiten. Auf dem Zielsystem wird nichts weiter benötigt. ## Verwendung ### Erster Start 1. App starten → Login-Dialog erscheint 2. SIP-Zugangsdaten eingeben (Server, Extension, Passwort, Port) 3. Nach erfolgreicher Registrierung: Status wechselt zu grün "Registriert" ### Anrufe | Aktion | Bedienung | |--------|-----------| | Anruf starten | Nummer eingeben + Enter oder "Anrufen"-Button | | Kontakt anrufen | Name im Wählfeld tippen → Vorschlag doppelklicken | | Annehmen | "Annehmen"-Button, F5, oder KDE-Benachrichtigung | | Auflegen | "Auflegen"-Button oder F6 | | Stummschalten | F7 | | Halten | F8 | | DTMF im Gespräch | Zifferntasten drücken (Wählfeld wechselt automatisch) | ### CardDAV-Kontakte Über **Einstellungen → CardDAV** können mehrere Accounts konfiguriert werden (z.B. Nextcloud): - URL: `https://nextcloud.example.de/remote.php/dav` - Benutzername + Passwort - Automatischer Sync im Hintergrund Kontakte können im Detail-Dialog bearbeitet und per CardDAV zurückgeschrieben werden. ### Favoriten - Im Kontakt-Detail-Dialog: "Favorit"-Button zum Pinnen/Entpinnen - Häufig angerufene Nummern werden automatisch angezeigt - Klick auf Favorit → Anruf wird gestartet ### Click-to-Call (URI-Handler) ```bash # tel: URI python3 main.py tel:+49123456789 # sip: URI python3 main.py sip:200@server # Als Standard-Handler registrieren (KDE) xdg-mime default sipwebapp.desktop x-scheme-handler/tel xdg-mime default sipwebapp.desktop x-scheme-handler/sip ``` Bei laufender Instanz wird der Anruf per D-Bus an die bestehende App weitergeleitet. ### Responsives Layout - **Schmal (<650px)**: Nur Wählfeld mit Kontaktsuche - **Breit (≥650px)**: Wählfeld links + Tabs rechts (Favoriten, Verlauf, Kontakte, BLF) ## Projektstruktur ``` SipWebApp/ ├── main.py # Einstiegspunkt, D-Bus Single-Instance ├── requirements.txt # Python-Abhängigkeiten ├── sipwebapp.spec # PyInstaller Build-Konfiguration ├── build_appimage.sh # AppImage Build-Skript ├── sip/ │ ├── engine.py # PJSUA2-Endpoint mit Qt-Integration │ ├── account.py # SIP-Account (Registrierung, Presence) │ └── call.py # SIP-Call (Medien, DTMF, Transfer) ├── ui/ │ ├── hauptfenster.py # Hauptfenster (Layout, Signale, SIP-Events) │ ├── waehlfeld.py # Wähltastatur + Kontaktsuche │ ├── kontakte.py # Kontakttabelle + Detail/Bearbeiten-Dialoge │ ├── anrufliste.py # Anrufverlauf mit Namensauflösung │ ├── favoriten_panel.py # Manuelle + automatische Favoriten │ ├── blf_panel.py # Besetzt-Lampenfeld (SIP Presence) │ ├── einstellungen.py # Einstellungs-Dialog (Audio, CardDAV, BLF) │ └── login_dialog.py # SIP-Login-Dialog ├── utils/ │ ├── config_manager.py # JSON-Konfiguration (~/.config/sipwebapp/) │ ├── carddav.py # CardDAV-Sync + Write-Back (vobject/requests) │ ├── audio_manager.py # PipeWire/PulseAudio Geräte-Verwaltung │ ├── klingelton.py # Klingelton über separates Audio-Gerät │ └── benachrichtigung.py # KDE D-Bus Desktop-Benachrichtigungen └── resources/ ├── sipwebapp.desktop # XDG Desktop-Entry ├── icons/phone.svg # App-Icon └── sounds/klingelton.wav # Standard-Klingelton ``` ## Architektur ### SIP-Integration (PJSUA2) PJSUA2 wird im **Single-Thread-Modus** betrieben: - `threadCnt=0`: Keine eigenen Worker-Threads - `mainThreadOnly=True`: Alle Callbacks im Qt-Hauptthread - `QTimer` pollt `libHandleEvents(0)` alle 50ms So werden Race-Conditions und Qt-Crash-Probleme vermieden. ### Audio-Routing PJSUA2 nutzt das `pulse`-Device. PipeWire übernimmt das Routing: - Mikrofon/Lautsprecher: Konfigurierbar in den Einstellungen - Klingelton: Separates Ausgabegerät (z.B. eingebaute Lautsprecher) - Lautstärke: Mikrofon + Lautsprecher über Slider (0-200%) ### Konfiguration Gespeichert unter `~/.config/sipwebapp/config.json`: - SIP-Zugangsdaten (Server, Extension, Passwort) - Audio-Geräte (Aufnahme, Wiedergabe, Klingelton) - CardDAV-Accounts (Multi-Account) - BLF-Extensions - Favoriten (manuell gepinnt) - Allgemein: Autostart, Minimiert starten, Tray-Verhalten ### Autostart Wenn in den Einstellungen aktiviert, wird ein Desktop-Entry erstellt: `~/.config/autostart/sipwebapp.desktop` Die Option "Minimiert starten" lässt die App direkt im System-Tray starten, ohne das Hauptfenster anzuzeigen. ## AppImage bauen Voraussetzungen auf dem Build-System: - Python 3.14+ - `python-pjproject` (AUR) - Internetzugang (lädt appimagetool + pip-Pakete) ```bash ./build_appimage.sh ``` Das Skript: 1. Erstellt ein Python-venv mit allen Abhängigkeiten 2. Kopiert pjsua2-Bindings + alle nativen Shared Libraries 3. Bündelt alles mit PyInstaller 4. Packt als AppImage (appimagetool) Ergebnis: `dist/SipSoftphone-x86_64.AppImage` (~90 MB) ## Tastatur-Shortcuts | Taste | Aktion | |-------|--------| | F5 | Anruf annehmen | | F6 | Auflegen | | F7 | Stummschalten | | F8 | Halten/Fortsetzen | | Escape | Nummernfeld leeren | | Enter | Nummer wählen | | 0-9, *, # | DTMF-Ziffern (Numpad-kompatibel) | ## Lizenz Proprietär - ALLES WATT LÄUFT (Eduard Wisch)