[ previous ] [ next ] [ threads ]
 To :  yate@v...
 From :  =?UTF-8?B?0JLQsNGB0LjQu9C40Lkg0KDQtdC00YzQutC40L0=?= <vir@c...>
 Subject :  Re: [yate] Perl script - Route and Ring
 Date :  Thu, 24 Jan 2013 09:48:14 +0400
23.01.2013 8:40, Rodrigo Ricardo Passos пишет:
> Hi yate users,
>
> I'm using perl script (Yate.pm) to routing calls in my SS7 server.
> When inbound call enter in SS7 channel, the pstn user can't listen the 
> ring tone.
> SIP 180 is sent over server to the softphone. Sip user listen the ring 
> tone normaly.
>
> Anyone knows how can i do to generate the ring tone ("fake") to pstn 
> user?
>
> Below, i'm showing  the logs of SIP and ISUP.
>
> Regards,
>
> Rodrigo R Passos
>
> Via: SIP/2.0/UDP 
> 192.168.10.11:5060;received=192.168.10.11;rport=5060;branch=z9hG4bK433265996
> Record-Route: 
> Contact: 
> 
> To: ;tag=421db41a
> From: ;tag=782452354
> Call-ID: 1570465931@1...
> CSeq: 3 INVITE
> User-Agent: eyeBeam release 1105z stamp 59031
> Content-Length: 0
>
> ------
>  Call ringing [0x9ed81f8]
>  Sending message (0xb69e83b8)
> -----
> CPR [cic=1 label=4-172-3:4-232-2:1]  01 00
>   EventInformation='ringing'
Here is one of my experimental scripts ("fake ringback tone" to sig/xxx 
channels), hope it will be useful.




#!/usr/bin/perl -w
#
# (c) vir
#
# Last modified: 2011-05-11 18:26:31 +0400
#

use strict;
use warnings FATAL => 'uninitialized';
use lib '.';
use Yate;

$|=1;

# id => { callerid=>id, calledid=>id, caller=>nnn, called=>nnn }
# [sig/xxx = callerid] --> [dumb/xxx = dumb1]DUMB[dumb/xxx = dumb2] ---> [iax/xxx = targetid]
my %calls;

my $debug = 0;

sub is_our_call($;$)
{
	my($msg) = @_;
	my $called = $msg->param('called');
	return 1 if ($msg->param('overlapped') ne 'true') && ($msg->param('module') eq 'sig')
		&& ($called !~ /^[12589]/ || $called =~ /^29/);
#		&& ($called =~ /^[34]/ || $called =~ /^29/ || $called =~ /^00/);
	$msg->dumpmsg('Not our call');
	return 0;
}

sub find_call($$)
{
	my($caller, $called) = @_;
	foreach my $call(values %calls) {
		return $call if $call->{'caller'} eq $caller && $call->{'caled'} eq $called
	}
	return undef;
}

sub on_call_route
{
	my $msg = shift;
	my $id = $msg->param('id');
	return undef unless $id=~/^sig\//;
	my $caller = $msg->param('caller');
	my $called = $msg->param('called');
	if(is_our_call($msg)) {
		my $call = ($calls{$id} = {});
		$call->{'caller'} = $caller;
		$call->{'called'} = $called;
		$call->{'callerid'} = $id;
		$call->{'billid'} = $msg->param('billid');
		$msg->param('autoring', 'false');

		my $msgid = $msg->generate_id;
		$calls{$msgid} = $call; # Store message id to get associate reponse with our call
		$msg->message('call.execute', undef, $msgid,
			caller => $msg->param('caller'),
			billid => $msg->param('billid'),
			callto => 'dumb/',
			target => $called,
			format => 'alaw',
		);
		return('true', 'dumb/');
	} else {
		return undef;
	}
}

sub on_reply_call_execute
{
	my $msg = shift;
	my $id = $msg->param('id');
	my $call = $calls{$id} or return undef;
	$msg->dumpmsg('First channel goes to dumb') if $debug;
	my $targetid = $msg->param('targetid');
	$call->{dumb1} = $targetid;
	return undef;
}

sub on_our_call_execute_result
{
	my $msg = shift;
	my $call = delete $calls{$msg->header('id')} || return;
	$msg->dumpmsg('Our call to real destinaton (result)') if $debug;
	$call->{dumb2} = $msg->param('id');
	$call->{calledid} = $msg->param('targetid');
	$calls{$call->{calledid}} = $call;
}

sub on_call_ringing
{
	my $msg = shift;
	my $id = $msg->param('id');
	my $call = $calls{$id} || return undef;
	my $targetid = $msg->{targetid};
	$msg->dumpmsg('Target is ringing now, so do we') if $debug;
	$msg->message('chan.masquerade', undef, undef,
		message => "chan.attach",
		id=>$call->{dumb1},
		source=>"tone/ring",
	);
	return 'true';
}

sub on_call_answered
{
	my $msg = shift;
	my $id = $msg->param('id');
	my $call = $calls{$id} || return undef;
	$msg->dumpmsg('Target answered, interconnecting peers') if $debug;
	$msg->message('call.answered', undef, undef,
		id => $call->{dumb1},
		targetid => $call->{callerid},
	);
	$msg->message('chan.connect', undef, undef,
		id => $call->{callerid},
		targetid => $call->{calledid},
		billid => $call->{billid},
	);
	delete $calls{$call->{callerid}};
	delete $calls{$call->{calledid}};
}

sub on_chan_hangup
{
	my $msg = shift;
	my $id = $msg->param('id');
	my $call = $calls{$id} || return undef;
	$msg->dumpmsg('Got hangup') if $debug;
	my $peer = $call->{ ($id eq $call->{callerid})?'calledid':'callerid' };
	$msg->message('call.drop', undef, undef,
		id => $peer,
		reason => 'Peer hangup',
	);
	delete $calls{$call->{callerid}};
	delete $calls{$call->{calledid}};
	return undef;
}

my $message = new Yate(Debug=>0);
$message->connect("192.168.1.44:42428");
$message->install("call.route",\&on_call_route,10);
$message->install("call.ringing",\&on_call_ringing,10);
$message->install("call.answered",\&on_call_answered,10);
$message->install("chan.hangup",\&on_chan_hangup,10);
$message->install_watcher('call.execute', \&on_reply_call_execute);
$message->install_incoming('call.execute', \&on_our_call_execute_result);
#$message->install("engine.timer",sub { warn "@_\n"; }, 10);
$message->listen();