Skip to content
Snippets Groups Projects
Commit ced6c682 authored by Alexandre Savard's avatar Alexandre Savard
Browse files

#9621: Implement conference functional tests

parent 00126a36
Branches
Tags
No related merge requests found
...@@ -59,11 +59,15 @@ class SflPhoneCtrl(Thread): ...@@ -59,11 +59,15 @@ class SflPhoneCtrl(Thread):
onCallCurrent_cb onCallCurrent_cb
onCallBusy_cb onCallBusy_cb
onCallFailure_cb onCallFailure_cb
onConferenceCreated_cb
""" """
# list of active calls (known by the client) # list of active calls (known by the client)
activeCalls = {} activeCalls = {}
# list of active conferences
activeConferences = {}
def __init__(self, name=sys.argv[0]): def __init__(self, name=sys.argv[0]):
Thread.__init__(self) Thread.__init__(self)
...@@ -74,6 +78,7 @@ class SflPhoneCtrl(Thread): ...@@ -74,6 +78,7 @@ class SflPhoneCtrl(Thread):
self.name = name self.name = name
self.currentCallId = "" self.currentCallId = ""
self.currentConfId = ""
self.isStop = False self.isStop = False
...@@ -145,6 +150,7 @@ class SflPhoneCtrl(Thread): ...@@ -145,6 +150,7 @@ class SflPhoneCtrl(Thread):
print "Adding Incoming call method" print "Adding Incoming call method"
proxy_callmgr.connect_to_signal('incomingCall', self.onIncomingCall) proxy_callmgr.connect_to_signal('incomingCall', self.onIncomingCall)
proxy_callmgr.connect_to_signal('callStateChanged', self.onCallStateChanged) proxy_callmgr.connect_to_signal('callStateChanged', self.onCallStateChanged)
proxy_callmgr.connect_to_signal('conferenceCreated', self.onConferenceCreated)
except dbus.DBusException, e: except dbus.DBusException, e:
print e print e
...@@ -171,7 +177,7 @@ class SflPhoneCtrl(Thread): ...@@ -171,7 +177,7 @@ class SflPhoneCtrl(Thread):
def onIncomingCall_cb(self): def onIncomingCall_cb(self):
pass pass
def onCallHangup_cb(self): def onCallHangup_cb(self, callId):
pass pass
def onCallRinging_cb(self): def onCallRinging_cb(self):
...@@ -202,7 +208,7 @@ class SflPhoneCtrl(Thread): ...@@ -202,7 +208,7 @@ class SflPhoneCtrl(Thread):
def onCallHangUp(self, callid): def onCallHangUp(self, callid):
""" Remove callid from call list """ """ Remove callid from call list """
self.onCallHangup_cb() self.onCallHangup_cb(callid)
self.currentCallId = "" self.currentCallId = ""
del self.activeCalls[callid] del self.activeCalls[callid]
...@@ -274,6 +280,12 @@ class SflPhoneCtrl(Thread): ...@@ -274,6 +280,12 @@ class SflPhoneCtrl(Thread):
else: else:
print "unknown state" print "unknown state"
def onConferenceCreated_cb(self):
pass
def onConferenceCreated(self, confId):
self.currentConfId = confId
self.onConferenceCreated_cb()
# #
# Account management # Account management
...@@ -545,9 +557,6 @@ class SflPhoneCtrl(Thread): ...@@ -545,9 +557,6 @@ class SflPhoneCtrl(Thread):
for call in self.activeCalls: for call in self.activeCalls:
print "\t" + call print "\t" + call
#
# Action
#
def Call(self, dest): def Call(self, dest):
"""Start a call and return a CallID """Start a call and return a CallID
...@@ -636,12 +645,6 @@ class SflPhoneCtrl(Thread): ...@@ -636,12 +645,6 @@ class SflPhoneCtrl(Thread):
def Hold(self, callid): def Hold(self, callid):
"""Hold a call identified by a CallID""" """Hold a call identified by a CallID"""
# if not self.account:
# self.setFirstRegisteredAccount()
# if not self.isAccountRegistered():
# raise SflPhoneError("Can't hold a call without a registered account")
if callid is None or callid == "": if callid is None or callid == "":
raise SflPhoneError("Invalid callID") raise SflPhoneError("Invalid callID")
...@@ -651,12 +654,6 @@ class SflPhoneCtrl(Thread): ...@@ -651,12 +654,6 @@ class SflPhoneCtrl(Thread):
def UnHold(self, callid): def UnHold(self, callid):
"""Unhold an incoming call identified by a CallID""" """Unhold an incoming call identified by a CallID"""
# if not self.account:
# self.setFirstRegisteredAccount()
# if not self.isAccountRegistered():
# raise SflPhoneError("Can't unhold a call without a registered account")
if callid is None or callid == "": if callid is None or callid == "":
raise SflPhoneError("Invalid callID") raise SflPhoneError("Invalid callID")
...@@ -679,6 +676,19 @@ class SflPhoneCtrl(Thread): ...@@ -679,6 +676,19 @@ class SflPhoneCtrl(Thread):
callid = m.hexdigest() callid = m.hexdigest()
return callid return callid
def createConference(self, call1Id, call2Id):
""" Create a conference given the two call ids """
self.callmanager.joinParticipant(call1Id, call2Id)
def hangupConference(self, confId):
""" Hang up each call for this conference """
self.callmanager.hangUpConference(confId)
def run(self): def run(self):
"""Processing method for this thread""" """Processing method for this thread"""
...@@ -688,4 +698,8 @@ class SflPhoneCtrl(Thread): ...@@ -688,4 +698,8 @@ class SflPhoneCtrl(Thread):
context.iteration(True) context.iteration(True)
if self.isStop: if self.isStop:
print "++++++++++++++++++++++++++++++++++++++++"
print "++++++++++++++++++++++++++++++++++++++++"
print "++++++++++++++++++++++++++++++++++++++++"
print "++++++++++++++++++++++++++++++++++++++++"
return return
#!/usr/bin/env python #!/usr/bin/env python
# #
# Copyright (C) 2009 by the Free Software Foundation, Inc. # Copyright (C) 2012 by the Free Software Foundation, Inc.
#
# Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License
...@@ -22,7 +24,7 @@ class SippWrapper: ...@@ -22,7 +24,7 @@ class SippWrapper:
""" Wrapper taht allow for managing sipp command line easily """ """ Wrapper taht allow for managing sipp command line easily """
def __init__(self): def __init__(self):
self.commandLine = "sipp" self.commandLine = "./sipp"
self.remoteServer = "" self.remoteServer = ""
self.remotePort = "" self.remotePort = ""
self.localInterface = "" self.localInterface = ""
...@@ -41,9 +43,11 @@ class SippWrapper: ...@@ -41,9 +43,11 @@ class SippWrapper:
self.enableTraceRtt = False self.enableTraceRtt = False
self.enableTraceLogs = False self.enableTraceLogs = False
def buildCommandLine(self): def buildCommandLine(self, port):
""" Fill the command line arguments based on specified parameters """ """ Fill the command line arguments based on specified parameters """
self.localPort = str(port)
if not self.remotePort and not self.remoteServer: if not self.remotePort and not self.remoteServer:
self.isUserAgentClient = False self.isUserAgentClient = False
elif self.remotePort and not self.remoteServer: elif self.remotePort and not self.remoteServer:
...@@ -106,9 +110,8 @@ class SippWrapper: ...@@ -106,9 +110,8 @@ class SippWrapper:
def launch(self): def launch(self):
""" Launch the sipp instance using the specified arguments """ """ Launch the sipp instance using the specified arguments """
self.buildCommandLine()
print self.commandLine print self.commandLine
return os.system(self.commandLine) return os.system(self.commandLine + " 2>&1 > /dev/null")
class SippScreenStatParser: class SippScreenStatParser:
......
#!/usr/bin/env python #!/USR/BIN/ENV PYTHON
# #
# Copyright (C) 2009 by the Free Software Foundation, Inc. # Copyright (C) 2012 by the Free Software Foundation, Inc.
#
# Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License
...@@ -18,7 +20,9 @@ ...@@ -18,7 +20,9 @@
import os import os
import time import time
import yaml
import logging import logging
import multiprocessing
from sippwrap import SippWrapper from sippwrap import SippWrapper
from sippwrap import SippScreenStatParser from sippwrap import SippScreenStatParser
from sflphonectrl import SflPhoneCtrl from sflphonectrl import SflPhoneCtrl
...@@ -29,10 +33,62 @@ from nose.tools import nottest ...@@ -29,10 +33,62 @@ from nose.tools import nottest
### function starting with 'test' are executed. ### function starting with 'test' are executed.
### ###
accountList = ["IP2IP", "Account:1332798167"]
SCENARIO_PATH = "../sippxml/" SCENARIO_PATH = "../sippxml/"
class SippCtrl:
def __init__(self):
self.remoteServer = "127.0.0.1"
self.remotePort = str(5062)
self.localInterface = "127.0.0.1"
self.localPort = str(5060)
def initialize_sipp_registration_instance(self, instance, xmlScenario):
instance.remoteServer = self.remoteServer
instance.remotePort = self.remotePort
instance.localInterface = self.localInterface
instance.localPort = self.localPort
instance.customScenarioFile = SCENARIO_PATH + xmlScenario
instance.numberOfCall = 1
instance.numberOfSimultaneousCall = 1
def initialize_sipp_call_instance(self, instance):
instance.localInterface = self.localInterface
instance.localPort = self.localPort
instance.numberOfCall = 1
instance.numberOfSimultaneousCall = 1
instance.enableTraceScreen = True
def launchSippProcess(self, sippInstance, localPort):
sippInstance.buildCommandLine(localPort)
sippInstance.launch()
def find_sipp_pid(self):
# Retreive the PID of the last
# The /proc/PID/cmdline contain the command line from
pids = [int(x) for x in os.listdir("/proc") if x.isdigit()]
sippPid = [pid for pid in pids if "sipp" in open("/proc/" + str(pid) + "/cmdline").readline()]
return sippPid[0]
def clean_log_directory(self):
dirlist = os.listdir("./")
files = [x for x in dirlist if "screen.log" in x]
for f in files:
os.remove(f)
def parse_results(self):
dirlist = os.listdir("./")
logfile = [x for x in dirlist if "screen.log" in x]
fullpath = os.path.dirname(os.path.realpath(__file__)) + "/"
# there should be only one screen.log file (see clean_log_directory)
resultParser = SippScreenStatParser(fullpath + logfile[0])
assert(not resultParser.isAnyFailedCall())
assert(resultParser.isAnySuccessfulCall())
class TestSFLPhoneAccountConfig(SflPhoneCtrl): class TestSFLPhoneAccountConfig(SflPhoneCtrl):
""" The test suite for account configuration """ """ The test suite for account configuration """
...@@ -46,14 +102,40 @@ class TestSFLPhoneAccountConfig(SflPhoneCtrl): ...@@ -46,14 +102,40 @@ class TestSFLPhoneAccountConfig(SflPhoneCtrl):
self.logger.addHandler(filehdlr) self.logger.addHandler(filehdlr)
self.logger.setLevel(logging.INFO) self.logger.setLevel(logging.INFO)
@nottest
def get_config(self):
""" Parsse configuration file and return a dictionary """
config = {}
with open("sflphoned.functest.yml","r") as stream:
config = yaml.load(stream)
return config
def get_account_list_from_config(self):
""" Get the accout list from config and add IP2IP """
config = self.get_config()
accounts = config["preferences"]["order"]
accountList = accounts.split('/')
del accountList[len(accountList)-1]
accountList.append("IP2IP")
return accountList
def test_get_account_list(self): def test_get_account_list(self):
self.logger.info("Test get account list") self.logger.info("Test get account list")
accountList = self.get_account_list_from_config()
# make sure that the intersection between the list is of same size
accList = self.getAllAccounts() accList = self.getAllAccounts()
listIntersection = set(accList) & set(accountList) listIntersection = set(accList) & set(accountList)
assert len(listIntersection) == len(accountList) assert len(listIntersection) == len(accountList)
@nottest
def test_account_registration(self): def test_account_registration(self):
self.logger.info("Test account registration") self.logger.info("Test account registration")
accList = [x for x in self.getAllAccounts() if x != "IP2IP"] accList = [x for x in self.getAllAccounts() if x != "IP2IP"]
...@@ -72,6 +154,24 @@ class TestSFLPhoneAccountConfig(SflPhoneCtrl): ...@@ -72,6 +154,24 @@ class TestSFLPhoneAccountConfig(SflPhoneCtrl):
assert self.isAccountRegistered(acc) assert self.isAccountRegistered(acc)
@nottest
def test_get_account_details(self):
self.logger.info("Test account details")
accList = [x for x in self.getAllAccounts() if x != "IP2IP"]
config = self.get_config()
accountDetails = {}
for acc in accList:
accountDetails[acc] = self.getAccountDetails(acc)
accountConfDetails = {}
for accConf in config["accounts"]:
accountConfDetails[accConf["id"]] = accConf
@nottest @nottest
def test_add_remove_account(self): def test_add_remove_account(self):
self.logger.info("Test add/remove account") self.logger.info("Test add/remove account")
...@@ -99,11 +199,12 @@ class TestSFLPhoneAccountConfig(SflPhoneCtrl): ...@@ -99,11 +199,12 @@ class TestSFLPhoneAccountConfig(SflPhoneCtrl):
class TestSFLPhoneRegisteredCalls(SflPhoneCtrl): class TestSFLPhoneRegisteredCalls(SflPhoneCtrl, SippCtrl):
""" The test suite for call interaction """ """ The test suite for call interaction """
def __init__(self): def __init__(self):
SflPhoneCtrl.__init__(self) SflPhoneCtrl.__init__(self)
SippCtrl.__init__(self)
self.logger = logging.getLogger("TestSFLPhoneRegisteredCalls") self.logger = logging.getLogger("TestSFLPhoneRegisteredCalls")
filehdlr = logging.FileHandler("/tmp/sfltestregisteredcall.log") filehdlr = logging.FileHandler("/tmp/sfltestregisteredcall.log")
...@@ -113,8 +214,6 @@ class TestSFLPhoneRegisteredCalls(SflPhoneCtrl): ...@@ -113,8 +214,6 @@ class TestSFLPhoneRegisteredCalls(SflPhoneCtrl):
self.logger.setLevel(logging.INFO) self.logger.setLevel(logging.INFO)
self.sippRegistrationInstance = SippWrapper() self.sippRegistrationInstance = SippWrapper()
self.sippCallInstance = SippWrapper() self.sippCallInstance = SippWrapper()
self.localInterface = "127.0.0.1"
self.localPort = str(5064)
# Make sure the test directory is populated with most recent log files # Make sure the test directory is populated with most recent log files
self.clean_log_directory() self.clean_log_directory()
...@@ -143,68 +242,144 @@ class TestSFLPhoneRegisteredCalls(SflPhoneCtrl): ...@@ -143,68 +242,144 @@ class TestSFLPhoneRegisteredCalls(SflPhoneCtrl):
self.stopThread() self.stopThread()
def clean_log_directory(self): def test_registered_call(self):
dirlist = os.listdir("./") self.logger.info("Test Registered Call")
files = [x for x in dirlist if "screen.log" in x]
for f in files:
os.remove(f)
# Launch a sipp instance for account registration on asterisk
# this account will then be used to receive call from sflphone
self.initialize_sipp_registration_instance(self.sippRegistrationInstance, "uac_register_no_cvs_300.xml")
regd = multiprocessing.Process(name='sipp1register', target=self.launchSippProcess,
args=(self.sippRegistrationInstance, 5064,))
regd.start()
def find_sipp_pid(self): # wait for the registration to complete
# Retreive the PID of the last regd.join()
# The /proc/PID/cmdline contain the command line from
pids = [int(x) for x in os.listdir("/proc") if x.isdigit()]
sippPid = [pid for pid in pids if "sipp" in open("/proc/" + str(pid) + "/cmdline").readline()]
return sippPid[0] # Launch a sipp instance waiting for a call from previously registered account
self.initialize_sipp_call_instance(self.sippCallInstance)
calld = multiprocessing.Process(name='sipp1call', target=self.launchSippProcess,
args=(self.sippCallInstance, 5064,))
calld.start()
# Make sure every account are enabled
accList = [x for x in self.getAllAccounts() if x != "IP2IP"]
for acc in accList:
if not self.isAccountRegistered(acc):
self.setAccountEnable(acc, True)
def parse_results(self): # Make a call to the SIPP instance
dirlist = os.listdir("./") self.Call("300")
logfile = [x for x in dirlist if "screen.log" in x]
print logfile
fullpath = os.path.dirname(os.path.realpath(__file__)) + "/" # Start the threaded loop to handle GLIB cllbacks
self.start()
# there should be only one screen.log file (see clean_log_directory) # Wait for the sipp instance to dump log files
resultParser = SippScreenStatParser(fullpath + logfile[0]) calld.join()
assert(not resultParser.isAnyFailedCall()) self.stopThread()
assert(resultParser.isAnySuccessfulCall()) self.parse_results()
def test_registered_call(self): class TestSFLPhoneConferenceCalls(SflPhoneCtrl, SippCtrl):
self.logger.info("Test Registered Call") """ Test Conference calls """
# launch the sipp instance in background def __init__(self):
# sipp 127.0.0.1:5060 -sf uac_register_no_cvs.xml -i 127.0.0.1 -p 5062 SflPhoneCtrl.__init__(self)
self.sippRegistrationInstance.remoteServer = "127.0.0.1" SippCtrl.__init__(self)
self.sippRegistrationInstance.remotePort = str(5062)
self.sippRegistrationInstance.localInterface = self.localInterface
self.sippRegistrationInstance.localPort = self.localPort
self.sippRegistrationInstance.customScenarioFile = SCENARIO_PATH + "uac_register_no_cvs.xml"
self.sippRegistrationInstance.launchInBackground = True
self.sippRegistrationInstance.numberOfCall = 1
self.sippRegistrationInstance.numberOfSimultaneousCall = 1
self.sippRegistrationInstance.launch() self.logger = logging.getLogger("TestSFLPhoneRegisteredCalls")
filehdlr = logging.FileHandler("/tmp/sfltestregisteredcall.log")
formatter = logging.Formatter("%(asctime)s %(levelname)s %(message)s")
filehdlr.setFormatter(formatter)
self.logger.addHandler(filehdlr)
self.logger.setLevel(logging.INFO)
self.sippRegistrationInstanceA = SippWrapper()
self.sippRegistrationInstanceB = SippWrapper()
self.sippCallInstanceA = SippWrapper()
self.sippCallInstanceB = SippWrapper()
self.localPortCallA = str(5064)
self.localPortCallB = str(5066)
self.callCount = 0
self.accountCalls = []
# Make sure the test directory is populated with most recent log files
# self.clean_log_directory()
# wait for this instance of sipp to complete registration
sippPid = self.find_sipp_pid()
while os.path.exists("/proc/" + str(sippPid)):
time.sleep(1)
# sipp -sn uas -p 5062 -i 127.0.0.1 def onCallCurrent_cb(self):
self.sippCallInstance.localInterface = self.localInterface """ On incoming call, answer the call, then hangup """
self.sippCallInstance.localPort = self.localPort
self.sippCallInstance.launchInBackground = True
self.sippCallInstance.numberOfCall = 1
self.sippCallInstance.numberOfSimultaneousCall = 1
self.sippCallInstance.enableTraceScreen = True
self.sippCallInstance.launch() self.callCount += 1
sippPid = self.find_sipp_pid() self.accountCalls.append(self.currentCallId)
print "Account List: ", str(self.accountCalls)
if self.callCount == 2:
self.createConference(self.accountCalls[0], self.accountCalls[1])
def onCallRinging_cb(self):
""" Display messages when call is ringing """
print "The call is ringing"
def onCallHangup_cb(self, callId):
""" Exit thread when all call are finished """
if callId in self.accountCalls:
self.accountCalls.remove(callId)
self.callCount -= 1
if self.callCount == 0:
self.stopThread()
def onCallFailure_cb(self):
""" If a failure occurs duing the call, just leave the running thread """
print "Stopping Thread"
self.stopThread()
def onConferenceCreated_cb(self):
""" Called once the conference is created """
print "Conference Created ", self.currentConfId
print "Conference Hangup ", self.currentConfId
self.hangupConference(self.currentConfId)
def test_conference_call(self):
self.logger.info("Test Registered Call")
# launch the sipp instance to register the first participant to astersik
self.initialize_sipp_registration_instance(self.sippRegistrationInstanceA, "uac_register_no_cvs_300.xml")
regd = multiprocessing.Process(name='sipp1register', target=self.launchSippProcess,
args=(self.sippRegistrationInstanceA, 5064,))
regd.start()
regd.join()
# launch the sipp instance to register the second participant to asterisk
self.initialize_sipp_registration_instance(self.sippRegistrationInstanceB, "uac_register_no_cvs_400.xml")
regd = multiprocessing.Process(name='sipp2register', target=self.launchSippProcess,
args=(self.sippRegistrationInstanceB, 5066,))
regd.start()
regd.join()
# launch the sipp instance waining for call as the first participant
self.initialize_sipp_call_instance(self.sippCallInstanceA)
calldA = multiprocessing.Process(name='sipp1call', target=self.launchSippProcess,
args=(self.sippCallInstanceA, 5064,))
calldA.start()
# launch the sipp instance waiting for call as the second particpant
self.initialize_sipp_call_instance(self.sippCallInstanceB)
calldB = multiprocessing.Process(name='sipp2call', target=self.launchSippProcess,
args=(self.sippCallInstanceB, 5066,))
calldB.start()
# make sure every account are enabled # make sure every account are enabled
accList = [x for x in self.getAllAccounts() if x != "IP2IP"] accList = [x for x in self.getAllAccounts() if x != "IP2IP"]
...@@ -212,14 +387,26 @@ class TestSFLPhoneRegisteredCalls(SflPhoneCtrl): ...@@ -212,14 +387,26 @@ class TestSFLPhoneRegisteredCalls(SflPhoneCtrl):
if not self.isAccountRegistered(acc): if not self.isAccountRegistered(acc):
self.setAccountEnable(acc, True) self.setAccountEnable(acc, True)
# Make a call to the SIPP instance # make a call to the SIPP instance
self.Call("300") self.Call("300")
self.Call("400")
# Start Glib mainloop to process callbacks # start the main loop for processing glib callbacks
self.start() self.start()
# Wait the sipp instance to dump log files print "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-"
while os.path.exists("/proc/" + str(sippPid)): calldA.join()
time.sleep(1) print "+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+"
calldB.join()
print "====================================================="
self.stopThread()
self.parse_results() self.parse_results()
# callInstance = TestSFLPhoneRegisteredCalls()
# callInstance.test_registered_call()
confInstance = TestSFLPhoneConferenceCalls()
confInstance.test_conference_call()
<?xml version="1.0" encoding="ISO-8859-2" ?>
<!-- Use with CSV file struct like: 3000;192.168.1.106;[authentication username=3000 password=3000];
(user part of uri, server address, auth tag in each line)
-->
<scenario name="register_client">
<send retrans="500">
<![CDATA[
REGISTER sip:127.0.0.1 SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
From: <sip:300@127.0.0.1>;tag=[call_number]
To: <sip:400@127.0.0.1>
Call-ID: [call_id]
CSeq: [cseq] REGISTER
Contact: sip:300@[local_ip]:[local_port]
Max-Forwards: 10
Expires: 120
User-Agent: SIPp/Win32
Content-Length: 0
]]>
</send>
<!-- asterisk -->
<recv response="200">
<!--
<action>
<ereg regexp=".*" search_in="hdr" header="Contact:" check_it="true" assign_to="1" />
</action>
-->
</recv>
<!--
<recv request="INVITE" crlf="true">
</recv>
<send>
<![CDATA[
SIP/2.0 180 Ringing
[last_Via:]
[last_From:]
[last_To:];tag=[pid]SIPpTag01[call_number]
[last_Call-ID:]
[last_CSeq:]
Contact: <sip:[local_ip]:[local_port];transport=[transport]>
Content-Length: 0
]]>
</send>
<send retrans="500">
<![CDATA[
SIP/2.0 200 OK
[last_Via:]
[last_From:]
[last_To:];tag=[pid]SIPpTag01[call_number]
[last_Call-ID:]
[last_CSeq:]
Contact: <sip:[local_ip]:[local_port];transport=[transport]>
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 0
a=rtpmap:0 PCMU/8000
]]>
</send>
<recv request="ACK"
optional="true"
rtd="true"
crlf="true">
</recv>
<recv request="BYE">
</recv>
<send>
<![CDATA[
SIP/2.0 200 OK
[last_Via:]
[last_From:]
[last_To:]
[last_Call-ID:]
[last_CSeq:]
Contact: <sip:[local_ip]:[local_port];transport=[transport]>
Content-Length: 0
]]>
</send>
<timewait milliseconds="4000"/>
<ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
<CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
-->
</scenario>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment