5
|
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 ------------------------------------------------------------*/
|