<div dir="ltr">Hi Guys,<div><br></div><div>I'm trying to use SipSimple SDK write test scripts that will be executed with fabric on a remote machine without a soundcard (ie. Amazon EC2) and which would dial in to our voice service and play back some wav files and/or DTMF's. <br>
</div><div><br></div><div><br></div><div style>At the moment I'm trying to use modified version of Saul's "jamesbond" script</div><div><div><div><a href="https://github.com/saghul/sipsimple-examples/tree/master/jamesbond">https://github.com/saghul/sipsimple-examples/tree/master/jamesbond</a></div>
</div><div style>to make a call and play a wav file once call is established. Modified script is at the end of email.</div><div style><br></div><div style>The problem is that there's no incoming RTP stream. I doubled check firewall rules and UDP traffic is allowed on all ports. I've attached a pcap file from an example call.</div>
<div style><br></div><div style>I'd be grateful if you could help me to figure out what's the problem.</div><div style><br></div><div style>btw. Is there a good and simple example script that would make unattended calls, play wav files and DTMF tones?</div>
<div style><br></div><div style>Many thanks,</div><div style>Janusz</div><div><br></div><div><br></div><div><b>caller.py:</b><br></div><div><br></div><div><div>#! /usr/bin/env python</div><div><br></div><div>import os</div>
<div>import sys</div><div>from datetime import datetime</div><div><br></div><div>from application.notification import NotificationCenter</div><div>from optparse import OptionParser</div><div>from threading import Event</div>
<div>from select import select</div><div><br></div><div>from sipsimple.account import AccountManager</div><div>from sipsimple.application import SIPApplication</div><div>from sipsimple.audio import WavePlayer</div><div>from sipsimple.configuration.settings import SIPSimpleSettings<br>
</div><div>from sipsimple.core import SIPURI, SIPCoreError, ToHeader</div><div>from sipsimple.lookup import DNSLookup, DNSLookupError</div><div>from sipsimple.session import Session</div><div>from sipsimple.streams import AudioStream</div>
<div>from sipsimple.threading.green import run_in_green_thread</div><div>from sipsimple.storage import FileStorage</div><div><br></div><div><br></div><div>class SimpleCallApplication(SIPApplication):</div><div>    </div><div>
    def __init__(self):</div><div>        SIPApplication.__init__(self)</div><div>        self.ended = Event()</div><div>        self.callee = None</div><div>        self.player = None</div><div>        self._wave_file = None</div>
<div>        self.session = None</div><div>        self.voice_audio_device = None</div><div>        self.voice_audio_bridge = None</div><div>        notification_center = NotificationCenter()</div><div>        notification_center.add_observer(self)</div>
<div><br></div><div>    def call(self, options):</div><div>        self.callee = options.target</div><div>        self._wave_file = options.filename</div><div>        self.start(FileStorage(os.path.expanduser('~/.sipclient')))</div>
<div><br></div><div>    @run_in_green_thread</div><div>    def _NH_SIPApplicationDidStart(self, notification):</div><div>        settings = SIPSimpleSettings()</div><div>        # We don't need speakers or microphone</div>
<div>        settings.audio.input_device = None</div><div>        settings.audio.output_device = None</div><div>        settings.rtp.port_range.start=5000</div><div>        settings.rtp.port_range.end=5500</div><div>        print 'RTP portRange: %s' % settings.rtp.port_range</div>
<div>        settings.save()</div><div>        self.player = WavePlayer(SIPApplication.voice_audio_mixer, self._wave_file, loop_count=0, initial_play=False)</div><div>        try:</div><div>            self.callee = ToHeader(SIPURI.parse(self.callee))</div>
<div>        except SIPCoreError:</div><div>            print 'Specified SIP URI is not valid'</div><div>            self.stop()</div><div>            return</div><div>        try:</div><div>            routes = DNSLookup().lookup_sip_proxy(self.callee.uri, ['udp']).wait()</div>
<div>        except DNSLookupError, e:</div><div>            print 'DNS lookup failed: %s' % str(e)</div><div>        else:</div><div>            account = AccountManager().default_account</div><div>            print account</div>
<div>            self.session = Session(account)</div><div>            self.session.connect(self.callee, routes, [AudioStream()])</div><div><br></div><div>    def _NH_SIPSessionGotRingIndication(self, notification):</div>
<div>        print 'Ringing!'</div><div><br></div><div>    def _NH_SIPSessionDidStart(self, notification):</div><div>        print 'Session started! at: %s' % (datetime.now().strftime("%Y-%m-%d_-_%H-%M-%S"))</div>
<div>        session = notification.sender</div><div>        audio_stream = session.streams[0]</div><div>        audio_stream.bridge.add(self.player)</div><div>        print 'Audio session established using "%s" codec at %sHz' % (audio_stream.codec, audio_stream.sample_rate)</div>
<div>        self.player.play()</div><div><br></div><div>    def _NH_SIPSessionDidFail(self, notification):</div><div>        print 'Failed to connect! %s' % (datetime.now().strftime("%Y-%m-%d_-_%H-%M-%S"))</div>
<div>        self.stop()</div><div><br></div><div>    def _NH_SIPSessionWillEnd(self, notification):</div><div>        session = notification.sender</div><div>        audio_stream = session.streams[0]</div><div>        self.player.stop()</div>
<div>        audio_stream.bridge.remove(self.player)</div><div><br></div><div>    def _NH_SIPSessionDidEnd(self, notification):</div><div>        print 'Session ended at: %s' % (datetime.now().strftime("%Y-%m-%d_-_%H-%M-%S"))</div>
<div>        self.stop()</div><div><br></div><div>    def _NH_SIPApplicationDidEnd(self, notification):</div><div>        self.ended.set()</div><div><br></div><div>if __name__ == '__main__':</div><div>    parser = OptionParser()</div>
<div>    parser.add_option('-t', '--target', help='Target URI')</div><div>    parser.add_option('-f', '--file', dest='filename', help='File to play', metavar='FILE')</div>
<div>    options, args = parser.parse_args()</div><div><br></div><div>    if not options.filename or not options.target:</div><div>        print 'Target and filename need to be specified, try --help'</div><div>        sys.exit(1)</div>
<div>    if not os.path.isfile(options.filename):</div><div>        print "The specified file doesn't exist"</div><div>        sys.exit(1)</div><div><br></div><div>    application = SimpleCallApplication()</div>
<div>    application.call(options)</div><div>    timeout = 30</div><div><br></div><div>    print "Placing call, wait %d seconds for call to end automatically or press Enter to quit the program %s" % (timeout, datetime.now().strftime("%Y-%m-%d_-_%H-%M-%S"))</div>
<div>    rlist, _, _ = select([sys.stdin], [], [], timeout)</div><div>    if rlist:</div><div>        s = sys.stdin.readline()</div><div>        print s</div><div>    else:</div><div>        print "No input from the console. Moving on... %s " % (datetime.now().strftime("%Y-%m-%d_-_%H-%M-%S"))</div>
<div><br></div><div>    if application.session:</div><div>        application.session.end()</div><div>    application.ended.wait()</div></div><div><br></div></div></div>