Browse Source

support sending of rtp

Change-Id: If832a763c021735357217b69f20891b547a9f6ef
changes/34/5834/1
Richard Fuchs 10 years ago
parent
commit
50bc73cfcb
5 changed files with 95 additions and 9 deletions
  1. +41
    -0
      perl/RTP.pm
  2. +1
    -1
      perl/Rtpengine.pm
  3. +31
    -5
      perl/Rtpengine/Test.pm
  4. +17
    -2
      perl/SDP.pm
  5. +5
    -1
      utils/test-basic.pl

+ 41
- 0
perl/RTP.pm View File

@ -2,5 +2,46 @@ package RTP;
use strict; use strict;
use warnings; use warnings;
use Time::HiRes qw(time);
use Math::BigInt;
sub new {
my ($class, $local_socket, $dest) = @_;
my $self = {};
bless $self, $class;
$self->{local_socket} = $local_socket;
$self->{destination} = $dest;
$self->{ssrc} = int(rand(2**32));
$self->{next_send} = time();
$self->{ptime} = 20;
$self->{clockrate} = 8000;
$self->{timestamp} = Math::BigInt->new(int(rand(2**32)));
$self->{seq} = rand(2**16);
$self->{payload} = 100;
return $self;
}
sub timer {
my ($self) = @_;
time() < $self->{next_send} and return;
my $hdr = pack("CCnNN", 0x80, 0x00, $self->{seq}, $self->{timestamp}->bstr(), $self->{ssrc});
my $payload = chr(rand(256)) x $self->{payload}; # XXX adapt to codec
$self->{local_socket}->send($hdr . $payload, 0, $self->{destination});
$self->{seq}++;
$self->{seq} > 0xffff and $self->{seq} -= 0x10000;
$self->{next_send} = $self->{next_send} + $self->{ptime} / 1000;
$self->{timestamp} += $self->{clockrate} / (1.0 / ($self->{ptime} / 1000)); # XXX might be fractional
$self->{timestamp} > 0xffffffff and $self->{timestamp} -= Math::BigInt->new('0x100000000');
}
1; 1;

+ 1
- 1
perl/Rtpengine.pm View File

@ -19,7 +19,7 @@ sub new {
$self->{socket} = $addr; $self->{socket} = $addr;
} }
else { else {
$self->{socket} = IO::Socket::IP->new(Type => &Socket::SOCK_DGRAM, Proto => 'udp',
$self->{socket} = IO::Socket::IP->new(Type => &SOCK_DGRAM, Proto => 'udp',
PeerHost => $addr, PeerPort => $port); PeerHost => $addr, PeerPort => $port);
} }


+ 31
- 5
perl/Rtpengine/Test.pm View File

@ -51,7 +51,7 @@ sub new {
$self->{timers} = []; $self->{timers} = [];
$self->{clients} = []; $self->{clients} = [];
$self->{rtpe} = Rtpengine->new('localhost', 2223);
$self->{control} = Rtpengine->new('localhost', 2223);
$self->{callid} = rand(); $self->{callid} = rand();
return $self; return $self;
@ -66,10 +66,14 @@ sub client {
sub run { sub run {
my ($self) = @_; my ($self) = @_;
$self->{mux}->loop(); $self->{mux}->loop();
} }
sub stop {
my ($self) = @_;
$self->{mux}->endloop();
}
sub timer_once { sub timer_once {
my ($self, $delay, $sub) = @_; my ($self, $delay, $sub) = @_;
push(@{$self->{timers}}, { sub => $sub, when => time() + $delay }); push(@{$self->{timers}}, { sub => $sub, when => time() + $delay });
@ -140,7 +144,7 @@ sub _new {
$self->{main_sockets} = $sockets[0]; # for m= and o= $self->{main_sockets} = $sockets[0]; # for m= and o=
$self->{local_sdp} = SDP->new($self->{main_sockets}->[0]); # no global c= $self->{local_sdp} = SDP->new($self->{main_sockets}->[0]); # no global c=
$self->{component_peers} = []; # keep track of source addresses
$self->{component_peers} = []; # keep track of peer source addresses
# default protocol # default protocol
my $proto = 'RTP/AVP'; my $proto = 'RTP/AVP';
@ -193,7 +197,7 @@ sub offer {
my $req = $self->_default_req_args('offer', 'from-tag' => $self->{tag}, sdp => $sdp_body, %args); my $req = $self->_default_req_args('offer', 'from-tag' => $self->{tag}, sdp => $sdp_body, %args);
my $out = $self->{parent}->{rtpe}->req($req);
my $out = $self->{parent}->{control}->req($req);
$other->_offered($out); $other->_offered($out);
} }
@ -218,7 +222,7 @@ sub answer {
my $req = $self->_default_req_args('answer', 'from-tag' => $other->{tag}, 'to-tag' => $self->{tag}, my $req = $self->_default_req_args('answer', 'from-tag' => $other->{tag}, 'to-tag' => $self->{tag},
sdp => $sdp_body, %args); sdp => $sdp_body, %args);
my $out = $self->{parent}->{rtpe}->req($req);
my $out = $self->{parent}->{control}->req($req);
$other->_answered($out); $other->_answered($out);
} }
@ -234,6 +238,14 @@ sub _answered {
$self->{ice} and $self->{ice}->decode($self->{remote_media}->decode_ice()); $self->{ice} and $self->{ice}->decode($self->{remote_media}->decode_ice());
} }
sub delete {
my ($self, %args) = @_;
my $req = $self->_default_req_args('delete', 'from-tag' => $self->{tag}, %args);
my $out = $self->{parent}->{control}->req($req);
}
sub _input { sub _input {
my ($self, $fh, $input, $peer) = @_; my ($self, $fh, $input, $peer) = @_;
@ -242,11 +254,17 @@ sub _input {
$self->{dtls} and $self->{dtls}->input($fh, $input, $peer); $self->{dtls} and $self->{dtls}->input($fh, $input, $peer);
$self->{ice} and $self->{ice}->input($fh, $input, $peer); $self->{ice} and $self->{ice}->input($fh, $input, $peer);
$$input eq '' and return;
# must be RTP input
$$input = '';
} }
sub _timer { sub _timer {
my ($self) = @_; my ($self) = @_;
$self->{ice} and $self->{ice}->timer(); $self->{ice} and $self->{ice}->timer();
$self->{rtp} and $self->{rtp}->timer();
} }
sub _peer_addr_check { sub _peer_addr_check {
@ -255,4 +273,12 @@ sub _peer_addr_check {
$dest_list->[$idx] = $peer; $dest_list->[$idx] = $peer;
} }
} }
sub start_rtp {
my ($self) = @_;
$self->{rtp} and die;
my $dest = $self->{remote_media}->endpoint();
$self->{rtp} = RTP->new($self->{rtp_sockets}->[0], $dest) or die;
}
1; 1;

+ 17
- 2
perl/SDP.pm View File

@ -4,6 +4,8 @@ use strict;
use warnings; use warnings;
use IO::Socket; use IO::Socket;
use Time::HiRes qw(gettimeofday); use Time::HiRes qw(gettimeofday);
use Socket;
use Socket6;
sub new { sub new {
my ($class, $origin, $connection) = @_; my ($class, $origin, $connection) = @_;
@ -106,10 +108,10 @@ sub encode_address {
sub decode_address { sub decode_address {
my ($s) = @_; my ($s) = @_;
if ($s =~ /^IN IP4 (\d+\.\d+\.\d+\.\d+)$/s) { if ($s =~ /^IN IP4 (\d+\.\d+\.\d+\.\d+)$/s) {
return $1;
return { address => $1, family => &AF_INET };
} }
if ($s =~ /^IN IP6 ([0-9a-fA-F:]+)$/s) { if ($s =~ /^IN IP6 ([0-9a-fA-F:]+)$/s) {
return $1;
return { address => $1, family => &AF_INET6 };
} }
die $s; die $s;
} }
@ -117,6 +119,10 @@ sub decode_address {
package SDP::Media; package SDP::Media;
use Socket;
use Socket6;
use IO::Socket;
sub new { sub new {
my ($class, $rtp, $rtcp, $protocol, $type) = @_; my ($class, $rtp, $rtcp, $protocol, $type) = @_;
@ -218,4 +224,13 @@ sub decode_ice {
return $ret; return $ret;
} }
sub endpoint {
my ($self) = @_;
my $conn = $self->connection();
my $port = $self->{port};
$conn->{family} == &AF_INET and return pack_sockaddr_in($port, inet_aton($conn->{address}));
$conn->{family} == &AF_INET6 and return pack_sockaddr_in6($port, inet_pton(&AF_INET6, $conn->{address}));
die;
}
1; 1;

+ 5
- 1
utils/test-basic.pl View File

@ -8,8 +8,12 @@ my $r = Rtpengine::Test->new();
my $a = $r->client(); my $a = $r->client();
my $b = $r->client(); my $b = $r->client();
$r->timer_once(3, sub { $b->answer($a, ICE => 'remove') });
$r->timer_once(3, sub { $b->answer($a, ICE => 'remove'); $a->start_rtp(); });
$r->timer_once(10, sub { $r->stop(); });
$a->offer($b, ICE => 'remove'); $a->offer($b, ICE => 'remove');
$b->start_rtp();
$r->run(); $r->run();
$a->delete();

Loading…
Cancel
Save