mirror of https://github.com/sipwise/rtpengine.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
322 lines
6.3 KiB
322 lines
6.3 KiB
#!/usr/bin/perl
|
|
|
|
# sample usage:
|
|
# ./ng-client offer --trust-address --from-tag=sgadhdagf --call-id=sfghjfsh --sdp=$'v=0\no=moo 1 2 IN IP4 192.168.1.90\ns=-\nc=IN IP4 192.168.1.90\nt=0 0\nm=audio 3456 RTP/AVP 0\n'
|
|
|
|
use warnings;
|
|
use strict;
|
|
use Getopt::Long;
|
|
use Data::Dumper;
|
|
use NGCP::Rtpengine;
|
|
|
|
my %options = ('proxy-address' => 'localhost', 'proxy-port' => 2223);
|
|
|
|
my @flags = qw(
|
|
trust-address
|
|
symmetric
|
|
asymmetric
|
|
unidirectional
|
|
force
|
|
strict-source
|
|
media-handover
|
|
reset
|
|
port-latching
|
|
no-rtcp-attribute
|
|
full-rtcp-attribute
|
|
loop-protect
|
|
record-call
|
|
always-transcode
|
|
SIPREC
|
|
pad-crypto
|
|
generate-mid
|
|
fragment
|
|
original-sendrecv
|
|
symmetric-codecs
|
|
asymmetric-codecs
|
|
inject-DTMF
|
|
detect-DTMF
|
|
generate-RTCP
|
|
single-codec
|
|
no-codec-renegotiation
|
|
pierce-NAT
|
|
SIP-source-address
|
|
allow-transcoding
|
|
force-transcoding
|
|
trickle-ICE
|
|
reject-ICE
|
|
egress
|
|
no-jitter-buffer
|
|
passthrough
|
|
no-passthrough
|
|
pause
|
|
early-media
|
|
block-short
|
|
recording-vsc
|
|
block-egress
|
|
directional
|
|
allow-no-codec-media
|
|
);
|
|
|
|
my @string_opts = qw(
|
|
from-tag
|
|
to-tag
|
|
call-id
|
|
to-call-id
|
|
transport-protocol
|
|
media-address
|
|
ICE
|
|
address-family
|
|
DTLS
|
|
via-branch
|
|
media-address
|
|
xmlrpc-callback
|
|
metadata
|
|
address
|
|
file
|
|
code
|
|
DTLS-fingerprint
|
|
ICE-lite
|
|
media-echo
|
|
label
|
|
set-label
|
|
from-label
|
|
to-label
|
|
DTMF-security
|
|
digit
|
|
DTMF-security-trigger
|
|
DTMF-security-trigger-end
|
|
trigger
|
|
trigger-end
|
|
all
|
|
frequency
|
|
blob
|
|
sdp
|
|
audio-player
|
|
dtmf-log-dest
|
|
output-destination
|
|
vsc-start-rec
|
|
vsc-stop-rec
|
|
vsc-pause-rec
|
|
vsc-start-stop-rec
|
|
vsc-pause-resume-rec
|
|
vsc-start-pause-resume-rec
|
|
rtpp-flags
|
|
body
|
|
);
|
|
|
|
my @int_opts = qw(
|
|
TOS
|
|
delete-delay
|
|
delay-buffer
|
|
volume
|
|
trigger-end-time
|
|
trigger-end-digits
|
|
DTMF-delay
|
|
ptime
|
|
db-id
|
|
duration
|
|
);
|
|
|
|
my @string_arr_opts = qw(
|
|
flags
|
|
rtcp-mux
|
|
SDES
|
|
supports
|
|
T38
|
|
OSRTP
|
|
received-from
|
|
from-tags
|
|
frequencies
|
|
);
|
|
|
|
my @codec_opts = qw(
|
|
strip
|
|
offer
|
|
transcode
|
|
mask
|
|
set
|
|
consume
|
|
accept
|
|
except
|
|
);
|
|
|
|
my @replace_opts = qw(
|
|
origin
|
|
session-connection
|
|
sdp-version
|
|
username
|
|
session-name
|
|
zero-address
|
|
force-increment-sdp-version
|
|
);
|
|
|
|
my @sdp_attr_sections = qw(
|
|
global
|
|
audio
|
|
video
|
|
);
|
|
my @sdp_attr_commands = qw(
|
|
add
|
|
remove
|
|
);
|
|
|
|
my %getopt = (
|
|
'json' => \$options{'json'},
|
|
'proxy-address=s' => \$options{'proxy-address'},
|
|
'proxy-port=s' => \$options{'proxy-port'},
|
|
'client-address=s' => \$options{'client-address'},
|
|
'sdp-file=s' => \$options{'sdp-file'},
|
|
'direction=s' => \$options{'direction'},
|
|
'v|verbose' => \$options{'verbose'},
|
|
'codec-options-flat' => \$options{'codec options flat'},
|
|
'blob-file=s' => \$options{'blob-file'},
|
|
);
|
|
|
|
for my $flag (@flags) {
|
|
$getopt{$flag} = \$options{$flag};
|
|
}
|
|
for my $flag (@string_opts) {
|
|
$getopt{"$flag=s"} = \$options{$flag};
|
|
}
|
|
for my $flag (@int_opts) {
|
|
$getopt{"$flag=i"} = \$options{$flag};
|
|
}
|
|
for my $flag (@string_arr_opts) {
|
|
$getopt{"$flag=s@"} = \$options{$flag};
|
|
}
|
|
for my $flag (@codec_opts) {
|
|
$getopt{"codec-$flag=s@"} = \$options{"codec-$flag"};
|
|
}
|
|
for my $flag (@replace_opts) {
|
|
$getopt{"replace-$flag"} = \$options{"replace-$flag"};
|
|
}
|
|
for my $sect (@sdp_attr_sections) {
|
|
for my $cmd (@sdp_attr_commands) {
|
|
$getopt{"sdp-attr-$sect-$cmd=s@"} = \$options{"sdp-attr-$sect-$cmd"};
|
|
}
|
|
}
|
|
|
|
GetOptions(%getopt) or die;
|
|
|
|
my $cmd = shift(@ARGV) or die;
|
|
|
|
my %packet = (command => $cmd);
|
|
|
|
for my $x (@string_opts) {
|
|
if (defined($options{$x})) {
|
|
if (!$options{json}) {
|
|
$packet{$x} = \$options{$x};
|
|
}
|
|
else {
|
|
$packet{$x} = $options{$x};
|
|
}
|
|
}
|
|
}
|
|
for my $x (@int_opts) {
|
|
defined($options{$x}) and $packet{$x} = $options{$x};
|
|
}
|
|
# process this first to get manually specified --flags=... in first
|
|
for my $x (@string_arr_opts) {
|
|
$packet{$x} = $options{$x}
|
|
if defined($options{$x}) && ref($options{$x}) eq 'ARRAY';
|
|
}
|
|
for my $x (@flags) {
|
|
defined($options{$x}) and push(@{$packet{flags}}, $x);
|
|
}
|
|
for my $x (@replace_opts) {
|
|
defined($options{'replace-' . $x}) and push(@{$packet{replace}}, $x);
|
|
}
|
|
if (defined($options{direction})) {
|
|
$options{direction} =~ /(.*),(.*)/ or die;
|
|
$packet{direction} = [$1,$2];
|
|
}
|
|
for my $x (@codec_opts) {
|
|
if ($options{'codec-'.$x} && @{$options{'codec-'.$x}}) {
|
|
if (!$options{'codec options flat'}) {
|
|
$packet{codec}{$x} = $options{'codec-'.$x};
|
|
}
|
|
else {
|
|
push(@{$packet{flags}}, map {'codec-'.$x.'-'.$_} @{$options{'codec-'.$x}});
|
|
}
|
|
}
|
|
}
|
|
for my $sect (@sdp_attr_sections) {
|
|
for my $cmd (@sdp_attr_commands) {
|
|
if ($options{"sdp-attr-$sect-$cmd"} && @{$options{"sdp-attr-$sect-$cmd"}}) {
|
|
$packet{'sdp-attr'}{$sect}{$cmd} = $options{"sdp-attr-$sect-$cmd"};
|
|
}
|
|
}
|
|
}
|
|
|
|
sub slurp_file {
|
|
local $/ = undef;
|
|
open(my $fh, '<', $_[0]) or die $!;
|
|
my $ret = <$fh>;
|
|
die $! unless defined $ret;
|
|
close($fh);
|
|
return $ret;
|
|
}
|
|
|
|
if (defined($options{'sdp-file'})) {
|
|
$packet{sdp} = slurp_file($options{'sdp-file'});
|
|
}
|
|
#elsif (@ARGV && $ARGV[0] eq 'sdp') {
|
|
# shift(@ARGV);
|
|
# $options{'client-address'} or die;
|
|
# my ($ca, $cp);
|
|
# if ($ca = inet_pton(AF_INET, $options{'client-address'})) {
|
|
# $ca = inet_ntop(AF_INET, $ca);
|
|
# $cp = "IP4";
|
|
# }
|
|
# elsif ($ca = inet_pton(AF_INET6, $options{'client-address'})) {
|
|
# $ca = inet_ntop(AF_INET6, $ca);
|
|
# $cp = "IP6";
|
|
# }
|
|
# $ca or die;
|
|
# my $sdp = "v=0\r\no=- 12345 67890 IN $cp $ca\r\ns=session\r\nc=IN $cp $ca\r\nt=0 0\r\n";
|
|
#
|
|
# $packet{sdp} = $sdp;
|
|
#}
|
|
|
|
if (defined($options{'blob-file'})) {
|
|
$packet{blob} = slurp_file($options{'blob-file'});
|
|
}
|
|
|
|
$options{verbose} and print Dumper \%packet;
|
|
|
|
if (defined($packet{sdp})) {
|
|
print("Old SDP:\n-----8<-----8<-----8<-----8<-----8<-----\n$packet{sdp}\n".
|
|
"----->8----->8----->8----->8----->8-----\n");
|
|
}
|
|
|
|
my $engine = NGCP::Rtpengine->new($options{'proxy-address'}, $options{'proxy-port'});
|
|
$engine->{json} = $options{json};
|
|
my $resp = $engine->req(\%packet);
|
|
|
|
#print Dumper $resp;
|
|
#exit;
|
|
|
|
if (exists($$resp{result}) && $$resp{result} eq 'ok') {
|
|
delete $$resp{result};
|
|
}
|
|
|
|
if (defined($$resp{sdp})) {
|
|
print("New SDP:\n-----8<-----8<-----8<-----8<-----8<-----\n$$resp{sdp}\n".
|
|
"----->8----->8----->8----->8----->8-----\n");
|
|
delete $$resp{sdp};
|
|
if (%$resp) {
|
|
print("Result dictionary:\n-----8<-----8<-----8<-----8<-----8<-----\n"
|
|
. Dumper($resp)
|
|
. "----->8----->8----->8----->8----->8-----\n");
|
|
}
|
|
}
|
|
else {
|
|
local $Data::Dumper::Indent = 1;
|
|
local $Data::Dumper::Terse = 1;
|
|
local $Data::Dumper::Quotekeys = 0;
|
|
local $Data::Dumper::Sortkeys = 1;
|
|
print("Result dictionary:\n-----8<-----8<-----8<-----8<-----8<-----\n"
|
|
. Dumper($resp)
|
|
. "----->8----->8----->8----->8----->8-----\n");
|
|
}
|