5
|
1 //#define LOG_FAX_AUDIO
|
|
2 /*
|
|
3 * SpanDSP - a series of DSP components for telephony
|
|
4 *
|
|
5 * fax.c - Analogue line ITU T.30 FAX transfer processing
|
|
6 *
|
|
7 * Written by Steve Underwood <steveu@coppice.org>
|
|
8 *
|
|
9 * Copyright (C) 2003, 2005, 2006 Steve Underwood
|
|
10 *
|
|
11 * All rights reserved.
|
|
12 *
|
|
13 * This program is free software; you can redistribute it and/or modify
|
|
14 * it under the terms of the GNU General Public License version 2, as
|
|
15 * published by the Free Software Foundation.
|
|
16 *
|
|
17 * This program is distributed in the hope that it will be useful,
|
|
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
20 * GNU General Public License for more details.
|
|
21 *
|
|
22 * You should have received a copy of the GNU General Public License
|
|
23 * along with this program; if not, write to the Free Software
|
|
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
25 *
|
|
26 * $Id: fax.c,v 1.52 2006/11/19 14:07:24 steveu Exp $
|
|
27 */
|
|
28
|
|
29 /*! \file */
|
|
30
|
|
31 #ifdef HAVE_CONFIG_H
|
|
32 #include <config.h>
|
|
33 #endif
|
|
34
|
|
35 #include <inttypes.h>
|
|
36 #include <stdlib.h>
|
|
37 #include <stdio.h>
|
|
38 #include <string.h>
|
|
39 #if defined(HAVE_TGMATH_H)
|
|
40 #include <tgmath.h>
|
|
41 #endif
|
|
42 #if defined(HAVE_MATH_H)
|
|
43 #include <math.h>
|
|
44 #endif
|
|
45 #include <assert.h>
|
|
46 #include <fcntl.h>
|
|
47 #include <time.h>
|
|
48 #if defined(LOG_FAX_AUDIO)
|
|
49 #include <unistd.h>
|
|
50 #endif
|
|
51
|
|
52 #include <tiffio.h>
|
|
53
|
|
54 #include "spandsp/telephony.h"
|
|
55 #include "spandsp/logging.h"
|
|
56 #include "spandsp/queue.h"
|
|
57 #include "spandsp/dc_restore.h"
|
|
58 #include "spandsp/power_meter.h"
|
|
59 #include "spandsp/complex.h"
|
|
60 #include "spandsp/tone_generate.h"
|
|
61 #include "spandsp/async.h"
|
|
62 #include "spandsp/hdlc.h"
|
|
63 #include "spandsp/silence_gen.h"
|
|
64 #include "spandsp/fsk.h"
|
|
65 #include "spandsp/v29rx.h"
|
|
66 #include "spandsp/v29tx.h"
|
|
67 #include "spandsp/v27ter_rx.h"
|
|
68 #include "spandsp/v27ter_tx.h"
|
|
69 #if defined(ENABLE_V17)
|
|
70 #include "spandsp/v17rx.h"
|
|
71 #include "spandsp/v17tx.h"
|
|
72 #endif
|
|
73 #include "spandsp/t4.h"
|
|
74
|
|
75 #include "spandsp/t30_fcf.h"
|
|
76 #include "spandsp/t35.h"
|
|
77 #include "spandsp/t30.h"
|
|
78
|
|
79 #include "spandsp/fax.h"
|
|
80
|
|
81 static void fax_send_hdlc(void *user_data, const uint8_t *msg, int len)
|
|
82 {
|
|
83 fax_state_t *s;
|
|
84
|
|
85 s = (fax_state_t *) user_data;
|
|
86
|
|
87 hdlc_tx_frame(&(s->hdlctx), msg, len);
|
|
88 s->first_tx_hdlc_frame = FALSE;
|
|
89 }
|
|
90 /*- End of function --------------------------------------------------------*/
|
|
91
|
|
92 static int dummy_rx(void *s, const int16_t amp[], int len)
|
|
93 {
|
|
94 return 0;
|
|
95 }
|
|
96 /*- End of function --------------------------------------------------------*/
|
|
97
|
|
98 #if defined(ENABLE_V17)
|
|
99 static int early_v17_rx(void *user_data, const int16_t amp[], int len)
|
|
100 {
|
|
101 fax_state_t *s;
|
|
102
|
|
103 s = (fax_state_t *) user_data;
|
|
104 v17_rx(&(s->v17rx), amp, len);
|
|
105 fsk_rx(&(s->v21rx), amp, len);
|
|
106 if (s->t30_state.rx_trained)
|
|
107 {
|
|
108 /* The fast modem has trained, so we no longer need to run the slow
|
|
109 one in parallel. */
|
|
110 span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.17 (%.2fdBm0)\n", v17_rx_signal_power(&(s->v17rx)));
|
|
111 s->rx_handler = (span_rx_handler_t *) &v17_rx;
|
|
112 s->rx_user_data = &(s->v17rx);
|
|
113 }
|
|
114 return len;
|
|
115 }
|
|
116 /*- End of function --------------------------------------------------------*/
|
|
117 #endif
|
|
118
|
|
119 static int early_v27ter_rx(void *user_data, const int16_t amp[], int len)
|
|
120 {
|
|
121 fax_state_t *s;
|
|
122
|
|
123 s = (fax_state_t *) user_data;
|
|
124 v27ter_rx(&(s->v27ter_rx), amp, len);
|
|
125 fsk_rx(&(s->v21rx), amp, len);
|
|
126 if (s->t30_state.rx_trained)
|
|
127 {
|
|
128 /* The fast modem has trained, so we no longer need to run the slow
|
|
129 one in parallel. */
|
|
130 span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.27ter (%.2fdBm0)\n", v27ter_rx_signal_power(&(s->v27ter_rx)));
|
|
131 s->rx_handler = (span_rx_handler_t *) &v27ter_rx;
|
|
132 s->rx_user_data = &(s->v27ter_rx);
|
|
133 }
|
|
134 return len;
|
|
135 }
|
|
136 /*- End of function --------------------------------------------------------*/
|
|
137
|
|
138 static int early_v29_rx(void *user_data, const int16_t amp[], int len)
|
|
139 {
|
|
140 fax_state_t *s;
|
|
141
|
|
142 s = (fax_state_t *) user_data;
|
|
143 v29_rx(&(s->v29rx), amp, len);
|
|
144 fsk_rx(&(s->v21rx), amp, len);
|
|
145 if (s->t30_state.rx_trained)
|
|
146 {
|
|
147 /* The fast modem has trained, so we no longer need to run the slow
|
|
148 one in parallel. */
|
|
149 span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.29 (%.2fdBm0)\n", v29_rx_signal_power(&(s->v29rx)));
|
|
150 s->rx_handler = (span_rx_handler_t *) &v29_rx;
|
|
151 s->rx_user_data = &(s->v29rx);
|
|
152 }
|
|
153 return len;
|
|
154 }
|
|
155 /*- End of function --------------------------------------------------------*/
|
|
156
|
|
157 int fax_rx(fax_state_t *s, int16_t *amp, int len)
|
|
158 {
|
|
159 int i;
|
|
160
|
|
161 #if defined(LOG_FAX_AUDIO)
|
|
162 if (s->fax_audio_rx_log >= 0)
|
|
163 write(s->fax_audio_rx_log, amp, len*sizeof(int16_t));
|
|
164 #endif
|
|
165 for (i = 0; i < len; i++)
|
|
166 amp[i] = dc_restore(&(s->dc_restore), amp[i]);
|
|
167 s->rx_handler(s->rx_user_data, amp, len);
|
|
168 t30_timer_update(&(s->t30_state), len);
|
|
169 return 0;
|
|
170 }
|
|
171 /*- End of function --------------------------------------------------------*/
|
|
172
|
|
173 static int set_next_tx_type(fax_state_t *s)
|
|
174 {
|
|
175 if (s->next_tx_handler)
|
|
176 {
|
|
177 s->tx_handler = s->next_tx_handler;
|
|
178 s->tx_user_data = s->next_tx_user_data;
|
|
179 s->next_tx_handler = NULL;
|
|
180 return 0;
|
|
181 }
|
|
182 /* If there is nothing else to change to, so use zero length silence */
|
|
183 silence_gen_alter(&(s->silence_gen), 0);
|
|
184 s->tx_handler = (span_tx_handler_t *) &silence_gen;
|
|
185 s->tx_user_data = &(s->silence_gen);
|
|
186 s->next_tx_handler = NULL;
|
|
187 s->transmit = FALSE;
|
|
188 return -1;
|
|
189 }
|
|
190 /*- End of function --------------------------------------------------------*/
|
|
191
|
|
192 int fax_tx(fax_state_t *s, int16_t *amp, int max_len)
|
|
193 {
|
|
194 int len;
|
|
195 #if defined(LOG_FAX_AUDIO)
|
|
196 int required_len;
|
|
197
|
|
198 required_len = max_len;
|
|
199 #endif
|
|
200 len = 0;
|
|
201 if (s->transmit)
|
|
202 {
|
|
203 while ((len += s->tx_handler(s->tx_user_data, amp + len, max_len - len)) < max_len)
|
|
204 {
|
|
205 /* Allow for a change of tx handler within a block */
|
|
206 if (set_next_tx_type(s) && s->current_tx_type != T30_MODEM_NONE && s->current_tx_type != T30_MODEM_DONE)
|
|
207 t30_send_complete(&(s->t30_state));
|
|
208 if (!s->transmit)
|
|
209 {
|
|
210 if (s->transmit_on_idle)
|
|
211 {
|
|
212 /* Pad to the requested length with silence */
|
|
213 memset(amp + len, 0, (max_len - len)*sizeof(int16_t));
|
|
214 len = max_len;
|
|
215 }
|
|
216 break;
|
|
217 }
|
|
218 }
|
|
219 }
|
|
220 else
|
|
221 {
|
|
222 if (s->transmit_on_idle)
|
|
223 {
|
|
224 /* Pad to the requested length with silence */
|
|
225 memset(amp, 0, max_len*sizeof(int16_t));
|
|
226 len = max_len;
|
|
227 }
|
|
228 }
|
|
229 #if defined(LOG_FAX_AUDIO)
|
|
230 if (s->fax_audio_tx_log >= 0)
|
|
231 {
|
|
232 if (len < required_len)
|
|
233 memset(amp + len, 0, (required_len - len)*sizeof(int16_t));
|
|
234 write(s->fax_audio_tx_log, amp, required_len*sizeof(int16_t));
|
|
235 }
|
|
236 #endif
|
|
237 return len;
|
|
238 }
|
|
239 /*- End of function --------------------------------------------------------*/
|
|
240
|
|
241 static void fax_set_rx_type(void *user_data, int type, int short_train, int use_hdlc)
|
|
242 {
|
|
243 fax_state_t *s;
|
|
244 put_bit_func_t put_bit_func;
|
|
245 void *put_bit_user_data;
|
|
246
|
|
247 s = (fax_state_t *) user_data;
|
|
248 span_log(&s->logging, SPAN_LOG_FLOW, "Set rx type %d\n", type);
|
|
249 if (s->current_rx_type == type)
|
|
250 return;
|
|
251 s->current_rx_type = type;
|
|
252 if (use_hdlc)
|
|
253 {
|
|
254 put_bit_func = (put_bit_func_t) hdlc_rx_put_bit;
|
|
255 put_bit_user_data = (void *) &(s->hdlcrx);
|
|
256 hdlc_rx_init(&(s->hdlcrx), FALSE, FALSE, 5, t30_hdlc_accept, &(s->t30_state));
|
|
257 }
|
|
258 else
|
|
259 {
|
|
260 put_bit_func = t30_non_ecm_put_bit;
|
|
261 put_bit_user_data = (void *) &(s->t30_state);
|
|
262 }
|
|
263 switch (type)
|
|
264 {
|
|
265 case T30_MODEM_V21:
|
|
266 if (s->flush_handler)
|
|
267 s->flush_handler(s, s->flush_user_data, 3);
|
|
268 fsk_rx_init(&(s->v21rx), &preset_fsk_specs[FSK_V21CH2], TRUE, (put_bit_func_t) hdlc_rx_put_bit, put_bit_user_data);
|
|
269 s->rx_handler = (span_rx_handler_t *) &fsk_rx;
|
|
270 s->rx_user_data = &(s->v21rx);
|
|
271 break;
|
|
272 case T30_MODEM_V27TER_2400:
|
|
273 v27ter_rx_restart(&(s->v27ter_rx), 2400, FALSE);
|
|
274 v27ter_rx_set_put_bit(&(s->v27ter_rx), put_bit_func, put_bit_user_data);
|
|
275 s->rx_handler = (span_rx_handler_t *) &early_v27ter_rx;
|
|
276 s->rx_user_data = s;
|
|
277 break;
|
|
278 case T30_MODEM_V27TER_4800:
|
|
279 v27ter_rx_restart(&(s->v27ter_rx), 4800, FALSE);
|
|
280 v27ter_rx_set_put_bit(&(s->v27ter_rx), put_bit_func, put_bit_user_data);
|
|
281 s->rx_handler = (span_rx_handler_t *) &early_v27ter_rx;
|
|
282 s->rx_user_data = s;
|
|
283 break;
|
|
284 case T30_MODEM_V29_7200:
|
|
285 v29_rx_restart(&(s->v29rx), 7200, FALSE);
|
|
286 v29_rx_set_put_bit(&(s->v29rx), put_bit_func, put_bit_user_data);
|
|
287 s->rx_handler = (span_rx_handler_t *) &early_v29_rx;
|
|
288 s->rx_user_data = s;
|
|
289 break;
|
|
290 case T30_MODEM_V29_9600:
|
|
291 v29_rx_restart(&(s->v29rx), 9600, FALSE);
|
|
292 v29_rx_set_put_bit(&(s->v29rx), put_bit_func, put_bit_user_data);
|
|
293 s->rx_handler = (span_rx_handler_t *) &early_v29_rx;
|
|
294 s->rx_user_data = s;
|
|
295 break;
|
|
296 #if defined(ENABLE_V17)
|
|
297 case T30_MODEM_V17_7200:
|
|
298 v17_rx_restart(&(s->v17rx), 7200, short_train);
|
|
299 v17_rx_set_put_bit(&(s->v17rx), put_bit_func, put_bit_user_data);
|
|
300 s->rx_handler = (span_rx_handler_t *) &early_v17_rx;
|
|
301 s->rx_user_data = s;
|
|
302 break;
|
|
303 case T30_MODEM_V17_9600:
|
|
304 v17_rx_restart(&(s->v17rx), 9600, short_train);
|
|
305 v17_rx_set_put_bit(&(s->v17rx), put_bit_func, put_bit_user_data);
|
|
306 s->rx_handler = (span_rx_handler_t *) &early_v17_rx;
|
|
307 s->rx_user_data = s;
|
|
308 break;
|
|
309 case T30_MODEM_V17_12000:
|
|
310 v17_rx_restart(&(s->v17rx), 12000, short_train);
|
|
311 v17_rx_set_put_bit(&(s->v17rx), put_bit_func, put_bit_user_data);
|
|
312 s->rx_handler = (span_rx_handler_t *) &early_v17_rx;
|
|
313 s->rx_user_data = s;
|
|
314 break;
|
|
315 case T30_MODEM_V17_14400:
|
|
316 v17_rx_restart(&(s->v17rx), 14400, short_train);
|
|
317 v17_rx_set_put_bit(&(s->v17rx), put_bit_func, put_bit_user_data);
|
|
318 s->rx_handler = (span_rx_handler_t *) &early_v17_rx;
|
|
319 s->rx_user_data = s;
|
|
320 break;
|
|
321 #endif
|
|
322 case T30_MODEM_DONE:
|
|
323 span_log(&s->logging, SPAN_LOG_FLOW, "FAX exchange complete\n");
|
|
324 default:
|
|
325 s->rx_handler = (span_rx_handler_t *) &dummy_rx;
|
|
326 s->rx_user_data = s;
|
|
327 break;
|
|
328 }
|
|
329 }
|
|
330 /*- End of function --------------------------------------------------------*/
|
|
331
|
|
332 static void fax_set_tx_type(void *user_data, int type, int short_train, int use_hdlc)
|
|
333 {
|
|
334 fax_state_t *s;
|
|
335 tone_gen_descriptor_t tone_desc;
|
|
336 get_bit_func_t get_bit_func;
|
|
337 void *get_bit_user_data;
|
|
338
|
|
339 s = (fax_state_t *) user_data;
|
|
340 span_log(&s->logging, SPAN_LOG_FLOW, "Set tx type %d\n", type);
|
|
341 if (s->current_tx_type == type)
|
|
342 return;
|
|
343 s->first_tx_hdlc_frame = TRUE;
|
|
344 if (use_hdlc)
|
|
345 {
|
|
346 get_bit_func = (get_bit_func_t) hdlc_tx_get_bit;
|
|
347 get_bit_user_data = (void *) &(s->hdlctx);
|
|
348 }
|
|
349 else
|
|
350 {
|
|
351 get_bit_func = t30_non_ecm_get_bit;
|
|
352 get_bit_user_data = (void *) &(s->t30_state);
|
|
353 }
|
|
354 switch (type)
|
|
355 {
|
|
356 case T30_MODEM_PAUSE:
|
|
357 silence_gen_alter(&(s->silence_gen), ms_to_samples(short_train));
|
|
358 s->tx_handler = (span_tx_handler_t *) &silence_gen;
|
|
359 s->tx_user_data = &(s->silence_gen);
|
|
360 s->next_tx_handler = NULL;
|
|
361 s->transmit = TRUE;
|
|
362 break;
|
|
363 case T30_MODEM_CNG:
|
|
364 /* 0.5s of 1100Hz+-38Hz + 3.0s of silence repeating. Timing +-15% */
|
|
365 make_tone_gen_descriptor(&tone_desc,
|
|
366 1100,
|
|
367 -11,
|
|
368 0,
|
|
369 0,
|
|
370 500,
|
|
371 3000,
|
|
372 0,
|
|
373 0,
|
|
374 TRUE);
|
|
375 tone_gen_init(&(s->tone_gen), &tone_desc);
|
|
376 s->tx_handler = (span_tx_handler_t *) &tone_gen;
|
|
377 s->tx_user_data = &(s->tone_gen);
|
|
378 s->next_tx_handler = NULL;
|
|
379 s->transmit = TRUE;
|
|
380 break;
|
|
381 case T30_MODEM_CED:
|
|
382 /* 0.2s of silence, then 2.6s to 4s of 2100Hz+-15Hz tone, then 75ms of silence. The 75ms of silence
|
|
383 will be inserted by the pre V.21 pause we use for any switch to V.21. */
|
|
384 silence_gen_alter(&(s->silence_gen), ms_to_samples(200));
|
|
385 make_tone_gen_descriptor(&tone_desc,
|
|
386 2100,
|
|
387 -11,
|
|
388 0,
|
|
389 0,
|
|
390 2600,
|
|
391 0,
|
|
392 0,
|
|
393 0,
|
|
394 FALSE);
|
|
395 tone_gen_init(&(s->tone_gen), &tone_desc);
|
|
396 s->tx_handler = (span_tx_handler_t *) &silence_gen;
|
|
397 s->tx_user_data = &(s->silence_gen);
|
|
398 s->next_tx_handler = (span_tx_handler_t *) &tone_gen;
|
|
399 s->next_tx_user_data = &(s->tone_gen);
|
|
400 s->transmit = TRUE;
|
|
401 break;
|
|
402 case T30_MODEM_V21:
|
|
403 fsk_tx_init(&(s->v21tx), &preset_fsk_specs[FSK_V21CH2], get_bit_func, get_bit_user_data);
|
|
404 /* The spec says 1s +-15% of preamble. So, the minimum is 32 octets. */
|
|
405 hdlc_tx_preamble(&(s->hdlctx), 32);
|
|
406 /* Pause before switching from phase C, as per T.30 5.3.2.2. If we omit this, the receiver
|
|
407 might not see the carrier fall between the high speed and low speed sections. In practice,
|
|
408 a 75ms gap before any V.21 transmission is harmless, adds little to the overall length of
|
|
409 a call, and ensures the receiving end is ready. */
|
|
410 silence_gen_alter(&(s->silence_gen), ms_to_samples(75));
|
|
411 s->tx_handler = (span_tx_handler_t *) &silence_gen;
|
|
412 s->tx_user_data = &(s->silence_gen);
|
|
413 s->next_tx_handler = (span_tx_handler_t *) &fsk_tx;
|
|
414 s->next_tx_user_data = &(s->v21tx);
|
|
415 s->transmit = TRUE;
|
|
416 break;
|
|
417 case T30_MODEM_V27TER_2400:
|
|
418 silence_gen_alter(&(s->silence_gen), ms_to_samples(75));
|
|
419 v27ter_tx_restart(&(s->v27ter_tx), 2400, s->use_tep);
|
|
420 v27ter_tx_set_get_bit(&(s->v27ter_tx), get_bit_func, get_bit_user_data);
|
|
421 s->tx_handler = (span_tx_handler_t *) &silence_gen;
|
|
422 s->tx_user_data = &(s->silence_gen);
|
|
423 s->next_tx_handler = (span_tx_handler_t *) &v27ter_tx;
|
|
424 s->next_tx_user_data = &(s->v27ter_tx);
|
|
425 hdlc_tx_preamble(&(s->hdlctx), 60);
|
|
426 s->transmit = TRUE;
|
|
427 break;
|
|
428 case T30_MODEM_V27TER_4800:
|
|
429 silence_gen_alter(&(s->silence_gen), ms_to_samples(75));
|
|
430 v27ter_tx_restart(&(s->v27ter_tx), 4800, s->use_tep);
|
|
431 v27ter_tx_set_get_bit(&(s->v27ter_tx), get_bit_func, get_bit_user_data);
|
|
432 s->tx_handler = (span_tx_handler_t *) &silence_gen;
|
|
433 s->tx_user_data = &(s->silence_gen);
|
|
434 s->next_tx_handler = (span_tx_handler_t *) &v27ter_tx;
|
|
435 s->next_tx_user_data = &(s->v27ter_tx);
|
|
436 hdlc_tx_preamble(&(s->hdlctx), 120);
|
|
437 s->transmit = TRUE;
|
|
438 break;
|
|
439 case T30_MODEM_V29_7200:
|
|
440 silence_gen_alter(&(s->silence_gen), ms_to_samples(75));
|
|
441 v29_tx_restart(&(s->v29tx), 7200, s->use_tep);
|
|
442 v29_tx_set_get_bit(&(s->v29tx), get_bit_func, get_bit_user_data);
|
|
443 s->tx_handler = (span_tx_handler_t *) &silence_gen;
|
|
444 s->tx_user_data = &(s->silence_gen);
|
|
445 s->next_tx_handler = (span_tx_handler_t *) &v29_tx;
|
|
446 s->next_tx_user_data = &(s->v29tx);
|
|
447 hdlc_tx_preamble(&(s->hdlctx), 180);
|
|
448 s->transmit = TRUE;
|
|
449 break;
|
|
450 case T30_MODEM_V29_9600:
|
|
451 silence_gen_alter(&(s->silence_gen), ms_to_samples(75));
|
|
452 v29_tx_restart(&(s->v29tx), 9600, s->use_tep);
|
|
453 v29_tx_set_get_bit(&(s->v29tx), get_bit_func, get_bit_user_data);
|
|
454 s->tx_handler = (span_tx_handler_t *) &silence_gen;
|
|
455 s->tx_user_data = &(s->silence_gen);
|
|
456 s->next_tx_handler = (span_tx_handler_t *) &v29_tx;
|
|
457 s->next_tx_user_data = &(s->v29tx);
|
|
458 hdlc_tx_preamble(&(s->hdlctx), 240);
|
|
459 s->transmit = TRUE;
|
|
460 break;
|
|
461 #if defined(ENABLE_V17)
|
|
462 case T30_MODEM_V17_7200:
|
|
463 silence_gen_alter(&(s->silence_gen), ms_to_samples(75));
|
|
464 v17_tx_restart(&(s->v17tx), 7200, s->use_tep, short_train);
|
|
465 v17_tx_set_get_bit(&(s->v17tx), get_bit_func, get_bit_user_data);
|
|
466 s->tx_handler = (span_tx_handler_t *) &silence_gen;
|
|
467 s->tx_user_data = &(s->silence_gen);
|
|
468 s->next_tx_handler = (span_tx_handler_t *) &v17_tx;
|
|
469 s->next_tx_user_data = &(s->v17tx);
|
|
470 hdlc_tx_preamble(&(s->hdlctx), 180);
|
|
471 s->transmit = TRUE;
|
|
472 break;
|
|
473 case T30_MODEM_V17_9600:
|
|
474 silence_gen_alter(&(s->silence_gen), ms_to_samples(75));
|
|
475 v17_tx_restart(&(s->v17tx), 9600, s->use_tep, short_train);
|
|
476 v17_tx_set_get_bit(&(s->v17tx), get_bit_func, get_bit_user_data);
|
|
477 s->tx_handler = (span_tx_handler_t *) &silence_gen;
|
|
478 s->tx_user_data = &(s->silence_gen);
|
|
479 s->next_tx_handler = (span_tx_handler_t *) &v17_tx;
|
|
480 s->next_tx_user_data = &(s->v17tx);
|
|
481 hdlc_tx_preamble(&(s->hdlctx), 240);
|
|
482 s->transmit = TRUE;
|
|
483 break;
|
|
484 case T30_MODEM_V17_12000:
|
|
485 silence_gen_alter(&(s->silence_gen), ms_to_samples(75));
|
|
486 v17_tx_restart(&(s->v17tx), 12000, s->use_tep, short_train);
|
|
487 v17_tx_set_get_bit(&(s->v17tx), get_bit_func, get_bit_user_data);
|
|
488 s->tx_handler = (span_tx_handler_t *) &silence_gen;
|
|
489 s->tx_user_data = &(s->silence_gen);
|
|
490 s->next_tx_handler = (span_tx_handler_t *) &v17_tx;
|
|
491 s->next_tx_user_data = &(s->v17tx);
|
|
492 hdlc_tx_preamble(&(s->hdlctx), 300);
|
|
493 s->transmit = TRUE;
|
|
494 break;
|
|
495 case T30_MODEM_V17_14400:
|
|
496 silence_gen_alter(&(s->silence_gen), ms_to_samples(75));
|
|
497 v17_tx_restart(&(s->v17tx), 14400, s->use_tep, short_train);
|
|
498 v17_tx_set_get_bit(&(s->v17tx), get_bit_func, get_bit_user_data);
|
|
499 s->tx_handler = (span_tx_handler_t *) &silence_gen;
|
|
500 s->tx_user_data = &(s->silence_gen);
|
|
501 s->next_tx_handler = (span_tx_handler_t *) &v17_tx;
|
|
502 s->next_tx_user_data = &(s->v17tx);
|
|
503 hdlc_tx_preamble(&(s->hdlctx), 360);
|
|
504 s->transmit = TRUE;
|
|
505 break;
|
|
506 #endif
|
|
507 case T30_MODEM_DONE:
|
|
508 span_log(&s->logging, SPAN_LOG_FLOW, "FAX exchange complete\n");
|
|
509 /* Fall through */
|
|
510 default:
|
|
511 silence_gen_alter(&(s->silence_gen), 0);
|
|
512 s->tx_handler = (span_tx_handler_t *) &silence_gen;
|
|
513 s->tx_user_data = &(s->silence_gen);
|
|
514 s->next_tx_handler = NULL;
|
|
515 s->transmit = FALSE;
|
|
516 break;
|
|
517 }
|
|
518 s->current_tx_type = type;
|
|
519 }
|
|
520 /*- End of function --------------------------------------------------------*/
|
|
521
|
|
522 void fax_set_transmit_on_idle(fax_state_t *s, int transmit_on_idle)
|
|
523 {
|
|
524 s->transmit_on_idle = transmit_on_idle;
|
|
525 }
|
|
526 /*- End of function --------------------------------------------------------*/
|
|
527
|
|
528 void fax_set_tep_mode(fax_state_t *s, int use_tep)
|
|
529 {
|
|
530 s->use_tep = use_tep;
|
|
531 }
|
|
532 /*- End of function --------------------------------------------------------*/
|
|
533
|
|
534 int fax_init(fax_state_t *s, int calling_party)
|
|
535 {
|
|
536 memset(s, 0, sizeof(*s));
|
|
537 span_log_init(&s->logging, SPAN_LOG_NONE, NULL);
|
|
538 span_log_set_protocol(&s->logging, "FAX");
|
|
539 t30_init(&(s->t30_state),
|
|
540 calling_party,
|
|
541 fax_set_rx_type,
|
|
542 (void *) s,
|
|
543 fax_set_tx_type,
|
|
544 (void *) s,
|
|
545 fax_send_hdlc,
|
|
546 (void *) s);
|
|
547 t30_set_supported_modems(&(s->t30_state),
|
|
548 #if defined(ENABLE_V17)
|
|
549 T30_SUPPORT_V27TER | T30_SUPPORT_V29 | T30_SUPPORT_V17);
|
|
550 #else
|
|
551 T30_SUPPORT_V27TER | T30_SUPPORT_V29);
|
|
552 #endif
|
|
553 hdlc_rx_init(&(s->hdlcrx), FALSE, FALSE, 5, t30_hdlc_accept, &(s->t30_state));
|
|
554 fsk_rx_init(&(s->v21rx), &preset_fsk_specs[FSK_V21CH2], TRUE, (put_bit_func_t) hdlc_rx_put_bit, &(s->hdlcrx));
|
|
555 hdlc_tx_init(&(s->hdlctx), FALSE, 2, FALSE, t30_send_complete, &(s->t30_state));
|
|
556 s->first_tx_hdlc_frame = TRUE;
|
|
557 fsk_tx_init(&(s->v21tx), &preset_fsk_specs[FSK_V21CH2], (get_bit_func_t) hdlc_tx_get_bit, &(s->hdlctx));
|
|
558 #if defined(ENABLE_V17)
|
|
559 v17_rx_init(&(s->v17rx), 14400, t30_non_ecm_put_bit, &(s->t30_state));
|
|
560 v17_tx_init(&(s->v17tx), 14400, s->use_tep, t30_non_ecm_get_bit, &(s->t30_state));
|
|
561 #endif
|
|
562 v29_rx_init(&(s->v29rx), 9600, t30_non_ecm_put_bit, &(s->t30_state));
|
|
563 v29_rx_signal_cutoff(&(s->v29rx), -45.5);
|
|
564 v29_tx_init(&(s->v29tx), 9600, s->use_tep, t30_non_ecm_get_bit, &(s->t30_state));
|
|
565 v27ter_rx_init(&(s->v27ter_rx), 4800, t30_non_ecm_put_bit, &(s->t30_state));
|
|
566 v27ter_tx_init(&(s->v27ter_tx), 4800, s->use_tep, t30_non_ecm_get_bit, &(s->t30_state));
|
|
567 silence_gen_init(&(s->silence_gen), 0);
|
|
568 dc_restore_init(&(s->dc_restore));
|
|
569 t30_restart(&(s->t30_state));
|
|
570 #if defined(LOG_FAX_AUDIO)
|
|
571 {
|
|
572 char buf[100 + 1];
|
|
573 struct tm *tm;
|
|
574 time_t now;
|
|
575
|
|
576 time(&now);
|
|
577 tm = localtime(&now);
|
|
578 sprintf(buf,
|
|
579 "/tmp/fax-rx-audio-%x-%02d%02d%02d%02d%02d%02d",
|
|
580 s,
|
|
581 tm->tm_year%100,
|
|
582 tm->tm_mon + 1,
|
|
583 tm->tm_mday,
|
|
584 tm->tm_hour,
|
|
585 tm->tm_min,
|
|
586 tm->tm_sec);
|
|
587 s->fax_audio_rx_log = open(buf, O_CREAT | O_TRUNC | O_WRONLY, 0666);
|
|
588 sprintf(buf,
|
|
589 "/tmp/fax-tx-audio-%x-%02d%02d%02d%02d%02d%02d",
|
|
590 s,
|
|
591 tm->tm_year%100,
|
|
592 tm->tm_mon + 1,
|
|
593 tm->tm_mday,
|
|
594 tm->tm_hour,
|
|
595 tm->tm_min,
|
|
596 tm->tm_sec);
|
|
597 s->fax_audio_tx_log = open(buf, O_CREAT | O_TRUNC | O_WRONLY, 0666);
|
|
598 }
|
|
599 #endif
|
|
600 return 0;
|
|
601 }
|
|
602 /*- End of function --------------------------------------------------------*/
|
|
603
|
|
604 int fax_release(fax_state_t *s)
|
|
605 {
|
|
606 t30_release(&s->t30_state);
|
|
607 return 0;
|
|
608 }
|
|
609 /*- End of function --------------------------------------------------------*/
|
|
610
|
|
611 void fax_set_flush_handler(fax_state_t *s, fax_flush_handler_t *handler, void *user_data)
|
|
612 {
|
|
613 s->flush_handler = handler;
|
|
614 s->flush_user_data = user_data;
|
|
615 }
|
|
616 /*- End of function --------------------------------------------------------*/
|
|
617 /*- End of file ------------------------------------------------------------*/
|