- Autostart: Desktop-Entry wird in ~/.config/autostart/ erstellt - Minimiert starten: App startet direkt im System-Tray - Einstellungen lesen Config direkt, kein CLI-Flag nötig - README.md aktualisiert Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
254 lines
8.8 KiB
Markdown
254 lines
8.8 KiB
Markdown
# 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)
|