1 #ident "$Id: faxsend.c,v 4.9 2007/06/15 06:44:58 gert Exp $ Copyright (c) 1994 Gert Doering"
2 
3 /* faxsend.c
4  *
5  * Send single fax pages using a class 2 or class 2.0 faxmodem.
6  * Called by faxrec.c (poll server) and sendfax.c (sending faxes).
7  *
8  * Depends on "modem_type" being set to Mt_class2_0 for 2.0 support.
9  *
10  * Eventually add headers to each page.
11  *
12  * The code is still quite rough, but it works.
13  *
14  * $Log: faxsend.c,v $
15  * Revision 4.9  2007/06/15 06:44:58  gert
16  * add CVS Log tag
17  *
18  */
19 
20 #include <stdio.h>
21 #include <strings.h>
22 #include <fcntl.h>
23 #include <unistd.h>
24 #include "syslibs.h"
25 
26 #ifndef sunos4
27 #include <sys/ioctl.h>
28 #endif
29 #include <signal.h>
30 
31 #include "mgetty.h"
32 #include "tio.h"
33 #include "policy.h"
34 #include "fax_lib.h"
35 
36 static boolean fax_sendpg_timeout = FALSE;
37 
fax_send_timeout(SIG_HDLR_ARGS)38 static RETSIGTYPE fax_send_timeout(SIG_HDLR_ARGS)
39 {
40     signal( SIGALRM, fax_send_timeout );	/* reactivate handler */
41 
42     lprintf( L_WARN, "fax_send: timeout" );
43     fax_sendpg_timeout = TRUE;
44 }
45 
46 /* DLE ETX: send at end of all fax data to terminate page */
47 
48 static	char	fax_end_of_page[] = { DLE, ETX };
49 
50 static void fax_send_panic_exit _P1( (fd), int fd )
51 {
52     lprintf( L_FATAL, "PANIC: timeout sending fax page data, trying force modem reset\n" );
53 
54     /* by all means, reset modem */
55 
56     /* heavily use alarm(), to make sure nothing blocks */
57 
58     /* flush output queue */
59     alarm( 5 ); tio_flush_queue( fd, TIO_Q_OUT );
60 
61     /* restart possibly suspended output */
62     alarm( 5 ); tio_flow( fd, TRUE );
63 
64     /* tell modem that the page is finished. Try twice */
65     alarm( 5 );	write( fd, fax_end_of_page, sizeof( fax_end_of_page ) );
66 
67     alarm( 5 );	write( fd, fax_end_of_page, sizeof( fax_end_of_page ) );
68 
69     /* Hang up. Various methods */
70     alarm( 5 ); write( fd, "AT+FK\r\n", 7 );
71     alarm( 5 ); write( fd, "ATH0\r\n", 6 );
72 
73     /* Now, try to reset it by lowering DTR */
74     alarm( 10 );
75     tio_toggle_dtr( fd, 500 );
76     delay(500);
77     tio_toggle_dtr( fd, 500 );
78     delay(500);
79 
80     /* try again to hang up + reset it */
81     alarm( 5 ); write( fd, "ATH0Z\r\n", 7 );
82     delay(500);
83 
84     /* if the modem is *still* off-hook, there's nothing we can do. */
85     /* Hope that mgetty will be able to reinitialize it */
86 
87     alarm( 0 );
88     rmlocks();
89     exit(15);
90 }
91 
92 /* fax_send_page - send one complete fax-G3-file to the modem
93  *
94  * modem has to be in sync, waiting for at+fdt
95  * page punctuation is transmitted according to "ppm"
96  * number of bytes transmitted is added to "*bytes_sent" (for statistics)
97  */
98 int fax_send_page _P5( (g3_file, bytes_sent, tio, ppm, fd),
99 		       char * g3_file, int * bytes_sent, TIO * tio,
100 		       Post_page_messages ppm, int fd )
101 {
102     int g3fd;
103     char ch;
104     char buf[256];			/* read chunk */
105     char wbuf[ sizeof(buf) * 2 ];	/* worst case: size doubles */
106 
107     int w_total = 0;			/* total bytes written */
108 
109     int rc;				/* return code */
110 
111 #ifdef CLASS1
112     if ( modem_type == Mt_class1 || modem_type == Mt_class1_0 )
113     		return fax1_send_page( g3_file, bytes_sent, tio, ppm, fd );
114 #endif
115 
116     lprintf( L_NOISE, "fax_send_page(\"%s\") started...", g3_file );
117 
118     /* disable software output flow control! It would eat the XON otherwise! */
119     tio_set_flow_control( fd, tio, (FAXSEND_FLOW) & FLOW_HARD );
120     tio_set( fd, tio );
121 
122     /* tell modem that we're ready to send - modem will answer
123      * with a couple of "+F..." messages and finally CONNECT and XON
124      */
125 
126     if ( fax_command( "AT+FDT", "CONNECT", fd ) == ERROR ||
127 	 fax_hangup != 0 )
128     {
129 	lprintf( L_WARN, "AT+FDT -> some error (%d), abort fax send!",
130 		 fax_hangup_code );
131 	return ERROR;
132     }
133 
134     /* alarm handler */
135     signal( SIGALRM, fax_send_timeout );
136 
137     /* when modem is ready to receive data, it will send us an XON
138      * (20 seconds timeout)
139      *
140      * Not all issues of the class 2 draft require this Xon, and, further,
141      * the class 2.0 and 2.1 standard do *not* have it, so it's optional.
142      */
143     if ( modem_type == Mt_class2 &&
144 	 ( modem_quirks & MQ_NO_XON ) == 0 )
145     {
146 	lprintf( L_NOISE, "waiting for XON, got:" );
147 
148 	alarm( 20 );
149 	do
150 	{
151 	    if ( mdm_read_byte( fd, &ch ) != 1 )
152 	    {
153 		lprintf( L_ERROR, "timeout waiting for XON" );
154 		fprintf( stderr, "error waiting for XON!\n" );
155 		close( fd );
156 		exit(11);		/*! FIXME! should be done farther up */
157 	    }
158 	    lputc( L_NOISE, ch );
159 	}
160 	while ( ch != XON );
161 	alarm(0);
162     }					/* end if ( mt == class 2 ) */
163 
164     /* Now enable software flow control, if desired, we've got the Xon
165      */
166     tio_set_flow_control( fd, tio, (FAXSEND_FLOW) & (FLOW_HARD|FLOW_XON_OUT));
167     tio_set( fd, tio );
168 
169     /* send one page */
170     lprintf( L_MESG, "sending %s...", g3_file );
171 
172     g3fd = open( g3_file, O_RDONLY );
173     if ( g3fd == -1 )
174     {
175 	lprintf( L_ERROR, "cannot open %s", g3_file );
176 	lprintf( L_WARN, "have to send empty page instead" );
177     }
178     else
179     {
180 	int r, i, w;
181 	int w_refresh = 0;
182 	boolean first = TRUE;
183 
184 	/* timing at start of page is a bit critical - some modems can't
185 	 * get this reliably right, so we have the option to send a few ms
186 	 * of 0-bytes, before the 001 EOL, thus relaxing the timing a bit
187 	 */
188 	if ( modem_quirks & MQ_NEED_SP_PAD )
189 	{
190 	    char nbuf[100];
191 
192 	    lprintf( L_MESG, "send %d 0-bytes (pad before first EOL)...", sizeof(nbuf) );
193 	    bzero( nbuf, sizeof(nbuf) );
194 	    write( fd, nbuf, sizeof(nbuf) );
195 	}
196 
197 	alarm( 40 );		/* timeout if we get stuck in flow control */
198 
199 	while ( ( r = read( g3fd, buf, 64 ) ) > 0 )
200 	{
201 	    /* refresh alarm counter every 1000 bytes */
202 	    if ( w_refresh > 1000 )
203 	    {
204 		w_refresh -= 1000;
205 		alarm( 30 );
206 	    }
207 
208 	    i = 0;
209 	    /* skip over GhostScript / digifaxhigh header */
210 
211 	    if ( first )
212 	    {
213 		first = FALSE;
214 		if ( r >= 64 && strcmp( buf+1,
215 					"PC Research, Inc" ) == 0 )
216 		{
217 		    lprintf( L_MESG, "skipping over GhostScript header" );
218 		    i = 64;
219 		    /* for dfax files, we can check if the resolutions match
220 		     */
221 		    if ( ( fax_par_d.vr != 0 ) != ( buf[29] != 0 ) )
222 		    {
223 			fprintf( stderr, "WARNING: sending in %s mode, fax data is %s mode\n",
224 				 fax_par_d.vr? "fine" : "normal",
225 				 buf[29]     ? "fine" : "normal" );
226 			lprintf( L_WARN, "resolution mismatch" );
227 		    }
228 		}
229                 else
230 		/* it's incredible how stupid users are - check for */
231 		/* "tiffg3" files and issue a warning if the file is */
232 		/* suspect */
233                 if ( r >= 2 && ( ( buf[0] == 0x49 && buf[1] == 0x49 ) ||
234                                  ( buf[0] == 0x4d && buf[1] == 0x4d ) ) )
235 		{
236 		    lprintf( L_WARN, "file may be 'tiffg3' - TIFF is *not* a valid input format" );
237 		    fprintf( stderr, "WARNING: file may be 'tiffg3' - TIFF file format is *not* supported!\n" );
238 		    fprintf( stderr, "         Thus, fax transmission will most propably fail\n" );
239 		}
240                 else
241                 if ( r < 10 || buf[0] != 0 )
242 		{
243 		    lprintf( L_WARN, "file looks 'suspicious', buf=%02x %02x %02x %02x...", buf[0] &0xff, buf[1] &0xff, buf[2] &0xff, buf[3] &0xff );
244                     fprintf( stderr, "WARNING: are you sure that this is a G3 fax file? Doesn't seem to be...\n" );
245 		}
246 	    }
247 
248 	    /* escape DLE characters. If necessary (+FBO=0), swap bits */
249 
250 	    for ( w = 0; i < r; i++ )
251 	    {
252 		wbuf[ w ] = fax_send_swaptable[ (unsigned char) buf[i] ];
253 		if ( wbuf[ w++ ] == DLE ) wbuf[ w++ ] = DLE;
254 	    }
255 
256 	    lprintf( L_JUNK, "read %d, write %d", r, w );
257 
258 	    if ( write( fd, wbuf, w ) != w )
259 	    {
260 		lprintf( L_ERROR, "could not write all %d bytes", w );
261 	    }
262 
263 	    /* check for timeout */
264 
265 	    if ( fax_sendpg_timeout )
266 	    {
267 		fax_send_panic_exit( fd );
268 	    }
269 
270 	    w_total += w;
271 	    w_refresh += w;
272 
273 	    /* look if there's something to read
274 	     *
275 	     * normally there shouldn't be anything, but I have
276 	     * seen very old ZyXEL releases sending junk and then
277 	     * failing completely... so this may help when debugging
278 	     *
279 	     * Also, if you don't use FLOW_SOFT for sendfax, and
280 	     * your modem insists on xon/xoff flow control, you'll
281 	     * see these characters [0x11/0x13] here.
282 	     */
283 
284 	    if ( check_for_input( fd ) )
285 	    {
286 		lprintf( L_NOISE, "input: got " );
287 		do
288 		{
289 		    /* intentionally don't use mdm_read_byte here */
290 		    if ( read( fd, &ch, 1 ) != 1 )
291 		    {
292 			lprintf( L_ERROR, "read failed" );
293 			break;
294 		    }
295 		    else
296 			lputc( L_NOISE, ch );
297 		}
298 		while ( check_for_input( fd ) );
299 	    }
300 	}		/* end while (more g3 data to read) */
301 	close(g3fd);
302     }			/* end if (open file succeeded) */
303 
304     lprintf( L_MESG, "page complete, %d bytes sent", w_total );
305 
306     if ( bytes_sent != NULL )
307             *bytes_sent += w_total;
308 
309     /* send end-of-page characters and post-page-message */
310     rc = fax_send_ppm( fd, tio, ppm );
311 
312     alarm(0);
313 
314     return rc;
315 }
316 
317 /* send end-of-page code, set fax_page_transmit_status
318  *
319  * class 2  : send <DLE> <ETX>, then send AT+FET=... according to "type"
320  * class 2.0: send <DLE>{<mps>|<eop>|<eom>}, then send AT+FPS?
321  */
322 int fax_send_ppm _P3( (fd, tio, ppm),
323 		      int fd, TIO * tio, Post_page_messages ppm )
324 {
325     int rc;
326 
327     /* set alarm clock to a time long enough to handle *very* slow links
328      * on modems with *very* large buffers (2400 / ZyXEL...)
329      */
330     alarm( FAX_RESPONSE_TIMEOUT );
331 
332     if ( modem_type == Mt_class2_0 )
333     {
334 	/* in class 2.0, end-of-page *and* page punctuation are
335 	 * transmitted in one. The modem will return OK or ERROR,
336 	 * depending on the remote page transmit status
337 	 */
338 	/* EIA 592, 8.3.3.7 */
339 	char ppm_char, ppm_buf[2], *ppm_r;
340 
341 	switch( ppm )
342 	{
343 	  case pp_mps:		/* another page next */
344 	    ppm_char = 0x2c; break;
345 	  case pp_eom:		/* last page, another document next */
346 	    ppm_char = 0x3b; break;
347 	  case pp_eop:		/* no more pages or documents */
348 	    /* stop being sensitive to DCD drops */
349 #ifdef sun
350 	    /* On SUNs, HW handshake has to be off while carrier is low */
351 	    /* -> to avoid underruns, drain buffers first (Nils Jonsson) */
352 	    tio_drain_output( fd );
353 	    tio_set_flow_control(fd, tio, (FAXSEND_FLOW) & FLOW_XON_OUT);
354 #endif
355 	    tio_carrier( tio, FALSE );
356 	    tio_set( fd, tio );
357 
358 	    ppm_char = 0x2e; break;
359 	  default:
360 	    lprintf( L_WARN, "ppm type %d not implemented", ppm );
361 	    return ERROR;
362 	}
363 
364 	lprintf( L_MESG, "sending DLE '" );
365 	lputc( L_MESG, ppm_char ); lputc( L_MESG, '\'' );
366 
367 	ppm_buf[0] = DLE; ppm_buf[1] = ppm_char;
368 	if ( write( fd, ppm_buf, 2 ) != 2 )
369 	{
370 	    lprintf( L_ERROR, "cannot write PPM" );
371 	    return ERROR;
372 	}
373 
374 	/* FIXME: I think this should be done with fax_wait_for()! */
375 	do
376 	{
377 	    ppm_r = mdm_get_line( fd );
378 	    if ( ppm_r == NULL ) return ERROR;
379 
380 	    /* hangup code. See fax_wait_for() for comments */
381 	    if ( strncmp( ppm_r, "+FHS:", 5 ) == 0 )
382 	    {
383 		fax_hangup = 1;
384 		signal( SIGHUP, SIG_IGN );
385 		sscanf( &ppm_r[5], "%d", &fax_hangup_code );
386 		lprintf( L_MESG, "connection hangup: '%s'", ppm_r );
387 		lprintf( L_NOISE,"(%s)", fax_strerror( fax_hangup_code ));
388 	    }
389 	}
390 	while ( strcmp( ppm_r, "OK" ) != 0 &&
391 	        strcmp( ppm_r, "ERROR" ) != 0 );
392 	lprintf( L_MESG, "got response: '%s'", ppm_r );
393 
394 	/* fax page status is encoded here! */
395 	/* FIXME: query page tx status from modem */
396 	fax_page_tx_status = ( strcmp( ppm_r, "OK" ) == 0 ) ? 1: 2;
397 
398 	/* FIXME: this way? */
399 /*	fax_command( "AT+FPS?", "OK", fd ); */
400 
401 	return NOERROR;
402     }
403     else
404     {
405 	/* transmit end of page (<DLE><ETX> -> OK) */
406 
407 	lprintf( L_MESG, "sending DLE ETX..." );
408 	write( fd, fax_end_of_page, sizeof( fax_end_of_page ));
409 
410 	if ( fax_wait_for( "OK", fd ) == ERROR ) return ERROR;
411 
412 	/* transmit page punctuation */
413 
414 	switch ( ppm )
415 	{
416 	  case pp_mps:		/* another page next */
417 	    rc = fax_command( "AT+FET=0", "OK", fd );
418 	    break;
419 	  case pp_eom:		/* last page, another document next */
420 	    rc = fax_command( "AT+FET=1", "OK", fd );
421 	    break;
422 	  case pp_eop:		/* no more pages or documents, over & out */
423 
424 	    /* take care of modems pulling DCD low before the final
425 	     * result code has reached the host
426 	     */
427 	    tio_carrier( tio, FALSE );
428 #ifdef sun
429 	    /* HW handshake has to be off while carrier is low */
430 	    tio_set_flow_control(fd, tio, (FAXSEND_FLOW) & FLOW_XON_OUT);
431 #endif
432 	    tio_set( fd, tio );
433 
434 	    rc = fax_command( "AT+FET=2", "OK", fd );
435 	    break;
436 	  default:		/* pri-xxx codes */
437 	    lprintf( L_WARN, "ppm type %d not implemented", ppm );
438 	    rc = ERROR;
439 	}
440 
441 	return rc;
442     }				/* end if ( ! modem == 2.0 ) */
443 }
444