@ -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." ) ;