mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-05-04 22:19:38 +00:00
96_SIP: add set reject and attr sip_blocking
git-svn-id: https://svn.fhem.de/fhem/trunk/fhem@13789 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
68c015c7cd
commit
8dc972caa8
120
FHEM/96_SIP.pm
120
FHEM/96_SIP.pm
@ -49,17 +49,18 @@ use Net::SIP qw//;
|
|||||||
use Net::SIP::Packet;
|
use Net::SIP::Packet;
|
||||||
use IO::Socket;
|
use IO::Socket;
|
||||||
use Socket;
|
use Socket;
|
||||||
use Net::Domain qw( hostfqdn );
|
use Net::Domain qw(hostname hostfqdn);
|
||||||
use Blocking; # http://www.fhemwiki.de/wiki/Blocking_Call
|
use Blocking; # http://www.fhemwiki.de/wiki/Blocking_Call
|
||||||
#use Data::Dumper;
|
#use Data::Dumper;
|
||||||
|
|
||||||
my $sip_version ="V1.46 / 21.03.17";
|
my $sip_version ="V1.47 / 24.03.17";
|
||||||
my $ua; # SIP user agent
|
my $ua; # SIP user agent
|
||||||
my @fifo;
|
my @fifo;
|
||||||
|
|
||||||
my %sets = (
|
my %sets = (
|
||||||
"call" => "",
|
"call" => "",
|
||||||
"listen:noArg" => "",
|
"listen:noArg" => "",
|
||||||
|
"reject:noArg" => "",
|
||||||
"reset:noArg" => "",
|
"reset:noArg" => "",
|
||||||
"fetch:noArg" => "",
|
"fetch:noArg" => "",
|
||||||
"password" => ""
|
"password" => ""
|
||||||
@ -95,6 +96,7 @@ sub SIP_Initialize($$)
|
|||||||
"sip_dtmf_loop:once,loop ".
|
"sip_dtmf_loop:once,loop ".
|
||||||
"sip_listen:none,dtmf,wfp ".
|
"sip_listen:none,dtmf,wfp ".
|
||||||
"sip_filter ".
|
"sip_filter ".
|
||||||
|
"sip_blocking ".
|
||||||
"T2S_Device ".
|
"T2S_Device ".
|
||||||
"T2S_Timeout ".
|
"T2S_Timeout ".
|
||||||
"audio_converter:sox,ffmpeg ".
|
"audio_converter:sox,ffmpeg ".
|
||||||
@ -106,15 +108,13 @@ sub SIP_Define($$)
|
|||||||
my ($hash, $def) = @_;
|
my ($hash, $def) = @_;
|
||||||
my @a = split("[ \t][ \t]*", $def);
|
my @a = split("[ \t][ \t]*", $def);
|
||||||
my $name = shift @a;
|
my $name = shift @a;
|
||||||
my $host = hostfqdn();
|
my $addr = "0.0.0.0";
|
||||||
my $addr = inet_ntoa(scalar(gethostbyname($host)));
|
|
||||||
|
|
||||||
$hash->{STATE} = "defined";
|
$hash->{STATE} = "defined";
|
||||||
$hash->{VERSION} = $sip_version;
|
$hash->{VERSION} = $sip_version;
|
||||||
$hash->{".reset"} = 0;
|
$hash->{".reset"} = 0;
|
||||||
$attr{$name}{sip_ringtime} = '3' unless (exists($attr{$name}{sip_ringtime}));
|
$attr{$name}{sip_ringtime} = '3' unless (exists($attr{$name}{sip_ringtime}));
|
||||||
$attr{$name}{sip_user} = '620' unless (exists($attr{$name}{sip_user}));
|
$attr{$name}{sip_user} = '620' unless (exists($attr{$name}{sip_user}));
|
||||||
$attr{$name}{sip_ip} = $addr unless (exists($attr{$name}{sip_ip}));
|
|
||||||
$attr{$name}{sip_port} = '5060' unless (exists($attr{$name}{sip_port}));
|
$attr{$name}{sip_port} = '5060' unless (exists($attr{$name}{sip_port}));
|
||||||
$attr{$name}{sip_registrar} = 'fritz.box' unless (exists($attr{$name}{sip_registrar}));
|
$attr{$name}{sip_registrar} = 'fritz.box' unless (exists($attr{$name}{sip_registrar}));
|
||||||
$attr{$name}{sip_listen} = 'none' unless (exists($attr{$name}{sip_listen}));
|
$attr{$name}{sip_listen} = 'none' unless (exists($attr{$name}{sip_listen}));
|
||||||
@ -123,6 +123,18 @@ sub SIP_Define($$)
|
|||||||
$attr{$name}{sip_dtmf_send} = 'audio' unless (exists($attr{$name}{sip_dtmf_send}));
|
$attr{$name}{sip_dtmf_send} = 'audio' unless (exists($attr{$name}{sip_dtmf_send}));
|
||||||
$attr{$name}{sip_from} = 'sip:'.$attr{$name}{sip_user}.'@'.$attr{$name}{sip_registrar} unless (exists($attr{$name}{sip_from}));
|
$attr{$name}{sip_from} = 'sip:'.$attr{$name}{sip_user}.'@'.$attr{$name}{sip_registrar} unless (exists($attr{$name}{sip_from}));
|
||||||
|
|
||||||
|
unless (exists($attr{$name}{sip_ip}))
|
||||||
|
{
|
||||||
|
eval { $addr = inet_ntoa(scalar(gethostbyname(hostfqdn()))); };
|
||||||
|
if ($@)
|
||||||
|
{
|
||||||
|
Log3 $name,2,"$name, please check your FQDN hostname -> $@";
|
||||||
|
eval { $addr = inet_ntoa(scalar(gethostbyname(hostname()))); };
|
||||||
|
Log3 $name,2,"$name, please check your hostname -> ".$@ if ($@);
|
||||||
|
}
|
||||||
|
$attr{$name}{sip_ip} = $addr;
|
||||||
|
}
|
||||||
|
|
||||||
RemoveInternalTimer($hash);
|
RemoveInternalTimer($hash);
|
||||||
InternalTimer(gettimeofday()+5, "SIP_updateConfig", $hash);
|
InternalTimer(gettimeofday()+5, "SIP_updateConfig", $hash);
|
||||||
return undef;
|
return undef;
|
||||||
@ -513,8 +525,7 @@ sub SIP_CALLDone($)
|
|||||||
my $nr2 = $nr;
|
my $nr2 = $nr;
|
||||||
$nr2 =~ tr/0-9//cd;
|
$nr2 =~ tr/0-9//cd;
|
||||||
CommandDefine(undef, "at_forcecall_".$nr2." at +00:01:00 set $name call $nr $ringtime $msg $force");
|
CommandDefine(undef, "at_forcecall_".$nr2." at +00:01:00 set $name call $nr $ringtime $msg $force");
|
||||||
my $room = AttrVal($name,"room","unsorted");
|
$attr{"at_forcecall_".$nr2}{room} = AttrVal($name,"room","unsorted");
|
||||||
$attr{"at_forcecall_".$nr2}{room} = $room;
|
|
||||||
delete $hash->{CALL};
|
delete $hash->{CALL};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -677,6 +688,12 @@ sub SIP_Set($@)
|
|||||||
readingsSingleUpdate($hash, "caller","fetch",1);
|
readingsSingleUpdate($hash, "caller","fetch",1);
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
elsif ($cmd eq "reject")
|
||||||
|
{
|
||||||
|
readingsSingleUpdate($hash, "caller","reject",1);
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
elsif ($cmd eq "reset")
|
elsif ($cmd eq "reset")
|
||||||
{
|
{
|
||||||
$hash->{".reset"} = 1;
|
$hash->{".reset"} = 1;
|
||||||
@ -756,9 +773,10 @@ sub SIP_ListenStart($)
|
|||||||
my $okloopbye = 0; # Ende-Flag für recv_bye währne der OK-Ansage
|
my $okloopbye = 0; # Ende-Flag für recv_bye währne der OK-Ansage
|
||||||
my $byebye = 0; # Anrufer hat aufgelegt
|
my $byebye = 0; # Anrufer hat aufgelegt
|
||||||
my $packets = 50;
|
my $packets = 50;
|
||||||
|
my $block_it;
|
||||||
|
|
||||||
my $sub_create;
|
my $sub_create;
|
||||||
my $sub_invite;
|
my $sub_invite_wfp;
|
||||||
my $sub_filter;
|
my $sub_filter;
|
||||||
my $sub_bye;
|
my $sub_bye;
|
||||||
my $sub_dtmf;
|
my $sub_dtmf;
|
||||||
@ -840,34 +858,56 @@ sub SIP_ListenStart($)
|
|||||||
$sub_create = sub
|
$sub_create = sub
|
||||||
{
|
{
|
||||||
my ($call,$request,$leg,$from) = @_;
|
my ($call,$request,$leg,$from) = @_;
|
||||||
my $method = $request->method;
|
$hash->{call} = $call;
|
||||||
my $response = $request->create_response( '180','Ringing' );
|
$hash->{request} = $request;
|
||||||
|
$hash->{leg} = $leg;
|
||||||
|
$hash->{from} = $from;
|
||||||
|
#my $method = $request->method;
|
||||||
|
my $response = ($block_it) ? $request->create_response('487','Request Terminated') : $request->create_response('180','Ringing');
|
||||||
$call->{endpoint}->new_response( $call->{ctx},$response,$leg,$from );
|
$call->{endpoint}->new_response( $call->{ctx},$response,$leg,$from );
|
||||||
1;
|
1;
|
||||||
};
|
};
|
||||||
|
|
||||||
$sub_invite = sub
|
$sub_invite_wfp = sub
|
||||||
{
|
{
|
||||||
my ($a,$b,$c,$d) = @_;
|
my ($a,$b,$c,$d) = @_;
|
||||||
my $waittime = int(AttrVal($name, "sip_waittime", 10));
|
my $waittime = int(AttrVal($name, "sip_waittime", 10));
|
||||||
my $action;
|
|
||||||
my $i;
|
my $i;
|
||||||
|
|
||||||
$packets = 50;
|
$packets = 50;
|
||||||
for($i=0; $i<$waittime; $i++)
|
for($i=1; $i<=$waittime; $i++)
|
||||||
{
|
{
|
||||||
SIP_telnet($hash,"set $name caller_state ringing\nexit\n") if (!$i);
|
last if ($block_it); #und gleich wieder weg
|
||||||
|
Log3 $name, 4,"$logname, SIP_invite -> ringing $i";
|
||||||
|
SIP_telnet($hash,"set $name caller_state ringing_$i\nexit\n");
|
||||||
sleep 1;
|
sleep 1;
|
||||||
######## $$$ read state of my device
|
######## $$$ read state of my device
|
||||||
$action = SIP_telnet($hash,"get $name caller\n");
|
my $action = SIP_telnet($hash,"get $name caller\n");
|
||||||
Log3 $name, 4, "$logname, SIP_invite ->ringing $i : $action";
|
|
||||||
if ( $action eq "fetch" )
|
if ( $action eq "fetch" )
|
||||||
{
|
{
|
||||||
|
Log3 $name, 4,"$logname, SIP_invite fetch !";
|
||||||
SIP_telnet($hash,"set $name caller_state fetching\nexit\n");
|
SIP_telnet($hash,"set $name caller_state fetching\nexit\n");
|
||||||
last;
|
last;
|
||||||
}
|
}
|
||||||
|
elsif ( $action eq "reject" )
|
||||||
|
{
|
||||||
|
Log3 $name, 4,"$logname, SIP_invite block !";
|
||||||
|
SIP_telnet($hash,"set $name caller_state rejected\nexit\n");
|
||||||
|
|
||||||
|
my $call = $hash->{call};
|
||||||
|
my $request = $hash->{request};
|
||||||
|
my $leg = $hash->{leg};
|
||||||
|
my $from = $hash->{from};
|
||||||
|
|
||||||
|
my $response = $request->create_response('603','Declined');
|
||||||
|
$call->{endpoint}->new_response( $call->{ctx},$response,$leg,$from );
|
||||||
|
|
||||||
|
last;
|
||||||
}
|
}
|
||||||
SIP_telnet($hash, "set $name caller none\nset $name caller_state waiting\nexit\n") if ($i>=$waittime);
|
|
||||||
|
|
||||||
|
}
|
||||||
|
SIP_telnet($hash, "set $name caller none\nset $name caller_state waiting\nexit\n") if ($i>$waittime);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
@ -876,6 +916,7 @@ sub SIP_ListenStart($)
|
|||||||
{
|
{
|
||||||
my ($a,$b) = @_;
|
my ($a,$b) = @_;
|
||||||
Log3 $name, 5, "$logname, SIP_filter : a:$a | b:$b";
|
Log3 $name, 5, "$logname, SIP_filter : a:$a | b:$b";
|
||||||
|
$block_it = 0; #
|
||||||
|
|
||||||
my ($caller,undef) = split("\;", $a);
|
my ($caller,undef) = split("\;", $a);
|
||||||
my @callers;
|
my @callers;
|
||||||
@ -886,18 +927,30 @@ sub SIP_ListenStart($)
|
|||||||
SIP_telnet($hash, "set $name caller $caller\nexit\n");
|
SIP_telnet($hash, "set $name caller $caller\nexit\n");
|
||||||
|
|
||||||
my ($callnr,undef) = split("\@", $caller);
|
my ($callnr,undef) = split("\@", $caller);
|
||||||
# $callnr =~ s/sip://;
|
|
||||||
|
my $block = AttrVal($name,"sip_blocking",undef);
|
||||||
|
if (defined($block))
|
||||||
|
{
|
||||||
|
my @blockers = split (/,/,$block);
|
||||||
|
foreach (@blockers)
|
||||||
|
{
|
||||||
|
if ((index($callnr, $_) > -1) || ($_ eq ".*"))
|
||||||
|
{
|
||||||
|
SIP_telnet($hash,"set $name caller_state blocking\nexit\n");
|
||||||
|
Log3 $name, 4, "$logname, blocking $callnr found on $block";
|
||||||
|
$block_it = 1;
|
||||||
|
#$byebye = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
my $filter = AttrVal($name,"sip_filter",undef);
|
my $filter = AttrVal($name,"sip_filter",undef);
|
||||||
if (defined($filter))
|
if (defined($filter))
|
||||||
{
|
{
|
||||||
@callers = split (/,/,$filter);
|
@callers = split (/,/,$filter);
|
||||||
foreach (@callers)
|
foreach (@callers) { return 1 if (index($callnr, $_) > -1); }
|
||||||
{
|
SIP_telnet($hash,"set $name caller_state ignoring\nexit\n");
|
||||||
#Log3 $name, 5, "$logname, $_ -> $callnr";
|
Log3 $name, 4, "$logname, ignoring $callnr number not found in $filter";
|
||||||
return 1 if (index($callnr, $_) > -1);
|
|
||||||
}
|
|
||||||
Log3 $name, 5, "$logname, blocking $callnr not found in $filter";
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@ -929,16 +982,25 @@ sub SIP_ListenStart($)
|
|||||||
$hash->{dtmf_event} = "";
|
$hash->{dtmf_event} = "";
|
||||||
$hash->{old} ="-";
|
$hash->{old} ="-";
|
||||||
|
|
||||||
|
SIP_telnet($hash, "set $name caller none\nset $name caller_state waitting\nexit\n") ;
|
||||||
|
|
||||||
$ua->listen (cb_create => \&$sub_create,
|
$ua->listen (cb_create => \&$sub_create,
|
||||||
cb_invite => sub {
|
cb_invite => sub {
|
||||||
|
if (!$block_it)
|
||||||
|
{
|
||||||
SIP_telnet($hash,"set $name caller_state ringing\nexit\n");
|
SIP_telnet($hash,"set $name caller_state ringing\nexit\n");
|
||||||
sleep int(AttrVal($name, "sip_ringtime", 3)); #Anrufer hört das typische Klingeln wenn die Gegenseite nicht abnimmt
|
sleep int(AttrVal($name, "sip_ringtime", 3)); #Anrufer hört das typische Klingeln wenn die Gegenseite nicht abnimmt
|
||||||
|
}
|
||||||
},
|
},
|
||||||
filter => \&$sub_filter,
|
filter => \&$sub_filter,
|
||||||
cb_established => sub {
|
cb_established => sub {
|
||||||
(my $status,$call) = @_;
|
(my $status,$call) = @_;
|
||||||
SIP_telnet($hash,"set $name caller_state established\nexit\n");
|
if (!$block_it)
|
||||||
return 1;
|
{ SIP_telnet($hash,"set $name caller_state established\nexit\n"); return 1; }
|
||||||
|
else {
|
||||||
|
sleep 1;
|
||||||
|
#SIP_telnet($hash, "set $name caller none\nset $name caller_state waitting\nexit\n") ;
|
||||||
|
return 0; }
|
||||||
} # sobald invite verlassen wird, wird in cb_established verzweigt
|
} # sobald invite verlassen wird, wird in cb_established verzweigt
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -983,8 +1045,8 @@ sub SIP_ListenStart($)
|
|||||||
$dtmf_loop = 0; # beende die inner loop
|
$dtmf_loop = 0; # beende die inner loop
|
||||||
$byebye = 1;
|
$byebye = 1;
|
||||||
}
|
}
|
||||||
else { $dtmf_loop = (AttrVal($name,"sip_dtmf_loop","once")) ? 0 : 1;
|
else { $dtmf_loop = ((AttrVal($name,"sip_dtmf_loop","once") eq 'once')) ? 0 : 1;
|
||||||
SIP_telnet($hash, "set $name caller none\nset $name caller_state hangup\nexit\n") if(!$dtmf_loop);
|
SIP_telnet($hash, "set $name caller_state hangup\nexit\n") if(!$dtmf_loop);
|
||||||
} # führt ggf. zum Schleifenende
|
} # führt ggf. zum Schleifenende
|
||||||
} # end inner loop
|
} # end inner loop
|
||||||
|
|
||||||
@ -1000,7 +1062,7 @@ sub SIP_ListenStart($)
|
|||||||
{
|
{
|
||||||
$ua->listen(
|
$ua->listen(
|
||||||
cb_create => \&$sub_create,
|
cb_create => \&$sub_create,
|
||||||
cb_invite => \&$sub_invite,
|
cb_invite => \&$sub_invite_wfp,
|
||||||
filter => \&$sub_filter,
|
filter => \&$sub_filter,
|
||||||
recv_bye => \&$sub_bye,
|
recv_bye => \&$sub_bye,
|
||||||
init_media => $ua->rtp('send_recv',($msg3) ? $msg3 : $send_something),
|
init_media => $ua->rtp('send_recv',($msg3) ? $msg3 : $send_something),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user