Esempio n. 1
0
void sngisdn_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status_t status)
{
	ftdm_sigmsg_t sig;
	sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)ftdmchan->span->signal_data;
	
	ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Signalling link status changed to %s\n", ftdm_signaling_status2str(status));

	memset(&sig, 0, sizeof(sig));
	sig.chan_id = ftdmchan->chan_id;
	sig.span_id = ftdmchan->span_id;
	sig.channel = ftdmchan;
	sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
	sig.ev_data.sigstatus.status = status;
	ftdm_span_send_signal(ftdmchan->span, &sig);

	if (FTDM_SPAN_IS_BRI(ftdmchan->span)) {		
		sngisdn_chan_data_t		*sngisdn_info = ftdmchan->call_data;
		if (ftdm_test_flag(sngisdn_info, FLAG_ACTIVATING)) {
			ftdm_clear_flag(sngisdn_info, FLAG_ACTIVATING);

			ftdm_sched_timer(signal_data->sched, "delayed_setup", 1000, sngisdn_delayed_setup, (void*) sngisdn_info, NULL);
		}
	}
	return;
}
Esempio n. 2
0
void on_wat_sms_ind(unsigned char span_id, wat_sms_event_t *sms_event)
{
	//printf("on_wat_sms_ind\r\n");
	
	ftdm_span_t *span = NULL;
	ftdm_channel_t *ftdmchan;
	
	ftdm_gsm_span_data_t *gsm_data = NULL;

	if(!(span = GetSpanByID(span_id, &gsm_data))) {
		return;
	}
	
	ftdmchan = gsm_data->dchan;
	
	{
		ftdm_sms_data_t sms_data;
		memset(&sms_data, 0, sizeof(sms_data));
		
		strncpy(sms_data.from, sms_event->from.digits, sizeof(sms_data.from));
		strncpy(sms_data.body, sms_event->content.data, sizeof(sms_data.body));
		
		ftdm_sigmsg_t sigev; 
		memset(&sigev, 0, sizeof(sigev)); 
		sigev.event_id = FTDM_SIGEVENT_SMS; 
		sigev.channel = ftdmchan ;   
		gsm_data->dchan->caller_data.priv = (void *)&sms_data;
		ftdm_span_send_signal(span, &sigev); 
	}
//	SEND_STATE_SIGNAL(FTDM_SIGEVENT_SMS);
	return;
}
Esempio n. 3
0
void sngisdn_trace_raw_q931(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len)
{
	uint8_t 			*raw_data;
	ftdm_sigmsg_t		sigev;
	ftdm_channel_t *ftdmchan = NULL;
	sngisdn_frame_info_t  frame_info;

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

	/* Note: Mapped raw trace assume only exclusive b-channel selection is used. i.e the b-channel selected on outgoing SETUP is always used for the call */
	
	if (sngisdn_get_frame_info(data, data_len, dir, &frame_info) == FTDM_SUCCESS) {
		if (sngisdn_map_call(signal_data, frame_info, &ftdmchan) == FTDM_SUCCESS) {
			sigev.call_id = ftdmchan->caller_data.call_id;
			sigev.span_id = ftdmchan->physical_span_id;
			sigev.chan_id = ftdmchan->physical_chan_id;
			sigev.channel = ftdmchan;
		}
		sigev.event_id = FTDM_SIGEVENT_TRACE_RAW;

		sigev.ev_data.trace.dir = dir;
		sigev.ev_data.trace.type = FTDM_TRACE_TYPE_Q931;

		raw_data = ftdm_malloc(data_len);
		ftdm_assert(raw_data, "Failed to malloc");

		memcpy(raw_data, data, data_len);
		sigev.raw.data = raw_data;
		sigev.raw.len = data_len;
		sigev.raw.autofree = 1;
		ftdm_span_send_signal(signal_data->ftdm_span, &sigev);
	}
}
void sngisdn_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status_t status)
{
	ftdm_sigmsg_t sig;
	ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Signalling link status changed to %s\n", ftdm_signaling_status2str(status));

	memset(&sig, 0, sizeof(sig));
	sig.chan_id = ftdmchan->chan_id;
	sig.span_id = ftdmchan->span_id;
	sig.channel = ftdmchan;
	sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
	sig.raw_data = &status;
	ftdm_span_send_signal(ftdmchan->span, &sig);
	return;
}
void sngisdn_trace_raw_q921(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len)
{
    uint8_t 			*raw_data;
    ftdm_sigmsg_t		sigev;

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

    sigev.span_id = signal_data->ftdm_span->span_id;
    sigev.chan_id = signal_data->dchan->chan_id;
    sigev.channel = signal_data->dchan;
    sigev.event_id = FTDM_SIGEVENT_TRACE_RAW;

    sigev.ev_data.trace.dir = dir;
    sigev.ev_data.trace.type = FTDM_TRACE_TYPE_Q921;

    raw_data = ftdm_malloc(data_len);
    ftdm_assert(raw_data, "Failed to malloc");

    memcpy(raw_data, data, data_len);
    sigev.raw.data = raw_data;
    sigev.raw.len = data_len;
    ftdm_span_send_signal(signal_data->ftdm_span, &sigev);
}
void sngisdn_send_signal(sngisdn_chan_data_t *sngisdn_info, ftdm_signal_event_t event_id)
{
	ftdm_sigmsg_t sigev;
	ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;

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

	sigev.chan_id = ftdmchan->chan_id;
	sigev.span_id = ftdmchan->span_id;
	sigev.channel = ftdmchan;
	sigev.event_id = event_id;

	if (sngisdn_info->variables) {
		/*
		* variables now belongs to the ftdm core, and
		* will be cleared after sigev is processed by user. Set
		* local pointer to NULL so we do not attempt to
		* destroy it */
		sigev.variables = sngisdn_info->variables;
		sngisdn_info->variables = NULL;
	}

	if (sngisdn_info->raw_data) {
		/*
		* raw_data now belongs to the ftdm core, and
		* will be cleared after sigev is processed by user. Set
		* local pointer to NULL so we do not attempt to
		* destroy it */
		
		sigev.raw.data = sngisdn_info->raw_data;
		sigev.raw.len = sngisdn_info->raw_data_len;
		
		sngisdn_info->raw_data = NULL;
		sngisdn_info->raw_data_len = 0;
	}
	ftdm_span_send_signal(ftdmchan->span, &sigev);
}
Esempio n. 7
0
FT_DECLARE(ftdm_status_t) _ftdm_channel_complete_state(const char *file, const char *func, int line, ftdm_channel_t *fchan)
{
	uint8_t hindex = 0;
	ftdm_time_t diff = 0;
	ftdm_channel_state_t state = fchan->state;

	if (fchan->state_status == FTDM_STATE_STATUS_COMPLETED) {
		ftdm_assert_return(!ftdm_test_flag(fchan, FTDM_CHANNEL_STATE_CHANGE), FTDM_FAIL, 
				"State change flag set but state is not completed\n");
		return FTDM_SUCCESS;
	}

	ftdm_usrmsg_free(&fchan->usrmsg);
	
	ftdm_clear_flag(fchan, FTDM_CHANNEL_STATE_CHANGE);

	if (state == FTDM_CHANNEL_STATE_PROGRESS) {
		ftdm_set_flag(fchan, FTDM_CHANNEL_PROGRESS);
	} else if (state == FTDM_CHANNEL_STATE_PROGRESS_MEDIA) {
		ftdm_set_flag(fchan, FTDM_CHANNEL_PROGRESS);	
		ftdm_test_and_set_media(fchan);
	} else if (state == FTDM_CHANNEL_STATE_UP) {
		ftdm_set_flag(fchan, FTDM_CHANNEL_PROGRESS);
		ftdm_set_flag(fchan, FTDM_CHANNEL_ANSWERED);	
		ftdm_test_and_set_media(fchan);
	} else if (state == FTDM_CHANNEL_STATE_DIALING) {
		ftdm_sigmsg_t msg;
		memset(&msg, 0, sizeof(msg));
		msg.channel = fchan;
		msg.event_id = FTDM_SIGEVENT_DIALING;
		ftdm_span_send_signal(fchan->span, &msg);
	} else if (state == FTDM_CHANNEL_STATE_HANGUP) {
		ftdm_set_echocancel_call_end(fchan);
	}

	/* MAINTENANCE WARNING
	 * we're assuming an indication performed 
	 * via state change will involve a single state change */
	ftdm_ack_indication(fchan, fchan->indication, FTDM_SUCCESS);

	hindex = (fchan->hindex == 0) ? (ftdm_array_len(fchan->history) - 1) : (fchan->hindex - 1);
	
	ftdm_assert(!fchan->history[hindex].end_time, "End time should be zero!\n");

	fchan->history[hindex].end_time = ftdm_current_time_in_ms();

	fchan->state_status = FTDM_STATE_STATUS_COMPLETED;

	diff = fchan->history[hindex].end_time - fchan->history[hindex].time;

	ftdm_log_chan_ex(fchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Completed state change from %s to %s in %llums\n", 
			ftdm_channel_state2str(fchan->last_state), ftdm_channel_state2str(state), diff);
	

	if (ftdm_test_flag(fchan, FTDM_CHANNEL_BLOCKING)) {
		ftdm_clear_flag(fchan, FTDM_CHANNEL_BLOCKING);
		ftdm_interrupt_signal(fchan->state_completed_interrupt);
	}

	return FTDM_SUCCESS;
}
Esempio n. 8
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;
}