Esempio n. 1
0
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;
    }
}
Esempio n. 2
0
SPAN_DECLARE(fax_modems_state_t *) fax_modems_init(fax_modems_state_t *s,
                                                   int use_tep,
                                                   hdlc_frame_handler_t hdlc_accept,
                                                   hdlc_underflow_handler_t hdlc_tx_underflow,
                                                   put_bit_func_t non_ecm_put_bit,
                                                   get_bit_func_t non_ecm_get_bit,
                                                   tone_report_func_t tone_callback,
                                                   void *user_data)
{
    if (s == NULL)
    {
        if ((s = (fax_modems_state_t *) span_alloc(sizeof(*s))) == NULL)
            return NULL;
    }
    /*endif*/
    memset(s, 0, sizeof(*s));
    s->use_tep = use_tep;

    modem_connect_tones_tx_init(&s->connect_tx, MODEM_CONNECT_TONES_FAX_CNG);
    span_log_init(&s->logging, SPAN_LOG_NONE, NULL);
    span_log_set_protocol(&s->logging, "FAX modems");

    s->tone_callback = tone_callback;
    s->tone_callback_user_data = user_data;
    if (tone_callback)
    {
        modem_connect_tones_rx_init(&s->connect_rx,
                                    MODEM_CONNECT_TONES_FAX_CNG,
                                    s->tone_callback,
                                    s->tone_callback_user_data);
    }
    /*endif*/
    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, fax_modems_hdlc_accept, s);
    hdlc_tx_init(&s->hdlc_tx, false, 2, false, hdlc_tx_underflow, user_data);

    fax_modems_start_slow_modem(s, FAX_MODEM_V21_RX);
    fsk_tx_init(&s->v21_tx, &preset_fsk_specs[FSK_V21CH2], (get_bit_func_t) hdlc_tx_get_bit, &s->hdlc_tx);

    silence_gen_init(&s->silence_gen, 0);

    s->rx_signal_present = false;
    s->rx_handler = (span_rx_handler_t) &span_dummy_rx;
    s->rx_fillin_handler = (span_rx_fillin_handler_t) &span_dummy_rx;
    s->rx_user_data = NULL;
    s->rx_fillin_user_data = NULL;
    s->tx_handler = (span_tx_handler_t) &silence_gen;
    s->tx_user_data = &s->silence_gen;
    return s;
}
Esempio n. 3
0
SPAN_DECLARE(fax_modems_state_t *) fax_modems_init(fax_modems_state_t *s,
                                                   int use_tep,
                                                   hdlc_frame_handler_t hdlc_accept,
                                                   hdlc_underflow_handler_t hdlc_tx_underflow,
                                                   put_bit_func_t non_ecm_put_bit,
                                                   get_bit_func_t non_ecm_get_bit,
                                                   tone_report_func_t tone_callback,
                                                   void *user_data)
{
    if (s == NULL)
    {
        if ((s = (fax_modems_state_t *) malloc(sizeof(*s))) == NULL)
            return NULL;
    }
    memset(s, 0, sizeof(*s));
    s->use_tep = use_tep;

    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], TRUE, (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);
    v17_rx_init(&s->v17_rx, 14400, non_ecm_put_bit, user_data);
    v17_tx_init(&s->v17_tx, 14400, s->use_tep, non_ecm_get_bit, user_data);
    v29_rx_init(&s->v29_rx, 9600, non_ecm_put_bit, user_data);
    v29_rx_signal_cutoff(&s->v29_rx, -45.5f);
    v29_tx_init(&s->v29_tx, 9600, s->use_tep, non_ecm_get_bit, user_data);
    v27ter_rx_init(&s->v27ter_rx, 4800, non_ecm_put_bit, user_data);
    v27ter_tx_init(&s->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);
    }
    dc_restore_init(&s->dc_restore);

    s->rx_signal_present = FALSE;
    s->rx_handler = (span_rx_handler_t *) &span_dummy_rx;
    s->rx_user_data = NULL;
    s->tx_handler = (span_tx_handler_t *) &silence_gen;
    s->tx_user_data = &s->silence_gen;
    return s;
}
Esempio n. 4
0
static void fax_set_tx_type(void *user_data, int type, int bit_rate, int short_train, int use_hdlc)
{
    fax_state_t *s;
    get_bit_func_t get_bit_func;
    void *get_bit_user_data;
    fax_modems_state_t *t;
    int tone;

    s = (fax_state_t *) user_data;
    t = &s->modems;
    span_log(&s->logging, SPAN_LOG_FLOW, "Set tx type %d\n", type);
    if (t->current_tx_type == type)
        return;
    if (use_hdlc)
    {
        get_bit_func = (get_bit_func_t) hdlc_tx_get_bit;
        get_bit_user_data = (void *) &t->hdlc_tx;
    }
    else
    {
        get_bit_func = t30_non_ecm_get_bit;
        get_bit_user_data = (void *) &s->t30;
    }
    switch (type)
    {
    case T30_MODEM_PAUSE:
        silence_gen_alter(&t->silence_gen, ms_to_samples(short_train));
        set_tx_handler(s, (span_tx_handler_t *) &silence_gen, &t->silence_gen);
        set_next_tx_handler(s, (span_tx_handler_t *) NULL, NULL);
        t->transmit = TRUE;
        break;
    case T30_MODEM_CED:
    case T30_MODEM_CNG:
        if (type == T30_MODEM_CED)
            tone = MODEM_CONNECT_TONES_FAX_CED;
        else
            tone = MODEM_CONNECT_TONES_FAX_CNG;
        modem_connect_tones_tx_init(&t->connect_tx, tone);
        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);
        t->transmit = TRUE;
        break;
    case T30_MODEM_V21:
        fsk_tx_init(&t->v21_tx, &preset_fsk_specs[FSK_V21CH2], get_bit_func, get_bit_user_data);
        /* The spec says 1s +-15% of preamble. So, the minimum is 32 octets. */
        hdlc_tx_flags(&t->hdlc_tx, 32);
        /* Pause before switching from phase C, as per T.30 5.3.2.2. If we omit this, the receiver
           might not see the carrier fall between the high speed and low speed sections. In practice,
           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));
        set_tx_handler(s, (span_tx_handler_t *) &silence_gen, &t->silence_gen);
        set_next_tx_handler(s, (span_tx_handler_t *) &fsk_tx, &t->v21_tx);
        t->transmit = TRUE;
        break;
    case T30_MODEM_V27TER:
        silence_gen_alter(&t->silence_gen, ms_to_samples(75));
        /* For any fast modem, set 200ms of preamble flags */
        hdlc_tx_flags(&t->hdlc_tx, bit_rate/(8*5));
        v27ter_tx_restart(&t->v27ter_tx, bit_rate, t->use_tep);
        v27ter_tx_set_get_bit(&t->v27ter_tx, get_bit_func, get_bit_user_data);
        set_tx_handler(s, (span_tx_handler_t *) &silence_gen, &t->silence_gen);
        set_next_tx_handler(s, (span_tx_handler_t *) &v27ter_tx, &t->v27ter_tx);
        t->transmit = TRUE;
        break;
    case T30_MODEM_V29:
        silence_gen_alter(&t->silence_gen, ms_to_samples(75));
        /* For any fast modem, set 200ms of preamble flags */
        hdlc_tx_flags(&t->hdlc_tx, bit_rate/(8*5));
        v29_tx_restart(&t->v29_tx, bit_rate, t->use_tep);
        v29_tx_set_get_bit(&t->v29_tx, get_bit_func, get_bit_user_data);
        set_tx_handler(s, (span_tx_handler_t *) &silence_gen, &t->silence_gen);
        set_next_tx_handler(s, (span_tx_handler_t *) &v29_tx, &t->v29_tx);
        t->transmit = TRUE;
        break;
    case T30_MODEM_V17:
        silence_gen_alter(&t->silence_gen, ms_to_samples(75));
        /* For any fast modem, set 200ms of preamble flags */
        hdlc_tx_flags(&t->hdlc_tx, bit_rate/(8*5));
        v17_tx_restart(&t->v17_tx, bit_rate, t->use_tep, short_train);
        v17_tx_set_get_bit(&t->v17_tx, get_bit_func, get_bit_user_data);
        set_tx_handler(s, (span_tx_handler_t *) &silence_gen, &t->silence_gen);
        set_next_tx_handler(s, (span_tx_handler_t *) &v17_tx, &t->v17_tx);
        t->transmit = TRUE;
        break;
    case T30_MODEM_DONE:
        span_log(&s->logging, SPAN_LOG_FLOW, "FAX exchange complete\n");
        /* Fall through */
    default:
        silence_gen_alter(&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);
        t->transmit = FALSE;
        break;
    }
    t->tx_bit_rate = bit_rate;
    t->current_tx_type = type;
}
Esempio n. 5
0
static int v8_calls_non_v8_tests(SNDFILE *outhandle)
{
    v8_state_t *v8_caller;
    modem_connect_tones_tx_state_t *non_v8_answerer_tx;
    logging_state_t *caller_logging;
    int caller_available_modulations;
    int i;
    int samples;
    int outframes;
    int16_t amp[SAMPLES_PER_CHUNK];
    int16_t out_amp[2*SAMPLES_PER_CHUNK];
    v8_parms_t v8_call_parms;

    caller_available_modulations = V8_MOD_V17
                                 | V8_MOD_V21
                                 | V8_MOD_V22
                                 | V8_MOD_V23HDX
                                 | V8_MOD_V23
                                 | V8_MOD_V26BIS
                                 | V8_MOD_V26TER
                                 | V8_MOD_V27TER
                                 | V8_MOD_V29
                                 | V8_MOD_V32
                                 | V8_MOD_V34HDX
                                 | V8_MOD_V34
                                 | V8_MOD_V90
                                 | V8_MOD_V92;
    negotiations_ok = 0;

    v8_call_parms.modem_connect_tone = MODEM_CONNECT_TONES_NONE;
    v8_call_parms.send_ci = true;
    v8_call_parms.v92 = -1;
    v8_call_parms.call_function = V8_CALL_V_SERIES;
    v8_call_parms.modulations = caller_available_modulations;
    v8_call_parms.protocol = V8_PROTOCOL_LAPM_V42;
    v8_call_parms.pcm_modem_availability = 0;
    v8_call_parms.pstn_access = 0;
    v8_call_parms.nsf = -1;
    v8_call_parms.t66 = -1;
    v8_caller = v8_init(NULL,
                        true,
                        &v8_call_parms,
                        handler,
                        (void *) "caller");
    non_v8_answerer_tx = modem_connect_tones_tx_init(NULL, MODEM_CONNECT_TONES_ANS_PR);
    caller_logging = v8_get_logging_state(v8_caller);
    span_log_set_level(caller_logging, SPAN_LOG_FLOW | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
    span_log_set_tag(caller_logging, "caller");
    for (i = 0;  i < 1000;  i++)
    {
        samples = v8_tx(v8_caller, amp, SAMPLES_PER_CHUNK);
        if (samples < SAMPLES_PER_CHUNK)
        {
            vec_zeroi16(amp + samples, SAMPLES_PER_CHUNK - samples);
            samples = SAMPLES_PER_CHUNK;
        }
        /*endif*/
        span_log_bump_samples(caller_logging, samples);
        for (i = 0;  i < samples;  i++)
            out_amp[2*i] = amp[i];
        /*endfor*/

        samples = modem_connect_tones_tx(non_v8_answerer_tx, amp, SAMPLES_PER_CHUNK);
        if (samples < SAMPLES_PER_CHUNK)
        {
            vec_zeroi16(amp + samples, SAMPLES_PER_CHUNK - samples);
            samples = SAMPLES_PER_CHUNK;
        }
        /*endif*/
        if (v8_rx(v8_caller, amp, samples))
            break;
        /*endif*/
        for (i = 0;  i < samples;  i++)
            out_amp[2*i + 1] = amp[i];
        /*endfor*/

        if (outhandle)
        {
            outframes = sf_writef_short(outhandle, out_amp, samples);
            if (outframes != samples)
            {
                fprintf(stderr, "    Error writing audio file\n");
                exit(2);
            }
            /*endif*/
        }
        /*endif*/
    }
    /*endfor*/
    v8_free(v8_caller);
    modem_connect_tones_tx_free(non_v8_answerer_tx);

    if (negotiations_ok != 42)
    {
        printf("Tests failed.\n");
        exit(2);
    }
    /*endif*/
    return 0;
}