From 5f1ee2632d7e9211514376a104203114ae7a0374 Mon Sep 17 00:00:00 2001 From: Gerhard Jungwirth Date: Tue, 29 Nov 2016 15:55:53 +0100 Subject: [PATCH] TT#6831 decode utf-16 for incoming sms they may come in as utf-8 or utf-16. the latter causes catalyst to die per default, which we circumvent. then we manually decode the text in utf-16. + fix bug where last jumps out of subrouting causing an exception Change-Id: I9df15317f4438b4205f7f0f6af26df8f85ae0614 --- lib/NGCP/Panel.pm | 6 + lib/NGCP/Panel/Controller/InternalSms.pm | 167 ++++++++++++----------- 2 files changed, 95 insertions(+), 78 deletions(-) diff --git a/lib/NGCP/Panel.pm b/lib/NGCP/Panel.pm index a3c840b33d..43fc536392 100644 --- a/lib/NGCP/Panel.pm +++ b/lib/NGCP/Panel.pm @@ -49,6 +49,12 @@ for my $path(qw#./logging.conf /etc/ngcp-panel/logging.conf#) { } $logger_config = $panel_config unless(defined $logger_config); +sub handle_unicode_encoding_exception { + my ($self, $exception_context) = @_; + $self->log->debug(">> handle_unicode_encoding_exception: ", $exception_context->{error_msg}); + return $exception_context->{param_value}; +} + __PACKAGE__->config( name => 'NGCP::Panel', # Disable deprecated behavior needed by old applications diff --git a/lib/NGCP/Panel/Controller/InternalSms.pm b/lib/NGCP/Panel/Controller/InternalSms.pm index 5701815ff9..7bf785d19e 100644 --- a/lib/NGCP/Panel/Controller/InternalSms.pm +++ b/lib/NGCP/Panel/Controller/InternalSms.pm @@ -5,6 +5,7 @@ use Sipwise::Base; use parent 'Catalyst::Controller'; use Time::Period; use File::FnMatch qw(:fnmatch); +use Encode qw/decode/; #sub auto :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) { sub auto { @@ -26,6 +27,14 @@ sub receive :Chained('list') :PathPart('receive') :Args(0) { my $to = $c->req->params->{to} // ""; my $text = $c->req->params->{text} // ""; my $token = $c->req->params->{auth_token} // ""; + my $charset = $c->req->params->{charset} // ""; + + my $decoded_text = ''; + if ($charset && $charset =~ m/^utf-16/i) { + $decoded_text = decode($charset, $text); + $c->log->debug("decoded sms text using encoding $charset"); + $text = $decoded_text; + } unless ($from && $to && $text && $token) { $c->log->error("Missing one param of: from ($from), to ($to), text ($text), auth_token ($token)."); @@ -66,99 +75,101 @@ sub receive :Chained('list') :PathPart('receive') :Args(0) { }); # check for cfs + { - my $cf_maps = $c->model('DB')->resultset('voip_cf_mappings')->search({ - subscriber_id => $prov_dbalias->subscriber_id, - type => 'cfs' - }); - unless($cf_maps->count) { - $c->log->info("No cfs for inbound sms from $from to $to found."); - last; - } + my $cf_maps = $c->model('DB')->resultset('voip_cf_mappings')->search({ + subscriber_id => $prov_dbalias->subscriber_id, + type => 'cfs' + }); + unless($cf_maps->count) { + $c->log->info("No cfs for inbound sms from $from to $to found."); + last; + } - my $dset; - foreach my $map($cf_maps->all) { - # check source set - my $source_pass = 1; - if($map->source_set) { - $source_pass = 0; - foreach my $source($map->source_set->voip_cf_sources->all) { - $c->log->info(">>>> checking $from against ".$source->source); - if(fnmatch($source->source, $from)) { - $c->log->info(">>>> matched $from against ".$source->source.", pass"); - $source_pass = 1; - last; + my $dset; + foreach my $map($cf_maps->all) { + # check source set + my $source_pass = 1; + if($map->source_set) { + $source_pass = 0; + foreach my $source($map->source_set->voip_cf_sources->all) { + $c->log->info(">>>> checking $from against ".$source->source); + if(fnmatch($source->source, $from)) { + $c->log->info(">>>> matched $from against ".$source->source.", pass"); + $source_pass = 1; + last; + } } } - } - if($source_pass) { - $c->log->info(">>>> source check for $from passed, continue with time check"); - } else { - $c->log->info(">>>> source check for $from failed, trying next map entry"); - next; - } + if($source_pass) { + $c->log->info(">>>> source check for $from passed, continue with time check"); + } else { + $c->log->info(">>>> source check for $from failed, trying next map entry"); + next; + } - my $time_pass = 1; - if($map->time_set) { - $time_pass = 0; - foreach my $time($map->time_set->voip_cf_periods->all) { - my $timestring = join(' ', - $time->year // '', - $time->month // '', - $time->mday // '', - $time->wday // '', - $time->hour // '', - $time->minute // '' - ); - $c->log->info(">>>> checking $now against ".$timestring); - if(inPeriod($now, $timestring)) { - $c->log->info(">>>> matched $now against ".$timestring.", pass"); - $time_pass = 1; - last; + my $time_pass = 1; + if($map->time_set) { + $time_pass = 0; + foreach my $time($map->time_set->voip_cf_periods->all) { + my $timestring = join(' ', + $time->year // '', + $time->month // '', + $time->mday // '', + $time->wday // '', + $time->hour // '', + $time->minute // '' + ); + $c->log->info(">>>> checking $now against ".$timestring); + if(inPeriod($now, $timestring)) { + $c->log->info(">>>> matched $now against ".$timestring.", pass"); + $time_pass = 1; + last; + } } } + if($time_pass) { + $c->log->info(">>>> time check for $now passed, use destination set"); + $dset = $map->destination_set; + last; + } else { + $c->log->info(">>>> time check for $now failed, trying next map entry"); + next; + } } - if($time_pass) { - $c->log->info(">>>> time check for $now passed, use destination set"); - $dset = $map->destination_set; + + unless($dset) { + $c->log->info(">>>> checks failed, bailing out without forwarding"); last; - } else { - $c->log->info(">>>> time check for $now failed, trying next map entry"); - next; } - } - unless($dset) { - $c->log->info(">>>> checks failed, bailing out without forwarding"); - last; - } + $c->log->info(">>>> proceed sms forwarding"); - $c->log->info(">>>> proceed sms forwarding"); - - unless($dset->voip_cf_destinations->first) { - $c->log->info(">>>> detected cf mapping has no destinations in destination set"); - last; - } - my $dst = $dset->voip_cf_destinations->first->destination; - $dst =~ s/^sip:(.+)\@.+$/$1/; - $c->log->info(">>>> forward sms to $dst"); - - # feed back into kannel - my $error_msg; - NGCP::Panel::Utils::SMS::send_sms( - c => $c, - caller => $to, # use the original to as new from + unless($dset->voip_cf_destinations->first) { + $c->log->info(">>>> detected cf mapping has no destinations in destination set"); + last; + } + my $dst = $dset->voip_cf_destinations->first->destination; + $dst =~ s/^sip:(.+)\@.+$/$1/; + $c->log->info(">>>> forward sms to $dst"); + + # feed back into kannel + my $error_msg; + NGCP::Panel::Utils::SMS::send_sms( + c => $c, + caller => $to, # use the original to as new from + callee => $dst, + text => $text, + err_code => sub {$error_msg = shift;}, + ); + my $fwd_item = $c->model('DB')->resultset('sms_journal')->create({ + subscriber_id => $prov_dbalias->subscriber_id, + direction => "forward", + caller => $to, callee => $dst, text => $text, - err_code => sub {$error_msg = shift;}, - ); - my $fwd_item = $c->model('DB')->resultset('sms_journal')->create({ - subscriber_id => $prov_dbalias->subscriber_id, - direction => "forward", - caller => $to, - callee => $dst, - text => $text, }); + } }); } catch($e) { $c->log->error("Failed to store received SMS message.");