TT#8901 support soundsets

* add invite_allowip_soundset as example

Change-Id: I08d3918b91ea4baa64f7bddfffee18b2374647a3
changes/86/10686/5
Victor Seva 9 years ago
parent c3afdeaf28
commit 1e66618bed

@ -125,6 +125,12 @@ function create_voip_prefs
"${BIN_DIR}/create_ncos.pl" "${SCEN_CHECK_DIR}/ncos.yml"
fi
if [ -f "${SCEN_CHECK_DIR}/soundsets.yml" ]; then
echo "$(date) - Creating soundsets"
"${BIN_DIR}/create_soundsets.pl" \
"${SCEN_CHECK_DIR}/soundsets.yml" "${SCEN_CHECK_DIR}/scenario_ids.yml"
fi
if [ -f "${SCEN_CHECK_DIR}/peer.yml" ]; then
echo "$(date) - Creating peers"
"${BIN_DIR}/create_peers.pl" \
@ -176,6 +182,11 @@ function delete_voip
sed -e "s:$(cat "${SCEN_CHECK_DIR}/hosts")::" -i /etc/hosts
rm "${SCEN_CHECK_DIR}/hosts"
fi
if [ -f "${SCEN_CHECK_DIR}/soundsets.yml" ]; then
echo "$(date) - Deleting soundsets"
"${BIN_DIR}/create_soundsets.pl" -delete "${SCEN_CHECK_DIR}/soundsets.yml"
fi
}
function delete_locations

@ -0,0 +1,140 @@
#!/usr/bin/perl
#
# Copyright: 2013-2016 Sipwise Development Team <support@sipwise.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This package is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# On Debian systems, the complete text of the GNU General
# Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".
#
use strict;
use warnings;
use English;
use Getopt::Long;
use Cwd 'abs_path';
use Config::Tiny;
use Sipwise::API qw(all);
use YAML qw{ DumpFile LoadFile };
use File::Basename qw{ basename };
my $config = Config::Tiny->read('/etc/default/ngcp-api');
my $opts;
if ($config) {
$opts = {};
$opts->{host} = $config->{_}->{NGCP_API_IP};
$opts->{port} = $config->{_}->{NGCP_API_PORT};
$opts->{sslverify} = $config->{_}->{NGCP_API_SSLVERIFY};
}
my $api = Sipwise::API->new($opts);
$opts = $api->opts;
my $del = 0;
my $ids;
my $ids_path;
sub usage {
return "Usage:\n$PROGRAM_NAME scenario.yml scenarios_ids.yml\n".
"Options:\n".
" -delete\n".
" -d debug\n".
" -h this help\n";
}
my $help = 0;
GetOptions ("h|help" => \$help,
"d|debug" => \$opts->{verbose},
"delete" => \$del)
or die("Error in command line arguments\n".usage());
die(usage()) unless (!$help);
if(!$del) {
die("Error: wrong number of arguments\n".usage()) unless ($#ARGV == 1);
} else {
die("Error: wrong number of arguments\n".usage()) unless ($#ARGV == 0);
}
sub manage_soundfiles
{
my ($data, $id) = @_;
foreach my $sf (sort keys %{$data->{sounds}})
{
my $sf_data = $data->{sounds}->{$sf};
my $filename = $sf_data->{filename};
$sf_data->{set_id} = $data->{id};
$sf_data->{handle} = $sf;
$sf_data->{filename} = basename($filename, '.wav');
$api->upload_soundfile($sf_data, abs_path($filename));
print "[$filename] uploaded\n";
}
return;
}
sub do_create
{
my $data = shift;
foreach my $st (sort keys %{$data->{soundsets}})
{
my $st_data = {
name => $st,
reseller_id => $data->{soundsets}->{$st}->{reseller_id}
};
$data->{soundsets}->{$st}->{id} = $api->check_soundset_exists($st_data);
if(defined $data->{soundsets}->{$st}->{id}) {
print "soundset[$st] already there [$data->{soundsets}->{$st}->{id}]\n";
} else {
$data->{soundsets}->{$st}->{id} = $api->create_soundset($st_data);
print "soundset [$st]: created [$data->{soundsets}->{$st}->{id}]\n";
manage_soundfiles($data->{soundsets}->{$st});
}
$ids->{soundsets}->{$st}->{id} = $data->{soundsets}->{$st}->{id};
}
return;
}
sub do_delete
{
my $data = shift;
foreach my $st (sort keys %{$data->{soundsets}})
{
my $st_data = {
name => $st,
reseller_id => $data->{soundsets}->{$st}->{reseller_id}
};
$data->{soundsets}->{$st}->{id} = $api->check_soundset_exists($st_data);
if(defined $data->{soundsets}->{$st}->{id}) {
$api->delete_soundset($data->{soundsets}->{$st}->{id});
print "delete soundset[$st] -> [$data->{soundsets}->{$st}->{id}]\n";
}
}
return;
}
sub main {
my $r = shift;
if ($del) {
return do_delete($r);
} else {
return do_create($r);
}
}
if(! $del) {
$ids_path = abs_path($ARGV[1]);
$ids = LoadFile($ids_path);
}
main(LoadFile(abs_path($ARGV[0])), $ids);
if(! $del) {
DumpFile($ids_path, $ids);
}

@ -54,6 +54,23 @@ GetOptions ("h|help" => \$help, "d|debug" => \$opts->{verbose})
die(usage()) unless (!$help);
die("Error: wrong number of arguments\n".usage()) unless ($#ARGV == 0);
sub resolve_ids {
my $prefs = shift;
return $prefs;
my $key;
if(defined $prefs->{sound_set}) {
$key = $prefs->{sound_set};
my $id = $api->check_soundset_exists({name => $key});
if($id) {
$prefs->{sound_set} = $id;
print "soundset[$key] => $prefs->{sound_set}\n";
} else {
die("soundset[$key] not found\n");
}
}
return $prefs;
}
sub merge
{
my $a = shift;
@ -163,21 +180,20 @@ sub set_peer_preferences
sub main {
my $prefs = shift;
my $peers;
my $rule_set;
for my $key (keys %{$prefs})
{
my $prefs_id = resolve_ids($prefs->{$key});
print "processing $key\n";
if ( $key =~ /@/ ) {
my @fields = split /@/, $key;
if (!$fields[0]) {
set_domain_preferences($fields[1], $prefs->{$key});
set_domain_preferences($fields[1], $prefs_id);
} else {
set_subscriber_preferences($fields[0], $fields[1], $prefs->{$key});
set_subscriber_preferences($fields[0], $fields[1], $prefs_id);
}
} else {
set_peer_preferences($key, $prefs->{$key});
set_peer_preferences($key, $prefs_id);
}
}
exit;
@ -197,5 +213,4 @@ sub get_json {
}
my $cf = get_json($ARGV[0]);
main($cf);

1
debian/control vendored

@ -11,6 +11,7 @@ Package: kamailio-config-tests
Architecture: all
Depends:
curl,
libfile-slurp-perl,
libgraphviz-perl,
libjson-perl,
libtemplate-perl,

@ -29,6 +29,7 @@ use LWP::UserAgent;
use IO::Socket::SSL;
use URI;
use Data::Dumper;
use File::Slurp;
my $opts_default = {
host => '127.0.0.1',
@ -90,6 +91,21 @@ sub do_request {
return $res;
}
sub _do_binary_request {
my ($self, $ua, $url, $filename, $ct) = @_;
my $content;
my $req = HTTP::Request->new('POST', $url);
$req->header('Content-Type' => $ct);
$req->header('Prefer' => 'return=representation');
$req->content(read_file($filename));
my $res = $ua->request($req);
if(!$res->is_success) {
print "$url\n";
}
return $res;
}
sub do_query {
my $self = shift;
my $ua = shift;
@ -645,4 +661,42 @@ sub delete_ncoslnpcarrier {
return $self->_delete($urldata);
}
sub check_soundset_exists {
my ($self, $data) = @_;
my $urldata = "/api/soundsets/";
my $collection_id = 'ngcp:soundsets';
return $self->_exists($data, $urldata, $collection_id);
}
sub create_soundset {
my ($self, $data) = @_;
my $urldata = '/api/soundsets/';
return $self->_create($data, $urldata);
}
sub delete_soundset {
my ($self, $id) = @_;
my $urldata = "/api/soundsets/${id}";
return $self->_delete($urldata);
}
sub upload_soundfile {
my ($self, $data, $filepath) = @_;
my $urldata = "/api/soundfiles/?".
"filename=$data->{filename}&handle=$data->{handle}".
"&set_id=$data->{set_id}&loopplay=$data->{loopplay}";
my $urlbase = 'https://'.$self->{opts}->{host}.':'.$self->{opts}->{port};
my $ua = $self->create_ua();
my $res = $self->_do_binary_request($ua, $urlbase.$urldata,
$filepath, 'audio/x-wav');
if(! $res->is_success) {
die $res->as_string;
}
return;
}
1;

@ -0,0 +1,30 @@
flow:
- start|DEFAULT_ROUTE:
- start|ROUTE_NET_INFO:
- return|ROUTE_NET_INFO:
- start|ROUTE_PRX_REQUEST:
- start|ROUTE_INITVARS:
- return|ROUTE_INITVARS:
- start|ROUTE_INVITE:
- start|ROUTE_LOAD_CALLEE_DOMAIN_PREF:
- start|ROUTE_CLEAR_CALLEE_DOMAIN_PREF:
- return|ROUTE_CLEAR_CALLEE_DOMAIN_PREF:
- return|ROUTE_LOAD_CALLEE_DOMAIN_PREF:
- start|ROUTE_FIND_CALLER:
- start|ROUTE_AUTH:
- exit|ROUTE_AUTH:
sip_in:
- '^INVITE'
- 'Contact: sip:testuser1002@'
- 'CSeq: 1 INVITE'
- 'Max-Forwards: 69'
- 'Content-Type: application/sdp'
sip_out:
- [
'^SIP/2.0 100 Trying',
'CSeq: 1 INVITE'
]
- [
'^SIP/2.0 407 Proxy Authentication Required',
'CSeq: 1 INVITE'
]

@ -0,0 +1,98 @@
flow:
- start|DEFAULT_ROUTE:
- start|ROUTE_NET_INFO:
- return|ROUTE_NET_INFO:
- start|ROUTE_PRX_REQUEST:
- start|ROUTE_INITVARS:
- return|ROUTE_INITVARS:
- start|ROUTE_INVITE:
- start|ROUTE_LOAD_CALLEE_DOMAIN_PREF:
- start|ROUTE_CLEAR_CALLEE_DOMAIN_PREF:
- return|ROUTE_CLEAR_CALLEE_DOMAIN_PREF:
- return|ROUTE_LOAD_CALLEE_DOMAIN_PREF:
- start|ROUTE_FIND_CALLER:
- start|ROUTE_AUTH:
- start|ROUTE_AUTH_HELPER:
$fd: spce.test
$var(realm_user): testuser1002
$var(realm_domain): spce.test
- return|ROUTE_AUTH_HELPER:
$avp(orig_acc_caller_user): ['testuser1002']
$avp(orig_acc_caller_domain): ['spce.test']
- start|ROUTE_ADD_CALLINFO_REPLY:
- start|ROUTE_ADD_CALLINFO_CALLER_PRIMARY:
- return|ROUTE_ADD_CALLINFO_CALLER_PRIMARY:
- return|ROUTE_ADD_CALLINFO_REPLY:
- return|ROUTE_AUTH:
- return|ROUTE_FIND_CALLER:
- start|ROUTE_LOAD_CALLER_PREF:
- start|ROUTE_CLEAR_CALLER_PREF:
- return|ROUTE_CLEAR_CALLER_PREF:
- start|ROUTE_LOAD_CALLER_CONTRACT_PREF:
- return|ROUTE_LOAD_CALLER_CONTRACT_PREF:
- return|ROUTE_LOAD_CALLER_PREF:
$xavp(caller_usr_prefs[0]=>allowed_ips_grp[*]): '\d+'
$xavp(caller_real_prefs[0]=>allowed_ips_grp[*]): '\d+'
- start|ROUTE_DLG_MANAGE:
- return|ROUTE_DLG_MANAGE:
- start|ROUTE_ACC_FAILURE:
- start|ROUTE_ACC_CALLER:
- return|ROUTE_ACC_CALLER:
- start|ROUTE_ACC_CALLEE:
- return|ROUTE_ACC_CALLEE:
- return|ROUTE_ACC_FAILURE:
- start|ROUTE_EARLY_REJECT:
- start|ROUTE_TO_APPSRV:
- start|ROUTE_LOAD_APPSRV:
- start|ROUTE_CNT_DLG_CHECK:
- return|ROUTE_CNT_DLG_CHECK:
- return|ROUTE_LOAD_APPSRV:
- start|ROUTE_OUTBOUND:
- start|BRANCH_ROUTE_NO_SBC:
- start|ROUTE_BRANCH_ACC_RTP:
- return|ROUTE_BRANCH_ACC_RTP:
- start|ROUTE_FILTER_PRACK:
- return|ROUTE_FILTER_PRACK:
- start|ROUTE_ADD_CALLINFO:
- start|ROUTE_ADD_CALLINFO_CALLER_PRIMARY:
- return|ROUTE_ADD_CALLINFO_CALLER_PRIMARY:
- start|ROUTE_ADD_CALLINFO_CALLEE_PRIMARY:
- return|ROUTE_ADD_CALLINFO_CALLEE_PRIMARY:
- return|ROUTE_ADD_CALLINFO:
- return|BRANCH_ROUTE_NO_SBC:
- return|BRANCH_ROUTE_NO_SBC:
- exit|ROUTE_OUTBOUND:
sip_in:
- '^INVITE'
- 'Contact: sip:testuser1002@'
- 'CSeq: 2 INVITE'
- 'Max-Forwards: 69'
- 'Content-Type: application/sdp'
- 'Proxy-Authorization: Digest username="testuser1002"'
sip_out:
- [
'^SIP/2.0 100 Trying',
'CSeq: 2 INVITE',
'From: <sip:testuser1002@'
]
- [
'^SIP/2.0 101 Connecting',
'CSeq: 2 INVITE',
'From: <sip:testuser1002@'
]
- [
'^INVITE sip:earlyannounce@app.local SIP/2.0',
'From: <sip:testuser1002@',
'To: <sip:testuser1003@',
'CSeq: 2 INVITE',
'Contact: sip:testuser1002@127.126.0.1:\d+',
'Max-Forwards: 68',
'Content-Type: application/sdp',
'Content-Length: \d+',
'P-App-Param: audio_id=\d+;play_looped=no;fr_code=403;fr_reason=Unauthorized IP detected',
'P-App-Name: early_dbprompt',
'P-Caller-UUID: [% spce_test.testuser1002.uuid %]',
'P-Callee-UUID: [% spce_test.testuser1002.uuid %]',
'P-NGCP-Caller-Info: <sip:testuser1002@spce.test>;ip=127.126.0.1;port=\d+;primary=4311002',
'P-NGCP-Callee-Info: <sip:@>;ip=127.0.0.1;port=5080;primary=4311002',
]

@ -0,0 +1,19 @@
flow:
- start|REPLY_ROUTE_NAT:
- exit|REPLY_ROUTE_NAT:
sip_in:
- '^SIP/2.0 183 Progress'
- 'From: <sip:testuser1002@'
- 'To: <sip:testuser1003@'
- 'CSeq: 2 INVITE'
- 'Contact: <sip:(earlyannounce@)?127.0.0.1:5080(;transport=udp)?>'
- 'Content-Type: application/sdp'
- 'Content-Length: \d+'
sip_out:
- [
'^SIP/2.0 183 Progress',
'Contact: <sip:(earlyannounce@)?127.0.0.1:5080(;transport=udp)?>',
'Content-Type: application/sdp',
'Content-Length: \d+',
'P-Out-Socket: udp:127.0.0.1:5060'
]

@ -0,0 +1,33 @@
flow:
- start|REPLY_ROUTE_NAT:
- start|FAILURE_ROUTE_EARLY_REJECT:
- start|ROUTE_STOP_RTPPROXY_BRANCH:
- start|ROUTE_RESTORE_CLUSTERSET:
- return|ROUTE_RESTORE_CLUSTERSET:
- return|ROUTE_STOP_RTPPROXY_BRANCH:
- exit|FAILURE_ROUTE_EARLY_REJECT:
- start|dialog:failed:
- return|dialog:failed:
$avp(lua_dlg_profile): None
- return|dialog:failed:
sip_in:
- '^SIP/2.0 403 Unauthorized IP detected'
- 'From: <sip:testuser1002@spce.test>;tag='
- 'To: <sip:testuser1003@spce.test>;tag='
- 'CSeq: 2 INVITE'
- 'Content-Length: 0'
sip_out:
- [
'^ACK sip:earlyannounce@app.local SIP/2.0',
'From: <sip:testuser1002@spce.test>;tag=',
'To: <sip:testuser1003@spce.test>;tag=',
'CSeq: 2 ACK',
'Max-Forwards: 68',
'Content-Length: 0'
]
- [
'^SIP/2.0 403 Unauthorized IP detected',
'CSeq: 2 INVITE',
'Content-Length: 0',
'P-Out-Socket: udp:127.0.0.1:5060'
]

@ -0,0 +1,23 @@
flow:
- start|DEFAULT_ROUTE:
- start|ROUTE_NET_INFO:
- return|ROUTE_NET_INFO:
- start|ROUTE_PRX_REQUEST:
- start|ROUTE_INITVARS:
- return|ROUTE_INITVARS:
- start|ROUTE_LOCAL:
- return|ROUTE_LOCAL:
sip_in:
- '^ACK sip:testuser1003@spce.test:5060 SIP/2.0'
- 'From: <sip:testuser1002@spce.test>;tag='
- 'To: <sip:testuser1003@spce.test>;tag='
- 'CSeq: 2 ACK'
- 'Contact: sip:testuser1002@127.126.0.1:\d+'
- 'Max-Forwards: 69'
- 'Content-Length: 0'
- 'P-NGCP-Src-Ip: 127.126.0.1'
- 'P-NGCP-Src-Port: \d+'
- 'P-NGCP-Src-Proto: udp'
- 'P-NGCP-Src-Af: 4'
- 'P-Sock-Info: udp:127.0.0.1:5060'
sip_out: []

@ -0,0 +1,11 @@
{
"@spce.test": {
"sound_set": "default_soundset"
},
"testuser1002@spce.test": {
"allowed_ips": [
"1.2.3.4"
],
"cli": 4311002
}
}

@ -0,0 +1,38 @@
test_uuid: invite_allowip_soundset
domains:
'spce.test':
reseller_id: 1
customers:
'customer.test':
contacts:
- email: "customer.test@spce.test"
reseller_id: 1
details:
status: 'active'
type: 'sipaccount'
billing_profile_id: 1
reseller_id: 1
subscribers:
spce.test:
testuser1003:
customer: 'customer.test'
password: testuser
cc: 43
ac: 1
sn: 1003
testuser1002:
customer: 'customer.test'
password: testuser
cc: 43
ac: 1
sn: 1002
scenarios:
- ip: 127.126.0.1
username: testuser1002
domain: spce.test
responders:
- ip: 127.1.0.1
username: testuser1003
domain: spce.test
register: no
active: no

@ -0,0 +1,110 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<scenario name="Sipwise NGCP Benchmark UAC Caller">
<send start_rtd="1" start_rtd="2">
<![CDATA[
INVITE sip:[field0 file="callee.csv" line=0]@[field3 file="callee.csv" line=0] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
From: <sip:[field0 file="caller.csv" line=0]@[field2 file="caller.csv" line=0]>;tag=[pid]SIPpTag00[call_number]
To: <sip:[field0 file="callee.csv" line=0]@[field3 file="callee.csv" line=0]>
Call-ID: NGCP%[field4 file="callee.csv" line=0]%///[call_id]
CSeq: 1 INVITE
Contact: sip:[field0 file="caller.csv" line=0]@[local_ip]:[local_port]
Max-Forwards: 70
Content-Type: application/sdp
Content-Length: [len]
v=0
o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
s=-
c=IN IP[media_ip_type] [media_ip]
t=0 0
m=audio [media_port] RTP/AVP 8
a=rtpmap:8 PCMA/8000
a=ptime:50
]]>
</send>
<recv response="100" rtd="1" optional="true">
</recv>
<recv response="407" rtd="2" auth="true"/>
<send>
<![CDATA[
ACK sip:[field0 file="callee.csv" line=0]@[field3 file="callee.csv" line=0]:[remote_port] SIP/2.0
[last_Via:]
From: <sip:[field0 file="caller.csv" line=0]@[field2 file="caller.csv" line=0]>;tag=[pid]SIPpTag00[call_number]
To: <sip:[field0 file="callee.csv" line=0]@[field3 file="callee.csv" line=0]>[peer_tag_param]
Call-ID: NGCP%[field4 file="callee.csv" line=0]%///[call_id]
CSeq: 1 ACK
Contact: sip:[field0 file="caller.csv" line=0]@[local_ip]:[local_port]
Max-Forwards: 70
Content-Length: 0
]]>
</send>
<pause milliseconds="500"/>
<send start_rtd="3">
<![CDATA[
INVITE sip:[field0 file="callee.csv" line=0]@[field3 file="callee.csv" line=0] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
From: <sip:[field0 file="caller.csv" line=0]@[field2 file="caller.csv" line=0]>;tag=[pid]SIPpTag00[call_number]
To: <sip:[field0 file="callee.csv" line=0]@[field3 file="callee.csv" line=0]>
Call-ID: NGCP%[field4 file="callee.csv" line=0]%///[call_id]
CSeq: 2 INVITE
Contact: sip:[field0 file="caller.csv" line=0]@[local_ip]:[local_port]
Max-Forwards: 70
[field1 file="caller.csv" line=0]
Content-Type: application/sdp
Content-Length: [len]
v=0
o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
s=-
c=IN IP[media_ip_type] [media_ip]
t=0 0
m=audio [media_port] RTP/AVP 8
a=rtpmap:8 PCMA/8000
a=ptime:50
]]>
</send>
<recv response="100" optional="true">
</recv>
<recv response="183">
</recv>
<recv response="403" rtd="3">
</recv>
<send>
<![CDATA[
ACK sip:[field0 file="callee.csv" line=0]@[field3 file="callee.csv" line=0]:[remote_port] SIP/2.0
[last_Via:]
From: <sip:[field0 file="caller.csv" line=0]@[field2 file="caller.csv" line=0]>;tag=[pid]SIPpTag00[call_number]
To: <sip:[field0 file="callee.csv" line=0]@[field3 file="callee.csv" line=0]>[peer_tag_param]
Call-ID: NGCP%[field4 file="callee.csv" line=0]%///[call_id]
CSeq: 2 ACK
Contact: sip:[field0 file="caller.csv" line=0]@[local_ip]:[local_port]
Max-Forwards: 70
Content-Length: 0
]]>
</send>
<ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200, 500, 1000"/>
<!-- <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/> -->
</scenario>

@ -0,0 +1,7 @@
soundsets:
'default_soundset':
reseller_id: 1
sounds:
unauth_caller_ip:
filename: sounds/no_sh.wav
loopplay: false

Binary file not shown.
Loading…
Cancel
Save