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:
Wzut 2017-03-24 19:25:19 +00:00
parent 68c015c7cd
commit 8dc972caa8

View File

@ -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),