Brauche Hilfe beim Bau eines Servers in FHEM

Begonnen von betateilchen, 13 Mai 2026, 12:26:02

Vorheriges Thema - Nächstes Thema

betateilchen

Moin,

auch wenn ich schon unzählige Jahre in FHEM unterwegs bin, habe ich bis heute nicht verstanden, wie FHEM die Bereitstellung eigener "Server" handhabt. (MQTT2, HTTPSRV usw.)
Dass es TCPServerUtils und DevIO gibt, weiß ich. Aber das sind für mich nach wie vor böhmische Dörfer.

Was will ich tun? Mein Ziel ist ein absolut primitiver Endpunkt in FHEM, der SIP requests annimmt.
Das soll ermöglichen, von einem VoIP Telefon aus SIP Nachrichten zu schicken (aka: eine Nummer wählen) die dann in FHEM per notify ausgewertet werden kann. Das SIP Modul ist dafür viel zu viel Overhead.

Als perl Skript (ca. 100 Zeilen) auf der Konsole habe ich das soweit fertig, dass ich die Nachrichten empfangen kann.


# hier registriert sich das Tischtelefon am "Server"
Message: REGISTER sip:192.168.123.115 SIP/2.0
REGISTER
   sip:snomd892m@192.168.123.115 => 192.168.123.20

# hier wird vom Telefon aus die Nummer **55 gewählt
Message: INVITE sip:**55@192.168.123.115;user=phone SIP/2.0
   INVITE
   sip:**55@192.168.123.115;user=phone

# hier wird eine weitere eingehende Nachricht empfangen (eigentlich nicht relevant)
Message: ACK sip:**55@192.168.123.115;user=phone SIP/2.0
   ACK
   sip:**55@192.168.123.115;user=phone

Das Grundprinzip ist einfach:

# hier wird der "Server" gestartet
my $server = IO::Socket::INET->new(LocalPort=>'5060',Proto=>"udp")
   or die "Couldn't be a udp server: $@\n";

# das ist die Schleife, in der die Nachrichten ankommen und verarbeitet werden
# in $datagram steht die empfangene Nachricht
while ($user=$server->recv($datagram,$MAX_TO_READ)) {...}

# das ist die Funktion, mit der SIP-Antworten an das Telefon geschickt werden
sub send_msg {
  my $ip = shift;
  my $infoline = shift;
  my $headers = shift;
  my $body = shift;
  my $msg=$infoline."\r\n".$headers.$body;
  my $sock = new IO::Socket::INET (
    PeerAddr =>$ip,
    PeerPort => '5060',
    Proto => 'udp');
  die "Could not create socket: $!\n" unless $sock;
  print $sock $msg;
  close($sock);
}


Und nun hätte ich das Ganze gerne in eine FHEM-Modul verpackt, damit ich das nicht auf der Konsole laufen lassen muss.
Natürlich hatte ich schon versucht, mir das aus irgendwelchen existierenden Servermodulen zusammenbauen. Aber inzwischen ist der Frustpegel recht hoch, weil mir einfach das Grundverständnis dazu fehlt.

Da es diesen SIP Endpoint in der Installation nur einmal geben wird, brauche ich kein define() usw. Deshalb könnte ich mir sogar vorstellen, das in einer 99_xxx Datei zu haben. Das Ding soll einfach eingehende Nachrichten als FHEM-event ausgeben. Fertig.

Mag mir jemand helfen?
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

rudolfkoenig


betateilchen

Hallo Rudi,

danke, der Schubs in Richtung IO::Socket hilft mir schonmal viel weiter.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

betateilchen

Das Wichtigste funktioniert schon: Die SIP Kommunikation in beide Richtungen und die Auswertung der gewählten Eingabe (*123#)

Du darfst diesen Dateianhang nicht ansehen.

Die ausgehende Fehlermeldung 500 ist die einfachste Variante, das anrufende Telefon zum Auflegen zu bewegen 8)

026.05.13 19:46:04 4: minisip: _process.154 Message in:
REGISTER sip:fhem.h5u.de SIP/2.0
Via: SIP/2.0/UDP 192.168.123.20:5060;branch=z9hG4bK-rmdqj26earfz;rport
From: "minisip" <sip:snomd892m@fhem.h5u.de>;tag=pqaprqtvwg
To: "minisip" <sip:snomd892m@fhem.h5u.de>
Call-ID: 28b6046a5d61-24dncbeulwxn
CSeq: 3 REGISTER
Max-Forwards: 70
User-Agent: snomD892/10.1.215.13
Contact: <sip:snomd892m@192.168.123.20:5060>;reg-id=1;q=1.0;+sip.instance="<urn:uuid:9f2ea6dd-3881-4616-8a6b-000413C404BB>";audio;mobility="fixed";duplex="full";description="snomD892";actor="principal";events="dialog";methods="INVITE,ACK,CANCEL,BYE,REFER,OPTIONS,NOTIFY,SUBSCRIBE,PRACK,MESSAGE,INFO"
Allow-Events: dialog, talk, hold, check-sync
X-Real-IP: 192.168.123.20
Supported: path, gruu
Expires: 3600
Content-Length: 0

2026.05.13 19:46:04 4: minisip: _send_msg.128 Message out:
SIP/2.0 200 OK

2026.05.13 19:47:11 4: minisip: _process.154 Message in:
INVITE sip:*123%23@fhem.h5u.de;user=phone SIP/2.0
Via: SIP/2.0/UDP 192.168.123.20:5060;branch=z9hG4bK-1o0bnne388bw;rport
From: "minisip" <sip:snomd892m@fhem.h5u.de>;tag=98dch5ijde
To: <sip:*123%23@fhem.h5u.de;user=phone>
Call-ID: 1bb9046ad66d-8wys93m4uced
CSeq: 1 INVITE
Max-Forwards: 70
User-Agent: snomD892/10.1.215.13
Contact: "minisip" <sip:snomd892m@192.168.123.20:5060>;reg-id=1
X-Serialnumber: 000413C404BB
Accept: application/sdp
Allow: INVITE, ACK, CANCEL, BYE, REFER, OPTIONS, NOTIFY, SUBSCRIBE, PRACK, MESSAGE, INFO, UPDATE
Allow-Events: talk, hold, refer, call-info
Supported: timer, 100rel, replaces, from-change
Session-Expires: 3600
Min-SE: 90
Content-Type: application/sdp
Content-Length: 489

v=0
o=root 983923464 983923464 IN IP4 192.168.123.20
s=call
c=IN IP4 192.168.123.20
t=0 0
m=audio 56472 RTP/AVP 9 0 8 3 99 111 18 101
a=crypto:1 AES_CM_128_HMAC_SHA1_32 inline:IaFzQVRpvef4ageCSg/2mqdhfmSIsREuZUen3wvM
a=rtpmap:9 G722/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:3 GSM/8000
a=rtpmap:99 G726-32/8000
a=rtpmap:111 AAL2-G726-32/8000
a=rtpmap:18 G729/8000
a=fmtp:18 annexb=no
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=ptime:20
a=sendrecv

2026.05.13 19:47:11 4: minisip: _send_msg.128 Message out:
SIP/2.0 500 Error

2026.05.13 19:47:11 4: minisip: _process.154 Message in:
ACK sip:*123%23@fhem.h5u.de;user=phone SIP/2.0
Via: SIP/2.0/UDP 192.168.123.20:5060;branch=z9hG4bK-1o0bnne388bw;rport
From: "minisip" <sip:snomd892m@fhem.h5u.de>;tag=98dch5ijde
To: <sip:*123%23@fhem.h5u.de;user=phone>
Call-ID: 1bb9046ad66d-8wys93m4uced
CSeq: 1 ACK
Max-Forwards: 70
User-Agent: snomD892/10.1.215.13
Contact: "minisip" <sip:snomd892m@192.168.123.20:5060>;reg-id=1
Content-Length: 0

-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!