<div dir="ltr"><div>I agree.</div>
<div> </div>
<div>I have started working on a library like asterisk-java (now onhold but hopefully can continue working on it in a couple of weeks) using groovy (will name it fs-groovy :))</div>
<div> </div>
<div>The way I check if the command was successful is to look for the Event with CHANNEL_EXECUTE_COMPLETE and Application and ApplicationData.</div>
<div> </div>
<div>Here is how I implemented it. Still needs more work though.</div>
<div>--<br></div>
<div>
<table class="code">
<tbody>
<tr>
<td><span class=""></span></td></tr>
<tr>
<th id="L2"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L2">2</a></th>
<td><span class=""></span></td></tr>
<tr>
<th id="L3"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L3">3</a></th>
<td><span class="">import org.apache.mina.common.IoSession</span></td></tr>
<tr>
<th id="L4"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L4">4</a></th>
<td><span class="">import java.util.concurrent.BlockingQueue</span></td></tr>
<tr>
<th id="L5"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L5">5</a></th>
<td><span class="">import java.util.concurrent.Executors</span></td></tr>
<tr>
<th id="L6"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L6">6</a></th>
<td><span class="">import java.util.concurrent.ExecutorService</span></td></tr>
<tr>
<th id="L7"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L7">7</a></th>
<td><span class="">import java.util.concurrent.Future</span></td></tr>
<tr>
<th id="L8"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L8">8</a></th>
<td><span class="">import java.util.concurrent.Callable</span></td></tr>
<tr>
<th id="L9"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L9">9</a></th>
<td><span class="">import java.util.concurrent.ExecutionException</span></td></tr>
<tr>
<th id="L10"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L10">10</a></th>
<td><span class="">import java.util.concurrent.TimeoutException</span></td></tr>
<tr>
<th id="L11"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L11">11</a></th>
<td><span class="">import java.util.concurrent.TimeUnit</span></td></tr>
<tr>
<th id="L12"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L12">12</a></th>
<td><span class=""></span></td></tr>
<tr>
<th id="L13"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L13">13</a></th>
<td><span class=""></span></td></tr>
<tr>
<th id="L14"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L14">14</a></th>
<td><span class=""></span></td></tr>
<tr>
<th id="L15"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L15">15</a></th>
<td><span class="">class Session { </span></td></tr>
<tr>
<th id="L16"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L16">16</a></th>
<td><span class=""> private IoSession session</span></td></tr>
<tr>
<th id="L17"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L17">17</a></th>
<td><span class=""> private FSEventHandler handler</span></td></tr>
<tr>
<th id="L18"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L18">18</a></th>
<td><span class=""> private BlockingQueue<String> msgQ</span></td></tr>
<tr>
<th id="L19"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L19">19</a></th>
<td><span class=""> private final ExecutorService executor = Executors.newSingleThreadExecutor()</span></td></tr>
<tr>
<th id="L20"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L20">20</a></th>
<td><span class=""> private final static long DEFAULT_TIMEOUT = 5000</span></td></tr>
<tr>
<th id="L21"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L21">21</a></th>
<td><span class=""> </span></td></tr>
<tr>
<th id="L22"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L22">22</a></th>
<td><span class=""> def data</span></td></tr>
<tr>
<th id="L23"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L23">23</a></th>
<td><span class=""> </span></td></tr>
<tr>
<th id="L24"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L24">24</a></th>
<td><span class=""> def Session(IoSession s, BlockingQueue q) {</span></td></tr>
<tr>
<th id="L25"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L25">25</a></th>
<td><span class=""> session = s</span></td></tr>
<tr>
<th id="L26"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L26">26</a></th>
<td><span class=""> msgQ = q</span></td></tr>
<tr>
<th id="L27"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L27">27</a></th>
<td><span class=""> }</span></td></tr>
<tr>
<th id="L28"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L28">28</a></th>
<td><span class=""></span></td></tr>
<tr>
<th id="L29"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L29">29</a></th>
<td><span class=""> private def executeAndWait(Closure task, long timeout=0) {</span></td></tr>
<tr>
<th id="L30"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L30">30</a></th>
<td><span class=""> Future <CommandResult> f = executor.submit(task as Callable) </span></td></tr>
<tr>
<th id="L31"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L31">31</a></th>
<td><span class=""> def result</span></td></tr>
<tr>
<th id="L32"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L32">32</a></th>
<td><span class=""> def boolean success = false</span></td></tr>
<tr>
<th id="L33"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L33">33</a></th>
<td><span class=""> try {</span></td></tr>
<tr>
<th id="L34"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L34">34</a></th>
<td><span class=""> if (timeout != 0) {</span></td></tr>
<tr>
<th id="L35"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L35">35</a></th>
<td><span class=""> result = f.get(timeout, TimeUnit.MILLISECONDS)</span></td></tr>
<tr>
<th id="L36"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L36">36</a></th>
<td><span class=""> } else {</span></td></tr>
<tr>
<th id="L37"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L37">37</a></th>
<td><span class=""> result = f.get()</span></td></tr>
<tr>
<th id="L38"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L38">38</a></th>
<td><span class=""> } </span></td></tr>
<tr>
<th id="L39"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L39">39</a></th>
<td><span class=""> if (result.code == CommandResult.OK) data = result.data</span></td></tr>
<tr>
<th id="L40"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L40">40</a></th>
<td><span class=""> } catch (ExecutionException e) {</span></td></tr>
<tr>
<th id="L41"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L41">41</a></th>
<td><span class=""> // Should log here</span></td></tr>
<tr>
<th id="L42"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L42">42</a></th>
<td><span class=""> } catch (TimeoutException e) {</span></td></tr>
<tr>
<th id="L43"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L43">43</a></th>
<td><span class=""> f.cancel(true)</span></td></tr>
<tr>
<th id="L44"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L44">44</a></th>
<td><span class=""> }</span></td></tr>
<tr>
<th id="L45"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L45">45</a></th>
<td><span class=""> </span></td></tr>
<tr>
<th id="L46"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L46">46</a></th>
<td><span class=""> return result</span></td></tr>
<tr>
<th id="L47"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L47">47</a></th>
<td><span class=""> } </span></td></tr>
<tr>
<th id="L48"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L48">48</a></th>
<td><span class=""> </span></td></tr>
<tr>
<th id="L49"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L49">49</a></th>
<td><span class=""> def answer() { </span></td></tr>
<tr>
<th id="L50"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L50">50</a></th>
<td><span class=""> def task = {</span></td></tr>
<tr>
<th id="L51"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L51">51</a></th>
<td><span class=""> def done = false</span></td></tr>
<tr>
<th id="L52"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L52">52</a></th>
<td><span class=""> def r = new CommandResult()</span></td></tr>
<tr>
<th id="L53"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L53">53</a></th>
<td><span class=""> sendMessage("answer")</span></td></tr>
<tr>
<th id="L54"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L54">54</a></th>
<td><span class=""> while (! done) {</span></td></tr>
<tr>
<th id="L55"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L55">55</a></th>
<td><span class=""> def m = msgQ.take()</span></td></tr>
<tr>
<th id="L56"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L56">56</a></th>
<td><span class=""> if ((m?.event?.Name == "CHANNEL_EXECUTE_COMPLETE") && (m?.Application == "answer")) {</span></td></tr>
<tr>
<th id="L57"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L57">57</a></th>
<td><span class=""> done = true</span></td></tr>
<tr>
<th id="L58"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L58">58</a></th>
<td><span class=""> r.code = CommandResult.OK</span></td></tr>
<tr>
<th id="L59"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L59">59</a></th>
<td><span class=""> r.data = m</span></td></tr>
<tr>
<th id="L60"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L60">60</a></th>
<td><span class=""> } </span></td></tr>
<tr>
<th id="L61"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L61">61</a></th>
<td><span class=""> } </span></td></tr>
<tr>
<th id="L62"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L62">62</a></th>
<td><span class=""> return r </span></td></tr>
<tr>
<th id="L63"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L63">63</a></th>
<td><span class=""> }</span></td></tr>
<tr>
<th id="L64"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L64">64</a></th>
<td><span class=""> executeAndWait(task, DEFAULT_TIMEOUT)</span></td></tr>
<tr>
<th id="L65"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L65">65</a></th>
<td><span class=""> }</span></td></tr>
<tr>
<th id="L66"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L66">66</a></th>
<td><span class=""> </span></td></tr>
<tr>
<th id="L67"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L67">67</a></th>
<td><span class=""> def unset(var) {</span></td></tr>
<tr>
<th id="L68"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L68">68</a></th>
<td><span class=""> def task = {</span></td></tr>
<tr>
<th id="L69"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L69">69</a></th>
<td><span class=""> def done = false</span></td></tr>
<tr>
<th id="L70"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L70">70</a></th>
<td><span class=""> def r = new CommandResult()</span></td></tr>
<tr>
<th id="L71"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L71">71</a></th>
<td><span class=""> sendMessage("unset", var)</span></td></tr>
<tr>
<th id="L72"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L72">72</a></th>
<td><span class=""> while (! done) {</span></td></tr>
<tr>
<th id="L73"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L73">73</a></th>
<td><span class=""> def m = msgQ.take()</span></td></tr>
<tr>
<th id="L74"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L74">74</a></th>
<td><span class=""> if ((m?.event?.Name == "CHANNEL_EXECUTE_COMPLETE") </span></td></tr>
<tr>
<th id="L75"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L75">75</a></th>
<td><span class=""> && (m?.Application == "unset")</span></td></tr>
<tr>
<th id="L76"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L76">76</a></th>
<td><span class=""> && (m?.ApplicationData == var)) {</span></td></tr>
<tr>
<th id="L77"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L77">77</a></th>
<td><span class=""> done = true</span></td></tr>
<tr>
<th id="L78"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L78">78</a></th>
<td><span class=""> r.code = CommandResult.OK</span></td></tr>
<tr>
<th id="L79"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L79">79</a></th>
<td><span class=""> r.data = m</span></td></tr>
<tr>
<th id="L80"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L80">80</a></th>
<td><span class=""> } </span></td></tr>
<tr>
<th id="L81"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L81">81</a></th>
<td><span class=""> } </span></td></tr>
<tr>
<th id="L82"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L82">82</a></th>
<td><span class=""> return r </span></td></tr>
<tr>
<th id="L83"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L83">83</a></th>
<td><span class=""> }</span></td></tr>
<tr>
<th id="L84"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L84">84</a></th>
<td><span class=""> executeAndWait(task, DEFAULT_TIMEOUT) </span></td></tr>
<tr>
<th id="L85"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L85">85</a></th>
<td><span class=""> }</span></td></tr>
<tr>
<th id="L86"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L86">86</a></th>
<td><span class=""> </span></td></tr>
<tr>
<th id="L87"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L87">87</a></th>
<td><span class=""> def queueDtmf(dtmfs) {</span></td></tr>
<tr>
<th id="L88"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L88">88</a></th>
<td><span class=""> def task = {</span></td></tr>
<tr>
<th id="L89"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L89">89</a></th>
<td><span class=""> def done = false</span></td></tr>
<tr>
<th id="L90"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L90">90</a></th>
<td><span class=""> def r = new CommandResult()</span></td></tr>
<tr>
<th id="L91"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L91">91</a></th>
<td><span class=""> sendMessage("queue_dtmf", dtmfs)</span></td></tr>
<tr>
<th id="L92"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L92">92</a></th>
<td><span class=""> while (! done) {</span></td></tr>
<tr>
<th id="L93"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L93">93</a></th>
<td><span class=""> def m = msgQ.take()</span></td></tr>
<tr>
<th id="L94"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L94">94</a></th>
<td><span class=""> if ((m?.event?.Name == "CHANNEL_EXECUTE_COMPLETE") </span></td></tr>
<tr>
<th id="L95"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L95">95</a></th>
<td><span class=""> && (m?.Application == "queue_dtmf")</span></td></tr>
<tr>
<th id="L96"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L96">96</a></th>
<td><span class=""> && (m?.ApplicationData == dtmfs)) {</span></td></tr>
<tr>
<th id="L97"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L97">97</a></th>
<td><span class=""> done = true</span></td></tr>
<tr>
<th id="L98"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L98">98</a></th>
<td><span class=""> r.code = CommandResult.OK</span></td></tr>
<tr>
<th id="L99"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L99">99</a></th>
<td><span class=""> r.data = m</span></td></tr>
<tr>
<th id="L100"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L100">100</a></th>
<td><span class=""> } </span></td></tr>
<tr>
<th id="L101"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L101">101</a></th>
<td><span class=""> } </span></td></tr>
<tr>
<th id="L102"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L102">102</a></th>
<td><span class=""> return r </span></td></tr>
<tr>
<th id="L103"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L103">103</a></th>
<td><span class=""> }</span></td></tr>
<tr>
<th id="L104"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L104">104</a></th>
<td><span class=""> executeAndWait(task, DEFAULT_TIMEOUT) </span></td></tr>
<tr>
<th id="L105"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L105">105</a></th>
<td><span class=""> }</span></td></tr>
<tr>
<th id="L106"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L106">106</a></th>
<td><span class=""> </span></td></tr>
<tr>
<th id="L107"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L107">107</a></th>
<td><span class="">/*</span></td></tr>
<tr>
<th id="L108"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L108">108</a></th>
<td><span class=""> def hangup() {</span></td></tr>
<tr>
<th id="L109"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L109">109</a></th>
<td><span class=""> def task = {</span></td></tr>
<tr>
<th id="L110"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L110">110</a></th>
<td><span class=""> def done = false</span></td></tr>
<tr>
<th id="L111"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L111">111</a></th>
<td><span class=""> def r = new CommandResult()</span></td></tr>
<tr>
<th id="L112"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L112">112</a></th>
<td><span class=""> sendMessage("hangup")</span></td></tr>
<tr>
<th id="L113"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L113">113</a></th>
<td><span class=""> while (! done) {</span></td></tr>
<tr>
<th id="L114"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L114">114</a></th>
<td><span class=""> def m = msgQ.take()</span></td></tr>
<tr>
<th id="L115"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L115">115</a></th>
<td><span class=""> if ((m?.event?.Name == "CHANNEL_EXECUTE_COMPLETE") </span></td></tr>
<tr>
<th id="L116"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L116">116</a></th>
<td><span class=""> && (m?.Application == "queue_dtmf")</span></td></tr>
<tr>
<th id="L117"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L117">117</a></th>
<td><span class=""> && (m?.ApplicationData == dtmfs)) {</span></td></tr>
<tr>
<th id="L118"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L118">118</a></th>
<td><span class=""> done = true</span></td></tr>
<tr>
<th id="L119"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L119">119</a></th>
<td><span class=""> r.code = CommandResult.OK</span></td></tr>
<tr>
<th id="L120"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L120">120</a></th>
<td><span class=""> r.data = m</span></td></tr>
<tr>
<th id="L121"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L121">121</a></th>
<td><span class=""> } </span></td></tr>
<tr>
<th id="L122"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L122">122</a></th>
<td><span class=""> } </span></td></tr>
<tr>
<th id="L123"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L123">123</a></th>
<td><span class=""> return r </span></td></tr>
<tr>
<th id="L124"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L124">124</a></th>
<td><span class=""> }</span></td></tr>
<tr>
<th id="L125"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L125">125</a></th>
<td><span class=""> executeAndWait(task, DEFAULT_TIMEOUT) </span></td></tr>
<tr>
<th id="L126"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L126">126</a></th>
<td><span class=""> } </span></td></tr>
<tr>
<th id="L127"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L127">127</a></th>
<td><span class="">*/ </span></td></tr>
<tr>
<th id="L128"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L128">128</a></th>
<td><span class=""></span></td></tr>
<tr>
<th id="L129"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L129">129</a></th>
<td><span class=""> def setVariable(String var, String value) {</span></td></tr>
<tr>
<th id="L130"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L130">130</a></th>
<td><span class=""> def task = {</span></td></tr>
<tr>
<th id="L131"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L131">131</a></th>
<td><span class=""> def done = false</span></td></tr>
<tr>
<th id="L132"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L132">132</a></th>
<td><span class=""> def r = new CommandResult()</span></td></tr>
<tr>
<th id="L133"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L133">133</a></th>
<td><span class=""> sendMessage("set", "${var}=${value}")</span></td></tr>
<tr>
<th id="L134"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L134">134</a></th>
<td><span class=""> while (! done) {</span></td></tr>
<tr>
<th id="L135"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L135">135</a></th>
<td><span class=""> def m = msgQ.take()</span></td></tr>
<tr>
<th id="L136"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L136">136</a></th>
<td><span class=""> if ((m?.event?.Name == "CHANNEL_EXECUTE_COMPLETE") </span></td></tr>
<tr>
<th id="L137"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L137">137</a></th>
<td><span class=""> && (m?.Application == "set")</span></td></tr>
<tr>
<th id="L138"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L138">138</a></th>
<td><span class=""> && (m?.ApplicationData == "${var}=${value}")) {</span></td></tr>
<tr>
<th id="L139"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L139">139</a></th>
<td><span class=""> done = true</span></td></tr>
<tr>
<th id="L140"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L140">140</a></th>
<td><span class=""> r.code = CommandResult.OK</span></td></tr>
<tr>
<th id="L141"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L141">141</a></th>
<td><span class=""> r.data = m</span></td></tr>
<tr>
<th id="L142"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L142">142</a></th>
<td><span class=""> } </span></td></tr>
<tr>
<th id="L143"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L143">143</a></th>
<td><span class=""> } </span></td></tr>
<tr>
<th id="L144"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L144">144</a></th>
<td><span class=""> return r </span></td></tr>
<tr>
<th id="L145"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L145">145</a></th>
<td><span class=""> }</span></td></tr>
<tr>
<th id="L146"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L146">146</a></th>
<td><span class=""> executeAndWait(task, DEFAULT_TIMEOUT) </span></td></tr>
<tr>
<th id="L147"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L147">147</a></th>
<td><span class=""> </span></td></tr>
<tr>
<th id="L148"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L148">148</a></th>
<td><span class=""> }</span></td></tr>
<tr>
<th id="L149"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L149">149</a></th>
<td><span class=""> </span></td></tr>
<tr>
<th id="L150"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L150">150</a></th>
<td><span class=""> def export(String var) {</span></td></tr>
<tr>
<th id="L151"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L151">151</a></th>
<td><span class=""> set("export_vars", var)</span></td></tr>
<tr>
<th id="L152"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L152">152</a></th>
<td><span class=""> }</span></td></tr>
<tr>
<th id="L153"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L153">153</a></th>
<td><span class=""> </span></td></tr>
<tr>
<th id="L154"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L154">154</a></th>
<td><span class=""> def bridge(String number) {</span></td></tr>
<tr>
<th id="L155"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L155">155</a></th>
<td><span class=""> def task = {</span></td></tr>
<tr>
<th id="L156"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L156">156</a></th>
<td><span class=""> def done = false</span></td></tr>
<tr>
<th id="L157"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L157">157</a></th>
<td><span class=""> def r = new CommandResult()</span></td></tr>
<tr>
<th id="L158"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L158">158</a></th>
<td><span class=""> sendMessage("bridge", number)</span></td></tr>
<tr>
<th id="L159"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L159">159</a></th>
<td><span class=""> while (! done) {</span></td></tr>
<tr>
<th id="L160"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L160">160</a></th>
<td><span class=""> def m = msgQ.take()</span></td></tr>
<tr>
<th id="L161"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L161">161</a></th>
<td><span class="">// println m</span></td></tr>
<tr>
<th id="L162"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L162">162</a></th>
<td><span class=""> if (((m?.event?.Name == "CHANNEL_EXECUTE_COMPLETE") </span></td></tr>
<tr>
<th id="L163"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L163">163</a></th>
<td><span class=""> && (m?.Application == "bridge")</span></td></tr>
<tr>
<th id="L164"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L164">164</a></th>
<td><span class=""> && (m?.ApplicationData == number)) ||</span></td></tr>
<tr>
<th id="L165"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L165">165</a></th>
<td><span class=""> ((m?.event?.Name == "CHANNEL_UNBRIDGE") </span></td></tr>
<tr>
<th id="L166"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L166">166</a></th>
<td><span class=""> && (m?.variable.bridge_channel == number)) || (m?.SESSIONCLOSED == "true")) {</span></td></tr>
<tr>
<th id="L167"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L167">167</a></th>
<td><span class=""> done = true</span></td></tr>
<tr>
<th id="L168"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L168">168</a></th>
<td><span class=""> r.code = CommandResult.OK</span></td></tr>
<tr>
<th id="L169"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L169">169</a></th>
<td><span class=""> r.data = m</span></td></tr>
<tr>
<th id="L170"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L170">170</a></th>
<td><span class=""> } </span></td></tr>
<tr>
<th id="L171"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L171">171</a></th>
<td><span class=""> } </span></td></tr>
<tr>
<th id="L172"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L172">172</a></th>
<td><span class=""> return r </span></td></tr>
<tr>
<th id="L173"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L173">173</a></th>
<td><span class=""> }</span></td></tr>
<tr>
<th id="L174"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L174">174</a></th>
<td><span class=""> executeAndWait(task)</span></td></tr>
<tr>
<th id="L175"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L175">175</a></th>
<td><span class=""> }</span></td></tr>
<tr>
<th id="L176"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L176">176</a></th>
<td><span class=""> </span></td></tr>
<tr>
<th id="L177"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L177">177</a></th>
<td><span class=""> def promptForDigits(int min, int max, String soundFile, String variableName, long timeout, String terminator) {</span></td></tr>
<tr>
<th id="L178"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L178">178</a></th>
<td><span class=""> def task = {</span></td></tr>
<tr>
<th id="L179"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L179">179</a></th>
<td><span class=""> def done = false</span></td></tr>
<tr>
<th id="L180"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L180">180</a></th>
<td><span class=""> def r = new CommandResult()</span></td></tr>
<tr>
<th id="L181"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L181">181</a></th>
<td><span class=""> def appData = "${min} ${max} ${soundFile} ${variableName} ${timeout} ${terminator}"</span></td></tr>
<tr>
<th id="L182"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L182">182</a></th>
<td><span class=""> sendMessage("read", appData, true)</span></td></tr>
<tr>
<th id="L183"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L183">183</a></th>
<td><span class=""> while (! done) {</span></td></tr>
<tr>
<th id="L184"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L184">184</a></th>
<td><span class=""> def m = msgQ.take()</span></td></tr>
<tr>
<th id="L185"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L185">185</a></th>
<td><span class=""> if ((m?.event?.Name == "CHANNEL_EXECUTE_COMPLETE") </span></td></tr>
<tr>
<th id="L186"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L186">186</a></th>
<td><span class=""> && (m?.Application == "read")</span></td></tr>
<tr>
<th id="L187"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L187">187</a></th>
<td><span class=""> && (m?.ApplicationData == appData)) {</span></td></tr>
<tr>
<th id="L188"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L188">188</a></th>
<td><span class=""> done = true</span></td></tr>
<tr>
<th id="L189"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L189">189</a></th>
<td><span class=""> r.code = CommandResult.OK</span></td></tr>
<tr>
<th id="L190"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L190">190</a></th>
<td><span class=""> r.data = m</span></td></tr>
<tr>
<th id="L191"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L191">191</a></th>
<td><span class=""> } </span></td></tr>
<tr>
<th id="L192"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L192">192</a></th>
<td><span class=""> } </span></td></tr>
<tr>
<th id="L193"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L193">193</a></th>
<td><span class=""> return r </span></td></tr>
<tr>
<th id="L194"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L194">194</a></th>
<td><span class=""> }</span></td></tr>
<tr>
<th id="L195"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L195">195</a></th>
<td><span class=""> executeAndWait(task, timeout)</span></td></tr>
<tr>
<th id="L196"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L196">196</a></th>
<td><span class=""> }</span></td></tr>
<tr>
<th id="L197"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L197">197</a></th>
<td><span class=""> </span></td></tr>
<tr>
<th id="L198"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L198">198</a></th>
<td><span class=""> def originate(String url) {</span></td></tr>
<tr>
<th id="L199"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L199">199</a></th>
<td><span class=""> sendMessage("originate", url, true)</span></td></tr>
<tr>
<th id="L200"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L200">200</a></th>
<td><span class=""> }</span></td></tr>
<tr>
<th id="L201"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L201">201</a></th>
<td><span class=""> </span></td></tr>
<tr>
<th id="L202"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L202">202</a></th>
<td><span class=""> def sleep(int sec) {</span></td></tr>
<tr>
<th id="L203"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L203">203</a></th>
<td><span class=""> sendMessage("sleep", new Integer(sec*1000).toString())</span></td></tr>
<tr>
<th id="L204"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L204">204</a></th>
<td><span class=""> }</span></td></tr>
<tr>
<th id="L205"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L205">205</a></th>
<td><span class=""> </span></td></tr>
<tr>
<th id="L206"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L206">206</a></th>
<td><span class=""> def say(String phrase) {</span></td></tr>
<tr>
<th id="L207"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L207">207</a></th>
<td><span class=""> sendMessage("phrase", "spell,$phrase")</span></td></tr>
<tr>
<th id="L208"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L208">208</a></th>
<td><span class=""> }</span></td></tr>
<tr>
<th id="L209"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L209">209</a></th>
<td><span class=""> </span></td></tr>
<tr>
<th id="L210"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L210">210</a></th>
<td><span class=""> def script() {</span></td></tr>
<tr>
<th id="L211"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L211">211</a></th>
<td><span class=""> return "jeprox"</span></td></tr>
<tr>
<th id="L212"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L212">212</a></th>
<td><span class=""> }</span></td></tr>
<tr>
<th id="L213"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L213">213</a></th>
<td><span class=""> </span></td></tr>
<tr>
<th id="L214"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L214">214</a></th>
<td><span class=""> private def sendMessage(String app, String arg=null, boolean event_lock=false) { </span></td></tr>
<tr>
<th id="L215"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L215">215</a></th>
<td><span class=""> String msg = "sendmsg\ncall-command: execute\nexecute-app-name: ${app}"</span></td></tr>
<tr>
<th id="L216"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L216">216</a></th>
<td><span class=""> if (arg) {</span></td></tr>
<tr>
<th id="L217"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L217">217</a></th>
<td><span class=""> msg += "\nexecute-app-arg: ${arg}"</span></td></tr>
<tr>
<th id="L218"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L218">218</a></th>
<td><span class=""> }</span></td></tr>
<tr>
<th id="L219"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L219">219</a></th>
<td><span class=""> if (event_lock) {</span></td></tr>
<tr>
<th id="L220"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L220">220</a></th>
<td><span class=""> msg += "\nevent-lock: ${event_lock}"</span></td></tr>
<tr>
<th id="L221"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L221">221</a></th>
<td><span class=""> }</span></td></tr>
<tr>
<th id="L222"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L222">222</a></th>
<td><span class=""> System.out.println(msg)</span></td></tr>
<tr>
<th id="L223"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L223">223</a></th>
<td><span class=""> session.write("$msg\n\n")</span></td></tr>
<tr>
<th id="L224"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L224">224</a></th>
<td><span class=""> }</span></td></tr>
<tr>
<th id="L225"><a href="http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L225">225</a></th>
<td><span class="">}</span></td></tr></tbody></table><br></div>
<div class="gmail_quote">On Thu, Sep 18, 2008 at 5:49 PM, Luke Graybill <span dir="ltr"><<a href="mailto:killarny@gmail.com">killarny@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: #ccc 1px solid">
<div dir="ltr">I've been doing a lot of work recently with FreeSWITCH's mod_event_socket, and I wanted to comment a bit about the syntax used for commands through the socket while using asynchronous mode. I haven't tried the synchronous mode yet, as I always want to be free to be able to execute commands without waiting for other commands to finish. For instance, I need to be able to collect DTMF events while I'm playing a sound file, so that the user can do things like select menu items without listening to the entire menu first.<br>
<br>Asterisk's AMI protocol allows you to specify an ActionID along with every command that you send. Asterisk then includes this ActionID with every event that is related to that command, making it cake to coordinate an asynchronous client.<br>
<br>However, even in async mode, FreeSWITCH's mod_event_socket doesn't communicate any identifying information for command responses, or for events triggered by a previous command, unless one uses the bgapi command set. This command set is not applicable to every situation, though. It only applies to commands which manipulate the call; if one needs to manipulate the channel, then messages must be used through the sendmsg command set, which doesn't provide any specific identifying information.<br>
<br>Now, to complicate things, with all commands (even bgapi) the protocol works something like this: you send a command, and wait for a response from mod_event_socket. This response is assumed to be immediate before anything else the client might receive from mod_event_socket, and in the case of bgapi, this response will contain a job-id to use for comparing job-related events later.<br>
<br>For example, for the following command:<br><br>
<div style="MARGIN-LEFT: 40px"><span style="FONT-FAMILY: verdana,sans-serif">sendmsg</span><br style="FONT-FAMILY: verdana,sans-serif"><span style="FONT-FAMILY: verdana,sans-serif">call-command: execute</span><br><span style="FONT-FAMILY: verdana,sans-serif">execute-app-name: answer\n\n</span><br style="FONT-FAMILY: verdana,sans-serif">
</div><br>The response is this:<br><br>
<div style="MARGIN-LEFT: 40px"><span style="FONT-FAMILY: verdana,sans-serif">Content-Type: command/reply</span><br style="FONT-FAMILY: verdana,sans-serif"><span style="FONT-FAMILY: verdana,sans-serif">Reply-Text: +OK</span><br style="FONT-FAMILY: verdana,sans-serif">
</div><br>That response is generic to nearly every single command sent, and is only really saying "The last transmission was a valid command, and didn't immediately fail". The command may actually fail later, and command specific feedback is generally contained in later events (which have no unique identifying information).<br>
<br>My issue here is that this seems to be forcing an asynchronous client to rely upon a synchronous ordering of response directly following command, thus violating the very concepts of an asynchronous protocol in which there should be no assumed order. Not only that, but this method increases the complexity of a client, which must be aware of limitations that wouldn't ordinarily be required by a true asynchronous protocol. An asynchronous client should be unconcerned with listening for a synchronous response to every command.<br>
<br>My suggested solution is to apply the job-id concept from bgapi to messages as well, and to go a step further; borrow the Asterisk idea of transmitting an identifier along with each command. Every response and event related to that command should then contain the very same identifier in the header.</div>
<br>_______________________________________________<br>Freeswitch-users mailing list<br><a href="mailto:Freeswitch-users@lists.freeswitch.org">Freeswitch-users@lists.freeswitch.org</a><br><a href="http://lists.freeswitch.org/mailman/listinfo/freeswitch-users" target="_blank">http://lists.freeswitch.org/mailman/listinfo/freeswitch-users</a><br>
UNSUBSCRIBE:<a href="http://lists.freeswitch.org/mailman/options/freeswitch-users" target="_blank">http://lists.freeswitch.org/mailman/options/freeswitch-users</a><br><a href="http://www.freeswitch.org/" target="_blank">http://www.freeswitch.org</a><br>
<br></blockquote></div><br></div>