Logo Search packages:      
Sourcecode: iaxmodem version File versions  Download package

void t30_send_complete ( void *  user_data  ) 

Inform the T.30 engine the current transmission has completed.

Inform the T.30 engine the current transmission has completed.

Parameters:
s The T.30 context.

Definition at line 3335 of file t30.c.

References t30_state_s::current_status, t30_state_s::dcs_frame, t30_state_s::dcs_len, t30_state_s::dis_dtc_frame, t30_state_s::dis_dtc_len, t30_state_s::dis_received, t30_state_s::error_correcting_mode, t30_state_s::iaf, t30_state_s::logging, t30_state_s::next_rx_step, t30_state_s::next_tx_step, t30_state_s::phase, t30_state_s::phase_e_handler, t30_state_s::phase_e_user_data, t30_state_s::retries, t30_state_s::send_hdlc_handler, t30_state_s::send_hdlc_user_data, t30_state_s::short_train, span_log(), t30_state_s::state, t30_state_s::step, T30_EOM, T30_IAF_MODE_NO_TCF, T30_NULL, t30_state_s::timer_is_t4, and t30_state_s::timer_t2_t4.

Referenced by fax_init(), and fax_tx().

{
    t30_state_t *s;
    
    s = (t30_state_t *) user_data;

    span_log(&s->logging, SPAN_LOG_FLOW, "Send complete in phase %s, state %d\n", phase_names[s->phase], s->state);
    /* We have finished sending our messages, so move on to the next operation. */
    switch (s->state)
    {
    case T30_STATE_ANSWERING:
        span_log(&s->logging, SPAN_LOG_FLOW, "Starting answer mode\n");
        set_phase(s, T30_PHASE_B_TX);
        s->timer_t2_t4 = ms_to_samples(DEFAULT_TIMER_T2);
        s->timer_is_t4 = FALSE;
        set_state(s, T30_STATE_R);
        s->dis_received = FALSE;
        send_dis_or_dtc_sequence(s);
        break;
    case T30_STATE_R:
        switch (s->step)
        {
        case 0:
            s->step++;
            if (send_ident_frame(s, T30_CSI))
                break;
            /* Fall through */
        case 1:
            s->step++;
            set_dis_or_dtc(s);
            send_frame(s, s->dis_dtc_frame, s->dis_dtc_len);
            break;
        case 2:
            s->step++;
            if (s->send_hdlc_handler)
                s->send_hdlc_handler(s->send_hdlc_user_data, NULL, 0);
            break;        
        default:
            /* Wait for an acknowledgement. */
            set_phase(s, T30_PHASE_B_RX);
            s->timer_t2_t4 = ms_to_samples(DEFAULT_TIMER_T4);
            s->timer_is_t4 = TRUE;
            break;
        }
        break;
    case T30_STATE_F_CFR:
        if (s->step == 0)
        {
            if (s->send_hdlc_handler)
                s->send_hdlc_handler(s->send_hdlc_user_data, NULL, 0);
            s->step++;
        }
        else
        {
            set_state(s, T30_STATE_F_DOC);
            set_phase(s, (s->error_correcting_mode)  ?  T30_PHASE_C_ECM_RX  : T30_PHASE_C_NON_ECM_RX);
            s->next_rx_step = T30_MPS;
        }
        break;
    case T30_STATE_F_FTT:
        if (s->step == 0)
        {
            if (s->send_hdlc_handler)
                s->send_hdlc_handler(s->send_hdlc_user_data, NULL, 0);
            s->step++;
        }
        else
        {
            set_phase(s, T30_PHASE_B_RX);
            s->timer_t2_t4 = ms_to_samples(DEFAULT_TIMER_T4);
            s->timer_is_t4 = TRUE;
        }
        break;
    case T30_STATE_III_Q_MCF:
    case T30_STATE_III_Q_RTP:
    case T30_STATE_III_Q_RTN:
    case T30_STATE_F_POST_RCP_PPR:
    case T30_STATE_F_POST_RCP_MCF:
        if (s->step == 0)
        {
            if (s->send_hdlc_handler)
                s->send_hdlc_handler(s->send_hdlc_user_data, NULL, 0);
            s->step++;
        }
        else
        {
            switch (s->next_rx_step)
            {
            case T30_MPS:
            case T30_PRI_MPS:
                set_state(s, T30_STATE_F_DOC);
                set_phase(s, (s->error_correcting_mode)  ?  T30_PHASE_C_ECM_RX  : T30_PHASE_C_NON_ECM_RX);
                break;
            case T30_EOM:
            case T30_PRI_EOM:
                /* TODO: */
                disconnect(s);
                break;
            case T30_EOP:
            case T30_PRI_EOP:
                disconnect(s);
                break;
            default:
                span_log(&s->logging, SPAN_LOG_FLOW, "Unknown next rx step - %d\n", s->next_rx_step);
                disconnect(s);
                break;
            }
        }
        break;
    case T30_STATE_II_Q:
    case T30_STATE_IV_PPS_NULL:
    case T30_STATE_IV_PPS_Q:
        if (s->step == 0)
        {
            if (s->send_hdlc_handler)
                s->send_hdlc_handler(s->send_hdlc_user_data, NULL, 0);
            s->step++;
        }
        else
        {
            /* We have finished sending the post image message. Wait for an
               acknowledgement. */
            set_phase(s, T30_PHASE_D_RX);
            s->timer_t2_t4 = ms_to_samples(DEFAULT_TIMER_T4);
            s->timer_is_t4 = TRUE;
        }
        break;
    case T30_STATE_B:
        /* We have now allowed time for the last message to flush
           through the system, so it is safe to report the end of the
           call. */
        if (s->phase_e_handler)
            s->phase_e_handler(s, s->phase_e_user_data, s->current_status);
        set_state(s, T30_STATE_CALL_FINISHED);
        set_phase(s, T30_PHASE_CALL_FINISHED);
        break;
    case T30_STATE_C:
        if (s->step == 0)
        {
            if (s->send_hdlc_handler)
                s->send_hdlc_handler(s->send_hdlc_user_data, NULL, 0);
            s->step++;
        }
        else
        {
            /* We just sent the disconnect message. Now it is time to disconnect */
            disconnect(s);
        }
        break;
    case T30_STATE_D:
        switch (s->step)
        {
        case 0:
            s->step++;
            if (send_sub_frame(s))
                break;
            /* Fall through */
        case 1:
            s->step++;
            if (send_ident_frame(s, T30_TSI))
                break;
            /* Fall through */
        case 2:
            s->step++;
            send_frame(s, s->dcs_frame, s->dcs_len);
            break;
        case 3:
            s->step++;
            if (s->send_hdlc_handler)
                s->send_hdlc_handler(s->send_hdlc_user_data, NULL, 0);
            break;        
        default:
            if ((s->iaf & T30_IAF_MODE_NO_TCF))
            {
                /* Skip the trainability test */
                s->retries = 0;
                s->short_train = TRUE;
                if (s->error_correcting_mode)
                {
                    set_state(s, T30_STATE_IV);
                    queue_phase(s, T30_PHASE_C_ECM_TX);
                }
                else
                {
                    set_state(s, T30_STATE_I);
                    queue_phase(s, T30_PHASE_C_NON_ECM_TX);
                }
            }
            else
            {
                /* Do the trainability test */
                set_state(s, T30_STATE_D_TCF);
                set_phase(s, T30_PHASE_C_NON_ECM_TX);
            }
            break;
        }
        break;
    case T30_STATE_D_TCF:
        /* Finished sending training test. Listen for the response. */
        set_phase(s, T30_PHASE_B_RX);
        s->timer_t2_t4 = ms_to_samples(DEFAULT_TIMER_T4);
        s->timer_is_t4 = TRUE;
        set_state(s, T30_STATE_D_POST_TCF);
        break;
    case T30_STATE_I:
        /* Send the end of page message */
        set_phase(s, T30_PHASE_D_TX);
        set_state(s, T30_STATE_II_Q);
        /* We might need to resend the page we are on, but we need to check if there
           are any more pages to send, so we can send the correct signal right now. */
        send_simple_frame(s, s->next_tx_step = check_next_tx_step(s));
        break;
    case T30_STATE_IV:
        /* We have finished sending an FCD frame */
        if (s->step == 0)
        {
            if (send_next_ecm_frame(s))
            {
                if (s->send_hdlc_handler)
                    s->send_hdlc_handler(s->send_hdlc_user_data, NULL, 0);
                s->step++;
            }
        }
        else
        {
            /* Send the end of page or partial page message */
            set_phase(s, T30_PHASE_D_TX);
            s->next_tx_step = check_next_tx_step(s);
            if (send_pps_frame(s) == T30_NULL)
                set_state(s, T30_STATE_IV_PPS_NULL);
            else
                set_state(s, T30_STATE_IV_PPS_Q);
        }
        break;
    case T30_STATE_CALL_FINISHED:
        /* Just ignore anything that happens now. We might get here if a premature
           disconnect from the far end overlaps something. */
        break;
    default:
        span_log(&s->logging, SPAN_LOG_FLOW, "Bad state in t30_send_complete - %d\n", s->state);
        break;
    }
}


Generated by  Doxygen 1.6.0   Back to index