List Info

Thread: r2578 - openpbx/trunk/apps




r2578 - openpbx/trunk/apps
user name
2007-04-01 17:43:35
Author: ctrix
Date: 2007-04-01 18:43:35 -0400 (Sun, 01 Apr 2007)
New Revision: 2578

Modified:
   openpbx/trunk/apps/app_rxfax.c
   openpbx/trunk/apps/app_txfax.c
Log:
This should improve app_(T|R)Fax capabilities to send audio
faxes. T38 is to be improved in Txfax.

Modified: openpbx/trunk/apps/app_rxfax.c
============================================================
=======
--- openpbx/trunk/apps/app_rxfax.c	2007-04-01 15:50:04 UTC
(rev 2577)
+++ openpbx/trunk/apps/app_rxfax.c	2007-04-01 22:43:35 UTC
(rev 2578)
 -462,7
+462,9 
                 if (fax_rx(&fax, inf->data,
inf->samples))
                     break;
                 samples = (inf->samples <=
MAX_BLOCK_SIZE)  ?  inf->samples  :  MAX_BLOCK_SIZE;
-                if ((len = fax_tx(&fax, (int16_t *)
&buf[OPBX_FRIENDLY_OFFSET], samples)))
+
+		len = fax_tx(&fax, (int16_t *)
&buf[OPBX_FRIENDLY_OFFSET], samples);
+                if ( len )
                 {
                     opbx_fr_init_ex(&outf,
OPBX_FRAME_VOICE, OPBX_FORMAT_SLINEAR, "RxFAX");
                     outf.datalen = len*sizeof(int16_t);
 -475,6
+477,20 
                         break;
                     }
                 }
+		else {
+		    len = samples;
+                    opbx_fr_init_ex(&outf,
OPBX_FRAME_VOICE, OPBX_FORMAT_SLINEAR, "RxFAX");
+                    outf.datalen = len*sizeof(int16_t);
+                    outf.samples = len;
+                    outf.data =
&buf[OPBX_FRIENDLY_OFFSET];
+                    outf.offset = OPBX_FRIENDLY_OFFSET;
+		   
memset(&buf[OPBX_FRIENDLY_OFFSET],0,outf.datalen);
+                    if (opbx_write(chan, &outf) <
0)
+                    {
+                        opbx_log(LOG_WARNING, "Unable
to write frame to channel; %sn", strerror(errno));
+                        break;
+                    }
+		}
             }
             else if (inf->frametype == OPBX_FRAME_MODEM 
&&  inf->subclass == OPBX_MODEM_T38)
             {

Modified: openpbx/trunk/apps/app_txfax.c
============================================================
=======
--- openpbx/trunk/apps/app_txfax.c	2007-04-01 15:50:04 UTC
(rev 2577)
+++ openpbx/trunk/apps/app_txfax.c	2007-04-01 22:43:35 UTC
(rev 2578)
 -14,7
+14,8 
 #ifdef HAVE_CONFIG_H
 #include "confdefs.h"
 #endif
- 
+
+#include <assert.h>
 #include <string.h>
 #include <stdlib.h>
 #include <inttypes.h>
 -65,6
+66,7 
 LOCAL_USER_DECL;
 
 #define MAX_BLOCK_SIZE 240
+#define ready_to_talk(chan) ( (!chan || 
opbx_check_hangup(chan) )  ?  0  :  1)
 
 static void span_message(int level, const char *msg)
 {
 -80,14
+82,86 
     opbx_log(opbx_level, __FILE__, __LINE__,
__PRETTY_FUNCTION__, msg);
 }
 /*- End of function
--------------------------------------------------------*/
-/* Removing alerts generated by the compiler.
-static void t30_flush(t30_state_t *s, int which)
+
+/* Return a monotonically increasing time, in microseconds
*/
+static uint64_t nowis(void)
 {
-    //TODO:
+    int64_t now;
+#ifndef HAVE_POSIX_TIMERS
+    struct timeval tv;
+
+    gettimeofday(&tv, NULL);
+    now = tv.tv_sec*1000000LL + tv.tv_usec;
+#else
+    struct timespec ts;
+    
+    if (clock_gettime(CLOCK_MONOTONIC, &ts))
+        opbx_log(LOG_WARNING, "clock_gettime returned
%sn", strerror(errno));
+    now = ts.tv_sec*1000000LL + ts.tv_nsec/1000;
+#endif
+    return now;
 }
-*/
+
 /*- End of function
--------------------------------------------------------*/
 
+/*
************************************************************
*****************
+	MEMBER GENERATOR
+  
************************************************************
****************/
+
+static void *faxgen_alloc(struct opbx_channel *chan, void
*params)
+{
+    opbx_log(LOG_DEBUG,"Allocating fax
generatorn");
+    return params;
+}
+
+/*- End of function
--------------------------------------------------------*/
+
+static void faxgen_release(struct opbx_channel *chan, void
*data)
+{
+    opbx_log(LOG_DEBUG,"Releasing fax
generatorn");
+    return;
+}
+
+/*- End of function
--------------------------------------------------------*/
+
+static int faxgen_generate(struct opbx_channel *chan, void
*data, int samples)
+{
+    int len;
+    fax_state_t *fax;
+    struct opbx_frame outf;
+
+    uint8_t __buf[sizeof(uint16_t)*MAX_BLOCK_SIZE +
2*OPBX_FRIENDLY_OFFSET];
+    uint8_t *buf = __buf + OPBX_FRIENDLY_OFFSET;
+    
+    fax = (fax_state_t*) data;
+
+    samples = ( samples <= MAX_BLOCK_SIZE )  ?  samples 
:  MAX_BLOCK_SIZE;
+    len = fax_tx(fax, (int16_t *)
&buf[OPBX_FRIENDLY_OFFSET], samples);
+
+    if (len) {
+        opbx_fr_init_ex(&outf, OPBX_FRAME_VOICE,
OPBX_FORMAT_SLINEAR, "TxFAX");
+        outf.datalen = len*sizeof(int16_t);
+        outf.samples = len;
+        outf.data = &buf[OPBX_FRIENDLY_OFFSET];
+        outf.offset = OPBX_FRIENDLY_OFFSET;
+
+        if (opbx_write(chan, &outf) < 0) {
+            opbx_log(LOG_WARNING, "Unable to write
frame to channel; %sn", strerror(errno));
+        }
+    }
+
+    return 0;
+}
+
+struct opbx_generator faxgen = 
+{
+	alloc: 		faxgen_alloc,
+	release: 	faxgen_release,
+	generate: 	faxgen_generate,
+} ;
+
+/*- End of function
--------------------------------------------------------*/
+
 static void phase_e_handler(t30_state_t *s, void
*user_data, int result)
 {
     struct opbx_channel *chan;
 -157,67
+231,258 
 }
 /*- End of function
--------------------------------------------------------*/
 
-/* Return a monotonically increasing time, in microseconds
*/
-static int64_t nowis(void)
-{
-    int64_t now;
-#ifndef HAVE_POSIX_TIMERS
-    struct timeval tv;
 
-    gettimeofday(&tv, NULL);
-    now = tv.tv_sec*1000000LL + tv.tv_usec;
-#else
-    struct timespec ts;
+static int txfax_t38(struct opbx_channel *chan,
t38_terminal_state_t *t38, char *source_file, int
calling_party,int verbose, int ecm) {
+    char 		*x;
+    struct opbx_frame 	*inf = NULL;
+    int 		ready = 1,
+			res = 0;
+
+    memset(t38, 0, sizeof(t38));
+
+    t38_terminal_init(t38, calling_party,
t38_tx_packet_handler, chan);
+
+    span_log_set_message_handler(&t38->logging,
span_message);
+   
span_log_set_message_handler(&t38->t30_state.logging,
span_message);
+    span_log_set_message_handler(&t38->t38.logging,
span_message);
+
+    if (verbose)
+    {
+        span_log_set_level(&t38->logging,
SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL |
SPAN_LOG_FLOW);
+        span_log_set_level(&t38->t30_state.logging,
SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL |
SPAN_LOG_FLOW);
+        span_log_set_level(&t38->t38.logging,
SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL |
SPAN_LOG_FLOW);
+    }
+
+    x = pbx_builtin_getvar_helper(chan,
"LOCALSTATIONID");
+    if (x  &&  x[0])
+        t30_set_local_ident(&t38->t30_state, x);
+    x = pbx_builtin_getvar_helper(chan,
"LOCALHEADERINFO");
+    if (x  &&  x[0])
+        t30_set_header_info(&t38->t30_state, x);
+    t30_set_tx_file(&t38->t30_state, source_file,
-1, -1);
+    //t30_set_phase_b_handler(&t38.t30_state,
phase_b_handler, chan);
+    //t30_set_phase_d_handler(&t38.t30_state,
phase_d_handler, chan);
+    t30_set_phase_e_handler(&t38->t30_state,
phase_e_handler, chan);
+
+    t30_set_supported_image_sizes(&t38->t30_state,
T30_SUPPORT_US_LETTER_LENGTH | T30_SUPPORT_US_LEGAL_LENGTH |
T30_SUPPORT_UNLIMITED_LENGTH
+                                	        |
T30_SUPPORT_215MM_WIDTH | T30_SUPPORT_255MM_WIDTH |
T30_SUPPORT_303MM_WIDTH);
+    t30_set_supported_resolutions(&t38->t30_state,
T30_SUPPORT_STANDARD_RESOLUTION |
T30_SUPPORT_FINE_RESOLUTION |
T30_SUPPORT_SUPERFINE_RESOLUTION
+                                                |
T30_SUPPORT_R8_RESOLUTION | T30_SUPPORT_R16_RESOLUTION);
+
+    if (ecm) {
+        t30_set_ecm_capability(&t38->t30_state,
TRUE);
+       
t30_set_supported_compressions(&t38->t30_state,
T30_SUPPORT_T4_1D_COMPRESSION |
T30_SUPPORT_T4_2D_COMPRESSION |
T30_SUPPORT_T6_COMPRESSION);
+        opbx_log(LOG_DEBUG, "Enabling ECM mode for
app_txfaxn"  );
+    }
+
+
+
+    while ( ready && ready_to_talk(chan) )
+    {
     
-    if (clock_gettime(CLOCK_MONOTONIC, &ts))
-        opbx_log(LOG_WARNING, "clock_gettime returned
%sn", strerror(errno));
-    now = ts.tv_sec*1000000LL + ts.tv_nsec/1000;
-#endif
-    return now;
+	if ( !chan->t38mode_enabled )
+	    break;
+
+        if ((res = opbx_waitfor(chan, 20)) < 0) {
+	    ready = 0;
+            break;
+	}
+
+        inf = opbx_read(chan);
+        if (inf == NULL) {
+	    ready = 0;
+            break;
+        }
+
+        if (inf->frametype == OPBX_FRAME_MODEM 
&&  inf->subclass == OPBX_MODEM_T38)
+        {
+    	    t38_core_rx_ifp_packet(&t38->t38,
inf->seq_no, inf->data, inf->datalen);
+	}
+
+        opbx_fr_free(inf);
+    }
+
+    return ready;
+
 }
+
 /*- End of function
--------------------------------------------------------*/
 
+static int txfax_audio(struct opbx_channel *chan,
fax_state_t *fax, char *source_file, int calling_party,int
verbose, int ecm) {
+    char 		*x;
+    struct opbx_frame 	*inf = NULL;
+    struct opbx_frame 	outf;
+    int 		ready = 1,
+			samples = 0,
+			res = 0,
+			len = 0,
+			generator_mode = 0;
+    uint64_t		begin = 0,
+			received_frames = 0;
+
+    uint8_t __buf[sizeof(uint16_t)*MAX_BLOCK_SIZE +
2*OPBX_FRIENDLY_OFFSET];
+    uint8_t *buf = __buf + OPBX_FRIENDLY_OFFSET;
+
+    memset(fax, 0, sizeof(fax));
+
+    fax_init(fax, calling_party);
+    fax_set_transmit_on_idle(fax,TRUE);
+    span_log_set_message_handler(&fax->logging,
span_message);
+   
span_log_set_message_handler(&fax->t30_state.logging,
span_message);
+    if (verbose)
+    {
+        span_log_set_level(&fax->logging,
SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL |
SPAN_LOG_FLOW);
+        span_log_set_level(&fax->t30_state.logging,
SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL |
SPAN_LOG_FLOW);
+    }
+    x = pbx_builtin_getvar_helper(chan,
"LOCALSTATIONID");
+    if (x  &&  x[0])
+        t30_set_local_ident(&fax->t30_state, x);
+    x = pbx_builtin_getvar_helper(chan,
"LOCALHEADERINFO");
+    if (x  &&  x[0])
+        t30_set_header_info(&fax->t30_state, x);
+    t30_set_tx_file(&fax->t30_state, source_file,
-1, -1);
+    //t30_set_phase_b_handler(&fax.t30_state,
phase_b_handler, chan);
+    //t30_set_phase_d_handler(&fax.t30_state,
phase_d_handler, chan);
+    t30_set_phase_e_handler(&fax->t30_state,
phase_e_handler, chan);
+
+    /* Support for different image sizes &&
resolutions*/
+    t30_set_supported_image_sizes(&fax->t30_state,
T30_SUPPORT_US_LETTER_LENGTH | T30_SUPPORT_US_LEGAL_LENGTH |
T30_SUPPORT_UNLIMITED_LENGTH
+                                                |
T30_SUPPORT_215MM_WIDTH | T30_SUPPORT_255MM_WIDTH |
T30_SUPPORT_303MM_WIDTH);
+    t30_set_supported_resolutions(&fax->t30_state,
T30_SUPPORT_STANDARD_RESOLUTION |
T30_SUPPORT_FINE_RESOLUTION |
T30_SUPPORT_SUPERFINE_RESOLUTION
+                                                |
T30_SUPPORT_R8_RESOLUTION | T30_SUPPORT_R16_RESOLUTION);
+    if (ecm) {
+        t30_set_ecm_capability(&fax->t30_state,
TRUE);
+       
t30_set_supported_compressions(&fax->t30_state,
T30_SUPPORT_T4_1D_COMPRESSION |
T30_SUPPORT_T4_2D_COMPRESSION |
T30_SUPPORT_T6_COMPRESSION);
+        opbx_log(LOG_DEBUG, "Enabling ECM mode for
app_txfaxn"  );
+    }
+
+    /* This is the main loop */
+
+    begin = nowis();
+
+    while ( ready && ready_to_talk(chan) )
+    {
+    
+	if ( chan->t38mode_enabled )
+	    break;
+
+        if ((res = opbx_waitfor(chan, 20)) < 0) {
+	    ready = 0;
+            break;
+	}
+
+        inf = opbx_read(chan);
+        if (inf == NULL) {
+	    ready = 0;
+            break;
+        }
+
+	/* We got a frame */
+        if (inf->frametype == OPBX_FRAME_VOICE) {
+
+	    received_frames ++;
+
+            if (fax_rx(fax, inf->data,
inf->samples))
+                    break;
+
+            samples = (inf->samples <=
MAX_BLOCK_SIZE)  ?  inf->samples  :  MAX_BLOCK_SIZE;
+            len = fax_tx(fax, (int16_t *)
&buf[OPBX_FRIENDLY_OFFSET], samples);
+
+            if (len) {
+                opbx_fr_init_ex(&outf,
OPBX_FRAME_VOICE, OPBX_FORMAT_SLINEAR, "TxFAX");
+                outf.datalen = len*sizeof(int16_t);
+                outf.samples = len;
+                outf.data =
&buf[OPBX_FRIENDLY_OFFSET];
+                outf.offset = OPBX_FRIENDLY_OFFSET;
+
+                if (opbx_write(chan, &outf) < 0) {
+                    opbx_log(LOG_WARNING, "Unable to
write frame to channel; %sn", strerror(errno));
+                    break;
+                }
+            }
+        }
+	else {
+	    if ( (nowis() - begin) > 1000000 ) {
+		if (received_frames < 20 ) { // just to be sure we
have had no frames ...
+		    opbx_log(LOG_WARNING,"Switching to generator
moden");
+		    generator_mode = 1;
+		    break;
+		}
+	    }
+	}
+        opbx_fr_free(inf);
+    }
+
+    if (generator_mode) {
+	// This is activated when we don't receive any frame for
+	// X seconds (see above)... we are probably on ZAP or
talking without UDPTL to
+	// another openpbx box
+	opbx_generator_activate(chan, &faxgen, fax);
+
+	while ( ready && ready_to_talk(chan) ) {
+
+	    if ( chan->t38mode_enabled )
+		break;
+
+	    if ((res = opbx_waitfor(chan, 20)) < 0) {
+	        ready = 0;
+        	break;
+	    }
+
+    	    inf = opbx_read(chan);
+    	    if (inf == NULL) {
+		ready = 0;
+        	break;
+    	    }
+
+	    /* We got a frame */
+    	    if (inf->frametype == OPBX_FRAME_VOICE) {
+        	if (fax_rx(fax, inf->data, inf->samples)) {
+		    ready = 0;
+                    break;
+		}
+	    }
+
+	}
+
+	opbx_generator_deactivate(chan);
+
+    }
+
+    return ready;
+}
+
+/*- End of function
--------------------------------------------------------*/
+
+
 static int txfax_exec(struct opbx_channel *chan, void
*data)
 {
+    fax_state_t 	fax;
+    t38_terminal_state_t t38;
+
     int res = 0;
     char source_file[256];
-    char *x;
     char *s;
     char *t;
     char *v;
     int option;
     int len;
-    fax_state_t fax;
-    t38_terminal_state_t t38;
+    int ready;
+
     int calling_party;
     int verbose;
-    int samples;
-    int call_is_t38_mode;
     int ecm = FALSE;
     
     struct localuser *u;
-    struct opbx_frame *inf = NULL;
-    struct opbx_frame outf;
 
     int original_read_fmt;
     int original_write_fmt;
-    int64_t now;
-    int64_t next;
-    int64_t passage;
-    int delay;
 
-    time_t begin, thistime;
-    
-    pbx_builtin_setvar_helper(chan,
"REMOTESTATIONID", "");
-    pbx_builtin_setvar_helper(chan, "FAXPAGES",
"");
-    pbx_builtin_setvar_helper(chan,
"FAXRESOLUTION", "");
-    pbx_builtin_setvar_helper(chan, "FAXBITRATE",
"");
-    pbx_builtin_setvar_helper(chan,
"PHASEESTATUS", "");
-    pbx_builtin_setvar_helper(chan,
"PHASEESTRING", "");
-
     uint8_t __buf[sizeof(uint16_t)*MAX_BLOCK_SIZE +
2*OPBX_FRIENDLY_OFFSET];
     uint8_t *buf = __buf + OPBX_FRIENDLY_OFFSET;
 
+    /* Basic initial checkings */
+
     if (chan == NULL)
     {
         opbx_log(LOG_WARNING, "Fax transmit channel is
NULL. Giving up.n");
 -231,7
+496,18 
         opbx_log(LOG_WARNING, "Txfax requires an
argument (filename)n");
         return -1;
     }
+
+    /* Resetting channel variables related to T38 */
     
+    pbx_builtin_setvar_helper(chan,
"REMOTESTATIONID", "");
+    pbx_builtin_setvar_helper(chan, "FAXPAGES",
"");
+    pbx_builtin_setvar_helper(chan,
"FAXRESOLUTION", "");
+    pbx_builtin_setvar_helper(chan, "FAXBITRATE",
"");
+    pbx_builtin_setvar_helper(chan,
"PHASEESTATUS", "");
+    pbx_builtin_setvar_helper(chan,
"PHASEESTRING", "");
+
+    /* Parsig parameters */
+    
     calling_party = FALSE;
     verbose = FALSE;
     source_file[0] = ''; 
 -273,7
+549,6 
             /* TODO: handle this */
         }
     }
-
     /* Done parsing */
 
     LOCAL_USER_ADD(u);
 -283,239
+558,83 
         /* Shouldn't need this, but checking to see if
channel is already answered
          * Theoretically the PBX should already have
answered before running the app */
         res = opbx_answer(chan);
+	if (!res)
+	{
+    	    opbx_log(LOG_WARNING, "Could not answer
channel '%s'n", chan->name);
+	    LOCAL_USER_REMOVE(u);
+	    return res;
+	}
     }
+
+    /* Setting read and write formats */
     
-    if (!res)
+    original_read_fmt = chan->readformat;
+    if (original_read_fmt != OPBX_FORMAT_SLINEAR)
     {
-        original_read_fmt = chan->readformat;
-        if (original_read_fmt != OPBX_FORMAT_SLINEAR)
+        res = opbx_set_read_format(chan,
OPBX_FORMAT_SLINEAR);
+        if (res < 0)
         {
-            res = opbx_set_read_format(chan,
OPBX_FORMAT_SLINEAR);
-            if (res < 0)
-            {
-                opbx_log(LOG_WARNING, "Unable to set
to linear read mode, giving upn");
-                LOCAL_USER_REMOVE(u);
-                return -1;
-            }
+            opbx_log(LOG_WARNING, "Unable to set to
linear read mode, giving upn");
+            LOCAL_USER_REMOVE(u);
+            return -1;
         }
-        original_write_fmt = chan->writeformat;
-        if (original_write_fmt != OPBX_FORMAT_SLINEAR)
+    }
+
+    original_write_fmt = chan->writeformat;
+    if (original_write_fmt != OPBX_FORMAT_SLINEAR)
+    {
+        res = opbx_set_write_format(chan,
OPBX_FORMAT_SLINEAR);
+        if (res < 0)
         {
-            res = opbx_set_write_format(chan,
OPBX_FORMAT_SLINEAR);
-            if (res < 0)
-            {
-                opbx_log(LOG_WARNING, "Unable to set
to linear write mode, giving upn");
-                res = opbx_set_read_format(chan,
original_read_fmt);
-                if (res)
-                    opbx_log(LOG_WARNING, "Unable to
restore read format on '%s'n", chan->name);
-                LOCAL_USER_REMOVE(u);
-                return -1;
-            }
+            opbx_log(LOG_WARNING, "Unable to set to
linear write mode, giving upn");
+            res = opbx_set_read_format(chan,
original_read_fmt);
+            if (res)
+                opbx_log(LOG_WARNING, "Unable to
restore read format on '%s'n", chan->name);
+            LOCAL_USER_REMOVE(u);
+            return -1;
         }
+    }
 
-        memset(&fax, 0, sizeof(fax));
-        memset(&t38, 0, sizeof(t38));
 
-        fax_init(&fax, calling_party);
-        fax_set_transmit_on_idle(&fax,TRUE);
-        span_log_set_message_handler(&fax.logging,
span_message);
-       
span_log_set_message_handler(&fax.t30_state.logging,
span_message);
-        if (verbose)
-        {
-            span_log_set_level(&fax.logging,
SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL |
SPAN_LOG_FLOW);
-            span_log_set_level(&fax.t30_state.logging,
SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL |
SPAN_LOG_FLOW);
-        }
-        x = pbx_builtin_getvar_helper(chan,
"LOCALSTATIONID");
-        if (x  &&  x[0])
-            t30_set_local_ident(&fax.t30_state, x);
-        x = pbx_builtin_getvar_helper(chan,
"LOCALHEADERINFO");
-        if (x  &&  x[0])
-            t30_set_header_info(&fax.t30_state, x);
-        t30_set_tx_file(&fax.t30_state, source_file,
-1, -1);
-        //t30_set_phase_b_handler(&fax.t30_state,
phase_b_handler, chan);
-        //t30_set_phase_d_handler(&fax.t30_state,
phase_d_handler, chan);
-        t30_set_phase_e_handler(&fax.t30_state,
phase_e_handler, chan);
+    /* This is the main loop */
 
-        t38_terminal_init(&t38, calling_party,
t38_tx_packet_handler, chan);
-        span_log_set_message_handler(&t38.logging,
span_message);
-       
span_log_set_message_handler(&t38.t30_state.logging,
span_message);
-        span_log_set_message_handler(&t38.t38.logging,
span_message);
-        if (verbose)
-        {
-            span_log_set_level(&t38.logging,
SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL |
SPAN_LOG_FLOW);
-            span_log_set_level(&t38.t30_state.logging,
SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL |
SPAN_LOG_FLOW);
-            span_log_set_level(&t38.t38.logging,
SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL |
SPAN_LOG_FLOW);
-        }
-        x = pbx_builtin_getvar_helper(chan,
"LOCALSTATIONID");
-        if (x  &&  x[0])
-            t30_set_local_ident(&t38.t30_state, x);
-        x = pbx_builtin_getvar_helper(chan,
"LOCALHEADERINFO");
-        if (x  &&  x[0])
-            t30_set_header_info(&t38.t30_state, x);
-        t30_set_tx_file(&t38.t30_state, source_file,
-1, -1);
-        //t30_set_phase_b_handler(&t38.t30_state,
phase_b_handler, chan);
-        //t30_set_phase_d_handler(&t38.t30_state,
phase_d_handler, chan);
-        t30_set_phase_e_handler(&t38.t30_state,
phase_e_handler, chan);
+    ready = TRUE;        
 
-        /* Support for different image sizes &&
resolutions*/
-        t30_set_supported_image_sizes(&fax.t30_state,
T30_SUPPORT_US_LETTER_LENGTH | T30_SUPPORT_US_LEGAL_LENGTH |
T30_SUPPORT_UNLIMITED_LENGTH
-                                                        |
T30_SUPPORT_215MM_WIDTH | T30_SUPPORT_255MM_WIDTH |
T30_SUPPORT_303MM_WIDTH);
-        t30_set_supported_resolutions(&fax.t30_state,
T30_SUPPORT_STANDARD_RESOLUTION |
T30_SUPPORT_FINE_RESOLUTION |
T30_SUPPORT_SUPERFINE_RESOLUTION
-                                                        |
T30_SUPPORT_R8_RESOLUTION | T30_SUPPORT_R16_RESOLUTION);
-        t30_set_supported_image_sizes(&t38.t30_state,
T30_SUPPORT_US_LETTER_LENGTH | T30_SUPPORT_US_LEGAL_LENGTH |
T30_SUPPORT_UNLIMITED_LENGTH
-                                                        |
T30_SUPPORT_215MM_WIDTH | T30_SUPPORT_255MM_WIDTH |
T30_SUPPORT_303MM_WIDTH);
-        t30_set_supported_resolutions(&t38.t30_state,
T30_SUPPORT_STANDARD_RESOLUTION |
T30_SUPPORT_FINE_RESOLUTION |
T30_SUPPORT_SUPERFINE_RESOLUTION
-                                                        |
T30_SUPPORT_R8_RESOLUTION | T30_SUPPORT_R16_RESOLUTION);
-        if (ecm) {
-                t30_set_ecm_capability(&fax.t30_state,
TRUE);
-           
t30_set_supported_compressions(&fax.t30_state,
T30_SUPPORT_T4_1D_COMPRESSION |
T30_SUPPORT_T4_2D_COMPRESSION |
T30_SUPPORT_T6_COMPRESSION);
-                t30_set_ecm_capability(&t38.t30_state,
TRUE);
-           
t30_set_supported_compressions(&t38.t30_state,
T30_SUPPORT_T4_1D_COMPRESSION |
T30_SUPPORT_T4_2D_COMPRESSION |
T30_SUPPORT_T6_COMPRESSION);
-            opbx_log(LOG_DEBUG, "Enabling ECM mode for
app_txfaxn"  );
-        }
-        
-        call_is_t38_mode = FALSE;
-        passage = nowis();
-        next = passage + 30000;
-        time(&begin);
-        while (1)
-        {
-            now = nowis();
-            delay = (next < now)  ?  0  :  (next - now +
500)/1000;
-            if ((res = opbx_waitfor(chan, delay)) < 0)
-                break;
+    while ( ready && ready_to_talk(chan) )
+    {
 
-            // Let's timeout if we have no input packets
for at least 60 secs.
-            time(&thistime);
-            if ( ((thistime-begin) >= 60) &&
!call_is_t38_mode ) {
-                    opbx_log(LOG_DEBUG, "No data
received for %ld seconds. Hanging up.n",
(int)thistime-begin  );
-                break;
-            }
 
-            // Let's help T38 switchover (don't wait for
udptl packets but trust channel state).
-            if (!call_is_t38_mode) {
-                if (chan->t38mode_enabled==1) {
-                    call_is_t38_mode=TRUE;
-                        opbx_log(LOG_DEBUG, "T38
switchover detectedn" );
-                }
-            }
+        if ( ready && chan->t38mode_enabled!=1 )
{
+	    ready = txfax_audio( chan, &fax, source_file,
calling_party, verbose, ecm);
+	}
 
-            if (call_is_t38_mode)
-            {
-                now = nowis();
-                t38_terminal_send_timeout(&t38, (now -
passage)/125);
-                passage = now;
-                /* End application when T38/T30 has
finished */
-                if ((t38.current_rx_type == T30_MODEM_DONE)
 ||  (t38.current_tx_type == T30_MODEM_DONE))
-                    break;
-            }
+        if ( ready && chan->t38mode_enabled==1 )
{
+	    ready = txfax_t38  ( chan, &t38, source_file,
calling_party, verbose, ecm);
+	}
 
-            if (res == 0)
-            {
-                if (!call_is_t38_mode)
-                {
-                    samples = 160;
-                    if ((len = fax_tx(&fax, (int16_t *)
&buf[OPBX_FRIENDLY_OFFSET], samples)))
-                    {
-                        opbx_fr_init_ex(&outf,
OPBX_FRAME_VOICE, OPBX_FORMAT_SLINEAR, "TxFAX");
-                        outf.datalen =
len*sizeof(int16_t);
-                        outf.samples = len;
-                        outf.data =
&buf[OPBX_FRIENDLY_OFFSET];
-                        outf.offset =
OPBX_FRIENDLY_OFFSET;
-                        if (opbx_write(chan, &outf)
< 0)
-                        {
-                            opbx_log(LOG_WARNING,
"Unable to write frame to channel; %sn",
strerror(errno));
-                            break;
-                        }
-                        passage = now;
-                            next += 20000; // If I remember
well, spandsp generates 1 frame every 20ms
-                    }
-                }
-                else 
-                    next += 30000;
-                continue;
-            } 
-            else
-            {
-                // TxFax receives 1 fake packet every 3-4
secs. 
-                // This check is used to verify autenticity
of RTP packets.
-                if ( thistime-begin <=2 )
-                    time(&begin);
-            }
+	ready = 0; // 1 loop is enough. This could be useful if we
want to turn from udptl to RTP later.
 
-            if ((inf = opbx_read(chan)) == NULL)
-            {
-                res = -1;
-                break;
-            }
+    }
 
+    t30_terminate(&fax.t30_state);
+    t30_terminate(&t38.t30_state);
+    fax_release(&fax);
 
-            if (inf->frametype == OPBX_FRAME_VOICE 
&&  !call_is_t38_mode)
-            {
-                if (fax_rx(&fax, inf->data,
inf->samples))
-                    break;
-                samples = (inf->samples <=
MAX_BLOCK_SIZE)  ?  inf->samples  :  MAX_BLOCK_SIZE;
-                if ((len = fax_tx(&fax, (int16_t *)
&buf[OPBX_FRIENDLY_OFFSET], samples)))
-                {
-                    opbx_fr_init_ex(&outf,
OPBX_FRAME_VOICE, OPBX_FORMAT_SLINEAR, "TxFAX");
-                    outf.datalen = len*sizeof(int16_t);
-                    outf.samples = len;
-                    outf.data =
&buf[OPBX_FRIENDLY_OFFSET];
-                    outf.offset = OPBX_FRIENDLY_OFFSET;
-                    if (opbx_write(chan, &outf) <
0)
-                    {
-                        opbx_log(LOG_WARNING, "Unable
to write frame to channel; %sn", strerror(errno));
-                        break;
-                    }
-                }
-            }
-            else if (inf->frametype == OPBX_FRAME_MODEM 
&&  inf->subclass == OPBX_MODEM_T38)
-            {
-                //printf("T.38 frame
receivedn");
-                if (!call_is_t38_mode)
-                {
-                            call_is_t38_mode = TRUE;
-                            passage = now;
-                }
-                t38_core_rx_ifp_packet(&t38.t38,
inf->seq_no, inf->data, inf->datalen);
-            } 
-            else 
-            {
-                if (verbose)
-                    opbx_log(LOG_DEBUG," Unknown pkt
received: frametype: %d subclass: %d t38_mode: %dn",
-                        inf->frametype,
inf->subclass, call_is_t38_mode );
-            }
-            opbx_fr_free(inf);
-        }
-        if (inf == NULL)
-        {
-            opbx_log(LOG_DEBUG, "Got hangupn");
-            res = -1;
-        }
+    /* Restoring initial channel formats. */
 
-        if (!call_is_t38_mode)
-            t30_terminate(&fax.t30_state);
-        else
-            t30_terminate(&t38.t30_state);
-
-        if (original_read_fmt != OPBX_FORMAT_SLINEAR)
-        {
-            if ((res = opbx_set_read_format(chan,
original_read_fmt)))
-                opbx_log(LOG_WARNING, "Unable to
restore read format on '%s'n", chan->name);
-        }
-        if (original_write_fmt != OPBX_FORMAT_SLINEAR)
-        {
-            if ((res = opbx_set_write_format(chan,
original_write_fmt)))
-                opbx_log(LOG_WARNING, "Unable to
restore write format on '%s'n", chan->name);
-        }
-        fax_release(&fax);
+    if (original_read_fmt != OPBX_FORMAT_SLINEAR)
+    {
+        if ((res = opbx_set_read_format(chan,
original_read_fmt)))
+            opbx_log(LOG_WARNING, "Unable to restore
read format on '%s'n", chan->name);
     }
-    else
+    if (original_write_fmt != OPBX_FORMAT_SLINEAR)
     {
-        opbx_log(LOG_WARNING, "Could not answer
channel '%s'n", chan->name);
+        if ((res = opbx_set_write_format(chan,
original_write_fmt)))
+            opbx_log(LOG_WARNING, "Unable to restore
write format on '%s'n", chan->name);
     }
-    LOCAL_USER_REMOVE(u);
-    return res;
+
+    return ready;
+
 }
 /*- End of function
--------------------------------------------------------*/
 

_______________________________________________
Openpbx-svn mailing list
Openpbx-svnopenpbx.org
http://lists.openpbx.org/mailman/listinfo/openpbx-svn

[1]

about | contact  Other archives ( Real Estate discussion Medical topics )