Various fax_modems.c related improvements

This commit is contained in:
Steve Underwood 2012-08-26 15:43:15 +08:00 committed by Ken Rice
parent 3e0aad8eda
commit f26a4990d7
6 changed files with 437 additions and 283 deletions

View File

@ -123,13 +123,13 @@
#define HDLC_FRAMING_OK_THRESHOLD 8 #define HDLC_FRAMING_OK_THRESHOLD 8
static void fax_send_hdlc(void *user_data, const uint8_t *msg, int len) static void fax_modems_hdlc_tx_frame(void *user_data, const uint8_t *msg, int len)
{ {
fax_state_t *s; fax_modems_state_t *s;
s = (fax_state_t *) user_data; s = (fax_modems_state_t *) user_data;
hdlc_tx_frame(&s->modems.hdlc_tx, msg, len); hdlc_tx_frame(&s->hdlc_tx, msg, len);
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
@ -142,7 +142,6 @@ static void tone_detected(void *user_data, int tone, int level, int delay)
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
#if 0
static void v8_handler(void *user_data, v8_parms_t *result) static void v8_handler(void *user_data, v8_parms_t *result)
{ {
fax_state_t *s; fax_state_t *s;
@ -151,7 +150,6 @@ static void v8_handler(void *user_data, v8_parms_t *result)
span_log(&s->logging, SPAN_LOG_FLOW, "V.8 report received\n"); span_log(&s->logging, SPAN_LOG_FLOW, "V.8 report received\n");
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
#endif
static void hdlc_underflow_handler(void *user_data) static void hdlc_underflow_handler(void *user_data)
{ {
@ -162,31 +160,6 @@ static void hdlc_underflow_handler(void *user_data)
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
static void set_rx_handler(fax_state_t *s,
span_rx_handler_t rx_handler,
span_rx_fillin_handler_t fillin_handler,
void *user_data)
{
s->modems.rx_handler = rx_handler;
s->modems.rx_fillin_handler = fillin_handler;
s->modems.rx_user_data = user_data;
}
/*- End of function --------------------------------------------------------*/
static void fax_modems_set_tx_handler(fax_state_t *s, span_tx_handler_t handler, void *user_data)
{
s->modems.tx_handler = handler;
s->modems.tx_user_data = user_data;
}
/*- End of function --------------------------------------------------------*/
static void fax_modems_set_next_tx_handler(fax_state_t *s, span_tx_handler_t handler, void *user_data)
{
s->modems.next_tx_handler = handler;
s->modems.next_tx_user_data = user_data;
}
/*- End of function --------------------------------------------------------*/
static int v17_v21_rx(void *user_data, const int16_t amp[], int len) static int v17_v21_rx(void *user_data, const int16_t amp[], int len)
{ {
fax_state_t *t; fax_state_t *t;
@ -195,23 +168,20 @@ static int v17_v21_rx(void *user_data, const int16_t amp[], int len)
t = (fax_state_t *) user_data; t = (fax_state_t *) user_data;
s = &t->modems; s = &t->modems;
v17_rx(&s->fast_modems.v17_rx, amp, len); v17_rx(&s->fast_modems.v17_rx, amp, len);
fsk_rx(&s->v21_rx, amp, len);
if (t->t30.rx_trained) if (t->t30.rx_trained)
{ {
/* The fast modem has trained, so we no longer need to run the slow one in parallel. */ /* The fast modem has trained, so we no longer need to run the slow one in parallel. */
span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.17 (%.2fdBm0)\n", v17_rx_signal_power(&s->fast_modems.v17_rx)); span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.17 (%.2fdBm0)\n", v17_rx_signal_power(&s->fast_modems.v17_rx));
set_rx_handler(t, (span_rx_handler_t) &v17_rx, (span_rx_fillin_handler_t) &v17_rx_fillin, &s->fast_modems.v17_rx); fax_modems_set_rx_handler(s, (span_rx_handler_t) &v17_rx, &s->fast_modems.v17_rx, (span_rx_fillin_handler_t) &v17_rx_fillin, &s->fast_modems.v17_rx);
} }
else else if (t->t30.rx_frame_received)
{ {
fsk_rx(&s->v21_rx, amp, len); /* We have received something, and the fast modem has not trained. We must be receiving valid V.21 */
if (t->t30.rx_frame_received) span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
{ fax_modems_set_rx_handler(s, (span_rx_handler_t) &fsk_rx, &s->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
/* We have received something, and the fast modem has not trained. We must
be receiving valid V.21 */
span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
set_rx_handler(t, (span_rx_handler_t) &fsk_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
}
} }
/*endif*/
return 0; return 0;
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
@ -237,23 +207,20 @@ static int v27ter_v21_rx(void *user_data, const int16_t amp[], int len)
t = (fax_state_t *) user_data; t = (fax_state_t *) user_data;
s = &t->modems; s = &t->modems;
v27ter_rx(&s->fast_modems.v27ter_rx, amp, len); v27ter_rx(&s->fast_modems.v27ter_rx, amp, len);
fsk_rx(&s->v21_rx, amp, len);
if (t->t30.rx_trained) if (t->t30.rx_trained)
{ {
/* The fast modem has trained, so we no longer need to run the slow one in parallel. */ /* The fast modem has trained, so we no longer need to run the slow one in parallel. */
span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.27ter (%.2fdBm0)\n", v27ter_rx_signal_power(&s->fast_modems.v27ter_rx)); span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.27ter (%.2fdBm0)\n", v27ter_rx_signal_power(&s->fast_modems.v27ter_rx));
set_rx_handler(t, (span_rx_handler_t) &v27ter_rx, (span_rx_fillin_handler_t) &v27ter_rx_fillin, &s->fast_modems.v27ter_rx); fax_modems_set_rx_handler(s, (span_rx_handler_t) &v27ter_rx, &s->fast_modems.v27ter_rx, (span_rx_fillin_handler_t) &v27ter_rx_fillin, &s->fast_modems.v27ter_rx);
} }
else else if (t->t30.rx_frame_received)
{ {
fsk_rx(&s->v21_rx, amp, len); /* We have received something, and the fast modem has not trained. We must be receiving valid V.21 */
if (t->t30.rx_frame_received)
{
/* We have received something, and the fast modem has not trained. We must
be receiving valid V.21 */
span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx)); span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
set_rx_handler(t, (span_rx_handler_t) &fsk_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx); fax_modems_set_rx_handler(s, (span_rx_handler_t) &fsk_rx, &s->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
}
} }
/*endif*/
return 0; return 0;
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
@ -279,23 +246,20 @@ static int v29_v21_rx(void *user_data, const int16_t amp[], int len)
t = (fax_state_t *) user_data; t = (fax_state_t *) user_data;
s = &t->modems; s = &t->modems;
v29_rx(&s->fast_modems.v29_rx, amp, len); v29_rx(&s->fast_modems.v29_rx, amp, len);
fsk_rx(&s->v21_rx, amp, len);
if (t->t30.rx_trained) if (t->t30.rx_trained)
{ {
/* The fast modem has trained, so we no longer need to run the slow one in parallel. */ /* The fast modem has trained, so we no longer need to run the slow one in parallel. */
span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.29 (%.2fdBm0)\n", v29_rx_signal_power(&s->fast_modems.v29_rx)); span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.29 (%.2fdBm0)\n", v29_rx_signal_power(&s->fast_modems.v29_rx));
set_rx_handler(t, (span_rx_handler_t) &v29_rx, (span_rx_fillin_handler_t) &v29_rx_fillin, &s->fast_modems.v29_rx); fax_modems_set_rx_handler(s, (span_rx_handler_t) &v29_rx, &s->fast_modems.v29_rx, (span_rx_fillin_handler_t) &v29_rx_fillin, &s->fast_modems.v29_rx);
} }
else else if (t->t30.rx_frame_received)
{ {
fsk_rx(&s->v21_rx, amp, len); /* We have received something, and the fast modem has not trained. We must be receiving valid V.21 */
if (t->t30.rx_frame_received) span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
{ fax_modems_set_rx_handler(s, (span_rx_handler_t) &fsk_rx, &s->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
/* We have received something, and the fast modem has not trained. We must
be receiving valid V.21 */
span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
set_rx_handler(t, (span_rx_handler_t) &fsk_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
}
} }
/*endif*/
return 0; return 0;
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
@ -351,7 +315,7 @@ SPAN_DECLARE_NONSTD(int) fax_rx_fillin(fax_state_t *s, int len)
} }
#endif #endif
/* Call the fillin function of the current modem (if there is one). */ /* Call the fillin function of the current modem (if there is one). */
s->modems.rx_fillin_handler(s->modems.rx_user_data, len); s->modems.rx_fillin_handler(s->modems.rx_fillin_user_data, len);
t30_timer_update(&s->t30, len); t30_timer_update(&s->t30, len);
return 0; return 0;
} }
@ -364,14 +328,14 @@ static int set_next_tx_type(fax_state_t *s)
t = &s->modems; t = &s->modems;
if (t->next_tx_handler) if (t->next_tx_handler)
{ {
fax_modems_set_tx_handler(s, t->next_tx_handler, t->next_tx_user_data); fax_modems_set_tx_handler(t, t->next_tx_handler, t->next_tx_user_data);
t->next_tx_handler = NULL; t->next_tx_handler = NULL;
return 0; return 0;
} }
/* If there is nothing else to change to, so use zero length silence */ /* If there is nothing else to change to, so use zero length silence */
silence_gen_alter(&t->silence_gen, 0); silence_gen_alter(&t->silence_gen, 0);
fax_modems_set_tx_handler(s, (span_tx_handler_t) &silence_gen, &t->silence_gen); fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL); fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
t->transmit = FALSE; t->transmit = FALSE;
return -1; return -1;
} }
@ -456,27 +420,27 @@ static void fax_set_rx_type(void *user_data, int type, int bit_rate, int short_t
case T30_MODEM_V21: case T30_MODEM_V21:
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); 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);
fsk_rx_signal_cutoff(&t->v21_rx, -45.5f); fsk_rx_signal_cutoff(&t->v21_rx, -45.5f);
set_rx_handler(s, (span_rx_handler_t) &fsk_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &t->v21_rx); fax_modems_set_rx_handler(t, (span_rx_handler_t) &fsk_rx, &t->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &t->v21_rx);
break; break;
case T30_MODEM_V27TER: case T30_MODEM_V27TER:
v27ter_rx_restart(&t->fast_modems.v27ter_rx, bit_rate, FALSE); v27ter_rx_restart(&t->fast_modems.v27ter_rx, bit_rate, FALSE);
v27ter_rx_set_put_bit(&t->fast_modems.v27ter_rx, put_bit_func, put_bit_user_data); v27ter_rx_set_put_bit(&t->fast_modems.v27ter_rx, put_bit_func, put_bit_user_data);
set_rx_handler(s, &v27ter_v21_rx, &v27ter_v21_rx_fillin, s); fax_modems_set_rx_handler(t, &v27ter_v21_rx, s, &v27ter_v21_rx_fillin, s);
break; break;
case T30_MODEM_V29: case T30_MODEM_V29:
v29_rx_restart(&t->fast_modems.v29_rx, bit_rate, FALSE); v29_rx_restart(&t->fast_modems.v29_rx, bit_rate, FALSE);
v29_rx_set_put_bit(&t->fast_modems.v29_rx, put_bit_func, put_bit_user_data); v29_rx_set_put_bit(&t->fast_modems.v29_rx, put_bit_func, put_bit_user_data);
set_rx_handler(s, &v29_v21_rx, &v29_v21_rx_fillin, s); fax_modems_set_rx_handler(t, &v29_v21_rx, s, &v29_v21_rx_fillin, s);
break; break;
case T30_MODEM_V17: case T30_MODEM_V17:
v17_rx_restart(&t->fast_modems.v17_rx, bit_rate, short_train); v17_rx_restart(&t->fast_modems.v17_rx, bit_rate, short_train);
v17_rx_set_put_bit(&t->fast_modems.v17_rx, put_bit_func, put_bit_user_data); v17_rx_set_put_bit(&t->fast_modems.v17_rx, put_bit_func, put_bit_user_data);
set_rx_handler(s, &v17_v21_rx, &v17_v21_rx_fillin, s); fax_modems_set_rx_handler(t, &v17_v21_rx, s, &v17_v21_rx_fillin, s);
break; break;
case T30_MODEM_DONE: case T30_MODEM_DONE:
span_log(&s->logging, SPAN_LOG_FLOW, "FAX exchange complete\n"); span_log(&s->logging, SPAN_LOG_FLOW, "FAX exchange complete\n");
default: default:
set_rx_handler(s, (span_rx_handler_t) &span_dummy_rx, (span_rx_fillin_handler_t) &span_dummy_rx_fillin, s); fax_modems_set_rx_handler(t, (span_rx_handler_t) &span_dummy_rx, s, (span_rx_fillin_handler_t) &span_dummy_rx_fillin, s);
break; break;
} }
} }
@ -509,8 +473,8 @@ static void fax_set_tx_type(void *user_data, int type, int bit_rate, int short_t
{ {
case T30_MODEM_PAUSE: case T30_MODEM_PAUSE:
silence_gen_alter(&t->silence_gen, ms_to_samples(short_train)); silence_gen_alter(&t->silence_gen, ms_to_samples(short_train));
fax_modems_set_tx_handler(s, (span_tx_handler_t) &silence_gen, &t->silence_gen); fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL); fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
t->transmit = TRUE; t->transmit = TRUE;
break; break;
case T30_MODEM_CED: case T30_MODEM_CED:
@ -520,8 +484,8 @@ static void fax_set_tx_type(void *user_data, int type, int bit_rate, int short_t
else else
tone = MODEM_CONNECT_TONES_FAX_CNG; tone = MODEM_CONNECT_TONES_FAX_CNG;
modem_connect_tones_tx_init(&t->connect_tx, tone); modem_connect_tones_tx_init(&t->connect_tx, tone);
fax_modems_set_tx_handler(s, (span_tx_handler_t) &modem_connect_tones_tx, &t->connect_tx); fax_modems_set_tx_handler(t, (span_tx_handler_t) &modem_connect_tones_tx, &t->connect_tx);
fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL); fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
t->transmit = TRUE; t->transmit = TRUE;
break; break;
case T30_MODEM_V21: case T30_MODEM_V21:
@ -533,8 +497,8 @@ static void fax_set_tx_type(void *user_data, int type, int bit_rate, int short_t
a 75ms gap before any V.21 transmission is harmless, adds little to the overall length of a 75ms gap before any V.21 transmission is harmless, adds little to the overall length of
a call, and ensures the receiving end is ready. */ a call, and ensures the receiving end is ready. */
silence_gen_alter(&t->silence_gen, ms_to_samples(75)); silence_gen_alter(&t->silence_gen, ms_to_samples(75));
fax_modems_set_tx_handler(s, (span_tx_handler_t) &silence_gen, &t->silence_gen); fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
fax_modems_set_next_tx_handler(s, (span_tx_handler_t) &fsk_tx, &t->v21_tx); fax_modems_set_next_tx_handler(t, (span_tx_handler_t) &fsk_tx, &t->v21_tx);
t->transmit = TRUE; t->transmit = TRUE;
break; break;
case T30_MODEM_V17: case T30_MODEM_V17:
@ -543,8 +507,8 @@ static void fax_set_tx_type(void *user_data, int type, int bit_rate, int short_t
hdlc_tx_flags(&t->hdlc_tx, bit_rate/(8*5)); hdlc_tx_flags(&t->hdlc_tx, bit_rate/(8*5));
v17_tx_restart(&t->fast_modems.v17_tx, bit_rate, t->use_tep, short_train); v17_tx_restart(&t->fast_modems.v17_tx, bit_rate, t->use_tep, short_train);
v17_tx_set_get_bit(&t->fast_modems.v17_tx, get_bit_func, get_bit_user_data); v17_tx_set_get_bit(&t->fast_modems.v17_tx, get_bit_func, get_bit_user_data);
fax_modems_set_tx_handler(s, (span_tx_handler_t) &silence_gen, &t->silence_gen); fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
fax_modems_set_next_tx_handler(s, (span_tx_handler_t) &v17_tx, &t->fast_modems.v17_tx); fax_modems_set_next_tx_handler(t, (span_tx_handler_t) &v17_tx, &t->fast_modems.v17_tx);
t->transmit = TRUE; t->transmit = TRUE;
break; break;
case T30_MODEM_V27TER: case T30_MODEM_V27TER:
@ -553,8 +517,8 @@ static void fax_set_tx_type(void *user_data, int type, int bit_rate, int short_t
hdlc_tx_flags(&t->hdlc_tx, bit_rate/(8*5)); hdlc_tx_flags(&t->hdlc_tx, bit_rate/(8*5));
v27ter_tx_restart(&t->fast_modems.v27ter_tx, bit_rate, t->use_tep); v27ter_tx_restart(&t->fast_modems.v27ter_tx, bit_rate, t->use_tep);
v27ter_tx_set_get_bit(&t->fast_modems.v27ter_tx, get_bit_func, get_bit_user_data); v27ter_tx_set_get_bit(&t->fast_modems.v27ter_tx, get_bit_func, get_bit_user_data);
fax_modems_set_tx_handler(s, (span_tx_handler_t) &silence_gen, &t->silence_gen); fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
fax_modems_set_next_tx_handler(s, (span_tx_handler_t) &v27ter_tx, &t->fast_modems.v27ter_tx); fax_modems_set_next_tx_handler(t, (span_tx_handler_t) &v27ter_tx, &t->fast_modems.v27ter_tx);
t->transmit = TRUE; t->transmit = TRUE;
break; break;
case T30_MODEM_V29: case T30_MODEM_V29:
@ -563,8 +527,8 @@ static void fax_set_tx_type(void *user_data, int type, int bit_rate, int short_t
hdlc_tx_flags(&t->hdlc_tx, bit_rate/(8*5)); hdlc_tx_flags(&t->hdlc_tx, bit_rate/(8*5));
v29_tx_restart(&t->fast_modems.v29_tx, bit_rate, t->use_tep); v29_tx_restart(&t->fast_modems.v29_tx, bit_rate, t->use_tep);
v29_tx_set_get_bit(&t->fast_modems.v29_tx, get_bit_func, get_bit_user_data); v29_tx_set_get_bit(&t->fast_modems.v29_tx, get_bit_func, get_bit_user_data);
fax_modems_set_tx_handler(s, (span_tx_handler_t) &silence_gen, &t->silence_gen); fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
fax_modems_set_next_tx_handler(s, (span_tx_handler_t) &v29_tx, &t->fast_modems.v29_tx); fax_modems_set_next_tx_handler(t, (span_tx_handler_t) &v29_tx, &t->fast_modems.v29_tx);
t->transmit = TRUE; t->transmit = TRUE;
break; break;
case T30_MODEM_DONE: case T30_MODEM_DONE:
@ -572,8 +536,8 @@ static void fax_set_tx_type(void *user_data, int type, int bit_rate, int short_t
/* Fall through */ /* Fall through */
default: default:
silence_gen_alter(&t->silence_gen, 0); silence_gen_alter(&t->silence_gen, 0);
fax_modems_set_tx_handler(s, (span_tx_handler_t) &silence_gen, &t->silence_gen); fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL); fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
t->transmit = FALSE; t->transmit = FALSE;
break; break;
} }
@ -590,7 +554,7 @@ SPAN_DECLARE(void) fax_set_transmit_on_idle(fax_state_t *s, int transmit_on_idle
SPAN_DECLARE(void) fax_set_tep_mode(fax_state_t *s, int use_tep) SPAN_DECLARE(void) fax_set_tep_mode(fax_state_t *s, int use_tep)
{ {
s->modems.use_tep = use_tep; fax_modems_set_tep_mode(&s->modems, use_tep);
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
@ -608,12 +572,9 @@ SPAN_DECLARE(logging_state_t *) fax_get_logging_state(fax_state_t *s)
SPAN_DECLARE(int) fax_restart(fax_state_t *s, int calling_party) SPAN_DECLARE(int) fax_restart(fax_state_t *s, int calling_party)
{ {
#if 0
v8_parms_t v8_parms; v8_parms_t v8_parms;
#endif
fax_modems_restart(&s->modems); fax_modems_restart(&s->modems);
#if 0
v8_parms.modem_connect_tone = MODEM_CONNECT_TONES_ANSAM_PR; v8_parms.modem_connect_tone = MODEM_CONNECT_TONES_ANSAM_PR;
v8_parms.call_function = V8_CALL_T30_RX; v8_parms.call_function = V8_CALL_T30_RX;
v8_parms.modulations = V8_MOD_V21; v8_parms.modulations = V8_MOD_V21;
@ -631,7 +592,6 @@ SPAN_DECLARE(int) fax_restart(fax_state_t *s, int calling_party)
v8_parms.nsf = -1; v8_parms.nsf = -1;
v8_parms.t66 = -1; v8_parms.t66 = -1;
v8_restart(&s->v8, calling_party, &v8_parms); v8_restart(&s->v8, calling_party, &v8_parms);
#endif
t30_restart(&s->t30); t30_restart(&s->t30);
#if defined(LOG_FAX_AUDIO) #if defined(LOG_FAX_AUDIO)
{ {
@ -669,9 +629,7 @@ SPAN_DECLARE(int) fax_restart(fax_state_t *s, int calling_party)
SPAN_DECLARE(fax_state_t *) fax_init(fax_state_t *s, int calling_party) SPAN_DECLARE(fax_state_t *) fax_init(fax_state_t *s, int calling_party)
{ {
#if 0
v8_parms_t v8_parms; v8_parms_t v8_parms;
#endif
if (s == NULL) if (s == NULL)
{ {
@ -695,10 +653,9 @@ SPAN_DECLARE(fax_state_t *) fax_init(fax_state_t *s, int calling_party)
(void *) s, (void *) s,
fax_set_tx_type, fax_set_tx_type,
(void *) s, (void *) s,
fax_send_hdlc, fax_modems_hdlc_tx_frame,
(void *) s); (void *) &s->modems);
t30_set_supported_modems(&s->t30, T30_SUPPORT_V27TER | T30_SUPPORT_V29 | T30_SUPPORT_V17); t30_set_supported_modems(&s->t30, T30_SUPPORT_V27TER | T30_SUPPORT_V29 | T30_SUPPORT_V17);
#if 0
v8_parms.modem_connect_tone = MODEM_CONNECT_TONES_ANSAM_PR; v8_parms.modem_connect_tone = MODEM_CONNECT_TONES_ANSAM_PR;
v8_parms.call_function = V8_CALL_T30_RX; v8_parms.call_function = V8_CALL_T30_RX;
v8_parms.modulations = V8_MOD_V21; v8_parms.modulations = V8_MOD_V21;
@ -716,7 +673,6 @@ SPAN_DECLARE(fax_state_t *) fax_init(fax_state_t *s, int calling_party)
v8_parms.nsf = -1; v8_parms.nsf = -1;
v8_parms.t66 = -1; v8_parms.t66 = -1;
v8_init(&s->v8, calling_party, &v8_parms, v8_handler, s); v8_init(&s->v8, calling_party, &v8_parms, v8_handler, s);
#endif
fax_restart(s, calling_party); fax_restart(s, calling_party);
return s; return s;
} }

View File

@ -86,6 +86,40 @@
#define HDLC_FRAMING_OK_THRESHOLD 5 #define HDLC_FRAMING_OK_THRESHOLD 5
SPAN_DECLARE(void) fax_modems_hdlc_tx_frame(void *user_data, const uint8_t *msg, int len)
{
fax_modems_state_t *s;
s = (fax_modems_state_t *) user_data;
hdlc_tx_frame(&s->hdlc_tx, msg, len);
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(void) fax_modems_hdlc_tx_flags(fax_modems_state_t *s, int flags)
{
hdlc_tx_flags(&s->hdlc_tx, flags);
}
/*- End of function --------------------------------------------------------*/
static void v17_rx_status_handler(void *user_data, int status)
{
fax_modems_state_t *s;
s = (fax_modems_state_t *) user_data;
switch (status)
{
case SIG_STATUS_TRAINING_SUCCEEDED:
span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.17 (%.2fdBm0)\n", v17_rx_signal_power(&s->fast_modems.v17_rx));
fax_modems_set_rx_handler(s, (span_rx_handler_t) &v17_rx, &s->fast_modems.v17_rx, (span_rx_fillin_handler_t) &v17_rx_fillin, &s->fast_modems.v17_rx);
v17_rx_set_modem_status_handler(&s->fast_modems.v17_rx, NULL, s);
s->fast_modems.v17_rx.put_bit(s->fast_modems.v17_rx.put_bit_user_data, status);
break;
}
/*endswitch*/
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE_NONSTD(int) fax_modems_v17_v21_rx(void *user_data, const int16_t amp[], int len) SPAN_DECLARE_NONSTD(int) fax_modems_v17_v21_rx(void *user_data, const int16_t amp[], int len)
{ {
fax_modems_state_t *s; fax_modems_state_t *s;
@ -97,10 +131,7 @@ SPAN_DECLARE_NONSTD(int) fax_modems_v17_v21_rx(void *user_data, const int16_t am
{ {
/* We have received something, and the fast modem has not trained. We must be receiving valid V.21 */ /* We have received something, and the fast modem has not trained. We must be receiving valid V.21 */
span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx)); span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
s->rx_handler = (span_rx_handler_t) &fsk_rx; fax_modems_set_rx_handler(s, (span_rx_handler_t) &fsk_rx, &s->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
s->rx_fillin_handler = (span_rx_fillin_handler_t) &fsk_rx_fillin;
s->rx_user_data = &s->v21_rx;
s->rx_fillin_user_data = &s->v21_rx;
} }
/*endif*/ /*endif*/
return 0; return 0;
@ -118,6 +149,24 @@ SPAN_DECLARE_NONSTD(int) fax_modems_v17_v21_rx_fillin(void *user_data, int len)
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
static void v27ter_rx_status_handler(void *user_data, int status)
{
fax_modems_state_t *s;
s = (fax_modems_state_t *) user_data;
switch (status)
{
case SIG_STATUS_TRAINING_SUCCEEDED:
span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.27ter (%.2fdBm0)\n", v27ter_rx_signal_power(&s->fast_modems.v27ter_rx));
fax_modems_set_rx_handler(s, (span_rx_handler_t) &v27ter_rx, &s->fast_modems.v27ter_rx, (span_rx_fillin_handler_t) &v27ter_rx_fillin, &s->fast_modems.v27ter_rx);
v27ter_rx_set_modem_status_handler(&s->fast_modems.v27ter_rx, NULL, s);
s->fast_modems.v27ter_rx.put_bit(s->fast_modems.v27ter_rx.put_bit_user_data, status);
break;
}
/*endswitch*/
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE_NONSTD(int) fax_modems_v27ter_v21_rx(void *user_data, const int16_t amp[], int len) SPAN_DECLARE_NONSTD(int) fax_modems_v27ter_v21_rx(void *user_data, const int16_t amp[], int len)
{ {
fax_modems_state_t *s; fax_modems_state_t *s;
@ -129,10 +178,7 @@ SPAN_DECLARE_NONSTD(int) fax_modems_v27ter_v21_rx(void *user_data, const int16_t
{ {
/* We have received something, and the fast modem has not trained. We must be receiving valid V.21 */ /* We have received something, and the fast modem has not trained. We must be receiving valid V.21 */
span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx)); span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
s->rx_handler = (span_rx_handler_t) &fsk_rx; fax_modems_set_rx_handler(s, (span_rx_handler_t) &fsk_rx, &s->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
s->rx_fillin_handler = (span_rx_fillin_handler_t) &fsk_rx_fillin;
s->rx_user_data = &s->v21_rx;
s->rx_fillin_user_data = &s->v21_rx;
} }
/*endif*/ /*endif*/
return 0; return 0;
@ -150,6 +196,24 @@ SPAN_DECLARE_NONSTD(int) fax_modems_v27ter_v21_rx_fillin(void *user_data, int le
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
static void v29_rx_status_handler(void *user_data, int status)
{
fax_modems_state_t *s;
s = (fax_modems_state_t *) user_data;
switch (status)
{
case SIG_STATUS_TRAINING_SUCCEEDED:
span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.29 (%.2fdBm0)\n", v29_rx_signal_power(&s->fast_modems.v29_rx));
fax_modems_set_rx_handler(s, (span_rx_handler_t) &v29_rx, &s->fast_modems.v29_rx, (span_rx_fillin_handler_t) &v29_rx_fillin, &s->fast_modems.v29_rx);
v29_rx_set_modem_status_handler(&s->fast_modems.v29_rx, NULL, s);
s->fast_modems.v29_rx.put_bit(s->fast_modems.v29_rx.put_bit_user_data, status);
break;
}
/*endswitch*/
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE_NONSTD(int) fax_modems_v29_v21_rx(void *user_data, const int16_t amp[], int len) SPAN_DECLARE_NONSTD(int) fax_modems_v29_v21_rx(void *user_data, const int16_t amp[], int len)
{ {
fax_modems_state_t *s; fax_modems_state_t *s;
@ -161,10 +225,7 @@ SPAN_DECLARE_NONSTD(int) fax_modems_v29_v21_rx(void *user_data, const int16_t am
{ {
/* We have received something, and the fast modem has not trained. We must be receiving valid V.21 */ /* We have received something, and the fast modem has not trained. We must be receiving valid V.21 */
span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx)); span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
s->rx_handler = (span_rx_handler_t) &fsk_rx; fax_modems_set_rx_handler(s, (span_rx_handler_t) &fsk_rx, &s->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
s->rx_fillin_handler = (span_rx_fillin_handler_t) &fsk_rx_fillin;
s->rx_user_data = &s->v21_rx;
s->rx_fillin_user_data = &s->v21_rx;
} }
/*endif*/ /*endif*/
return 0; return 0;
@ -192,61 +253,137 @@ static void v21_rx_status_handler(void *user_data, int status)
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
static void v17_rx_status_handler(void *user_data, int status) SPAN_DECLARE(void) fax_modems_start_slow_modem(fax_modems_state_t *s, int which)
{ {
fax_modems_state_t *s; switch (which)
s = (fax_modems_state_t *) user_data;
switch (status)
{ {
case SIG_STATUS_TRAINING_SUCCEEDED: case FAX_MODEM_V21_RX:
span_log(&s->logging, SPAN_LOG_FLOW, "Switching to V.17 (%.2fdBm0)\n", v17_rx_signal_power(&s->fast_modems.v17_rx)); 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);
s->rx_handler = (span_rx_handler_t) &v17_rx; fsk_rx_signal_cutoff(&s->v21_rx, -39.09f);
s->rx_fillin_handler = (span_rx_fillin_handler_t) &v17_rx_fillin; s->rx_frame_received = FALSE;
s->rx_user_data = &s->fast_modems.v17_rx; break;
s->rx_fillin_user_data = &s->fast_modems.v17_rx; case FAX_MODEM_V21_TX:
fsk_tx_init(&s->v21_tx, &preset_fsk_specs[FSK_V21CH2], (get_bit_func_t) hdlc_tx_get_bit, &s->hdlc_tx);
break; break;
} }
/*endswitch*/
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
static void v27ter_rx_status_handler(void *user_data, int status) SPAN_DECLARE(void) fax_modems_start_fast_modem(fax_modems_state_t *s, int which, int bit_rate, int short_train, int hdlc_mode)
{ {
fax_modems_state_t *s; put_bit_func_t put_bit;
get_bit_func_t get_bit;
void *get_bit_user_data;
void *put_bit_user_data;
s = (fax_modems_state_t *) user_data; s->bit_rate = bit_rate;
switch (status) if (hdlc_mode)
{ {
case SIG_STATUS_TRAINING_SUCCEEDED: get_bit = (get_bit_func_t) hdlc_tx_get_bit;
span_log(&s->logging, SPAN_LOG_FLOW, "Switching to V.27ter (%.2fdBm0)\n", v27ter_rx_signal_power(&s->fast_modems.v27ter_rx)); get_bit_user_data = (void *) &s->hdlc_tx;
s->rx_handler = (span_rx_handler_t) &v27ter_rx; put_bit = (put_bit_func_t) hdlc_rx_put_bit;
s->rx_fillin_handler = (span_rx_fillin_handler_t) &v27ter_rx_fillin; put_bit_user_data = (void *) &s->hdlc_rx;
s->rx_user_data = &s->fast_modems.v27ter_rx; }
s->rx_fillin_user_data = &s->fast_modems.v27ter_rx; else
{
get_bit = s->get_bit;
get_bit_user_data = s->get_bit_user_data;
put_bit = s->put_bit;
put_bit_user_data = s->put_bit_user_data;
}
/*endif*/
/* If we change modems we need to do a complete reinitialisation of the modem, because
the modems use overlapping memory. */
if (s->fast_modem != which)
{
s->current_rx_type = which;
s->short_train = FALSE;
s->fast_modem = which;
if (hdlc_mode)
s->rx_frame_received = FALSE;
switch (s->fast_modem)
{
case FAX_MODEM_V27TER_RX:
v27ter_rx_init(&s->fast_modems.v27ter_rx, s->bit_rate, put_bit, put_bit_user_data);
v27ter_rx_set_modem_status_handler(&s->fast_modems.v27ter_rx, v27ter_rx_status_handler, s);
fax_modems_set_rx_handler(s, (span_rx_handler_t) &fax_modems_v27ter_v21_rx, s, (span_rx_fillin_handler_t) &fax_modems_v27ter_v21_rx_fillin, s);
break;
case FAX_MODEM_V29_RX:
v29_rx_init(&s->fast_modems.v29_rx, s->bit_rate, put_bit, put_bit_user_data);
v29_rx_signal_cutoff(&s->fast_modems.v29_rx, -45.5f);
v29_rx_set_modem_status_handler(&s->fast_modems.v29_rx, v29_rx_status_handler, s);
fax_modems_set_rx_handler(s, (span_rx_handler_t) &fax_modems_v29_v21_rx, s, (span_rx_fillin_handler_t) &fax_modems_v29_v21_rx_fillin, s);
break;
case FAX_MODEM_V17_RX:
v17_rx_init(&s->fast_modems.v17_rx, s->bit_rate, put_bit, put_bit_user_data);
v17_rx_set_modem_status_handler(&s->fast_modems.v17_rx, v17_rx_status_handler, s);
fax_modems_set_rx_handler(s, (span_rx_handler_t) &fax_modems_v17_v21_rx, s, (span_rx_fillin_handler_t) &fax_modems_v17_v21_rx_fillin, s);
break;
case FAX_MODEM_V27TER_TX:
v27ter_tx_init(&s->fast_modems.v27ter_tx, s->bit_rate, s->use_tep, get_bit, get_bit_user_data);
fax_modems_set_tx_handler(s, (span_tx_handler_t) &v27ter_tx, &s->fast_modems.v27ter_tx);
fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
break;
case FAX_MODEM_V29_TX:
v29_tx_init(&s->fast_modems.v29_tx, s->bit_rate, s->use_tep, get_bit, get_bit_user_data);
fax_modems_set_tx_handler(s, (span_tx_handler_t) &v29_tx, &s->fast_modems.v29_tx);
fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
break;
case FAX_MODEM_V17_TX:
v17_tx_init(&s->fast_modems.v17_tx, s->bit_rate, s->use_tep, get_bit, get_bit_user_data);
fax_modems_set_tx_handler(s, (span_tx_handler_t) &v17_tx, &s->fast_modems.v17_tx);
fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
break; break;
} }
/*endswitch*/ /*endswitch*/
} }
/*- End of function --------------------------------------------------------*/ else
static void v29_rx_status_handler(void *user_data, int status)
{ {
fax_modems_state_t *s; s->short_train = short_train;
switch (s->fast_modem)
s = (fax_modems_state_t *) user_data;
switch (status)
{ {
case SIG_STATUS_TRAINING_SUCCEEDED: case FAX_MODEM_V27TER_RX:
span_log(&s->logging, SPAN_LOG_FLOW, "Switching to V.29 (%.2fdBm0)\n", v29_rx_signal_power(&s->fast_modems.v29_rx)); v27ter_rx_restart(&s->fast_modems.v27ter_rx, s->bit_rate, FALSE);
s->rx_handler = (span_rx_handler_t) &v29_rx; v27ter_rx_set_put_bit(&s->fast_modems.v27ter_rx, put_bit, put_bit_user_data);
s->rx_fillin_handler = (span_rx_fillin_handler_t) &v29_rx_fillin; v27ter_rx_set_modem_status_handler(&s->fast_modems.v27ter_rx, v27ter_rx_status_handler, s);
s->rx_user_data = &s->fast_modems.v29_rx; fax_modems_set_rx_handler(s, (span_rx_handler_t) &fax_modems_v27ter_v21_rx, s, (span_rx_fillin_handler_t) &fax_modems_v27ter_v21_rx_fillin, s);
s->rx_fillin_user_data = &s->fast_modems.v29_rx; break;
case FAX_MODEM_V29_RX:
v29_rx_restart(&s->fast_modems.v29_rx, s->bit_rate, FALSE);
v29_rx_set_put_bit(&s->fast_modems.v29_rx, put_bit, put_bit_user_data);
v29_rx_set_modem_status_handler(&s->fast_modems.v29_rx, v29_rx_status_handler, s);
fax_modems_set_rx_handler(s, (span_rx_handler_t) &fax_modems_v29_v21_rx, s, (span_rx_fillin_handler_t) &fax_modems_v29_v21_rx_fillin, s);
break;
case FAX_MODEM_V17_RX:
v17_rx_restart(&s->fast_modems.v17_rx, s->bit_rate, s->short_train);
v17_rx_set_put_bit(&s->fast_modems.v17_rx, put_bit, put_bit_user_data);
v17_rx_set_modem_status_handler(&s->fast_modems.v17_rx, v17_rx_status_handler, s);
fax_modems_set_rx_handler(s, (span_rx_handler_t) &fax_modems_v17_v21_rx, s, (span_rx_fillin_handler_t) &fax_modems_v17_v21_rx_fillin, s);
break;
case FAX_MODEM_V27TER_TX:
v27ter_tx_restart(&s->fast_modems.v27ter_tx, s->bit_rate, s->use_tep);
v27ter_tx_set_get_bit(&s->fast_modems.v27ter_tx, get_bit, get_bit_user_data);
fax_modems_set_tx_handler(s, (span_tx_handler_t) &v27ter_tx, &s->fast_modems.v27ter_tx);
fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
break;
case FAX_MODEM_V29_TX:
v29_tx_restart(&s->fast_modems.v29_tx, s->bit_rate, s->use_tep);
v29_tx_set_get_bit(&s->fast_modems.v29_tx, get_bit, get_bit_user_data);
fax_modems_set_tx_handler(s, (span_tx_handler_t) &v29_tx, &s->fast_modems.v29_tx);
fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
break;
case FAX_MODEM_V17_TX:
v17_tx_restart(&s->fast_modems.v17_tx, s->bit_rate, s->use_tep, s->short_train);
v17_tx_set_get_bit(&s->fast_modems.v17_tx, get_bit, get_bit_user_data);
fax_modems_set_tx_handler(s, (span_tx_handler_t) &v17_tx, &s->fast_modems.v17_tx);
fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
break; break;
} }
/*endswitch*/ /*endswitch*/
} }
/*endif*/
}
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
SPAN_DECLARE(void) fax_modems_start_rx_modem(fax_modems_state_t *s, int which) SPAN_DECLARE(void) fax_modems_start_rx_modem(fax_modems_state_t *s, int which)
@ -268,6 +405,42 @@ SPAN_DECLARE(void) fax_modems_start_rx_modem(fax_modems_state_t *s, int which)
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
SPAN_DECLARE(void) fax_modems_set_rx_handler(fax_modems_state_t *s,
span_rx_handler_t rx_handler,
void *rx_user_data,
span_rx_fillin_handler_t rx_fillin_handler,
void *rx_fillin_user_data)
{
s->rx_handler = rx_handler;
s->rx_user_data = rx_user_data;
s->rx_fillin_handler = rx_fillin_handler;
s->rx_fillin_user_data = rx_fillin_user_data;
}
/*- End of function --------------------------------------------------------*/
#if 0
SPAN_DECLARE(void) fax_modems_set_rx_active(fax_modems_state_t *s, int active)
{
s->rx_handler = (active) ? s->base_rx_handler : span_dummy_rx;
s->rx_fillin_handler = (active) ? s->base_rx_fillin_handler : span_dummy_rx_fillin;
}
/*- End of function --------------------------------------------------------*/
#endif
SPAN_DECLARE(void) fax_modems_set_tx_handler(fax_modems_state_t *s, span_tx_handler_t handler, void *user_data)
{
s->tx_handler = handler;
s->tx_user_data = user_data;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(void) fax_modems_set_next_tx_handler(fax_modems_state_t *s, span_tx_handler_t handler, void *user_data)
{
s->next_tx_handler = handler;
s->next_tx_user_data = user_data;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(void) fax_modems_set_tep_mode(fax_modems_state_t *s, int use_tep) SPAN_DECLARE(void) fax_modems_set_tep_mode(fax_modems_state_t *s, int use_tep)
{ {
s->use_tep = use_tep; s->use_tep = use_tep;
@ -304,8 +477,31 @@ SPAN_DECLARE(fax_modems_state_t *) fax_modems_init(fax_modems_state_t *s,
memset(s, 0, sizeof(*s)); memset(s, 0, sizeof(*s));
s->use_tep = use_tep; s->use_tep = use_tep;
modem_connect_tones_tx_init(&s->connect_tx, MODEM_CONNECT_TONES_FAX_CNG);
if (tone_callback)
{
modem_connect_tones_rx_init(&s->connect_rx,
MODEM_CONNECT_TONES_FAX_CNG,
tone_callback,
user_data);
}
/*endif*/
span_log_init(&s->logging, SPAN_LOG_NONE, NULL);
span_log_set_protocol(&s->logging, "FAX modems");
dc_restore_init(&s->dc_restore);
s->get_bit = non_ecm_get_bit;
s->get_bit_user_data = user_data;
s->put_bit = non_ecm_put_bit;
s->put_bit_user_data = user_data;
s->hdlc_accept = hdlc_accept;
s->hdlc_accept_user_data = user_data;
hdlc_rx_init(&s->hdlc_rx, FALSE, FALSE, HDLC_FRAMING_OK_THRESHOLD, hdlc_accept, user_data); hdlc_rx_init(&s->hdlc_rx, FALSE, FALSE, HDLC_FRAMING_OK_THRESHOLD, hdlc_accept, user_data);
hdlc_tx_init(&s->hdlc_tx, FALSE, 2, FALSE, hdlc_tx_underflow, user_data); hdlc_tx_init(&s->hdlc_tx, FALSE, 2, FALSE, hdlc_tx_underflow, user_data);
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); 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);
fsk_rx_signal_cutoff(&s->v21_rx, -39.09f); fsk_rx_signal_cutoff(&s->v21_rx, -39.09f);
fsk_tx_init(&s->v21_tx, &preset_fsk_specs[FSK_V21CH2], (get_bit_func_t) hdlc_tx_get_bit, &s->hdlc_tx); fsk_tx_init(&s->v21_tx, &preset_fsk_specs[FSK_V21CH2], (get_bit_func_t) hdlc_tx_get_bit, &s->hdlc_tx);
@ -317,16 +513,6 @@ SPAN_DECLARE(fax_modems_state_t *) fax_modems_init(fax_modems_state_t *s,
v27ter_rx_init(&s->fast_modems.v27ter_rx, 4800, non_ecm_put_bit, user_data); v27ter_rx_init(&s->fast_modems.v27ter_rx, 4800, non_ecm_put_bit, user_data);
v27ter_tx_init(&s->fast_modems.v27ter_tx, 4800, s->use_tep, non_ecm_get_bit, user_data); v27ter_tx_init(&s->fast_modems.v27ter_tx, 4800, s->use_tep, non_ecm_get_bit, user_data);
silence_gen_init(&s->silence_gen, 0); silence_gen_init(&s->silence_gen, 0);
modem_connect_tones_tx_init(&s->connect_tx, MODEM_CONNECT_TONES_FAX_CNG);
if (tone_callback)
{
modem_connect_tones_rx_init(&s->connect_rx,
MODEM_CONNECT_TONES_FAX_CNG,
tone_callback,
user_data);
}
/*endif*/
dc_restore_init(&s->dc_restore);
s->rx_signal_present = FALSE; s->rx_signal_present = FALSE;
s->rx_handler = (span_rx_handler_t) &span_dummy_rx; s->rx_handler = (span_rx_handler_t) &span_dummy_rx;

View File

@ -65,10 +65,30 @@ SPAN_DECLARE_NONSTD(int) fax_modems_v17_v21_rx_fillin(void *user_data, int len);
SPAN_DECLARE_NONSTD(int) fax_modems_v27ter_v21_rx_fillin(void *user_data, int len); SPAN_DECLARE_NONSTD(int) fax_modems_v27ter_v21_rx_fillin(void *user_data, int len);
SPAN_DECLARE_NONSTD(int) fax_modems_v29_v21_rx_fillin(void *user_data, int len); SPAN_DECLARE_NONSTD(int) fax_modems_v29_v21_rx_fillin(void *user_data, int len);
SPAN_DECLARE(void) fax_modems_hdlc_tx_frame(void *user_data, const uint8_t *msg, int len);
SPAN_DECLARE(void) fax_modems_hdlc_tx_flags(fax_modems_state_t *s, int flags);
SPAN_DECLARE(void) fax_modems_start_rx_modem(fax_modems_state_t *s, int which); SPAN_DECLARE(void) fax_modems_start_rx_modem(fax_modems_state_t *s, int which);
SPAN_DECLARE(void) fax_modems_start_fast_modem(fax_modems_state_t *s, int which, int bit_rate, int short_train, int hdlc_mode);
SPAN_DECLARE(void) fax_modems_start_slow_modem(fax_modems_state_t *s, int which);
SPAN_DECLARE(void) fax_modems_set_tep_mode(fax_modems_state_t *s, int use_tep); SPAN_DECLARE(void) fax_modems_set_tep_mode(fax_modems_state_t *s, int use_tep);
SPAN_DECLARE(void) fax_modems_set_rx_handler(fax_modems_state_t *s,
span_rx_handler_t rx_handler,
void *rx_user_data,
span_rx_fillin_handler_t rx_fillin_handler,
void *rx_fillin_user_data);
SPAN_DECLARE(void) fax_modems_set_rx_active(fax_modems_state_t *s, int active);
SPAN_DECLARE(void) fax_modems_set_tx_handler(fax_modems_state_t *s, span_tx_handler_t handler, void *user_data);
SPAN_DECLARE(void) fax_modems_set_next_tx_handler(fax_modems_state_t *s, span_tx_handler_t handler, void *user_data);
SPAN_DECLARE(int) fax_modems_restart(fax_modems_state_t *s); SPAN_DECLARE(int) fax_modems_restart(fax_modems_state_t *s);
/*! Get a pointer to the logging context associated with a FAX modems context. /*! Get a pointer to the logging context associated with a FAX modems context.

View File

@ -82,11 +82,30 @@ struct fax_modems_state_s
/*! \brief */ /*! \brief */
dc_restore_state_t dc_restore; dc_restore_state_t dc_restore;
/*! \brief The fast modem type currently in use */
int fast_modem;
/*! \brief The currently selected receiver type */ /*! \brief The currently selected receiver type */
int current_rx_type; int current_rx_type;
/*! \brief The currently selected transmitter type */ /*! \brief The currently selected transmitter type */
int current_tx_type; int current_tx_type;
int bit_rate;
int short_train;
/*! \brief The callback function used to put each bit received. */
put_bit_func_t put_bit;
/*! \brief A user specified opaque pointer passed to the put_bit routine. */
void *put_bit_user_data;
/*! \brief The callback function used to get the next bit to be transmitted. */
get_bit_func_t get_bit;
/*! \brief A user specified opaque pointer passed to the get_bit function. */
void *get_bit_user_data;
hdlc_frame_handler_t hdlc_accept;
void *hdlc_accept_user_data;
/*! \brief TRUE if a carrier is present. Otherwise FALSE. */ /*! \brief TRUE if a carrier is present. Otherwise FALSE. */
int rx_signal_present; int rx_signal_present;
/*! \brief TRUE if a modem has trained correctly. */ /*! \brief TRUE if a modem has trained correctly. */
@ -96,9 +115,9 @@ struct fax_modems_state_s
/*! \brief The current receive signal handler */ /*! \brief The current receive signal handler */
span_rx_handler_t rx_handler; span_rx_handler_t rx_handler;
void *rx_user_data;
/*! \brief The current receive missing signal fill-in handler */ /*! \brief The current receive missing signal fill-in handler */
span_rx_fillin_handler_t rx_fillin_handler; span_rx_fillin_handler_t rx_fillin_handler;
void *rx_user_data;
void *rx_fillin_user_data; void *rx_fillin_user_data;
/*! \brief The current transmit signal handler */ /*! \brief The current transmit signal handler */

View File

@ -186,9 +186,6 @@ enum
static int restart_modem(t31_state_t *s, int new_modem); static int restart_modem(t31_state_t *s, int new_modem);
static void hdlc_accept_frame(void *user_data, const uint8_t *msg, int len, int ok); static void hdlc_accept_frame(void *user_data, const uint8_t *msg, int len, int ok);
static void set_rx_handler(t31_state_t *s, span_rx_handler_t rx_handler, span_rx_fillin_handler_t fillin_handler, void *user_data);
static void set_tx_handler(t31_state_t *s, span_tx_handler_t handler, void *user_data);
static void set_next_tx_handler(t31_state_t *s, span_tx_handler_t handler, void *user_data);
static int v17_v21_rx(void *user_data, const int16_t amp[], int len); static int v17_v21_rx(void *user_data, const int16_t amp[], int len);
static int v17_v21_rx_fillin(void *user_data, int len); static int v17_v21_rx_fillin(void *user_data, int len);
static int v27ter_v21_rx(void *user_data, const int16_t amp[], int len); static int v27ter_v21_rx(void *user_data, const int16_t amp[], int len);
@ -1194,12 +1191,14 @@ static void non_ecm_rx_status(void *user_data, int status)
break; break;
case SIG_STATUS_TRAINING_FAILED: case SIG_STATUS_TRAINING_FAILED:
s->at_state.rx_trained = FALSE; s->at_state.rx_trained = FALSE;
s->audio.modems.rx_trained = FALSE;
break; break;
case SIG_STATUS_TRAINING_SUCCEEDED: case SIG_STATUS_TRAINING_SUCCEEDED:
/* The modem is now trained */ /* The modem is now trained */
at_put_response_code(&s->at_state, AT_RESPONSE_CODE_CONNECT); at_put_response_code(&s->at_state, AT_RESPONSE_CODE_CONNECT);
s->at_state.rx_signal_present = TRUE; s->at_state.rx_signal_present = TRUE;
s->at_state.rx_trained = TRUE; s->at_state.rx_trained = TRUE;
s->audio.modems.rx_trained = TRUE;
break; break;
case SIG_STATUS_CARRIER_UP: case SIG_STATUS_CARRIER_UP:
break; break;
@ -1218,6 +1217,7 @@ static void non_ecm_rx_status(void *user_data, int status)
} }
s->at_state.rx_signal_present = FALSE; s->at_state.rx_signal_present = FALSE;
s->at_state.rx_trained = FALSE; s->at_state.rx_trained = FALSE;
s->audio.modems.rx_trained = FALSE;
break; break;
default: default:
if (s->at_state.p.result_code_format) if (s->at_state.p.result_code_format)
@ -1394,7 +1394,6 @@ static void tone_detected(void *user_data, int tone, int level, int delay)
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
#if 0
static void v8_handler(void *user_data, v8_parms_t *result) static void v8_handler(void *user_data, v8_parms_t *result)
{ {
t31_state_t *s; t31_state_t *s;
@ -1403,7 +1402,6 @@ static void v8_handler(void *user_data, v8_parms_t *result)
span_log(&s->logging, SPAN_LOG_FLOW, "V.8 report received\n"); span_log(&s->logging, SPAN_LOG_FLOW, "V.8 report received\n");
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
#endif
static void hdlc_tx_underflow(void *user_data) static void hdlc_tx_underflow(void *user_data)
{ {
@ -1435,17 +1433,20 @@ static void hdlc_rx_status(void *user_data, int status)
break; break;
case SIG_STATUS_TRAINING_FAILED: case SIG_STATUS_TRAINING_FAILED:
s->at_state.rx_trained = FALSE; s->at_state.rx_trained = FALSE;
s->audio.modems.rx_trained = FALSE;
break; break;
case SIG_STATUS_TRAINING_SUCCEEDED: case SIG_STATUS_TRAINING_SUCCEEDED:
/* The modem is now trained */ /* The modem is now trained */
s->at_state.rx_signal_present = TRUE; s->at_state.rx_signal_present = TRUE;
s->at_state.rx_trained = TRUE; s->at_state.rx_trained = TRUE;
s->audio.modems.rx_trained = TRUE;
break; break;
case SIG_STATUS_CARRIER_UP: case SIG_STATUS_CARRIER_UP:
if (s->modem == FAX_MODEM_CNG_TONE || s->modem == FAX_MODEM_NOCNG_TONE || s->modem == FAX_MODEM_V21_RX) if (s->modem == FAX_MODEM_CNG_TONE || s->modem == FAX_MODEM_NOCNG_TONE || s->modem == FAX_MODEM_V21_RX)
{ {
s->at_state.rx_signal_present = TRUE; s->at_state.rx_signal_present = TRUE;
s->rx_frame_received = FALSE; s->rx_frame_received = FALSE;
s->audio.modems.rx_frame_received = FALSE;
} }
break; break;
case SIG_STATUS_CARRIER_DOWN: case SIG_STATUS_CARRIER_DOWN:
@ -1473,6 +1474,7 @@ static void hdlc_rx_status(void *user_data, int status)
} }
s->at_state.rx_signal_present = FALSE; s->at_state.rx_signal_present = FALSE;
s->at_state.rx_trained = FALSE; s->at_state.rx_trained = FALSE;
s->audio.modems.rx_trained = FALSE;
break; break;
case SIG_STATUS_FRAMING_OK: case SIG_STATUS_FRAMING_OK:
if (s->modem == FAX_MODEM_CNG_TONE || s->modem == FAX_MODEM_NOCNG_TONE) if (s->modem == FAX_MODEM_CNG_TONE || s->modem == FAX_MODEM_NOCNG_TONE)
@ -1492,6 +1494,7 @@ static void hdlc_rx_status(void *user_data, int status)
{ {
s->at_state.rx_signal_present = TRUE; s->at_state.rx_signal_present = TRUE;
s->rx_frame_received = TRUE; s->rx_frame_received = TRUE;
s->audio.modems.rx_frame_received = TRUE;
s->modem = FAX_MODEM_V21_RX; s->modem = FAX_MODEM_V21_RX;
s->at_state.transmit = FALSE; s->at_state.transmit = FALSE;
s->at_state.dte_is_waiting = TRUE; s->at_state.dte_is_waiting = TRUE;
@ -1503,6 +1506,7 @@ static void hdlc_rx_status(void *user_data, int status)
s->modem = FAX_MODEM_SILENCE_TX; s->modem = FAX_MODEM_SILENCE_TX;
t31_set_at_rx_mode(s, AT_MODE_OFFHOOK_COMMAND); t31_set_at_rx_mode(s, AT_MODE_OFFHOOK_COMMAND);
s->rx_frame_received = FALSE; s->rx_frame_received = FALSE;
s->audio.modems.rx_frame_received = FALSE;
at_put_response_code(&s->at_state, AT_RESPONSE_CODE_FCERROR); at_put_response_code(&s->at_state, AT_RESPONSE_CODE_FCERROR);
} }
} }
@ -1515,6 +1519,7 @@ static void hdlc_rx_status(void *user_data, int status)
/* Report CONNECT as soon as possible to avoid a timeout. */ /* Report CONNECT as soon as possible to avoid a timeout. */
at_put_response_code(&s->at_state, AT_RESPONSE_CODE_CONNECT); at_put_response_code(&s->at_state, AT_RESPONSE_CODE_CONNECT);
s->rx_frame_received = TRUE; s->rx_frame_received = TRUE;
s->audio.modems.rx_frame_received = TRUE;
} }
else else
{ {
@ -1553,6 +1558,7 @@ static void hdlc_accept_frame(void *user_data, const uint8_t *msg, int len, int
/* Report CONNECT as soon as possible to avoid a timeout. */ /* Report CONNECT as soon as possible to avoid a timeout. */
at_put_response_code(&s->at_state, AT_RESPONSE_CODE_CONNECT); at_put_response_code(&s->at_state, AT_RESPONSE_CODE_CONNECT);
s->rx_frame_received = TRUE; s->rx_frame_received = TRUE;
s->audio.modems.rx_frame_received = TRUE;
} }
else else
{ {
@ -1589,6 +1595,7 @@ static void hdlc_accept_frame(void *user_data, const uint8_t *msg, int len, int
at_put_response_code(&s->at_state, (ok) ? AT_RESPONSE_CODE_OK : AT_RESPONSE_CODE_ERROR); at_put_response_code(&s->at_state, (ok) ? AT_RESPONSE_CODE_OK : AT_RESPONSE_CODE_ERROR);
s->at_state.dte_is_waiting = FALSE; s->at_state.dte_is_waiting = FALSE;
s->rx_frame_received = FALSE; s->rx_frame_received = FALSE;
s->audio.modems.rx_frame_received = FALSE;
} }
} }
else else
@ -1632,8 +1639,10 @@ static int restart_modem(t31_state_t *s, int new_modem)
s->tx.final = FALSE; s->tx.final = FALSE;
s->at_state.rx_signal_present = FALSE; s->at_state.rx_signal_present = FALSE;
s->at_state.rx_trained = FALSE; s->at_state.rx_trained = FALSE;
s->audio.modems.rx_trained = FALSE;
s->rx_frame_received = FALSE; s->rx_frame_received = FALSE;
set_rx_handler(s, (span_rx_handler_t) &span_dummy_rx, (span_rx_fillin_handler_t) &span_dummy_rx_fillin, NULL); s->audio.modems.rx_frame_received = FALSE;
fax_modems_set_rx_handler(t, (span_rx_handler_t) &span_dummy_rx, NULL, (span_rx_fillin_handler_t) &span_dummy_rx_fillin, NULL);
use_hdlc = FALSE; use_hdlc = FALSE;
switch (s->modem) switch (s->modem)
{ {
@ -1652,10 +1661,10 @@ static int restart_modem(t31_state_t *s, int new_modem)
/* Do V.21/HDLC receive in parallel. The other end may send its /* Do V.21/HDLC receive in parallel. The other end may send its
first message at any time. The CNG tone will continue until first message at any time. The CNG tone will continue until
we get a valid preamble. */ we get a valid preamble. */
set_rx_handler(s, (span_rx_handler_t) &cng_rx, (span_rx_fillin_handler_t) &span_dummy_rx_fillin, s);
t31_v21_rx(s); t31_v21_rx(s);
set_tx_handler(s, (span_tx_handler_t) &modem_connect_tones_tx, &t->connect_tx); fax_modems_set_rx_handler(t, (span_rx_handler_t) &cng_rx, s, (span_rx_fillin_handler_t) &span_dummy_rx_fillin, NULL);
set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL); fax_modems_set_tx_handler(t, (span_tx_handler_t) &modem_connect_tones_tx, &t->connect_tx);
fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
} }
s->at_state.transmit = TRUE; s->at_state.transmit = TRUE;
break; break;
@ -1665,10 +1674,10 @@ static int restart_modem(t31_state_t *s, int new_modem)
} }
else else
{ {
set_rx_handler(s, (span_rx_handler_t) &cng_rx, (span_rx_fillin_handler_t) &span_dummy_rx_fillin, s);
t31_v21_rx(s); t31_v21_rx(s);
fax_modems_set_rx_handler(t, (span_rx_handler_t) &cng_rx, s, (span_rx_fillin_handler_t) &span_dummy_rx_fillin, NULL);
silence_gen_set(&t->silence_gen, 0); silence_gen_set(&t->silence_gen, 0);
set_tx_handler(s, (span_tx_handler_t) &silence_gen, &t->silence_gen); fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
} }
s->at_state.transmit = FALSE; s->at_state.transmit = FALSE;
break; break;
@ -1682,8 +1691,8 @@ static int restart_modem(t31_state_t *s, int new_modem)
else else
{ {
modem_connect_tones_tx_init(&t->connect_tx, MODEM_CONNECT_TONES_FAX_CED); modem_connect_tones_tx_init(&t->connect_tx, MODEM_CONNECT_TONES_FAX_CED);
set_tx_handler(s, (span_tx_handler_t) &modem_connect_tones_tx, &t->connect_tx); fax_modems_set_tx_handler(t, (span_tx_handler_t) &modem_connect_tones_tx, &t->connect_tx);
set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL); fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
} }
s->at_state.transmit = TRUE; s->at_state.transmit = TRUE;
break; break;
@ -1702,8 +1711,8 @@ static int restart_modem(t31_state_t *s, int new_modem)
/* The spec says 1s +-15% of preamble. So, the minimum is 32 octets. */ /* The spec says 1s +-15% of preamble. So, the minimum is 32 octets. */
hdlc_tx_flags(&t->hdlc_tx, 32); hdlc_tx_flags(&t->hdlc_tx, 32);
fsk_tx_init(&t->v21_tx, &preset_fsk_specs[FSK_V21CH2], (get_bit_func_t) hdlc_tx_get_bit, &t->hdlc_tx); fsk_tx_init(&t->v21_tx, &preset_fsk_specs[FSK_V21CH2], (get_bit_func_t) hdlc_tx_get_bit, &t->hdlc_tx);
set_tx_handler(s, (span_tx_handler_t) &fsk_tx, &t->v21_tx); fax_modems_set_tx_handler(t, (span_tx_handler_t) &fsk_tx, &t->v21_tx);
set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL); fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
} }
s->hdlc_tx.final = FALSE; s->hdlc_tx.final = FALSE;
s->hdlc_tx.len = 0; s->hdlc_tx.len = 0;
@ -1716,8 +1725,8 @@ static int restart_modem(t31_state_t *s, int new_modem)
} }
else else
{ {
set_rx_handler(s, (span_rx_handler_t) &fsk_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &t->v21_rx);
t31_v21_rx(s); t31_v21_rx(s);
fax_modems_set_rx_handler(t, (span_rx_handler_t) &fsk_rx, &t->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &t->v21_rx);
} }
break; break;
case FAX_MODEM_V17_TX: case FAX_MODEM_V17_TX:
@ -1748,8 +1757,8 @@ static int restart_modem(t31_state_t *s, int new_modem)
else else
{ {
v17_tx_restart(&t->fast_modems.v17_tx, s->bit_rate, FALSE, s->short_train); v17_tx_restart(&t->fast_modems.v17_tx, s->bit_rate, FALSE, s->short_train);
set_tx_handler(s, (span_tx_handler_t) &v17_tx, &t->fast_modems.v17_tx); fax_modems_set_tx_handler(t, (span_tx_handler_t) &v17_tx, &t->fast_modems.v17_tx);
set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL); fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
} }
s->tx.out_bytes = 0; s->tx.out_bytes = 0;
s->tx.data_started = FALSE; s->tx.data_started = FALSE;
@ -1758,7 +1767,7 @@ static int restart_modem(t31_state_t *s, int new_modem)
case FAX_MODEM_V17_RX: case FAX_MODEM_V17_RX:
if (!s->t38_mode) if (!s->t38_mode)
{ {
set_rx_handler(s, (span_rx_handler_t) &v17_v21_rx, (span_rx_fillin_handler_t) &v17_v21_rx_fillin, s); fax_modems_set_rx_handler(t, (span_rx_handler_t) &v17_v21_rx, s, (span_rx_fillin_handler_t) &v17_v21_rx_fillin, s);
v17_rx_restart(&t->fast_modems.v17_rx, s->bit_rate, s->short_train); v17_rx_restart(&t->fast_modems.v17_rx, s->bit_rate, s->short_train);
/* Allow for +FCERROR/+FRH:3 */ /* Allow for +FCERROR/+FRH:3 */
t31_v21_rx(s); t31_v21_rx(s);
@ -1785,8 +1794,8 @@ static int restart_modem(t31_state_t *s, int new_modem)
else else
{ {
v27ter_tx_restart(&t->fast_modems.v27ter_tx, s->bit_rate, FALSE); v27ter_tx_restart(&t->fast_modems.v27ter_tx, s->bit_rate, FALSE);
set_tx_handler(s, (span_tx_handler_t) &v27ter_tx, &t->fast_modems.v27ter_tx); fax_modems_set_tx_handler(t, (span_tx_handler_t) &v27ter_tx, &t->fast_modems.v27ter_tx);
set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL); fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
} }
s->tx.out_bytes = 0; s->tx.out_bytes = 0;
s->tx.data_started = FALSE; s->tx.data_started = FALSE;
@ -1795,7 +1804,7 @@ static int restart_modem(t31_state_t *s, int new_modem)
case FAX_MODEM_V27TER_RX: case FAX_MODEM_V27TER_RX:
if (!s->t38_mode) if (!s->t38_mode)
{ {
set_rx_handler(s, (span_rx_handler_t) &v27ter_v21_rx, (span_rx_fillin_handler_t) &v27ter_v21_rx_fillin, s); fax_modems_set_rx_handler(t, (span_rx_handler_t) &v27ter_v21_rx, s, (span_rx_fillin_handler_t) &v27ter_v21_rx_fillin, s);
v27ter_rx_restart(&t->fast_modems.v27ter_rx, s->bit_rate, FALSE); v27ter_rx_restart(&t->fast_modems.v27ter_rx, s->bit_rate, FALSE);
/* Allow for +FCERROR/+FRH:3 */ /* Allow for +FCERROR/+FRH:3 */
t31_v21_rx(s); t31_v21_rx(s);
@ -1822,8 +1831,8 @@ static int restart_modem(t31_state_t *s, int new_modem)
else else
{ {
v29_tx_restart(&t->fast_modems.v29_tx, s->bit_rate, FALSE); v29_tx_restart(&t->fast_modems.v29_tx, s->bit_rate, FALSE);
set_tx_handler(s, (span_tx_handler_t) &v29_tx, &t->fast_modems.v29_tx); fax_modems_set_tx_handler(t, (span_tx_handler_t) &v29_tx, &t->fast_modems.v29_tx);
set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL); fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
} }
s->tx.out_bytes = 0; s->tx.out_bytes = 0;
s->tx.data_started = FALSE; s->tx.data_started = FALSE;
@ -1832,7 +1841,7 @@ static int restart_modem(t31_state_t *s, int new_modem)
case FAX_MODEM_V29_RX: case FAX_MODEM_V29_RX:
if (!s->t38_mode) if (!s->t38_mode)
{ {
set_rx_handler(s, (span_rx_handler_t) &v29_v21_rx, (span_rx_fillin_handler_t) &v29_v21_rx_fillin, s); fax_modems_set_rx_handler(t, (span_rx_handler_t) &v29_v21_rx, s, (span_rx_fillin_handler_t) &v29_v21_rx_fillin, s);
v29_rx_restart(&t->fast_modems.v29_rx, s->bit_rate, FALSE); v29_rx_restart(&t->fast_modems.v29_rx, s->bit_rate, FALSE);
/* Allow for +FCERROR/+FRH:3 */ /* Allow for +FCERROR/+FRH:3 */
t31_v21_rx(s); t31_v21_rx(s);
@ -1853,18 +1862,18 @@ static int restart_modem(t31_state_t *s, int new_modem)
else else
{ {
silence_gen_set(&t->silence_gen, 0); silence_gen_set(&t->silence_gen, 0);
set_tx_handler(s, (span_tx_handler_t) &silence_gen, &t->silence_gen); fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL); fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
} }
s->at_state.transmit = FALSE; s->at_state.transmit = FALSE;
break; break;
case FAX_MODEM_SILENCE_RX: case FAX_MODEM_SILENCE_RX:
if (!s->t38_mode) if (!s->t38_mode)
{ {
set_rx_handler(s, (span_rx_handler_t) &silence_rx, (span_rx_fillin_handler_t) &span_dummy_rx_fillin, s); fax_modems_set_rx_handler(t, (span_rx_handler_t) &silence_rx, s, (span_rx_fillin_handler_t) &span_dummy_rx_fillin, NULL);
silence_gen_set(&t->silence_gen, 0); silence_gen_set(&t->silence_gen, 0);
set_tx_handler(s, (span_tx_handler_t) &silence_gen, &t->silence_gen); fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL); fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
} }
s->at_state.transmit = FALSE; s->at_state.transmit = FALSE;
break; break;
@ -1881,8 +1890,8 @@ static int restart_modem(t31_state_t *s, int new_modem)
{ {
s->modem = FAX_MODEM_SILENCE_TX; s->modem = FAX_MODEM_SILENCE_TX;
silence_gen_alter(&t->silence_gen, ms_to_samples(200)); silence_gen_alter(&t->silence_gen, ms_to_samples(200));
set_tx_handler(s, (span_tx_handler_t) &silence_gen, &t->silence_gen); fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL); fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
s->at_state.transmit = TRUE; s->at_state.transmit = TRUE;
} }
break; break;
@ -2055,6 +2064,7 @@ static int process_class1_cmd(at_state_t *t, void *user_data, int direction, int
/* Send straight away, if there is something queued. */ /* Send straight away, if there is something queued. */
t31_set_at_rx_mode(s, AT_MODE_DELIVERY); t31_set_at_rx_mode(s, AT_MODE_DELIVERY);
s->rx_frame_received = FALSE; s->rx_frame_received = FALSE;
s->audio.modems.rx_frame_received = FALSE;
do do
{ {
if (!queue_empty(s->rx_queue)) if (!queue_empty(s->rx_queue))
@ -2225,7 +2235,7 @@ SPAN_DECLARE(int) t31_at_rx(t31_state_t *s, const char *t, int len)
s->at_state.rx_data_bytes = 0; s->at_state.rx_data_bytes = 0;
s->at_state.transmit = FALSE; s->at_state.transmit = FALSE;
s->modem = FAX_MODEM_SILENCE_TX; s->modem = FAX_MODEM_SILENCE_TX;
set_rx_handler(s, (span_rx_handler_t) &span_dummy_rx, (span_rx_fillin_handler_t) &span_dummy_rx_fillin, NULL); fax_modems_set_rx_handler(&s->audio.modems, (span_rx_handler_t) &span_dummy_rx, NULL, (span_rx_fillin_handler_t) &span_dummy_rx_fillin, NULL);
t31_set_at_rx_mode(s, AT_MODE_OFFHOOK_COMMAND); t31_set_at_rx_mode(s, AT_MODE_OFFHOOK_COMMAND);
at_put_response_code(&s->at_state, AT_RESPONSE_CODE_OK); at_put_response_code(&s->at_state, AT_RESPONSE_CODE_OK);
} }
@ -2251,31 +2261,6 @@ SPAN_DECLARE(int) t31_at_rx(t31_state_t *s, const char *t, int len)
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
static void set_rx_handler(t31_state_t *s,
span_rx_handler_t rx_handler,
span_rx_fillin_handler_t fillin_handler,
void *user_data)
{
s->audio.modems.rx_handler = rx_handler;
s->audio.modems.rx_fillin_handler = fillin_handler;
s->audio.modems.rx_user_data = user_data;
}
/*- End of function --------------------------------------------------------*/
static void set_tx_handler(t31_state_t *s, span_tx_handler_t handler, void *user_data)
{
s->audio.modems.tx_handler = handler;
s->audio.modems.tx_user_data = user_data;
}
/*- End of function --------------------------------------------------------*/
static void set_next_tx_handler(t31_state_t *s, span_tx_handler_t handler, void *user_data)
{
s->audio.modems.next_tx_handler = handler;
s->audio.modems.next_tx_user_data = user_data;
}
/*- End of function --------------------------------------------------------*/
static int silence_rx(void *user_data, const int16_t amp[], int len) static int silence_rx(void *user_data, const int16_t amp[], int len)
{ {
t31_state_t *s; t31_state_t *s;
@ -2326,8 +2311,8 @@ static int v17_v21_rx(void *user_data, const int16_t amp[], int len)
{ {
/* The fast modem has trained, so we no longer need to run the slow /* The fast modem has trained, so we no longer need to run the slow
one in parallel. */ one in parallel. */
span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.17 (%.2fdBm0)\n", v17_rx_signal_power(&s->fast_modems.v17_rx)); span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.17 (%.2fdBm0)\n", v17_rx_signal_power(&s->fast_modems.v17_rx));
set_rx_handler(t, (span_rx_handler_t) &v17_rx, (span_rx_fillin_handler_t) &v17_rx_fillin, &s->fast_modems.v17_rx); fax_modems_set_rx_handler(s, (span_rx_handler_t) &v17_rx, &s->fast_modems.v17_rx, (span_rx_fillin_handler_t) &v17_rx_fillin, &s->fast_modems.v17_rx);
} }
else else
{ {
@ -2336,8 +2321,8 @@ static int v17_v21_rx(void *user_data, const int16_t amp[], int len)
{ {
/* We have received something, and the fast modem has not trained. We must /* We have received something, and the fast modem has not trained. We must
be receiving valid V.21 */ be receiving valid V.21 */
span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx)); span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
set_rx_handler(t, (span_rx_handler_t) &fsk_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx); fax_modems_set_rx_handler(s, (span_rx_handler_t) &fsk_rx, &s->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
} }
} }
return len; return len;
@ -2369,8 +2354,8 @@ static int v27ter_v21_rx(void *user_data, const int16_t amp[], int len)
{ {
/* The fast modem has trained, so we no longer need to run the slow /* The fast modem has trained, so we no longer need to run the slow
one in parallel. */ one in parallel. */
span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.27ter (%.2fdBm0)\n", v27ter_rx_signal_power(&s->fast_modems.v27ter_rx)); span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.27ter (%.2fdBm0)\n", v27ter_rx_signal_power(&s->fast_modems.v27ter_rx));
set_rx_handler(t, (span_rx_handler_t) &v27ter_rx, (span_rx_fillin_handler_t) &v27ter_rx_fillin, &s->fast_modems.v27ter_rx); fax_modems_set_rx_handler(s, (span_rx_handler_t) &v27ter_rx, &s->fast_modems.v27ter_rx, (span_rx_fillin_handler_t) &v27ter_rx_fillin, &s->fast_modems.v27ter_rx);
} }
else else
{ {
@ -2379,8 +2364,8 @@ static int v27ter_v21_rx(void *user_data, const int16_t amp[], int len)
{ {
/* We have received something, and the fast modem has not trained. We must /* We have received something, and the fast modem has not trained. We must
be receiving valid V.21 */ be receiving valid V.21 */
span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx)); span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
set_rx_handler(t, (span_rx_handler_t) &fsk_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx); fax_modems_set_rx_handler(s, (span_rx_handler_t) &fsk_rx, &s->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
} }
} }
return len; return len;
@ -2413,7 +2398,7 @@ static int v29_v21_rx(void *user_data, const int16_t amp[], int len)
/* The fast modem has trained, so we no longer need to run the slow /* The fast modem has trained, so we no longer need to run the slow
one in parallel. */ one in parallel. */
span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.29 (%.2fdBm0)\n", v29_rx_signal_power(&s->fast_modems.v29_rx)); span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.29 (%.2fdBm0)\n", v29_rx_signal_power(&s->fast_modems.v29_rx));
set_rx_handler(t, (span_rx_handler_t) &v29_rx, (span_rx_fillin_handler_t) &v29_rx_fillin, &s->fast_modems.v29_rx); fax_modems_set_rx_handler(s, (span_rx_handler_t) &v29_rx, &s->fast_modems.v29_rx, (span_rx_fillin_handler_t) &v29_rx_fillin, &s->fast_modems.v29_rx);
} }
else else
{ {
@ -2422,8 +2407,8 @@ static int v29_v21_rx(void *user_data, const int16_t amp[], int len)
{ {
/* We have received something, and the fast modem has not trained. We must /* We have received something, and the fast modem has not trained. We must
be receiving valid V.21 */ be receiving valid V.21 */
span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx)); span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
set_rx_handler(t, (span_rx_handler_t) &fsk_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx); fax_modems_set_rx_handler(s, (span_rx_handler_t) &fsk_rx, &s->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
} }
} }
return len; return len;
@ -2535,14 +2520,14 @@ static int set_next_tx_type(t31_state_t *s)
{ {
if (s->audio.next_tx_handler) if (s->audio.next_tx_handler)
{ {
set_tx_handler(s, s->audio.next_tx_handler, s->audio.next_tx_user_data); fax_modems_set_tx_handler(&s->audio.modems, s->audio.next_tx_handler, s->audio.next_tx_user_data);
set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL); fax_modems_set_next_tx_handler(&s->audio.modems, (span_tx_handler_t) NULL, NULL);
return 0; return 0;
} }
/* There is nothing else to change to, so use zero length silence */ /* There is nothing else to change to, so use zero length silence */
silence_gen_alter(&s->audio.modems.silence_gen, 0); silence_gen_alter(&s->audio.modems.silence_gen, 0);
set_tx_handler(s, (span_tx_handler_t) &silence_gen, &s->audio.modems.silence_gen); fax_modems_set_tx_handler(&s->audio.modems, (span_tx_handler_t) &silence_gen, &s->audio.modems.silence_gen);
set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL); fax_modems_set_next_tx_handler(&s->audio.modems, (span_tx_handler_t) NULL, NULL);
return -1; return -1;
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
@ -2671,9 +2656,7 @@ SPAN_DECLARE(t31_state_t *) t31_init(t31_state_t *s,
t38_tx_packet_handler_t tx_t38_packet_handler, t38_tx_packet_handler_t tx_t38_packet_handler,
void *tx_t38_packet_user_data) void *tx_t38_packet_user_data)
{ {
#if 0
v8_parms_t v8_parms; v8_parms_t v8_parms;
#endif
int alloced; int alloced;
if (at_tx_handler == NULL || modem_control_handler == NULL) if (at_tx_handler == NULL || modem_control_handler == NULL)
@ -2700,7 +2683,6 @@ SPAN_DECLARE(t31_state_t *) t31_init(t31_state_t *s,
non_ecm_get_bit, non_ecm_get_bit,
tone_detected, tone_detected,
(void *) s); (void *) s);
#if 0
v8_parms.modem_connect_tone = MODEM_CONNECT_TONES_ANSAM_PR; v8_parms.modem_connect_tone = MODEM_CONNECT_TONES_ANSAM_PR;
v8_parms.call_function = V8_CALL_T30_RX; v8_parms.call_function = V8_CALL_T30_RX;
v8_parms.modulations = V8_MOD_V21 v8_parms.modulations = V8_MOD_V21
@ -2717,12 +2699,12 @@ SPAN_DECLARE(t31_state_t *) t31_init(t31_state_t *s,
v8_parms.t66 = -1; v8_parms.t66 = -1;
v8_init(&s->audio.v8, FALSE, &v8_parms, v8_handler, s); v8_init(&s->audio.v8, FALSE, &v8_parms, v8_handler, s);
#endif
power_meter_init(&s->audio.rx_power, 4); power_meter_init(&s->audio.rx_power, 4);
s->audio.last_sample = 0; s->audio.last_sample = 0;
s->audio.silence_threshold_power = power_meter_level_dbm0(-36); s->audio.silence_threshold_power = power_meter_level_dbm0(-36);
s->at_state.rx_signal_present = FALSE; s->at_state.rx_signal_present = FALSE;
s->at_state.rx_trained = FALSE; s->at_state.rx_trained = FALSE;
s->audio.modems.rx_trained = FALSE;
s->at_state.do_hangup = FALSE; s->at_state.do_hangup = FALSE;
s->at_state.line_ptr = 0; s->at_state.line_ptr = 0;

View File

@ -196,7 +196,11 @@ static void non_ecm_remove_fill_and_put_bit(void *user_data, int bit);
static void non_ecm_push_residue(t38_gateway_state_t *s); static void non_ecm_push_residue(t38_gateway_state_t *s);
static void tone_detected(void *user_data, int tone, int level, int delay); static void tone_detected(void *user_data, int tone, int level, int delay);
static void set_rx_handler(t38_gateway_state_t *s, span_rx_handler_t handler, span_rx_fillin_handler_t fillin_handler, void *user_data) static void set_rx_handler(t38_gateway_state_t *s,
span_rx_handler_t handler,
void *user_data,
span_rx_fillin_handler_t fillin_handler,
void *rx_fillin_user_data)
{ {
if (s->audio.modems.rx_handler != span_dummy_rx) if (s->audio.modems.rx_handler != span_dummy_rx)
{ {
@ -207,6 +211,7 @@ static void set_rx_handler(t38_gateway_state_t *s, span_rx_handler_t handler, sp
s->audio.base_rx_handler = handler; s->audio.base_rx_handler = handler;
s->audio.base_rx_fillin_handler = fillin_handler; s->audio.base_rx_fillin_handler = fillin_handler;
s->audio.modems.rx_user_data = user_data; s->audio.modems.rx_user_data = user_data;
s->audio.modems.rx_fillin_user_data = rx_fillin_user_data;
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
@ -257,7 +262,7 @@ static int v17_v21_rx(void *user_data, const int16_t amp[], int len)
/* The fast modem has trained, so we no longer need to run the slow /* The fast modem has trained, so we no longer need to run the slow
one in parallel. */ one in parallel. */
span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.17 (%.2fdBm0)\n", v17_rx_signal_power(&s->fast_modems.v17_rx)); span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.17 (%.2fdBm0)\n", v17_rx_signal_power(&s->fast_modems.v17_rx));
set_rx_handler(t, (span_rx_handler_t) &v17_rx, (span_rx_fillin_handler_t) &v17_rx_fillin, &s->fast_modems.v17_rx); set_rx_handler(t, (span_rx_handler_t) &v17_rx, &s->fast_modems.v17_rx, (span_rx_fillin_handler_t) &v17_rx_fillin, &s->fast_modems.v17_rx);
} }
else else
{ {
@ -265,7 +270,7 @@ static int v17_v21_rx(void *user_data, const int16_t amp[], int len)
if (s->rx_signal_present) if (s->rx_signal_present)
{ {
span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx)); span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
set_rx_handler(t, (span_rx_handler_t) &fsk_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx); set_rx_handler(t, (span_rx_handler_t) &fsk_rx, &s->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
} }
/*endif*/ /*endif*/
} }
@ -300,7 +305,7 @@ static int v27ter_v21_rx(void *user_data, const int16_t amp[], int len)
/* The fast modem has trained, so we no longer need to run the slow /* The fast modem has trained, so we no longer need to run the slow
one in parallel. */ one in parallel. */
span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.27ter (%.2fdBm0)\n", v27ter_rx_signal_power(&s->fast_modems.v27ter_rx)); span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.27ter (%.2fdBm0)\n", v27ter_rx_signal_power(&s->fast_modems.v27ter_rx));
set_rx_handler(t, (span_rx_handler_t) &v27ter_rx, (span_rx_fillin_handler_t) &v27ter_v21_rx_fillin, &s->fast_modems.v27ter_rx); set_rx_handler(t, (span_rx_handler_t) &v27ter_rx, &s->fast_modems.v27ter_rx, (span_rx_fillin_handler_t) &v27ter_v21_rx_fillin, &s->fast_modems.v27ter_rx);
} }
else else
{ {
@ -308,7 +313,7 @@ static int v27ter_v21_rx(void *user_data, const int16_t amp[], int len)
if (s->rx_signal_present) if (s->rx_signal_present)
{ {
span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx)); span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
set_rx_handler(t, (span_rx_handler_t) &fsk_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx); set_rx_handler(t, (span_rx_handler_t) &fsk_rx, &s->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
} }
/*endif*/ /*endif*/
} }
@ -343,7 +348,7 @@ static int v29_v21_rx(void *user_data, const int16_t amp[], int len)
/* The fast modem has trained, so we no longer need to run the slow /* The fast modem has trained, so we no longer need to run the slow
one in parallel. */ one in parallel. */
span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.29 (%.2fdBm0)\n", v29_rx_signal_power(&s->fast_modems.v29_rx)); span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.29 (%.2fdBm0)\n", v29_rx_signal_power(&s->fast_modems.v29_rx));
set_rx_handler(t, (span_rx_handler_t) &v29_rx, (span_rx_fillin_handler_t) &v29_rx_fillin, &s->fast_modems.v29_rx); set_rx_handler(t, (span_rx_handler_t) &v29_rx, &s->fast_modems.v29_rx, (span_rx_fillin_handler_t) &v29_rx_fillin, &s->fast_modems.v29_rx);
} }
else else
{ {
@ -351,7 +356,7 @@ static int v29_v21_rx(void *user_data, const int16_t amp[], int len)
if (s->rx_signal_present) if (s->rx_signal_present)
{ {
span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx)); span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
set_rx_handler(t, (span_rx_handler_t) &fsk_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx); set_rx_handler(t, (span_rx_handler_t) &fsk_rx, &s->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
} }
/*endif*/ /*endif*/
} }
@ -422,6 +427,7 @@ static int set_next_tx_type(t38_gateway_state_t *s)
int short_train; int short_train;
fax_modems_state_t *t; fax_modems_state_t *t;
t38_gateway_hdlc_state_t *u; t38_gateway_hdlc_state_t *u;
int bit_rate;
t = &s->audio.modems; t = &s->audio.modems;
t38_non_ecm_buffer_report_output_status(&s->core.non_ecm_to_modem, &s->logging); t38_non_ecm_buffer_report_output_status(&s->core.non_ecm_to_modem, &s->logging);
@ -511,16 +517,8 @@ static int set_next_tx_type(t38_gateway_state_t *s)
break; break;
case T38_IND_V27TER_2400_TRAINING: case T38_IND_V27TER_2400_TRAINING:
case T38_IND_V27TER_4800_TRAINING: case T38_IND_V27TER_4800_TRAINING:
switch (indicator) bit_rate =
{ t->tx_bit_rate = (indicator == T38_IND_V27TER_4800_TRAINING) ? 4800 : 2400;
case T38_IND_V27TER_2400_TRAINING:
t->tx_bit_rate = 2400;
break;
case T38_IND_V27TER_4800_TRAINING:
t->tx_bit_rate = 4800;
break;
}
/*endswitch*/
silence_gen_alter(&t->silence_gen, ms_to_samples(75)); silence_gen_alter(&t->silence_gen, ms_to_samples(75));
v27ter_tx_restart(&t->fast_modems.v27ter_tx, t->tx_bit_rate, t->use_tep); v27ter_tx_restart(&t->fast_modems.v27ter_tx, t->tx_bit_rate, t->use_tep);
v27ter_tx_set_get_bit(&t->fast_modems.v27ter_tx, get_bit_func, get_bit_user_data); v27ter_tx_set_get_bit(&t->fast_modems.v27ter_tx, get_bit_func, get_bit_user_data);
@ -530,16 +528,8 @@ static int set_next_tx_type(t38_gateway_state_t *s)
break; break;
case T38_IND_V29_7200_TRAINING: case T38_IND_V29_7200_TRAINING:
case T38_IND_V29_9600_TRAINING: case T38_IND_V29_9600_TRAINING:
switch (indicator) bit_rate =
{ t->tx_bit_rate = (indicator == T38_IND_V29_9600_TRAINING) ? 9600 : 7200;
case T38_IND_V29_7200_TRAINING:
t->tx_bit_rate = 7200;
break;
case T38_IND_V29_9600_TRAINING:
t->tx_bit_rate = 9600;
break;
}
/*endswitch*/
silence_gen_alter(&t->silence_gen, ms_to_samples(75)); silence_gen_alter(&t->silence_gen, ms_to_samples(75));
v29_tx_restart(&t->fast_modems.v29_tx, t->tx_bit_rate, t->use_tep); v29_tx_restart(&t->fast_modems.v29_tx, t->tx_bit_rate, t->use_tep);
v29_tx_set_get_bit(&t->fast_modems.v29_tx, get_bit_func, get_bit_user_data); v29_tx_set_get_bit(&t->fast_modems.v29_tx, get_bit_func, get_bit_user_data);
@ -560,34 +550,35 @@ static int set_next_tx_type(t38_gateway_state_t *s)
{ {
case T38_IND_V17_7200_SHORT_TRAINING: case T38_IND_V17_7200_SHORT_TRAINING:
short_train = TRUE; short_train = TRUE;
t->tx_bit_rate = 7200; bit_rate = 7200;
break; break;
case T38_IND_V17_7200_LONG_TRAINING: case T38_IND_V17_7200_LONG_TRAINING:
t->tx_bit_rate = 7200; bit_rate = 7200;
break; break;
case T38_IND_V17_9600_SHORT_TRAINING: case T38_IND_V17_9600_SHORT_TRAINING:
short_train = TRUE; short_train = TRUE;
t->tx_bit_rate = 9600; bit_rate = 9600;
break; break;
case T38_IND_V17_9600_LONG_TRAINING: case T38_IND_V17_9600_LONG_TRAINING:
t->tx_bit_rate = 9600; bit_rate = 9600;
break; break;
case T38_IND_V17_12000_SHORT_TRAINING: case T38_IND_V17_12000_SHORT_TRAINING:
short_train = TRUE; short_train = TRUE;
t->tx_bit_rate = 12000; bit_rate = 12000;
break; break;
case T38_IND_V17_12000_LONG_TRAINING: case T38_IND_V17_12000_LONG_TRAINING:
t->tx_bit_rate = 12000; bit_rate = 12000;
break; break;
case T38_IND_V17_14400_SHORT_TRAINING: case T38_IND_V17_14400_SHORT_TRAINING:
short_train = TRUE; short_train = TRUE;
t->tx_bit_rate = 14400; bit_rate = 14400;
break; break;
case T38_IND_V17_14400_LONG_TRAINING: case T38_IND_V17_14400_LONG_TRAINING:
t->tx_bit_rate = 14400; bit_rate = 14400;
break; break;
} }
/*endswitch*/ /*endswitch*/
t->tx_bit_rate = bit_rate;
silence_gen_alter(&t->silence_gen, ms_to_samples(75)); silence_gen_alter(&t->silence_gen, ms_to_samples(75));
v17_tx_restart(&t->fast_modems.v17_tx, t->tx_bit_rate, t->use_tep, short_train); v17_tx_restart(&t->fast_modems.v17_tx, t->tx_bit_rate, t->use_tep, short_train);
v17_tx_set_get_bit(&t->fast_modems.v17_tx, get_bit_func, get_bit_user_data); v17_tx_set_get_bit(&t->fast_modems.v17_tx, get_bit_func, get_bit_user_data);
@ -1087,7 +1078,7 @@ static int process_rx_indicator(t38_core_state_t *t, void *user_data, int indica
span_log(&s->logging, span_log(&s->logging,
SPAN_LOG_FLOW, SPAN_LOG_FLOW,
"Changing - (%d) %s -> %s\n", "Changing - (%d) %s -> %s\n",
silence_gen_remainder(&(s->audio.modems.silence_gen)), silence_gen_remainder(&s->audio.modems.silence_gen),
t38_indicator_to_str(t->current_rx_indicator), t38_indicator_to_str(t->current_rx_indicator),
t38_indicator_to_str(indicator)); t38_indicator_to_str(indicator));
switch (s->t38x.current_rx_field_class) switch (s->t38x.current_rx_field_class)
@ -1107,7 +1098,7 @@ static int process_rx_indicator(t38_core_state_t *t, void *user_data, int indica
span_log(&s->logging, span_log(&s->logging,
SPAN_LOG_FLOW, SPAN_LOG_FLOW,
"Queued change - (%d) %s -> %s\n", "Queued change - (%d) %s -> %s\n",
silence_gen_remainder(&(s->audio.modems.silence_gen)), silence_gen_remainder(&s->audio.modems.silence_gen),
t38_indicator_to_str(t->current_rx_indicator), t38_indicator_to_str(t->current_rx_indicator),
t38_indicator_to_str(indicator)); t38_indicator_to_str(indicator));
} }
@ -2159,23 +2150,23 @@ static int restart_rx_modem(t38_gateway_state_t *s)
case FAX_MODEM_V27TER_RX: case FAX_MODEM_V27TER_RX:
v27ter_rx_restart(&t->fast_modems.v27ter_rx, s->core.fast_bit_rate, FALSE); v27ter_rx_restart(&t->fast_modems.v27ter_rx, s->core.fast_bit_rate, FALSE);
v27ter_rx_set_put_bit(&t->fast_modems.v27ter_rx, put_bit_func, put_bit_user_data); v27ter_rx_set_put_bit(&t->fast_modems.v27ter_rx, put_bit_func, put_bit_user_data);
set_rx_handler(s, &v27ter_v21_rx, &v27ter_v21_rx_fillin, s); set_rx_handler(s, &v27ter_v21_rx, s, &v27ter_v21_rx_fillin, s);
s->core.fast_rx_active = FAX_MODEM_V27TER_RX; s->core.fast_rx_active = FAX_MODEM_V27TER_RX;
break; break;
case FAX_MODEM_V29_RX: case FAX_MODEM_V29_RX:
v29_rx_restart(&t->fast_modems.v29_rx, s->core.fast_bit_rate, FALSE); v29_rx_restart(&t->fast_modems.v29_rx, s->core.fast_bit_rate, FALSE);
v29_rx_set_put_bit(&t->fast_modems.v29_rx, put_bit_func, put_bit_user_data); v29_rx_set_put_bit(&t->fast_modems.v29_rx, put_bit_func, put_bit_user_data);
set_rx_handler(s, &v29_v21_rx, &v29_v21_rx_fillin, s); set_rx_handler(s, &v29_v21_rx, s, &v29_v21_rx_fillin, s);
s->core.fast_rx_active = FAX_MODEM_V29_RX; s->core.fast_rx_active = FAX_MODEM_V29_RX;
break; break;
case FAX_MODEM_V17_RX: case FAX_MODEM_V17_RX:
v17_rx_restart(&t->fast_modems.v17_rx, s->core.fast_bit_rate, s->core.short_train); v17_rx_restart(&t->fast_modems.v17_rx, s->core.fast_bit_rate, s->core.short_train);
v17_rx_set_put_bit(&t->fast_modems.v17_rx, put_bit_func, put_bit_user_data); v17_rx_set_put_bit(&t->fast_modems.v17_rx, put_bit_func, put_bit_user_data);
set_rx_handler(s, &v17_v21_rx, &v17_v21_rx_fillin, s); set_rx_handler(s, &v17_v21_rx, s, &v17_v21_rx_fillin, s);
s->core.fast_rx_active = FAX_MODEM_V17_RX; s->core.fast_rx_active = FAX_MODEM_V17_RX;
break; break;
default: default:
set_rx_handler(s, (span_rx_handler_t) &fsk_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &t->v21_rx); set_rx_handler(s, (span_rx_handler_t) &fsk_rx, &t->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &t->v21_rx);
s->core.fast_rx_active = FAX_MODEM_NONE; s->core.fast_rx_active = FAX_MODEM_NONE;
break; break;
} }
@ -2233,7 +2224,7 @@ SPAN_DECLARE_NONSTD(int) t38_gateway_rx(t38_gateway_state_t *s, int16_t amp[], i
#endif #endif
update_rx_timing(s, len); update_rx_timing(s, len);
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
amp[i] = dc_restore(&(s->audio.modems.dc_restore), amp[i]); amp[i] = dc_restore(&s->audio.modems.dc_restore, amp[i]);
/*endfor*/ /*endfor*/
s->audio.modems.rx_handler(s->audio.modems.rx_user_data, amp, len); s->audio.modems.rx_handler(s->audio.modems.rx_user_data, amp, len);
return 0; return 0;
@ -2263,7 +2254,7 @@ SPAN_DECLARE_NONSTD(int) t38_gateway_rx_fillin(t38_gateway_state_t *s, int len)
#endif #endif
update_rx_timing(s, len); update_rx_timing(s, len);
/* TODO: handle the modems properly */ /* TODO: handle the modems properly */
s->audio.modems.rx_fillin_handler(s->audio.modems.rx_user_data, len); s->audio.modems.rx_fillin_handler(s->audio.modems.rx_fillin_user_data, len);
return 0; return 0;
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
@ -2284,7 +2275,7 @@ SPAN_DECLARE_NONSTD(int) t38_gateway_tx(t38_gateway_state_t *s, int16_t amp[], i
len += s->audio.modems.tx_handler(s->audio.modems.tx_user_data, amp + len, max_len - len); len += s->audio.modems.tx_handler(s->audio.modems.tx_user_data, amp + len, max_len - len);
if (len < max_len) if (len < max_len)
{ {
silence_gen_set(&(s->audio.modems.silence_gen), 0); silence_gen_set(&s->audio.modems.silence_gen, 0);
set_next_tx_type(s); set_next_tx_type(s);
} }
/*endif*/ /*endif*/