List Info

Thread: r2582 - openpbx/trunk/apps




r2582 - openpbx/trunk/apps
user name
2007-04-02 18:34:37
Author: ctrix
Date: 2007-04-02 19:34:37 -0400 (Mon, 02 Apr 2007)
New Revision: 2582

Modified:
   openpbx/trunk/apps/app_rxfax.c
   openpbx/trunk/apps/app_t38gateway.c
   openpbx/trunk/apps/app_txfax.c
Log:
More TxFax and RxFax improvements... more things will follow
later ...

Modified: openpbx/trunk/apps/app_rxfax.c
============================================================
=======
--- openpbx/trunk/apps/app_rxfax.c	2007-04-02 22:03:08 UTC
(rev 2581)
+++ openpbx/trunk/apps/app_rxfax.c	2007-04-02 23:34:37 UTC
(rev 2582)
 -1,7
+1,7 
 /*
  * OpenPBX -- An open source telephony toolkit.
  *
- * Trivial application to receive a TIFF FAX file
+ * Trivial application to send a TIFF file as a FAX
  * 
  * Copyright (C) 2003, 2005, Steve Underwood
  *
 -15,12
+15,13 
 #include "confdefs.h"
 #endif
 
-#include <stdio.h> 
+#include <assert.h>
 #include <string.h>
 #include <stdlib.h>
 #include <inttypes.h>
 #include <pthread.h>
 #include <errno.h>
+#include <sys/time.h>
 
 #include <spandsp.h>
 
 -35,7
+36,6 
 #include "openpbx/pbx.h"
 #include "openpbx/module.h"
 #include "openpbx/translate.h"
-#include "openpbx/dsp.h"
 #include "openpbx/manager.h"
 
 static char *tdesc = "Trivial FAX Receive
Application";
 -68,6
+68,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)
 {
 -84,24
+85,110 
 }
 /*- End of function
--------------------------------------------------------*/
 
-/* remove compiler warnings
-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, "RxFAX");
+        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));
+        }
+    }
+    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));
+        }
+    }
+
+    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;
-    t30_stats_t t;
     char local_ident[21];
     char far_ident[21];
     char buf[128];
+    t30_stats_t t;
+
+    t30_get_transfer_statistics(s, &t);
     
     chan = (struct opbx_channel *) user_data;
-    t30_get_transfer_statistics(s, &t);
     t30_get_local_ident(s, local_ident);
     t30_get_far_ident(s, far_ident);
     pbx_builtin_setvar_helper(chan,
"REMOTESTATIONID", far_ident);
 -117,7
+204,7 
     pbx_builtin_setvar_helper(chan,
"PHASEESTRING", buf);
 
     opbx_log(LOG_DEBUG,
"======================================================
========================n");
-    if (result == T30_ERR_OK)
+    if (result == T30_ERR_OK) 
     {
         opbx_log(LOG_DEBUG, "Fax successfully
received.n");
         opbx_log(LOG_DEBUG, "Remote station id:
%sn", far_ident);
 -126,7
+213,7 
         opbx_log(LOG_DEBUG, "Image resolution:  %i x
%in", t.x_resolution, t.y_resolution);
         opbx_log(LOG_DEBUG, "Transfer Rate:    
%in", t.bit_rate);
         manager_event(EVENT_FLAG_CALL,
-                      "FaxReceived",
"Channel: %snExten: %snCallerID: %snRemoteStationID:
%snLocalStationID: %snPagesTransferred: %inResolution:
%inTransferRate: %inFileName: %sn",
+                      "FaxSent", "Channel:
%snExten: %snCallerID: %snRemoteStationID:
%snLocalStationID: %snPagesTransferred: %inResolution:
%inTransferRate: %inFileName: %sn",
                       chan->name,
                       chan->exten,
                       (chan->cid.cid_num)  ? 
chan->cid.cid_num  :  "",
 -140,7
+227,7 
     else
     {
         opbx_log(LOG_DEBUG, "Fax receive not
successful - result (%d) %s.n", result,
t30_completion_code_to_str(result));
-    }
+    }	
     opbx_log(LOG_DEBUG,
"======================================================
========================n");
 }
 /*- End of function
--------------------------------------------------------*/
 -174,9
+261,10 
     struct opbx_channel *chan;
 
     chan = (struct opbx_channel *) user_data;
+
     opbx_fr_init_ex(&outf, OPBX_FRAME_MODEM,
OPBX_MODEM_T38, "RxFAX");
     outf.datalen = len;
-    outf.data = (uint8_t *) buf;
+    outf.data = (char *) buf;
     outf.tx_copies = count;
     if (opbx_write(chan, &outf) < 0)
         opbx_log(LOG_WARNING, "Unable to write frame
to channel; %sn", strerror(errno));
 -184,28
+272,259 
 }
 /*- 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 rxfax_t38(struct opbx_channel *chan,
t38_terminal_state_t *t38, char *file, int calling_party,int
verbose, int ecm) {
+    char 		*x;
+    struct opbx_frame 	*inf = NULL;
+    int 		ready = 1,
+			res = 0;
+    uint64_t 		now;
+    uint64_t 		passage;
+
+    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_rx_file(&t38->t30_state, file, -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_rxfaxn"  );
+    }
+
+    passage = nowis();
+
+    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;
+	}
+
+        now = nowis();
+        t38_terminal_send_timeout(t38, (now -
passage)/125);
+        passage = now;
+        /* End application when T38/T30 has finished */
+        if ((t38->current_tx_type == T30_MODEM_DONE)  ||
 (t38->current_rx_type == T30_MODEM_DONE)) 
+            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 rxfax_audio(struct opbx_channel *chan,
fax_state_t *fax, char *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);
+    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_rx_file(&fax->t30_state, file, -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_rxfaxn"  );
+    }
+
+    /* 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, "RxFAX");
+                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 
+	    {
+	        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 ( (nowis() - begin) > 1000000 ) {
+		if (received_frames < 20 ) { // just to be sure we
have had no frames ...
+		    opbx_log(LOG_NOTICE,"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_log(LOG_NOTICE,"Got it 2n");
+	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 rxfax_exec(struct opbx_channel *chan, void
*data)
 {
+    fax_state_t 	fax;
+    t38_terminal_state_t t38;
+
     int res = 0;
     char template_file[256];
     char target_file[256];
 -215,42
+534,26 
     char *x;
     int option;
     int len;
+    int ready;
     int i;
-    fax_state_t fax;
-    t38_terminal_state_t t38;
+
     int calling_party;
     int verbose;
     int ecm = FALSE;
-    int rxpkt;
-    int samples;
-    int call_is_t38_mode;
-
+    
     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 receive channel is
NULL. Giving up.n");
+        opbx_log(LOG_WARNING, "Fax transmit channel is
NULL. Giving up.n");
         return -1;
     }
 
 -261,10
+564,21 
         opbx_log(LOG_WARNING, "Rxfax 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;
-    target_file[0] = '';
+    target_file[0] = ''; 
 
     for (option = 0, v = s = data;  v;  option++, s++)
     {
 -316,250
+630,88 
     if (chan->_state != OPBX_STATE_UP)
     {
         /* Shouldn't need this, but checking to see if
channel is already answered
-         * Theoretically asterisk should already have
answered before running the app */
+         * 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)
-        {
-            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;
-            }
-        }
-        fax_init(&fax, calling_party);
-        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_rx_file(&fax.t30_state, target_file,
-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);
+    }
 
-        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)
+    original_write_fmt = chan->writeformat;
+    if (original_write_fmt != OPBX_FORMAT_SLINEAR)
+    {
+        res = opbx_set_write_format(chan,
OPBX_FORMAT_SLINEAR);
+        if (res < 0)
         {
-            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);
+            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;
         }
-        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_rx_file(&t38.t30_state, target_file,
-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);
+    }
 
-        /* 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_rxfaxn"  );
-        }
-        
-        call_is_t38_mode = FALSE;
-        passage = nowis();
-        next = passage + 30000;
-        rxpkt = 0;
-        time(&begin);
-        while ((res = opbx_waitfor(chan, 30)) > -1)
-        {
-            time(&thistime);
-            if ((thistime - begin) >= 20  && 
(!rxpkt))
-            {
-                opbx_log(LOG_DEBUG, "No data received
for %ld seconds. Hanging up.n", (int) thistime -
begin);
-                break;
-            }
+    /* This is the main loop */
 
-            now = nowis();
-            delay = (next < now)  ?  0  :  (next - now +
500)/1000;
-            if ((res = opbx_waitfor(chan, delay)) < 0)
-                break;
-            // increment received packet count.
-            rxpkt += res;
-                
-            if (!call_is_t38_mode)
-            {
-                if (chan->t38mode_enabled == 1)
-                {
-                    call_is_t38_mode = TRUE;
-                    opbx_log(LOG_DEBUG, "T38
switchover detectedn" );
-                }
-            }
+    ready = TRUE;        
 
-            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 (res == 0)
-            {
-                next += 30000;
-                continue;
-            }
-            if ((inf = opbx_read(chan)) == NULL)
-            {
-                res = -1;
-                break;
-            }
+    while ( ready && ready_to_talk(chan) )
+    {
 
-            time(&begin);
-            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;
 
-		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);
-                    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 {
-		    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)
-            {
-                //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 (inf->frametype == 5)
-            {
-                // DTMF packet
-            }
-            else if (inf->frametype == OPBX_FRAME_VOICE
&& call_is_t38_mode)
-            {
-                // VOICE While in T38 mode packet
-            }
-            else if ( inf->frametype ==
OPBX_FRAME_NULL)
-            {
-                // NULL PACKET
-            }
-            else if (inf->frametype == 0  && 
!call_is_t38_mode)
-            {
-                // We received unknown frametype.
-                // This happens when a T38 switchover has
been performed and
-                // we consider RTP frames as UDPTL. Let's
switch to t38 mode.
-                call_is_t38_mode = TRUE;
-                passage = now;
-            }
-            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;
-        }
-        
-        //opbx_log(LOG_WARNING, "Terminating
faxn");
-        if (!call_is_t38_mode)
-            t30_terminate(&fax.t30_state);
-        else
-            t30_terminate(&t38.t30_state);
+        if ( ready && chan->t38mode_enabled!=1 )
{
+	    ready = rxfax_audio( chan, &fax, target_file,
calling_party, verbose, ecm);
+	}
 
-        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 ( ready && chan->t38mode_enabled==1 )
{
+	    ready = rxfax_t38  ( chan, &t38, target_file,
calling_party, verbose, ecm);
+	}
+
+	ready = 0; // 1 loop is enough. This could be useful if we
want to turn from udptl to RTP later.
+
     }
+
+    if (!chan->t38mode_enabled)
+	t30_terminate(&fax.t30_state);
     else
+	t30_terminate(&t38.t30_state);
+
+    fax_release(&fax);
+
+    /* Restoring initial channel formats. */
+
+    if (original_read_fmt != OPBX_FORMAT_SLINEAR)
     {
-        opbx_log(LOG_WARNING, "Could not answer
channel '%s'n", chan->name);
+        if ((res = opbx_set_read_format(chan,
original_read_fmt)))
+            opbx_log(LOG_WARNING, "Unable to restore
read format on '%s'n", chan->name);
     }
-    LOCAL_USER_REMOVE(u);
-    return res;
+    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);
+    }
+
+    return ready;
+
 }
 /*- End of function
--------------------------------------------------------*/
 
 -574,6
+726,7 
 {
     return opbx_register_application(app, rxfax_exec,
synopsis, descrip);
 }
+/*- End of function
--------------------------------------------------------*/
 
 char *description(void)
 {
 -584,6
+737,7 
 int usecount(void)
 {
     int res;
+
     STANDARD_USECOUNT(res);
     return res;
 }

Modified: openpbx/trunk/apps/app_t38gateway.c
============================================================
=======
--- openpbx/trunk/apps/app_t38gateway.c	2007-04-02 22:03:08
UTC (rev 2581)
+++ openpbx/trunk/apps/app_t38gateway.c	2007-04-02 23:34:37
UTC (rev 2582)
 -352,6
+352,7 
         else
             timeout = 60000;
     }
+
     if ((dest = strchr(tech, '/')))
     {
         int cause = 0;
 -363,6
+364,7 
             opbx_log(LOG_ERROR, "Error creating
channel %s/%sn", tech, dest);
             ALL_DONE(u, 0);
         }
+
 	if (peer)
 	{
 	  opbx_channel_inherit_variables(chan, peer);

Modified: openpbx/trunk/apps/app_txfax.c
============================================================
=======
--- openpbx/trunk/apps/app_txfax.c	2007-04-02 22:03:08 UTC
(rev 2581)
+++ openpbx/trunk/apps/app_txfax.c	2007-04-02 23:34:37 UTC
(rev 2582)
 -149,6
+149,20 
             opbx_log(LOG_WARNING, "Unable to write
frame to channel; %sn", strerror(errno));
         }
     }
+    else
+    {
+        len = 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;
+       
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));
+        }
+    }
 
     return 0;
 }
 -626,8
+640,11 
 
     }
 
-    t30_terminate(&fax.t30_state);
-    t30_terminate(&t38.t30_state);
+    if (!chan->t38mode_enabled)
+	t30_terminate(&fax.t30_state);
+    else
+	t30_terminate(&t38.t30_state);
+
     fax_release(&fax);
 
     /* Restoring initial channel formats. */

_______________________________________________
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 )