SPAN_DECLARE(void) fax_modems_start_slow_modem(fax_modems_state_t *s, int which) { switch (which) { 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); 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); fsk_rx_signal_cutoff(&s->v21_rx, -39.09f); s->rx_frame_received = false; break; case FAX_MODEM_CED_TONE_RX: modem_connect_tones_rx_init(&s->connect_rx, MODEM_CONNECT_TONES_FAX_CED, s->tone_callback, s->tone_callback_user_data); fax_modems_set_rx_handler(s, (span_rx_handler_t) &modem_connect_tones_rx, &s->connect_rx, (span_rx_fillin_handler_t) &modem_connect_tones_rx_fillin, &s->connect_rx); break; case FAX_MODEM_CNG_TONE_RX: modem_connect_tones_rx_init(&s->connect_rx, MODEM_CONNECT_TONES_FAX_CNG, s->tone_callback, s->tone_callback_user_data); fax_modems_set_rx_handler(s, (span_rx_handler_t) &modem_connect_tones_rx, &s->connect_rx, (span_rx_fillin_handler_t) &modem_connect_tones_rx_fillin, &s->connect_rx); 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); fax_modems_set_tx_handler(s, (span_tx_handler_t) &fsk_tx, &s->v21_tx); fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL); break; case FAX_MODEM_CED_TONE_TX: modem_connect_tones_tx_init(&s->connect_tx, MODEM_CONNECT_TONES_FAX_CED); fax_modems_set_tx_handler(s, (span_tx_handler_t) &modem_connect_tones_tx, &s->connect_tx); fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL); break; case FAX_MODEM_CNG_TONE_TX: modem_connect_tones_tx_init(&s->connect_tx, MODEM_CONNECT_TONES_FAX_CNG); fax_modems_set_tx_handler(s, (span_tx_handler_t) &modem_connect_tones_tx, &s->connect_tx); fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL); break; } }
static void fax_set_rx_type(void *user_data, int type, int bit_rate, int short_train, int use_hdlc) { fax_state_t *s; fax_modems_state_t *t; s = (fax_state_t *) user_data; t = &s->modems; span_log(&s->logging, SPAN_LOG_FLOW, "Set rx type %d\n", type); if (t->current_rx_type == type) return; t->current_rx_type = type; t->rx_bit_rate = bit_rate; hdlc_rx_init(&t->hdlc_rx, false, true, HDLC_FRAMING_OK_THRESHOLD, fax_modems_hdlc_accept, t); switch (type) { case T30_MODEM_V21: fax_modems_start_slow_modem(t, FAX_MODEM_V21_RX); break; case T30_MODEM_V17: fax_modems_start_fast_modem(t, FAX_MODEM_V17_RX, bit_rate, short_train, use_hdlc); break; case T30_MODEM_V27TER: fax_modems_start_fast_modem(t, FAX_MODEM_V27TER_RX, bit_rate, short_train, use_hdlc); break; case T30_MODEM_V29: fax_modems_start_fast_modem(t, FAX_MODEM_V29_RX, bit_rate, short_train, use_hdlc); break; case T30_MODEM_DONE: span_log(&s->logging, SPAN_LOG_FLOW, "FAX exchange complete\n"); default: 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; } }
SPAN_DECLARE_NONSTD(int) fax_modems_v29_v21_rx(void *user_data, const int16_t amp[], int len) { fax_modems_state_t *s; s = (fax_modems_state_t *) user_data; v29_rx(&s->fast_modems.v29_rx, amp, len); fsk_rx(&s->v21_rx, amp, len); if (s->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.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; }
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); break; } /*endswitch*/ s->fast_modems.v29_rx.put_bit(s->fast_modems.v29_rx.put_bit_user_data, 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) { put_bit_func_t put_bit; get_bit_func_t get_bit; void *get_bit_user_data; void *put_bit_user_data; s->bit_rate = bit_rate; if (hdlc_mode) { 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; } 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; } /*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*/ }