Mercurial > hg > audiostuff
comparison spandsp-0.0.6pre17/tests/fax_tester.c @ 4:26cd8f1ef0b1
import spandsp-0.0.6pre17
author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
---|---|
date | Fri, 25 Jun 2010 15:50:58 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
3:c6c5a16ce2f2 | 4:26cd8f1ef0b1 |
---|---|
1 /* | |
2 * SpanDSP - a series of DSP components for telephony | |
3 * | |
4 * faxtester_tests.c | |
5 * | |
6 * Written by Steve Underwood <steveu@coppice.org> | |
7 * | |
8 * Copyright (C) 2008 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 Lesser General Public License version 2.1, | |
14 * as 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 Lesser General Public License for more details. | |
20 * | |
21 * You should have received a copy of the GNU Lesser General Public | |
22 * License along with this program; if not, write to the Free Software | |
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
24 * | |
25 * $Id: fax_tester.c,v 1.23 2009/11/02 13:25:20 steveu Exp $ | |
26 */ | |
27 | |
28 /*! \file */ | |
29 | |
30 #if defined(HAVE_CONFIG_H) | |
31 #include <config.h> | |
32 #endif | |
33 | |
34 #include <inttypes.h> | |
35 #include <stdlib.h> | |
36 #include <stdio.h> | |
37 #include <string.h> | |
38 #if defined(HAVE_TGMATH_H) | |
39 #include <tgmath.h> | |
40 #endif | |
41 #if defined(HAVE_MATH_H) | |
42 #include <math.h> | |
43 #endif | |
44 #include "floating_fudge.h" | |
45 #include <assert.h> | |
46 #include <fcntl.h> | |
47 #include <time.h> | |
48 #include <unistd.h> | |
49 | |
50 #if defined(HAVE_LIBXML_XMLMEMORY_H) | |
51 #include <libxml/xmlmemory.h> | |
52 #endif | |
53 #if defined(HAVE_LIBXML_PARSER_H) | |
54 #include <libxml/parser.h> | |
55 #endif | |
56 #if defined(HAVE_LIBXML_XINCLUDE_H) | |
57 #include <libxml/xinclude.h> | |
58 #endif | |
59 | |
60 //#if defined(WITH_SPANDSP_INTERNALS) | |
61 #define SPANDSP_EXPOSE_INTERNAL_STRUCTURES | |
62 //#endif | |
63 | |
64 #include "spandsp.h" | |
65 | |
66 #include "fax_tester.h" | |
67 | |
68 #define HDLC_FRAMING_OK_THRESHOLD 5 | |
69 | |
70 static void timer_update(faxtester_state_t *s, int len) | |
71 { | |
72 s->timer += len; | |
73 if (s->timer > s->timeout) | |
74 { | |
75 s->timeout = 0x7FFFFFFFFFFFFFFFLL; | |
76 if (s->front_end_step_timeout_handler) | |
77 s->front_end_step_timeout_handler(s, s->front_end_step_timeout_user_data); | |
78 } | |
79 } | |
80 /*- End of function --------------------------------------------------------*/ | |
81 | |
82 static void front_end_step_complete(faxtester_state_t *s) | |
83 { | |
84 if (s->front_end_step_complete_handler) | |
85 s->front_end_step_complete_handler(s, s->front_end_step_complete_user_data); | |
86 } | |
87 /*- End of function --------------------------------------------------------*/ | |
88 | |
89 void faxtester_send_hdlc_flags(faxtester_state_t *s, int flags) | |
90 { | |
91 hdlc_tx_flags(&(s->modems.hdlc_tx), flags); | |
92 } | |
93 /*- End of function --------------------------------------------------------*/ | |
94 | |
95 void faxtester_send_hdlc_msg(faxtester_state_t *s, const uint8_t *msg, int len, int crc_ok) | |
96 { | |
97 hdlc_tx_frame(&(s->modems.hdlc_tx), msg, len); | |
98 if (!crc_ok) | |
99 hdlc_tx_corrupt_frame(&(s->modems.hdlc_tx)); | |
100 } | |
101 /*- End of function --------------------------------------------------------*/ | |
102 | |
103 static void hdlc_underflow_handler(void *user_data) | |
104 { | |
105 faxtester_state_t *s; | |
106 uint8_t buf[400]; | |
107 | |
108 s = (faxtester_state_t *) user_data; | |
109 | |
110 if (s->image_buffer) | |
111 { | |
112 /* We are sending an ECM image */ | |
113 if (s->image_ptr < s->image_len) | |
114 { | |
115 buf[0] = 0xFF; | |
116 buf[1] = 0x03; | |
117 buf[2] = 0x06; | |
118 buf[3] = s->image_ptr/s->ecm_frame_size; | |
119 memcpy(buf + 4, &s->image_buffer[s->image_ptr], s->ecm_frame_size); | |
120 hdlc_tx_frame(&(s->modems.hdlc_tx), buf, 4 + s->ecm_frame_size); | |
121 if (s->corrupt_crc >= 0 && s->corrupt_crc == s->image_ptr/s->ecm_frame_size) | |
122 hdlc_tx_corrupt_frame(&(s->modems.hdlc_tx)); | |
123 s->image_ptr += s->ecm_frame_size; | |
124 return; | |
125 } | |
126 else | |
127 { | |
128 /* The actual image is over. We are sending the final RCP frames. */ | |
129 if (s->image_bit_ptr > 2) | |
130 { | |
131 s->image_bit_ptr--; | |
132 buf[0] = 0xFF; | |
133 buf[1] = 0x03; | |
134 buf[2] = 0x86; | |
135 hdlc_tx_frame(&(s->modems.hdlc_tx), buf, 3); | |
136 return; | |
137 } | |
138 else | |
139 { | |
140 /* All done. */ | |
141 s->image_buffer = NULL; | |
142 } | |
143 } | |
144 } | |
145 front_end_step_complete(s); | |
146 } | |
147 /*- End of function --------------------------------------------------------*/ | |
148 | |
149 static void modem_tx_status(void *user_data, int status) | |
150 { | |
151 faxtester_state_t *s; | |
152 | |
153 s = (faxtester_state_t *) user_data; | |
154 printf("Tx status is %s (%d)\n", signal_status_to_str(status), status); | |
155 switch (status) | |
156 { | |
157 case SIG_STATUS_SHUTDOWN_COMPLETE: | |
158 front_end_step_complete(s); | |
159 break; | |
160 } | |
161 } | |
162 /*- End of function --------------------------------------------------------*/ | |
163 | |
164 static void tone_detected(void *user_data, int tone, int level, int delay) | |
165 { | |
166 faxtester_state_t *s; | |
167 | |
168 s = (faxtester_state_t *) user_data; | |
169 span_log(&s->logging, | |
170 SPAN_LOG_FLOW, | |
171 "%s (%d) declared (%ddBm0)\n", | |
172 modem_connect_tone_to_str(tone), | |
173 tone, | |
174 level); | |
175 if (tone != MODEM_CONNECT_TONES_NONE) | |
176 { | |
177 s->tone_on_time = s->timer; | |
178 } | |
179 else | |
180 { | |
181 span_log(&s->logging, | |
182 SPAN_LOG_FLOW, | |
183 "Tone was on for %fs\n", | |
184 (float) (s->timer - s->tone_on_time)/SAMPLE_RATE + 0.55); | |
185 } | |
186 s->tone_state = tone; | |
187 if (tone == MODEM_CONNECT_TONES_NONE) | |
188 front_end_step_complete(s); | |
189 } | |
190 /*- End of function --------------------------------------------------------*/ | |
191 | |
192 static int non_ecm_get_bit(void *user_data) | |
193 { | |
194 faxtester_state_t *s; | |
195 int bit; | |
196 | |
197 s = (faxtester_state_t *) user_data; | |
198 if (s->image_bit_ptr == 0) | |
199 { | |
200 if (s->image_ptr >= s->image_len) | |
201 { | |
202 s->image_buffer = NULL; | |
203 return SIG_STATUS_END_OF_DATA; | |
204 } | |
205 s->image_bit_ptr = 8; | |
206 s->image_ptr++; | |
207 } | |
208 s->image_bit_ptr--; | |
209 bit = (s->image_buffer[s->image_ptr] >> (7 - s->image_bit_ptr)) & 0x01; | |
210 //printf("Rx bit - %d\n", bit); | |
211 return bit; | |
212 } | |
213 /*- End of function --------------------------------------------------------*/ | |
214 | |
215 void faxtester_set_non_ecm_image_buffer(faxtester_state_t *s, const uint8_t *buf, int len) | |
216 { | |
217 s->image_ptr = 0; | |
218 s->image_bit_ptr = 8; | |
219 s->image_len = len; | |
220 s->image_buffer = buf; | |
221 } | |
222 /*- End of function --------------------------------------------------------*/ | |
223 | |
224 void faxtester_set_ecm_image_buffer(faxtester_state_t *s, const uint8_t *buf, int len, int block, int frame_size, int crc_hit) | |
225 { | |
226 int start; | |
227 | |
228 start = 256*frame_size*block; | |
229 if (len > start + 256*frame_size) | |
230 len = start + 256*frame_size; | |
231 | |
232 s->ecm_frame_size = frame_size; | |
233 s->image_ptr = start; | |
234 s->image_bit_ptr = 8; | |
235 s->image_len = len; | |
236 s->image_buffer = buf; | |
237 s->corrupt_crc = crc_hit; | |
238 /* Send the first frame */ | |
239 hdlc_underflow_handler(s); | |
240 } | |
241 /*- End of function --------------------------------------------------------*/ | |
242 | |
243 static void non_ecm_rx_status(void *user_data, int status) | |
244 { | |
245 faxtester_state_t *s; | |
246 | |
247 s = (faxtester_state_t *) user_data; | |
248 span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier status is %s (%d)\n", signal_status_to_str(status), status); | |
249 switch (status) | |
250 { | |
251 case SIG_STATUS_TRAINING_FAILED: | |
252 s->modems.rx_trained = FALSE; | |
253 break; | |
254 case SIG_STATUS_TRAINING_SUCCEEDED: | |
255 /* The modem is now trained */ | |
256 s->modems.rx_trained = TRUE; | |
257 break; | |
258 case SIG_STATUS_CARRIER_UP: | |
259 s->modems.rx_signal_present = TRUE; | |
260 break; | |
261 case SIG_STATUS_CARRIER_DOWN: | |
262 if (s->modems.rx_trained) | |
263 { | |
264 if (s->real_time_frame_handler) | |
265 s->real_time_frame_handler(s, s->real_time_frame_user_data, TRUE, NULL, 0); | |
266 } | |
267 s->modems.rx_signal_present = FALSE; | |
268 s->modems.rx_trained = FALSE; | |
269 break; | |
270 } | |
271 } | |
272 /*- End of function --------------------------------------------------------*/ | |
273 | |
274 static void non_ecm_put_bit(void *user_data, int bit) | |
275 { | |
276 faxtester_state_t *s; | |
277 | |
278 if (bit < 0) | |
279 { | |
280 non_ecm_rx_status(user_data, bit); | |
281 return; | |
282 } | |
283 s = (faxtester_state_t *) user_data; | |
284 } | |
285 /*- End of function --------------------------------------------------------*/ | |
286 | |
287 static void hdlc_rx_status(void *user_data, int status) | |
288 { | |
289 faxtester_state_t *s; | |
290 | |
291 s = (faxtester_state_t *) user_data; | |
292 fprintf(stderr, "HDLC carrier status is %s (%d)\n", signal_status_to_str(status), status); | |
293 switch (status) | |
294 { | |
295 case SIG_STATUS_TRAINING_FAILED: | |
296 s->modems.rx_trained = FALSE; | |
297 break; | |
298 case SIG_STATUS_TRAINING_SUCCEEDED: | |
299 /* The modem is now trained */ | |
300 s->modems.rx_trained = TRUE; | |
301 break; | |
302 case SIG_STATUS_CARRIER_UP: | |
303 s->modems.rx_signal_present = TRUE; | |
304 break; | |
305 case SIG_STATUS_CARRIER_DOWN: | |
306 s->modems.rx_signal_present = FALSE; | |
307 s->modems.rx_trained = FALSE; | |
308 break; | |
309 } | |
310 } | |
311 /*- End of function --------------------------------------------------------*/ | |
312 | |
313 static void hdlc_accept(void *user_data, const uint8_t *msg, int len, int ok) | |
314 { | |
315 faxtester_state_t *s; | |
316 | |
317 if (len < 0) | |
318 { | |
319 hdlc_rx_status(user_data, len); | |
320 return; | |
321 } | |
322 s = (faxtester_state_t *) user_data; | |
323 if (s->real_time_frame_handler) | |
324 s->real_time_frame_handler(s, s->real_time_frame_user_data, TRUE, msg, len); | |
325 } | |
326 /*- End of function --------------------------------------------------------*/ | |
327 | |
328 static int v17_v21_rx(void *user_data, const int16_t amp[], int len) | |
329 { | |
330 faxtester_state_t *t; | |
331 fax_modems_state_t *s; | |
332 | |
333 t = (faxtester_state_t *) user_data; | |
334 s = &t->modems; | |
335 v17_rx(&s->v17_rx, amp, len); | |
336 fsk_rx(&s->v21_rx, amp, len); | |
337 if (s->rx_trained) | |
338 { | |
339 /* The fast modem has trained, so we no longer need to run the slow | |
340 one in parallel. */ | |
341 span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.17 (%.2fdBm0)\n", v17_rx_signal_power(&s->v17_rx)); | |
342 s->rx_handler = (span_rx_handler_t *) &v17_rx; | |
343 s->rx_user_data = &s->v17_rx; | |
344 } | |
345 return 0; | |
346 } | |
347 /*- End of function --------------------------------------------------------*/ | |
348 | |
349 static int v27ter_v21_rx(void *user_data, const int16_t amp[], int len) | |
350 { | |
351 faxtester_state_t *t; | |
352 fax_modems_state_t *s; | |
353 | |
354 t = (faxtester_state_t *) user_data; | |
355 s = &t->modems; | |
356 v27ter_rx(&s->v27ter_rx, amp, len); | |
357 fsk_rx(&s->v21_rx, amp, len); | |
358 if (s->rx_trained) | |
359 { | |
360 /* The fast modem has trained, so we no longer need to run the slow | |
361 one in parallel. */ | |
362 span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.27ter (%.2fdBm0)\n", v27ter_rx_signal_power(&s->v27ter_rx)); | |
363 s->rx_handler = (span_rx_handler_t *) &v27ter_rx; | |
364 s->rx_user_data = &s->v27ter_rx; | |
365 } | |
366 return 0; | |
367 } | |
368 /*- End of function --------------------------------------------------------*/ | |
369 | |
370 static int v29_v21_rx(void *user_data, const int16_t amp[], int len) | |
371 { | |
372 faxtester_state_t *t; | |
373 fax_modems_state_t *s; | |
374 | |
375 t = (faxtester_state_t *) user_data; | |
376 s = &t->modems; | |
377 v29_rx(&s->v29_rx, amp, len); | |
378 fsk_rx(&s->v21_rx, amp, len); | |
379 if (s->rx_trained) | |
380 { | |
381 /* The fast modem has trained, so we no longer need to run the slow | |
382 one in parallel. */ | |
383 span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.29 (%.2fdBm0)\n", v29_rx_signal_power(&s->v29_rx)); | |
384 s->rx_handler = (span_rx_handler_t *) &v29_rx; | |
385 s->rx_user_data = &s->v29_rx; | |
386 } | |
387 return 0; | |
388 } | |
389 /*- End of function --------------------------------------------------------*/ | |
390 | |
391 int faxtester_rx(faxtester_state_t *s, int16_t *amp, int len) | |
392 { | |
393 int i; | |
394 | |
395 for (i = 0; i < len; i++) | |
396 amp[i] = dc_restore(&(s->modems.dc_restore), amp[i]); | |
397 s->modems.rx_handler(s->modems.rx_user_data, amp, len); | |
398 timer_update(s, len); | |
399 if (s->wait_for_silence) | |
400 { | |
401 if (!s->modems.rx_signal_present) | |
402 { | |
403 s->wait_for_silence = FALSE; | |
404 front_end_step_complete(s); | |
405 } | |
406 } | |
407 return 0; | |
408 } | |
409 /*- End of function --------------------------------------------------------*/ | |
410 | |
411 int faxtester_tx(faxtester_state_t *s, int16_t *amp, int max_len) | |
412 { | |
413 int len; | |
414 int required_len; | |
415 | |
416 required_len = max_len; | |
417 len = 0; | |
418 if (s->transmit) | |
419 { | |
420 while ((len += s->modems.tx_handler(s->modems.tx_user_data, amp + len, max_len - len)) < max_len) | |
421 { | |
422 /* Allow for a change of tx handler within a block */ | |
423 front_end_step_complete(s); | |
424 if (!s->transmit) | |
425 { | |
426 if (s->modems.transmit_on_idle) | |
427 { | |
428 /* Pad to the requested length with silence */ | |
429 memset(amp + len, 0, (max_len - len)*sizeof(int16_t)); | |
430 len = max_len; | |
431 } | |
432 break; | |
433 } | |
434 } | |
435 } | |
436 else | |
437 { | |
438 if (s->modems.transmit_on_idle) | |
439 { | |
440 /* Pad to the requested length with silence */ | |
441 memset(amp, 0, max_len*sizeof(int16_t)); | |
442 len = max_len; | |
443 } | |
444 } | |
445 return len; | |
446 } | |
447 /*- End of function --------------------------------------------------------*/ | |
448 | |
449 void faxtest_set_rx_silence(faxtester_state_t *s) | |
450 { | |
451 s->wait_for_silence = TRUE; | |
452 } | |
453 /*- End of function --------------------------------------------------------*/ | |
454 | |
455 void faxtester_set_rx_type(void *user_data, int type, int bit_rate, int short_train, int use_hdlc) | |
456 { | |
457 faxtester_state_t *s; | |
458 put_bit_func_t put_bit_func; | |
459 void *put_bit_user_data; | |
460 fax_modems_state_t *t; | |
461 int tone; | |
462 | |
463 s = (faxtester_state_t *) user_data; | |
464 t = &s->modems; | |
465 span_log(&s->logging, SPAN_LOG_FLOW, "Set rx type %d\n", type); | |
466 if (s->current_rx_type == type) | |
467 return; | |
468 s->current_rx_type = type; | |
469 if (use_hdlc) | |
470 { | |
471 put_bit_func = (put_bit_func_t) hdlc_rx_put_bit; | |
472 put_bit_user_data = (void *) &t->hdlc_rx; | |
473 hdlc_rx_init(&t->hdlc_rx, FALSE, FALSE, HDLC_FRAMING_OK_THRESHOLD, hdlc_accept, s); | |
474 } | |
475 else | |
476 { | |
477 put_bit_func = non_ecm_put_bit; | |
478 put_bit_user_data = (void *) s; | |
479 } | |
480 switch (type) | |
481 { | |
482 case T30_MODEM_CED: | |
483 case T30_MODEM_CNG: | |
484 if (type == T30_MODEM_CED) | |
485 tone = MODEM_CONNECT_TONES_FAX_CED; | |
486 else | |
487 tone = MODEM_CONNECT_TONES_FAX_CNG; | |
488 modem_connect_tones_rx_init(&t->connect_rx, | |
489 tone, | |
490 tone_detected, | |
491 (void *) s); | |
492 t->rx_handler = (span_rx_handler_t *) &modem_connect_tones_rx; | |
493 t->rx_user_data = &t->connect_rx; | |
494 s->tone_state = MODEM_CONNECT_TONES_NONE; | |
495 break; | |
496 case T30_MODEM_V21: | |
497 if (s->flush_handler) | |
498 s->flush_handler(s, s->flush_user_data, 3); | |
499 fsk_rx_init(&t->v21_rx, &preset_fsk_specs[FSK_V21CH2], FSK_FRAME_MODE_SYNC, (put_bit_func_t) hdlc_rx_put_bit, put_bit_user_data); | |
500 fsk_rx_signal_cutoff(&t->v21_rx, -45.5); | |
501 t->rx_handler = (span_rx_handler_t *) &fsk_rx; | |
502 t->rx_user_data = &t->v21_rx; | |
503 break; | |
504 case T30_MODEM_V27TER: | |
505 v27ter_rx_restart(&t->v27ter_rx, bit_rate, FALSE); | |
506 v27ter_rx_set_put_bit(&t->v27ter_rx, put_bit_func, put_bit_user_data); | |
507 t->rx_handler = (span_rx_handler_t *) &v27ter_v21_rx; | |
508 t->rx_user_data = s; | |
509 break; | |
510 case T30_MODEM_V29: | |
511 v29_rx_restart(&t->v29_rx, bit_rate, FALSE); | |
512 v29_rx_set_put_bit(&t->v29_rx, put_bit_func, put_bit_user_data); | |
513 t->rx_handler = (span_rx_handler_t *) &v29_v21_rx; | |
514 t->rx_user_data = s; | |
515 break; | |
516 case T30_MODEM_V17: | |
517 v17_rx_restart(&t->v17_rx, bit_rate, short_train); | |
518 v17_rx_set_put_bit(&t->v17_rx, put_bit_func, put_bit_user_data); | |
519 t->rx_handler = (span_rx_handler_t *) &v17_v21_rx; | |
520 t->rx_user_data = s; | |
521 break; | |
522 case T30_MODEM_DONE: | |
523 span_log(&s->logging, SPAN_LOG_FLOW, "FAX exchange complete\n"); | |
524 default: | |
525 t->rx_handler = (span_rx_handler_t *) &span_dummy_rx; | |
526 t->rx_user_data = s; | |
527 break; | |
528 } | |
529 } | |
530 /*- End of function --------------------------------------------------------*/ | |
531 | |
532 void faxtester_set_tx_type(void *user_data, int type, int bit_rate, int short_train, int use_hdlc) | |
533 { | |
534 faxtester_state_t *s; | |
535 get_bit_func_t get_bit_func; | |
536 void *get_bit_user_data; | |
537 fax_modems_state_t *t; | |
538 int tone; | |
539 | |
540 s = (faxtester_state_t *) user_data; | |
541 t = &s->modems; | |
542 span_log(&s->logging, SPAN_LOG_FLOW, "Set tx type %d\n", type); | |
543 if (s->current_tx_type == type) | |
544 return; | |
545 if (use_hdlc) | |
546 { | |
547 get_bit_func = (get_bit_func_t) hdlc_tx_get_bit; | |
548 get_bit_user_data = (void *) &t->hdlc_tx; | |
549 } | |
550 else | |
551 { | |
552 get_bit_func = non_ecm_get_bit; | |
553 get_bit_user_data = (void *) s; | |
554 } | |
555 switch (type) | |
556 { | |
557 case T30_MODEM_PAUSE: | |
558 silence_gen_alter(&t->silence_gen, ms_to_samples(short_train)); | |
559 t->tx_handler = (span_tx_handler_t *) &silence_gen; | |
560 t->tx_user_data = &t->silence_gen; | |
561 s->transmit = TRUE; | |
562 break; | |
563 case T30_MODEM_CED: | |
564 case T30_MODEM_CNG: | |
565 if (type == T30_MODEM_CED) | |
566 tone = MODEM_CONNECT_TONES_FAX_CED; | |
567 else | |
568 tone = MODEM_CONNECT_TONES_FAX_CNG; | |
569 modem_connect_tones_tx_init(&t->connect_tx, tone); | |
570 t->tx_handler = (span_tx_handler_t *) &modem_connect_tones_tx; | |
571 t->tx_user_data = &t->connect_tx; | |
572 s->transmit = TRUE; | |
573 break; | |
574 case T30_MODEM_V21: | |
575 fsk_tx_init(&t->v21_tx, &preset_fsk_specs[FSK_V21CH2], get_bit_func, get_bit_user_data); | |
576 fsk_tx_set_modem_status_handler(&t->v21_tx, modem_tx_status, (void *) s); | |
577 t->tx_handler = (span_tx_handler_t *) &fsk_tx; | |
578 t->tx_user_data = &t->v21_tx; | |
579 s->transmit = TRUE; | |
580 break; | |
581 case T30_MODEM_V27TER: | |
582 v27ter_tx_restart(&t->v27ter_tx, bit_rate, t->use_tep); | |
583 v27ter_tx_set_get_bit(&t->v27ter_tx, get_bit_func, get_bit_user_data); | |
584 v27ter_tx_set_modem_status_handler(&t->v27ter_tx, modem_tx_status, (void *) s); | |
585 t->tx_handler = (span_tx_handler_t *) &v27ter_tx; | |
586 t->tx_user_data = &t->v27ter_tx; | |
587 /* For any fast modem, set 200ms of preamble flags */ | |
588 hdlc_tx_flags(&t->hdlc_tx, bit_rate/(8*5)); | |
589 s->transmit = TRUE; | |
590 break; | |
591 case T30_MODEM_V29: | |
592 v29_tx_restart(&t->v29_tx, bit_rate, t->use_tep); | |
593 v29_tx_set_get_bit(&t->v29_tx, get_bit_func, get_bit_user_data); | |
594 v29_tx_set_modem_status_handler(&t->v29_tx, modem_tx_status, (void *) s); | |
595 t->tx_handler = (span_tx_handler_t *) &v29_tx; | |
596 t->tx_user_data = &t->v29_tx; | |
597 /* For any fast modem, set 200ms of preamble flags */ | |
598 hdlc_tx_flags(&t->hdlc_tx, bit_rate/(8*5)); | |
599 s->transmit = TRUE; | |
600 break; | |
601 case T30_MODEM_V17: | |
602 v17_tx_restart(&t->v17_tx, bit_rate, t->use_tep, short_train); | |
603 v17_tx_set_get_bit(&t->v17_tx, get_bit_func, get_bit_user_data); | |
604 v17_tx_set_modem_status_handler(&t->v17_tx, modem_tx_status, (void *) s); | |
605 t->tx_handler = (span_tx_handler_t *) &v17_tx; | |
606 t->tx_user_data = &t->v17_tx; | |
607 /* For any fast modem, set 200ms of preamble flags */ | |
608 hdlc_tx_flags(&t->hdlc_tx, bit_rate/(8*5)); | |
609 s->transmit = TRUE; | |
610 break; | |
611 case T30_MODEM_DONE: | |
612 span_log(&s->logging, SPAN_LOG_FLOW, "FAX exchange complete\n"); | |
613 /* Fall through */ | |
614 default: | |
615 silence_gen_alter(&t->silence_gen, 0); | |
616 t->tx_handler = (span_tx_handler_t *) &silence_gen; | |
617 t->tx_user_data = &t->silence_gen; | |
618 s->transmit = FALSE; | |
619 break; | |
620 } | |
621 s->current_tx_type = type; | |
622 } | |
623 /*- End of function --------------------------------------------------------*/ | |
624 | |
625 void faxtester_set_timeout(faxtester_state_t *s, int timeout) | |
626 { | |
627 if (timeout >= 0) | |
628 s->timeout = s->timer + timeout*SAMPLE_RATE/1000; | |
629 else | |
630 s->timeout = 0x7FFFFFFFFFFFFFFFLL; | |
631 } | |
632 /*- End of function --------------------------------------------------------*/ | |
633 | |
634 void faxtester_set_transmit_on_idle(faxtester_state_t *s, int transmit_on_idle) | |
635 { | |
636 s->modems.transmit_on_idle = transmit_on_idle; | |
637 } | |
638 /*- End of function --------------------------------------------------------*/ | |
639 | |
640 void faxtester_set_tep_mode(faxtester_state_t *s, int use_tep) | |
641 { | |
642 s->modems.use_tep = use_tep; | |
643 } | |
644 /*- End of function --------------------------------------------------------*/ | |
645 | |
646 void faxtester_set_real_time_frame_handler(faxtester_state_t *s, faxtester_real_time_frame_handler_t *handler, void *user_data) | |
647 { | |
648 s->real_time_frame_handler = handler; | |
649 s->real_time_frame_user_data = user_data; | |
650 } | |
651 /*- End of function --------------------------------------------------------*/ | |
652 | |
653 void faxtester_set_front_end_step_complete_handler(faxtester_state_t *s, faxtester_front_end_step_complete_handler_t *handler, void *user_data) | |
654 { | |
655 s->front_end_step_complete_handler = handler; | |
656 s->front_end_step_complete_user_data = user_data; | |
657 } | |
658 /*- End of function --------------------------------------------------------*/ | |
659 | |
660 void faxtester_set_front_end_step_timeout_handler(faxtester_state_t *s, faxtester_front_end_step_complete_handler_t *handler, void *user_data) | |
661 { | |
662 s->front_end_step_timeout_handler = handler; | |
663 s->front_end_step_timeout_user_data = user_data; | |
664 } | |
665 /*- End of function --------------------------------------------------------*/ | |
666 | |
667 static void faxtester_fax_modems_init(fax_modems_state_t *s, int use_tep, void *user_data) | |
668 { | |
669 s->use_tep = use_tep; | |
670 | |
671 hdlc_rx_init(&s->hdlc_rx, FALSE, FALSE, HDLC_FRAMING_OK_THRESHOLD, hdlc_accept, user_data); | |
672 hdlc_tx_init(&s->hdlc_tx, FALSE, 2, FALSE, hdlc_underflow_handler, user_data); | |
673 fsk_rx_init(&s->v21_rx, &preset_fsk_specs[FSK_V21CH2], FSK_FRAME_MODE_SYNC, (put_bit_func_t) hdlc_rx_put_bit, &s->hdlc_rx); | |
674 fsk_rx_signal_cutoff(&s->v21_rx, -45.5); | |
675 fsk_tx_init(&s->v21_tx, &preset_fsk_specs[FSK_V21CH2], (get_bit_func_t) hdlc_tx_get_bit, &s->hdlc_tx); | |
676 fsk_tx_set_modem_status_handler(&s->v21_tx, modem_tx_status, user_data); | |
677 v17_rx_init(&s->v17_rx, 14400, non_ecm_put_bit, user_data); | |
678 v17_tx_init(&s->v17_tx, 14400, s->use_tep, non_ecm_get_bit, user_data); | |
679 v17_tx_set_modem_status_handler(&s->v17_tx, modem_tx_status, user_data); | |
680 v29_rx_init(&s->v29_rx, 9600, non_ecm_put_bit, user_data); | |
681 v29_rx_signal_cutoff(&s->v29_rx, -45.5); | |
682 v29_tx_init(&s->v29_tx, 9600, s->use_tep, non_ecm_get_bit, user_data); | |
683 v29_tx_set_modem_status_handler(&s->v29_tx, modem_tx_status, user_data); | |
684 v27ter_rx_init(&s->v27ter_rx, 4800, non_ecm_put_bit, user_data); | |
685 v27ter_tx_init(&s->v27ter_tx, 4800, s->use_tep, non_ecm_get_bit, user_data); | |
686 v27ter_tx_set_modem_status_handler(&s->v27ter_tx, modem_tx_status, user_data); | |
687 silence_gen_init(&s->silence_gen, 0); | |
688 modem_connect_tones_tx_init(&s->connect_tx, MODEM_CONNECT_TONES_FAX_CNG); | |
689 modem_connect_tones_rx_init(&s->connect_rx, | |
690 MODEM_CONNECT_TONES_FAX_CNG, | |
691 tone_detected, | |
692 user_data); | |
693 dc_restore_init(&s->dc_restore); | |
694 | |
695 s->rx_signal_present = FALSE; | |
696 s->rx_handler = (span_rx_handler_t *) &span_dummy_rx; | |
697 s->rx_user_data = NULL; | |
698 s->tx_handler = (span_tx_handler_t *) &silence_gen; | |
699 s->tx_user_data = &s->silence_gen; | |
700 } | |
701 /*- End of function --------------------------------------------------------*/ | |
702 | |
703 faxtester_state_t *faxtester_init(faxtester_state_t *s, int calling_party) | |
704 { | |
705 if (s == NULL) | |
706 { | |
707 if ((s = (faxtester_state_t *) malloc(sizeof(*s))) == NULL) | |
708 return NULL; | |
709 } | |
710 | |
711 memset(s, 0, sizeof(*s)); | |
712 span_log_init(&s->logging, SPAN_LOG_NONE, NULL); | |
713 span_log_set_protocol(&s->logging, "TST"); | |
714 faxtester_fax_modems_init(&s->modems, FALSE, s); | |
715 faxtester_set_timeout(s, -1); | |
716 faxtester_set_tx_type(s, T30_MODEM_NONE, 0, FALSE, FALSE); | |
717 | |
718 return s; | |
719 } | |
720 /*- End of function --------------------------------------------------------*/ | |
721 | |
722 int faxtester_release(faxtester_state_t *s) | |
723 { | |
724 return 0; | |
725 } | |
726 /*- End of function --------------------------------------------------------*/ | |
727 | |
728 int faxtester_free(faxtester_state_t *s) | |
729 { | |
730 free(s); | |
731 return 0; | |
732 } | |
733 /*- End of function --------------------------------------------------------*/ | |
734 | |
735 void faxtester_set_flush_handler(faxtester_state_t *s, faxtester_flush_handler_t *handler, void *user_data) | |
736 { | |
737 s->flush_handler = handler; | |
738 s->flush_user_data = user_data; | |
739 } | |
740 /*- End of function --------------------------------------------------------*/ | |
741 /*- End of file ------------------------------------------------------------*/ |