Пример #1
0
static ftdm_status_t ftdm_gsm_state_advance(ftdm_channel_t *ftdmchan)
{

	ftdm_log_chan(ftdmchan, STATE_ADVANCE_LOG_LEVEL , "Executing state handler for %s\n", ftdm_channel_state2str(ftdmchan->state));
	
	ftdm_channel_complete_state(ftdmchan);

		switch (ftdmchan->state) {

		/* starting an incoming call */
		case FTDM_CHANNEL_STATE_COLLECT: 
			{
				
				
			}
			break;

			/* starting an outgoing call */
		case FTDM_CHANNEL_STATE_DIALING:
			{
				uint32_t interval = 0;
				
				ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Starting outgoing call with interval %d\n", interval);

				{

					ftdm_gsm_span_data_t *gsm_data;
					gsm_data = ftdmchan->span->signal_data;
					gsm_data->call_id = g_outbound_call_id++;				
					wat_con_event_t con_event;
					memset(&con_event, 0, sizeof(con_event));
					ftdm_set_string(con_event.called_num.digits, ftdmchan->caller_data.dnis.digits);
					ftdm_log(FTDM_LOG_DEBUG, "Dialing number %s\n", con_event.called_num.digits);
					wat_con_req(ftdmchan->span->span_id, gsm_data->call_id , &con_event);
 
					SEND_STATE_SIGNAL(FTDM_SIGEVENT_DIALING);
					
					
				}

				
			}
			break;

			/* incoming call was offered */
		case FTDM_CHANNEL_STATE_RING:

			/* notify the user about the new call */

			ftdm_log(FTDM_LOG_INFO, "Answering Incomming Call\r\n");
			SEND_STATE_SIGNAL(FTDM_SIGEVENT_START);
			
			break;

			/* the call is making progress */
		case FTDM_CHANNEL_STATE_PROGRESS:
		case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
			{
				SEND_STATE_SIGNAL(FTDM_SIGEVENT_PROGRESS_MEDIA);
				ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP);
			}
			break;

			/* the call was answered */
		case FTDM_CHANNEL_STATE_UP:
			{
				if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
				
					SEND_STATE_SIGNAL(FTDM_SIGEVENT_UP);
				}
				else {
						ftdm_gsm_span_data_t *gsm_data;
						gsm_data = ftdmchan->span->signal_data;
						wat_con_cfm(ftdmchan->span->span_id, gsm_data->call_id); 
				}
				
				
			}
			break;

			/* just got hangup */
		case FTDM_CHANNEL_STATE_HANGUP:
			{
				ftdm_gsm_span_data_t *gsm_data;
				gsm_data = ftdmchan->span->signal_data;
				wat_rel_req(ftdmchan->span->span_id, gsm_data->call_id);
				gsm_data->call_id = 0;
				SEND_STATE_SIGNAL(FTDM_SIGEVENT_STOP);
			}
			break;

		case FTDM_CHANNEL_STATE_TERMINATING:
			{
				SEND_STATE_SIGNAL(FTDM_SIGEVENT_STOP);
			}
			break;

			/* finished call for good */
		case FTDM_CHANNEL_STATE_DOWN: 
			{
				ftdm_channel_t *closed_chan;
				closed_chan = ftdmchan;
				ftdm_channel_close(&closed_chan);
				ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "State processing ended.\n");
				SEND_STATE_SIGNAL(FTDM_SIGEVENT_STOP);
			}
			break;

			/* INDICATE_RINGING doesn't apply to MFC/R2. maybe we could generate a tone */
		case FTDM_CHANNEL_STATE_RINGING: 
			ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "RINGING indicated, ignoring it as it doesn't apply to MFC/R2\n");
			SEND_STATE_SIGNAL(FTDM_SIGEVENT_RINGING);
				
			break;

			/* put the r2 channel back to IDLE, close ftdmchan and set it's state as DOWN */
		case FTDM_CHANNEL_STATE_RESET:
			{
				ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "RESET indicated, putting the R2 channel back to IDLE\n");
				ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
			}
			break;

		default:
			{
				ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Unhandled channel state change: %s\n", ftdm_channel_state2str(ftdmchan->state));
			}
			break;
	}

	
	return FTDM_SUCCESS;
}
Пример #2
0
static ftdm_status_t state_advance(ftdm_channel_t *ftdmchan)
{
    ftdm_status_t status;
    ftdm_sigmsg_t sig;
    pritap_t *pritap = ftdmchan->span->signal_data;
    pritap_t *peer_pritap = pritap->peerspan->signal_data;

    ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "processing state %s\n", ftdm_channel_state2str(ftdmchan->state));

    memset(&sig, 0, sizeof(sig));
    sig.chan_id = ftdmchan->chan_id;
    sig.span_id = ftdmchan->span_id;
    sig.channel = ftdmchan;

    ftdm_channel_complete_state(ftdmchan);

    switch (ftdmchan->state) {
    case FTDM_CHANNEL_STATE_DOWN:
    {
        ftdm_channel_t *fchan = ftdmchan;

        /* Destroy the peer data first */
        if (fchan->call_data) {
            ftdm_channel_t *peerchan = fchan->call_data;
            ftdm_channel_t *pchan = peerchan;

            ftdm_channel_lock(peerchan);

            pchan->call_data = NULL;
            pchan->pflags = 0;
            ftdm_channel_close(&pchan);

            ftdm_channel_unlock(peerchan);
        } else {
            ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "No call data?\n");
        }

        ftdmchan->call_data = NULL;
        ftdmchan->pflags = 0;
        ftdm_channel_close(&fchan);
    }
    break;

    case FTDM_CHANNEL_STATE_PROGRESS:
    case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
    case FTDM_CHANNEL_STATE_HANGUP:
        break;

    case FTDM_CHANNEL_STATE_UP:
    {
        if (ftdm_test_pflag(ftdmchan, PRITAP_NETWORK_ANSWER)) {
            ftdm_clear_pflag(ftdmchan, PRITAP_NETWORK_ANSWER);
            sig.event_id = FTDM_SIGEVENT_UP;
            ftdm_span_send_signal(ftdmchan->span, &sig);
        }
    }
    break;

    case FTDM_CHANNEL_STATE_RING:
    {
        sig.event_id = FTDM_SIGEVENT_START;
        /* The ring interface (where the setup was received) is the peer, since we RING the channel
         * where PROCEED/PROGRESS is received */
        ftdm_sigmsg_add_var(&sig, "pritap_ring_interface", PRITAP_GET_INTERFACE(peer_pritap->iface));
        if ((status = ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS)) {
            ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
        }
    }
    break;

    case FTDM_CHANNEL_STATE_TERMINATING:
    {
        if (ftdmchan->last_state != FTDM_CHANNEL_STATE_HANGUP) {
            sig.event_id = FTDM_SIGEVENT_STOP;
            status = ftdm_span_send_signal(ftdmchan->span, &sig);
        }
        ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
    }
    break;

    default:
    {
        ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "ignoring state change from %s to %s\n", ftdm_channel_state2str(ftdmchan->last_state), ftdm_channel_state2str(ftdmchan->state));
    }
    break;
    }

    return FTDM_SUCCESS;
}