From 9bd363fdfb71fd99fdededca3ede0f928e0c66e5 Mon Sep 17 00:00:00 2001 From: Andreas Granig Date: Wed, 28 Nov 2018 17:16:58 +0100 Subject: [PATCH] TT#47976 Also use MWI PUBLISH from vmnotify Change-Id: I4c139a116a3ebe0fccd8b191102e4473e196d4fe --- vmnotify | 133 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 102 insertions(+), 31 deletions(-) diff --git a/vmnotify b/vmnotify index e76d235..aeb221f 100755 --- a/vmnotify +++ b/vmnotify @@ -22,6 +22,7 @@ use HTTP::Request; use LWP::UserAgent; use JSON; use IO::Socket::SSL; +use DBI; unless (scalar @ARGV) { print < - voicemail context (default: "default") - - destination user + - mailbox number - amount of new messages [old messages] - amount of old messages [urgent messages] - amount of urgent messages @@ -80,6 +81,17 @@ EOF my $log = Log::Log4perl->get_logger("vmnotify"); my %data = (); +my $dsn = "DBI:mysql:database=kamailio;host=$CONFIG{DB_HOST};port=$CONFIG{DB_PORT}"; +my $dbh = DBI->connect($dsn, $CONFIG{DB_USER}, $CONFIG{DB_PASS}) or die + "Failed to connect to central db: $DBI::errstr"; +my $sth_etag = $dbh->prepare( + "select etag from presentity where username=? and domain=? ". + "and event='message-summary' order by received_time desc limit 1" +) or die "Failed to prepare etag query: $DBI::errstr"; +my $sth_userdom = $dbh->prepare( + "select username, domain from dbaliases where alias_username=?" +) or die "Failed to prepare userdom query: $DBI::errstr"; + #---------------------------------------------------------------------- sub log_syslog { my $str = shift; @@ -103,10 +115,10 @@ sub gen_branchid { map { $list[int(rand($#list))] } (1..8); } -sub send_mwi_notify { - - open(my $fh, "<", $CONFIG{SIPFILE}) - or die "Cannot open file: $CONFIG{SIPFILE}"; +sub load_mwi_file { + my $path = shift; + open(my $fh, "<", $path) + or die "Cannot open file '$path': $!"; binmode $fh; my $mwi; while (<$fh>) { @@ -114,29 +126,12 @@ sub send_mwi_notify { $mwi .= $_; } close $fh; + return $mwi; +} - die "Empty MWI. Cannot send SIP MWI notification\n" unless $mwi; - - my $log_str = sprintf < "Messages-Waiting: ". ($data{new} ? "yes" : "no"), - body_vm => "Voice-Message: $data{new}/$data{old} ($data{urgent}/0)", - call_id => $data{callid}, - mbid => $data{user}, - branch => gen_branchid(), - user => $data{user}, - dsthost => $CONFIG{SERVER}, - - ); - - $macros{bodylen} = 2+length($macros{body_mw})+2+length($macros{body_vm})+2; - - map { $mwi =~ s/\$$_\$/$macros{$_}/gi; } keys %macros; +sub send_mwi { + my $log_str = shift; + my $mwi = shift; my $sock = IO::Socket::INET->new(PeerAddr => $CONFIG{SERVER}, LocalAddr => $CONFIG{LOCAL_IP}, @@ -150,6 +145,44 @@ EOF or die sprintf "Cannot send %s error=%s\n", $log_str, $ERRNO; $sock->close(); +} + +sub send_mwi_notify { + my $macros = shift; + my $mwi = load_mwi_file($CONFIG{SIPFILE}); + die "Empty MWI. Cannot send SIP MWI notification\n" unless $mwi; + + my $log_str = sprintf <{bodylen} = 2+length($macros->{body_mw})+2+length($macros->{body_vm})+2; + map { $mwi =~ s/\$$_\$/$macros->{$_}/gi; } keys %{ $macros }; + send_mwi($log_str, $mwi); + + $log->debug($log_str); + + return; +} + +sub send_mwi_publish { + my $macros = shift; + my $mwi = load_mwi_file($CONFIG{SIPPUBLISHFILE}); + die "Empty PUBLISH MWI. Cannot publish SIP MWI notification\n" unless $mwi; + + my $log_str = sprintf <{bodylen} = 2+length($macros->{body_mw})+2+length($macros->{body_vm})+2; + map { $mwi =~ s/\$$_\$/$macros->{$_}/gi; } keys %{ $macros }; + $mwi =~ s/\r\nSTRIP\r\n/\r\n/g; + $log->debug($mwi); + send_mwi($log_str, $mwi); $log->debug($log_str); @@ -164,7 +197,7 @@ sub send_ext_notify { prefix => 'voicemail', suffix => 'notify', caller => $data{from}, - callee => $data{user}, + callee => $data{mailbox}, callid => $data{callid}, token => '', ); @@ -191,7 +224,7 @@ sub send_ext_notify { my $json = { caller => $data{from}, - callee => $data{user}, + callee => $data{mailbox}, recording_id => $data{msgnum}, timestamp => $data{date}, duration => $data{duration}, @@ -216,12 +249,31 @@ EOF return; } +sub get_etag { + my $user = shift; + my $domain = shift; + $sth_etag->execute($user, $domain) + or die "Failed to load ETag for $user\@$domain"; + my ($etag) = $sth_etag->fetchrow_array(); + $sth_etag->finish(); + return $etag; +} + +sub get_user_domain { + my $alias = shift; + $sth_userdom->execute($alias) + or die "Failed to load user and domain for $alias"; + my ($user, $domain) = $sth_userdom->fetchrow_array(); + $sth_userdom->finish(); + return ($user, $domain); +} + sub main { eval { die "Incorrect arguments list" if $#ARGV < 2; my $idx = 0; - foreach my $arg (qw(context user new old urgent)) { + foreach my $arg (qw(context mailbox new old urgent)) { $data{$arg} = $ARGV[$idx] // 0; $idx++; } @@ -233,8 +285,27 @@ sub main { } $data{callid} = gen_callid().'@voip.sipwise.local'; + ($data{user}, $data{domain}) = get_user_domain($data{mailbox}); + my $etag = get_etag($data{user}, $data{domain}); + my $sipifmatch = defined $etag ? "SIP-If-Match: $etag" : "STRIP"; + + my %macros = ( + body_mw => "Messages-Waiting: ". ($data{new} ? "yes" : "no"), + body_vm => "Voice-Message: $data{new}/$data{old} ($data{urgent}/0)", + call_id => $data{callid}, + branch => gen_branchid(), + user => $data{user}, + domain => $data{domain}, + sipifmatch => $sipifmatch, + ); + + send_mwi_notify(\%macros); + + # use a different call-id for publish vs the notify above to make traces more clear + # that they actually don't belong together + $macros{call_id} = gen_callid().'@voip.sipwise.local'; + send_mwi_publish(\%macros); - send_mwi_notify(); if ($extended && $CONFIG{EXT_NOTIFY} && $CONFIG{EXT_NOTIFY} eq "yes") { send_ext_notify();