1 #ident "$Id: class1.c,v 4.20 2009/03/19 15:51:17 gert Exp $ Copyright (c) Gert Doering" 2 3 /* class1.c 4 * 5 * High-level functions to handle class 1 fax -- 6 * state machines for fax phase A, B, C, D. Error recovery. 7 * 8 * Uses library functions in class1lib.c, faxlib.c and modem.c 9 * 10 * $Log: class1.c,v $ 11 * Revision 4.20 2009/03/19 15:51:17 gert 12 * bugfix: new NSF sending code was introducing extra "AT+FTH=3" commands 13 * (due to confusion about internal requirements of fax1_send_frame()) 14 * 15 * Revision 4.19 2009/03/19 15:33:59 gert 16 * send NSF frames on reception (if modem quirk 0x40, for now) 17 * handle different modem behaviour regarding AT+FTS=8;+FTH=3 gracefully 18 * 19 * Revision 4.18 2006/10/27 09:07:12 gert 20 * add file name of page currently sent to log message 21 * 22 * Revision 4.17 2006/10/25 10:55:01 gert 23 * class 1 receive: log current try #, send DIS only if CSI went without error 24 * 25 * Revision 4.16 2006/09/29 19:30:26 gert 26 * properly calculate scan line time -> padding bytes 27 * implement FTT -> retraining, with baud rate reduction 28 * 29 * Revision 4.15 2006/09/26 15:36:07 gert 30 * - handle modems that don't get AT+FTS=8;+FTM=nn right 31 * (re-do AT+FTM if the first command yields "OK") 32 * - switch on and off Xon/Xoff flow control before/after sending page data 33 * 34 * Revision 4.14 2006/09/25 22:26:54 gert 35 * fax1_send_page(): move all the G3 file handling to g3file.c functions 36 * (-> cleanup code, build common infrastructure for class 1 + class 2) 37 * 38 * Revision 4.13 2006/03/22 14:13:12 gert 39 * when sending, hand over received NSF to NSF decoder (faxlib.c/hyla_nsf.c) 40 * 41 * Revision 4.12 2006/03/07 21:31:50 gert 42 * class 1 sending implementation: 43 * - handle end-of-page (return to phase B or phase C, or send DCN/hangup) 44 * - move sending of TSI and DCS inside fax1_send_page(), to be able to 45 * handle RTN/RTP transparently - somewhat sloppy "phase B" definition, 46 * but much cleaner this way 47 * - fix reading of G3 files - skip digifax header, also send last chunk 48 * - fix bit swapping (fax_send_swaptable) 49 * -> class 1 sending now works, if the receiver doesn't need EOL padding 50 * 51 * Revision 4.11 2006/03/07 14:16:56 gert 52 * fax1_dial_and_phase_AB(): add torture test code, refusing incoming CSI/DIS 53 * 2 times before going on (mainly for testing receiver robustness) 54 * fax1_send_page(): add log message to point out unimplemented stuff 55 * 56 * Revision 4.10 2006/01/04 21:07:12 gert 57 * remove "speed" argument from fax1_send_dcs() (use fax1_max global) 58 * 59 * Revision 4.9 2006/01/03 09:12:20 gert 60 * initialize "tries" in fax1_receive_page() 61 * 62 * Revision 4.8 2006/01/01 17:07:43 gert 63 * change all fax1_send_dcn() to already set appropriate hangup code 64 * add prototypes for local functions 65 * add timeout handling and re-try logic to fax1_highlevel_receive(), 66 * fax1_receive_tcf() and fax1_receive_page() 67 * add handling of incoming DCNs (give up) 68 * add calculation of "how long should TCF be?" + checking to fax1_receive_tcf() 69 * 70 * Revision 4.7 2005/12/31 17:47:10 gert 71 * use fax1_send_dis() instead of doing it here 72 * 73 * Revision 4.6 2005/12/31 15:52:08 gert 74 * more comments 75 * fax 1 receiver: 76 * * use global variable fax1_receive_have_connect to 77 * communicate answering status ("have we seen CONNECT?") from mgetty.c 78 * * prepare full T.30 receive state machine, including EOM->phase B 79 * and RTP/RTN->TCF (not complete) 80 * * set fax_hangup/fax_hangup_code correctly upon some error situations 81 * 82 * Revision 4.5 2005/12/30 23:05:05 gert 83 * rework fax1_send_frame(): leading 0xff is now implicit 84 * (symmetric to fax1_receive_frame()) 85 * change all callers to use new "frame" layout without 0xff 86 * change lots of occurences of "3" to use "T30_CAR_V21" 87 * rename fax1_receive() to fax1_highlevel_receive() 88 * use "fd" and not "STDIN" everywhere 89 * hand DCS frame to class1lib/fax1_parse_dcs() 90 * -> use proper carrier values for TCF and page reception (partially untested) 91 * change "simple" frame sending to use fax1_send_simf_final() 92 * add more comments about individual fax phases 93 * 94 * Revision 4.4 2005/12/28 21:53:08 gert 95 * fix some compiler warnings and typos 96 * adapt to changed fax1_send_idframe() 97 * add CVS header 98 * add (very rough and incomplete) fax class 1 implementation, consisting 99 * - fax1_receive() (to be called from faxrec.c) 100 * - fax1_receive_tcf() (handle TCF training frame + responses) 101 * - fax1_receive_page() (setup page reception, hand to fax_get_page_data()) 102 * 103 */ 104 105 #ifdef CLASS1 106 107 #include <stdio.h> 108 #include <stdlib.h> 109 #include <string.h> 110 #include <unistd.h> 111 #include <signal.h> 112 #include <fcntl.h> 113 114 #include "mgetty.h" 115 #include "fax_lib.h" 116 #include "tio.h" 117 #include "class1.h" 118 #include "policy.h" 119 120 enum T30_phases { Phase_A, Phase_B, Phase_C, Phase_D, Phase_E } fax1_phase; 121 122 /* maping of "st" codes to actual time (for normal res.) */ 123 static int fax_scan_times[8] = { 0, 5, 10, 10, 20, 20, 40, 40 }; 124 125 int fax1_dial_and_phase_AB _P2( (dial_cmd,fd), char * dial_cmd, int fd ) 126 { 127 char * p; /* modem response */ 128 uch framebuf[FRAMESIZE]; 129 int first; 130 int len; 131 #ifdef TORTURE_TEST 132 int t_tries=0; 133 #endif 134 135 /* send dial command */ 136 if ( fax_send( dial_cmd, fd ) == ERROR ) 137 { 138 fax_hangup = TRUE; fax_hangup_code = FHUP_ERROR; 139 return ERROR; 140 } 141 142 /* wait for ERROR/NO CARRIER/CONNECT */ 143 signal( SIGALRM, fax1_sig_alarm ); 144 alarm(FAX_RESPONSE_TIMEOUT); 145 146 while( !fax_hangup ) 147 { 148 p = mdm_get_line ( fd ); 149 150 if ( p == NULL ) 151 { lprintf( L_ERROR, "fax1_dial: hard error dialing out" ); 152 fax_hangup = TRUE; fax_hangup_code = FHUP_ERROR; break; } 153 154 lprintf( L_NOISE, "fax1_dial: string '%s'", p ); 155 156 if ( strcmp( p, "ERROR" ) == 0 || 157 strcmp( p, "NO CARRIER" ) == 0 ) 158 { fax_hangup = TRUE; fax_hangup_code = FHUP_ERROR; break; } 159 160 if ( strcmp( p, "NO DIALTONE" ) == 0 || 161 strcmp( p, "NO DIAL TONE" ) == 0 ) 162 { fax_hangup = TRUE; fax_hangup_code = FHUP_NODIAL; break; } 163 164 if ( strcmp( p, "BUSY" ) == 0 ) 165 { fax_hangup = TRUE; fax_hangup_code = FHUP_BUSY; break; } 166 167 if ( strcmp( p, "CONNECT" ) == 0 ) /* gotcha! */ 168 { break; } 169 } 170 171 alarm(0); 172 if ( fax_hangup ) return ERROR; 173 174 /* now start fax negotiation (receive CSI, DIS, send DCS) 175 * read all incoming frames until FINAL bit is set 176 */ 177 first=TRUE; 178 again: 179 do 180 { 181 if ( (len = fax1_receive_frame( fd, first? 0:3, 30, framebuf ) ) 182 == ERROR ) 183 { 184 /*!!!! try 3 times! (flow diagram from T.30 / T30_T1 timeout) */ 185 fax_hangup = TRUE; fax_hangup_code = 11; return ERROR; 186 } 187 switch ( framebuf[1] ) /* FCF */ 188 { 189 case T30_CSI: fax1_copy_id( framebuf ); break; 190 case T30_NSF: fax1_incoming_nsf( framebuf+2, len-2 ); break; 191 case T30_DIS: fax1_parse_dis( framebuf ); break; 192 case T30_DCN: fax1_send_dcn( fd, 20 ); return ERROR; 193 default: 194 lprintf( L_WARN, "unexpected frame type 0x%02x", framebuf[1] ); 195 } 196 first=FALSE; 197 } 198 while( ( framebuf[0] & T30_FINAL ) == 0 ); 199 200 #ifdef TORTURE_TEST 201 while( ++t_tries < 3 ) 202 { mdm_command( "AT+FRS=200", fd ); goto again; } 203 #endif 204 205 206 fax1_phase = Phase_B; /* Phase A done */ 207 208 return NOERROR; 209 } 210 211 212 /* fax1_send_page 213 * 214 * send a page of G3 data 215 * - if phase is "B", include sending of DCS, TCF and possibly 216 * baud rate stepdown and repeated transmission of DCS. 217 * - if phase is "C", directly send page data 218 */ 219 220 int fax1_send_page _P5( (g3_file, bytes_sent, tio, ppm, fd), 221 char * g3_file, int * bytes_sent, TIO * tio, 222 Post_page_messages ppm, int fd ) 223 { 224 uch framebuf[FRAMESIZE]; 225 char * line; 226 char cmd[40]; 227 char dleetx[] = { DLE, ETX }; 228 char rtc[] = { 0x00, 0x08, 0x80, 0x00, 0x08, 0x80, 0x00, 0x08 }; 229 int pad_bytes, s_time; 230 231 /* if we're in T.30 phase B, send DCS + training frame (TCF) now... 232 * don't forget delay (75ms +/- 20ms)! 233 * 234 * NOTE: this is not strictly "phase B" - in T.30, phase B begins 235 * after sending the DCS, and before sending TCF. But since RTN/RTP 236 * return to sending DCS (bullet "D" in T.30 chart 5-2a), grouping it 237 * this way is much more logical to implement 238 */ 239 240 /* calculate scan line time 241 * in fine mode, some of the values get divided by 2 242 */ 243 s_time = fax_scan_times[ remote_cap.st & 0x7 ]; 244 if ( remote_cap.vr == 1 && 245 (remote_cap.st & 0x1) == 0 ) s_time /= 2; 246 247 if ( fax1_phase == Phase_B ) 248 { 249 char train[150]; 250 int i, num; 251 int tries=0; 252 253 retrain: /* "(D)" in T.30/Figure 5-2a */ 254 255 /* send local id frame (TSI) */ 256 fax1_send_idframe( fd, T30_TSI|0x01, T30_CAR_V21 ); 257 258 /* send DCS */ 259 if ( fax1_send_dcs( fd, s_time ) == ERROR ) 260 { 261 fax_hangup = TRUE; fax_hangup_code = 10; return ERROR; 262 } 263 264 sprintf( cmd, "AT+FTS=8;+FTM=%d", dcs_btp->c_long ); 265 fax_send( cmd, fd ); 266 267 line = mdm_get_line( fd ); 268 if ( line != NULL && strcmp( line, cmd ) == 0 ) 269 line = mdm_get_line( fd ); 270 271 if ( strcmp( line, "OK" ) == 0 ) 272 { 273 lprintf( L_MESG, "fax1_send_page: unexpected OK, re-do AT+FTM" ); 274 275 sprintf( cmd, "AT+FTM=%d", dcs_btp->c_long ); 276 fax_send( cmd, fd ); 277 278 line = mdm_get_line( fd ); 279 if ( line != NULL && strcmp( line, cmd ) == 0 ) 280 line = mdm_get_line( fd ); 281 } 282 283 if ( line == NULL || strcmp( line, "CONNECT" ) != 0 ) 284 { 285 lprintf( L_ERROR, "fax1_send_page: unexpected response 1: '%s'", line ); 286 fax_hangup = TRUE; fax_hangup_code = 20; return ERROR; 287 } 288 289 /* send data for training (1.5s worth) */ 290 291 num = (dcs_btp->speed/8)*1.5; 292 lprintf( L_NOISE, "fax1_send_page: send %d bytes training (TCF)", num ); 293 memset( train, 0, sizeof(train)); 294 295 for( i=0; i<num; i+=sizeof(train)) 296 write( fd, train, sizeof(train) ); 297 write( fd, dleetx, 2 ); 298 299 line = mdm_get_line( fd ); 300 if ( line == NULL || strcmp( line, "OK" ) != 0 ) 301 { 302 lprintf( L_ERROR, "fax1_send_page: unexpected response 2: '%s'", line ); 303 fax_hangup = TRUE; fax_hangup_code = 20; return ERROR; 304 } 305 306 /* receive frame - FTT or CFR */ 307 /*!!! return code! TODO: retry logic - T.30 fig. 5-2a/p.16 */ 308 fax1_receive_frame( fd, 3, 30, framebuf ); 309 310 if ( ( framebuf[0] & T30_FINAL ) == 0 || 311 framebuf[1] != T30_CFR ) 312 { 313 tries++; 314 lprintf( L_WARN, "fax1_send_frame: failed to train (%d)", tries); 315 316 if ( tries > 1 ) fax1_reduce_max(); 317 if ( tries < 3 ) goto retrain; 318 319 /* give up */ 320 fax1_send_dcn( fd, 27 ); return ERROR; 321 } 322 323 /* phase B done, go to phase C */ 324 fax1_phase = Phase_C; 325 } 326 327 if ( fax1_phase != Phase_C ) 328 { 329 lprintf( L_ERROR, "fax1_send_page: internal error: not Phase C" ); 330 fax_hangup = TRUE; fax_hangup_code = FHUP_ERROR; 331 return ERROR; 332 } 333 334 /* open G3 file, read first chunk, potentially skipping digifax header 335 */ 336 if ( g3_open_read( g3_file ) < 0 ) 337 { 338 /*!!! do something smart here...? */ 339 fax1_send_dcn( fd, FHUP_ERROR ); 340 return ERROR; 341 } 342 343 344 /* number of bytes to pad depend on scan time */ 345 pad_bytes = ((dcs_btp->speed/8) * s_time + 999) / 1000; 346 lprintf( L_MESG, "scan line time: %d ms -> %d bytes/line at %d bps", 347 s_time, pad_bytes, dcs_btp->speed ); 348 349 /* Phase C: send page data with high-speed carrier 350 */ 351 sprintf( cmd, "AT+FTM=%d", dcs_btp->c_short ); 352 fax_send( cmd, fd ); 353 354 line = mdm_get_line( fd ); 355 if ( line != NULL && strcmp( line, cmd ) == 0 ) 356 line = mdm_get_line( fd ); 357 358 if ( line == NULL || strcmp( line, "CONNECT" ) != 0 ) 359 { 360 lprintf( L_ERROR, "fax1_send_page: unexpected response 3: '%s'", line ); 361 fax_hangup = TRUE; fax_hangup_code = 40; return ERROR; 362 } 363 364 lprintf( L_NOISE, "send page data (\"%s\")...", g3_file ); 365 366 /* turn on xon/xoff flow control now, for page data sending 367 */ 368 if ( (FAXSEND_FLOW) & FLOW_SOFT ) 369 { 370 tio_set_flow_control( fd, tio, (FAXSEND_FLOW) & (FLOW_HARD|FLOW_XON_OUT)); 371 tio_set( fd, tio ); 372 } 373 374 /* read page data from file, invert byte order, 375 * insert padding bits (if scan line time > 0), 376 * at end-of-file, add RTC 377 */ 378 if ( g3_send_file( g3_rf_chunk, fd, TRUE, TRUE, pad_bytes, 0 /*TODO!*/) < 0 ) 379 { 380 lprintf( L_ERROR, "error in g3_send_file()" ); 381 return ERROR; 382 } 383 384 /*!!! ERROR HANDLING!! */ 385 /*!!! PARANOIA: alarm()!! */ 386 /* end of page: RTC */ 387 write( fd, rtc, sizeof(rtc) ); 388 389 /* end of data: DLE ETX */ 390 write( fd, dleetx, 2 ); 391 392 line = mdm_get_line( fd ); 393 if ( line == NULL || strcmp( line, "OK" ) != 0 ) 394 { 395 lprintf( L_ERROR, "fax1_send_page: unexpected response 3a: '%s'", line ); 396 fax_hangup = TRUE; fax_hangup_code = 40; return ERROR; 397 } 398 399 /* turn off xon/xoff flow control (will interfere with received frames) */ 400 if ( (FAXSEND_FLOW) & FLOW_SOFT ) 401 { 402 tio_set_flow_control( fd, tio, (FAXSEND_FLOW) & FLOW_HARD ); 403 tio_set( fd, tio ); 404 } 405 406 /* now send end-of-page frame (MPS/EOM/EOP) and get pps */ 407 408 fax1_phase = Phase_D; 409 lprintf( L_MESG, "page data sent, sending end-of-page frame (C->D)" ); 410 sprintf( cmd, "AT+FTS=8;+FTH=3" ); 411 fax_send( cmd, fd ); 412 413 line = mdm_get_line( fd ); 414 if ( line != NULL && strcmp( line, cmd ) == 0 ) 415 line = mdm_get_line( fd ); 416 417 if ( line == NULL || strcmp( line, "CONNECT" ) != 0 ) 418 { 419 if ( strcmp( line, "OK" ) == 0 ) goto tryanyway; 420 lprintf( L_ERROR, "fax1_send_page: unexpected response 4: '%s'", line ); 421 fax_hangup = TRUE; fax_hangup_code = 50; return ERROR; 422 } 423 424 /* some modems seemingly can't handle AT+FTS=8;+FTH=3 (returning 425 * "OK" instead of "CONNECT"), so send AT+FTH=3 again for those. 426 */ 427 tryanyway: 428 429 framebuf[0] = 0x03 | T30_FINAL; 430 switch( ppm ) 431 { 432 case pp_eom: framebuf[1] = T30_EOM | fax1_dis; break; 433 case pp_eop: framebuf[1] = T30_EOP | fax1_dis; break; 434 case pp_mps: framebuf[1] = T30_MPS | fax1_dis; break; 435 default: 436 lprintf( L_WARN, "fax1_send_page: canthappen(1) - PRI not supported" ); 437 } 438 439 if ( strcmp( line, "OK" ) == 0 ) /* re-send AT+FTH=3 */ 440 { 441 fax1_send_frame( fd, T30_CAR_V21, framebuf, 2 ); 442 } 443 else /* it got sent & acked */ 444 { 445 fax1_send_frame( fd, T30_CAR_HAVE_V21, framebuf, 2 ); 446 } 447 448 /* get MPS/RTP/RTN code */ 449 fax1_receive_frame( fd, T30_CAR_V21, 30, framebuf ); 450 451 /*!!! T.30 flow chart... */ 452 453 switch( framebuf[1] ) 454 { 455 case T30_MCF: /* page good */ 456 fax_page_tx_status = 1; fax1_phase = Phase_C; break; 457 case T30_RTN: /* retrain / negative */ 458 fax_page_tx_status = 2; fax1_phase = Phase_B; break; 459 case T30_RTP: /* retrain / positive */ 460 fax_page_tx_status = 3; fax1_phase = Phase_B; break; 461 case T30_PIN: /* procedure interrupt */ 462 fax_page_tx_status = 4; fax1_phase = Phase_B; break; 463 case T30_PIP: 464 fax_page_tx_status = 5; fax1_phase = Phase_C; break; 465 default: 466 lprintf( L_ERROR, "fax1_transmit_page: unexpected frame" ); 467 fax1_send_dcn(fd, 53); break; 468 } 469 470 /* if this was the last page, and the receiver is happy 471 * (MCF or RTP), send DCN, and call it quits 472 */ 473 if ( ppm == pp_eop && 474 ( fax_page_tx_status == 1 || fax_page_tx_status == 3 || 475 fax_page_tx_status == 5 ) ) 476 { 477 fax1_send_dcn( fd, 0 ); 478 fax1_phase = Phase_E; 479 } 480 481 /* otherwise, nothing to do - caller will re-enter fax1_send_page(), 482 * for next page / re-send of same page (we won't know) 483 */ 484 return NOERROR; 485 } 486 487 boolean fax1_receive_have_connect = FALSE; 488 489 int fax1_receive_tcf _PROTO((int fd, int carrier, int wantbytes)); 490 int fax1_receive_page _PROTO((int fd, int carrier, int * pagenum, 491 char * dirlist, int uid, int gid, int mode )); 492 493 int fax1_highlevel_receive _P6( (fd, pagenum, dirlist, uid, gid, mode ), 494 int fd, int * pagenum, char * dirlist, 495 int uid, int gid, int mode) 496 { 497 int rc; 498 uch frame[FRAMESIZE]; 499 char * p; 500 Post_page_messages ppm = pp_mps; 501 boolean first = TRUE; 502 int tries; 503 boolean have_dcs; 504 505 /* after ATA/CONNECT, first AT+FTH=3 is implicit -> send frames 506 right away (first=TRUE) - when coming back to phase B after EOM, 507 AT+FTH=3 must be sent */ 508 509 /* with +FAE=1, the sequence seems to be 510 * RING 511 * ATA 512 * FAX 513 * CONNECT 514 */ 515 516 if ( !fax1_receive_have_connect ) 517 { 518 alarm(10); 519 p = mdm_get_line( fd ); 520 alarm(0); 521 522 if ( p == NULL || strcmp( p, "CONNECT" ) != 0 ) 523 { 524 lprintf( L_WARN, "fax1_receive: initial CONNECT not seen" ); 525 fax_hangup = TRUE; fax_hangup_code = FHUP_TIMEOUT; 526 return ERROR; 527 } 528 } 529 530 *pagenum = 0; 531 532 /* phase B: Fax negotiations 533 */ 534 tries=0; have_dcs=FALSE; 535 536 receive_phase_b: 537 lprintf( L_MESG, "fax1 T.30 receive phase B (try %d)", tries+1 ); 538 539 /* send NSF frame (if requested) */ 540 if ( modem_quirks & MQ_SHOW_NSF ) 541 { 542 rc = fax1_send_nsf( fd, first?T30_CAR_HAVE_V21: T30_CAR_V21 ); 543 } 544 545 /* send local ID frame (CSI) - non-final */ 546 rc = fax1_send_idframe( fd, T30_CSI, first?T30_CAR_HAVE_V21: T30_CAR_V21 ); 547 first = FALSE; 548 549 /* send DIS (but only if we haven't seen an error sending CSI) */ 550 if ( rc == NOERROR ) 551 rc = fax1_send_dis( fd ); 552 553 /* now see what the other side has to say... */ 554 wait_for_dcs: 555 556 do 557 { 558 if ( fax1_receive_frame( fd, T30_CAR_V21, 30, frame ) == ERROR ) 559 { 560 if ( ++tries < 3 ) goto receive_phase_b; 561 fax1_send_dcn( fd, 70 ); 562 return ERROR; 563 } 564 switch( frame[1] & 0xfe ) /* FCF, ignoring X-bit */ 565 { 566 case T30_TSI: fax1_copy_id( frame ); break; 567 case T30_NSF: break; 568 case T30_DCS: fax1_parse_dcs( frame ); have_dcs=TRUE; break; 569 case T30_DCN: fax1_send_dcn( fd, 70 ); 570 return ERROR; break; 571 default: 572 lprintf( L_WARN, "unexpected frame type 0x%02x", frame[1] ); 573 } 574 } 575 while( ( frame[0] & T30_FINAL ) == 0 ); 576 577 if ( !have_dcs ) 578 { 579 lprintf( L_WARN, "T.30 B: final frame, but no DCS seen, re-send DIS" ); 580 if ( ++tries < 3 ) goto receive_phase_b; 581 fax1_send_dcn( fd, 70 ); 582 return ERROR; 583 } 584 585 /* fax1_parse_dcs() has setup dcs_btp and fax_par_d for us */ 586 587 /* receive 1.5s training sequence */ 588 rc = fax1_receive_tcf( fd, dcs_btp->c_long, (dcs_btp->speed/8)*1.5 ); 589 590 /* error receiving TCF ("no carrier seen") -> redo DIS/DCS */ 591 if ( rc < 0 ) 592 goto receive_phase_b; 593 594 /* TCF bad? send FTT (failure to train), wait for next DCS */ 595 if ( rc == 0 ) 596 { 597 rc = fax1_send_simf_final( fd, T30_CAR_V21, T30_FTT ); 598 if ( ++tries < 10 ) goto wait_for_dcs; 599 fax1_send_dcn( fd, 73 ); 600 return ERROR; 601 } 602 603 /* TCF good, send CFR frame (confirmation to receive) */ 604 rc = fax1_send_simf_final( fd, T30_CAR_V21, T30_CFR ); 605 606 receive_next_page: 607 608 /* phase C: start page reception & get page data 609 */ 610 lprintf( L_MESG, "fax1 T.30 receive phase C" ); 611 612 rc = fax1_receive_page( fd, dcs_btp->c_short, pagenum, 613 dirlist, uid, gid, mode ); 614 615 /* if we have already hung up, not worth doing any retries etc. 616 */ 617 if ( rc == ERROR && fax_hangup ) return ERROR; 618 619 /* phase D: post-message status 620 * switch back to low-speed carrier, get (PRI-)EOM/MPS/EOP code 621 */ 622 623 tries=0; 624 receive_phase_d: 625 lprintf( L_MESG, "fax1 T.30 receive phase D" ); 626 627 /* TODO: T.30 flow chart: will we ever hit non-final frames here? 628 * what to do on error? 629 */ 630 do 631 { 632 if ( fax1_receive_frame( fd, T30_CAR_V21, 30, frame ) == ERROR ) 633 { 634 /* retry post-page handshake 3 times, then give up */ 635 if ( ++tries < 3 ) goto receive_phase_d; 636 fax1_send_dcn( fd, 100 ); 637 return ERROR; 638 } 639 switch( frame[1] & 0xfe & ~T30_PRI ) /* FCF, ignoring X-bit */ 640 { 641 case T30_MPS: 642 lprintf( L_MESG, "MPS: end of page, more to come" ); ppm = pp_mps; 643 break; 644 case T30_EOM: 645 lprintf( L_MESG, "EOM: back to phase B" ); ppm = pp_eom; 646 break; 647 case T30_EOP: 648 lprintf( L_MESG, "EOP: end of transmission" ); 649 ppm = pp_eop; 650 break; 651 case T30_DCN: 652 fax1_send_dcn( fd, 101 ); 653 return ERROR; 654 break; 655 default: 656 lprintf( L_WARN, "unexpected frame type 0x%02x", frame[1] ); 657 } 658 } 659 while( ( frame[0] & T30_FINAL ) == 0 ); 660 661 /* send back page good/bad return code (TODO: RTN/RTP codes) */ 662 /* TODO: for RTN/RTP, restart training sequence (TCF) (??) */ 663 rc = fax1_send_simf_final( fd, T30_CAR_V21, T30_MCF ); 664 665 /* go back to phase B (EOM), go to next page (MPS), done (EOP) */ 666 if ( ppm == pp_eom ) 667 { goto receive_phase_b; } 668 if ( ppm == pp_mps ) 669 { goto receive_next_page; } 670 671 /* EOP - get goodbye frame (DCN) from remote end, hang up */ 672 fax1_receive_frame( fd, T30_CAR_V21, 30, frame ); 673 674 if ( (frame[1] & 0xfe) != T30_DCN ) 675 { 676 lprintf( L_WARN, "fax1_receive: unexpected frame 0x%02x 0x%02x after EOP", frame[0], frame[1] ); 677 } 678 679 fax_hangup = TRUE; 680 fax_hangup_code = 0; 681 return NOERROR; 682 } 683 684 int fax1_receive_tcf _P3((fd,carrier,wantbytes), 685 int fd, int carrier, int wantbytes) 686 { 687 int rc, count, notnull; 688 char c, *p; 689 boolean wasDLE=FALSE; 690 int tries; 691 692 tries=0; 693 694 lprintf( L_NOISE, "fax1_r_tcf: carrier=%d", carrier ); 695 696 get_carrier: 697 rc = fax1_init_FRM( fd, carrier ); 698 if ( rc == ERROR ) 699 { 700 while( ++tries<3 ) goto get_carrier; 701 return ERROR; 702 } 703 704 /* TODO: proper timeout settings as per T.30 (?) */ 705 alarm(5); 706 count = notnull = 0; 707 708 lprintf( L_JUNK, "fax1_r_tcf: got: " ); 709 while(1) 710 { 711 if ( mdm_read_byte( fd, &c ) != 1 ) 712 { 713 /* timeout? corrupted DLE/ETX? let caller send FTT and retry */ 714 lprintf( L_ERROR, "fax1_r_tcf: cannot read byte, return" ); 715 return 0; 716 } 717 if ( c != 0 ) lputc( L_JUNK, c ); 718 719 if ( wasDLE ) 720 { 721 if ( c == ETX ) break; 722 wasDLE = 0; 723 } 724 if ( c == DLE ) { wasDLE = 1; continue; } 725 726 count++; 727 if ( c != 0 ) notnull++; 728 } 729 730 /* read post-frame "NO CARRIER" message */ 731 p = mdm_get_line( fd ); 732 alarm(0); 733 if ( p == NULL || strcmp( p, "NO CARRIER" ) != 0 ) 734 lprintf( L_WARN, "unexpected post-TCF modem response: '%s'", p ); 735 736 if ( count < (wantbytes*3)/4 || /* not enough bytes */ 737 notnull > count/10 ) /* or too many errors */ 738 { 739 lprintf( L_NOISE, "TCF: want %d, got %d, %d non-null -> retry", 740 wantbytes, count, notnull ); 741 return 0; /* try again */ 742 } 743 744 lprintf( L_NOISE, "TCF: want %d, got %d, %d non-null -> OK", 745 wantbytes, count, notnull ); 746 return 1; /* acceptable, go ahead */ 747 } 748 749 int fax1_receive_page _P7( (fd,carrier,pagenum,dirlist,uid,gid,mode), 750 int fd, int carrier, 751 int * pagenum, char * dirlist, 752 int uid, int gid, int mode ) 753 { 754 int rc; 755 char *p; 756 int tries; 757 758 char directory[MAXPATH]; 759 760 fax_find_directory( dirlist, directory, sizeof(directory) ); 761 762 tries=0; 763 764 lprintf( L_NOISE, "fax1_rp: carrier=%d", carrier ); 765 766 get_carrier: 767 /* TODO: proper timeout settings as per T.30 */ 768 alarm(10); 769 rc = fax1_init_FRM( fd, carrier ); 770 alarm(0); 771 772 if ( rc == ERROR ) 773 { 774 if ( ++tries < 3 ) goto get_carrier; 775 fax1_send_dcn( fd, 90 ); 776 return ERROR; 777 } 778 779 /* now get page data (common function for class 1 and class 2) 780 * note: fax_get_page_data() has its own alarm/timeout handling 781 */ 782 rc = fax_get_page_data( fd, ++(*pagenum), directory, uid, gid, mode ); 783 784 /* read post-page "NO CARRIER" message */ 785 alarm(10); 786 p = mdm_get_line( fd ); 787 alarm(0); 788 if ( p == NULL || strcmp( p, "NO CARRIER" ) != 0 ) 789 lprintf( L_WARN, "unexpected post-page modem response: '%s'", p ); 790 791 if ( rc == ERROR ) 792 { fax1_send_dcn( fd, 90 ); return ERROR; } 793 794 /* TODO: copy quality checking */ 795 796 return NOERROR; 797 } 798 799 #endif /* CLASS 1 */ 800