linux.sipsoftphone/sip/account.py
data 48ddb4b4af Initiales Release: SIP Softphone für FreePBX/Asterisk
PySide6/PJSUA2-basiertes Desktop-Softphone mit:
- SIP-Telefonie (Anrufe, DTMF, Halten, Transfer, Konferenz)
- CardDAV-Kontaktsync mit Write-Back (Multi-Account)
- Kontaktverwaltung mit Suche und Bearbeiten-Dialog
- Anrufliste mit Namensauflösung
- Favoriten-Panel (manuell + häufig angerufen)
- BLF-Panel (SIP Presence Monitoring)
- Responsives Layout (kompakt/erweitert)
- Click-to-Call (tel:/sip: URI via D-Bus)
- KDE-Integration (Tray, Benachrichtigungen)
- PipeWire/PulseAudio Audio-Routing
- AppImage Build-Support (PyInstaller + appimagetool)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 13:18:54 +01:00

82 lines
2.5 KiB
Python

"""SIP-Account Klasse - Wrapper um pjsua2.Account für FreePBX-Registrierung."""
import pjsua2 as pj
from sip.call import MeinAnruf
class MeinAccount(pj.Account):
"""SIP-Account für FreePBX-Registrierung.
Verwaltet den Registrierungsstatus und eingehende Anrufe.
"""
def __init__(self, callback=None):
pj.Account.__init__(self)
self._callback = callback
self.aktueller_anruf = None
# Für Konferenz: Liste aller aktiven Anrufe
self.aktive_anrufe = []
def onRegState(self, prm):
"""Registrierungsstatus hat sich geändert."""
ai = self.getInfo()
if self._callback:
self._callback("registrierung", {
"aktiv": ai.regIsActive,
"code": prm.code,
"grund": prm.reason,
"uri": ai.uri,
})
def onIncomingCall(self, iprm):
"""Eingehender Anruf empfangen."""
anruf = MeinAnruf(self, iprm.callId, self._callback)
ci = anruf.getInfo()
# Als aktuellen Anruf setzen und in Liste aufnehmen
self.aktueller_anruf = anruf
self.aktive_anrufe.append(anruf)
if self._callback:
self._callback("eingehend", {
"remoteUri": ci.remoteUri,
"remoteContact": ci.remoteContact,
})
# 180 Ringing senden
prm = pj.CallOpParam()
prm.statusCode = pj.PJSIP_SC_RINGING
anruf.answer(prm)
def anruf_starten(self, ziel_uri):
"""Ausgehenden Anruf starten."""
anruf = MeinAnruf(self, callback=self._callback)
prm = pj.CallOpParam(True)
anruf.makeCall(ziel_uri, prm)
self.aktueller_anruf = anruf
self.aktive_anrufe.append(anruf)
return anruf
def anruf_annehmen(self):
"""Eingehenden Anruf annehmen (200 OK)."""
if self.aktueller_anruf:
prm = pj.CallOpParam()
prm.statusCode = pj.PJSIP_SC_OK
self.aktueller_anruf.answer(prm)
def anruf_beenden(self):
"""Aktuellen Anruf auflegen."""
if self.aktueller_anruf:
self.aktueller_anruf.auflegen()
def anruf_entfernen(self, anruf):
"""Beendeten Anruf aus der Liste entfernen."""
if anruf in self.aktive_anrufe:
self.aktive_anrufe.remove(anruf)
if self.aktueller_anruf is anruf:
# Nächsten aktiven Anruf als aktuell setzen
self.aktueller_anruf = (
self.aktive_anrufe[-1] if self.aktive_anrufe else None
)