Mercurial > hg > audiostuff
comparison spandsp-0.0.3/spandsp-0.0.3/src/t30.c @ 5:f762bf195c4b
import spandsp-0.0.3
author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
---|---|
date | Fri, 25 Jun 2010 16:00:21 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
4:26cd8f1ef0b1 | 5:f762bf195c4b |
---|---|
1 /* | |
2 * SpanDSP - a series of DSP components for telephony | |
3 * | |
4 * t30.c - ITU T.30 FAX transfer processing | |
5 * | |
6 * Written by Steve Underwood <steveu@coppice.org> | |
7 * | |
8 * Copyright (C) 2003, 2004, 2005, 2006 Steve Underwood | |
9 * | |
10 * All rights reserved. | |
11 * | |
12 * This program is free software; you can redistribute it and/or modify | |
13 * it under the terms of the GNU General Public License version 2, as | |
14 * published by the Free Software Foundation. | |
15 * | |
16 * This program is distributed in the hope that it will be useful, | |
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 * GNU General Public License for more details. | |
20 * | |
21 * You should have received a copy of the GNU General Public License | |
22 * along with this program; if not, write to the Free Software | |
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
24 * | |
25 * $Id: t30.c,v 1.149 2006/11/30 15:41:47 steveu Exp $ | |
26 */ | |
27 | |
28 /*! \file */ | |
29 | |
30 #ifdef HAVE_CONFIG_H | |
31 #include <config.h> | |
32 #endif | |
33 | |
34 #include <stdlib.h> | |
35 #include <stdio.h> | |
36 #include <inttypes.h> | |
37 #include <string.h> | |
38 #include <fcntl.h> | |
39 #include <time.h> | |
40 #if defined(HAVE_TGMATH_H) | |
41 #include <tgmath.h> | |
42 #endif | |
43 #if defined(HAVE_MATH_H) | |
44 #include <math.h> | |
45 #endif | |
46 #include <tiffio.h> | |
47 | |
48 #include "spandsp/telephony.h" | |
49 #include "spandsp/logging.h" | |
50 #include "spandsp/bit_operations.h" | |
51 #include "spandsp/queue.h" | |
52 #include "spandsp/power_meter.h" | |
53 #include "spandsp/complex.h" | |
54 #include "spandsp/tone_generate.h" | |
55 #include "spandsp/async.h" | |
56 #include "spandsp/hdlc.h" | |
57 #include "spandsp/fsk.h" | |
58 #include "spandsp/v29rx.h" | |
59 #include "spandsp/v29tx.h" | |
60 #include "spandsp/v27ter_rx.h" | |
61 #include "spandsp/v27ter_tx.h" | |
62 #include "spandsp/t4.h" | |
63 | |
64 #include "spandsp/t30_fcf.h" | |
65 #include "spandsp/t35.h" | |
66 #include "spandsp/t30.h" | |
67 | |
68 #define MAX_MESSAGE_TRIES 3 | |
69 | |
70 #define ms_to_samples(t) (((t)*SAMPLE_RATE)/1000) | |
71 | |
72 typedef struct | |
73 { | |
74 int val; | |
75 const char *str; | |
76 } value_string_t; | |
77 | |
78 /* T.30 defines the following call phases: | |
79 Phase A: Call set-up. | |
80 Exchange of CNG, CED and the called terminal identification. | |
81 Phase B: Pre-message procedure for identifying and selecting the required facilities. | |
82 Capabilities negotiation, and training, up the the confirmation to receive. | |
83 Phase C: Message transmission (includes phasing and synchronization where appropriate). | |
84 Transfer of the message at high speed. | |
85 Phase D: Post-message procedure, including end-of-message and confirmation and multi-document procedures. | |
86 End of message and acknowledgement. | |
87 Phase E: Call release | |
88 Final call disconnect. */ | |
89 enum | |
90 { | |
91 T30_PHASE_IDLE = 0, /* Freshly initialised */ | |
92 T30_PHASE_A_CED, /* Doing the CED (answer) sequence */ | |
93 T30_PHASE_A_CNG, /* Doing the CNG (caller) sequence */ | |
94 T30_PHASE_B_RX, /* Receiving pre-message control messages */ | |
95 T30_PHASE_B_TX, /* Transmitting pre-message control messages */ | |
96 T30_PHASE_C_NON_ECM_RX, /* Receiving a document message in non-ECM mode */ | |
97 T30_PHASE_C_NON_ECM_TX, /* Transmitting a document message in non-ECM mode */ | |
98 T30_PHASE_C_ECM_RX, /* Receiving a document message in ECM (HDLC) mode */ | |
99 T30_PHASE_C_ECM_TX, /* Transmitting a document message in ECM (HDLC) mode */ | |
100 T30_PHASE_D_RX, /* Receiving post-message control messages */ | |
101 T30_PHASE_D_TX, /* Transmitting post-message control messages */ | |
102 T30_PHASE_E, /* In phase E */ | |
103 T30_PHASE_CALL_FINISHED /* Call completely finished */ | |
104 }; | |
105 | |
106 static const char *phase_names[] = | |
107 { | |
108 "T30_PHASE_IDLE", | |
109 "T30_PHASE_A_CED", | |
110 "T30_PHASE_A_CNG", | |
111 "T30_PHASE_B_RX", | |
112 "T30_PHASE_B_TX", | |
113 "T30_PHASE_C_NON_ECM_RX", | |
114 "T30_PHASE_C_NON_ECM_TX", | |
115 "T30_PHASE_C_ECM_RX", | |
116 "T30_PHASE_C_ECM_TX", | |
117 "T30_PHASE_D_RX", | |
118 "T30_PHASE_D_TX", | |
119 "T30_PHASE_E", | |
120 "T30_PHASE_CALL_FINISHED" | |
121 }; | |
122 | |
123 /* These state names are modelled after places in the T.30 flow charts. */ | |
124 enum | |
125 { | |
126 T30_STATE_ANSWERING = 1, | |
127 T30_STATE_B, | |
128 T30_STATE_C, | |
129 T30_STATE_D, | |
130 T30_STATE_D_TCF, | |
131 T30_STATE_D_POST_TCF, | |
132 T30_STATE_F_TCF, | |
133 T30_STATE_F_CFR, | |
134 T30_STATE_F_FTT, | |
135 T30_STATE_F_DOC, | |
136 T30_STATE_F_POST_DOC_NON_ECM, | |
137 T30_STATE_F_POST_DOC_ECM, | |
138 T30_STATE_F_POST_RCP_MCF, | |
139 T30_STATE_F_POST_RCP_PPR, | |
140 T30_STATE_R, | |
141 T30_STATE_T, | |
142 T30_STATE_I, | |
143 T30_STATE_II, | |
144 T30_STATE_II_Q, | |
145 T30_STATE_III_Q_MCF, | |
146 T30_STATE_III_Q_RTP, | |
147 T30_STATE_III_Q_RTN, | |
148 T30_STATE_IV, | |
149 T30_STATE_IV_PPS_NULL, | |
150 T30_STATE_IV_PPS_Q, | |
151 T30_STATE_IV_PPS_RNR, | |
152 T30_STATE_IV_CTC, | |
153 T30_STATE_IV_EOR, | |
154 T30_STATE_IV_EOR_RNR, | |
155 T30_STATE_CALL_FINISHED | |
156 }; | |
157 | |
158 enum | |
159 { | |
160 T30_MODE_SEND_DOC = 1, | |
161 T30_MODE_RECEIVE_DOC | |
162 }; | |
163 | |
164 enum | |
165 { | |
166 T30_COPY_QUALITY_GOOD = 0, | |
167 T30_COPY_QUALITY_POOR, | |
168 T30_COPY_QUALITY_BAD | |
169 }; | |
170 | |
171 #define DISBIT1 0x01 | |
172 #define DISBIT2 0x02 | |
173 #define DISBIT3 0x04 | |
174 #define DISBIT4 0x08 | |
175 #define DISBIT5 0x10 | |
176 #define DISBIT6 0x20 | |
177 #define DISBIT7 0x40 | |
178 #define DISBIT8 0x80 | |
179 | |
180 /* All timers specified in milliseconds */ | |
181 | |
182 /* Time-out T0 defines the amount of time an automatic calling terminal waits for the called terminal | |
183 to answer the call. | |
184 T0 begins after the dialling of the number is completed and is reset: | |
185 a) when T0 times out; or | |
186 b) when timer T1 is started; or | |
187 c) if the terminal is capable of detecting any condition which indicates that the call will not be | |
188 successful, when such a condition is detected. | |
189 The recommended value of T0 is 60+-5s; however, when it is anticipated that a long call set-up | |
190 time may be encountered, an alternative value of up to 120s may be used. | |
191 NOTE - National regulations may require the use of other values for T0. */ | |
192 #define DEFAULT_TIMER_T0 60000 | |
193 | |
194 /* Time-out T1 defines the amount of time two terminals will continue to attempt to identify each | |
195 other. T1 is 35+-5s, begins upon entering phase B, and is reset upon detecting a valid signal or | |
196 when T1 times out. | |
197 For operating methods 3 and 4 (see 3.1), the calling terminal starts time-out T1 upon reception of | |
198 the V.21 modulation scheme. | |
199 For operating method 4 bis a (see 3.1), the calling terminal starts time-out T1 upon starting | |
200 transmission using the V.21 modulation scheme. */ | |
201 #define DEFAULT_TIMER_T1 35000 | |
202 | |
203 /* Time-out T2 makes use of the tight control between commands and responses to detect the loss of | |
204 command/response synchronization. T2 is 6+-1s and begins when initiating a command search | |
205 (e.g., the first entrance into the "command received" subroutine, reference flow diagram in 5.2). | |
206 T2 is reset when an HDLC flag is received or when T2 times out. */ | |
207 #define DEFAULT_TIMER_T2 7000 | |
208 | |
209 /* Time-out T3 defines the amount of time a terminal will attempt to alert the local operator in | |
210 response to a procedural interrupt. Failing to achieve operator intervention, the terminal will | |
211 discontinue this attempt and shall issue other commands or responses. T3 is 10+-5s, begins on the | |
212 first detection of a procedural interrupt command/response signal (i.e., PIN/PIP or PRI-Q) and is | |
213 reset when T3 times out or when the operator initiates a line request. */ | |
214 #define DEFAULT_TIMER_T3 15000 | |
215 | |
216 /* NOTE - For manual FAX units, the value of timer T4 may be either 3.0s +-15% or 4.5s +-15%. | |
217 If the value of 4.5s is used, then after detection of a valid response to the first DIS, it may | |
218 be reduced to 3.0s +-15%. T4 = 3.0s +-15% for automatic units. */ | |
219 #define DEFAULT_TIMER_T4 3450 | |
220 | |
221 /* Time-out T5 is defined for the optional T.4 error correction mode. Time-out T5 defines the amount | |
222 of time waiting for clearance of the busy condition of the receiving terminal. T5 is 60+-5s and | |
223 begins on the first detection of the RNR response. T5 is reset when T5 times out or the MCF or PIP | |
224 response is received or when the ERR or PIN response is received in the flow control process after | |
225 transmitting the EOR command. If the timer T5 has expired, the DCN command is transmitted for | |
226 call release. */ | |
227 #define DEFAULT_TIMER_T5 65000 | |
228 | |
229 #define DEFAULT_TIMER_T6 5000 | |
230 | |
231 #define DEFAULT_TIMER_T7 6000 | |
232 | |
233 #define DEFAULT_TIMER_T8 10000 | |
234 | |
235 /* Exact widths in PELs for the difference resolutions, and page widths: | |
236 R4 864 pels/215mm for ISO A4, North American Letter and Legal | |
237 R4 1024 pels/255mm for ISO B4 | |
238 R4 1216 pels/303mm for ISO A3 | |
239 R8 1728 pels/215mm for ISO A4, North American Letter and Legal | |
240 R8 2048 pels/255mm for ISO B4 | |
241 R8 2432 pels/303mm for ISO A3 | |
242 R16 3456 pels/215mm for ISO A4, North American Letter and Legal | |
243 R16 4096 pels/255mm for ISO B4 | |
244 R16 4864 pels/303mm for ISO A3 | |
245 */ | |
246 | |
247 #define T30_V17_FALLBACK_START 0 | |
248 #define T30_V29_FALLBACK_START 3 | |
249 #define T30_V27TER_FALLBACK_START 6 | |
250 | |
251 static const struct | |
252 { | |
253 int bit_rate; | |
254 int modem_type; | |
255 uint8_t dcs_code; | |
256 } fallback_sequence[] = | |
257 { | |
258 {14400, T30_MODEM_V17_14400, DISBIT6}, | |
259 {12000, T30_MODEM_V17_12000, (DISBIT6 | DISBIT4)}, | |
260 { 9600, T30_MODEM_V17_9600, (DISBIT6 | DISBIT3)}, | |
261 { 9600, T30_MODEM_V29_9600, DISBIT3}, | |
262 { 7200, T30_MODEM_V17_7200, (DISBIT6 | DISBIT4 | DISBIT3)}, | |
263 { 7200, T30_MODEM_V29_7200, (DISBIT4 | DISBIT3)}, | |
264 { 4800, T30_MODEM_V27TER_4800, DISBIT4}, | |
265 { 2400, T30_MODEM_V27TER_2400, 0}, | |
266 { 0, 0, 0} | |
267 }; | |
268 | |
269 static void queue_phase(t30_state_t *s, int phase); | |
270 static void set_phase(t30_state_t *s, int phase); | |
271 static void set_state(t30_state_t *s, int state); | |
272 static void send_simple_frame(t30_state_t *s, int type); | |
273 static void send_frame(t30_state_t *s, const uint8_t *fr, int frlen); | |
274 static void send_dcn(t30_state_t *s); | |
275 static void repeat_last_command(t30_state_t *s); | |
276 static void disconnect(t30_state_t *s); | |
277 static void decode_20digit_msg(t30_state_t *s, char *msg, const uint8_t *pkt, int len); | |
278 static void decode_url_msg(t30_state_t *s, char *msg, const uint8_t *pkt, int len); | |
279 | |
280 static void rx_start_page(t30_state_t *s) | |
281 { | |
282 int i; | |
283 | |
284 t4_rx_set_image_width(&(s->t4), s->image_width); | |
285 t4_rx_set_sub_address(&(s->t4), s->far_sub_address); | |
286 t4_rx_set_far_ident(&(s->t4), s->far_ident); | |
287 t4_rx_set_vendor(&(s->t4), s->vendor); | |
288 t4_rx_set_model(&(s->t4), s->model); | |
289 | |
290 t4_rx_set_rx_encoding(&(s->t4), s->line_encoding); | |
291 t4_rx_set_y_resolution(&(s->t4), s->y_resolution); | |
292 | |
293 t4_rx_start_page(&(s->t4)); | |
294 /* Clear the buffer */ | |
295 for (i = 0; i < 256; i++) | |
296 s->ecm_len[i] = -1; | |
297 s->ecm_frames = -1; | |
298 s->ecm_page++; | |
299 s->ecm_block = 0; | |
300 } | |
301 /*- End of function --------------------------------------------------------*/ | |
302 | |
303 static int copy_quality(t30_state_t *s) | |
304 { | |
305 t4_stats_t stats; | |
306 | |
307 /* There is no specification for judging copy quality. However, we need to classify | |
308 it at three levels, to control what we do next: OK; tolerable, but retrain; | |
309 intolerable, so retrain. */ | |
310 t4_get_transfer_statistics(&(s->t4), &stats); | |
311 span_log(&s->logging, SPAN_LOG_FLOW, "Pages = %d\n", stats.pages_transferred); | |
312 span_log(&s->logging, SPAN_LOG_FLOW, "Image size = %dx%d\n", stats.width, stats.length); | |
313 span_log(&s->logging, SPAN_LOG_FLOW, "Image resolution = %dx%d\n", stats.x_resolution, stats.y_resolution); | |
314 span_log(&s->logging, SPAN_LOG_FLOW, "Bad rows = %d\n", stats.bad_rows); | |
315 span_log(&s->logging, SPAN_LOG_FLOW, "Longest bad row run = %d\n", stats.longest_bad_row_run); | |
316 if (stats.bad_rows*50 < stats.length) | |
317 return T30_COPY_QUALITY_GOOD; | |
318 if (stats.bad_rows*20 < stats.length) | |
319 return T30_COPY_QUALITY_POOR; | |
320 return T30_COPY_QUALITY_BAD; | |
321 } | |
322 /*- End of function --------------------------------------------------------*/ | |
323 | |
324 const char *t30_completion_code_to_str(int result) | |
325 { | |
326 switch (result) | |
327 { | |
328 case T30_ERR_OK: | |
329 return "OK"; | |
330 case T30_ERR_CEDTONE: | |
331 return "The CED tone exceeded 5s"; | |
332 case T30_ERR_T0EXPIRED: | |
333 return "Timed out waiting for initial communication"; | |
334 case T30_ERR_T1EXPIRED: | |
335 return "Timed out waiting for the first message"; | |
336 case T30_ERR_T3EXPIRED: | |
337 return "Timed out waiting for procedural interrupt"; | |
338 case T30_ERR_HDLCCARR: | |
339 return "The HDLC carrier did not stop in a timely manner"; | |
340 case T30_ERR_CANNOTTRAIN: | |
341 return "Failed to train with any of the compatible modems"; | |
342 case T30_ERR_OPERINTFAIL: | |
343 return "Operator intervention failed"; | |
344 case T30_ERR_INCOMPATIBLE: | |
345 return "Far end is not compatible"; | |
346 case T30_ERR_NOTRXCAPABLE: | |
347 return "Far end is not receive capable"; | |
348 case T30_ERR_NOTTXCAPABLE: | |
349 return "Far end is not transmit capable"; | |
350 case T30_ERR_UNEXPECTED: | |
351 return "Unexpected message received"; | |
352 case T30_ERR_NORESSUPPORT: | |
353 return "Far end cannot receive at the resolution of the image"; | |
354 case T30_ERR_NOSIZESUPPORT: | |
355 return "Far end cannot receive at the size of image"; | |
356 case T30_ERR_FILEERROR: | |
357 return "TIFF/F file cannot be opened"; | |
358 case T30_ERR_NOPAGE: | |
359 return "TIFF/F page not found"; | |
360 case T30_ERR_BADTIFF: | |
361 return "TIFF/F format is not compatible"; | |
362 case T30_ERR_UNSUPPORTED: | |
363 return "Unsupported feature"; | |
364 case T30_ERR_BADDCSTX: | |
365 return "Received bad response to DCS or training"; | |
366 case T30_ERR_BADPGTX: | |
367 return "Received a DCN from remote after sending a page"; | |
368 case T30_ERR_ECMPHDTX: | |
369 return "Invalid ECM response received from receiver"; | |
370 case T30_ERR_ECMRNRTX: | |
371 return "Timer T5 expired, receiver not ready"; | |
372 case T30_ERR_GOTDCNTX: | |
373 return "Received a DCN while waiting for a DIS"; | |
374 case T30_ERR_INVALRSPTX: | |
375 return "Invalid response after sending a page"; | |
376 case T30_ERR_NODISTX: | |
377 return "Received other than DIS while waiting for DIS"; | |
378 case T30_ERR_NXTCMDTX: | |
379 return "Timed out waiting for next send_page command from driver"; | |
380 case T30_ERR_PHBDEADTX: | |
381 return "Received no response to DCS, training or TCF"; | |
382 case T30_ERR_PHDDEADTX: | |
383 return "No response after sending a page"; | |
384 case T30_ERR_ECMPHDRX: | |
385 return "Invalid ECM response received from transmitter"; | |
386 case T30_ERR_GOTDCSRX: | |
387 return "DCS received while waiting for DTC"; | |
388 case T30_ERR_INVALCMDRX: | |
389 return "Unexpected command after page received"; | |
390 case T30_ERR_NOCARRIERRX: | |
391 return "Carrier lost during fax receive"; | |
392 case T30_ERR_NOEOLRX: | |
393 return "Timed out while waiting for EOL (end Of line)"; | |
394 case T30_ERR_NOFAXRX: | |
395 return "Timed out while waiting for first line"; | |
396 case T30_ERR_NXTCMDRX: | |
397 return "Timed out waiting for next receive page command"; | |
398 case T30_ERR_T2EXPDCNRX: | |
399 return "Timer T2 expired while waiting for DCN"; | |
400 case T30_ERR_T2EXPDRX: | |
401 return "Timer T2 expired while waiting for phase D"; | |
402 case T30_ERR_T2EXPFAXRX: | |
403 return "Timer T2 expired while waiting for fax page"; | |
404 case T30_ERR_T2EXPMPSRX: | |
405 return "Timer T2 expired while waiting for next fax page"; | |
406 case T30_ERR_T2EXPRRRX: | |
407 return "Timer T2 expired while waiting for RR command"; | |
408 case T30_ERR_T2EXPRX: | |
409 return "Timer T2 expired while waiting for NSS, DCS or MCF"; | |
410 case T30_ERR_DCNWHYRX: | |
411 return "Unexpected DCN while waiting for DCS or DIS"; | |
412 case T30_ERR_DCNDATARX: | |
413 return "Unexpected DCN while waiting for image data"; | |
414 case T30_ERR_DCNFAXRX: | |
415 return "Unexpected DCN while waiting for EOM, EOP or MPS"; | |
416 case T30_ERR_DCNPHDRX: | |
417 return "Unexpected DCN after EOM or MPS sequence"; | |
418 case T30_ERR_DCNRRDRX: | |
419 return "Unexpected DCN after RR/RNR sequence"; | |
420 case T30_ERR_DCNNORTNRX: | |
421 return "Unexpected DCN after requested retransmission"; | |
422 case T30_ERR_BADPAGE: | |
423 return "TIFF/F page number tag missing"; | |
424 case T30_ERR_BADTAG: | |
425 return "Incorrect values for TIFF/F tags"; | |
426 case T30_ERR_BADTIFFHDR: | |
427 return "Bad TIFF/F header - incorrect values in fields"; | |
428 case T30_ERR_BADPARM: | |
429 return "Invalid value for fax parameter"; | |
430 case T30_ERR_BADSTATE: | |
431 return "Invalid initial state value specified"; | |
432 case T30_ERR_CMDDATA: | |
433 return "Last command contained invalid data"; | |
434 case T30_ERR_DISCONNECT: | |
435 return "Fax call disconnected by the other station"; | |
436 case T30_ERR_INVALARG: | |
437 return "Illegal argument to function"; | |
438 case T30_ERR_INVALFUNC: | |
439 return "Illegal call to function"; | |
440 case T30_ERR_NODATA: | |
441 return "Data requested is not available (NSF, DIS, DCS)"; | |
442 case T30_ERR_NOMEM: | |
443 return "Cannot allocate memory for more pages"; | |
444 case T30_ERR_NOPOLL: | |
445 return "Poll not accepted"; | |
446 case T30_ERR_NOSTATE: | |
447 return "Initial state value not set"; | |
448 case T30_ERR_RETRYDCN: | |
449 return "Disconnected after permitted retries"; | |
450 case T30_ERR_CALLDROPPED: | |
451 return "The call dropped prematurely"; | |
452 } | |
453 return "???"; | |
454 } | |
455 /*- End of function --------------------------------------------------------*/ | |
456 | |
457 void t30_non_ecm_put_bit(void *user_data, int bit) | |
458 { | |
459 t30_state_t *s; | |
460 int was_trained; | |
461 | |
462 s = (t30_state_t *) user_data; | |
463 if (bit < 0) | |
464 { | |
465 /* Special conditions */ | |
466 switch (bit) | |
467 { | |
468 case PUTBIT_TRAINING_FAILED: | |
469 span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier training failed in state %d\n", s->state); | |
470 s->rx_trained = FALSE; | |
471 /* Cancel the timer, since we have actually seen something, and wait until the carrier drops | |
472 before proceeding. */ | |
473 // TODO: this is not a complete answer to handling failures to train | |
474 s->timer_t2_t4 = 0; | |
475 break; | |
476 case PUTBIT_TRAINING_SUCCEEDED: | |
477 /* The modem is now trained */ | |
478 span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier trained in state %d\n", s->state); | |
479 /* In case we are in trainability test mode... */ | |
480 /* A FAX machine is supposed to send 1.5s of training test | |
481 data, but some send a little bit less. Lets just check | |
482 the first 1s, and be safe. */ | |
483 s->training_current_zeros = 0; | |
484 s->training_most_zeros = 0; | |
485 s->rx_signal_present = TRUE; | |
486 s->rx_trained = TRUE; | |
487 s->timer_t2_t4 = 0; | |
488 break; | |
489 case PUTBIT_CARRIER_UP: | |
490 span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier up in state %d\n", s->state); | |
491 break; | |
492 case PUTBIT_CARRIER_DOWN: | |
493 span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier down in state %d\n", s->state); | |
494 was_trained = s->rx_trained; | |
495 s->rx_signal_present = FALSE; | |
496 s->rx_trained = FALSE; | |
497 switch (s->state) | |
498 { | |
499 case T30_STATE_F_TCF: | |
500 /* Only respond if we managed to actually sync up with the source. We don't | |
501 want to respond just because we saw a click. These often occur just | |
502 before the real signal, with many modems. Presumably this is due to switching | |
503 within the far end modem. We also want to avoid the possibility of responding | |
504 to the tail end of any slow modem signal. If there was a genuine data signal | |
505 which we failed to train on it should not matter. If things are that bad, we | |
506 do not stand much chance of good quality communications. */ | |
507 if (was_trained) | |
508 { | |
509 /* Although T.30 says the training test should be 1.5s of all 0's, some FAX | |
510 machines send a burst of all 1's before the all 0's. Tolerate this. */ | |
511 if (s->training_current_zeros > s->training_most_zeros) | |
512 s->training_most_zeros = s->training_current_zeros; | |
513 if (s->training_most_zeros < fallback_sequence[s->current_fallback].bit_rate) | |
514 { | |
515 span_log(&s->logging, SPAN_LOG_FLOW, "Trainability test failed - longest run of zeros was %d\n", s->training_most_zeros); | |
516 set_phase(s, T30_PHASE_B_TX); | |
517 set_state(s, T30_STATE_F_FTT); | |
518 send_simple_frame(s, T30_FTT); | |
519 } | |
520 else | |
521 { | |
522 /* The training went OK */ | |
523 s->short_train = TRUE; | |
524 s->in_message = TRUE; | |
525 rx_start_page(s); | |
526 set_phase(s, T30_PHASE_B_TX); | |
527 set_state(s, T30_STATE_F_CFR); | |
528 send_simple_frame(s, T30_CFR); | |
529 } | |
530 } | |
531 break; | |
532 case T30_STATE_F_POST_DOC_NON_ECM: | |
533 /* Page ended cleanly */ | |
534 if (s->current_status == T30_ERR_NOCARRIERRX) | |
535 s->current_status = T30_ERR_OK; | |
536 break; | |
537 default: | |
538 /* We should be receiving a document right now, but it did not end cleanly. */ | |
539 if (was_trained) | |
540 { | |
541 span_log(&s->logging, SPAN_LOG_WARNING, "Page did not end cleanly\n"); | |
542 /* We trained OK, so we should have some kind of received page, even though | |
543 it did not end cleanly. */ | |
544 set_state(s, T30_STATE_F_POST_DOC_NON_ECM); | |
545 set_phase(s, T30_PHASE_D_RX); | |
546 s->timer_t2_t4 = ms_to_samples(DEFAULT_TIMER_T2); | |
547 s->timer_is_t4 = FALSE; | |
548 if (s->current_status == T30_ERR_NOCARRIERRX) | |
549 s->current_status = T30_ERR_OK; | |
550 } | |
551 else | |
552 { | |
553 span_log(&s->logging, SPAN_LOG_WARNING, "Non-ECM carrier not found\n"); | |
554 s->current_status = T30_ERR_NOCARRIERRX; | |
555 } | |
556 break; | |
557 } | |
558 if (s->next_phase != T30_PHASE_IDLE) | |
559 { | |
560 set_phase(s, s->next_phase); | |
561 s->next_phase = T30_PHASE_IDLE; | |
562 } | |
563 break; | |
564 default: | |
565 span_log(&s->logging, SPAN_LOG_WARNING, "Unexpected non-ECM special bit - %d!\n", bit); | |
566 break; | |
567 } | |
568 return; | |
569 } | |
570 switch (s->state) | |
571 { | |
572 case T30_STATE_F_TCF: | |
573 /* Trainability test */ | |
574 if (bit) | |
575 { | |
576 if (s->training_current_zeros > s->training_most_zeros) | |
577 s->training_most_zeros = s->training_current_zeros; | |
578 s->training_current_zeros = 0; | |
579 } | |
580 else | |
581 { | |
582 s->training_current_zeros++; | |
583 } | |
584 break; | |
585 case T30_STATE_F_DOC: | |
586 /* Document transfer */ | |
587 if (t4_rx_put_bit(&(s->t4), bit)) | |
588 { | |
589 /* That is the end of the document */ | |
590 set_state(s, T30_STATE_F_POST_DOC_NON_ECM); | |
591 queue_phase(s, T30_PHASE_D_RX); | |
592 s->timer_t2_t4 = ms_to_samples(DEFAULT_TIMER_T2); | |
593 s->timer_is_t4 = FALSE; | |
594 } | |
595 break; | |
596 } | |
597 } | |
598 /*- End of function --------------------------------------------------------*/ | |
599 | |
600 void t30_non_ecm_putbyte(void *user_data, int byte) | |
601 { | |
602 t30_state_t *s; | |
603 int i; | |
604 | |
605 s = (t30_state_t *) user_data; | |
606 switch (s->state) | |
607 { | |
608 case T30_STATE_F_TCF: | |
609 /* Trainability test */ | |
610 if (byte == 0) | |
611 { | |
612 s->training_current_zeros += 8; | |
613 } | |
614 else | |
615 { | |
616 for (i = 7; i >= 0; i--) | |
617 { | |
618 if (((byte >> i) & 1)) | |
619 { | |
620 if (s->training_current_zeros > s->training_most_zeros) | |
621 s->training_most_zeros = s->training_current_zeros; | |
622 s->training_current_zeros = 0; | |
623 } | |
624 else | |
625 { | |
626 s->training_current_zeros++; | |
627 } | |
628 } | |
629 } | |
630 break; | |
631 case T30_STATE_F_DOC: | |
632 /* Document transfer */ | |
633 for (i = 7; i >= 0; i--) | |
634 { | |
635 if (t4_rx_put_bit(&(s->t4), (byte >> i) & 1)) | |
636 { | |
637 /* That is the end of the document */ | |
638 set_state(s, T30_STATE_F_POST_DOC_NON_ECM); | |
639 queue_phase(s, T30_PHASE_D_RX); | |
640 s->timer_t2_t4 = ms_to_samples(DEFAULT_TIMER_T2); | |
641 s->timer_is_t4 = FALSE; | |
642 } | |
643 } | |
644 break; | |
645 } | |
646 } | |
647 /*- End of function --------------------------------------------------------*/ | |
648 | |
649 int t30_non_ecm_get_bit(void *user_data) | |
650 { | |
651 int bit; | |
652 t30_state_t *s; | |
653 | |
654 s = (t30_state_t *) user_data; | |
655 switch (s->state) | |
656 { | |
657 case T30_STATE_D_TCF: | |
658 /* Trainability test. */ | |
659 bit = 0; | |
660 if (s->training_test_bits-- < 0) | |
661 { | |
662 /* Finished sending training test. */ | |
663 bit = PUTBIT_END_OF_DATA; | |
664 } | |
665 break; | |
666 case T30_STATE_I: | |
667 /* Transferring real data. */ | |
668 bit = t4_tx_get_bit(&(s->t4)); | |
669 break; | |
670 case T30_STATE_D_POST_TCF: | |
671 case T30_STATE_II_Q: | |
672 /* We should be padding out a block of samples if we are here */ | |
673 bit = 0; | |
674 break; | |
675 default: | |
676 span_log(&s->logging, SPAN_LOG_WARNING, "t30_non_ecm_get_bit in bad state %d\n", s->state); | |
677 bit = 2; | |
678 break; | |
679 } | |
680 return bit; | |
681 } | |
682 /*- End of function --------------------------------------------------------*/ | |
683 | |
684 static int check_next_tx_step(t30_state_t *s) | |
685 { | |
686 int more; | |
687 | |
688 if (t4_tx_more_pages(&(s->t4)) == 0) | |
689 return (s->local_interrupt_pending) ? T30_PRI_MPS : T30_MPS; | |
690 /* Call a user handler, if one is set, to check if another document is to be sent. | |
691 If so, we send an EOM, rather than an EOP. Then we will renegotiate, and the new | |
692 document will begin. */ | |
693 if (s->document_handler) | |
694 more = s->document_handler(s, s->document_user_data, 0); | |
695 else | |
696 more = FALSE; | |
697 if (more) | |
698 return (s->local_interrupt_pending) ? T30_PRI_EOM : T30_EOM; | |
699 return (s->local_interrupt_pending) ? T30_PRI_EOP : T30_EOP; | |
700 } | |
701 /*- End of function --------------------------------------------------------*/ | |
702 | |
703 static int get_partial_ecm_page(t30_state_t *s) | |
704 { | |
705 int i; | |
706 int j; | |
707 int k; | |
708 int bit; | |
709 uint8_t octet; | |
710 | |
711 s->ppr_count = 0; | |
712 /* Fill our partial page buffer with a partial page. Use the negotiated preferred frame size | |
713 as the basis for the size of the frames produced. */ | |
714 /* We fill the buffer with complete HDLC frames, ready to send out. */ | |
715 /* The frames are all marked as not being final frames. When sent, the are followed by a partial | |
716 page signal, which is marked as the final frame. */ | |
717 for (i = 0; i < 256; i++) | |
718 s->ecm_len[i] = -1; | |
719 for (i = 3; i < 32 + 3; i++) | |
720 s->ecm_frame_map[i] = 0xFF; | |
721 for (i = 0; i < 256; i++) | |
722 { | |
723 s->ecm_data[i][0] = 0xFF; | |
724 s->ecm_data[i][1] = 0x03; | |
725 s->ecm_data[i][2] = T4_FCD; | |
726 /* These frames contain a frame sequence number within the partial page (one octet) followed | |
727 by some image data. */ | |
728 s->ecm_data[i][3] = i; | |
729 for (j = 4; j < s->octets_per_ecm_frame + 4; j++) | |
730 { | |
731 octet = 0; | |
732 for (k = 0; k < 8; k++) | |
733 { | |
734 if (((bit = t4_tx_get_bit(&(s->t4)))) == PUTBIT_END_OF_DATA) | |
735 { | |
736 if (k > 0) | |
737 s->ecm_data[i][j++] = (uint8_t) (octet >> (7 - k)); | |
738 if (j > 0) | |
739 { | |
740 memset(&s->ecm_data[i][j], 0, s->octets_per_ecm_frame + 4 - j); | |
741 s->ecm_len[i++] = (int16_t) (s->octets_per_ecm_frame + 4); | |
742 } | |
743 /* The image is not big enough to fill the entire buffer */ | |
744 /* We need to pad to a full frame, as most receivers expect | |
745 that. */ | |
746 s->ecm_frames = i; | |
747 span_log(&s->logging, SPAN_LOG_FLOW, "Partial page buffer contains %d frames (%d per frame)\n", i, s->octets_per_ecm_frame); | |
748 s->ecm_at_page_end = TRUE; | |
749 return i; | |
750 } | |
751 octet = (uint8_t) ((octet >> 1) | ((bit & 1) << 7)); | |
752 } | |
753 s->ecm_data[i][j] = octet; | |
754 } | |
755 s->ecm_len[i] = (int16_t) j; | |
756 } | |
757 /* We filled the entire buffer */ | |
758 s->ecm_frames = 256; | |
759 span_log(&s->logging, SPAN_LOG_FLOW, "Partial page buffer full (%d per frame)\n", s->octets_per_ecm_frame); | |
760 s->ecm_at_page_end = ((t4_tx_check_bit(&(s->t4)) & 2) != 0); | |
761 return 256; | |
762 } | |
763 /*- End of function --------------------------------------------------------*/ | |
764 | |
765 static int t30_ecm_commit_partial_page(t30_state_t *s) | |
766 { | |
767 int i; | |
768 int j; | |
769 int k; | |
770 int bit; | |
771 | |
772 span_log(&s->logging, SPAN_LOG_FLOW, "Commiting partial page - %d frames\n", s->ecm_frames); | |
773 for (i = 0; i < s->ecm_frames; i++) | |
774 { | |
775 for (j = 0; j < s->ecm_len[i]; j++) | |
776 { | |
777 for (k = 0; k < 8; k++) | |
778 { | |
779 bit = (s->ecm_data[i][j] >> k) & 1; | |
780 if (t4_rx_put_bit(&(s->t4), bit)) | |
781 { | |
782 /* That is the end of the document */ | |
783 /* Clear the buffer */ | |
784 for (i = 0; i < 256; i++) | |
785 s->ecm_len[i] = -1; | |
786 s->ecm_frames = -1; | |
787 return -1; | |
788 } | |
789 } | |
790 } | |
791 } | |
792 /* Clear the buffer */ | |
793 for (i = 0; i < 256; i++) | |
794 s->ecm_len[i] = -1; | |
795 s->ecm_frames = -1; | |
796 return 0; | |
797 } | |
798 /*- End of function --------------------------------------------------------*/ | |
799 | |
800 static int send_next_ecm_frame(t30_state_t *s) | |
801 { | |
802 int i; | |
803 uint8_t frame[3]; | |
804 | |
805 if (s->ecm_current_frame < s->ecm_frames) | |
806 { | |
807 /* Search for the next frame, within the current partial page, which has | |
808 not been tagged as transferred OK. */ | |
809 for (i = s->ecm_current_frame; i < s->ecm_frames; i++) | |
810 { | |
811 if (s->ecm_len[i] >= 0) | |
812 { | |
813 send_frame(s, s->ecm_data[i], s->ecm_len[i]); | |
814 s->ecm_current_frame = i + 1; | |
815 return 0; | |
816 } | |
817 } | |
818 } | |
819 if (s->ecm_current_frame <= s->ecm_frames + 3) | |
820 { | |
821 /* We have sent all the FCD frames. Send some RCP frames. Three seems to be | |
822 a popular number, to minimise the risk of a bit error stopping the receiving | |
823 end from recognising the RCP. */ | |
824 s->ecm_current_frame++; | |
825 /* The RCP frame is an odd man out, as its a simple 1 byte control | |
826 frame, but is specified to not have the final bit set. */ | |
827 frame[0] = 0xFF; | |
828 frame[1] = 0x03; | |
829 frame[2] = (uint8_t) (T4_RCP | s->dis_received); | |
830 send_frame(s, frame, 3); | |
831 return 0; | |
832 } | |
833 return -1; | |
834 } | |
835 /*- End of function --------------------------------------------------------*/ | |
836 | |
837 static void print_frame(t30_state_t *s, const char *io, const uint8_t *fr, int frlen) | |
838 { | |
839 span_log(&s->logging, | |
840 SPAN_LOG_FLOW, | |
841 "%s %s with%s final frame tag\n", | |
842 io, | |
843 t30_frametype(fr[2]), | |
844 (fr[1] & 0x10) ? "" : "out"); | |
845 span_log_buf(&s->logging, SPAN_LOG_FLOW, io, fr, frlen); | |
846 } | |
847 /*- End of function --------------------------------------------------------*/ | |
848 | |
849 static void send_frame(t30_state_t *s, const uint8_t *fr, int frlen) | |
850 { | |
851 print_frame(s, "Tx: ", fr, frlen); | |
852 | |
853 if (s->send_hdlc_handler) | |
854 s->send_hdlc_handler(s->send_hdlc_user_data, fr, frlen); | |
855 } | |
856 /*- End of function --------------------------------------------------------*/ | |
857 | |
858 static void send_simple_frame(t30_state_t *s, int type) | |
859 { | |
860 uint8_t frame[3]; | |
861 | |
862 /* The simple command/response frames are always final frames */ | |
863 frame[0] = 0xFF; | |
864 frame[1] = 0x13; | |
865 frame[2] = (uint8_t) (type | s->dis_received); | |
866 send_frame(s, frame, 3); | |
867 } | |
868 /*- End of function --------------------------------------------------------*/ | |
869 | |
870 static void send_20digit_msg_frame(t30_state_t *s, int cmd, char *msg) | |
871 { | |
872 size_t len; | |
873 int p; | |
874 uint8_t frame[23]; | |
875 | |
876 len = strlen(msg); | |
877 p = 0; | |
878 frame[p++] = 0xFF; | |
879 frame[p++] = 0x03; | |
880 frame[p++] = (uint8_t) (cmd | s->dis_received); | |
881 while (len > 0) | |
882 frame[p++] = msg[--len]; | |
883 while (p < 23) | |
884 frame[p++] = ' '; | |
885 send_frame(s, frame, 23); | |
886 } | |
887 /*- End of function --------------------------------------------------------*/ | |
888 | |
889 static int send_ident_frame(t30_state_t *s, uint8_t cmd) | |
890 { | |
891 /* Only send if there is an ident to send. */ | |
892 if (s->local_ident[0]) | |
893 { | |
894 span_log(&s->logging, SPAN_LOG_FLOW, "Sending ident '%s'\n", s->local_ident); | |
895 /* 'cmd' should be T30_TSI, T30_CIG or T30_CSI */ | |
896 send_20digit_msg_frame(s, cmd, s->local_ident); | |
897 return TRUE; | |
898 } | |
899 return FALSE; | |
900 } | |
901 /*- End of function --------------------------------------------------------*/ | |
902 | |
903 static int send_pw_frame(t30_state_t *s) | |
904 { | |
905 /* Only send if there is a password to send. */ | |
906 if (s->local_password[0]) | |
907 { | |
908 span_log(&s->logging, SPAN_LOG_FLOW, "Sending password '%s'\n", s->local_password); | |
909 send_20digit_msg_frame(s, T30_PWD, s->local_password); | |
910 return TRUE; | |
911 } | |
912 return FALSE; | |
913 } | |
914 /*- End of function --------------------------------------------------------*/ | |
915 | |
916 static int send_sub_frame(t30_state_t *s) | |
917 { | |
918 /* Only send if there is a sub-address to send. */ | |
919 if (s->local_sub_address[0]) | |
920 { | |
921 span_log(&s->logging, SPAN_LOG_FLOW, "Sending sub address '%s'\n", s->local_sub_address); | |
922 send_20digit_msg_frame(s, T30_SUB, s->local_sub_address); | |
923 return TRUE; | |
924 } | |
925 return FALSE; | |
926 } | |
927 /*- End of function --------------------------------------------------------*/ | |
928 | |
929 static int send_nsf_frame(t30_state_t *s) | |
930 { | |
931 int p; | |
932 uint8_t frame[100 + 3]; | |
933 | |
934 /* Only send if there is an NSF message to send. */ | |
935 if (s->local_nsf_len) | |
936 { | |
937 span_log(&s->logging, SPAN_LOG_FLOW, "Sending user supplied NSF - %d octets\n", s->local_nsf_len); | |
938 p = 0; | |
939 frame[p++] = 0xFF; | |
940 frame[p++] = 0x03; | |
941 frame[p++] = (uint8_t) (T30_NSF | s->dis_received); | |
942 for ( ; p < s->local_nsf_len + 3; p++) | |
943 frame[p] = s->local_nsf[p - 3]; | |
944 send_frame(s, frame, s->local_nsf_len + 3); | |
945 return TRUE; | |
946 } | |
947 return FALSE; | |
948 } | |
949 /*- End of function --------------------------------------------------------*/ | |
950 | |
951 static int send_pps_frame(t30_state_t *s) | |
952 { | |
953 uint8_t frame[100 + 3]; | |
954 | |
955 frame[0] = 0xFF; | |
956 frame[1] = 0x13; | |
957 frame[2] = T30_PPS; | |
958 frame[3] = (s->ecm_at_page_end) ? ((uint8_t) (s->next_tx_step | s->dis_received)) : T30_NULL; | |
959 frame[4] = (uint8_t) (s->ecm_page & 0xFF); | |
960 frame[5] = (uint8_t) (s->ecm_block & 0xFF); | |
961 frame[6] = (uint8_t) (s->ecm_frames - 1); | |
962 span_log(&s->logging, SPAN_LOG_FLOW, "Sending PPS + %s\n", t30_frametype(frame[3])); | |
963 send_frame(s, frame, 7); | |
964 return frame[3] & 0xFE; | |
965 } | |
966 /*- End of function --------------------------------------------------------*/ | |
967 | |
968 static int set_dis_or_dtc(t30_state_t *s) | |
969 { | |
970 /* Whether we use a DIS or a DTC is determined by whether we have received a DIS. | |
971 We just need to edit the prebuilt message. */ | |
972 s->dis_dtc_frame[2] = (uint8_t) (T30_DIS | s->dis_received); | |
973 /* If we have a file name to receive into, then we are receive capable */ | |
974 if (s->rx_file[0]) | |
975 s->dis_dtc_frame[4] |= DISBIT2; | |
976 else | |
977 s->dis_dtc_frame[4] &= ~DISBIT2; | |
978 /* If we have a file name to transmit, then we are ready to transmit (polling) */ | |
979 if (s->tx_file[0]) | |
980 s->dis_dtc_frame[4] |= DISBIT1; | |
981 else | |
982 s->dis_dtc_frame[4] &= ~DISBIT1; | |
983 t30_decode_dis_dtc_dcs(s, s->dis_dtc_frame, s->dis_dtc_len); | |
984 return 0; | |
985 } | |
986 /*- End of function --------------------------------------------------------*/ | |
987 | |
988 static int build_dis_or_dtc(t30_state_t *s) | |
989 { | |
990 int i; | |
991 | |
992 /* Build a skeleton for the DIS and DTC messages. This will be edited for | |
993 the dynamically changing capabilities (e.g. can receive) just before | |
994 it is sent. It might also be edited if the application changes our | |
995 capabilities (e.g. disabling fine mode). Right now we set up all the | |
996 unchanging stuff about what we are capable of doing. */ | |
997 s->dis_dtc_frame[0] = 0xFF; | |
998 s->dis_dtc_frame[1] = 0x13; | |
999 s->dis_dtc_frame[2] = (uint8_t) (T30_DIS | s->dis_received); | |
1000 s->dis_dtc_frame[3] = 0x00; | |
1001 s->dis_dtc_frame[4] = 0x00; | |
1002 for (i = 5; i < 18; i++) | |
1003 s->dis_dtc_frame[i] = DISBIT8; | |
1004 s->dis_dtc_frame[18] = 0x00; | |
1005 | |
1006 /* Always say 256 octets per ECM frame preferred, as 64 is never used in the | |
1007 real world. */ | |
1008 if ((s->iaf & T30_IAF_MODE_T37)) | |
1009 s->dis_dtc_frame[3] |= DISBIT1; | |
1010 if ((s->iaf & T30_IAF_MODE_T38)) | |
1011 s->dis_dtc_frame[3] |= DISBIT3; | |
1012 /* No 3G mobile */ | |
1013 /* No V.8 */ | |
1014 /* 256 octets preferred - don't bother making this optional, as everything uses 256 */ | |
1015 /* Ready to transmit a fax (polling) will be determined separately, and this message edited. */ | |
1016 /* Ready to receive a fax will be determined separately, and this message edited. */ | |
1017 /* With no modems set we are actually selecting V.27ter fallback at 2400bps */ | |
1018 if ((s->supported_modems & T30_SUPPORT_V27TER)) | |
1019 s->dis_dtc_frame[4] |= DISBIT4; | |
1020 if ((s->supported_modems & T30_SUPPORT_V29)) | |
1021 s->dis_dtc_frame[4] |= DISBIT3; | |
1022 /* V.17 is only valid when combined with V.29 and V.27ter, so if we enable V.17 we force the others too. */ | |
1023 if ((s->supported_modems & T30_SUPPORT_V17)) | |
1024 s->dis_dtc_frame[4] |= (DISBIT6 | DISBIT4 | DISBIT3); | |
1025 if ((s->supported_resolutions & T30_SUPPORT_FINE_RESOLUTION)) | |
1026 s->dis_dtc_frame[4] |= DISBIT7; | |
1027 if ((s->supported_compressions & T30_SUPPORT_T4_2D_COMPRESSION)) | |
1028 s->dis_dtc_frame[4] |= DISBIT8; | |
1029 /* 215mm wide is always supported */ | |
1030 if ((s->supported_image_sizes & T30_SUPPORT_303MM_WIDTH)) | |
1031 s->dis_dtc_frame[5] |= DISBIT2; | |
1032 else if ((s->supported_image_sizes & T30_SUPPORT_255MM_WIDTH)) | |
1033 s->dis_dtc_frame[5] |= DISBIT1; | |
1034 /* A4 is always supported. */ | |
1035 if ((s->supported_image_sizes & T30_SUPPORT_UNLIMITED_LENGTH)) | |
1036 s->dis_dtc_frame[5] |= DISBIT4; | |
1037 else if ((s->supported_image_sizes & T30_SUPPORT_B4_LENGTH)) | |
1038 s->dis_dtc_frame[5] |= DISBIT3; | |
1039 /* No scan-line padding required. */ | |
1040 s->dis_dtc_frame[5] |= (DISBIT7 | DISBIT6 | DISBIT5); | |
1041 if ((s->supported_compressions & T30_SUPPORT_NO_COMPRESSION)) | |
1042 s->dis_dtc_frame[6] |= DISBIT2; | |
1043 if (s->ecm_allowed) | |
1044 s->dis_dtc_frame[6] |= DISBIT3; | |
1045 if ((s->supported_compressions & T30_SUPPORT_T6_COMPRESSION)) | |
1046 s->dis_dtc_frame[6] |= DISBIT7; | |
1047 #if defined(SUPPORT_FNV) | |
1048 s->dis_dtc_frame[7] |= DISBIT1; | |
1049 #endif | |
1050 if ((s->supported_polling_features & T30_SUPPORT_SEP)) | |
1051 s->dis_dtc_frame[7] |= DISBIT3; | |
1052 if ((s->supported_polling_features & T30_SUPPORT_PSA)) | |
1053 s->dis_dtc_frame[7] |= DISBIT4; | |
1054 if ((s->supported_compressions & T30_SUPPORT_T43_COMPRESSION)) | |
1055 s->dis_dtc_frame[7] |= DISBIT4; | |
1056 /* No plane interleave */ | |
1057 /* No G.726 */ | |
1058 /* No extended voice coding */ | |
1059 if ((s->supported_resolutions & T30_SUPPORT_SUPERFINE_RESOLUTION)) | |
1060 s->dis_dtc_frame[8] |= DISBIT1; | |
1061 if ((s->supported_resolutions & T30_SUPPORT_300_300_RESOLUTION)) | |
1062 s->dis_dtc_frame[8] |= DISBIT2; | |
1063 if ((s->supported_resolutions & (T30_SUPPORT_400_400_RESOLUTION | T30_SUPPORT_R16_RESOLUTION))) | |
1064 s->dis_dtc_frame[8] |= DISBIT3; | |
1065 /* Metric */ | |
1066 s->dis_dtc_frame[8] |= DISBIT4; | |
1067 /* No sub-addressing */ | |
1068 /* No password */ | |
1069 /* No data file (polling) */ | |
1070 /* No BFT */ | |
1071 /* No DTM */ | |
1072 /* No EDI */ | |
1073 /* No BTM */ | |
1074 /* No mixed mode (polling) */ | |
1075 /* No character mode */ | |
1076 /* No mixed mode */ | |
1077 /* No mode 26 */ | |
1078 /* No digital network capable */ | |
1079 /* No JPEG */ | |
1080 /* No full colour */ | |
1081 /* No 12bits/pel */ | |
1082 /* No sub-sampling */ | |
1083 if ((s->supported_image_sizes & T30_SUPPORT_US_LETTER_LENGTH)) | |
1084 s->dis_dtc_frame[12] |= DISBIT4; | |
1085 if ((s->supported_image_sizes & T30_SUPPORT_US_LEGAL_LENGTH)) | |
1086 s->dis_dtc_frame[12] |= DISBIT5; | |
1087 if ((s->supported_compressions & T30_SUPPORT_T85_COMPRESSION)) | |
1088 s->dis_dtc_frame[12] |= DISBIT6; | |
1089 /* No T.85 optional. */ | |
1090 if ((s->supported_resolutions & T30_SUPPORT_600_600_RESOLUTION)) | |
1091 s->dis_dtc_frame[15] |= DISBIT1; | |
1092 if ((s->supported_resolutions & T30_SUPPORT_1200_1200_RESOLUTION)) | |
1093 s->dis_dtc_frame[15] |= DISBIT2; | |
1094 if ((s->supported_resolutions & T30_SUPPORT_300_600_RESOLUTION)) | |
1095 s->dis_dtc_frame[15] |= DISBIT3; | |
1096 if ((s->supported_resolutions & T30_SUPPORT_400_800_RESOLUTION)) | |
1097 s->dis_dtc_frame[15] |= DISBIT4; | |
1098 if ((s->supported_resolutions & T30_SUPPORT_600_1200_RESOLUTION)) | |
1099 s->dis_dtc_frame[15] |= DISBIT5; | |
1100 if ((s->supported_compressions & T30_SUPPORT_T45_COMPRESSION)) | |
1101 s->dis_dtc_frame[16] |= DISBIT4; | |
1102 if ((s->iaf & T30_IAF_MODE_FLOW_CONTROL)) | |
1103 s->dis_dtc_frame[18] |= DISBIT1; | |
1104 if ((s->iaf & T30_IAF_MODE_CONTINUOUS_FLOW)) | |
1105 s->dis_dtc_frame[18] |= DISBIT3; | |
1106 s->dis_dtc_len = 19; | |
1107 t30_decode_dis_dtc_dcs(s, s->dis_dtc_frame, s->dis_dtc_len); | |
1108 return 0; | |
1109 } | |
1110 /*- End of function --------------------------------------------------------*/ | |
1111 | |
1112 static int build_dcs(t30_state_t *s, const uint8_t *msg, int len) | |
1113 { | |
1114 /* Translation between the codes for the minimum scan times the other end needs, | |
1115 and the codes for what we say will be used. We need 0 minimum. */ | |
1116 static const uint8_t translate_min_scan_time[3][8] = | |
1117 { | |
1118 /* 20 5 10 20 40 40 10 0ms */ | |
1119 {0, 1, 2, 0, 4, 4, 2, 7}, /* normal */ | |
1120 {0, 1, 2, 2, 4, 0, 1, 7}, /* fine */ | |
1121 {2, 1, 1, 1, 0, 2, 1, 7} /* superfine, when half fine time is selected */ | |
1122 }; | |
1123 /* Translation between the codes for the minimum scan time we will use, and milliseconds. */ | |
1124 static const int min_scan_times[8] = | |
1125 { | |
1126 20, 5, 10, 0, 40, 0, 0, 0 | |
1127 }; | |
1128 uint8_t dis_dtc_frame[T30_MAX_DIS_DTC_DCS_LEN]; | |
1129 uint8_t min_bits_field; | |
1130 int i; | |
1131 | |
1132 if (len < 6) | |
1133 { | |
1134 span_log(&s->logging, SPAN_LOG_FLOW, "Short DIS/DTC frame\n"); | |
1135 return -1; | |
1136 } | |
1137 | |
1138 /* Make a local copy of the message, padded to the maximum possible length with zeros. This allows | |
1139 us to simply pick out the bits, without worrying about whether they were set from the remote side. */ | |
1140 if (len > T30_MAX_DIS_DTC_DCS_LEN) | |
1141 { | |
1142 memcpy(dis_dtc_frame, msg, T30_MAX_DIS_DTC_DCS_LEN); | |
1143 } | |
1144 else | |
1145 { | |
1146 memcpy(dis_dtc_frame, msg, len); | |
1147 if (len < T30_MAX_DIS_DTC_DCS_LEN) | |
1148 memset(dis_dtc_frame + len, 0, T30_MAX_DIS_DTC_DCS_LEN - len); | |
1149 } | |
1150 | |
1151 /* Make a DCS frame based on local issues and a received DIS frame. Negotiate the result | |
1152 based on what both parties can do. */ | |
1153 s->dcs_frame[0] = 0xFF; | |
1154 s->dcs_frame[1] = 0x13; | |
1155 s->dcs_frame[2] = (uint8_t) (T30_DCS | s->dis_received); | |
1156 s->dcs_frame[3] = 0x00; | |
1157 s->dcs_frame[4] = 0x00; | |
1158 for (i = 5; i < 18; i++) | |
1159 s->dcs_frame[i] = DISBIT8; | |
1160 s->dcs_frame[18] = 0x00; | |
1161 /* Set to required modem rate; standard resolution */ | |
1162 s->dcs_frame[4] |= fallback_sequence[s->current_fallback].dcs_code; | |
1163 | |
1164 if ((s->iaf & T30_IAF_MODE_NO_FILL_BITS)) | |
1165 min_bits_field = 7; | |
1166 else | |
1167 min_bits_field = (dis_dtc_frame[5] >> 4) & 7; | |
1168 /* Select the compression to use. */ | |
1169 switch(s->line_encoding) | |
1170 { | |
1171 case T4_COMPRESSION_ITU_T6: | |
1172 s->dcs_frame[6] |= DISBIT7; | |
1173 break; | |
1174 case T4_COMPRESSION_ITU_T4_2D: | |
1175 s->dcs_frame[4] |= DISBIT8; | |
1176 break; | |
1177 default: | |
1178 break; | |
1179 } | |
1180 /* If we have a file to send, tell the far end to go into receive mode. */ | |
1181 if (s->tx_file[0]) | |
1182 s->dcs_frame[4] |= DISBIT2; | |
1183 /* Set the minimum scan time bits */ | |
1184 switch (s->y_resolution) | |
1185 { | |
1186 case T4_Y_RESOLUTION_SUPERFINE: | |
1187 if ((dis_dtc_frame[8] & DISBIT1)) | |
1188 { | |
1189 s->dcs_frame[8] |= DISBIT1; | |
1190 if ((dis_dtc_frame[8] & DISBIT6)) | |
1191 min_bits_field = translate_min_scan_time[2][min_bits_field]; | |
1192 else | |
1193 min_bits_field = translate_min_scan_time[1][min_bits_field]; | |
1194 break; | |
1195 } | |
1196 /* Fall back */ | |
1197 s->y_resolution = T4_Y_RESOLUTION_FINE; | |
1198 span_log(&s->logging, SPAN_LOG_FLOW, "Remote FAX does not support super-fine resolution.\n"); | |
1199 /* Fall through */ | |
1200 case T4_Y_RESOLUTION_FINE: | |
1201 if ((dis_dtc_frame[4] & DISBIT7)) | |
1202 { | |
1203 s->dcs_frame[4] |= DISBIT7; | |
1204 min_bits_field = translate_min_scan_time[1][min_bits_field]; | |
1205 break; | |
1206 } | |
1207 /* Fall back */ | |
1208 s->y_resolution = T4_Y_RESOLUTION_STANDARD; | |
1209 span_log(&s->logging, SPAN_LOG_FLOW, "Remote FAX does not support fine resolution.\n"); | |
1210 /* Fall through */ | |
1211 default: | |
1212 case T4_Y_RESOLUTION_STANDARD: | |
1213 min_bits_field = translate_min_scan_time[0][min_bits_field]; | |
1214 break; | |
1215 } | |
1216 if (min_scan_times[min_bits_field] == 0) | |
1217 s->min_row_bits = 0; | |
1218 else | |
1219 s->min_row_bits = fallback_sequence[s->current_fallback].bit_rate*min_scan_times[min_bits_field]/1000; | |
1220 s->dcs_frame[5] |= min_bits_field << 4; | |
1221 span_log(&s->logging, SPAN_LOG_FLOW, "Minimum bits per row will be %d\n", s->min_row_bits); | |
1222 switch (s->image_width) | |
1223 { | |
1224 /* Low (R4) res widths are not supported in recent versions of T.30 */ | |
1225 /* Medium (R8) res widths */ | |
1226 case 1728: | |
1227 break; | |
1228 case 2048: | |
1229 if ((s->dis_dtc_frame[5] & (DISBIT2 | DISBIT1)) < 1) | |
1230 { | |
1231 span_log(&s->logging, SPAN_LOG_FLOW, "Image width (%d pixels) not acceptable to far end\n", s->image_width); | |
1232 return -1; | |
1233 } | |
1234 s->dcs_frame[5] |= DISBIT1; | |
1235 break; | |
1236 case 2432: | |
1237 if ((s->dis_dtc_frame[5] & (DISBIT2 | DISBIT1)) < 2) | |
1238 { | |
1239 span_log(&s->logging, SPAN_LOG_FLOW, "Image width (%d pixels) not acceptable to far end\n", s->image_width); | |
1240 return -1; | |
1241 } | |
1242 s->dcs_frame[5] |= DISBIT2; | |
1243 break; | |
1244 /* High (R16) res widths */ | |
1245 case 3456: | |
1246 if ((dis_dtc_frame[8] & DISBIT3) == 0) | |
1247 { | |
1248 span_log(&s->logging, SPAN_LOG_FLOW, "Image width (%d pixels) not acceptable to far end\n", s->image_width); | |
1249 return -1; | |
1250 } | |
1251 s->dcs_frame[8] |= DISBIT3; | |
1252 break; | |
1253 case 4096: | |
1254 if ((dis_dtc_frame[8] & DISBIT3) == 0 || (s->dis_dtc_frame[5] & (DISBIT2 | DISBIT1)) == 0) | |
1255 { | |
1256 span_log(&s->logging, SPAN_LOG_FLOW, "Image width (%d pixels) not acceptable to far end\n", s->image_width); | |
1257 return -1; | |
1258 } | |
1259 s->dcs_frame[5] |= DISBIT1; | |
1260 s->dcs_frame[8] |= DISBIT3; | |
1261 break; | |
1262 case 4864: | |
1263 if ((dis_dtc_frame[8] & DISBIT3) == 0 || (s->dis_dtc_frame[5] & (DISBIT2 | DISBIT1)) != DISBIT2) | |
1264 { | |
1265 span_log(&s->logging, SPAN_LOG_FLOW, "Image width (%d pixels) not acceptable to far end\n", s->image_width); | |
1266 return -1; | |
1267 } | |
1268 s->dcs_frame[5] |= DISBIT2; | |
1269 s->dcs_frame[8] |= DISBIT3; | |
1270 break; | |
1271 default: | |
1272 /* The image is of an unrecognised width. */ | |
1273 span_log(&s->logging, SPAN_LOG_FLOW, "Image width (%d pixels) not a valid FAX image width\n", s->image_width); | |
1274 return -1; | |
1275 } | |
1276 if (s->error_correcting_mode) | |
1277 s->dcs_frame[6] |= DISBIT3; | |
1278 s->dcs_len = 19; | |
1279 t30_decode_dis_dtc_dcs(s, s->dcs_frame, s->dcs_len); | |
1280 return 0; | |
1281 } | |
1282 /*- End of function --------------------------------------------------------*/ | |
1283 | |
1284 static int check_rx_dis_dtc(t30_state_t *s, const uint8_t *msg, int len) | |
1285 { | |
1286 uint8_t dis_dtc_frame[T30_MAX_DIS_DTC_DCS_LEN]; | |
1287 | |
1288 if (len < 6) | |
1289 { | |
1290 span_log(&s->logging, SPAN_LOG_FLOW, "Short DIS/DTC frame\n"); | |
1291 return -1; | |
1292 } | |
1293 | |
1294 /* Make a local copy of the message, padded to the maximum possible length with zeros. This allows | |
1295 us to simply pick out the bits, without worrying about whether they were set from the remote side. */ | |
1296 if (len > T30_MAX_DIS_DTC_DCS_LEN) | |
1297 { | |
1298 memcpy(dis_dtc_frame, msg, T30_MAX_DIS_DTC_DCS_LEN); | |
1299 } | |
1300 else | |
1301 { | |
1302 memcpy(dis_dtc_frame, msg, len); | |
1303 if (len < T30_MAX_DIS_DTC_DCS_LEN) | |
1304 memset(dis_dtc_frame + len, 0, T30_MAX_DIS_DTC_DCS_LEN - len); | |
1305 } | |
1306 s->error_correcting_mode = (s->ecm_allowed && (dis_dtc_frame[6] & DISBIT3) != 0); | |
1307 /* 256 octets per ECM frame */ | |
1308 s->octets_per_ecm_frame = 256; | |
1309 /* Select the compression to use. */ | |
1310 if ((s->supported_compressions & T30_SUPPORT_T6_COMPRESSION) && (dis_dtc_frame[6] & DISBIT7)) | |
1311 { | |
1312 s->line_encoding = T4_COMPRESSION_ITU_T6; | |
1313 } | |
1314 else if ((s->supported_compressions & T30_SUPPORT_T4_2D_COMPRESSION) && (dis_dtc_frame[4] & DISBIT8)) | |
1315 { | |
1316 s->line_encoding = T4_COMPRESSION_ITU_T4_2D; | |
1317 } | |
1318 else | |
1319 { | |
1320 s->line_encoding = T4_COMPRESSION_ITU_T4_1D; | |
1321 } | |
1322 span_log(&s->logging, SPAN_LOG_FLOW, "Selected compression %d\n", s->line_encoding); | |
1323 switch (dis_dtc_frame[4] & (DISBIT6 | DISBIT5 | DISBIT4 | DISBIT3)) | |
1324 { | |
1325 case 0: | |
1326 s->current_fallback = T30_V27TER_FALLBACK_START + 1; | |
1327 break; | |
1328 case DISBIT4: | |
1329 s->current_fallback = T30_V27TER_FALLBACK_START; | |
1330 break; | |
1331 case DISBIT3: | |
1332 /* TODO: this doesn't allow for skipping the V.27ter modes */ | |
1333 s->current_fallback = T30_V29_FALLBACK_START; | |
1334 break; | |
1335 case (DISBIT4 | DISBIT3): | |
1336 s->current_fallback = T30_V29_FALLBACK_START; | |
1337 break; | |
1338 case (DISBIT6 | DISBIT4 | DISBIT3): | |
1339 if ((s->supported_modems & T30_SUPPORT_V17)) | |
1340 s->current_fallback = T30_V17_FALLBACK_START; | |
1341 else | |
1342 s->current_fallback = T30_V29_FALLBACK_START; | |
1343 break; | |
1344 default: | |
1345 span_log(&s->logging, SPAN_LOG_FLOW, "Remote does not support a compatible modem\n"); | |
1346 /* We cannot talk to this machine! */ | |
1347 return -1; | |
1348 } | |
1349 return 0; | |
1350 } | |
1351 /*- End of function --------------------------------------------------------*/ | |
1352 | |
1353 static int check_rx_dcs(t30_state_t *s, const uint8_t *msg, int len) | |
1354 { | |
1355 static const int widths[3][4] = | |
1356 { | |
1357 { 864, 1024, 1216, -1}, /* R4 resolution - no longer used in recent versions of T.30 */ | |
1358 {1728, 2048, 2432, -1}, /* R8 resolution */ | |
1359 {3456, 4096, 4864, -1} /* R16 resolution */ | |
1360 }; | |
1361 uint8_t dcs_frame[T30_MAX_DIS_DTC_DCS_LEN]; | |
1362 int speed; | |
1363 int i; | |
1364 | |
1365 t30_decode_dis_dtc_dcs(s, msg, len); | |
1366 | |
1367 /* Check DCS frame from remote */ | |
1368 if (len < 6) | |
1369 { | |
1370 span_log(&s->logging, SPAN_LOG_FLOW, "Short DCS frame\n"); | |
1371 return -1; | |
1372 } | |
1373 | |
1374 /* Make a local copy of the message, padded to the maximum possible length with zeros. This allows | |
1375 us to simply pick out the bits, without worrying about whether they were set from the remote side. */ | |
1376 if (len > T30_MAX_DIS_DTC_DCS_LEN) | |
1377 { | |
1378 memcpy(dcs_frame, msg, T30_MAX_DIS_DTC_DCS_LEN); | |
1379 } | |
1380 else | |
1381 { | |
1382 memcpy(dcs_frame, msg, len); | |
1383 if (len < T30_MAX_DIS_DTC_DCS_LEN) | |
1384 memset(dcs_frame + len, 0, T30_MAX_DIS_DTC_DCS_LEN - len); | |
1385 } | |
1386 | |
1387 s->octets_per_ecm_frame = (dcs_frame[6] & DISBIT4) ? 256 : 64; | |
1388 if ((dcs_frame[8] & DISBIT1)) | |
1389 s->y_resolution = T4_Y_RESOLUTION_SUPERFINE; | |
1390 else if (dcs_frame[4] & DISBIT7) | |
1391 s->y_resolution = T4_Y_RESOLUTION_FINE; | |
1392 else | |
1393 s->y_resolution = T4_Y_RESOLUTION_STANDARD; | |
1394 s->image_width = widths[(dcs_frame[8] & DISBIT3) ? 2 : 1][dcs_frame[5] & (DISBIT2 | DISBIT1)]; | |
1395 | |
1396 /* Check which compression we will use. */ | |
1397 if ((dcs_frame[6] & DISBIT7)) | |
1398 s->line_encoding = T4_COMPRESSION_ITU_T6; | |
1399 else if ((dcs_frame[4] & DISBIT8)) | |
1400 s->line_encoding = T4_COMPRESSION_ITU_T4_2D; | |
1401 else | |
1402 s->line_encoding = T4_COMPRESSION_ITU_T4_1D; | |
1403 span_log(&s->logging, SPAN_LOG_FLOW, "Selected compression %d\n", s->line_encoding); | |
1404 if (!(dcs_frame[4] & DISBIT2)) | |
1405 span_log(&s->logging, SPAN_LOG_FLOW, "Remote cannot receive\n"); | |
1406 | |
1407 speed = dcs_frame[4] & (DISBIT6 | DISBIT5 | DISBIT4 | DISBIT3); | |
1408 for (i = 0; fallback_sequence[i].bit_rate; i++) | |
1409 { | |
1410 if (fallback_sequence[i].dcs_code == speed) | |
1411 break; | |
1412 } | |
1413 if (fallback_sequence[i].bit_rate == 0) | |
1414 { | |
1415 span_log(&s->logging, SPAN_LOG_FLOW, "Remote asked for a modem standard we do not support\n"); | |
1416 return -1; | |
1417 } | |
1418 s->current_fallback = i; | |
1419 s->error_correcting_mode = ((dcs_frame[6] & DISBIT3) != 0); | |
1420 return 0; | |
1421 } | |
1422 /*- End of function --------------------------------------------------------*/ | |
1423 | |
1424 static void send_dcn(t30_state_t *s) | |
1425 { | |
1426 queue_phase(s, T30_PHASE_D_TX); | |
1427 set_state(s, T30_STATE_C); | |
1428 send_simple_frame(s, T30_DCN); | |
1429 } | |
1430 /*- End of function --------------------------------------------------------*/ | |
1431 | |
1432 static void send_dis_or_dtc_sequence(t30_state_t *s) | |
1433 { | |
1434 if (send_nsf_frame(s)) | |
1435 { | |
1436 s->step = 0; | |
1437 return; | |
1438 } | |
1439 if (send_ident_frame(s, T30_CSI)) | |
1440 { | |
1441 s->step = 1; | |
1442 return; | |
1443 } | |
1444 set_dis_or_dtc(s); | |
1445 send_frame(s, s->dis_dtc_frame, s->dis_dtc_len); | |
1446 s->step = 2; | |
1447 } | |
1448 /*- End of function --------------------------------------------------------*/ | |
1449 | |
1450 static void send_dcs_sequence(t30_state_t *s) | |
1451 { | |
1452 if (send_pw_frame(s)) | |
1453 { | |
1454 s->step = 0; | |
1455 return; | |
1456 } | |
1457 if (send_sub_frame(s)) | |
1458 { | |
1459 s->step = 1; | |
1460 return; | |
1461 } | |
1462 if (send_ident_frame(s, T30_TSI)) | |
1463 { | |
1464 s->step = 2; | |
1465 return; | |
1466 } | |
1467 send_frame(s, s->dcs_frame, s->dcs_len); | |
1468 s->step = 3; | |
1469 } | |
1470 /*- End of function --------------------------------------------------------*/ | |
1471 | |
1472 static void disconnect(t30_state_t *s) | |
1473 { | |
1474 span_log(&s->logging, SPAN_LOG_FLOW, "Disconnecting\n"); | |
1475 /* Make sure any FAX in progress is tidied up. If the tidying up has | |
1476 already happened, repeating it here is harmless. */ | |
1477 t4_rx_end(&(s->t4)); | |
1478 t4_tx_end(&(s->t4)); | |
1479 s->timer_t0_t1 = 0; | |
1480 s->timer_t2_t4 = 0; | |
1481 s->timer_t3 = 0; | |
1482 s->timer_t5 = 0; | |
1483 set_phase(s, T30_PHASE_E); | |
1484 set_state(s, T30_STATE_B); | |
1485 } | |
1486 /*- End of function --------------------------------------------------------*/ | |
1487 | |
1488 static int start_sending_document(t30_state_t *s) | |
1489 { | |
1490 if (s->tx_file[0] == '\0') | |
1491 { | |
1492 /* There is nothing to send */ | |
1493 span_log(&s->logging, SPAN_LOG_FLOW, "No document to send\n"); | |
1494 return FALSE; | |
1495 } | |
1496 span_log(&s->logging, SPAN_LOG_FLOW, "Start sending document\n"); | |
1497 if (t4_tx_init(&(s->t4), s->tx_file, s->tx_start_page, s->tx_stop_page)) | |
1498 { | |
1499 span_log(&s->logging, SPAN_LOG_WARNING, "Cannot open source TIFF file '%s'\n", s->tx_file); | |
1500 s->current_status = T30_ERR_FILEERROR; | |
1501 return FALSE; | |
1502 } | |
1503 t4_tx_set_tx_encoding(&(s->t4), s->line_encoding); | |
1504 t4_tx_set_min_row_bits(&(s->t4), s->min_row_bits); | |
1505 t4_tx_set_local_ident(&(s->t4), s->local_ident); | |
1506 t4_tx_set_header_info(&(s->t4), s->header_info); | |
1507 | |
1508 s->y_resolution = t4_tx_get_y_resolution(&(s->t4)); | |
1509 switch (s->y_resolution) | |
1510 { | |
1511 case T4_Y_RESOLUTION_STANDARD: | |
1512 s->dcs_frame[4] &= ~DISBIT7; | |
1513 s->dcs_frame[8] &= ~DISBIT1; | |
1514 break; | |
1515 case T4_Y_RESOLUTION_FINE: | |
1516 s->dcs_frame[4] |= DISBIT7; | |
1517 s->dcs_frame[8] &= ~DISBIT1; | |
1518 break; | |
1519 case T4_Y_RESOLUTION_SUPERFINE: | |
1520 s->dcs_frame[4] &= ~DISBIT7; | |
1521 s->dcs_frame[8] |= DISBIT1; | |
1522 break; | |
1523 } | |
1524 s->image_width = t4_tx_get_image_width(&(s->t4)); | |
1525 t4_tx_start_page(&(s->t4)); | |
1526 s->ecm_page = 0; | |
1527 s->ecm_block = 0; | |
1528 if (s->error_correcting_mode) | |
1529 { | |
1530 if (get_partial_ecm_page(s) == 0) | |
1531 span_log(&s->logging, SPAN_LOG_WARNING, "No image data to send\n"); | |
1532 } | |
1533 /* Schedule training after the messages */ | |
1534 set_state(s, T30_STATE_D); | |
1535 s->retries = 0; | |
1536 send_dcs_sequence(s); | |
1537 return TRUE; | |
1538 } | |
1539 /*- End of function --------------------------------------------------------*/ | |
1540 | |
1541 static int restart_sending_document(t30_state_t *s) | |
1542 { | |
1543 /* Schedule training after the messages */ | |
1544 t4_tx_restart_page(&(s->t4)); | |
1545 set_state(s, T30_STATE_D); | |
1546 s->retries = 0; | |
1547 s->ecm_block = 0; | |
1548 send_dis_or_dtc_sequence(s); | |
1549 return TRUE; | |
1550 } | |
1551 /*- End of function --------------------------------------------------------*/ | |
1552 | |
1553 static int start_receiving_document(t30_state_t *s) | |
1554 { | |
1555 if (s->rx_file[0] == '\0') | |
1556 { | |
1557 /* There is nothing to receive to */ | |
1558 span_log(&s->logging, SPAN_LOG_FLOW, "No document to receive\n"); | |
1559 return FALSE; | |
1560 } | |
1561 span_log(&s->logging, SPAN_LOG_FLOW, "Start receiving document\n"); | |
1562 queue_phase(s, T30_PHASE_B_TX); | |
1563 set_state(s, T30_STATE_R); | |
1564 s->dis_received = FALSE; | |
1565 s->ecm_page = 0; | |
1566 s->ecm_block = 0; | |
1567 send_dis_or_dtc_sequence(s); | |
1568 return TRUE; | |
1569 } | |
1570 /*- End of function --------------------------------------------------------*/ | |
1571 | |
1572 static void unexpected_frame(t30_state_t *s, const uint8_t *msg, int len) | |
1573 { | |
1574 span_log(&s->logging, SPAN_LOG_FLOW, "Unexpected %s received in state %d\n", t30_frametype(msg[2]), s->state); | |
1575 if (s->state == T30_STATE_F_DOC) | |
1576 s->current_status = T30_ERR_INVALCMDRX; | |
1577 } | |
1578 /*- End of function --------------------------------------------------------*/ | |
1579 | |
1580 static void unexpected_final_frame(t30_state_t *s, const uint8_t *msg, int len) | |
1581 { | |
1582 span_log(&s->logging, SPAN_LOG_FLOW, "Unexpected %s received in state %d\n", t30_frametype(msg[2]), s->state); | |
1583 s->current_status = T30_ERR_UNEXPECTED; | |
1584 send_dcn(s); | |
1585 } | |
1586 /*- End of function --------------------------------------------------------*/ | |
1587 | |
1588 static void unexpected_frame_length(t30_state_t *s, const uint8_t *msg, int len) | |
1589 { | |
1590 span_log(&s->logging, SPAN_LOG_FLOW, "Unexpected %s frame length - %d\n", t30_frametype(msg[0]), len); | |
1591 s->current_status = T30_ERR_UNEXPECTED; | |
1592 send_dcn(s); | |
1593 } | |
1594 /*- End of function --------------------------------------------------------*/ | |
1595 | |
1596 static void process_rx_dis_or_dtc(t30_state_t *s, const uint8_t *msg, int len) | |
1597 { | |
1598 /* Digital identification signal or digital transmit command */ | |
1599 s->dis_received = TRUE; | |
1600 check_rx_dis_dtc(s, msg, len); | |
1601 switch (s->state) | |
1602 { | |
1603 case T30_STATE_D_POST_TCF: | |
1604 /* It appears they didn't see what we sent - retry the TCF */ | |
1605 if (++s->retries > MAX_MESSAGE_TRIES) | |
1606 { | |
1607 s->current_status = T30_ERR_RETRYDCN; | |
1608 send_dcn(s); | |
1609 break; | |
1610 } | |
1611 /* TODO: We should fall through at this point. However, if we do that | |
1612 we need to allow for a send or receive already being in progress from | |
1613 a previous try */ | |
1614 queue_phase(s, T30_PHASE_B_TX); | |
1615 /* Schedule training after the messages */ | |
1616 set_state(s, T30_STATE_D); | |
1617 send_dcs_sequence(s); | |
1618 break; | |
1619 case T30_STATE_R: | |
1620 case T30_STATE_T: | |
1621 case T30_STATE_F_DOC: | |
1622 t30_decode_dis_dtc_dcs(s, msg, len); | |
1623 if (s->phase_b_handler) | |
1624 s->phase_b_handler(s, s->phase_d_user_data, msg[2]); | |
1625 queue_phase(s, T30_PHASE_B_TX); | |
1626 /* Try to send something */ | |
1627 if (s->tx_file[0]) | |
1628 { | |
1629 span_log(&s->logging, SPAN_LOG_FLOW, "Trying to send file '%s'\n", s->tx_file); | |
1630 if ((msg[4] & DISBIT2)) | |
1631 { | |
1632 if (!start_sending_document(s)) | |
1633 { | |
1634 send_dcn(s); | |
1635 break; | |
1636 } | |
1637 if (build_dcs(s, msg, len)) | |
1638 { | |
1639 span_log(&s->logging, SPAN_LOG_FLOW, "The remote machine is incompatible\n", s->tx_file); | |
1640 s->current_status = T30_ERR_INCOMPATIBLE; | |
1641 send_dcn(s); | |
1642 break; | |
1643 } | |
1644 } | |
1645 else | |
1646 { | |
1647 span_log(&s->logging, SPAN_LOG_FLOW, "%s far end cannot receive\n", t30_frametype(msg[2])); | |
1648 s->current_status = T30_ERR_NOTRXCAPABLE; | |
1649 send_dcn(s); | |
1650 } | |
1651 break; | |
1652 } | |
1653 span_log(&s->logging, SPAN_LOG_FLOW, "%s nothing to send\n", t30_frametype(msg[2])); | |
1654 /* ... then try to receive something */ | |
1655 if (s->rx_file[0]) | |
1656 { | |
1657 span_log(&s->logging, SPAN_LOG_FLOW, "Trying to receive file '%s'\n", s->rx_file); | |
1658 if ((msg[4] & DISBIT1)) | |
1659 { | |
1660 if (!start_receiving_document(s)) | |
1661 { | |
1662 send_dcn(s); | |
1663 break; | |
1664 } | |
1665 if (set_dis_or_dtc(s)) | |
1666 { | |
1667 s->current_status = T30_ERR_INCOMPATIBLE; | |
1668 send_dcn(s); | |
1669 break; | |
1670 } | |
1671 } | |
1672 else | |
1673 { | |
1674 span_log(&s->logging, SPAN_LOG_FLOW, "%s far end cannot transmit\n", t30_frametype(msg[2])); | |
1675 s->current_status = T30_ERR_NOTTXCAPABLE; | |
1676 send_dcn(s); | |
1677 } | |
1678 break; | |
1679 } | |
1680 span_log(&s->logging, SPAN_LOG_FLOW, "%s nothing to receive\n", t30_frametype(msg[2])); | |
1681 /* There is nothing to do, or nothing we are able to do. */ | |
1682 send_dcn(s); | |
1683 break; | |
1684 default: | |
1685 unexpected_final_frame(s, msg, len); | |
1686 break; | |
1687 } | |
1688 } | |
1689 /*- End of function --------------------------------------------------------*/ | |
1690 | |
1691 static void process_rx_dcs(t30_state_t *s, const uint8_t *msg, int len) | |
1692 { | |
1693 /* Digital command signal */ | |
1694 switch (s->state) | |
1695 { | |
1696 case T30_STATE_R: | |
1697 case T30_STATE_F_DOC: | |
1698 /* (TSI) DCS */ | |
1699 /* (PWD) (SUB) (TSI) DCS */ | |
1700 check_rx_dcs(s, msg, len); | |
1701 if (s->phase_b_handler) | |
1702 s->phase_b_handler(s, s->phase_d_user_data, T30_DCS); | |
1703 /* Start document reception */ | |
1704 span_log(&s->logging, | |
1705 SPAN_LOG_FLOW, | |
1706 "Get document at %dbps, modem %d\n", | |
1707 fallback_sequence[s->current_fallback].bit_rate, | |
1708 fallback_sequence[s->current_fallback].modem_type); | |
1709 if (s->rx_file[0] == '\0') | |
1710 { | |
1711 span_log(&s->logging, SPAN_LOG_FLOW, "No document to receive\n"); | |
1712 s->current_status = T30_ERR_FILEERROR; | |
1713 send_dcn(s); | |
1714 break; | |
1715 } | |
1716 if (!s->in_message && t4_rx_init(&(s->t4), s->rx_file, T4_COMPRESSION_ITU_T4_2D)) | |
1717 { | |
1718 span_log(&s->logging, SPAN_LOG_WARNING, "Cannot open target TIFF file '%s'\n", s->rx_file); | |
1719 s->current_status = T30_ERR_FILEERROR; | |
1720 send_dcn(s); | |
1721 break; | |
1722 } | |
1723 if (!(s->iaf & T30_IAF_MODE_NO_TCF)) | |
1724 { | |
1725 set_state(s, T30_STATE_F_TCF); | |
1726 set_phase(s, T30_PHASE_C_NON_ECM_RX); | |
1727 } | |
1728 break; | |
1729 default: | |
1730 unexpected_final_frame(s, msg, len); | |
1731 break; | |
1732 } | |
1733 } | |
1734 /*- End of function --------------------------------------------------------*/ | |
1735 | |
1736 static void process_rx_cfr(t30_state_t *s, const uint8_t *msg, int len) | |
1737 { | |
1738 /* Confirmation to receive */ | |
1739 switch (s->state) | |
1740 { | |
1741 case T30_STATE_D_POST_TCF: | |
1742 /* Trainability test succeeded. Send the document. */ | |
1743 span_log(&s->logging, SPAN_LOG_FLOW, "Trainability test succeeded\n"); | |
1744 s->retries = 0; | |
1745 s->short_train = TRUE; | |
1746 if (s->error_correcting_mode) | |
1747 { | |
1748 set_state(s, T30_STATE_IV); | |
1749 queue_phase(s, T30_PHASE_C_ECM_TX); | |
1750 s->ecm_current_frame = 0; | |
1751 send_next_ecm_frame(s); | |
1752 } | |
1753 else | |
1754 { | |
1755 set_state(s, T30_STATE_I); | |
1756 queue_phase(s, T30_PHASE_C_NON_ECM_TX); | |
1757 } | |
1758 break; | |
1759 default: | |
1760 unexpected_final_frame(s, msg, len); | |
1761 break; | |
1762 } | |
1763 } | |
1764 /*- End of function --------------------------------------------------------*/ | |
1765 | |
1766 static void process_rx_ftt(t30_state_t *s, const uint8_t *msg, int len) | |
1767 { | |
1768 /* Failure to train */ | |
1769 switch (s->state) | |
1770 { | |
1771 case T30_STATE_D_POST_TCF: | |
1772 /* Trainability test failed. Try again. */ | |
1773 span_log(&s->logging, SPAN_LOG_FLOW, "Trainability test failed\n"); | |
1774 s->retries = 0; | |
1775 s->short_train = FALSE; | |
1776 if (fallback_sequence[++s->current_fallback].bit_rate == 0) | |
1777 { | |
1778 /* We have fallen back as far as we can go. Give up. */ | |
1779 s->current_fallback = 0; | |
1780 s->current_status = T30_ERR_CANNOTTRAIN; | |
1781 send_dcn(s); | |
1782 break; | |
1783 } | |
1784 /* Schedule training after the messages */ | |
1785 set_state(s, T30_STATE_D); | |
1786 s->retries = 0; | |
1787 send_dcs_sequence(s); | |
1788 break; | |
1789 default: | |
1790 unexpected_final_frame(s, msg, len); | |
1791 break; | |
1792 } | |
1793 } | |
1794 /*- End of function --------------------------------------------------------*/ | |
1795 | |
1796 static void process_rx_eom(t30_state_t *s, const uint8_t *msg, int len) | |
1797 { | |
1798 /* End of message */ | |
1799 switch (s->state) | |
1800 { | |
1801 case T30_STATE_F_POST_DOC_NON_ECM: | |
1802 if (s->phase_d_handler) | |
1803 s->phase_d_handler(s, s->phase_d_user_data, T30_EOM); | |
1804 s->next_rx_step = T30_EOM; | |
1805 /* Return to phase B */ | |
1806 queue_phase(s, T30_PHASE_B_TX); | |
1807 switch (copy_quality(s)) | |
1808 { | |
1809 case T30_COPY_QUALITY_GOOD: | |
1810 t4_rx_end_page(&(s->t4)); | |
1811 rx_start_page(s); | |
1812 set_state(s, T30_STATE_III_Q_MCF); | |
1813 send_simple_frame(s, T30_MCF); | |
1814 break; | |
1815 case T30_COPY_QUALITY_POOR: | |
1816 t4_rx_end_page(&(s->t4)); | |
1817 rx_start_page(s); | |
1818 set_state(s, T30_STATE_III_Q_RTP); | |
1819 send_simple_frame(s, T30_RTP); | |
1820 break; | |
1821 case T30_COPY_QUALITY_BAD: | |
1822 rx_start_page(s); | |
1823 set_state(s, T30_STATE_III_Q_RTN); | |
1824 send_simple_frame(s, T30_RTN); | |
1825 break; | |
1826 } | |
1827 break; | |
1828 default: | |
1829 unexpected_final_frame(s, msg, len); | |
1830 break; | |
1831 } | |
1832 } | |
1833 /*- End of function --------------------------------------------------------*/ | |
1834 | |
1835 static void process_rx_mps(t30_state_t *s, const uint8_t *msg, int len) | |
1836 { | |
1837 /* Multi-page signal */ | |
1838 switch (s->state) | |
1839 { | |
1840 case T30_STATE_F_POST_DOC_NON_ECM: | |
1841 if (s->phase_d_handler) | |
1842 s->phase_d_handler(s, s->phase_d_user_data, T30_MPS); | |
1843 s->next_rx_step = T30_MPS; | |
1844 /* Return to phase C */ | |
1845 queue_phase(s, T30_PHASE_D_TX); | |
1846 switch (copy_quality(s)) | |
1847 { | |
1848 case T30_COPY_QUALITY_GOOD: | |
1849 t4_rx_end_page(&(s->t4)); | |
1850 rx_start_page(s); | |
1851 set_state(s, T30_STATE_III_Q_MCF); | |
1852 send_simple_frame(s, T30_MCF); | |
1853 break; | |
1854 case T30_COPY_QUALITY_POOR: | |
1855 t4_rx_end_page(&(s->t4)); | |
1856 rx_start_page(s); | |
1857 set_state(s, T30_STATE_III_Q_RTP); | |
1858 send_simple_frame(s, T30_RTP); | |
1859 break; | |
1860 case T30_COPY_QUALITY_BAD: | |
1861 rx_start_page(s); | |
1862 set_state(s, T30_STATE_III_Q_RTN); | |
1863 send_simple_frame(s, T30_RTN); | |
1864 break; | |
1865 } | |
1866 break; | |
1867 default: | |
1868 unexpected_final_frame(s, msg, len); | |
1869 break; | |
1870 } | |
1871 } | |
1872 /*- End of function --------------------------------------------------------*/ | |
1873 | |
1874 static void process_rx_eop(t30_state_t *s, const uint8_t *msg, int len) | |
1875 { | |
1876 /* End of procedure */ | |
1877 switch (s->state) | |
1878 { | |
1879 case T30_STATE_F_POST_DOC_NON_ECM: | |
1880 if (s->phase_d_handler) | |
1881 s->phase_d_handler(s, s->phase_d_user_data, T30_EOP); | |
1882 s->next_rx_step = T30_EOP; | |
1883 queue_phase(s, T30_PHASE_D_TX); | |
1884 switch (copy_quality(s)) | |
1885 { | |
1886 case T30_COPY_QUALITY_GOOD: | |
1887 t4_rx_end_page(&(s->t4)); | |
1888 t4_rx_end(&(s->t4)); | |
1889 s->in_message = FALSE; | |
1890 set_state(s, T30_STATE_III_Q_MCF); | |
1891 send_simple_frame(s, T30_MCF); | |
1892 break; | |
1893 case T30_COPY_QUALITY_POOR: | |
1894 t4_rx_end_page(&(s->t4)); | |
1895 t4_rx_end(&(s->t4)); | |
1896 s->in_message = FALSE; | |
1897 set_state(s, T30_STATE_III_Q_RTP); | |
1898 send_simple_frame(s, T30_RTP); | |
1899 break; | |
1900 case T30_COPY_QUALITY_BAD: | |
1901 set_state(s, T30_STATE_III_Q_RTN); | |
1902 send_simple_frame(s, T30_RTN); | |
1903 break; | |
1904 } | |
1905 break; | |
1906 default: | |
1907 unexpected_final_frame(s, msg, len); | |
1908 break; | |
1909 } | |
1910 } | |
1911 /*- End of function --------------------------------------------------------*/ | |
1912 | |
1913 static void process_rx_pri_eom(t30_state_t *s, const uint8_t *msg, int len) | |
1914 { | |
1915 /* Procedure interrupt - end of procedure */ | |
1916 switch (s->state) | |
1917 { | |
1918 case T30_STATE_F_POST_DOC_NON_ECM: | |
1919 if (s->phase_d_handler) | |
1920 { | |
1921 s->phase_d_handler(s, s->phase_d_user_data, T30_PRI_EOM); | |
1922 s->timer_t3 = ms_to_samples(DEFAULT_TIMER_T3); | |
1923 } | |
1924 s->next_rx_step = T30_PRI_EOM; | |
1925 switch (copy_quality(s)) | |
1926 { | |
1927 case T30_COPY_QUALITY_GOOD: | |
1928 t4_rx_end_page(&(s->t4)); | |
1929 t4_rx_end(&(s->t4)); | |
1930 s->in_message = FALSE; | |
1931 set_state(s, T30_STATE_III_Q_MCF); | |
1932 break; | |
1933 case T30_COPY_QUALITY_POOR: | |
1934 t4_rx_end_page(&(s->t4)); | |
1935 t4_rx_end(&(s->t4)); | |
1936 s->in_message = FALSE; | |
1937 set_state(s, T30_STATE_III_Q_RTP); | |
1938 break; | |
1939 case T30_COPY_QUALITY_BAD: | |
1940 set_state(s, T30_STATE_III_Q_RTN); | |
1941 break; | |
1942 } | |
1943 break; | |
1944 default: | |
1945 unexpected_final_frame(s, msg, len); | |
1946 break; | |
1947 } | |
1948 } | |
1949 /*- End of function --------------------------------------------------------*/ | |
1950 | |
1951 static void process_rx_pri_mps(t30_state_t *s, const uint8_t *msg, int len) | |
1952 { | |
1953 /* Procedure interrupt - multipage signal */ | |
1954 switch (s->state) | |
1955 { | |
1956 case T30_STATE_F_POST_DOC_NON_ECM: | |
1957 if (s->phase_d_handler) | |
1958 { | |
1959 s->phase_d_handler(s, s->phase_d_user_data, T30_PRI_MPS); | |
1960 s->timer_t3 = ms_to_samples(DEFAULT_TIMER_T3); | |
1961 } | |
1962 s->next_rx_step = T30_PRI_MPS; | |
1963 switch (copy_quality(s)) | |
1964 { | |
1965 case T30_COPY_QUALITY_GOOD: | |
1966 t4_rx_end_page(&(s->t4)); | |
1967 t4_rx_end(&(s->t4)); | |
1968 s->in_message = FALSE; | |
1969 set_state(s, T30_STATE_III_Q_MCF); | |
1970 break; | |
1971 case T30_COPY_QUALITY_POOR: | |
1972 t4_rx_end_page(&(s->t4)); | |
1973 t4_rx_end(&(s->t4)); | |
1974 s->in_message = FALSE; | |
1975 set_state(s, T30_STATE_III_Q_RTP); | |
1976 break; | |
1977 case T30_COPY_QUALITY_BAD: | |
1978 set_state(s, T30_STATE_III_Q_RTN); | |
1979 break; | |
1980 } | |
1981 break; | |
1982 default: | |
1983 unexpected_final_frame(s, msg, len); | |
1984 break; | |
1985 } | |
1986 } | |
1987 /*- End of function --------------------------------------------------------*/ | |
1988 | |
1989 static void process_rx_pri_eop(t30_state_t *s, const uint8_t *msg, int len) | |
1990 { | |
1991 /* Procedure interrupt - end of procedure */ | |
1992 switch (s->state) | |
1993 { | |
1994 case T30_STATE_F_POST_DOC_NON_ECM: | |
1995 if (s->phase_d_handler) | |
1996 { | |
1997 s->phase_d_handler(s, s->phase_d_user_data, T30_PRI_EOP); | |
1998 s->timer_t3 = ms_to_samples(DEFAULT_TIMER_T3); | |
1999 } | |
2000 s->next_rx_step = T30_PRI_EOP; | |
2001 switch (copy_quality(s)) | |
2002 { | |
2003 case T30_COPY_QUALITY_GOOD: | |
2004 t4_rx_end_page(&(s->t4)); | |
2005 t4_rx_end(&(s->t4)); | |
2006 s->in_message = FALSE; | |
2007 set_state(s, T30_STATE_III_Q_MCF); | |
2008 break; | |
2009 case T30_COPY_QUALITY_POOR: | |
2010 t4_rx_end_page(&(s->t4)); | |
2011 t4_rx_end(&(s->t4)); | |
2012 s->in_message = FALSE; | |
2013 set_state(s, T30_STATE_III_Q_RTP); | |
2014 break; | |
2015 case T30_COPY_QUALITY_BAD: | |
2016 set_state(s, T30_STATE_III_Q_RTN); | |
2017 break; | |
2018 } | |
2019 break; | |
2020 default: | |
2021 unexpected_final_frame(s, msg, len); | |
2022 break; | |
2023 } | |
2024 } | |
2025 /*- End of function --------------------------------------------------------*/ | |
2026 | |
2027 static void process_rx_nss(t30_state_t *s, const uint8_t *msg, int len) | |
2028 { | |
2029 /* Non-standard facilities set-up */ | |
2030 switch (s->state) | |
2031 { | |
2032 default: | |
2033 unexpected_final_frame(s, msg, len); | |
2034 break; | |
2035 } | |
2036 } | |
2037 /*- End of function --------------------------------------------------------*/ | |
2038 | |
2039 static void process_rx_ctc(t30_state_t *s, const uint8_t *msg, int len) | |
2040 { | |
2041 /* Continue to correct */ | |
2042 switch (s->state) | |
2043 { | |
2044 case T30_STATE_F_DOC: | |
2045 case T30_STATE_F_POST_DOC_ECM: | |
2046 send_simple_frame(s, T30_CTR); | |
2047 break; | |
2048 default: | |
2049 unexpected_final_frame(s, msg, len); | |
2050 break; | |
2051 } | |
2052 } | |
2053 /*- End of function --------------------------------------------------------*/ | |
2054 | |
2055 static void process_rx_ctr(t30_state_t *s, const uint8_t *msg, int len) | |
2056 { | |
2057 /* Response for continue to correct */ | |
2058 switch (s->state) | |
2059 { | |
2060 case T30_STATE_IV_CTC: | |
2061 break; | |
2062 default: | |
2063 unexpected_final_frame(s, msg, len); | |
2064 break; | |
2065 } | |
2066 } | |
2067 /*- End of function --------------------------------------------------------*/ | |
2068 | |
2069 static void process_rx_err(t30_state_t *s, const uint8_t *msg, int len) | |
2070 { | |
2071 /* Response for end of retransmission */ | |
2072 switch (s->state) | |
2073 { | |
2074 case T30_STATE_IV_EOR: | |
2075 case T30_STATE_IV_EOR_RNR: | |
2076 /* TODO: Continue with the next message if MPS or EOM? */ | |
2077 send_dcn(s); | |
2078 break; | |
2079 default: | |
2080 unexpected_final_frame(s, msg, len); | |
2081 break; | |
2082 } | |
2083 } | |
2084 /*- End of function --------------------------------------------------------*/ | |
2085 | |
2086 static void process_rx_ppr(t30_state_t *s, const uint8_t *msg, int len) | |
2087 { | |
2088 int i; | |
2089 int j; | |
2090 int frame_no; | |
2091 int mask; | |
2092 uint8_t frame[100 + 3]; | |
2093 | |
2094 /* Partial page request */ | |
2095 switch (s->state) | |
2096 { | |
2097 case T30_STATE_IV_PPS_NULL: | |
2098 case T30_STATE_IV_PPS_Q: | |
2099 if (++s->ppr_count >= 4) | |
2100 { | |
2101 /* Continue to correct? */ | |
2102 /* TODO: Decide if we should continue */ | |
2103 if (1) | |
2104 { | |
2105 set_state(s, T30_STATE_IV_CTC); | |
2106 send_simple_frame(s, T30_CTC); | |
2107 } | |
2108 else | |
2109 { | |
2110 set_state(s, T30_STATE_IV_EOR); | |
2111 frame[0] = 0xFF; | |
2112 frame[1] = 0x13; | |
2113 frame[2] = T30_EOR; | |
2114 frame[3] = (s->ecm_at_page_end) ? ((uint8_t) (s->next_tx_step | s->dis_received)) : T30_NULL; | |
2115 span_log(&s->logging, SPAN_LOG_FLOW, "Sending EOR + %s\n", t30_frametype(frame[3])); | |
2116 send_frame(s, frame, 4); | |
2117 } | |
2118 } | |
2119 else | |
2120 { | |
2121 /* Check which frames are OK, and mark them as OK. */ | |
2122 for (i = 0; i < 32; i++) | |
2123 { | |
2124 if (msg[i + 3] == 0) | |
2125 { | |
2126 s->ecm_frame_map[i + 3] = 0; | |
2127 for (j = 0; j < 8; j++) | |
2128 s->ecm_len[(i << 3) + j] = -1; | |
2129 } | |
2130 else | |
2131 { | |
2132 mask = 1; | |
2133 for (j = 0; j < 8; j++) | |
2134 { | |
2135 frame_no = (i << 3) + j; | |
2136 /* Tick off the frames they are not complaining about as OK */ | |
2137 if ((msg[i + 3] & mask) == 0) | |
2138 s->ecm_len[frame_no] = -1; | |
2139 else | |
2140 { | |
2141 if (frame_no < s->ecm_frames) | |
2142 span_log(&s->logging, SPAN_LOG_FLOW, "Frame %d to be resent\n", frame_no); | |
2143 #if 0 | |
2144 /* Diagnostic: See if the other end is complaining about something we didn't even send this time. */ | |
2145 if (s->ecm_len[frame_no] < 0) | |
2146 span_log(&s->logging, SPAN_LOG_FLOW, "PPR contains complaint about frame %d, which was not send\n", frame_no); | |
2147 #endif | |
2148 } | |
2149 mask <<= 1; | |
2150 } | |
2151 } | |
2152 } | |
2153 /* Initiate resending of the remainder of the frames. */ | |
2154 set_state(s, T30_STATE_IV); | |
2155 queue_phase(s, T30_PHASE_C_ECM_TX); | |
2156 s->ecm_current_frame = 0; | |
2157 send_next_ecm_frame(s); | |
2158 } | |
2159 break; | |
2160 default: | |
2161 unexpected_final_frame(s, msg, len); | |
2162 break; | |
2163 } | |
2164 } | |
2165 /*- End of function --------------------------------------------------------*/ | |
2166 | |
2167 static void process_rx_rr(t30_state_t *s, const uint8_t *msg, int len) | |
2168 { | |
2169 /* Receiver ready */ | |
2170 switch (s->state) | |
2171 { | |
2172 case T30_STATE_F_POST_DOC_NON_ECM: | |
2173 /* TODO: */ | |
2174 s->timer_t5 = 0; | |
2175 break; | |
2176 default: | |
2177 unexpected_final_frame(s, msg, len); | |
2178 break; | |
2179 } | |
2180 } | |
2181 /*- End of function --------------------------------------------------------*/ | |
2182 | |
2183 static void process_rx_rnr(t30_state_t *s, const uint8_t *msg, int len) | |
2184 { | |
2185 /* Receive not ready */ | |
2186 switch (s->state) | |
2187 { | |
2188 case T30_STATE_IV_PPS_NULL: | |
2189 case T30_STATE_IV_PPS_Q: | |
2190 set_state(s, T30_STATE_IV_PPS_RNR); | |
2191 send_simple_frame(s, T30_RR); | |
2192 break; | |
2193 case T30_STATE_IV_PPS_RNR: | |
2194 send_simple_frame(s, T30_RR); | |
2195 /* TODO: */ | |
2196 if (s->timer_t5 == 0) | |
2197 s->timer_t5 = ms_to_samples(DEFAULT_TIMER_T5); | |
2198 break; | |
2199 case T30_STATE_IV_EOR: | |
2200 set_state(s, T30_STATE_IV_EOR_RNR); | |
2201 send_simple_frame(s, T30_RR); | |
2202 break; | |
2203 case T30_STATE_IV_EOR_RNR: | |
2204 send_simple_frame(s, T30_RR); | |
2205 break; | |
2206 default: | |
2207 unexpected_final_frame(s, msg, len); | |
2208 break; | |
2209 } | |
2210 } | |
2211 /*- End of function --------------------------------------------------------*/ | |
2212 | |
2213 static void process_rx_eos(t30_state_t *s, const uint8_t *msg, int len) | |
2214 { | |
2215 /* End of selection */ | |
2216 switch (s->state) | |
2217 { | |
2218 default: | |
2219 unexpected_final_frame(s, msg, len); | |
2220 break; | |
2221 } | |
2222 } | |
2223 /*- End of function --------------------------------------------------------*/ | |
2224 | |
2225 static void process_rx_tr(t30_state_t *s, const uint8_t *msg, int len) | |
2226 { | |
2227 /* Transmit ready */ | |
2228 switch (s->state) | |
2229 { | |
2230 default: | |
2231 unexpected_final_frame(s, msg, len); | |
2232 break; | |
2233 } | |
2234 } | |
2235 /*- End of function --------------------------------------------------------*/ | |
2236 | |
2237 static void process_rx_fcd(t30_state_t *s, const uint8_t *msg, int len) | |
2238 { | |
2239 int frame_no; | |
2240 int i; | |
2241 | |
2242 /* Facsimile coded data */ | |
2243 switch (s->state) | |
2244 { | |
2245 case T30_STATE_F_DOC: | |
2246 if (len <= 4 + 256) | |
2247 { | |
2248 frame_no = msg[3]; | |
2249 /* Just store the actual image data, and record its length */ | |
2250 span_log(&s->logging, SPAN_LOG_FLOW, "Storing image frame %d, length %d\n", frame_no, len - 4); | |
2251 for (i = 0; i < len - 4; i++) | |
2252 s->ecm_data[frame_no][i] = msg[i + 4]; | |
2253 s->ecm_len[frame_no] = (int16_t) (len - 4); | |
2254 span_log(&s->logging, SPAN_LOG_FLOW, "Storing ECM frame %d\n", frame_no); | |
2255 } | |
2256 else | |
2257 { | |
2258 unexpected_frame_length(s, msg, len); | |
2259 } | |
2260 break; | |
2261 default: | |
2262 unexpected_final_frame(s, msg, len); | |
2263 break; | |
2264 } | |
2265 } | |
2266 /*- End of function --------------------------------------------------------*/ | |
2267 | |
2268 static void process_rx_rcp(t30_state_t *s, const uint8_t *msg, int len) | |
2269 { | |
2270 /* Return to control for partial page */ | |
2271 switch (s->state) | |
2272 { | |
2273 case T30_STATE_F_DOC: | |
2274 set_state(s, T30_STATE_F_POST_DOC_ECM); | |
2275 queue_phase(s, T30_PHASE_D_RX); | |
2276 break; | |
2277 case T30_STATE_F_POST_DOC_ECM: | |
2278 /* Ignore extra RCP frames. The source will usually send several to maximum the chance of | |
2279 one getting through OK. */ | |
2280 break; | |
2281 default: | |
2282 unexpected_final_frame(s, msg, len); | |
2283 break; | |
2284 } | |
2285 } | |
2286 /*- End of function --------------------------------------------------------*/ | |
2287 | |
2288 static void process_rx_fnv(t30_state_t *s, const uint8_t *msg, int len) | |
2289 { | |
2290 logging_state_t *log; | |
2291 const char *x; | |
2292 | |
2293 /* Field not valid */ | |
2294 /* TODO: analyse the message, as per 5.3.6.2.13 */ | |
2295 if (!span_log_test(&s->logging, SPAN_LOG_FLOW)) | |
2296 return; | |
2297 log = &s->logging; | |
2298 | |
2299 if ((msg[3] & 0x01)) | |
2300 span_log(log, SPAN_LOG_FLOW, " Incorrect password (PWD).\n"); | |
2301 if ((msg[3] & 0x02)) | |
2302 span_log(log, SPAN_LOG_FLOW, " Selective polling reference (SEP) not known.\n"); | |
2303 if ((msg[3] & 0x04)) | |
2304 span_log(log, SPAN_LOG_FLOW, " Subaddress (SUB) not known.\n"); | |
2305 if ((msg[3] & 0x08)) | |
2306 span_log(log, SPAN_LOG_FLOW, " Sender identity (SID) not known.\n"); | |
2307 if ((msg[3] & 0x10)) | |
2308 span_log(log, SPAN_LOG_FLOW, " Secure fax error.\n"); | |
2309 if ((msg[3] & 0x20)) | |
2310 span_log(log, SPAN_LOG_FLOW, " Transmitting subscriber identity (TSI) not accepted.\n"); | |
2311 if ((msg[3] & 0x40)) | |
2312 span_log(log, SPAN_LOG_FLOW, " Polled subaddress (PSA) not known.\n"); | |
2313 if (len > 4 && (msg[3] & DISBIT8)) | |
2314 { | |
2315 if ((msg[4] & 0x01)) | |
2316 span_log(log, SPAN_LOG_FLOW, " BFT negotiations request not accepted.\n"); | |
2317 if ((msg[4] & 0x02)) | |
2318 span_log(log, SPAN_LOG_FLOW, " Internet routing address (IRA) not known.\n"); | |
2319 if ((msg[4] & 0x04)) | |
2320 span_log(log, SPAN_LOG_FLOW, " Internet selective polling address (ISP) not known.\n"); | |
2321 } | |
2322 if (len > 5) | |
2323 { | |
2324 span_log(log, SPAN_LOG_FLOW, " FNV sequence number %d.\n", msg[5]); | |
2325 } | |
2326 if (len > 6) | |
2327 { | |
2328 switch (msg[6]) | |
2329 { | |
2330 case 0x83: | |
2331 x = "Incorrect password (PWD)"; | |
2332 break; | |
2333 case 0x85: | |
2334 x = "Selective polling reference (SEP) not known"; | |
2335 break; | |
2336 case 0x43: | |
2337 case 0xC3: | |
2338 x = "Subaddress (SUB) not known"; | |
2339 break; | |
2340 case 0x45: | |
2341 case 0xC5: | |
2342 x = "Sender identity (SID) not known"; | |
2343 break; | |
2344 case 0x10: | |
2345 x = "Secure fax error"; | |
2346 break; | |
2347 case 0x42: | |
2348 case 0xC2: | |
2349 x = "Transmitting subscriber identity (TSI) not accepted"; | |
2350 break; | |
2351 case 0x86: | |
2352 x = "Polled subaddress (PSA) not known"; | |
2353 break; | |
2354 default: | |
2355 x = "???"; | |
2356 break; | |
2357 } | |
2358 span_log(log, SPAN_LOG_FLOW, " FNV diagnostic info type %s.\n", x); | |
2359 } | |
2360 if (len > 7) | |
2361 { | |
2362 span_log(log, SPAN_LOG_FLOW, " FNV length %d.\n", msg[7]); | |
2363 } | |
2364 /* We've decoded it, but we don't yet know how to deal with it, so treat it as unexpected */ | |
2365 unexpected_final_frame(s, msg, len); | |
2366 } | |
2367 /*- End of function --------------------------------------------------------*/ | |
2368 | |
2369 static void process_rx_pps(t30_state_t *s, const uint8_t *msg, int len) | |
2370 { | |
2371 int fcf2; | |
2372 int page; | |
2373 int block; | |
2374 int i; | |
2375 int j; | |
2376 int frame_no; | |
2377 int first_bad_frame; | |
2378 | |
2379 /* Partial page signal */ | |
2380 switch (s->state) | |
2381 { | |
2382 case T30_STATE_F_DOC: | |
2383 case T30_STATE_F_POST_DOC_ECM: | |
2384 if (len >= 7) | |
2385 { | |
2386 fcf2 = msg[3] & 0xFE; | |
2387 page = msg[4]; | |
2388 block = msg[5]; | |
2389 s->ecm_frames = msg[6] + 1; | |
2390 span_log(&s->logging, SPAN_LOG_FLOW, "Received PPS + %s\n", t30_frametype(msg[3])); | |
2391 /* Build a bit map of which frames we now have stored OK */ | |
2392 frame_no = 0; | |
2393 first_bad_frame = 256; | |
2394 for (i = 3; i < 3 + 32; i++) | |
2395 { | |
2396 s->ecm_frame_map[i] = 0; | |
2397 for (j = 0; j < 8; j++) | |
2398 { | |
2399 if (s->ecm_len[frame_no] < 0) | |
2400 { | |
2401 s->ecm_frame_map[i] |= (1 << j); | |
2402 if (frame_no < first_bad_frame) | |
2403 first_bad_frame = frame_no; | |
2404 } | |
2405 frame_no++; | |
2406 } | |
2407 } | |
2408 /* Now, are there really bad frames, or does our scan represent things being OK? */ | |
2409 queue_phase(s, T30_PHASE_D_TX); | |
2410 if (first_bad_frame >= s->ecm_frames) | |
2411 { | |
2412 /* Everything was OK. We can accept the data and move on. */ | |
2413 switch (fcf2) | |
2414 { | |
2415 case T30_NULL: | |
2416 /* We can confirm this partial page. */ | |
2417 t30_ecm_commit_partial_page(s); | |
2418 set_state(s, T30_STATE_F_POST_RCP_MCF); | |
2419 send_simple_frame(s, T30_MCF); | |
2420 break; | |
2421 case T30_EOP: | |
2422 case T30_EOM: | |
2423 case T30_MPS: | |
2424 case T30_PRI_EOP: | |
2425 case T30_PRI_EOM: | |
2426 case T30_PRI_MPS: | |
2427 /* We can confirm the whole page. */ | |
2428 s->next_rx_step = fcf2; | |
2429 t30_ecm_commit_partial_page(s); | |
2430 t4_rx_end_page(&(s->t4)); | |
2431 if (s->phase_d_handler) | |
2432 s->phase_d_handler(s, s->phase_d_user_data, fcf2); | |
2433 rx_start_page(s); | |
2434 set_state(s, T30_STATE_F_POST_RCP_MCF); | |
2435 send_simple_frame(s, T30_MCF); | |
2436 break; | |
2437 default: | |
2438 unexpected_final_frame(s, msg, len); | |
2439 break; | |
2440 } | |
2441 } | |
2442 else | |
2443 { | |
2444 /* We need to send the PPR frame we have created, to try to fill in the missing/bad data. */ | |
2445 set_state(s, T30_STATE_F_POST_RCP_PPR); | |
2446 s->ecm_frame_map[0] = 0xFF; | |
2447 s->ecm_frame_map[1] = 0x13; | |
2448 s->ecm_frame_map[2] = T30_PPR; | |
2449 send_frame(s, s->ecm_frame_map, 3 + 32); | |
2450 } | |
2451 } | |
2452 else | |
2453 { | |
2454 span_log(&s->logging, SPAN_LOG_FLOW, "Bad PPS message length %d.\n", len); | |
2455 } | |
2456 break; | |
2457 default: | |
2458 unexpected_final_frame(s, msg, len); | |
2459 break; | |
2460 } | |
2461 } | |
2462 /*- End of function --------------------------------------------------------*/ | |
2463 | |
2464 static void process_rx_tnr(t30_state_t *s, const uint8_t *msg, int len) | |
2465 { | |
2466 /* Transmit not ready */ | |
2467 switch (s->state) | |
2468 { | |
2469 default: | |
2470 unexpected_final_frame(s, msg, len); | |
2471 break; | |
2472 } | |
2473 } | |
2474 /*- End of function --------------------------------------------------------*/ | |
2475 | |
2476 static void process_rx_eor(t30_state_t *s, const uint8_t *msg, int len) | |
2477 { | |
2478 int fcf2; | |
2479 | |
2480 /* End of retransmission */ | |
2481 /* Partial page signal */ | |
2482 switch (s->state) | |
2483 { | |
2484 case T30_STATE_F_DOC: | |
2485 case T30_STATE_F_POST_DOC_ECM: | |
2486 if (len == 4) | |
2487 { | |
2488 fcf2 = msg[3] & 0xFE; | |
2489 span_log(&s->logging, SPAN_LOG_FLOW, "Received EOR + %s\n", t30_frametype(msg[3])); | |
2490 switch (fcf2) | |
2491 { | |
2492 case T30_NULL: | |
2493 break; | |
2494 case T30_PRI_EOM: | |
2495 case T30_PRI_MPS: | |
2496 case T30_PRI_EOP: | |
2497 /* TODO: Alert operator */ | |
2498 /* Fall through */ | |
2499 case T30_EOM: | |
2500 case T30_MPS: | |
2501 case T30_EOP: | |
2502 s->next_rx_step = fcf2; | |
2503 send_simple_frame(s, T30_ERR); | |
2504 break; | |
2505 default: | |
2506 unexpected_final_frame(s, msg, len); | |
2507 break; | |
2508 } | |
2509 } | |
2510 else | |
2511 { | |
2512 unexpected_frame_length(s, msg, len); | |
2513 } | |
2514 break; | |
2515 default: | |
2516 unexpected_final_frame(s, msg, len); | |
2517 break; | |
2518 } | |
2519 } | |
2520 /*- End of function --------------------------------------------------------*/ | |
2521 | |
2522 static void process_rx_fdm(t30_state_t *s, const uint8_t *msg, int len) | |
2523 { | |
2524 /* File diagnostics message */ | |
2525 switch (s->state) | |
2526 { | |
2527 default: | |
2528 unexpected_final_frame(s, msg, len); | |
2529 break; | |
2530 } | |
2531 } | |
2532 /*- End of function --------------------------------------------------------*/ | |
2533 | |
2534 static void process_rx_mcf(t30_state_t *s, const uint8_t *msg, int len) | |
2535 { | |
2536 t4_stats_t stats; | |
2537 | |
2538 /* Message confirmation */ | |
2539 switch (s->state) | |
2540 { | |
2541 case T30_STATE_II_Q: | |
2542 switch (s->next_tx_step) | |
2543 { | |
2544 case T30_MPS: | |
2545 case T30_PRI_MPS: | |
2546 s->retries = 0; | |
2547 t4_tx_end_page(&(s->t4)); | |
2548 if (s->phase_d_handler) | |
2549 s->phase_d_handler(s, s->phase_d_user_data, T30_MCF); | |
2550 t4_tx_start_page(&(s->t4)); | |
2551 set_state(s, T30_STATE_I); | |
2552 queue_phase(s, T30_PHASE_C_NON_ECM_TX); | |
2553 break; | |
2554 case T30_EOM: | |
2555 case T30_PRI_EOM: | |
2556 s->retries = 0; | |
2557 t4_tx_end_page(&(s->t4)); | |
2558 if (s->phase_d_handler) | |
2559 s->phase_d_handler(s, s->phase_d_user_data, T30_MCF); | |
2560 t4_tx_end(&(s->t4)); | |
2561 set_state(s, T30_STATE_R); | |
2562 if (span_log_test(&s->logging, SPAN_LOG_FLOW)) | |
2563 { | |
2564 t4_get_transfer_statistics(&(s->t4), &stats); | |
2565 span_log(&s->logging, SPAN_LOG_FLOW, "Success - delivered %d pages\n", stats.pages_transferred); | |
2566 } | |
2567 break; | |
2568 case T30_EOP: | |
2569 case T30_PRI_EOP: | |
2570 s->retries = 0; | |
2571 t4_tx_end_page(&(s->t4)); | |
2572 if (s->phase_d_handler) | |
2573 s->phase_d_handler(s, s->phase_d_user_data, T30_MCF); | |
2574 t4_tx_end(&(s->t4)); | |
2575 send_dcn(s); | |
2576 if (span_log_test(&s->logging, SPAN_LOG_FLOW)) | |
2577 { | |
2578 t4_get_transfer_statistics(&(s->t4), &stats); | |
2579 span_log(&s->logging, SPAN_LOG_FLOW, "Success - delivered %d pages\n", stats.pages_transferred); | |
2580 } | |
2581 break; | |
2582 } | |
2583 break; | |
2584 case T30_STATE_IV_PPS_NULL: | |
2585 case T30_STATE_IV_PPS_Q: | |
2586 case T30_STATE_IV_PPS_RNR: | |
2587 s->retries = 0; | |
2588 /* Is there more of the current page to get, or do we move on? */ | |
2589 span_log(&s->logging, SPAN_LOG_FLOW, "Is there more to send? - %d %d\n", s->ecm_frames, s->ecm_len[255]); | |
2590 if (!s->ecm_at_page_end && get_partial_ecm_page(s) > 0) | |
2591 { | |
2592 span_log(&s->logging, SPAN_LOG_WARNING, "Additional image data to send\n"); | |
2593 s->ecm_block++; | |
2594 set_state(s, T30_STATE_IV); | |
2595 queue_phase(s, T30_PHASE_C_ECM_TX); | |
2596 s->ecm_current_frame = 0; | |
2597 send_next_ecm_frame(s); | |
2598 } | |
2599 else | |
2600 { | |
2601 | |
2602 span_log(&s->logging, SPAN_LOG_FLOW, "Moving on to the next page\n"); | |
2603 switch (s->next_tx_step) | |
2604 { | |
2605 case T30_MPS: | |
2606 case T30_PRI_MPS: | |
2607 s->retries = 0; | |
2608 t4_tx_end_page(&(s->t4)); | |
2609 if (s->phase_d_handler) | |
2610 s->phase_d_handler(s, s->phase_d_user_data, T30_MCF); | |
2611 t4_tx_start_page(&(s->t4)); | |
2612 s->ecm_page++; | |
2613 s->ecm_block = 0; | |
2614 if (get_partial_ecm_page(s) > 0) | |
2615 { | |
2616 set_state(s, T30_STATE_IV); | |
2617 queue_phase(s, T30_PHASE_C_ECM_TX); | |
2618 s->ecm_current_frame = 0; | |
2619 send_next_ecm_frame(s); | |
2620 } | |
2621 break; | |
2622 case T30_EOM: | |
2623 case T30_PRI_EOM: | |
2624 s->retries = 0; | |
2625 t4_tx_end_page(&(s->t4)); | |
2626 if (s->phase_d_handler) | |
2627 s->phase_d_handler(s, s->phase_d_user_data, T30_MCF); | |
2628 t4_tx_end(&(s->t4)); | |
2629 set_state(s, T30_STATE_R); | |
2630 if (span_log_test(&s->logging, SPAN_LOG_FLOW)) | |
2631 { | |
2632 t4_get_transfer_statistics(&(s->t4), &stats); | |
2633 span_log(&s->logging, SPAN_LOG_FLOW, "Success - delivered %d pages\n", stats.pages_transferred); | |
2634 } | |
2635 break; | |
2636 case T30_EOP: | |
2637 case T30_PRI_EOP: | |
2638 s->retries = 0; | |
2639 t4_tx_end_page(&(s->t4)); | |
2640 if (s->phase_d_handler) | |
2641 s->phase_d_handler(s, s->phase_d_user_data, T30_MCF); | |
2642 t4_tx_end(&(s->t4)); | |
2643 send_dcn(s); | |
2644 if (span_log_test(&s->logging, SPAN_LOG_FLOW)) | |
2645 { | |
2646 t4_get_transfer_statistics(&(s->t4), &stats); | |
2647 span_log(&s->logging, SPAN_LOG_FLOW, "Success - delivered %d pages\n", stats.pages_transferred); | |
2648 } | |
2649 break; | |
2650 } | |
2651 } | |
2652 break; | |
2653 default: | |
2654 unexpected_final_frame(s, msg, len); | |
2655 break; | |
2656 } | |
2657 } | |
2658 /*- End of function --------------------------------------------------------*/ | |
2659 | |
2660 static void process_rx_rtp(t30_state_t *s, const uint8_t *msg, int len) | |
2661 { | |
2662 /* Retrain positive */ | |
2663 s->short_train = FALSE; | |
2664 switch (s->state) | |
2665 { | |
2666 case T30_STATE_II_Q: | |
2667 switch (s->next_tx_step) | |
2668 { | |
2669 case T30_MPS: | |
2670 case T30_PRI_MPS: | |
2671 s->retries = 0; | |
2672 if (s->phase_d_handler) | |
2673 s->phase_d_handler(s, s->phase_d_user_data, T30_RTP); | |
2674 /* Send fresh training, and then the next page */ | |
2675 queue_phase(s, T30_PHASE_B_TX); | |
2676 restart_sending_document(s); | |
2677 break; | |
2678 case T30_EOM: | |
2679 case T30_PRI_EOM: | |
2680 s->retries = 0; | |
2681 if (s->phase_d_handler) | |
2682 s->phase_d_handler(s, s->phase_d_user_data, T30_RTP); | |
2683 /* TODO: should go back to T, and resend */ | |
2684 set_state(s, T30_STATE_R); | |
2685 break; | |
2686 case T30_EOP: | |
2687 case T30_PRI_EOP: | |
2688 s->retries = 0; | |
2689 if (s->phase_d_handler) | |
2690 s->phase_d_handler(s, s->phase_d_user_data, T30_RTN); | |
2691 send_dcn(s); | |
2692 break; | |
2693 } | |
2694 break; | |
2695 default: | |
2696 unexpected_final_frame(s, msg, len); | |
2697 break; | |
2698 } | |
2699 } | |
2700 /*- End of function --------------------------------------------------------*/ | |
2701 | |
2702 static void process_rx_rtn(t30_state_t *s, const uint8_t *msg, int len) | |
2703 { | |
2704 /* Retrain negative */ | |
2705 s->short_train = FALSE; | |
2706 switch (s->state) | |
2707 { | |
2708 case T30_STATE_II_Q: | |
2709 switch (s->next_tx_step) | |
2710 { | |
2711 case T30_MPS: | |
2712 case T30_PRI_MPS: | |
2713 s->retries = 0; | |
2714 if (s->phase_d_handler) | |
2715 s->phase_d_handler(s, s->phase_d_user_data, T30_RTN); | |
2716 /* Send fresh training, and then repeat the last page */ | |
2717 queue_phase(s, T30_PHASE_B_TX); | |
2718 restart_sending_document(s); | |
2719 break; | |
2720 case T30_EOM: | |
2721 case T30_PRI_EOM: | |
2722 case T30_EOP: | |
2723 case T30_PRI_EOP: | |
2724 s->retries = 0; | |
2725 if (s->phase_d_handler) | |
2726 s->phase_d_handler(s, s->phase_d_user_data, T30_RTN); | |
2727 send_dcn(s); | |
2728 break; | |
2729 } | |
2730 break; | |
2731 default: | |
2732 unexpected_final_frame(s, msg, len); | |
2733 break; | |
2734 } | |
2735 } | |
2736 /*- End of function --------------------------------------------------------*/ | |
2737 | |
2738 static void process_rx_pip(t30_state_t *s, const uint8_t *msg, int len) | |
2739 { | |
2740 /* Procedure interrupt positive */ | |
2741 switch (s->state) | |
2742 { | |
2743 case T30_STATE_II_Q: | |
2744 case T30_STATE_IV_PPS_Q: | |
2745 case T30_STATE_IV_PPS_RNR: | |
2746 s->retries = 0; | |
2747 if (s->phase_d_handler) | |
2748 { | |
2749 s->phase_d_handler(s, s->phase_d_user_data, T30_PIP); | |
2750 s->timer_t3 = ms_to_samples(DEFAULT_TIMER_T3); | |
2751 } | |
2752 break; | |
2753 default: | |
2754 unexpected_final_frame(s, msg, len); | |
2755 break; | |
2756 } | |
2757 } | |
2758 /*- End of function --------------------------------------------------------*/ | |
2759 | |
2760 static void process_rx_pin(t30_state_t *s, const uint8_t *msg, int len) | |
2761 { | |
2762 /* Procedure interrupt negative */ | |
2763 switch (s->state) | |
2764 { | |
2765 case T30_STATE_II_Q: | |
2766 case T30_STATE_IV_PPS_Q: | |
2767 case T30_STATE_IV_PPS_RNR: | |
2768 case T30_STATE_IV_EOR: | |
2769 case T30_STATE_IV_EOR_RNR: | |
2770 s->retries = 0; | |
2771 if (s->phase_d_handler) | |
2772 { | |
2773 s->phase_d_handler(s, s->phase_d_user_data, T30_PIN); | |
2774 s->timer_t3 = ms_to_samples(DEFAULT_TIMER_T3); | |
2775 } | |
2776 break; | |
2777 default: | |
2778 unexpected_final_frame(s, msg, len); | |
2779 break; | |
2780 } | |
2781 } | |
2782 /*- End of function --------------------------------------------------------*/ | |
2783 | |
2784 static void process_rx_dcn(t30_state_t *s, const uint8_t *msg, int len) | |
2785 { | |
2786 /* Disconnect */ | |
2787 /* TODO: test if this is expected or unexpected */ | |
2788 switch (s->state) | |
2789 { | |
2790 #if 0 | |
2791 case ??????: | |
2792 /* Unexpected DCN while waiting for image data */ | |
2793 s->current_status = T30_ERR_DCNDATARX; | |
2794 break; | |
2795 #endif | |
2796 case T30_STATE_F_POST_DOC_NON_ECM: | |
2797 /* Unexpected DCN while waiting for EOM, EOP or MPS */ | |
2798 s->current_status = T30_ERR_DCNFAXRX; | |
2799 break; | |
2800 case T30_STATE_II_Q: | |
2801 switch (s->next_tx_step) | |
2802 { | |
2803 case T30_MPS: | |
2804 case T30_PRI_MPS: | |
2805 case T30_EOM: | |
2806 case T30_PRI_EOM: | |
2807 /* Unexpected DCN after EOM or MPS sequence */ | |
2808 s->current_status = T30_ERR_DCNPHDRX; | |
2809 break; | |
2810 } | |
2811 break; | |
2812 #if 0 | |
2813 case ??????: | |
2814 /* Unexpected DCN after RR/RNR sequence */ | |
2815 s->current_status = T30_ERR_DCNRRDRX; | |
2816 break; | |
2817 case ??????: | |
2818 /* Unexpected DCN after requested retransmission */ | |
2819 s->current_status = T30_ERR_DCNNORTNRX; | |
2820 break; | |
2821 #endif | |
2822 } | |
2823 /* Time to disconnect */ | |
2824 disconnect(s); | |
2825 } | |
2826 /*- End of function --------------------------------------------------------*/ | |
2827 | |
2828 static void process_rx_crp(t30_state_t *s, const uint8_t *msg, int len) | |
2829 { | |
2830 /* Command repeat */ | |
2831 repeat_last_command(s); | |
2832 } | |
2833 /*- End of function --------------------------------------------------------*/ | |
2834 | |
2835 static void hdlc_accept_control_msg(t30_state_t *s, int ok, const uint8_t *msg, int len) | |
2836 { | |
2837 int final_frame; | |
2838 char far_password[T30_MAX_IDENT_LEN]; | |
2839 | |
2840 final_frame = msg[1] & 0x10; | |
2841 if (!final_frame) | |
2842 { | |
2843 /* Restart the command or response timer, T2 or T4 */ | |
2844 s->timer_t2_t4 = ms_to_samples((s->timer_is_t4) ? DEFAULT_TIMER_T4 : DEFAULT_TIMER_T2); | |
2845 | |
2846 /* The following handles all the message types we expect to get without | |
2847 a final frame tag. If we get one that T.30 says we should not expect | |
2848 in a particular context, its pretty harmless, so don't worry. */ | |
2849 switch (msg[2] & 0xFE) | |
2850 { | |
2851 case T30_CSI: | |
2852 if (msg[2] == T30_CSI) | |
2853 { | |
2854 /* Called subscriber identification */ | |
2855 /* OK in (NSF) (CSI) DIS */ | |
2856 decode_20digit_msg(s, s->far_ident, &msg[2], len - 2); | |
2857 } | |
2858 else | |
2859 { | |
2860 /* CIG - Calling subscriber identification */ | |
2861 /* OK in (NSC) (CIG) DTC */ | |
2862 /* OK in (PWD) (SEP) (CIG) DTC */ | |
2863 decode_20digit_msg(s, s->far_ident, &msg[2], len - 2); | |
2864 } | |
2865 break; | |
2866 case T30_NSF: | |
2867 if (msg[2] == T30_NSF) | |
2868 { | |
2869 /* Non-standard facilities */ | |
2870 /* OK in (NSF) (CSI) DIS */ | |
2871 if (t35_decode(&msg[3], len - 3, &s->country, &s->vendor, &s->model)) | |
2872 { | |
2873 if (s->country) | |
2874 span_log(&s->logging, SPAN_LOG_FLOW, "The remote was made in '%s'\n", s->country); | |
2875 if (s->vendor) | |
2876 span_log(&s->logging, SPAN_LOG_FLOW, "The remote was made by '%s'\n", s->vendor); | |
2877 if (s->model) | |
2878 span_log(&s->logging, SPAN_LOG_FLOW, "The remote is a '%s'\n", s->model); | |
2879 } | |
2880 } | |
2881 else | |
2882 { | |
2883 /* NSC - Non-standard facilities command */ | |
2884 /* OK in (NSC) (CIG) DTC */ | |
2885 } | |
2886 break; | |
2887 case T30_PWD: | |
2888 if (msg[2] == T30_PWD) | |
2889 { | |
2890 /* Password */ | |
2891 /* OK in (PWD) (SUB) (TSI) DCS */ | |
2892 /* OK in (PWD) (SEP) (CIG) DTC */ | |
2893 decode_20digit_msg(s, far_password, &msg[2], len - 2); | |
2894 if (strcmp(s->far_password, far_password) == 0) | |
2895 s->far_password_ok = TRUE; | |
2896 } | |
2897 else | |
2898 { | |
2899 unexpected_frame(s, msg, len); | |
2900 } | |
2901 break; | |
2902 case T30_SEP: | |
2903 if (msg[2] == T30_SEP) | |
2904 { | |
2905 /* Selective polling */ | |
2906 /* OK in (PWD) (SEP) (CIG) DTC */ | |
2907 decode_20digit_msg(s, s->sep_address, &msg[2], len - 2); | |
2908 } | |
2909 else | |
2910 { | |
2911 unexpected_frame(s, msg, len); | |
2912 } | |
2913 break; | |
2914 case T30_PSA: | |
2915 if (msg[2] == T30_PSA) | |
2916 { | |
2917 /* Polled subaddress */ | |
2918 decode_20digit_msg(s, s->psa_address, &msg[2], len - 2); | |
2919 } | |
2920 else | |
2921 { | |
2922 unexpected_frame(s, msg, len); | |
2923 } | |
2924 break; | |
2925 case T30_CIA: | |
2926 if (msg[2] == T30_CIA) | |
2927 { | |
2928 /* Calling subscriber internet address */ | |
2929 decode_url_msg(s, NULL, &msg[2], len - 2); | |
2930 } | |
2931 else | |
2932 { | |
2933 unexpected_frame(s, msg, len); | |
2934 } | |
2935 break; | |
2936 case T30_ISP: | |
2937 if (msg[2] == T30_ISP) | |
2938 { | |
2939 /* Internet selective polling address */ | |
2940 decode_url_msg(s, NULL, &msg[2], len - 2); | |
2941 } | |
2942 else | |
2943 { | |
2944 unexpected_frame(s, msg, len); | |
2945 } | |
2946 break; | |
2947 case T30_TSI: | |
2948 /* Transmitting subscriber identity */ | |
2949 /* OK in (TSI) DCS */ | |
2950 /* OK in (PWD) (SUB) (TSI) DCS */ | |
2951 decode_20digit_msg(s, s->far_ident, &msg[2], len - 2); | |
2952 break; | |
2953 case T30_SUB: | |
2954 /* Subaddress */ | |
2955 /* OK in (PWD) (SUB) (TSI) DCS */ | |
2956 decode_20digit_msg(s, s->far_sub_address, &msg[2], len - 2); | |
2957 break; | |
2958 case T30_SID: | |
2959 /* Sender Identification */ | |
2960 /* T.30 does not say where this is OK */ | |
2961 decode_20digit_msg(s, NULL, &msg[2], len - 2); | |
2962 break; | |
2963 case T30_CSA: | |
2964 /* Calling subscriber internet address */ | |
2965 decode_url_msg(s, NULL, &msg[2], len - 2); | |
2966 break; | |
2967 case T30_TSA: | |
2968 /* Transmitting subscriber internet address */ | |
2969 decode_url_msg(s, NULL, &msg[2], len - 2); | |
2970 break; | |
2971 case T30_IRA: | |
2972 /* Internet routing address */ | |
2973 decode_url_msg(s, NULL, &msg[2], len - 2); | |
2974 break; | |
2975 case T4_FCD: | |
2976 process_rx_fcd(s, msg, len); | |
2977 break; | |
2978 case T4_RCP: | |
2979 process_rx_rcp(s, msg, len); | |
2980 break; | |
2981 default: | |
2982 span_log(&s->logging, SPAN_LOG_FLOW, "Unexpected %s frame\n", t30_frametype(msg[2])); | |
2983 break; | |
2984 } | |
2985 } | |
2986 else | |
2987 { | |
2988 /* Once we have any successful message from the far end, we | |
2989 cancel timer T1 */ | |
2990 s->timer_t0_t1 = 0; | |
2991 | |
2992 /* The following handles context sensitive message types, which should | |
2993 occur at the end of message sequences. They should, therefore have | |
2994 the final frame flag set. */ | |
2995 span_log(&s->logging, SPAN_LOG_FLOW, "In state %d\n", s->state); | |
2996 switch (msg[2] & 0xFE) | |
2997 { | |
2998 case T30_DIS: | |
2999 process_rx_dis_or_dtc(s, msg, len); | |
3000 break; | |
3001 case T30_DCS: | |
3002 process_rx_dcs(s, msg, len); | |
3003 break; | |
3004 case T30_NSS: | |
3005 process_rx_nss(s, msg, len); | |
3006 break; | |
3007 case T30_CTC: | |
3008 process_rx_ctc(s, msg, len); | |
3009 break; | |
3010 case T30_CFR: | |
3011 process_rx_cfr(s, msg, len); | |
3012 break; | |
3013 case T30_FTT: | |
3014 process_rx_ftt(s, msg, len); | |
3015 break; | |
3016 case T30_CTR: | |
3017 process_rx_ctr(s, msg, len); | |
3018 break; | |
3019 case T30_EOM: | |
3020 process_rx_eom(s, msg, len); | |
3021 break; | |
3022 case T30_MPS: | |
3023 process_rx_mps(s, msg, len); | |
3024 break; | |
3025 case T30_EOP: | |
3026 process_rx_eop(s, msg, len); | |
3027 break; | |
3028 case T30_PRI_EOM: | |
3029 process_rx_pri_eom(s, msg, len); | |
3030 break; | |
3031 case T30_PRI_MPS: | |
3032 process_rx_pri_mps(s, msg, len); | |
3033 break; | |
3034 case T30_PRI_EOP: | |
3035 process_rx_pri_eop(s, msg, len); | |
3036 break; | |
3037 case T30_EOS: | |
3038 process_rx_eos(s, msg, len); | |
3039 break; | |
3040 case T30_PPS: | |
3041 process_rx_pps(s, msg, len); | |
3042 break; | |
3043 case T30_EOR: | |
3044 process_rx_eor(s, msg, len); | |
3045 break; | |
3046 case T30_RR: | |
3047 process_rx_rr(s, msg, len); | |
3048 break; | |
3049 case T30_MCF: | |
3050 process_rx_mcf(s, msg, len); | |
3051 break; | |
3052 case T30_RTP: | |
3053 process_rx_rtp(s, msg, len); | |
3054 break; | |
3055 case T30_RTN: | |
3056 process_rx_rtn(s, msg, len); | |
3057 break; | |
3058 case T30_PIP: | |
3059 process_rx_pip(s, msg, len); | |
3060 break; | |
3061 case T30_PIN: | |
3062 process_rx_pin(s, msg, len); | |
3063 break; | |
3064 case T30_PPR: | |
3065 process_rx_ppr(s, msg, len); | |
3066 break; | |
3067 case T30_RNR: | |
3068 process_rx_rnr(s, msg, len); | |
3069 break; | |
3070 case T30_ERR: | |
3071 process_rx_err(s, msg, len); | |
3072 break; | |
3073 case T30_FDM: | |
3074 process_rx_fdm(s, msg, len); | |
3075 break; | |
3076 case T30_DCN: | |
3077 process_rx_dcn(s, msg, len); | |
3078 break; | |
3079 case T30_CRP: | |
3080 process_rx_crp(s, msg, len); | |
3081 break; | |
3082 case T30_FNV: | |
3083 process_rx_fnv(s, msg, len); | |
3084 break; | |
3085 case T30_TNR: | |
3086 process_rx_tnr(s, msg, len); | |
3087 break; | |
3088 case T30_TR: | |
3089 process_rx_tr(s, msg, len); | |
3090 break; | |
3091 case T4_RCP: | |
3092 process_rx_rcp(s, msg, len); | |
3093 break; | |
3094 default: | |
3095 /* We don't know what to do with this. */ | |
3096 unexpected_final_frame(s, msg, len); | |
3097 break; | |
3098 } | |
3099 } | |
3100 } | |
3101 /*- End of function --------------------------------------------------------*/ | |
3102 | |
3103 void t30_hdlc_accept(void *user_data, int ok, const uint8_t *msg, int len) | |
3104 { | |
3105 t30_state_t *s; | |
3106 | |
3107 s = (t30_state_t *) user_data; | |
3108 if (len < 0) | |
3109 { | |
3110 /* Special conditions */ | |
3111 switch (len) | |
3112 { | |
3113 case PUTBIT_TRAINING_FAILED: | |
3114 span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier training failed in state %d\n", s->state); | |
3115 s->rx_trained = FALSE; | |
3116 /* Cancel the timer, since we have actually seen something, and wait until the carrier drops | |
3117 before proceeding. */ | |
3118 // TODO: this is not a complete answer to handling failures to train | |
3119 s->timer_t2_t4 = 0; | |
3120 break; | |
3121 case PUTBIT_TRAINING_SUCCEEDED: | |
3122 /* The modem is now trained */ | |
3123 span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier trained in state %d\n", s->state); | |
3124 s->rx_signal_present = TRUE; | |
3125 s->rx_trained = TRUE; | |
3126 break; | |
3127 case PUTBIT_CARRIER_UP: | |
3128 span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier up in state %d\n", s->state); | |
3129 s->rx_signal_present = TRUE; | |
3130 break; | |
3131 case PUTBIT_CARRIER_DOWN: | |
3132 span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier down in state %d\n", s->state); | |
3133 s->rx_signal_present = FALSE; | |
3134 s->rx_trained = FALSE; | |
3135 /* If a phase change has been queued to occur after the receive signal drops, | |
3136 its time to change. */ | |
3137 if (s->next_phase != T30_PHASE_IDLE) | |
3138 { | |
3139 set_phase(s, s->next_phase); | |
3140 s->next_phase = T30_PHASE_IDLE; | |
3141 } | |
3142 break; | |
3143 case PUTBIT_FRAMING_OK: | |
3144 span_log(&s->logging, SPAN_LOG_FLOW, "HDLC framing OK in state %d\n", s->state); | |
3145 if (!s->far_end_detected && s->timer_t0_t1 > 0) | |
3146 { | |
3147 s->timer_t0_t1 = ms_to_samples(DEFAULT_TIMER_T1); | |
3148 s->far_end_detected = TRUE; | |
3149 if (s->phase == T30_PHASE_A_CED || s->phase == T30_PHASE_A_CNG) | |
3150 set_phase(s, T30_PHASE_B_RX); | |
3151 } | |
3152 /* 5.4.3.1 Timer T2 is reset if flag is received */ | |
3153 if (!s->timer_is_t4 && s->timer_t2_t4 > 0) | |
3154 s->timer_t2_t4 = 0; | |
3155 break; | |
3156 case PUTBIT_ABORT: | |
3157 /* Just ignore these */ | |
3158 break; | |
3159 default: | |
3160 span_log(&s->logging, SPAN_LOG_FLOW, "Unexpected HDLC special length - %d!\n", len); | |
3161 break; | |
3162 } | |
3163 return; | |
3164 } | |
3165 | |
3166 /* The spec. says a command or response is not valid if: | |
3167 - any of the frames, optional or mandatory, have an FCS error. | |
3168 - any single frame exceeds 3s +- 15% (i.e. no frame should exceed 2.55s) | |
3169 - the final frame is not tagged as a final frame | |
3170 - the final frame is not a recognised one. | |
3171 The first point seems benign. If we accept an optional frame, and a later | |
3172 frame is bad, having accepted the optional frame should be harmless. | |
3173 The 2.55s maximum seems to limit signalling frames to no more than 95 octets, | |
3174 including FCS, and flag octets (assuming the use of V.21). | |
3175 */ | |
3176 if (!ok) | |
3177 { | |
3178 span_log(&s->logging, SPAN_LOG_FLOW, "Bad CRC received\n"); | |
3179 if (s->crp_enabled) | |
3180 send_simple_frame(s, T30_CRP); | |
3181 return; | |
3182 } | |
3183 | |
3184 /* Cancel the command or response timer */ | |
3185 s->timer_t2_t4 = 0; | |
3186 if (len < 3) | |
3187 { | |
3188 span_log(&s->logging, SPAN_LOG_FLOW, "Bad HDLC frame length - %d\n", len); | |
3189 return; | |
3190 } | |
3191 if (msg[0] != 0xFF || !(msg[1] == 0x03 || msg[1] == 0x13)) | |
3192 { | |
3193 span_log(&s->logging, SPAN_LOG_FLOW, "Bad HDLC frame header - %02x %02x\n", msg[0], msg[1]); | |
3194 return; | |
3195 } | |
3196 print_frame(s, "Rx: ", msg, len); | |
3197 | |
3198 switch (s->phase) | |
3199 { | |
3200 case T30_PHASE_A_CED: | |
3201 case T30_PHASE_A_CNG: | |
3202 case T30_PHASE_B_RX: | |
3203 case T30_PHASE_C_ECM_RX: | |
3204 case T30_PHASE_D_RX: | |
3205 break; | |
3206 default: | |
3207 span_log(&s->logging, SPAN_LOG_FLOW, "Unexpected HDLC frame received in phase %s, state %d\n", phase_names[s->phase], s->state); | |
3208 break; | |
3209 } | |
3210 hdlc_accept_control_msg(s, ok, msg, len); | |
3211 } | |
3212 /*- End of function --------------------------------------------------------*/ | |
3213 | |
3214 static void queue_phase(t30_state_t *s, int phase) | |
3215 { | |
3216 if (s->rx_signal_present) | |
3217 { | |
3218 /* We need to wait for that signal to go away */ | |
3219 s->next_phase = phase; | |
3220 } | |
3221 else | |
3222 { | |
3223 set_phase(s, phase); | |
3224 s->next_phase = T30_PHASE_IDLE; | |
3225 } | |
3226 } | |
3227 /*- End of function --------------------------------------------------------*/ | |
3228 | |
3229 static void set_phase(t30_state_t *s, int phase) | |
3230 { | |
3231 if (phase != s->phase) | |
3232 { | |
3233 span_log(&s->logging, SPAN_LOG_FLOW, "Changing from phase %s to %s\n", phase_names[s->phase], phase_names[phase]); | |
3234 /* We may be killing a receiver before it has declared the end of the | |
3235 signal. Force the signal present indicator to off, because the | |
3236 receiver will never be able to. */ | |
3237 if (s->phase != T30_PHASE_A_CED && s->phase != T30_PHASE_A_CNG) | |
3238 s->rx_signal_present = FALSE; | |
3239 s->rx_trained = FALSE; | |
3240 s->phase = phase; | |
3241 switch (phase) | |
3242 { | |
3243 case T30_PHASE_A_CED: | |
3244 if (s->set_rx_type_handler) | |
3245 s->set_rx_type_handler(s->set_rx_type_user_data, T30_MODEM_V21, FALSE, TRUE); | |
3246 if (s->set_tx_type_handler) | |
3247 s->set_tx_type_handler(s->set_tx_type_user_data, T30_MODEM_CED, FALSE, FALSE); | |
3248 break; | |
3249 case T30_PHASE_A_CNG: | |
3250 if (s->set_rx_type_handler) | |
3251 s->set_rx_type_handler(s->set_rx_type_user_data, T30_MODEM_V21, FALSE, TRUE); | |
3252 if (s->set_tx_type_handler) | |
3253 s->set_tx_type_handler(s->set_tx_type_user_data, T30_MODEM_CNG, FALSE, FALSE); | |
3254 break; | |
3255 case T30_PHASE_B_RX: | |
3256 case T30_PHASE_D_RX: | |
3257 if (s->set_rx_type_handler) | |
3258 s->set_rx_type_handler(s->set_rx_type_user_data, T30_MODEM_V21, FALSE, TRUE); | |
3259 if (s->set_tx_type_handler) | |
3260 s->set_tx_type_handler(s->set_tx_type_user_data, T30_MODEM_NONE, FALSE, FALSE); | |
3261 break; | |
3262 case T30_PHASE_B_TX: | |
3263 case T30_PHASE_D_TX: | |
3264 if (!s->far_end_detected && s->timer_t0_t1 > 0) | |
3265 { | |
3266 s->timer_t0_t1 = ms_to_samples(DEFAULT_TIMER_T1); | |
3267 s->far_end_detected = TRUE; | |
3268 } | |
3269 if (s->set_rx_type_handler) | |
3270 s->set_rx_type_handler(s->set_rx_type_user_data, T30_MODEM_NONE, FALSE, FALSE); | |
3271 if (s->set_tx_type_handler) | |
3272 s->set_tx_type_handler(s->set_tx_type_user_data, T30_MODEM_V21, FALSE, TRUE); | |
3273 break; | |
3274 case T30_PHASE_C_NON_ECM_RX: | |
3275 s->timer_t2_t4 = ms_to_samples(DEFAULT_TIMER_T2); | |
3276 s->timer_is_t4 = FALSE; | |
3277 if (s->set_rx_type_handler) | |
3278 s->set_rx_type_handler(s->set_rx_type_user_data, fallback_sequence[s->current_fallback].modem_type, s->short_train, FALSE); | |
3279 if (s->set_tx_type_handler) | |
3280 s->set_tx_type_handler(s->set_tx_type_user_data, T30_MODEM_NONE, FALSE, FALSE); | |
3281 break; | |
3282 case T30_PHASE_C_NON_ECM_TX: | |
3283 /* Pause before switching from anything to phase C */ | |
3284 /* Always prime the training count for 1.5s of data at the current rate. Its harmless if | |
3285 we prime it and are not doing TCF. */ | |
3286 s->training_test_bits = (3*fallback_sequence[s->current_fallback].bit_rate)/2; | |
3287 if (s->set_rx_type_handler) | |
3288 s->set_rx_type_handler(s->set_rx_type_user_data, T30_MODEM_NONE, FALSE, FALSE); | |
3289 if (s->set_tx_type_handler) | |
3290 s->set_tx_type_handler(s->set_tx_type_user_data, fallback_sequence[s->current_fallback].modem_type, s->short_train, FALSE); | |
3291 break; | |
3292 case T30_PHASE_C_ECM_RX: | |
3293 s->timer_t2_t4 = ms_to_samples(DEFAULT_TIMER_T2); | |
3294 s->timer_is_t4 = FALSE; | |
3295 if (s->set_rx_type_handler) | |
3296 s->set_rx_type_handler(s->set_rx_type_user_data, fallback_sequence[s->current_fallback].modem_type, s->short_train, TRUE); | |
3297 if (s->set_tx_type_handler) | |
3298 s->set_tx_type_handler(s->set_tx_type_user_data, T30_MODEM_NONE, FALSE, FALSE); | |
3299 break; | |
3300 case T30_PHASE_C_ECM_TX: | |
3301 /* Pause before switching from anything to phase C */ | |
3302 if (s->set_rx_type_handler) | |
3303 s->set_rx_type_handler(s->set_rx_type_user_data, T30_MODEM_NONE, FALSE, FALSE); | |
3304 if (s->set_tx_type_handler) | |
3305 s->set_tx_type_handler(s->set_tx_type_user_data, fallback_sequence[s->current_fallback].modem_type, s->short_train, TRUE); | |
3306 break; | |
3307 case T30_PHASE_E: | |
3308 /* Send a little silence before ending things, to ensure the | |
3309 buffers are all flushed through, and the far end has seen | |
3310 the last message we sent. */ | |
3311 s->training_current_zeros = 0; | |
3312 s->training_most_zeros = 0; | |
3313 if (s->set_rx_type_handler) | |
3314 s->set_rx_type_handler(s->set_rx_type_user_data, T30_MODEM_NONE, FALSE, FALSE); | |
3315 if (s->set_tx_type_handler) | |
3316 s->set_tx_type_handler(s->set_tx_type_user_data, T30_MODEM_PAUSE, 200, FALSE); | |
3317 break; | |
3318 case T30_PHASE_CALL_FINISHED: | |
3319 if (s->set_rx_type_handler) | |
3320 s->set_rx_type_handler(s->set_rx_type_user_data, T30_MODEM_DONE, FALSE, FALSE); | |
3321 if (s->set_tx_type_handler) | |
3322 s->set_tx_type_handler(s->set_tx_type_user_data, T30_MODEM_DONE, FALSE, FALSE); | |
3323 break; | |
3324 } | |
3325 } | |
3326 } | |
3327 /*- End of function --------------------------------------------------------*/ | |
3328 | |
3329 static void set_state(t30_state_t *s, int state) | |
3330 { | |
3331 if (s->state != state) | |
3332 { | |
3333 span_log(&s->logging, SPAN_LOG_FLOW, "Changing from state %d to %d\n", s->state, state); | |
3334 s->state = state; | |
3335 s->step = 0; | |
3336 } | |
3337 } | |
3338 /*- End of function --------------------------------------------------------*/ | |
3339 | |
3340 void t30_receive_complete(void *user_data) | |
3341 { | |
3342 t30_state_t *s; | |
3343 | |
3344 s = (t30_state_t *) user_data; | |
3345 | |
3346 span_log(&s->logging, SPAN_LOG_FLOW, "Receive complete in phase %s, state %d\n", phase_names[s->phase], s->state); | |
3347 /* Usually receive complete is notified by a carrier down signal. However, | |
3348 in cases like a T.38 packet stream dying in the middle of reception | |
3349 there needs to be a means to stop things. */ | |
3350 if (s->phase == T30_PHASE_C_NON_ECM_RX) | |
3351 t30_non_ecm_put_bit(s, PUTBIT_CARRIER_DOWN); | |
3352 else | |
3353 t30_hdlc_accept(s, TRUE, NULL, PUTBIT_CARRIER_DOWN); | |
3354 } | |
3355 /*- End of function --------------------------------------------------------*/ | |
3356 | |
3357 void t30_send_complete(void *user_data) | |
3358 { | |
3359 t30_state_t *s; | |
3360 | |
3361 s = (t30_state_t *) user_data; | |
3362 | |
3363 span_log(&s->logging, SPAN_LOG_FLOW, "Send complete in phase %s, state %d\n", phase_names[s->phase], s->state); | |
3364 /* We have finished sending our messages, so move on to the next operation. */ | |
3365 switch (s->state) | |
3366 { | |
3367 case T30_STATE_ANSWERING: | |
3368 span_log(&s->logging, SPAN_LOG_FLOW, "Starting answer mode\n"); | |
3369 set_phase(s, T30_PHASE_B_TX); | |
3370 s->timer_t2_t4 = ms_to_samples(DEFAULT_TIMER_T2); | |
3371 s->timer_is_t4 = FALSE; | |
3372 set_state(s, T30_STATE_R); | |
3373 s->dis_received = FALSE; | |
3374 send_dis_or_dtc_sequence(s); | |
3375 break; | |
3376 case T30_STATE_R: | |
3377 switch (s->step) | |
3378 { | |
3379 case 0: | |
3380 s->step++; | |
3381 if (send_ident_frame(s, T30_CSI)) | |
3382 break; | |
3383 /* Fall through */ | |
3384 case 1: | |
3385 s->step++; | |
3386 set_dis_or_dtc(s); | |
3387 send_frame(s, s->dis_dtc_frame, s->dis_dtc_len); | |
3388 break; | |
3389 case 2: | |
3390 s->step++; | |
3391 if (s->send_hdlc_handler) | |
3392 s->send_hdlc_handler(s->send_hdlc_user_data, NULL, 0); | |
3393 break; | |
3394 default: | |
3395 /* Wait for an acknowledgement. */ | |
3396 set_phase(s, T30_PHASE_B_RX); | |
3397 s->timer_t2_t4 = ms_to_samples(DEFAULT_TIMER_T4); | |
3398 s->timer_is_t4 = TRUE; | |
3399 break; | |
3400 } | |
3401 break; | |
3402 case T30_STATE_F_CFR: | |
3403 if (s->step == 0) | |
3404 { | |
3405 if (s->send_hdlc_handler) | |
3406 s->send_hdlc_handler(s->send_hdlc_user_data, NULL, 0); | |
3407 s->step++; | |
3408 } | |
3409 else | |
3410 { | |
3411 set_state(s, T30_STATE_F_DOC); | |
3412 set_phase(s, (s->error_correcting_mode) ? T30_PHASE_C_ECM_RX : T30_PHASE_C_NON_ECM_RX); | |
3413 s->next_rx_step = T30_MPS; | |
3414 } | |
3415 break; | |
3416 case T30_STATE_F_FTT: | |
3417 if (s->step == 0) | |
3418 { | |
3419 if (s->send_hdlc_handler) | |
3420 s->send_hdlc_handler(s->send_hdlc_user_data, NULL, 0); | |
3421 s->step++; | |
3422 } | |
3423 else | |
3424 { | |
3425 set_phase(s, T30_PHASE_B_RX); | |
3426 s->timer_t2_t4 = ms_to_samples(DEFAULT_TIMER_T4); | |
3427 s->timer_is_t4 = TRUE; | |
3428 } | |
3429 break; | |
3430 case T30_STATE_III_Q_MCF: | |
3431 case T30_STATE_III_Q_RTP: | |
3432 case T30_STATE_III_Q_RTN: | |
3433 case T30_STATE_F_POST_RCP_PPR: | |
3434 case T30_STATE_F_POST_RCP_MCF: | |
3435 if (s->step == 0) | |
3436 { | |
3437 if (s->send_hdlc_handler) | |
3438 s->send_hdlc_handler(s->send_hdlc_user_data, NULL, 0); | |
3439 s->step++; | |
3440 } | |
3441 else | |
3442 { | |
3443 switch (s->next_rx_step) | |
3444 { | |
3445 case T30_MPS: | |
3446 case T30_PRI_MPS: | |
3447 set_state(s, T30_STATE_F_DOC); | |
3448 set_phase(s, (s->error_correcting_mode) ? T30_PHASE_C_ECM_RX : T30_PHASE_C_NON_ECM_RX); | |
3449 break; | |
3450 case T30_EOM: | |
3451 case T30_PRI_EOM: | |
3452 /* TODO: */ | |
3453 disconnect(s); | |
3454 break; | |
3455 case T30_EOP: | |
3456 case T30_PRI_EOP: | |
3457 disconnect(s); | |
3458 break; | |
3459 default: | |
3460 span_log(&s->logging, SPAN_LOG_FLOW, "Unknown next rx step - %d\n", s->next_rx_step); | |
3461 disconnect(s); | |
3462 break; | |
3463 } | |
3464 } | |
3465 break; | |
3466 case T30_STATE_II_Q: | |
3467 case T30_STATE_IV_PPS_NULL: | |
3468 case T30_STATE_IV_PPS_Q: | |
3469 if (s->step == 0) | |
3470 { | |
3471 if (s->send_hdlc_handler) | |
3472 s->send_hdlc_handler(s->send_hdlc_user_data, NULL, 0); | |
3473 s->step++; | |
3474 } | |
3475 else | |
3476 { | |
3477 /* We have finished sending the post image message. Wait for an | |
3478 acknowledgement. */ | |
3479 set_phase(s, T30_PHASE_D_RX); | |
3480 s->timer_t2_t4 = ms_to_samples(DEFAULT_TIMER_T4); | |
3481 s->timer_is_t4 = TRUE; | |
3482 } | |
3483 break; | |
3484 case T30_STATE_B: | |
3485 /* We have now allowed time for the last message to flush | |
3486 through the system, so it is safe to report the end of the | |
3487 call. */ | |
3488 if (s->phase_e_handler) | |
3489 s->phase_e_handler(s, s->phase_e_user_data, s->current_status); | |
3490 set_state(s, T30_STATE_CALL_FINISHED); | |
3491 set_phase(s, T30_PHASE_CALL_FINISHED); | |
3492 break; | |
3493 case T30_STATE_C: | |
3494 if (s->step == 0) | |
3495 { | |
3496 if (s->send_hdlc_handler) | |
3497 s->send_hdlc_handler(s->send_hdlc_user_data, NULL, 0); | |
3498 s->step++; | |
3499 } | |
3500 else | |
3501 { | |
3502 /* We just sent the disconnect message. Now it is time to disconnect */ | |
3503 disconnect(s); | |
3504 } | |
3505 break; | |
3506 case T30_STATE_D: | |
3507 switch (s->step) | |
3508 { | |
3509 case 0: | |
3510 s->step++; | |
3511 if (send_sub_frame(s)) | |
3512 break; | |
3513 /* Fall through */ | |
3514 case 1: | |
3515 s->step++; | |
3516 if (send_ident_frame(s, T30_TSI)) | |
3517 break; | |
3518 /* Fall through */ | |
3519 case 2: | |
3520 s->step++; | |
3521 send_frame(s, s->dcs_frame, s->dcs_len); | |
3522 break; | |
3523 case 3: | |
3524 s->step++; | |
3525 if (s->send_hdlc_handler) | |
3526 s->send_hdlc_handler(s->send_hdlc_user_data, NULL, 0); | |
3527 break; | |
3528 default: | |
3529 if ((s->iaf & T30_IAF_MODE_NO_TCF)) | |
3530 { | |
3531 /* Skip the trainability test */ | |
3532 s->retries = 0; | |
3533 s->short_train = TRUE; | |
3534 if (s->error_correcting_mode) | |
3535 { | |
3536 set_state(s, T30_STATE_IV); | |
3537 queue_phase(s, T30_PHASE_C_ECM_TX); | |
3538 } | |
3539 else | |
3540 { | |
3541 set_state(s, T30_STATE_I); | |
3542 queue_phase(s, T30_PHASE_C_NON_ECM_TX); | |
3543 } | |
3544 } | |
3545 else | |
3546 { | |
3547 /* Do the trainability test */ | |
3548 set_state(s, T30_STATE_D_TCF); | |
3549 set_phase(s, T30_PHASE_C_NON_ECM_TX); | |
3550 } | |
3551 break; | |
3552 } | |
3553 break; | |
3554 case T30_STATE_D_TCF: | |
3555 /* Finished sending training test. Listen for the response. */ | |
3556 set_phase(s, T30_PHASE_B_RX); | |
3557 s->timer_t2_t4 = ms_to_samples(DEFAULT_TIMER_T4); | |
3558 s->timer_is_t4 = TRUE; | |
3559 set_state(s, T30_STATE_D_POST_TCF); | |
3560 break; | |
3561 case T30_STATE_I: | |
3562 /* Send the end of page message */ | |
3563 set_phase(s, T30_PHASE_D_TX); | |
3564 set_state(s, T30_STATE_II_Q); | |
3565 /* We might need to resend the page we are on, but we need to check if there | |
3566 are any more pages to send, so we can send the correct signal right now. */ | |
3567 send_simple_frame(s, s->next_tx_step = check_next_tx_step(s)); | |
3568 break; | |
3569 case T30_STATE_IV: | |
3570 /* We have finished sending an FCD frame */ | |
3571 if (s->step == 0) | |
3572 { | |
3573 if (send_next_ecm_frame(s)) | |
3574 { | |
3575 if (s->send_hdlc_handler) | |
3576 s->send_hdlc_handler(s->send_hdlc_user_data, NULL, 0); | |
3577 s->step++; | |
3578 } | |
3579 } | |
3580 else | |
3581 { | |
3582 /* Send the end of page or partial page message */ | |
3583 set_phase(s, T30_PHASE_D_TX); | |
3584 s->next_tx_step = check_next_tx_step(s); | |
3585 if (send_pps_frame(s) == T30_NULL) | |
3586 set_state(s, T30_STATE_IV_PPS_NULL); | |
3587 else | |
3588 set_state(s, T30_STATE_IV_PPS_Q); | |
3589 } | |
3590 break; | |
3591 case T30_STATE_CALL_FINISHED: | |
3592 /* Just ignore anything that happens now. We might get here if a premature | |
3593 disconnect from the far end overlaps something. */ | |
3594 break; | |
3595 default: | |
3596 span_log(&s->logging, SPAN_LOG_FLOW, "Bad state in t30_send_complete - %d\n", s->state); | |
3597 break; | |
3598 } | |
3599 } | |
3600 /*- End of function --------------------------------------------------------*/ | |
3601 | |
3602 static void repeat_last_command(t30_state_t *s) | |
3603 { | |
3604 switch (s->state) | |
3605 { | |
3606 case T30_STATE_R: | |
3607 set_phase(s, T30_PHASE_B_TX); | |
3608 s->dis_received = FALSE; | |
3609 send_dis_or_dtc_sequence(s); | |
3610 break; | |
3611 case T30_STATE_III_Q_MCF: | |
3612 set_phase(s, T30_PHASE_D_TX); | |
3613 send_simple_frame(s, T30_MCF); | |
3614 break; | |
3615 case T30_STATE_III_Q_RTP: | |
3616 set_phase(s, T30_PHASE_D_TX); | |
3617 send_simple_frame(s, T30_RTP); | |
3618 break; | |
3619 case T30_STATE_III_Q_RTN: | |
3620 set_phase(s, T30_PHASE_D_TX); | |
3621 send_simple_frame(s, T30_RTN); | |
3622 break; | |
3623 case T30_STATE_II_Q: | |
3624 set_phase(s, T30_PHASE_D_TX); | |
3625 send_simple_frame(s, s->next_tx_step); | |
3626 break; | |
3627 case T30_STATE_IV_PPS_NULL: | |
3628 case T30_STATE_IV_PPS_Q: | |
3629 set_phase(s, T30_PHASE_D_TX); | |
3630 send_pps_frame(s); | |
3631 break; | |
3632 case T30_STATE_IV_PPS_RNR: | |
3633 case T30_STATE_IV_EOR_RNR: | |
3634 set_phase(s, T30_PHASE_D_TX); | |
3635 send_simple_frame(s, T30_RNR); | |
3636 break; | |
3637 case T30_STATE_D: | |
3638 send_dcs_sequence(s); | |
3639 break; | |
3640 case T30_STATE_F_FTT: | |
3641 set_phase(s, T30_PHASE_B_TX); | |
3642 send_simple_frame(s, T30_FTT); | |
3643 break; | |
3644 case T30_STATE_F_CFR: | |
3645 set_phase(s, T30_PHASE_B_TX); | |
3646 send_simple_frame(s, T30_CFR); | |
3647 break; | |
3648 default: | |
3649 span_log(&s->logging, SPAN_LOG_FLOW, "Repeat command called with nothing to repeat - phase %s, state %d\n", phase_names[s->phase], s->state); | |
3650 break; | |
3651 } | |
3652 } | |
3653 /*- End of function --------------------------------------------------------*/ | |
3654 | |
3655 static void timer_t0_expired(t30_state_t *s) | |
3656 { | |
3657 span_log(&s->logging, SPAN_LOG_FLOW, "T0 timeout in state %d\n", s->state); | |
3658 s->current_status = T30_ERR_T0EXPIRED; | |
3659 /* Just end the call */ | |
3660 disconnect(s); | |
3661 } | |
3662 /*- End of function --------------------------------------------------------*/ | |
3663 | |
3664 static void timer_t1_expired(t30_state_t *s) | |
3665 { | |
3666 span_log(&s->logging, SPAN_LOG_FLOW, "T1 timeout in state %d\n", s->state); | |
3667 /* The initial connection establishment has timeout out. In other words, we | |
3668 have been unable to communicate successfully with a remote machine. | |
3669 It is time to abandon the call. */ | |
3670 s->current_status = T30_ERR_T1EXPIRED; | |
3671 switch (s->state) | |
3672 { | |
3673 case T30_STATE_T: | |
3674 /* Just end the call */ | |
3675 disconnect(s); | |
3676 break; | |
3677 case T30_STATE_R: | |
3678 /* Send disconnect, and then end the call. Since we have not | |
3679 successfully contacted the far end, it is unclear why we should | |
3680 send a disconnect message at this point. However, it is what T.30 | |
3681 says we should do. */ | |
3682 send_dcn(s); | |
3683 break; | |
3684 } | |
3685 } | |
3686 /*- End of function --------------------------------------------------------*/ | |
3687 | |
3688 static void timer_t2_expired(t30_state_t *s) | |
3689 { | |
3690 span_log(&s->logging, SPAN_LOG_FLOW, "T2 timeout in phase %s, state %d\n", phase_names[s->phase], s->state); | |
3691 switch (s->state) | |
3692 { | |
3693 case T30_STATE_F_DOC: | |
3694 /* While waiting for FAX page */ | |
3695 s->current_status = T30_ERR_T2EXPFAXRX; | |
3696 break; | |
3697 case T30_STATE_F_POST_DOC_NON_ECM: | |
3698 /* While waiting for next FAX page */ | |
3699 s->current_status = T30_ERR_T2EXPMPSRX; | |
3700 break; | |
3701 #if 0 | |
3702 case ??????: | |
3703 /* While waiting for DCN */ | |
3704 s->current_status = T30_ERR_T2EXPDCNRX; | |
3705 break; | |
3706 case ??????: | |
3707 /* While waiting for phase D */ | |
3708 s->current_status = T30_ERR_T2EXPDRX; | |
3709 break; | |
3710 #endif | |
3711 case T30_STATE_IV_PPS_RNR: | |
3712 case T30_STATE_IV_EOR_RNR: | |
3713 /* While waiting for RR command */ | |
3714 s->current_status = T30_ERR_T2EXPRRRX; | |
3715 break; | |
3716 case T30_STATE_R: | |
3717 /* While waiting for NSS, DCS or MCF */ | |
3718 s->current_status = T30_ERR_T2EXPRX; | |
3719 break; | |
3720 } | |
3721 set_phase(s, T30_PHASE_B_TX); | |
3722 start_receiving_document(s); | |
3723 } | |
3724 /*- End of function --------------------------------------------------------*/ | |
3725 | |
3726 static void timer_t3_expired(t30_state_t *s) | |
3727 { | |
3728 span_log(&s->logging, SPAN_LOG_FLOW, "T3 timeout in phase %s, state %d\n", phase_names[s->phase], s->state); | |
3729 s->current_status = T30_ERR_T3EXPIRED; | |
3730 disconnect(s); | |
3731 } | |
3732 /*- End of function --------------------------------------------------------*/ | |
3733 | |
3734 static void timer_t4_expired(t30_state_t *s) | |
3735 { | |
3736 /* There was no response (or only a corrupt response) to a command */ | |
3737 span_log(&s->logging, SPAN_LOG_FLOW, "T4 timeout in phase %s, state %d\n", phase_names[s->phase], s->state); | |
3738 if (++s->retries > MAX_MESSAGE_TRIES) | |
3739 { | |
3740 s->current_status = T30_ERR_RETRYDCN; | |
3741 send_dcn(s); | |
3742 return; | |
3743 } | |
3744 repeat_last_command(s); | |
3745 } | |
3746 /*- End of function --------------------------------------------------------*/ | |
3747 | |
3748 static void timer_t5_expired(t30_state_t *s) | |
3749 { | |
3750 /* Give up waiting for the receiver to become ready in error correction mode */ | |
3751 send_dcn(s); | |
3752 } | |
3753 /*- End of function --------------------------------------------------------*/ | |
3754 | |
3755 void t30_timer_update(t30_state_t *s, int samples) | |
3756 { | |
3757 if (s->timer_t0_t1 > 0) | |
3758 { | |
3759 s->timer_t0_t1 -= samples; | |
3760 if (s->timer_t0_t1 <= 0) | |
3761 { | |
3762 if (s->far_end_detected) | |
3763 timer_t1_expired(s); | |
3764 else | |
3765 timer_t0_expired(s); | |
3766 } | |
3767 } | |
3768 if (s->timer_t3 > 0) | |
3769 { | |
3770 s->timer_t3 -= samples; | |
3771 if (s->timer_t3 <= 0) | |
3772 timer_t3_expired(s); | |
3773 } | |
3774 if (s->timer_t2_t4 > 0) | |
3775 { | |
3776 s->timer_t2_t4 -= samples; | |
3777 if (s->timer_t2_t4 <= 0) | |
3778 { | |
3779 if (s->timer_is_t4) | |
3780 timer_t4_expired(s); | |
3781 else | |
3782 timer_t2_expired(s); | |
3783 } | |
3784 } | |
3785 if (s->timer_t5 > 0) | |
3786 { | |
3787 s->timer_t5 -= samples; | |
3788 if (s->timer_t5 <= 0) | |
3789 timer_t5_expired(s); | |
3790 } | |
3791 } | |
3792 /*- End of function --------------------------------------------------------*/ | |
3793 | |
3794 static void decode_20digit_msg(t30_state_t *s, char *msg, const uint8_t *pkt, int len) | |
3795 { | |
3796 int p; | |
3797 int k; | |
3798 char text[20 + 1]; | |
3799 | |
3800 if (msg == NULL) | |
3801 msg = text; | |
3802 if (len > T30_MAX_IDENT_LEN) | |
3803 { | |
3804 unexpected_frame_length(s, pkt, len); | |
3805 msg[0] = '\0'; | |
3806 return; | |
3807 } | |
3808 p = len; | |
3809 /* Strip trailing spaces */ | |
3810 while (p > 1 && pkt[p - 1] == ' ') | |
3811 p--; | |
3812 /* The string is actually backwards in the message */ | |
3813 k = 0; | |
3814 while (p > 1) | |
3815 msg[k++] = pkt[--p]; | |
3816 msg[k] = '\0'; | |
3817 span_log(&s->logging, SPAN_LOG_FLOW, "Remote fax gave %s as: \"%s\"\n", t30_frametype(pkt[0]), msg); | |
3818 } | |
3819 /*- End of function --------------------------------------------------------*/ | |
3820 | |
3821 static void decode_url_msg(t30_state_t *s, char *msg, const uint8_t *pkt, int len) | |
3822 { | |
3823 char text[77 + 1]; | |
3824 | |
3825 /* TODO: decode properly, as per T.30 5.3.6.2.12 */ | |
3826 if (msg == NULL) | |
3827 msg = text; | |
3828 if (len < 3 || len > 77 + 3 || len != pkt[2] + 3) | |
3829 { | |
3830 unexpected_frame_length(s, pkt, len); | |
3831 msg[0] = '\0'; | |
3832 return; | |
3833 } | |
3834 /* First octet is the sequence number of the packet. | |
3835 Bit 7 = 1 for more follows, 0 for last packet in the sequence. | |
3836 Bits 6-0 = The sequence number, 0 to 0x7F | |
3837 Second octet is the type of internet address. | |
3838 Bits 7-4 = reserved | |
3839 Bits 3-0 = type: | |
3840 0 = reserved | |
3841 1 = e-mail address | |
3842 2 = URL | |
3843 3 = TCP/IP V4 | |
3844 4 = TCP/IP V6 | |
3845 5 = international phone number, in the usual +... format | |
3846 6-15 = reserved | |
3847 Third octet is the length of the internet address | |
3848 Bit 7 = 1 for more follows, 0 for last packet in the sequence. | |
3849 Bits 6-0 = length | |
3850 */ | |
3851 memcpy(msg, &pkt[3], len - 3); | |
3852 msg[len - 3] = '\0'; | |
3853 span_log(&s->logging, SPAN_LOG_FLOW, "Remote fax gave %s as: %d, %d, \"%s\"\n", t30_frametype(pkt[0]), pkt[0], pkt[1], msg); | |
3854 } | |
3855 /*- End of function --------------------------------------------------------*/ | |
3856 | |
3857 const char *t30_frametype(uint8_t x) | |
3858 { | |
3859 switch (x & 0xFE) | |
3860 { | |
3861 case T30_DIS: | |
3862 if (x == T30_DTC) | |
3863 return "DTC"; | |
3864 return "DIS"; | |
3865 case T30_CSI: | |
3866 if (x == T30_CIG) | |
3867 return "CIG"; | |
3868 return "CSI"; | |
3869 case T30_NSF: | |
3870 if (x == T30_NSC) | |
3871 return "NSC"; | |
3872 return "NSF"; | |
3873 case T30_PWD & 0xFE: | |
3874 if (x == T30_PWD) | |
3875 return "PWD"; | |
3876 break; | |
3877 case T30_SEP & 0xFE: | |
3878 if (x == T30_SEP) | |
3879 return "SEP"; | |
3880 break; | |
3881 case T30_PSA & 0xFE: | |
3882 if (x == T30_PSA) | |
3883 return "PSA"; | |
3884 break; | |
3885 case T30_CIA & 0xFE: | |
3886 if (x == T30_CIA) | |
3887 return "CIA"; | |
3888 break; | |
3889 case T30_ISP & 0xFE: | |
3890 if (x == T30_ISP) | |
3891 return "ISP"; | |
3892 break; | |
3893 case T30_DCS: | |
3894 return "DCS"; | |
3895 case T30_TSI: | |
3896 return "TSI"; | |
3897 case T30_NSS: | |
3898 return "NSS"; | |
3899 case T30_SUB: | |
3900 return "SUB"; | |
3901 case T30_SID: | |
3902 return "SID"; | |
3903 case T30_CTC: | |
3904 return "CTC"; | |
3905 case T30_TSA: | |
3906 return "TSA"; | |
3907 case T30_IRA: | |
3908 return "IRA"; | |
3909 case T30_CFR: | |
3910 return "CFR"; | |
3911 case T30_FTT: | |
3912 return "FTT"; | |
3913 case T30_CTR: | |
3914 return "CTR"; | |
3915 case T30_CSA: | |
3916 return "CSA"; | |
3917 case T30_EOM: | |
3918 return "EOM"; | |
3919 case T30_MPS: | |
3920 return "MPS"; | |
3921 case T30_EOP: | |
3922 return "EOP"; | |
3923 case T30_PRI_EOM: | |
3924 return "PRI_EOM"; | |
3925 case T30_PRI_MPS: | |
3926 return "PRI_MPS"; | |
3927 case T30_PRI_EOP: | |
3928 return "PRI_EOP"; | |
3929 case T30_EOS: | |
3930 return "EOS"; | |
3931 case T30_PPS: | |
3932 return "PPS"; | |
3933 case T30_EOR: | |
3934 return "EOR"; | |
3935 case T30_RR: | |
3936 return "RR"; | |
3937 case T30_MCF: | |
3938 return "MCF"; | |
3939 case T30_RTP: | |
3940 return "RTP"; | |
3941 case T30_RTN: | |
3942 return "RTN"; | |
3943 case T30_PIP: | |
3944 return "PIP"; | |
3945 case T30_PIN: | |
3946 return "PIN"; | |
3947 case T30_PPR: | |
3948 return "PPR"; | |
3949 case T30_RNR: | |
3950 return "RNR"; | |
3951 case T30_ERR: | |
3952 return "ERR"; | |
3953 case T30_FDM: | |
3954 return "FDM"; | |
3955 case T30_DCN: | |
3956 return "DCN"; | |
3957 case T30_CRP: | |
3958 return "CRP"; | |
3959 case T30_FNV: | |
3960 return "FNV"; | |
3961 case T30_TNR: | |
3962 return "TNR"; | |
3963 case T30_TR: | |
3964 return "TR"; | |
3965 case T30_PID: | |
3966 return "PID"; | |
3967 case T30_NULL: | |
3968 return "NULL"; | |
3969 case T4_FCD: | |
3970 return "FCD"; | |
3971 case T4_RCP: | |
3972 return "RCP"; | |
3973 } | |
3974 return "???"; | |
3975 } | |
3976 /*- End of function --------------------------------------------------------*/ | |
3977 | |
3978 static void octet_reserved_bit(logging_state_t *log, | |
3979 const uint8_t *msg, | |
3980 int bit_no, | |
3981 int expected) | |
3982 { | |
3983 char s[10] = ".... ...."; | |
3984 int bit; | |
3985 uint8_t octet; | |
3986 | |
3987 /* Break out the octet and the bit number within it. */ | |
3988 octet = msg[((bit_no - 1) >> 3) + 3]; | |
3989 bit_no = (bit_no - 1) & 7; | |
3990 /* Now get the actual bit. */ | |
3991 bit = (octet >> bit_no) & 1; | |
3992 /* Is it what it should be. */ | |
3993 if (bit ^ expected) | |
3994 { | |
3995 /* Only log unexpected values. */ | |
3996 s[7 - bit_no + ((bit_no < 4) ? 1 : 0)] = (uint8_t) (bit + '0'); | |
3997 span_log(log, SPAN_LOG_FLOW, " %s= Unexpected state for reserved bit: %d\n", s, bit); | |
3998 } | |
3999 } | |
4000 /*- End of function --------------------------------------------------------*/ | |
4001 | |
4002 static void octet_bit_field(logging_state_t *log, | |
4003 const uint8_t *msg, | |
4004 int bit_no, | |
4005 const char *desc, | |
4006 const char *yeah, | |
4007 const char *neigh) | |
4008 { | |
4009 char s[10] = ".... ...."; | |
4010 int bit; | |
4011 uint8_t octet; | |
4012 const char *tag; | |
4013 | |
4014 /* Break out the octet and the bit number within it. */ | |
4015 octet = msg[((bit_no - 1) >> 3) + 3]; | |
4016 bit_no = (bit_no - 1) & 7; | |
4017 /* Now get the actual bit. */ | |
4018 bit = (octet >> bit_no) & 1; | |
4019 /* Edit the bit string for display. */ | |
4020 s[7 - bit_no + ((bit_no < 4) ? 1 : 0)] = (uint8_t) (bit + '0'); | |
4021 /* Find the right tag to display. */ | |
4022 if (bit) | |
4023 { | |
4024 if ((tag = yeah) == NULL) | |
4025 tag = "Set"; | |
4026 } | |
4027 else | |
4028 { | |
4029 if ((tag = neigh) == NULL) | |
4030 tag = "Not set"; | |
4031 } | |
4032 /* Eh, voila! */ | |
4033 span_log(log, SPAN_LOG_FLOW, " %s= %s: %s\n", s, desc, tag); | |
4034 } | |
4035 /*- End of function --------------------------------------------------------*/ | |
4036 | |
4037 static void octet_field(logging_state_t *log, | |
4038 const uint8_t *msg, | |
4039 int start, | |
4040 int end, | |
4041 const char *desc, | |
4042 const value_string_t tags[]) | |
4043 { | |
4044 char s[10] = ".... ...."; | |
4045 int i; | |
4046 uint8_t octet; | |
4047 const char *tag; | |
4048 | |
4049 /* Break out the octet and the bit number range within it. */ | |
4050 octet = msg[((start - 1) >> 3) + 3]; | |
4051 start = (start - 1) & 7; | |
4052 end = ((end - 1) & 7) + 1; | |
4053 | |
4054 /* Edit the bit string for display. */ | |
4055 for (i = start; i < end; i++) | |
4056 s[7 - i + ((i < 4) ? 1 : 0)] = (uint8_t) ((octet >> i) & 1) + '0'; | |
4057 | |
4058 /* Find the right tag to display. */ | |
4059 octet = (uint8_t) ((octet >> start) & ((0xFF + (1 << (end - start))) & 0xFF)); | |
4060 tag = "Invalid"; | |
4061 for (i = 0; tags[i].str; i++) | |
4062 { | |
4063 if (octet == tags[i].val) | |
4064 { | |
4065 tag = tags[i].str; | |
4066 break; | |
4067 } | |
4068 } | |
4069 /* Eh, voila! */ | |
4070 span_log(log, SPAN_LOG_FLOW, " %s= %s: %s\n", s, desc, tag); | |
4071 } | |
4072 /*- End of function --------------------------------------------------------*/ | |
4073 | |
4074 void t30_decode_dis_dtc_dcs(t30_state_t *s, const uint8_t *pkt, int len) | |
4075 { | |
4076 logging_state_t *log; | |
4077 uint8_t frame_type; | |
4078 static const value_string_t available_signalling_rate_tags[] = | |
4079 { | |
4080 { 0x00, "V.27 ter fall-back mode" }, | |
4081 { 0x01, "V.29" }, | |
4082 { 0x02, "V.27 ter" }, | |
4083 { 0x03, "V.27 ter and V.29" }, | |
4084 { 0x0B, "V.27 ter, V.29, and V.17" }, | |
4085 { 0x06, "Reserved" }, | |
4086 { 0x0A, "Reserved" }, | |
4087 { 0x0E, "Reserved" }, | |
4088 { 0x0F, "Reserved" }, | |
4089 { 0x04, "Not used" }, | |
4090 { 0x05, "Not used" }, | |
4091 { 0x08, "Not used" }, | |
4092 { 0x09, "Not used" }, | |
4093 { 0x0C, "Not used" }, | |
4094 { 0x0D, "Not used" }, | |
4095 { 0x00, NULL } | |
4096 }; | |
4097 static const value_string_t selected_signalling_rate_tags[] = | |
4098 { | |
4099 { 0x00, "V.27ter 2400bps" }, | |
4100 { 0x01, "V.29, 9600bps" }, | |
4101 { 0x02, "V.27ter 4800bps" }, | |
4102 { 0x03, "V.29 7200bps" }, | |
4103 { 0x08, "V.17 14400bps" }, | |
4104 { 0x09, "V.17 9600bps" }, | |
4105 { 0x0A, "V.17 12000bps" }, | |
4106 { 0x0B, "V.17 7200bps" }, | |
4107 { 0x05, "Reserved" }, | |
4108 { 0x07, "Reserved" }, | |
4109 { 0x0C, "Reserved" }, | |
4110 { 0x0D, "Reserved" }, | |
4111 { 0x0E, "Reserved" }, | |
4112 { 0x0F, "Reserved" }, | |
4113 { 0x00, NULL } | |
4114 }; | |
4115 static const value_string_t available_scan_line_length_tags[] = | |
4116 { | |
4117 { 0x00, "215 mm +- 1%" }, | |
4118 { 0x01, "215 mm +- 1% and 255 mm +- 1%" }, | |
4119 { 0x02, "215 mm +- 1% and 255 mm +- 1% and 303 mm +- 1%" }, | |
4120 { 0x00, NULL } | |
4121 }; | |
4122 static const value_string_t selected_scan_line_length_tags[] = | |
4123 { | |
4124 { 0x00, "215 mm +- 1%" }, | |
4125 { 0x01, "255 mm +- 1%" }, | |
4126 { 0x02, "303 mm +- 1%" }, | |
4127 { 0x00, NULL } | |
4128 }; | |
4129 static const value_string_t available_recording_length_tags[] = | |
4130 { | |
4131 { 0x00, "A4 (297 mm)" }, | |
4132 { 0x01, "A4 (297 mm) and B4 (364 mm)" }, | |
4133 { 0x02, "Unlimited" }, | |
4134 { 0x00, NULL } | |
4135 }; | |
4136 static const value_string_t selected_recording_length_tags[] = | |
4137 { | |
4138 { 0x00, "A4 (297 mm)" }, | |
4139 { 0x01, "B4 (364 mm)" }, | |
4140 { 0x02, "Unlimited" }, | |
4141 { 0x00, NULL } | |
4142 }; | |
4143 static const value_string_t available_minimum_scan_line_time_tags[] = | |
4144 { | |
4145 { 0x00, "20 ms at 3.85 l/mm: T7.7 = T3.85" }, | |
4146 { 0x01, "5 ms at 3.85 l/mm: T7.7 = T3.85" }, | |
4147 { 0x02, "10 ms at 3.85 l/mm: T7.7 = T3.85" }, | |
4148 { 0x03, "20 ms at 3.85 l/mm: T7.7 = 1/2 T3.85" }, | |
4149 { 0x04, "40 ms at 3.85 l/mm: T7.7 = T3.85" }, | |
4150 { 0x05, "40 ms at 3.85 l/mm: T7.7 = 1/2 T3.85" }, | |
4151 { 0x06, "10 ms at 3.85 l/mm: T7.7 = 1/2 T3.85" }, | |
4152 { 0x07, "0 ms at 3.85 l/mm: T7.7 = T3.85" }, | |
4153 { 0x00, NULL } | |
4154 }; | |
4155 static const value_string_t selected_minimum_scan_line_time_tags[] = | |
4156 { | |
4157 { 0x00, "20 ms" }, | |
4158 { 0x01, "40 ms" }, | |
4159 { 0x02, "10 ms" }, | |
4160 { 0x04, "5 ms" }, | |
4161 { 0x07, "0 ms" }, | |
4162 { 0x00, NULL } | |
4163 }; | |
4164 static const value_string_t shared_data_memory_capacity_tags[] = | |
4165 { | |
4166 { 0x00, "Not available" }, | |
4167 { 0x01, "Level 2 = 2.0 Mbytes" }, | |
4168 { 0x02, "Level 1 = 1.0 Mbytes" }, | |
4169 { 0x03, "Level 3 = unlimited (i.e. >= 32 Mbytes)" }, | |
4170 { 0x00, NULL } | |
4171 }; | |
4172 static const value_string_t t89_profile_tags[] = | |
4173 { | |
4174 { 0x00, "Not used" }, | |
4175 { 0x01, "Profiles 2 and 3" }, | |
4176 { 0x02, "Profile 2" }, | |
4177 { 0x04, "Profile 1" }, | |
4178 { 0x06, "Profile 3" }, | |
4179 { 0x03, "Reserved" }, | |
4180 { 0x05, "Reserved" }, | |
4181 { 0x07, "Reserved" }, | |
4182 { 0x00, NULL } | |
4183 }; | |
4184 static const value_string_t t44_mixed_raster_content_tags[] = | |
4185 { | |
4186 { 0x00, "0" }, | |
4187 { 0x01, "1" }, | |
4188 { 0x02, "2" }, | |
4189 { 0x32, "3" }, | |
4190 { 0x04, "4" }, | |
4191 { 0x05, "5" }, | |
4192 { 0x06, "6" }, | |
4193 { 0x07, "7" }, | |
4194 { 0x00, NULL } | |
4195 }; | |
4196 | |
4197 if (!span_log_test(&s->logging, SPAN_LOG_FLOW)) | |
4198 return; | |
4199 frame_type = pkt[2] & 0xFE; | |
4200 log = &s->logging; | |
4201 if (len <= 2) | |
4202 { | |
4203 span_log(log, SPAN_LOG_FLOW, " Frame is short\n"); | |
4204 return; | |
4205 } | |
4206 | |
4207 span_log(log, SPAN_LOG_FLOW, "%s:\n", t30_frametype(pkt[2])); | |
4208 if (len <= 3) | |
4209 { | |
4210 span_log(log, SPAN_LOG_FLOW, " Frame is short\n"); | |
4211 return; | |
4212 } | |
4213 octet_bit_field(log, pkt, 1, "Store and forward Internet fax (T.37)", NULL, NULL); | |
4214 octet_reserved_bit(log, pkt, 2, 0); | |
4215 octet_bit_field(log, pkt, 3, "Real-time Internet fax (T.38)", NULL, NULL); | |
4216 octet_bit_field(log, pkt, 4, "3G mobile network", NULL, NULL); | |
4217 octet_reserved_bit(log, pkt, 5, 0); | |
4218 if (frame_type == T30_DCS) | |
4219 { | |
4220 octet_reserved_bit(log, pkt, 6, 0); | |
4221 octet_reserved_bit(log, pkt, 7, 0); | |
4222 } | |
4223 else | |
4224 { | |
4225 octet_bit_field(log, pkt, 6, "V.8 capabilities", NULL, NULL); | |
4226 octet_bit_field(log, pkt, 7, "Preferred octets", "64 octets", "256 octets"); | |
4227 } | |
4228 octet_reserved_bit(log, pkt, 8, 0); | |
4229 if (len <= 4) | |
4230 { | |
4231 span_log(log, SPAN_LOG_FLOW, " Frame is short\n"); | |
4232 return; | |
4233 } | |
4234 | |
4235 if (frame_type == T30_DCS) | |
4236 octet_reserved_bit(log, pkt, 9, 0); | |
4237 else | |
4238 octet_bit_field(log, pkt, 9, "Ready to transmit a fax document (polling)", NULL, NULL); | |
4239 octet_bit_field(log, pkt, 10, "Can receive fax", NULL, NULL); | |
4240 if (frame_type == T30_DCS) | |
4241 octet_field(log, pkt, 11, 14, "Selected data signalling rate", selected_signalling_rate_tags); | |
4242 else | |
4243 octet_field(log, pkt, 11, 14, "Supported data signalling rates", available_signalling_rate_tags); | |
4244 octet_bit_field(log, pkt, 15, "R8x7.7lines/mm and/or 200x200pels/25.4mm", NULL, NULL); | |
4245 octet_bit_field(log, pkt, 16, "2-D coding", NULL, NULL); | |
4246 if (len <= 5) | |
4247 { | |
4248 span_log(log, SPAN_LOG_FLOW, " Frame is short\n"); | |
4249 return; | |
4250 } | |
4251 | |
4252 if (frame_type == T30_DCS) | |
4253 { | |
4254 octet_field(log, pkt, 17, 18, "Recording width", selected_scan_line_length_tags); | |
4255 octet_field(log, pkt, 19, 20, "Recording length", selected_recording_length_tags); | |
4256 octet_field(log, pkt, 21, 23, "Minimum scan line time", selected_minimum_scan_line_time_tags); | |
4257 } | |
4258 else | |
4259 { | |
4260 octet_field(log, pkt, 17, 18, "Recording width", available_scan_line_length_tags); | |
4261 octet_field(log, pkt, 19, 20, "Recording length", available_recording_length_tags); | |
4262 octet_field(log, pkt, 21, 23, "Receiver's minimum scan line time", available_minimum_scan_line_time_tags); | |
4263 } | |
4264 octet_bit_field(log, pkt, 24, "Extension indicator", NULL, NULL); | |
4265 if (!(pkt[5] & DISBIT8)) | |
4266 return; | |
4267 if (len <= 6) | |
4268 { | |
4269 span_log(log, SPAN_LOG_FLOW, " Frame is short\n"); | |
4270 return; | |
4271 } | |
4272 | |
4273 octet_reserved_bit(log, pkt, 25, 0); | |
4274 octet_bit_field(log, pkt, 26, "Compressed/uncompressed mode", "Uncompressed", "Compressed"); | |
4275 octet_bit_field(log, pkt, 27, "Error correction mode (ECM)", "ECM", "Non-ECM"); | |
4276 if (frame_type == T30_DCS) | |
4277 octet_bit_field(log, pkt, 28, "Frame size", "64 octets", "256 octets"); | |
4278 else | |
4279 octet_reserved_bit(log, pkt, 28, 0); | |
4280 octet_reserved_bit(log, pkt, 29, 0); | |
4281 octet_reserved_bit(log, pkt, 30, 0); | |
4282 octet_bit_field(log, pkt, 31, "T.6 coding", NULL, NULL); | |
4283 octet_bit_field(log, pkt, 32, "Extension indicator", NULL, NULL); | |
4284 if (!(pkt[6] & DISBIT8)) | |
4285 return; | |
4286 if (len <= 7) | |
4287 { | |
4288 span_log(log, SPAN_LOG_FLOW, " Frame is short\n"); | |
4289 return; | |
4290 } | |
4291 | |
4292 octet_bit_field(log, pkt, 33, "\"Field not valid\" supported", NULL, NULL); | |
4293 if (frame_type == T30_DCS) | |
4294 { | |
4295 octet_reserved_bit(log, pkt, 34, 0); | |
4296 octet_reserved_bit(log, pkt, 35, 0); | |
4297 } | |
4298 else | |
4299 { | |
4300 octet_bit_field(log, pkt, 34, "Multiple selective polling", NULL, NULL); | |
4301 octet_bit_field(log, pkt, 35, "Polled subaddress", NULL, NULL); | |
4302 } | |
4303 octet_bit_field(log, pkt, 36, "T.43 coding", NULL, NULL); | |
4304 octet_bit_field(log, pkt, 37, "Plane interleave", NULL, NULL); | |
4305 octet_bit_field(log, pkt, 38, "Voice coding with 32kbit/s ADPCM (Rec. G.726)", NULL, NULL); | |
4306 octet_bit_field(log, pkt, 39, "Reserved for the use of extended voice coding set", NULL, NULL); | |
4307 octet_bit_field(log, pkt, 40, "Extension indicator", NULL, NULL); | |
4308 if (!(pkt[7] & DISBIT8)) | |
4309 return; | |
4310 if (len <= 8) | |
4311 { | |
4312 span_log(log, SPAN_LOG_FLOW, " Frame is short\n"); | |
4313 return; | |
4314 } | |
4315 | |
4316 octet_bit_field(log, pkt, 41, "R8x15.4lines/mm", NULL, NULL); | |
4317 octet_bit_field(log, pkt, 42, "300x300pels/25.4mm", NULL, NULL); | |
4318 octet_bit_field(log, pkt, 43, "R16x15.4lines/mm and/or 400x400pels/25.4 mm", NULL, NULL); | |
4319 if (frame_type == T30_DCS) | |
4320 { | |
4321 octet_bit_field(log, pkt, 44, "Resolution type selection", "Inch", "Metric"); | |
4322 octet_reserved_bit(log, pkt, 45, 0); | |
4323 octet_reserved_bit(log, pkt, 46, 0); | |
4324 octet_reserved_bit(log, pkt, 47, 0); | |
4325 } | |
4326 else | |
4327 { | |
4328 octet_bit_field(log, pkt, 44, "Inch-based resolution preferred", NULL, NULL); | |
4329 octet_bit_field(log, pkt, 45, "Metric-based resolution preferred", NULL, NULL); | |
4330 octet_bit_field(log, pkt, 46, "Minimum scan line time for higher resolutions", "T15.4 = 1/2 T7.7", "T15.4 = T7.7"); | |
4331 octet_bit_field(log, pkt, 47, "Selective polling", NULL, NULL); | |
4332 } | |
4333 octet_bit_field(log, pkt, 48, "Extension indicator", NULL, NULL); | |
4334 if (!(pkt[8] & DISBIT8)) | |
4335 return; | |
4336 if (len <= 9) | |
4337 { | |
4338 span_log(log, SPAN_LOG_FLOW, " Frame is short\n"); | |
4339 return; | |
4340 } | |
4341 | |
4342 octet_bit_field(log, pkt, 49, "Subaddressing", NULL, NULL); | |
4343 if (frame_type == T30_DCS) | |
4344 { | |
4345 octet_bit_field(log, pkt, 50, "Sender identification transmission", NULL, NULL); | |
4346 octet_reserved_bit(log, pkt, 51, 0); | |
4347 } | |
4348 else | |
4349 { | |
4350 octet_bit_field(log, pkt, 50, "Password", NULL, NULL); | |
4351 octet_bit_field(log, pkt, 51, "Ready to transmit a data file (polling)", NULL, NULL); | |
4352 } | |
4353 octet_reserved_bit(log, pkt, 52, 0); | |
4354 octet_bit_field(log, pkt, 53, "Binary file transfer (BFT)", NULL, NULL); | |
4355 octet_bit_field(log, pkt, 54, "Document transfer mode (DTM)", NULL, NULL); | |
4356 octet_bit_field(log, pkt, 55, "Electronic data interchange (EDI)", NULL, NULL); | |
4357 octet_bit_field(log, pkt, 56, "Extension indicator", NULL, NULL); | |
4358 if (!(pkt[9] & DISBIT8)) | |
4359 return; | |
4360 if (len <= 10) | |
4361 { | |
4362 span_log(log, SPAN_LOG_FLOW, " Frame is short\n"); | |
4363 return; | |
4364 } | |
4365 | |
4366 octet_bit_field(log, pkt, 57, "Basic transfer mode (BTM)", NULL, NULL); | |
4367 octet_reserved_bit(log, pkt, 58, 0); | |
4368 if (frame_type == T30_DCS) | |
4369 octet_reserved_bit(log, pkt, 59, 0); | |
4370 else | |
4371 octet_bit_field(log, pkt, 59, "Ready to transfer a character or mixed mode document (polling)", NULL, NULL); | |
4372 octet_bit_field(log, pkt, 60, "Character mode", NULL, NULL); | |
4373 octet_reserved_bit(log, pkt, 61, 0); | |
4374 octet_bit_field(log, pkt, 62, "Mixed mode (Annex E/T.4)", NULL, NULL); | |
4375 octet_reserved_bit(log, pkt, 63, 0); | |
4376 octet_bit_field(log, pkt, 64, "Extension indicator", NULL, NULL); | |
4377 if (!(pkt[10] & DISBIT8)) | |
4378 return; | |
4379 if (len <= 11) | |
4380 { | |
4381 span_log(log, SPAN_LOG_FLOW, " Frame is short\n"); | |
4382 return; | |
4383 } | |
4384 | |
4385 octet_bit_field(log, pkt, 65, "Processable mode 26 (Rec. T.505)", NULL, NULL); | |
4386 octet_bit_field(log, pkt, 66, "Digital network capability", NULL, NULL); | |
4387 octet_bit_field(log, pkt, 67, "Duplex capability", "Full", "Half only"); | |
4388 if (frame_type == T30_DCS) | |
4389 octet_bit_field(log, pkt, 68, "Full colour mode", NULL, NULL); | |
4390 else | |
4391 octet_bit_field(log, pkt, 68, "JPEG coding", NULL, NULL); | |
4392 octet_bit_field(log, pkt, 69, "Full colour mode", NULL, NULL); | |
4393 if (frame_type == T30_DCS) | |
4394 octet_bit_field(log, pkt, 70, "Preferred Huffman tables", NULL, NULL); | |
4395 else | |
4396 octet_reserved_bit(log, pkt, 70, 0); | |
4397 octet_bit_field(log, pkt, 71, "12bits/pel component", NULL, NULL); | |
4398 octet_bit_field(log, pkt, 72, "Extension indicator", NULL, NULL); | |
4399 if (!(pkt[11] & DISBIT8)) | |
4400 return; | |
4401 if (len <= 12) | |
4402 { | |
4403 span_log(log, SPAN_LOG_FLOW, " Frame is short\n"); | |
4404 return; | |
4405 } | |
4406 | |
4407 octet_bit_field(log, pkt, 73, "No subsampling (1:1:1)", NULL, NULL); | |
4408 octet_bit_field(log, pkt, 74, "Custom illuminant", NULL, NULL); | |
4409 octet_bit_field(log, pkt, 75, "Custom gamut range", NULL, NULL); | |
4410 octet_bit_field(log, pkt, 76, "North American Letter (215.9mm x 279.4mm)", NULL, NULL); | |
4411 octet_bit_field(log, pkt, 77, "North American Legal (215.9mm x 355.6mm)", NULL, NULL); | |
4412 octet_bit_field(log, pkt, 78, "Single-progression sequential coding (Rec. T.85) basic", NULL, NULL); | |
4413 octet_bit_field(log, pkt, 79, "Single-progression sequential coding (Rec. T.85) optional L0", NULL, NULL); | |
4414 octet_bit_field(log, pkt, 80, "Extension indicator", NULL, NULL); | |
4415 if (!(pkt[12] & DISBIT8)) | |
4416 return; | |
4417 if (len <= 13) | |
4418 { | |
4419 span_log(log, SPAN_LOG_FLOW, " Frame is short\n"); | |
4420 return; | |
4421 } | |
4422 | |
4423 octet_bit_field(log, pkt, 81, "HKM key management", NULL, NULL); | |
4424 octet_bit_field(log, pkt, 82, "RSA key management", NULL, NULL); | |
4425 octet_bit_field(log, pkt, 83, "Override", NULL, NULL); | |
4426 octet_bit_field(log, pkt, 84, "HFX40 cipher", NULL, NULL); | |
4427 octet_bit_field(log, pkt, 85, "Alternative cipher number 2", NULL, NULL); | |
4428 octet_bit_field(log, pkt, 86, "Alternative cipher number 3", NULL, NULL); | |
4429 octet_bit_field(log, pkt, 87, "HFX40-I hashing", NULL, NULL); | |
4430 octet_bit_field(log, pkt, 88, "Extension indicator", NULL, NULL); | |
4431 if (!(pkt[13] & DISBIT8)) | |
4432 return; | |
4433 if (len <= 14) | |
4434 { | |
4435 span_log(log, SPAN_LOG_FLOW, " Frame is short\n"); | |
4436 return; | |
4437 } | |
4438 | |
4439 octet_bit_field(log, pkt, 89, "Alternative hashing system 2", NULL, NULL); | |
4440 octet_bit_field(log, pkt, 90, "Alternative hashing system 3", NULL, NULL); | |
4441 octet_bit_field(log, pkt, 91, "Reserved for future security features", NULL, NULL); | |
4442 octet_field(log, pkt, 92, 94, "T.44 (Mixed Raster Content)", t44_mixed_raster_content_tags); | |
4443 octet_bit_field(log, pkt, 95, "Page length maximum stripe size for T.44 (Mixed Raster Content)", NULL, NULL); | |
4444 octet_bit_field(log, pkt, 96, "Extension indicator", NULL, NULL); | |
4445 if (!(pkt[14] & DISBIT8)) | |
4446 return; | |
4447 if (len <= 15) | |
4448 { | |
4449 span_log(log, SPAN_LOG_FLOW, " Frame is short\n"); | |
4450 return; | |
4451 } | |
4452 | |
4453 octet_bit_field(log, pkt, 97, "Colour/gray-scale 300pels/25.4mm x 300lines/25.4mm or 400pels/25.4mm x 400lines/25.4mm resolution", NULL, NULL); | |
4454 octet_bit_field(log, pkt, 98, "100pels/25.4mm x 100lines/25.4mm for colour/gray scale", NULL, NULL); | |
4455 octet_bit_field(log, pkt, 99, "Simple phase C BFT negotiations", NULL, NULL); | |
4456 if (frame_type == T30_DCS) | |
4457 { | |
4458 octet_reserved_bit(log, pkt, 100, 0); | |
4459 octet_reserved_bit(log, pkt, 101, 0); | |
4460 } | |
4461 else | |
4462 { | |
4463 octet_bit_field(log, pkt, 100, "Extended BFT Negotiations capable", NULL, NULL); | |
4464 octet_bit_field(log, pkt, 101, "Internet Selective Polling address (ISP)", NULL, NULL); | |
4465 } | |
4466 octet_bit_field(log, pkt, 102, "Internet Routing Address (IRA)", NULL, NULL); | |
4467 octet_reserved_bit(log, pkt, 103, 0); | |
4468 octet_bit_field(log, pkt, 104, "Extension indicator", NULL, NULL); | |
4469 if (!(pkt[15] & DISBIT8)) | |
4470 return; | |
4471 if (len <= 16) | |
4472 { | |
4473 span_log(log, SPAN_LOG_FLOW, " Frame is short\n"); | |
4474 return; | |
4475 } | |
4476 | |
4477 octet_bit_field(log, pkt, 105, "600pels/25.4mm x 600lines/25.4mm", NULL, NULL); | |
4478 octet_bit_field(log, pkt, 106, "1200pels/25.4mm x 1200lines/25.4mm", NULL, NULL); | |
4479 octet_bit_field(log, pkt, 107, "300pels/25.4mm x 600lines/25.4mm", NULL, NULL); | |
4480 octet_bit_field(log, pkt, 108, "400pels/25.4mm x 800lines/25.4mm", NULL, NULL); | |
4481 octet_bit_field(log, pkt, 109, "600pels/25.4mm x 1200lines/25.4mm", NULL, NULL); | |
4482 octet_bit_field(log, pkt, 110, "Colour/gray scale 600pels/25.4mm x 600lines/25.4mm", NULL, NULL); | |
4483 octet_bit_field(log, pkt, 111, "Colour/gray scale 1200pels/25.4mm x 1200lines/25.4mm", NULL, NULL); | |
4484 octet_bit_field(log, pkt, 112, "Extension indicator", NULL, NULL); | |
4485 if (!(pkt[16] & DISBIT8)) | |
4486 return; | |
4487 if (len <= 17) | |
4488 { | |
4489 span_log(log, SPAN_LOG_FLOW, " Frame is short\n"); | |
4490 return; | |
4491 } | |
4492 | |
4493 octet_bit_field(log, pkt, 113, "Double sided printing capability (alternate mode)", NULL, NULL); | |
4494 octet_bit_field(log, pkt, 114, "Double sided printing capability (continuous mode)", NULL, NULL); | |
4495 if (frame_type == T30_DCS) | |
4496 octet_bit_field(log, pkt, 115, "Black and white mixed raster content profile (MRCbw)", NULL, NULL); | |
4497 else | |
4498 octet_reserved_bit(log, pkt, 115, 0); | |
4499 octet_bit_field(log, pkt, 116, "T.45 (run length colour encoded)", NULL, NULL); | |
4500 octet_field(log, pkt, 117, 118, "Shared memory", shared_data_memory_capacity_tags); | |
4501 octet_bit_field(log, pkt, 119, "T.44 colour space", NULL, NULL); | |
4502 octet_bit_field(log, pkt, 120, "Extension indicator", NULL, NULL); | |
4503 if (!(pkt[17] & DISBIT8)) | |
4504 return; | |
4505 if (len <= 18) | |
4506 { | |
4507 span_log(log, SPAN_LOG_FLOW, " Frame is short\n"); | |
4508 return; | |
4509 } | |
4510 | |
4511 octet_bit_field(log, pkt, 121, "Flow control capability for T.38 communication", NULL, NULL); | |
4512 octet_bit_field(log, pkt, 122, "K>4", NULL, NULL); | |
4513 octet_bit_field(log, pkt, 123, "Internet aware T.38 mode fax (not affected by data signal rate bits)", NULL, NULL); | |
4514 octet_field(log, pkt, 124, 126, "T.89 (Application profiles for ITU-T Rec T.8)", t89_profile_tags); | |
4515 octet_bit_field(log, pkt, 127, "sYCC-JPEG coding", NULL, NULL); | |
4516 octet_bit_field(log, pkt, 128, "Extension indicator", NULL, NULL); | |
4517 if (!(pkt[18] & DISBIT8)) | |
4518 return; | |
4519 | |
4520 span_log(log, SPAN_LOG_FLOW, " Extended beyond the current T.30 specification!\n"); | |
4521 } | |
4522 /*- End of function --------------------------------------------------------*/ | |
4523 | |
4524 int t30_restart(t30_state_t *s) | |
4525 { | |
4526 s->phase = T30_PHASE_IDLE; | |
4527 s->next_phase = T30_PHASE_IDLE; | |
4528 s->current_fallback = 0; | |
4529 s->rx_signal_present = FALSE; | |
4530 s->rx_trained = FALSE; | |
4531 s->current_status = T30_ERR_OK; | |
4532 build_dis_or_dtc(s); | |
4533 if (s->calling_party) | |
4534 { | |
4535 set_state(s, T30_STATE_T); | |
4536 set_phase(s, T30_PHASE_A_CNG); | |
4537 } | |
4538 else | |
4539 { | |
4540 set_state(s, T30_STATE_ANSWERING); | |
4541 set_phase(s, T30_PHASE_A_CED); | |
4542 } | |
4543 s->far_end_detected = FALSE; | |
4544 s->timer_t0_t1 = ms_to_samples(DEFAULT_TIMER_T0); | |
4545 return 0; | |
4546 } | |
4547 /*- End of function --------------------------------------------------------*/ | |
4548 | |
4549 int t30_init(t30_state_t *s, | |
4550 int calling_party, | |
4551 t30_set_handler_t *set_rx_type_handler, | |
4552 void *set_rx_type_user_data, | |
4553 t30_set_handler_t *set_tx_type_handler, | |
4554 void *set_tx_type_user_data, | |
4555 t30_send_hdlc_handler_t *send_hdlc_handler, | |
4556 void *send_hdlc_user_data) | |
4557 { | |
4558 memset(s, 0, sizeof(*s)); | |
4559 s->calling_party = calling_party; | |
4560 s->set_rx_type_handler = set_rx_type_handler; | |
4561 s->set_rx_type_user_data = set_rx_type_user_data; | |
4562 s->set_tx_type_handler = set_tx_type_handler; | |
4563 s->set_tx_type_user_data = set_tx_type_user_data; | |
4564 s->send_hdlc_handler = send_hdlc_handler; | |
4565 s->send_hdlc_user_data = send_hdlc_user_data; | |
4566 | |
4567 /* Default to the basic modems. */ | |
4568 s->supported_modems = T30_SUPPORT_V27TER | T30_SUPPORT_V29; | |
4569 s->supported_compressions = T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION; | |
4570 s->supported_resolutions = T30_SUPPORT_STANDARD_RESOLUTION | T30_SUPPORT_FINE_RESOLUTION | T30_SUPPORT_SUPERFINE_RESOLUTION | |
4571 | T30_SUPPORT_R8_RESOLUTION; | |
4572 s->supported_image_sizes = T30_SUPPORT_US_LETTER_LENGTH | T30_SUPPORT_US_LEGAL_LENGTH | T30_SUPPORT_UNLIMITED_LENGTH | |
4573 | T30_SUPPORT_215MM_WIDTH; | |
4574 span_log_init(&s->logging, SPAN_LOG_NONE, NULL); | |
4575 span_log_set_protocol(&s->logging, "T.30"); | |
4576 t30_restart(s); | |
4577 return 0; | |
4578 } | |
4579 /*- End of function --------------------------------------------------------*/ | |
4580 | |
4581 void t30_release(t30_state_t *s) | |
4582 { | |
4583 /* Make sure any FAX in progress is tidied up. If the tidying up has | |
4584 already happened, repeating it here is harmless. */ | |
4585 t4_rx_end(&(s->t4)); | |
4586 t4_tx_end(&(s->t4)); | |
4587 } | |
4588 /*- End of function --------------------------------------------------------*/ | |
4589 | |
4590 t30_state_t *t30_create(int calling_party, | |
4591 t30_set_handler_t *set_rx_type_handler, | |
4592 void *set_rx_type_user_data, | |
4593 t30_set_handler_t *set_tx_type_handler, | |
4594 void *set_tx_type_user_data, | |
4595 t30_send_hdlc_handler_t *send_hdlc_handler, | |
4596 void *send_hdlc_user_data) | |
4597 { | |
4598 t30_state_t *s; | |
4599 | |
4600 if ((s = (t30_state_t *) malloc(sizeof(t30_state_t))) == NULL) | |
4601 return NULL; | |
4602 if (t30_init(s, | |
4603 calling_party, | |
4604 set_rx_type_handler, | |
4605 set_rx_type_user_data, | |
4606 set_tx_type_handler, | |
4607 set_tx_type_user_data, | |
4608 send_hdlc_handler, | |
4609 send_hdlc_user_data)) | |
4610 { | |
4611 free(s); | |
4612 return NULL; | |
4613 } | |
4614 return s; | |
4615 } | |
4616 /*- End of function --------------------------------------------------------*/ | |
4617 | |
4618 void t30_free(t30_state_t *s) | |
4619 { | |
4620 t30_release(s); | |
4621 free(s); | |
4622 } | |
4623 /*- End of function --------------------------------------------------------*/ | |
4624 | |
4625 void t30_terminate(t30_state_t *s) | |
4626 { | |
4627 if (s->phase != T30_PHASE_CALL_FINISHED) | |
4628 { | |
4629 /* The far end disconnected early, but was it just a tiny bit too early, | |
4630 as we were just tidying up, or seriously early as in a failure? */ | |
4631 switch (s->state) | |
4632 { | |
4633 case T30_STATE_C: | |
4634 /* We were sending the final disconnect, so just hussle things along. */ | |
4635 disconnect(s); | |
4636 break; | |
4637 case T30_STATE_B: | |
4638 /* We were in the final wait for everything to flush through, so just | |
4639 hussle things along. */ | |
4640 break; | |
4641 default: | |
4642 /* The call terminated prematurely. */ | |
4643 s->current_status = T30_ERR_CALLDROPPED; | |
4644 break; | |
4645 } | |
4646 if (s->phase_e_handler) | |
4647 s->phase_e_handler(s, s->phase_e_user_data, s->current_status); | |
4648 set_state(s, T30_STATE_CALL_FINISHED); | |
4649 set_phase(s, T30_PHASE_CALL_FINISHED); | |
4650 } | |
4651 } | |
4652 /*- End of function --------------------------------------------------------*/ | |
4653 | |
4654 void t30_set_iaf_mode(t30_state_t *s, int iaf) | |
4655 { | |
4656 s->iaf = iaf; | |
4657 } | |
4658 /*- End of function --------------------------------------------------------*/ | |
4659 | |
4660 int t30_set_header_info(t30_state_t *s, const char *info) | |
4661 { | |
4662 if (info == NULL) | |
4663 { | |
4664 s->header_info[0] = '\0'; | |
4665 return 0; | |
4666 } | |
4667 if (strlen(info) > 50) | |
4668 return -1; | |
4669 strcpy(s->header_info, info); | |
4670 t4_tx_set_header_info(&(s->t4), s->header_info); | |
4671 return 0; | |
4672 } | |
4673 /*- End of function --------------------------------------------------------*/ | |
4674 | |
4675 int t30_set_local_ident(t30_state_t *s, const char *id) | |
4676 { | |
4677 if (id == NULL) | |
4678 { | |
4679 s->local_ident[0] = '\0'; | |
4680 return 0; | |
4681 } | |
4682 if (strlen(id) > 20) | |
4683 return -1; | |
4684 strcpy(s->local_ident, id); | |
4685 t4_tx_set_local_ident(&(s->t4), s->local_ident); | |
4686 return 0; | |
4687 } | |
4688 /*- End of function --------------------------------------------------------*/ | |
4689 | |
4690 int t30_set_local_nsf(t30_state_t *s, const uint8_t *nsf, int len) | |
4691 { | |
4692 if (len > 100) | |
4693 return -1; | |
4694 memcpy(s->local_nsf, nsf, len); | |
4695 s->local_nsf_len = len; | |
4696 return 0; | |
4697 } | |
4698 /*- End of function --------------------------------------------------------*/ | |
4699 | |
4700 int t30_set_local_sub_address(t30_state_t *s, const char *sub_address) | |
4701 { | |
4702 if (sub_address == NULL) | |
4703 { | |
4704 s->local_sub_address[0] = '\0'; | |
4705 return 0; | |
4706 } | |
4707 if (strlen(sub_address) > 20) | |
4708 return -1; | |
4709 strcpy(s->local_sub_address, sub_address); | |
4710 return 0; | |
4711 } | |
4712 /*- End of function --------------------------------------------------------*/ | |
4713 | |
4714 size_t t30_get_sub_address(t30_state_t *s, char *sub_address) | |
4715 { | |
4716 if (sub_address) | |
4717 strcpy(sub_address, s->far_sub_address); | |
4718 return strlen(s->far_sub_address); | |
4719 } | |
4720 /*- End of function --------------------------------------------------------*/ | |
4721 | |
4722 size_t t30_get_header_info(t30_state_t *s, char *info) | |
4723 { | |
4724 if (info) | |
4725 strcpy(info, s->header_info); | |
4726 return strlen(s->header_info); | |
4727 } | |
4728 /*- End of function --------------------------------------------------------*/ | |
4729 | |
4730 size_t t30_get_local_ident(t30_state_t *s, char *id) | |
4731 { | |
4732 if (id) | |
4733 strcpy(id, s->local_ident); | |
4734 return strlen(s->local_ident); | |
4735 } | |
4736 /*- End of function --------------------------------------------------------*/ | |
4737 | |
4738 size_t t30_get_far_ident(t30_state_t *s, char *id) | |
4739 { | |
4740 if (id) | |
4741 strcpy(id, s->far_ident); | |
4742 return strlen(s->far_ident); | |
4743 } | |
4744 /*- End of function --------------------------------------------------------*/ | |
4745 | |
4746 const char *t30_get_far_country(t30_state_t *s) | |
4747 { | |
4748 return s->country; | |
4749 } | |
4750 /*- End of function --------------------------------------------------------*/ | |
4751 | |
4752 const char *t30_get_far_vendor(t30_state_t *s) | |
4753 { | |
4754 return s->vendor; | |
4755 } | |
4756 /*- End of function --------------------------------------------------------*/ | |
4757 | |
4758 const char *t30_get_far_model(t30_state_t *s) | |
4759 { | |
4760 return s->model; | |
4761 } | |
4762 /*- End of function --------------------------------------------------------*/ | |
4763 | |
4764 void t30_get_transfer_statistics(t30_state_t *s, t30_stats_t *t) | |
4765 { | |
4766 t4_stats_t stats; | |
4767 | |
4768 t->bit_rate = fallback_sequence[s->current_fallback].bit_rate; | |
4769 t->error_correcting_mode = s->error_correcting_mode; | |
4770 t4_get_transfer_statistics(&(s->t4), &stats); | |
4771 t->pages_transferred = stats.pages_transferred; | |
4772 t->width = stats.width; | |
4773 t->length = stats.length; | |
4774 t->bad_rows = stats.bad_rows; | |
4775 t->longest_bad_row_run = stats.longest_bad_row_run; | |
4776 t->x_resolution = stats.x_resolution; | |
4777 t->y_resolution = stats.y_resolution; | |
4778 t->encoding = stats.encoding; | |
4779 t->image_size = stats.image_size; | |
4780 t->current_status = s->current_status; | |
4781 } | |
4782 /*- End of function --------------------------------------------------------*/ | |
4783 | |
4784 void t30_set_phase_b_handler(t30_state_t *s, t30_phase_b_handler_t *handler, void *user_data) | |
4785 { | |
4786 s->phase_b_handler = handler; | |
4787 s->phase_b_user_data = user_data; | |
4788 } | |
4789 /*- End of function --------------------------------------------------------*/ | |
4790 | |
4791 void t30_set_phase_d_handler(t30_state_t *s, t30_phase_d_handler_t *handler, void *user_data) | |
4792 { | |
4793 s->phase_d_handler = handler; | |
4794 s->phase_d_user_data = user_data; | |
4795 } | |
4796 /*- End of function --------------------------------------------------------*/ | |
4797 | |
4798 void t30_set_phase_e_handler(t30_state_t *s, t30_phase_e_handler_t *handler, void *user_data) | |
4799 { | |
4800 s->phase_e_handler = handler; | |
4801 s->phase_e_user_data = user_data; | |
4802 } | |
4803 /*- End of function --------------------------------------------------------*/ | |
4804 | |
4805 void t30_set_document_handler(t30_state_t *s, t30_document_handler_t *handler, void *user_data) | |
4806 { | |
4807 s->document_handler = handler; | |
4808 s->document_user_data = user_data; | |
4809 } | |
4810 /*- End of function --------------------------------------------------------*/ | |
4811 | |
4812 void t30_set_rx_file(t30_state_t *s, const char *file, int stop_page) | |
4813 { | |
4814 strncpy(s->rx_file, file, sizeof(s->rx_file)); | |
4815 s->rx_file[sizeof(s->rx_file) - 1] = '\0'; | |
4816 s->rx_stop_page = stop_page; | |
4817 } | |
4818 /*- End of function --------------------------------------------------------*/ | |
4819 | |
4820 void t30_set_tx_file(t30_state_t *s, const char *file, int start_page, int stop_page) | |
4821 { | |
4822 strncpy(s->tx_file, file, sizeof(s->tx_file)); | |
4823 s->tx_file[sizeof(s->tx_file) - 1] = '\0'; | |
4824 s->tx_start_page = start_page; | |
4825 s->tx_stop_page = stop_page; | |
4826 } | |
4827 /*- End of function --------------------------------------------------------*/ | |
4828 | |
4829 void t30_set_supported_modems(t30_state_t *s, int supported_modems) | |
4830 { | |
4831 s->supported_modems = supported_modems; | |
4832 build_dis_or_dtc(s); | |
4833 } | |
4834 /*- End of function --------------------------------------------------------*/ | |
4835 | |
4836 void t30_set_supported_compressions(t30_state_t *s, int supported_compressions) | |
4837 { | |
4838 s->supported_compressions = supported_compressions; | |
4839 build_dis_or_dtc(s); | |
4840 } | |
4841 /*- End of function --------------------------------------------------------*/ | |
4842 | |
4843 void t30_set_supported_resolutions(t30_state_t *s, int supported_resolutions) | |
4844 { | |
4845 s->supported_resolutions = supported_resolutions; | |
4846 build_dis_or_dtc(s); | |
4847 } | |
4848 /*- End of function --------------------------------------------------------*/ | |
4849 | |
4850 void t30_set_supported_image_sizes(t30_state_t *s, int supported_image_sizes) | |
4851 { | |
4852 s->supported_image_sizes = supported_image_sizes; | |
4853 build_dis_or_dtc(s); | |
4854 } | |
4855 /*- End of function --------------------------------------------------------*/ | |
4856 | |
4857 void t30_set_ecm_capability(t30_state_t *s, int enabled) | |
4858 { | |
4859 s->ecm_allowed = enabled; | |
4860 build_dis_or_dtc(s); | |
4861 } | |
4862 /*- End of function --------------------------------------------------------*/ | |
4863 | |
4864 void t30_local_interrupt_request(t30_state_t *s, int state) | |
4865 { | |
4866 if (s->timer_t3 > 0) | |
4867 { | |
4868 /* Accept the far end's outstanding request for interrupt. */ | |
4869 /* TODO: */ | |
4870 send_simple_frame(s, (state) ? T30_PIP : T30_PIN); | |
4871 } | |
4872 s->local_interrupt_pending = state; | |
4873 } | |
4874 /*- End of function --------------------------------------------------------*/ | |
4875 /*- End of file ------------------------------------------------------------*/ |