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
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 --------------------------------------------------------*/
@ -142,7 +142,6 @@ static void tone_detected(void *user_data, int tone, int level, int delay)
}
/*- End of function --------------------------------------------------------*/
#if 0
static void v8_handler(void *user_data, v8_parms_t *result)
{
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");
}
/*- End of function --------------------------------------------------------*/
#endif
static void hdlc_underflow_handler(void *user_data)
{
@ -162,31 +160,6 @@ static void hdlc_underflow_handler(void *user_data)
}
/*- 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)
{
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;
s = &t->modems;
v17_rx(&s->fast_modems.v17_rx, amp, len);
fsk_rx(&s->v21_rx, amp, len);
if (t->t30.rx_trained)
{
/* 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));
set_rx_handler(t, (span_rx_handler_t) &v17_rx, (span_rx_fillin_handler_t) &v17_rx_fillin, &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));
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);
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(&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);
}
/* 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));
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;
}
/*- 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;
s = &t->modems;
v27ter_rx(&s->fast_modems.v27ter_rx, amp, len);
fsk_rx(&s->v21_rx, amp, len);
if (t->t30.rx_trained)
{
/* 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));
set_rx_handler(t, (span_rx_handler_t) &v27ter_rx, (span_rx_fillin_handler_t) &v27ter_rx_fillin, &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));
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);
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));
set_rx_handler(t, (span_rx_handler_t) &fsk_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(&s->logging, SPAN_LOG_FLOW, "Switching from V.27ter + 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);
}
/*endif*/
return 0;
}
/*- 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;
s = &t->modems;
v29_rx(&s->fast_modems.v29_rx, amp, len);
fsk_rx(&s->v21_rx, amp, len);
if (t->t30.rx_trained)
{
/* 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));
set_rx_handler(t, (span_rx_handler_t) &v29_rx, (span_rx_fillin_handler_t) &v29_rx_fillin, &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));
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);
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(&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);
}
/* 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));
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;
}
/*- End of function --------------------------------------------------------*/
@ -351,7 +315,7 @@ SPAN_DECLARE_NONSTD(int) fax_rx_fillin(fax_state_t *s, int len)
}
#endif
/* 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);
return 0;
}
@ -364,14 +328,14 @@ static int set_next_tx_type(fax_state_t *s)
t = &s->modems;
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;
return 0;
}
/* If there is nothing else to change to, so use zero length silence */
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_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
t->transmit = FALSE;
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:
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);
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;
case T30_MODEM_V27TER:
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);
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;
case T30_MODEM_V29:
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);
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;
case T30_MODEM_V17:
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);
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;
case T30_MODEM_DONE:
span_log(&s->logging, SPAN_LOG_FLOW, "FAX exchange complete\n");
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;
}
}
@ -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:
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_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
t->transmit = TRUE;
break;
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
tone = MODEM_CONNECT_TONES_FAX_CNG;
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_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);
t->transmit = TRUE;
break;
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 call, and ensures the receiving end is ready. */
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_next_tx_handler(s, (span_tx_handler_t) &fsk_tx, &t->v21_tx);
fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
fax_modems_set_next_tx_handler(t, (span_tx_handler_t) &fsk_tx, &t->v21_tx);
t->transmit = TRUE;
break;
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));
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);
fax_modems_set_tx_handler(s, (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_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
fax_modems_set_next_tx_handler(t, (span_tx_handler_t) &v17_tx, &t->fast_modems.v17_tx);
t->transmit = TRUE;
break;
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));
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);
fax_modems_set_tx_handler(s, (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_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
fax_modems_set_next_tx_handler(t, (span_tx_handler_t) &v27ter_tx, &t->fast_modems.v27ter_tx);
t->transmit = TRUE;
break;
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));
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);
fax_modems_set_tx_handler(s, (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_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
fax_modems_set_next_tx_handler(t, (span_tx_handler_t) &v29_tx, &t->fast_modems.v29_tx);
t->transmit = TRUE;
break;
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 */
default:
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_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
t->transmit = FALSE;
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)
{
s->modems.use_tep = use_tep;
fax_modems_set_tep_mode(&s->modems, use_tep);
}
/*- 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)
{
#if 0
v8_parms_t v8_parms;
#endif
fax_modems_restart(&s->modems);
#if 0
v8_parms.modem_connect_tone = MODEM_CONNECT_TONES_ANSAM_PR;
v8_parms.call_function = V8_CALL_T30_RX;
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.t66 = -1;
v8_restart(&s->v8, calling_party, &v8_parms);
#endif
t30_restart(&s->t30);
#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)
{
#if 0
v8_parms_t v8_parms;
#endif
if (s == NULL)
{
@ -695,10 +653,9 @@ SPAN_DECLARE(fax_state_t *) fax_init(fax_state_t *s, int calling_party)
(void *) s,
fax_set_tx_type,
(void *) s,
fax_send_hdlc,
(void *) s);
fax_modems_hdlc_tx_frame,
(void *) &s->modems);
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.call_function = V8_CALL_T30_RX;
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.t66 = -1;
v8_init(&s->v8, calling_party, &v8_parms, v8_handler, s);
#endif
fax_restart(s, calling_party);
return s;
}

View File

@ -86,6 +86,40 @@
#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)
{
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 */
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;
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;
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;
@ -118,6 +149,24 @@ SPAN_DECLARE_NONSTD(int) fax_modems_v17_v21_rx_fillin(void *user_data, int len)
}
/*- 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)
{
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 */
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;
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;
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;
@ -150,6 +196,24 @@ SPAN_DECLARE_NONSTD(int) fax_modems_v27ter_v21_rx_fillin(void *user_data, int le
}
/*- 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)
{
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 */
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;
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;
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;
@ -192,60 +253,136 @@ static void v21_rx_status_handler(void *user_data, int status)
}
/*- 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;
s = (fax_modems_state_t *) user_data;
switch (status)
switch (which)
{
case SIG_STATUS_TRAINING_SUCCEEDED:
span_log(&s->logging, SPAN_LOG_FLOW, "Switching to V.17 (%.2fdBm0)\n", v17_rx_signal_power(&s->fast_modems.v17_rx));
s->rx_handler = (span_rx_handler_t) &v17_rx;
s->rx_fillin_handler = (span_rx_fillin_handler_t) &v17_rx_fillin;
s->rx_user_data = &s->fast_modems.v17_rx;
s->rx_fillin_user_data = &s->fast_modems.v17_rx;
case FAX_MODEM_V21_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);
s->rx_frame_received = FALSE;
break;
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;
}
/*endswitch*/
}
/*- 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;
switch (status)
s->bit_rate = bit_rate;
if (hdlc_mode)
{
case SIG_STATUS_TRAINING_SUCCEEDED:
span_log(&s->logging, SPAN_LOG_FLOW, "Switching to V.27ter (%.2fdBm0)\n", v27ter_rx_signal_power(&s->fast_modems.v27ter_rx));
s->rx_handler = (span_rx_handler_t) &v27ter_rx;
s->rx_fillin_handler = (span_rx_fillin_handler_t) &v27ter_rx_fillin;
s->rx_user_data = &s->fast_modems.v27ter_rx;
s->rx_fillin_user_data = &s->fast_modems.v27ter_rx;
break;
get_bit = (get_bit_func_t) hdlc_tx_get_bit;
get_bit_user_data = (void *) &s->hdlc_tx;
put_bit = (put_bit_func_t) hdlc_rx_put_bit;
put_bit_user_data = (void *) &s->hdlc_rx;
}
/*endswitch*/
}
/*- 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)
else
{
case SIG_STATUS_TRAINING_SUCCEEDED:
span_log(&s->logging, SPAN_LOG_FLOW, "Switching to V.29 (%.2fdBm0)\n", v29_rx_signal_power(&s->fast_modems.v29_rx));
s->rx_handler = (span_rx_handler_t) &v29_rx;
s->rx_fillin_handler = (span_rx_fillin_handler_t) &v29_rx_fillin;
s->rx_user_data = &s->fast_modems.v29_rx;
s->rx_fillin_user_data = &s->fast_modems.v29_rx;
break;
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;
}
/*endswitch*/
/*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;
}
/*endswitch*/
}
else
{
s->short_train = short_train;
switch (s->fast_modem)
{
case FAX_MODEM_V27TER_RX:
v27ter_rx_restart(&s->fast_modems.v27ter_rx, s->bit_rate, FALSE);
v27ter_rx_set_put_bit(&s->fast_modems.v27ter_rx, 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_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;
}
/*endswitch*/
}
/*endif*/
}
/*- End of function --------------------------------------------------------*/
@ -268,6 +405,42 @@ SPAN_DECLARE(void) fax_modems_start_rx_modem(fax_modems_state_t *s, int which)
}
/*- 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)
{
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));
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_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_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);
@ -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_tx_init(&s->fast_modems.v27ter_tx, 4800, s->use_tep, non_ecm_get_bit, user_data);
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_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_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_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_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);
/*! 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 */
dc_restore_state_t dc_restore;
/*! \brief The fast modem type currently in use */
int fast_modem;
/*! \brief The currently selected receiver type */
int current_rx_type;
/*! \brief The currently selected transmitter 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. */
int rx_signal_present;
/*! \brief TRUE if a modem has trained correctly. */
@ -96,9 +115,9 @@ struct fax_modems_state_s
/*! \brief The current receive signal handler */
span_rx_handler_t rx_handler;
void *rx_user_data;
/*! \brief The current receive missing signal fill-in handler */
span_rx_fillin_handler_t rx_fillin_handler;
void *rx_user_data;
void *rx_fillin_user_data;
/*! \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 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_fillin(void *user_data, 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;
case SIG_STATUS_TRAINING_FAILED:
s->at_state.rx_trained = FALSE;
s->audio.modems.rx_trained = FALSE;
break;
case SIG_STATUS_TRAINING_SUCCEEDED:
/* The modem is now trained */
at_put_response_code(&s->at_state, AT_RESPONSE_CODE_CONNECT);
s->at_state.rx_signal_present = TRUE;
s->at_state.rx_trained = TRUE;
s->audio.modems.rx_trained = TRUE;
break;
case SIG_STATUS_CARRIER_UP:
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_trained = FALSE;
s->audio.modems.rx_trained = FALSE;
break;
default:
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 --------------------------------------------------------*/
#if 0
static void v8_handler(void *user_data, v8_parms_t *result)
{
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");
}
/*- End of function --------------------------------------------------------*/
#endif
static void hdlc_tx_underflow(void *user_data)
{
@ -1435,17 +1433,20 @@ static void hdlc_rx_status(void *user_data, int status)
break;
case SIG_STATUS_TRAINING_FAILED:
s->at_state.rx_trained = FALSE;
s->audio.modems.rx_trained = FALSE;
break;
case SIG_STATUS_TRAINING_SUCCEEDED:
/* The modem is now trained */
s->at_state.rx_signal_present = TRUE;
s->at_state.rx_trained = TRUE;
s->audio.modems.rx_trained = TRUE;
break;
case SIG_STATUS_CARRIER_UP:
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->rx_frame_received = FALSE;
s->audio.modems.rx_frame_received = FALSE;
}
break;
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_trained = FALSE;
s->audio.modems.rx_trained = FALSE;
break;
case SIG_STATUS_FRAMING_OK:
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->rx_frame_received = TRUE;
s->audio.modems.rx_frame_received = TRUE;
s->modem = FAX_MODEM_V21_RX;
s->at_state.transmit = FALSE;
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;
t31_set_at_rx_mode(s, AT_MODE_OFFHOOK_COMMAND);
s->rx_frame_received = FALSE;
s->audio.modems.rx_frame_received = FALSE;
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. */
at_put_response_code(&s->at_state, AT_RESPONSE_CODE_CONNECT);
s->rx_frame_received = TRUE;
s->audio.modems.rx_frame_received = TRUE;
}
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. */
at_put_response_code(&s->at_state, AT_RESPONSE_CODE_CONNECT);
s->rx_frame_received = TRUE;
s->audio.modems.rx_frame_received = TRUE;
}
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);
s->at_state.dte_is_waiting = FALSE;
s->rx_frame_received = FALSE;
s->audio.modems.rx_frame_received = FALSE;
}
}
else
@ -1632,8 +1639,10 @@ static int restart_modem(t31_state_t *s, int new_modem)
s->tx.final = FALSE;
s->at_state.rx_signal_present = FALSE;
s->at_state.rx_trained = FALSE;
s->audio.modems.rx_trained = 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;
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
first message at any time. The CNG tone will continue until
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);
set_tx_handler(s, (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_rx_handler(t, (span_rx_handler_t) &cng_rx, s, (span_rx_fillin_handler_t) &span_dummy_rx_fillin, 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;
break;
@ -1665,10 +1674,10 @@ static int restart_modem(t31_state_t *s, int new_modem)
}
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);
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);
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;
break;
@ -1682,8 +1691,8 @@ static int restart_modem(t31_state_t *s, int new_modem)
else
{
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);
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;
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. */
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);
set_tx_handler(s, (span_tx_handler_t) &fsk_tx, &t->v21_tx);
set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
fax_modems_set_tx_handler(t, (span_tx_handler_t) &fsk_tx, &t->v21_tx);
fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
}
s->hdlc_tx.final = FALSE;
s->hdlc_tx.len = 0;
@ -1716,8 +1725,8 @@ static int restart_modem(t31_state_t *s, int new_modem)
}
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);
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;
case FAX_MODEM_V17_TX:
@ -1748,8 +1757,8 @@ static int restart_modem(t31_state_t *s, int new_modem)
else
{
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);
set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
fax_modems_set_tx_handler(t, (span_tx_handler_t) &v17_tx, &t->fast_modems.v17_tx);
fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
}
s->tx.out_bytes = 0;
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:
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);
/* Allow for +FCERROR/+FRH:3 */
t31_v21_rx(s);
@ -1785,8 +1794,8 @@ static int restart_modem(t31_state_t *s, int new_modem)
else
{
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);
set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
fax_modems_set_tx_handler(t, (span_tx_handler_t) &v27ter_tx, &t->fast_modems.v27ter_tx);
fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
}
s->tx.out_bytes = 0;
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:
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);
/* Allow for +FCERROR/+FRH:3 */
t31_v21_rx(s);
@ -1822,8 +1831,8 @@ static int restart_modem(t31_state_t *s, int new_modem)
else
{
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);
set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
fax_modems_set_tx_handler(t, (span_tx_handler_t) &v29_tx, &t->fast_modems.v29_tx);
fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
}
s->tx.out_bytes = 0;
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:
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);
/* Allow for +FCERROR/+FRH:3 */
t31_v21_rx(s);
@ -1853,18 +1862,18 @@ static int restart_modem(t31_state_t *s, int new_modem)
else
{
silence_gen_set(&t->silence_gen, 0);
set_tx_handler(s, (span_tx_handler_t) &silence_gen, &t->silence_gen);
set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
}
s->at_state.transmit = FALSE;
break;
case FAX_MODEM_SILENCE_RX:
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);
set_tx_handler(s, (span_tx_handler_t) &silence_gen, &t->silence_gen);
set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
}
s->at_state.transmit = FALSE;
break;
@ -1881,8 +1890,8 @@ static int restart_modem(t31_state_t *s, int new_modem)
{
s->modem = FAX_MODEM_SILENCE_TX;
silence_gen_alter(&t->silence_gen, ms_to_samples(200));
set_tx_handler(s, (span_tx_handler_t) &silence_gen, &t->silence_gen);
set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
s->at_state.transmit = TRUE;
}
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. */
t31_set_at_rx_mode(s, AT_MODE_DELIVERY);
s->rx_frame_received = FALSE;
s->audio.modems.rx_frame_received = FALSE;
do
{
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.transmit = FALSE;
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);
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 --------------------------------------------------------*/
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)
{
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
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));
set_rx_handler(t, (span_rx_handler_t) &v17_rx, (span_rx_fillin_handler_t) &v17_rx_fillin, &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));
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
{
@ -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
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);
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);
}
}
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
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));
set_rx_handler(t, (span_rx_handler_t) &v27ter_rx, (span_rx_fillin_handler_t) &v27ter_rx_fillin, &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));
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
{
@ -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
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));
set_rx_handler(t, (span_rx_handler_t) &fsk_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &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));
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;
@ -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
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));
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
{
@ -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
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);
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);
}
}
return len;
@ -2535,14 +2520,14 @@ static int set_next_tx_type(t31_state_t *s)
{
if (s->audio.next_tx_handler)
{
set_tx_handler(s, 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_tx_handler(&s->audio.modems, s->audio.next_tx_handler, s->audio.next_tx_user_data);
fax_modems_set_next_tx_handler(&s->audio.modems, (span_tx_handler_t) NULL, NULL);
return 0;
}
/* There is nothing else to change to, so use zero length silence */
silence_gen_alter(&s->audio.modems.silence_gen, 0);
set_tx_handler(s, (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_tx_handler(&s->audio.modems, (span_tx_handler_t) &silence_gen, &s->audio.modems.silence_gen);
fax_modems_set_next_tx_handler(&s->audio.modems, (span_tx_handler_t) NULL, NULL);
return -1;
}
/*- 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,
void *tx_t38_packet_user_data)
{
#if 0
v8_parms_t v8_parms;
#endif
int alloced;
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,
tone_detected,
(void *) s);
#if 0
v8_parms.modem_connect_tone = MODEM_CONNECT_TONES_ANSAM_PR;
v8_parms.call_function = V8_CALL_T30_RX;
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_init(&s->audio.v8, FALSE, &v8_parms, v8_handler, s);
#endif
power_meter_init(&s->audio.rx_power, 4);
s->audio.last_sample = 0;
s->audio.silence_threshold_power = power_meter_level_dbm0(-36);
s->at_state.rx_signal_present = FALSE;
s->at_state.rx_trained = FALSE;
s->audio.modems.rx_trained = FALSE;
s->at_state.do_hangup = FALSE;
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 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)
{
@ -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_fillin_handler = fillin_handler;
s->audio.modems.rx_user_data = user_data;
s->audio.modems.rx_fillin_user_data = rx_fillin_user_data;
}
/*- 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
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));
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
{
@ -265,7 +270,7 @@ static int v17_v21_rx(void *user_data, const int16_t amp[], int len)
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));
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*/
}
@ -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
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));
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
{
@ -308,7 +313,7 @@ static int v27ter_v21_rx(void *user_data, const int16_t amp[], int len)
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));
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*/
}
@ -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
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));
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
{
@ -351,7 +356,7 @@ static int v29_v21_rx(void *user_data, const int16_t amp[], int len)
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));
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*/
}
@ -422,6 +427,7 @@ static int set_next_tx_type(t38_gateway_state_t *s)
int short_train;
fax_modems_state_t *t;
t38_gateway_hdlc_state_t *u;
int bit_rate;
t = &s->audio.modems;
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;
case T38_IND_V27TER_2400_TRAINING:
case T38_IND_V27TER_4800_TRAINING:
switch (indicator)
{
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*/
bit_rate =
t->tx_bit_rate = (indicator == T38_IND_V27TER_4800_TRAINING) ? 4800 : 2400;
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_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;
case T38_IND_V29_7200_TRAINING:
case T38_IND_V29_9600_TRAINING:
switch (indicator)
{
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*/
bit_rate =
t->tx_bit_rate = (indicator == T38_IND_V29_9600_TRAINING) ? 9600 : 7200;
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_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:
short_train = TRUE;
t->tx_bit_rate = 7200;
bit_rate = 7200;
break;
case T38_IND_V17_7200_LONG_TRAINING:
t->tx_bit_rate = 7200;
bit_rate = 7200;
break;
case T38_IND_V17_9600_SHORT_TRAINING:
short_train = TRUE;
t->tx_bit_rate = 9600;
bit_rate = 9600;
break;
case T38_IND_V17_9600_LONG_TRAINING:
t->tx_bit_rate = 9600;
bit_rate = 9600;
break;
case T38_IND_V17_12000_SHORT_TRAINING:
short_train = TRUE;
t->tx_bit_rate = 12000;
bit_rate = 12000;
break;
case T38_IND_V17_12000_LONG_TRAINING:
t->tx_bit_rate = 12000;
bit_rate = 12000;
break;
case T38_IND_V17_14400_SHORT_TRAINING:
short_train = TRUE;
t->tx_bit_rate = 14400;
bit_rate = 14400;
break;
case T38_IND_V17_14400_LONG_TRAINING:
t->tx_bit_rate = 14400;
bit_rate = 14400;
break;
}
/*endswitch*/
t->tx_bit_rate = bit_rate;
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_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_FLOW,
"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(indicator));
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_FLOW,
"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(indicator));
}
@ -2159,23 +2150,23 @@ static int restart_rx_modem(t38_gateway_state_t *s)
case FAX_MODEM_V27TER_RX:
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);
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;
break;
case FAX_MODEM_V29_RX:
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);
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;
break;
case FAX_MODEM_V17_RX:
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);
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;
break;
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;
break;
}
@ -2233,7 +2224,7 @@ SPAN_DECLARE_NONSTD(int) t38_gateway_rx(t38_gateway_state_t *s, int16_t amp[], i
#endif
update_rx_timing(s, len);
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*/
s->audio.modems.rx_handler(s->audio.modems.rx_user_data, amp, len);
return 0;
@ -2263,7 +2254,7 @@ SPAN_DECLARE_NONSTD(int) t38_gateway_rx_fillin(t38_gateway_state_t *s, int len)
#endif
update_rx_timing(s, len);
/* 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;
}
/*- 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);
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);
}
/*endif*/