#!/usr/bin/perl -w
# This script sends multiple re-INVITE in a SIP session.
#
# Asterisk server is expected to run on localhost and have a
# configuration to allow incoming calls to one registered user such as
# below. The server should also be compiled with DONT_OPTIMIZE and
# MALLOC_DEBUG. The option ignoresdpversion must be set in sip.conf;
# this allows us to have a simple script (otherwise, we would have to
# make sure SDP session version is increased on every re-INVITE to
# trigger the bug).
#
# If you monitor memory usage with Asterisk command
# 'memory show summary' you can notice increasing allocation in
# rtp_engine.c. If you monitor the output of the command
# 'memory show allocations rtp_engine.c', you can notice memory
# allocation occurring in ast_rtp_codecs_payload_copy().
#
#
# ; sip.conf
# [general]
# transport=udp
# ignoresdpversion=yes
#
# [friends_internal](!)
# type=friend
# host=dynamic
# context=from-internal
# disallow=all
# allow=ulaw
#
# [user](friends_internal)
# secret=12345 
#
#
# ; extensions.conf
# ; ... - sample file generated by "make sample"
# [from-internal]
# include => demo


use strict;
use Net::SIP;
use Time::HiRes qw(usleep);

# SIP session configuration
my $user          = 'user';
my $auth_user     = 'user';
my $auth_password = '12345';
my $sip_to        = 'sip:500@127.0.0.1';
my $registrar     = '127.0.0.1';
my $domain        = 'localdomain';

# Initial sleep delay (in seconds) to have time to switch to another
# console and start monitoring.
my $initial_delay = 5;

my $ua = Net::SIP::Simple->new(
  registrar => $registrar,
  domain    => $domain,
  from      => $user,
  auth      => [ $auth_user, $auth_password ],
);

# Send REGISTER request
$ua->register( expires => 3600 )
|| die "Not registered: " . $ua->error;
print "Registered\n";

# Send INVITE request
# We don't really care about the RTP in this test, so we use the
# defaults.
my $call = $ua->invite( $sip_to, )
|| die "Invite failed: " . $ua->error;

# Give some time to start monitoring.
sleep $initial_delay;

while(1) {
    # Send new INVITE in the same call.
    # If we capture traffic, we can actually confirm it is using the
    # same call-id.
    $call->reinvite;
    usleep 100;
}

# Send BYE request
# Code never reached because of infinite loop above.
$call->bye;
