<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[Freeswitch-trunk][15040] </title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<div id="header">FreeSWITCH Subversion</div>
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://fisheye.freeswitch.org/changelog/FreeSWITCH?cs=15040">15040</a></dd>
<dt>Author</dt> <dd>gled</dd>
<dt>Date</dt> <dd>2009-10-02 04:42:09 -0500 (Fri, 02 Oct 2009)</dd>
</dl>

<h3>Log Message</h3>
<pre>stream_file OK, still waiting for <a href="http://jira.freeswitch.org/browse/FSCORE-455">FSCORE-455</a> to get return values</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#freeswitchtrunkcontribgledesl2agiesl2agic">freeswitch/trunk/contrib/gled/esl2agi/esl2agi.c</a></li>
<li><a href="#freeswitchtrunkcontribgledesl2agiesl2agih">freeswitch/trunk/contrib/gled/esl2agi/esl2agi.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="freeswitchtrunkcontribgledesl2agiesl2agic"></a>
<div class="modfile"><h4>Modified: freeswitch/trunk/contrib/gled/esl2agi/esl2agi.c (15039 => 15040)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/contrib/gled/esl2agi/esl2agi.c        2009-10-01 22:56:33 UTC (rev 15039)
+++ freeswitch/trunk/contrib/gled/esl2agi/esl2agi.c        2009-10-02 09:42:09 UTC (rev 15040)
</span><span class="lines">@@ -47,7 +47,7 @@
</span><span class="cx">         esl_handle_t eslC = {{0}};
</span><span class="cx"> 
</span><span class="cx">         char script_path[1024] = &quot;\0&quot;;
</span><del>-        const char *buf;
</del><ins>+        char *buf;
</ins><span class="cx">         int pid;
</span><span class="cx">         int thread_running;
</span><span class="cx"> 
</span><span class="lines">@@ -94,6 +94,7 @@
</span><span class="cx">                 close(pipes.socket[1]);
</span><span class="cx">                 close(pipes.script[0]);
</span><span class="cx">                 close(esl_req.client_sock);
</span><ins>+                close(STDERR_FILENO);
</ins><span class="cx"> 
</span><span class="cx">                 dup2(pipes.socket[0], STDIN_FILENO);
</span><span class="cx">                 dup2(pipes.script[1], STDOUT_FILENO);
</span><span class="lines">@@ -114,19 +115,16 @@
</span><span class="cx"> 
</span><span class="cx">                 signal(SIGCHLD, SIG_IGN);
</span><span class="cx">                 signal(SIGPIPE, SIG_IGN);
</span><del>-
</del><ins>+                // fprintf(stderr,&quot;New call, handling setup...\n&quot;);
</ins><span class="cx">                 handle_setup_env(pipes.socket[1],&amp;eslC);
</span><span class="cx"> 
</span><span class="cx">                 /* TODO: check status */
</span><span class="cx">                 status = esl_send(&amp;eslC,&quot;myevents&quot;);
</span><del>-                eslC.async_execute = 0;
</del><ins>+                eslC.async_execute = 1;
</ins><span class="cx">                 while ( eslC.connected &amp;&amp; thread_running) {
</span><span class="cx">                         int r , nfds = 0;
</span><span class="cx">                         fd_set rd;
</span><span class="cx"> 
</span><del>-                        /* As we are in sync mode, we should NOT care about socket there, 
-                         * there is a binding of esl_execute to find command results
-                         */
</del><span class="cx">                         FD_ZERO(&amp;rd);
</span><span class="cx">                         FD_SET(pipes.script[0], &amp;rd);
</span><span class="cx">                         nfds = MAX(nfds,pipes.script[0]);
</span><span class="lines">@@ -135,13 +133,13 @@
</span><span class="cx">                         if (r == -1 )
</span><span class="cx">                                 break;
</span><span class="cx">                         else if (FD_ISSET(pipes.script[0],&amp;rd) ) { /* AGI has something to say */
</span><del>-                                bzero(&amp;sbuf,2047);
</del><span class="cx">                                 r = read(pipes.script[0],&amp;sbuf,2047);
</span><span class="cx">                                 if (r&lt;0)
</span><span class="cx">                                         goto end;
</span><span class="cx">                                 else {
</span><span class="cx">                                         /*TODO: correct ugly hack to remove final \n */
</span><span class="cx">                                         sbuf[r-1] = '\0';
</span><ins>+                                        // fprintf(stderr,&quot;Treating: '%s'\n&quot;,sbuf);
</ins><span class="cx">                                         if ( find_and_exec_command(&amp;eslC,pipes.socket[1],(char *) &amp;sbuf) &lt; 0 )
</span><span class="cx">                                                 goto end;
</span><span class="cx">                                 }
</span><span class="lines">@@ -199,7 +197,7 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         if (!(ip &amp;&amp; port)) {
</span><del>-                fprintf(stderr, &quot;Usage %s -h &lt;host&gt; -p &lt;port&gt;\n&quot;, argv[0]);
</del><ins>+                // fprintf(stderr, &quot;Usage %s -h &lt;host&gt; -p &lt;port&gt;\n&quot;, argv[0]);
</ins><span class="cx">                 return -1;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -210,175 +208,134 @@
</span><span class="cx">         return 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static int safe_int_snprintf_buffer(char **buf,const char *format, int ret) {
+        int size;
+        size = 2 + strlen(format); // Max 2 digits in int
+        if (*buf != NULL)
+                *buf = realloc(*buf,size+1);
+        else
+                *buf = malloc(size +1);
+        memset(*buf,0,size+1);
+        size = snprintf(*buf,size+1,format,ret);
+        return size;
+}
+
+/*
+ * Return malloc'd buf containing header value specified with %format
+ */
+static int fill_buffer_from_header(esl_event_t *event,char **buf,char *header,const char *format) {
+        int size=0;
+        char *sbuf;
+        sbuf = esl_event_get_header(event, header);
+        if (sbuf) {
+                size = strlen(sbuf) + strlen(format);
+                if (*buf == NULL)
+                        *buf = malloc(size+1);
+                else
+                        *buf = realloc(*buf,size+1);
+                memset(*buf,0,size+1);
+                size = snprintf(*buf,size,format,sbuf);
+        }
+        return size;
+}
+
</ins><span class="cx"> /* Setup env 
</span><del>- * TODO:        - correct parameters
- *                - add a generic routine instead of blindly repeating code
</del><ins>+ * TODO:        - check size, if no header found we should not block
</ins><span class="cx">  */
</span><span class="cx"> static int handle_setup_env(int fd,esl_handle_t *eslC) {
</span><del>-        char buf[1024];
-        char *sbuf;
</del><ins>+        char *sbuf=NULL;
+        int size;
</ins><span class="cx"> 
</span><span class="cx">         /* Setup Env for AGI scripts */
</span><del>-        if ( (sbuf = esl_event_get_header(eslC-&gt;info_event, &quot;variable_ivr_path&quot;)) ) {
-                sprintf(buf,&quot;agi_request: %s\n&quot;,sbuf);
-                if ( write(fd, buf,strlen(buf) ) &lt; 0)
</del><ins>+        if ( (size = fill_buffer_from_header(eslC-&gt;info_event,&amp;sbuf,&quot;variable_ivr_path&quot;,&quot;agi_request: %s\n&quot;) ) &gt; 0) {
+                if ( write(fd,sbuf,size) &lt; 0)
</ins><span class="cx">                         return -1;
</span><span class="cx">         }
</span><span class="cx">         else
</span><del>-                return -1;
</del><ins>+                        return -1;
</ins><span class="cx"> 
</span><del>-        if ( (sbuf = esl_event_get_header(eslC-&gt;info_event, &quot;variable_channel_name&quot;)) ) {
-                sprintf(buf,&quot;agi_channel: %s\n&quot;,sbuf);
-                if ( write(fd, buf,strlen(buf) ) &lt; 0)
</del><ins>+        if ( (size = fill_buffer_from_header(eslC-&gt;info_event,&amp;sbuf,&quot;variable_channel_name&quot;,&quot;agi_channel: %s\n&quot;) ) &gt; 0) {
+                if ( write(fd,sbuf,size) &lt; 0)
</ins><span class="cx">                         return -1;
</span><span class="cx">         }
</span><span class="cx">         else
</span><del>-                return -1;
</del><ins>+                        return -1;
</ins><span class="cx"> 
</span><del>-        if ( write(fd, &quot;agi_language: en\n&quot;,18) &lt; 0 )
</del><ins>+        if ( write(fd, &quot;agi_language: en\n&quot;,strlen(&quot;agi_language: en\n&quot;) ) &lt; 0 )
</ins><span class="cx">                 return -1;
</span><span class="cx"> 
</span><del>-        if ( (sbuf = esl_event_get_header(eslC-&gt;info_event, &quot;Channel-Source&quot;)) ) {
-                sprintf(buf, &quot;agi_type: %s\n&quot;, sbuf);
-                if ( write(fd, buf,strlen(buf) ) &lt; 0)
</del><ins>+        if ( (size = fill_buffer_from_header(eslC-&gt;info_event,&amp;sbuf,&quot;Channel-Source&quot;,&quot;agi_type: %s\n&quot;) ) &gt; 0) {
+                if ( write(fd,sbuf,size) &lt; 0)
</ins><span class="cx">                         return -1;
</span><span class="cx">         }
</span><span class="cx">         else
</span><del>-                return -1;
</del><ins>+                        return -1;
</ins><span class="cx"> 
</span><del>-        if ( (sbuf = esl_event_get_header(eslC-&gt;info_event, &quot;Channel-Unique-ID&quot;)) ) {
-                sprintf(buf, &quot;agi_uniqueid: %s\n&quot;, sbuf);
-                if ( write(fd, buf,strlen(buf) ) &lt; 0)
</del><ins>+        if ( (size = fill_buffer_from_header(eslC-&gt;info_event,&amp;sbuf,&quot;Channel-Unique-ID&quot;,&quot;agi_uniqueid: %s\n&quot;) ) &gt; 0) {
+                if ( write(fd,sbuf,size) &lt; 0)
</ins><span class="cx">                         return -1;
</span><span class="cx">         }
</span><span class="cx">         else
</span><del>-                return -1;
</del><ins>+                        return -1;
</ins><span class="cx"> 
</span><del>-        /* ANI/DNIS */
-        if ( (sbuf = esl_event_get_header(eslC-&gt;info_event, &quot;Channel-Caller-ID-Number&quot;)) ) {
-                sprintf(buf, &quot;agi_callerid: %s\n&quot;, sbuf);
-                if ( write(fd, buf,strlen(buf) ) &lt; 0)
</del><ins>+        if ( (size = fill_buffer_from_header(eslC-&gt;info_event,&amp;sbuf,&quot;Channel-Caller-ID-Number&quot;,&quot;agi_callerid: %s\n&quot;) ) &gt; 0) {
+                if ( write(fd,sbuf,size) &lt; 0)
</ins><span class="cx">                         return -1;
</span><span class="cx">         }
</span><del>-        else {
-                sprintf(buf, &quot;agi_callerid: %s\n&quot;, &quot;unknown&quot;);
-                if ( write(fd, buf,strlen(buf) ) &lt; 0)
</del><ins>+        else
</ins><span class="cx">                         return -1;
</span><del>-        }
-        if ( (sbuf = esl_event_get_header(eslC-&gt;info_event, &quot;Channel-Caller-ID-Name&quot;)) ) {
-                sprintf(buf, &quot;agi_calleridname: %s\n&quot;, sbuf);
-                if ( write(fd, buf,strlen(buf) ) &lt; 0)
</del><ins>+
+        if ( (size = fill_buffer_from_header(eslC-&gt;info_event,&amp;sbuf,&quot;Channel-Caller-ID-Name&quot;,&quot;agi_calleridname: %s\n&quot;) ) &gt; 0) {
+                if ( write(fd,sbuf,size) &lt; 0)
</ins><span class="cx">                         return -1;
</span><span class="cx">         }
</span><del>-        else {
-                sprintf(buf, &quot;agi_calleridname: %s\n&quot;, &quot;unknown&quot;);
-                if ( write(fd, buf,strlen(buf) ) &lt; 0)
</del><ins>+        else
</ins><span class="cx">                         return -1;
</span><del>-        }
</del><span class="cx"> 
</span><del>-        if ( (sbuf = esl_event_get_header(eslC-&gt;info_event, &quot;Channel-Screen-Bit&quot;)) ) {
-                sprintf(buf, &quot;agi_callingpres: %s\n&quot;, sbuf);
-                if ( write(fd, buf,strlen(buf) ) &lt; 0)
</del><ins>+        if ( (size = fill_buffer_from_header(eslC-&gt;info_event,&amp;sbuf,&quot;Channel-Screen-Bit&quot;,&quot;agi_callingpres: %s\n&quot;) ) &gt; 0) {
+                if ( write(fd,sbuf,size) &lt; 0)
</ins><span class="cx">                         return -1;
</span><span class="cx">         }
</span><del>-        else {
-                sprintf(buf, &quot;agi_callingpres: %s\n&quot;, &quot;unknown&quot;);
-                if ( write(fd, buf,strlen(buf) ) &lt; 0)
</del><ins>+        else
</ins><span class="cx">                         return -1;
</span><del>-        }
-        /* TODO */
-        if ( (sbuf = esl_event_get_header(eslC-&gt;info_event, &quot;Caller-Caller-ID-Number&quot;)) ) {
-                sprintf(buf, &quot;agi_callingani2: %s\n&quot;, sbuf);
-                if ( write(fd, buf,strlen(buf) ) &lt; 0)
-                        return -1;
-        }
-        else {
-                sprintf(buf, &quot;agi_callingani2: %s\n&quot;, &quot;unknown&quot;);
-                if ( write(fd, buf,strlen(buf) ) &lt; 0)
-                        return -1;
-        }
-        /* TODO */
-        if ( (sbuf = esl_event_get_header(eslC-&gt;info_event, &quot;Caller-Caller-ID-Number&quot;)) ) {
-                sprintf(buf, &quot;agi_callington: %s\n&quot;, sbuf);
-                if ( write(fd, buf,strlen(buf) ) &lt; 0)
-                        return -1;
-        }
-        else {
-                sprintf(buf, &quot;agi_callington: %s\n&quot;, &quot;unknown&quot;);
-                if ( write(fd, buf,strlen(buf) ) &lt; 0)
-                        return -1;
-        }
-        if ( (sbuf = esl_event_get_header(eslC-&gt;info_event, &quot;Caller-Destination-Number&quot;)) ) {
-                sprintf(buf, &quot;agi_dnid: %s\n&quot;, sbuf);
-                if ( write(fd, buf,strlen(buf) ) &lt; 0)
-                        return -1;
-        }
-        else {
-                sprintf(buf, &quot;agi_dnid: %s\n&quot;, &quot;unknown&quot;);
-                if ( write(fd, buf,strlen(buf) ) &lt; 0)
-                        return -1;
-        }
-        /* TODO */
-        if ( (sbuf = esl_event_get_header(eslC-&gt;info_event, &quot;Caller-Destination-Number&quot;)) ) {
-                sprintf(buf, &quot;agi_callingtns: %s\n&quot;, sbuf);
-                if ( write(fd, buf,strlen(buf) ) &lt; 0)
-                        return -1;
-        }
-        else {
-                sprintf(buf, &quot;agi_callingtns: %s\n&quot;, &quot;unknown&quot;);
-                if ( write(fd, buf,strlen(buf) ) &lt; 0)
-                        return -1;
-        }
</del><span class="cx"> 
</span><del>-        /* TODO: correct info */
-        if ( (sbuf = esl_event_get_header(eslC-&gt;info_event, &quot;Caller-Destination-Number&quot;)) ) {
-                sprintf(buf, &quot;agi_rdnis: %s\n&quot;, sbuf);
-                if ( write(fd, buf,strlen(buf) ) &lt; 0)
</del><ins>+        if ( (size = fill_buffer_from_header(eslC-&gt;info_event,&amp;sbuf,&quot;Caller-Destination-Number&quot;,&quot;agi_dnid: %s\n&quot;) ) &gt; 0) {
+                if ( write(fd,sbuf,size) &lt; 0)
</ins><span class="cx">                         return -1;
</span><span class="cx">         }
</span><del>-        else {
-                sprintf(buf, &quot;agi_rdnis: %s\n&quot;, &quot;unknown&quot;);
-                if ( write(fd, buf,strlen(buf) ) &lt; 0)
</del><ins>+        else
</ins><span class="cx">                         return -1;
</span><del>-        }
-        if ( (sbuf = esl_event_get_header(eslC-&gt;info_event, &quot;Channel-Context&quot;)) ) {
-                sprintf(buf, &quot;agi_context: %s\n&quot;, sbuf);
-                if ( write(fd, buf,strlen(buf) ) &lt; 0)
-                        return -1;
-        }
-        else {
-                sprintf(buf, &quot;agi_context: %s\n&quot;, &quot;unknown&quot;);
-                if ( write(fd, buf,strlen(buf) ) &lt; 0)
-                        return -1;
-        }
</del><span class="cx"> 
</span><del>-        if ( (sbuf = esl_event_get_header(eslC-&gt;info_event, &quot;Channel-Destination-Number&quot;)) ) {
-                sprintf(buf, &quot;agi_extension: %s\n&quot;, sbuf);
-                if ( write(fd, buf,strlen(buf) ) &lt; 0)
</del><ins>+        if ( (size = fill_buffer_from_header(eslC-&gt;info_event,&amp;sbuf,&quot;Channel-Context&quot;,&quot;agi_context: %s\n&quot;) ) &gt; 0) {
+                if ( write(fd,sbuf,size) &lt; 0)
</ins><span class="cx">                         return -1;
</span><span class="cx">         }
</span><del>-        else {
-                sprintf(buf, &quot;agi_extension: %s\n&quot;, &quot;unknown&quot;);
-                if ( write(fd, buf,strlen(buf) ) &lt; 0)
</del><ins>+        else
</ins><span class="cx">                         return -1;
</span><del>-        }
</del><span class="cx"> 
</span><del>-        /* TODO: correct info */
-        if ( (sbuf = esl_event_get_header(eslC-&gt;info_event, &quot;Channel-State-Number&quot;)) ) {
-                sprintf(buf, &quot;agi_priority: %s\n&quot;, sbuf);
-                if ( write(fd, buf,strlen(buf) ) &lt; 0)
</del><ins>+        if ( (size = fill_buffer_from_header(eslC-&gt;info_event,&amp;sbuf,&quot;Channel-Destination-Number&quot;,&quot;agi_extension: %s\n&quot;) ) &gt; 0) {
+                if ( write(fd,sbuf,size) &lt; 0)
</ins><span class="cx">                         return -1;
</span><span class="cx">         }
</span><del>-        else {
-                sprintf(buf, &quot;agi_priority: %s\n&quot;, &quot;unknown&quot;);
-                if ( write(fd, buf,strlen(buf) ) &lt; 0)
</del><ins>+        else
</ins><span class="cx">                         return -1;
</span><del>-        }
</del><span class="cx"> 
</span><del>-        if ( write(fd, &quot;agi_enhanced: 0.0\n&quot;, 19) &lt; 0 )
</del><ins>+        /* TODO 
+         * agi_callingani2
+         * agi_callington
+         * agi_callingtns
+         * agi_rdnis
+         * agi_priority
+         */
+
+        if ( write(fd, &quot;agi_enhanced: 0.0\n&quot;, strlen(&quot;agi_enhanced: 0.0\n&quot;) ) &lt; 0 )
</ins><span class="cx">                 return -1;
</span><del>-        if ( write(fd, &quot;agi_accountcode: \n\n&quot;, 21) &lt; 0 )
</del><ins>+        if ( write(fd, &quot;agi_accountcode: \n&quot;, strlen(&quot;agi_accountcode: \n&quot;) ) &lt; 0 )
</ins><span class="cx">                 return -1;
</span><ins>+
+        if ( write(fd, &quot;\n\n&quot;, 2 ) &lt; 0 )
+                return -1;
+
</ins><span class="cx">         return 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -393,7 +350,7 @@
</span><span class="cx">         if ( esl_execute(eslC,cmd,args,uuid) != ESL_FAIL) {
</span><span class="cx">                 while (!done &amp;&amp; eslC-&gt;connected) {
</span><span class="cx">                         if (esl_recv_event(eslC,1,NULL) == ESL_FAIL)
</span><del>-                                return -1;
</del><ins>+                                return -1; // Maybe point of failure
</ins><span class="cx">                         else if (eslC-&gt;last_ievent) {
</span><span class="cx">                                 if (eslC-&gt;last_ievent-&gt;event_id == ESL_EVENT_CHANNEL_EXECUTE_COMPLETE ) {
</span><span class="cx">                                         if (! strcasecmp(cmd,esl_event_get_header(eslC-&gt;last_ievent,&quot;Application&quot;) ) )
</span><span class="lines">@@ -410,41 +367,51 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> /*
</span><del>- * Hangup AGI cmd
- * TODO:        - Add arg support to know which channel we want to hangup.
</del><ins>+ * Answer AGI cmd
+ * TODO: Why is there an A on the AGI side ?
</ins><span class="cx">  */
</span><del>-static int handle_hangup(esl_handle_t *eslC,int fd,int *argc, char *argv[]) {
-        if (do_execute(eslC,&quot;hangup&quot;,NULL,NULL,NULL) &lt; 0 ) {
-                if ( write(fd,&quot;200 result=-1\n\n&quot;,128) &lt; 0 )
-                        return -1;
-        }
-        else {
-                if ( write(fd,&quot;200 result=0\n\n&quot;,128) &lt; 0 )
-                        return -1;
-        }
-        return 0;
</del><ins>+static int handle_answer(esl_handle_t *eslC,int fd,int *argc, char *argv[]) {
+        int res;
+        int size;
+        char *buf=NULL;
+        res = do_execute(eslC,&quot;answer&quot;,NULL,NULL,NULL);
+
+        size = safe_int_snprintf_buffer(&amp;buf,&quot;200 result=%d\n\n&quot;,res);
+
+        res = write(fd,buf,size);
+        free(buf);
+        return res;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> /*
</span><del>- * Answer AGI cmd
</del><ins>+ * Hangup AGI cmd
+ * TODO:        - Add arg support to know which channel we want to hangup.
</ins><span class="cx">  */
</span><del>-static int handle_answer(esl_handle_t *eslC,int fd,int *argc, char *argv[]) {
-        if (do_execute(eslC,&quot;answer&quot;,NULL,NULL,NULL) &lt; 0 ) {
-                if ( write(fd,&quot;200 result=-1\n\n&quot;,128) &lt; 0 )
-                        return -1;
-        }
-        else {
-                if ( write(fd,&quot;200 result=0\n\n&quot;,128) &lt; 0 )
-                        return -1;
-        }
-        return 0;
</del><ins>+static int handle_hangup(esl_handle_t *eslC,int fd,int *argc, char *argv[]) {
+        int res;
+        int size;
+        char *buf=NULL;
+
+        res = do_execute(eslC,&quot;hangup&quot;,NULL,NULL,NULL);
+
+        size = safe_int_snprintf_buffer(&amp;buf,&quot;200 result=%d\n\n&quot;,res);
+
+        res = write(fd,buf,size);
+        free(buf);
+        return res;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+/*
+ * STREAM FILE agi cmd
+ * TODO: rewrites with good string handling :)
+ */ 
</ins><span class="cx"> static int handle_streamfile(esl_handle_t *eslC,int fd,int *argc, char *argv[]) {
</span><del>-        char buf[1024];
-        char *sbuf;
</del><ins>+        char *buf;
</ins><span class="cx">         int offset=0;
</span><del>-        int dtmf=0;
</del><ins>+        char dtmf[2]={&quot;0&quot;};
+        int res;
+
</ins><span class="cx">         esl_event_t *reply=NULL;
</span><span class="cx"> 
</span><span class="cx">         if (*argc &lt; 3 || *argc &gt; 5)
</span><span class="lines">@@ -452,49 +419,75 @@
</span><span class="cx"> 
</span><span class="cx">         if (argv[3]) {
</span><span class="cx">                 /* We should set playback_terminators var there */
</span><del>-                sprintf(buf,&quot;playback_terminators=%s&quot;,argv[3]);
</del><ins>+                buf = malloc(strlen(argv[3])+22);
+                memset(buf,0,strlen(argv[3])+22);
+                snprintf(buf,22,&quot;playback_terminators=%s&quot;,argv[3]);
</ins><span class="cx">                 do_execute(eslC,&quot;set&quot;,buf,NULL,NULL);
</span><ins>+                free(buf);
</ins><span class="cx">         }
</span><del>-        bzero(&amp;buf,1023);
</del><span class="cx"> 
</span><span class="cx">         if (argv[4]) {
</span><span class="cx">                 offset = atoi(argv[4]);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        if (offset &gt; 0)
-                sprintf(buf,&quot;%s@@%d&quot;,argv[2],offset);
</del><ins>+        buf = malloc(strlen(argv[2]) + 1);
+        memset(buf,0,strlen(argv[2])+1);
+
+        if (offset &gt; 0) {
+                buf = realloc(buf,strlen(argv[2]) + strlen(argv[4]) + 3);
+                snprintf(buf,strlen(argv[2]) + strlen(argv[4]) + 3,&quot;%s@@%d&quot;,argv[2],offset);
+
+        }
</ins><span class="cx">         else
</span><del>-                sprintf(buf,&quot;%s&quot;,argv[2]);
</del><ins>+                snprintf(buf,strlen(argv[2]) + 1,&quot;%s&quot;,argv[2]);
+
</ins><span class="cx">         offset = 0;
</span><del>-        if ( do_execute(eslC,&quot;playback&quot;,buf,NULL,&amp;reply) &lt; 0 ) /* We should write about NON success there instead of returning stock */
-                return -1;
</del><ins>+        if ( do_execute(eslC,&quot;playback&quot;,buf,NULL,&amp;reply) &lt; 0 ) { /* We should write about NON success there instead of returning stock */
+                offset = -1;
+                fprintf(stderr,&quot;do_execute stream file failed\n&quot;);
+        }
</ins><span class="cx">         else {
</span><del>-                bzero(&amp;buf,1023);
-                /* We should check playback_samples var to return offset, sent in the CHANNEL_EXECUTE_COMPLETE and 
-                variable_playback_terminator_used to get the DTMF we had */
</del><ins>+                free(buf);
+                buf=NULL;
</ins><span class="cx">                 if (reply) {
</span><del>-                        if (! (sbuf = esl_event_get_header(reply, &quot;variable_playback_samples&quot;)) )
-                                        offset = -1;
-                        else {
-                                offset = atoi(sbuf);
-                        }
-                        if (! (sbuf = esl_event_get_header(reply, &quot;variable_playback_terminator_used&quot;)) )
-                                        dtmf = 0;
-                        else {
-                                dtmf = atoi(sbuf);
-                        }
</del><ins>+                        res = fill_buffer_from_header(eslC-&gt;info_event,&amp;buf,&quot;variable_playback_samples&quot;,&quot;%d&quot;);
+                        if ( res &lt;= 0 )
+                                offset = 0;
+                        else 
+                                offset = atoi(buf);
+
+                        fprintf(stderr,&quot;Offset is %d, res is %d, buf is %s\n&quot;,offset,res,buf);
+
+                        res = fill_buffer_from_header(reply,&amp;buf,&quot;variable_playback_terminator_used&quot;,&quot;%s&quot;);
+                        // sbuf = esl_event_get_header(reply, &quot;variable_playback_terminator_used&quot;);
+                        if (res &gt; 0)
+                                snprintf((char *)&amp;dtmf,1,&quot;%s&quot;,buf);
</ins><span class="cx">                 }
</span><ins>+                else {
+                        fprintf(stderr,&quot;No event reply in stream file\n&quot;);
+                        offset=-1;
+                }
</ins><span class="cx">         }
</span><ins>+        if (buf != NULL)
+                free(buf);
+        fprintf(stderr,&quot;End stream file %d %s\n&quot;,offset,dtmf);
</ins><span class="cx">         if (offset &lt; 0) {
</span><del>-                if ( write(fd,&quot;200 result=-1 endpos=0\n\n&quot;,128) &lt; 0 )
</del><ins>+                if ( write(fd,&quot;200 result=-1 endpos=0\n\n&quot;,128) &lt; 0 ) {
+                        fprintf(stderr,&quot;Write failed\n&quot;);
</ins><span class="cx">                         return -1;
</span><ins>+                }
</ins><span class="cx">         }
</span><span class="cx">         else {
</span><del>-                sprintf(buf,&quot;200 result=%d endpos=%d\n\n&quot;,dtmf,offset);
-                if ( write(fd,buf,128) &lt; 0 )
</del><ins>+                buf=malloc(65);
+                memset(buf,0,65);
+                snprintf(buf,64,&quot;200 result=%s endpos=%d\n\n&quot;,dtmf,offset);
+                if ( write(fd,buf,64) &lt; 0 ) {
+                        free(buf);
+                        fprintf(stderr,&quot;Write failed\n&quot;);
</ins><span class="cx">                         return -1;
</span><ins>+                }
+                free(buf);
</ins><span class="cx">         }
</span><del>-
</del><span class="cx">         return 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -594,4 +587,3 @@
</span><span class="cx">         }
</span><span class="cx">         return r;
</span><span class="cx"> }
</span><del>-
</del></span></pre></div>
<a id="freeswitchtrunkcontribgledesl2agiesl2agih"></a>
<div class="modfile"><h4>Modified: freeswitch/trunk/contrib/gled/esl2agi/esl2agi.h (15039 => 15040)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/contrib/gled/esl2agi/esl2agi.h        2009-10-01 22:56:33 UTC (rev 15039)
+++ freeswitch/trunk/contrib/gled/esl2agi/esl2agi.h        2009-10-02 09:42:09 UTC (rev 15040)
</span><span class="lines">@@ -61,6 +61,7 @@
</span><span class="cx"> #define ESL_A_TO_VOID(v)        ((void*)(v))
</span><span class="cx"> #define VOID_TO_ESL_A(p)        ((esl_accept_t*)(p))
</span><span class="cx"> #define MAX(x,y)                ((x) &gt; (y) ? (x) : (y))
</span><ins>+#define MIN(x,y)                ((x) &lt; (y) ? (x) : (y))
</ins><span class="cx"> 
</span><span class="cx"> /* 
</span><span class="cx">  * Struct Section
</span><span class="lines">@@ -88,49 +89,37 @@
</span><span class="cx"> 
</span><span class="cx"> static void *esl2agi_thread(void *data);
</span><span class="cx"> 
</span><del>-/*
- * - EXEC application OPTIONS
- * - GET DATA filetoplay timeout maxdigits
- * - GET VARIABLE variablename
- * - HANGUP 'channelname'
- * - RECORD FILE filename format escapedigits timeout offsetsamples BEEP s=silence
- * - SAY DIGITS
- * - set autohangup time
- * - set music  on|off class
- * - set variable
- * - stream file filename &lt;escape digits&gt; [sample offset]
- * - wait for digit timeout
- */
-
</del><span class="cx"> static int handle_setup_env(int fd,esl_handle_t *eslC);
</span><span class="cx"> 
</span><span class="cx"> static void parse_args(char *buf,int *argc,char *argv[_MAX_CMD_ARGS]);
</span><span class="cx"> 
</span><span class="cx"> static command_binding_t *find_binding(char *cmd[]);
</span><span class="cx"> 
</span><del>-static int handle_hangup(esl_handle_t *eslC,int fd,int *argc, char *argv[_MAX_CMD_ARGS]);
-
-static int handle_answer(esl_handle_t *eslC,int fd, int *argc, char *argv[_MAX_CMD_ARGS]);
-
</del><span class="cx"> static int find_and_exec_command(esl_handle_t *eslC,int fd,char *buf);
</span><span class="cx"> 
</span><ins>+static int do_execute(esl_handle_t *eslC,char *cmd,char *args,char *uuid,esl_event_t **save_reply);
+
</ins><span class="cx"> /*
</span><ins>+ * ported agi commands
+ */
</ins><span class="cx"> 
</span><del>-static int handle_exec(esl_handle_t *eslC,int fd,char *args);
</del><ins>+static int handle_hangup(esl_handle_t *eslC,int fd,int *argc, char *argv[_MAX_CMD_ARGS]);
</ins><span class="cx"> 
</span><del>-static int handle_getdata(esl_handle_t *eslC,int fd,char *args);
</del><ins>+static int handle_answer(esl_handle_t *eslC,int fd, int *argc, char *argv[_MAX_CMD_ARGS]);
</ins><span class="cx"> 
</span><del>-static int handle_getvar(esl_handle_t *eslC,int fd,char *args);
</del><ins>+static int handle_streamfile(esl_handle_t *eslC,int fd,int *argc, char *argv[_MAX_CMD_ARGS]);
</ins><span class="cx"> 
</span><del>-static int handle_record(esl_handle_t *eslC,int fd,char *args);
</del><span class="cx"> 
</span><del>-static int handle_say(esl_handle_t *eslC,int fd,char *args);
-
-static int handle_setvar(esl_handle_t *eslC,int fd,char *args);
-
-static int handle_set(esl_handle_t *eslC,int fd,char *args);
-
-static int handle_streamfile(esl_handle_t *eslC,int fd,char *args);
-
-static int handle_waitdigits(esl_handle_t *eslC,int fd,char *args);
-*/
</del><ins>+/* TODO
+ * - EXEC application OPTIONS
+ * - GET DATA filetoplay timeout maxdigits
+ * - GET VARIABLE variablename
+ * - HANGUP 'channelname'
+ * - RECORD FILE filename format escapedigits timeout offsetsamples BEEP s=silence
+ * - SAY DIGITS
+ * - set autohangup time
+ * - set music  on|off class
+ * - set variable
+ * - stream file filename &lt;escape digits&gt; [sample offset]
+ * - wait for digit timeout
+ */
</ins></span></pre>
</div>
</div>
<div id="footer">See you at ClueCon</div>

</body>
</html>