コード例 #1
0
/* FUNCTIONS ******************************************************************/
void handle_isup_t35(void *userdata)
{
    SS7_FUNC_TRACE_ENTER(__FUNCTION__);

    sngss7_timer_data_t *timer = userdata;
    sngss7_chan_data_t  *sngss7_info = timer->sngss7_info;
    ftdm_channel_t      *ftdmchan = sngss7_info->ftdmchan;

    /* now that we have the right channel...put a lock on it so no-one else can use it */
    ftdm_mutex_lock(ftdmchan->mutex);

    SS7_ERROR("[Call-Control] Timer 35 expired on CIC = %d\n", sngss7_info->circuit->cic);

    /* set the flag to indicate this hangup is started from the local side */
    sngss7_set_ckt_flag(sngss7_info, FLAG_LOCAL_REL);

    /* hang up on timer expiry */
    ftdmchan->caller_data.hangup_cause = 28;

    /* end the call */
    ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);

    /*unlock*/
    ftdm_mutex_unlock(ftdmchan->mutex);

    SS7_FUNC_TRACE_EXIT(__FUNCTION__);
    return;
}
コード例 #2
0
/* Unsed only for overlap receive */
void sngisdn_snd_setup_ack(ftdm_channel_t *ftdmchan)
{
	CnStEvnt cnStEvnt;
	
	sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
	sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;

	if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
		ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending SETUP ACK , but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
		sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
		ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
		return;
	}
	
	memset(&cnStEvnt, 0, sizeof(cnStEvnt));	



	ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending SETUP ACK (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces);

	if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, MI_SETUPACK, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces)) {
		ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, 	"stack refused SETUP ACK request\n");
	}
	return;
}
コード例 #3
0
void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan)
{	
	DiscEvnt discEvnt;

	sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
	sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;

	if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
		ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending DISCONNECT, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);

		sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
		ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
		return;
	}

	memset(&discEvnt, 0, sizeof(discEvnt));

	set_cause_ie(ftdmchan, &discEvnt.causeDgn[0]);
	set_facility_ie(ftdmchan, &discEvnt.facilityStr);
	set_user_to_user_ie(ftdmchan, &discEvnt.usrUsr);

	ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending DISCONNECT (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
	if (sng_isdn_disc_request(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &discEvnt)) {
		ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused DISCONNECT request\n");
	}
	return;
}
コード例 #4
0
void sngisdn_snd_connect(ftdm_channel_t *ftdmchan)
{
	CnStEvnt cnStEvnt;
	sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
	sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
	ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN};

	if (sngisdn_test_flag(sngisdn_info, FLAG_SENT_CONNECT)) {
		return;
	}
	sngisdn_set_flag(sngisdn_info, FLAG_SENT_CONNECT);

	if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
		ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending CONNECT, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
		sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
		ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
		return;
	}
	
	memset(&cnStEvnt, 0, sizeof(cnStEvnt));

	/* Indicate channel ID only in first response */
	if (!ftdm_test_flag(sngisdn_info, FLAG_SENT_CHAN_ID)) {
		set_chan_id_ie(ftdmchan, &cnStEvnt.chanId);
	}
	set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind);
	set_facility_ie(ftdmchan, &cnStEvnt.facilityStr);

	ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending CONNECT (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces);
	if (sng_isdn_con_response(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces)) {
		ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused CONNECT request\n");
	}
	return;
}
コード例 #5
0
void sngisdn_snd_alert(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind)
{
	CnStEvnt cnStEvnt;
	
	sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
	sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;

	if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
		ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending ALERT, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
		sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
		ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
		return;
	}	

	memset(&cnStEvnt, 0, sizeof(cnStEvnt));

	set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind);
	set_facility_ie(ftdmchan, &cnStEvnt.facilityStr);

	ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending ALERT (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces);

	if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId,&cnStEvnt, MI_ALERTING, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces)) {
		ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, 	"stack refused ALERT request\n");
	}
	return;
}
コード例 #6
0
void sngisdn_snd_progress(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind)
{
	CnStEvnt cnStEvnt;
	
	sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
	sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;

	if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
		ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending PROGRESS, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
		sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
		ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
		return;
	}	
	
	if (signal_data->switchtype == SNGISDN_SWITCH_INSNET) {
		/* Trillium Q931 layer complains of invalid event when receiving PROGRESS in
			INSNET variant, so PROGRESS event is probably invalid */
		return;
	}

	memset(&cnStEvnt, 0, sizeof(cnStEvnt));	
	set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind);
	set_facility_ie(ftdmchan, &cnStEvnt.facilityStr);

	ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending PROGRESS (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces);
	if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId,&cnStEvnt, MI_PROGRESS, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces)) {
		ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, 	"stack refused PROGRESS request\n");
	}
	return;
}
コード例 #7
0
/* Used only for BRI PTMP - This function is used when the NT side makes a call out,
	and one or multiple TE's reply, then NT assigns the call by sending a con_complete*/
void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan)
{
	CnStEvnt cnStEvnt;
	
	sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
	sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;

	if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
		ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending CONNECT COMPL , but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
		sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
		ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
		return;
	}
	
	memset(&cnStEvnt, 0, sizeof(cnStEvnt));

	/* Indicate channel ID only in first response */
	if (!ftdm_test_flag(sngisdn_info, FLAG_SENT_CHAN_ID)) {
		set_chan_id_ie(ftdmchan, &cnStEvnt.chanId);
	}

	ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending CONNECT COMPL (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces);

	if(sng_isdn_con_comp(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces)) {
		ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, 	"stack refused CONNECT ACK request\n");
	}
	return;
}
コード例 #8
0
void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare)
{
	RelEvnt relEvnt;
	uint32_t suInstId, spInstId;

	sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
	sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;

 	if (!sngisdn_info->suInstId) {
		ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending RELEASE, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);

		sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
		ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
		return;
	}
	
	memset(&relEvnt, 0, sizeof(relEvnt));
	
	/* Fill relEvnt here */
  	relEvnt.causeDgn[0].eh.pres = PRSNT_NODEF;
	relEvnt.causeDgn[0].location.pres = PRSNT_NODEF;
	relEvnt.causeDgn[0].location.val = IN_LOC_PRIVNETLU;
	relEvnt.causeDgn[0].codeStand3.pres = PRSNT_NODEF;
	relEvnt.causeDgn[0].codeStand3.val = IN_CSTD_CCITT;

	relEvnt.causeDgn[0].causeVal.pres = PRSNT_NODEF;
	relEvnt.causeDgn[0].causeVal.val = ftdmchan->caller_data.hangup_cause;
	relEvnt.causeDgn[0].recommend.pres = NOTPRSNT;
	relEvnt.causeDgn[0].dgnVal.pres = NOTPRSNT;

	if (glare) {
		suInstId = sngisdn_info->glare.suInstId;
		spInstId = sngisdn_info->glare.spInstId;
	} else {
		suInstId = sngisdn_info->suInstId;
		spInstId = sngisdn_info->spInstId;
	}

	set_facility_ie(ftdmchan, &relEvnt.facilityStr);
	
	ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending RELEASE/RELEASE COMPLETE (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, suInstId, spInstId);

	if (glare) {
		if (sng_isdn_release_request(signal_data->cc_id, suInstId, spInstId, &relEvnt)) {
			ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused RELEASE/RELEASE COMPLETE request\n");
		}
	} else {	
		if (sng_isdn_release_request(signal_data->cc_id, suInstId, spInstId, &relEvnt)) {
			ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused RELEASE/RELEASE COMPLETE request\n");
		}
	}	
	return;
}
コード例 #9
0
ファイル: testanalog.c プロジェクト: amalosh/freeswitch
static void *test_call(ftdm_thread_t *me, void *obj)
{
	ftdm_channel_t *chan = (ftdm_channel_t *) obj;
	uint8_t frame[1024];
	ftdm_size_t len;
	char *number = strdup("5551212");

	ftdm_sleep(10 * 1000);
	
	ftdm_log(FTDM_LOG_DEBUG, "answer call and start echo test\n");

	ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_UP);
	ftdm_channel_command(chan, FTDM_COMMAND_SEND_DTMF, number);

	while (chan->state == FTDM_CHANNEL_STATE_UP) {
		ftdm_wait_flag_t flags = FTDM_READ;
		
		if (ftdm_channel_wait(chan, &flags, -1) == FTDM_FAIL) {
			break;
		}
		len = sizeof(frame);
		if (flags & FTDM_READ) {
			if (ftdm_channel_read(chan, frame, &len) == FTDM_SUCCESS) {
				//ftdm_log(FTDM_LOG_DEBUG, "WRITE %d\n", len);
				ftdm_channel_write(chan, frame, sizeof(frame), &len);
			} else {
				break;
			}
		}
	}
	
	if (chan->state == FTDM_CHANNEL_STATE_UP) {
		ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_BUSY);
	}

	ftdm_log(FTDM_LOG_DEBUG, "call over\n");
	free(number);
	return NULL;
}
コード例 #10
0
ファイル: testanalog.c プロジェクト: amalosh/freeswitch
static FIO_SIGNAL_CB_FUNCTION(on_signal)
{
	ftdm_log(FTDM_LOG_DEBUG, "got sig [%s]\n", ftdm_signal_event2str(sigmsg->event_id));

	switch(sigmsg->event_id) {
	case FTDM_SIGEVENT_START:
		ftdm_set_state_locked(sigmsg->channel, FTDM_CHANNEL_STATE_RING);
		ftdm_log(FTDM_LOG_DEBUG, "launching thread and indicating ring\n");
		ftdm_thread_create_detached(test_call, sigmsg->channel);
		break;
	default:
		break;
	}

	return FTDM_SUCCESS;
}
コード例 #11
0
ftdm_status_t check_for_state_change(ftdm_channel_t *ftdmchan)
{

#if 0
    ftdm_log_chan_msg(ftdmchan, "Checking for pending state change\n");
#endif
    /* check to see if there are any pending state changes on the channel and give them a sec to happen*/
    ftdm_wait_for_flag_cleared(ftdmchan, FTDM_CHANNEL_STATE_CHANGE, 5000);

    /* check the flag to confirm it is clear now */
    if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
        /* the flag is still up...so we have a problem */
		ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "FTDM_CHANNEL_STATE_CHANGE set for over 500ms\n");

        /* move the state of the channel to RESTART to force a reset */
        ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);

        return FTDM_FAIL;
    }
    return FTDM_SUCCESS;
}
コード例 #12
0
ファイル: ftmod_pritap.c プロジェクト: odmanV2/freecenter
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;
}