Note that there are some explanatory texts on larger screens.

plurals
  1. POTwisted / Starpy FastAgi app only handling one call properly
    primarykey
    data
    text
    <p>I am developing a FastAgi application for an Asterisk IVR implementation using Starpy and Twisted. So far, the application runs pretty well when it only has one phone call. </p> <p>After a second call is established, all the successive responses from Asterisk are sent to the second call: the stream audio belonging to the first call it's heard on the second call, the Hangup() disconnects the second call (the first one stays connected until manually disconnected from the soft phone)</p> <p>I am using X-lite softphones with Elastix distro. My FastAgi server is on a Windows laptop. on Extensions_custom.conf I have these entries to route the calls:</p> <p>exten => 2000,1,AGI(agi://10.0.0.7:4573) exten => 2000,n,Hangup()</p> <p>This is how the protocol is set on the server:</p> <pre><code>logging.basicConfig() fastagi.log.setLevel( logging.DEBUG ) f = fastagi.FastAGIFactory(MyIVRApplication()) reactor.listenTCP(4573, f, 50, '10.0.0.167') reactor.run() </code></pre> <p>I built my application using one of the examples provided by starpy, the DialPlan() app which just plays the number of times that the app has been accessed. Even that application when run instead of my application has the same issues, only handles one call properly.</p> <p>I was using a wireless network, but same thing happens when using cables. I tried both a virtual machine with asterisk (in virtualbox) and a physical machine. Same thing. Installed a different softphone on and Android phone. Same thing. Used a physical Ip Phone. Same thing. The only thing that I have not tried yet is to move my FastAgi server to a linux box instead of using my windows laptop. </p> <p>Any help will be appreciated.</p> <p>Thanks in advance.</p> <p>Hector </p> <p>EDIT: </p> <p>I am adding the AGI debug log from Asterisk. As you can see, after the second call is establish, all the Tx and Rx commands are sent / received from the second channel. Asterisk never talks again with the first channel, which stays connected.</p> <pre><code>== Using SIP RTP TOS bits 184 == Using SIP RTP CoS mark 5 -- Executing [2000@from-internal:1] AGI("SIP/4001-00000006", "agi://10.0.0.167") in new stack AGI Tx &gt;&gt; agi_network: yes &lt;SIP/4001-00000006&gt;AGI Tx &gt;&gt; agi_request: agi://10.0.0.167 &lt;SIP/4001-00000006&gt;AGI Tx &gt;&gt; agi_channel: SIP/4001-00000006 &lt;SIP/4001-00000006&gt;AGI Tx &gt;&gt; agi_language: en &lt;SIP/4001-00000006&gt;AGI Tx &gt;&gt; agi_type: SIP &lt;SIP/4001-00000006&gt;AGI Tx &gt;&gt; agi_uniqueid: 1360854557.6 &lt;SIP/4001-00000006&gt;AGI Tx &gt;&gt; agi_version: 1.8.11.0 &lt;SIP/4001-00000006&gt;AGI Tx &gt;&gt; agi_callerid: 4001 &lt;SIP/4001-00000006&gt;AGI Tx &gt;&gt; agi_calleridname: device &lt;SIP/4001-00000006&gt;AGI Tx &gt;&gt; agi_callingpres: 0 &lt;SIP/4001-00000006&gt;AGI Tx &gt;&gt; agi_callingani2: 0 &lt;SIP/4001-00000006&gt;AGI Tx &gt;&gt; agi_callington: 0 &lt;SIP/4001-00000006&gt;AGI Tx &gt;&gt; agi_callingtns: 0 &lt;SIP/4001-00000006&gt;AGI Tx &gt;&gt; agi_dnid: 2000 &lt;SIP/4001-00000006&gt;AGI Tx &gt;&gt; agi_rdnis: unknown &lt;SIP/4001-00000006&gt;AGI Tx &gt;&gt; agi_context: from-internal &lt;SIP/4001-00000006&gt;AGI Tx &gt;&gt; agi_extension: 2000 &lt;SIP/4001-00000006&gt;AGI Tx &gt;&gt; agi_priority: 1 &lt;SIP/4001-00000006&gt;AGI Tx &gt;&gt; agi_enhanced: 0.0 &lt;SIP/4001-00000006&gt;AGI Tx &gt;&gt; agi_accountcode: &lt;SIP/4001-00000006&gt;AGI Tx &gt;&gt; agi_threadid: -1219851376 &lt;SIP/4001-00000006&gt;AGI Tx &gt;&gt; &lt;SIP/4001-00000006&gt;AGI Rx &lt;&lt; ANSWER &lt;SIP/4001-00000006&gt;AGI Tx &gt;&gt; 200 result=0 &lt;SIP/4001-00000006&gt;AGI Rx &lt;&lt; STREAM FILE "custom/bienvenida" '' 0 -- Playing 'custom/bienvenida' (escape_digits='') (sample_offset 0) &lt;SIP/4001-00000006&gt;AGI Tx &gt;&gt; 200 result=0 endpos=24402 &lt;SIP/4001-00000006&gt;AGI Rx &lt;&lt; GET DATA "custom/cuando_este_listo" 5000.0 1 -- &lt;SIP/4001-00000006&gt; Playing 'custom/cuando_este_listo.slin' (language 'en') &lt;SIP/4001-00000006&gt;AGI Tx &gt;&gt; 200 result= &lt;SIP/4001-00000006&gt;AGI Rx &lt;&lt; STREAM FILE "custom/14" '' 0 -- Playing 'custom/14' (escape_digits='') (sample_offset 0) &lt;SIP/4001-00000006&gt;AGI Tx &gt;&gt; 200 result=0 endpos=7028 &lt;SIP/4001-00000006&gt;AGI Rx &lt;&lt; STREAM FILE "custom/menos" '' 0 -- Playing 'custom/menos' (escape_digits='') (sample_offset 0) &lt;SIP/4001-00000006&gt;AGI Tx &gt;&gt; 200 result=0 endpos=6762 &lt;SIP/4001-00000006&gt;AGI Rx &lt;&lt; STREAM FILE "custom/9" '' 0 -- Playing 'custom/9' (escape_digits='') (sample_offset 0) &lt;SIP/4001-00000006&gt;AGI Tx &gt;&gt; 200 result=0 endpos=5666 &lt;SIP/4001-00000006&gt;AGI Rx &lt;&lt; GET DATA "" 5000.0 2 == Using SIP RTP TOS bits 184 == Using SIP RTP CoS mark 5 -- Executing [2000@from-internal:1] AGI("SIP/4002-00000007", "agi://10.0.0.167") in new stack AGI Tx &gt;&gt; agi_network: yes &lt;SIP/4002-00000007&gt;AGI Tx &gt;&gt; agi_request: agi://10.0.0.167 &lt;SIP/4002-00000007&gt;AGI Tx &gt;&gt; agi_channel: SIP/4002-00000007 &lt;SIP/4002-00000007&gt;AGI Tx &gt;&gt; agi_language: en &lt;SIP/4002-00000007&gt;AGI Tx &gt;&gt; agi_type: SIP &lt;SIP/4002-00000007&gt;AGI Tx &gt;&gt; agi_uniqueid: 1360854568.7 &lt;SIP/4002-00000007&gt;AGI Tx &gt;&gt; agi_version: 1.8.11.0 &lt;SIP/4002-00000007&gt;AGI Tx &gt;&gt; agi_callerid: 4002 &lt;SIP/4002-00000007&gt;AGI Tx &gt;&gt; agi_calleridname: device &lt;SIP/4002-00000007&gt;AGI Tx &gt;&gt; agi_callingpres: 0 &lt;SIP/4002-00000007&gt;AGI Tx &gt;&gt; agi_callingani2: 0 &lt;SIP/4002-00000007&gt;AGI Tx &gt;&gt; agi_callington: 0 &lt;SIP/4002-00000007&gt;AGI Tx &gt;&gt; agi_callingtns: 0 &lt;SIP/4002-00000007&gt;AGI Tx &gt;&gt; agi_dnid: 2000 &lt;SIP/4002-00000007&gt;AGI Tx &gt;&gt; agi_rdnis: unknown &lt;SIP/4002-00000007&gt;AGI Tx &gt;&gt; agi_context: from-internal &lt;SIP/4002-00000007&gt;AGI Tx &gt;&gt; agi_extension: 2000 &lt;SIP/4002-00000007&gt;AGI Tx &gt;&gt; agi_priority: 1 &lt;SIP/4002-00000007&gt;AGI Tx &gt;&gt; agi_enhanced: 0.0 &lt;SIP/4002-00000007&gt;AGI Tx &gt;&gt; agi_accountcode: &lt;SIP/4002-00000007&gt;AGI Tx &gt;&gt; agi_threadid: -1220097136 &lt;SIP/4002-00000007&gt;AGI Tx &gt;&gt; &lt;SIP/4002-00000007&gt;AGI Rx &lt;&lt; ANSWER &lt;SIP/4002-00000007&gt;AGI Tx &gt;&gt; 200 result=0 &lt;SIP/4002-00000007&gt;AGI Rx &lt;&lt; STREAM FILE "custom/bienvenida" '' 0 -- Playing 'custom/bienvenida' (escape_digits='') (sample_offset 0) &lt;SIP/4001-00000006&gt;AGI Tx &gt;&gt; 200 result= (timeout) &lt;SIP/4002-00000007&gt;AGI Rx &lt;&lt; STREAM FILE "custom/respuesta_incorrecta" '' 0 -- Playing 'custom/respuesta_incorrecta' (escape_digits='') (sample_offset 0) &lt;SIP/4002-00000007&gt;AGI Tx &gt;&gt; 200 result=0 endpos=14260 &lt;SIP/4002-00000007&gt;AGI Rx &lt;&lt; GET DATA "custom/cuando_este_listo" 5000.0 1 -- &lt;SIP/4002-00000007&gt; Playing 'custom/cuando_este_listo.slin' (language 'en') &lt;SIP/4002-00000007&gt;AGI Tx &gt;&gt; 200 result= -- &lt;SIP/4002-00000007&gt;AGI Script agi://10.0.0.167 completed, returning 0 &lt;SIP/4002-00000007&gt;AGI Tx &gt;&gt; HANGUP -- Executing [2000@from-internal:2] Hangup("SIP/4002-00000007", "") in new stack == Spawn extension (from-internal, 2000, 2) exited non-zero on 'SIP/4002-00000007' -- Executing [h@from-internal:1] Macro("SIP/4002-00000007", "hangupcall") in new stack -- Executing [s@macro-hangupcall:1] GotoIf("SIP/4002-00000007", "1?endmixmoncheck") in new stack -- Goto (macro-hangupcall,s,9) -- Executing [s@macro-hangupcall:9] NoOp("SIP/4002-00000007", "End of MIXMON check") in new stack -- Executing [s@macro-hangupcall:10] GotoIf("SIP/4002-00000007", "1?nomeetmemon") in new stack -- Goto (macro-hangupcall,s,15) -- Executing [s@macro-hangupcall:15] NoOp("SIP/4002-00000007", "MEETME_RECORDINGFILE=") in new stack -- Executing [s@macro-hangupcall:16] GotoIf("SIP/4002-00000007", "1?noautomon") in new stack -- Goto (macro-hangupcall,s,18) -- Executing [s@macro-hangupcall:18] NoOp("SIP/4002-00000007", "TOUCH_MONITOR_OUTPUT=") in new stack -- Executing [s@macro-hangupcall:19] GotoIf("SIP/4002-00000007", "1?noautomon2") in new stack -- Goto (macro-hangupcall,s,25) -- Executing [s@macro-hangupcall:25] NoOp("SIP/4002-00000007", "MONITOR_FILENAME=") in new stack -- Executing [s@macro-hangupcall:26] GotoIf("SIP/4002-00000007", "1?skiprg") in new stack -- Goto (macro-hangupcall,s,29) -- Executing [s@macro-hangupcall:29] GotoIf("SIP/4002-00000007", "1?skipblkvm") in new stack -- Goto (macro-hangupcall,s,32) -- Executing [s@macro-hangupcall:32] GotoIf("SIP/4002-00000007", "1?theend") in new stack -- Goto (macro-hangupcall,s,34) -- Executing [s@macro-hangupcall:34] Hangup("SIP/4002-00000007", "") in new stack == Spawn extension (macro-hangupcall, s, 34) exited non-zero on 'SIP/4002-00000007' in macro 'hangupcall' == Spawn extension (from-internal, h, 1) exited non-zero on 'SIP/4002-00000007' localhost*CLI&gt; </code></pre> <p>EDIT:</p> <p>Here's the code I used as a guide. It's an application that comes as a example in the Starpy library. When I put this application I get the same results. I put this because mine is a little tooooo big.</p> <pre><code>#! /usr/bin/env python """Read digits from the user in various ways...""" from twisted.internet import reactor, defer from starpy import fastagi, error import logging, time log = logging.getLogger( 'hellofastagi' ) class DialPlan( object ): """Stupid little application to report how many times it's been accessed""" def __init__( self ): self.count = 0 def __call__( self, agi ): """Store the AGI instance for later usage, kick off our operations""" self.agi = agi return self.start() def start( self ): """Begin the dial-plan-like operations""" return self.agi.answer().addCallbacks( self.onAnswered, self.answerFailure ) def answerFailure( self, reason ): """Deal with a failure to answer""" log.warn( """Unable to answer channel %r: %s""", self.agi.variables['agi_channel'], reason.getTraceback(), ) self.agi.finish() def onAnswered( self, resultLine ): """We've managed to answer the channel, yay!""" self.count += 1 return self.agi.wait( 2.0 ).addCallback( self.onWaited ) def onWaited( self, result ): """We've finished waiting, tell the user the number""" return self.agi.sayNumber( self.count, '*' ).addErrback( self.onNumberFailed, ).addCallbacks( self.onFinished, self.onFinished, ) def onFinished( self, resultLine ): """We said the number correctly, hang up on the user""" return self.agi.finish() def onNumberFailed( self, reason ): """We were unable to read the number to the user""" log.warn( """Unable to read number to user on channel %r: %s""", self.agi.variables['agi_channel'], reason.getTraceback(), ) def onHangupFailure( self, reason ): """Failed trying to hang up""" log.warn( """Unable to hang up channel %r: %s""", self.agi.variables['agi_channel'], reason.getTraceback(), ) if __name__ == "__main__": logging.basicConfig() fastagi.log.setLevel( logging.DEBUG ) f = fastagi.FastAGIFactory(DialPlan()) reactor.listenTCP(4573, f, 50, '10.0.0.167') # only binding on local interface reactor.run() </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload