コード例 #1
0
ftdm_status_t sngisdn_transfer(ftdm_channel_t *ftdmchan)
{
	const char* args;
	char *p;
	char *type = NULL;
	char *target = NULL;
	ftdm_status_t status = FTDM_FAIL;
	sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data;
	unsigned i;

	args = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "transfer_arg");
	if (ftdm_strlen_zero(args)) {
		ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Cannot perform transfer because call_transfer_arg variable is not set\n");
		goto done;
	}

	type = ftdm_strdup(args);
	if ((p = strchr(type, '/'))) {
		target = ftdm_strdup(p+1);
		*p = '\0';
	}

	if (ftdm_strlen_zero(type) || ftdm_strlen_zero(target)) {
		ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Invalid parameters for transfer %s, expected <type>/<target>\n", args);
		goto done;
	}

	if (sngisdn_info->transfer_data.type != SNGISDN_TRANSFER_NONE) {
		ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Cannot perform transfer because an existing transfer transfer is pending (%s)\n", sngisdn_transfer_type2str(sngisdn_info->transfer_data.type));
		goto done;
	}

	ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Transfer requested type:%s target:%s\n", type, target);
	for (i = 0; i < ftdm_array_len(transfer_interfaces); i++ ) {
		if (!strcasecmp(transfer_interfaces[i].name, type)) {
			/* Depending on the transfer type, the transfer function may change the
			 * channel state to UP, or last_state, but the transfer function will always result in
			 * an immediate state change if FTDM_SUCCESS is returned */

			status = transfer_interfaces[i].func(ftdmchan, transfer_interfaces[i].type, target);
			goto done;
		}
	}

	ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Invalid transfer type:%s\n", type);

done:
	if (status != FTDM_SUCCESS) {
		ftdm_set_state(ftdmchan, ftdmchan->last_state);
	}

	ftdm_safe_free(type);
	ftdm_safe_free(target);
	return status;
}
コード例 #2
0
/* No one calls this function yet, but it has been implemented to complement TXA messages */
void ft_to_sngss7_itx (ftdm_channel_t * ftdmchan)
{
#ifndef SANGOMA_SPIROU
    SS7_FUNC_TRACE_ENTER (__FUNCTION__);
    ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "ITX message not supported!, please update your libsng_ss7\n");
#else
    const char* var = NULL;
    sngss7_chan_data_t	*sngss7_info = ftdmchan->call_data;
    SiCnStEvnt itx;

    SS7_FUNC_TRACE_ENTER (__FUNCTION__);

    memset (&itx, 0x0, sizeof (itx));

    itx.msgNum.eh.pres = PRSNT_NODEF;
    itx.msgNum.msgNum.pres = PRSNT_NODEF;
    var = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_itx_msg_num");
    if (!ftdm_strlen_zero(var)) {
        itx.msgNum.msgNum.val = atoi(var);
    } else {
        itx.msgNum.msgNum.val = 0x1;
    }

    itx.chargUnitNum.eh.pres = PRSNT_NODEF;
    itx.chargUnitNum.chargUnitNum.pres = PRSNT_NODEF;
    var = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_itx_charge_unit");
    if (!ftdm_strlen_zero(var)) {
        itx.chargUnitNum.chargUnitNum.val = atoi(var);
    } else {
        itx.chargUnitNum.chargUnitNum.val = 0x1;
    }

    ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "ITX Charging Unit:%d Msg Num:%d\n", itx.chargUnitNum.chargUnitNum.val, itx.msgNum.msgNum.val);
    sng_cc_con_status  (1, sngss7_info->suInstId, sngss7_info->spInstId, sngss7_info->circuit->id, &itx, CHARGE_UNIT);

    SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx ITX\n", sngss7_info->circuit->cic);
#endif
    SS7_FUNC_TRACE_EXIT (__FUNCTION__);
    return;
}
コード例 #3
0
ファイル: ftmod_pritap.c プロジェクト: odmanV2/freecenter
static __inline__ ftdm_channel_t *tap_pri_get_fchan(pritap_t *pritap, passive_call_t *pcall, int channel)
{
    ftdm_channel_t *fchan = NULL;
    int err = 0;
    int chanpos = PRI_CHANNEL(channel);
    if (!chanpos || chanpos > pritap->span->chan_count) {
        ftdm_log(FTDM_LOG_CRIT, "Invalid pri tap channel %d requested in span %s\n", channel, pritap->span->name);
        return NULL;
    }

    fchan = pritap->span->channels[PRI_CHANNEL(channel)];

    ftdm_channel_lock(fchan);

    if (ftdm_test_flag(fchan, FTDM_CHANNEL_INUSE)) {
        ftdm_log(FTDM_LOG_ERROR, "Channel %d requested in span %s is already in use!\n", channel, pritap->span->name);
        err = 1;
        goto done;
    }

    if (ftdm_channel_open_chan(fchan) != FTDM_SUCCESS) {
        ftdm_log(FTDM_LOG_ERROR, "Could not open tap channel %d requested in span %s\n", channel, pritap->span->name);
        err = 1;
        goto done;
    }

    memset(&fchan->caller_data, 0, sizeof(fchan->caller_data));

    ftdm_set_string(fchan->caller_data.cid_num.digits, pcall->callingnum.digits);
    if (!ftdm_strlen_zero(pcall->callingname)) {
        ftdm_set_string(fchan->caller_data.cid_name, pcall->callingname);
    } else {
        ftdm_set_string(fchan->caller_data.cid_name, pcall->callingnum.digits);
    }
    ftdm_set_string(fchan->caller_data.ani.digits, pcall->callingani.digits);
    ftdm_set_string(fchan->caller_data.dnis.digits, pcall->callednum.digits);

done:
    if (fchan) {
        ftdm_channel_unlock(fchan);
    }

    if (err) {
        return NULL;
    }

    return fchan;
}
コード例 #4
0
ファイル: ftmod_wanpipe.c プロジェクト: Deepwalker/FreeSWITCH
/**
 * \brief Initialises a range of wanpipe channels
 * \param span FreeTDM span
 * \param spanno Wanpipe span number
 * \param start Initial wanpipe channel number
 * \param end Final wanpipe channel number
 * \param type FreeTDM channel type
 * \param name FreeTDM span name
 * \param number FreeTDM span number
 * \param cas_bits CAS bits
 * \return number of spans configured
 */
static unsigned wp_open_range(ftdm_span_t *span, unsigned spanno, unsigned start, unsigned end, ftdm_chan_type_t type, char *name, char *number, unsigned char cas_bits)
{
	unsigned configured = 0, x;
#ifdef LIBSANGOMA_VERSION
	sangoma_status_t sangstatus;
	sangoma_wait_obj_t *sangoma_wait_obj;
#endif

	if (type == FTDM_CHAN_TYPE_CAS) {
		ftdm_log(FTDM_LOG_DEBUG, "Configuring Wanpipe CAS channels with abcd == 0x%X\n", cas_bits);
	}	
	for(x = start; x < end; x++) {
		ftdm_channel_t *chan;
		ftdm_socket_t sockfd = FTDM_INVALID_SOCKET;
		const char *dtmf = "none";
		if (!strncasecmp(span->name, "smg_prid_nfas", 8) && span->trunk_type == FTDM_TRUNK_T1 && x == 24) {
#ifdef LIBSANGOMA_VERSION
			sockfd = __tdmv_api_open_span_chan(spanno, x);
#else
			ftdm_log(FTDM_LOG_ERROR, "span %d channel %d cannot be configured as smg_prid_nfas, you need to compile freetdm with newer libsangoma\n", spanno, x);
#endif
		} else {
			sockfd = tdmv_api_open_span_chan(spanno, x);
		}

		if (sockfd == FTDM_INVALID_SOCKET) {
			ftdm_log(FTDM_LOG_ERROR, "Failed to open wanpipe device span %d channel %d\n", spanno, x);
			continue;
		}
		
		if (ftdm_span_add_channel(span, sockfd, type, &chan) == FTDM_SUCCESS) {
			wanpipe_tdm_api_t tdm_api;
			memset(&tdm_api, 0, sizeof(tdm_api));
#ifdef LIBSANGOMA_VERSION
			/* we need SANGOMA_DEVICE_WAIT_OBJ_SIG and not SANGOMA_DEVICE_WAIT_OBJ alone because we need to call 
			 * sangoma_wait_obj_sig to wake up any I/O waiters when closing the channel (typically on ftdm shutdown)
			 * this adds an extra pair of file descriptors to the waitable object
			 * */
			sangstatus = sangoma_wait_obj_create(&sangoma_wait_obj, sockfd, SANGOMA_DEVICE_WAIT_OBJ_SIG);
			if (sangstatus != SANG_STATUS_SUCCESS) {
				ftdm_log(FTDM_LOG_ERROR, "failure create waitable object for s%dc%d\n", spanno, x);
				continue;
			}
			chan->mod_data = sangoma_wait_obj;
#endif
			
			chan->physical_span_id = spanno;
			chan->physical_chan_id = x;
			chan->rate = 8000;
			
			if (type == FTDM_CHAN_TYPE_FXS || type == FTDM_CHAN_TYPE_FXO || type == FTDM_CHAN_TYPE_B) {
				int err;
				
				dtmf = "software";

				err = sangoma_tdm_get_hw_coding(chan->sockfd, &tdm_api);

				if (tdm_api.wp_tdm_cmd.hw_tdm_coding) {
					chan->native_codec = chan->effective_codec = FTDM_CODEC_ALAW;
				} else {
					chan->native_codec = chan->effective_codec = FTDM_CODEC_ULAW;
				}

				err = sangoma_tdm_get_hw_dtmf(chan->sockfd, &tdm_api);
				if (err > 0) {
					ftdm_channel_set_feature(chan, FTDM_CHANNEL_FEATURE_DTMF_DETECT);
					dtmf = "hardware";
				}
			}

#ifdef LIBSANGOMA_VERSION
			if (type == FTDM_CHAN_TYPE_FXS) {
				if (sangoma_tdm_disable_ring_trip_detect_events(chan->sockfd, &tdm_api)) {
					/* we had problems of on-hook/off-hook detection due to how ring trip events were handled
					 * if this fails, I believe we will still work ok as long as we dont handle them incorrectly */
					ftdm_log(FTDM_LOG_WARNING, "Failed to disable ring trip events in channel s%dc%d\n", spanno, x);
				}
			}
#endif
#if 0
            if (type == FTDM_CHAN_TYPE_FXS || type == FTDM_CHAN_TYPE_FXO) {
                /* Enable FLASH/Wink Events */
                int err=sangoma_set_rm_rxflashtime(chan->sockfd, &tdm_api, wp_globals.flash_ms);
                if (err == 0) {
			        ftdm_log(FTDM_LOG_ERROR, "flash enabled s%dc%d\n", spanno, x);
                } else {
			        ftdm_log(FTDM_LOG_ERROR, "flash disabled s%dc%d\n", spanno, x);
                }
            }
#endif

			if (type == FTDM_CHAN_TYPE_CAS || type == FTDM_CHAN_TYPE_EM) {
#ifdef LIBSANGOMA_VERSION
				sangoma_tdm_write_rbs(chan->sockfd,&tdm_api,chan->physical_chan_id, wanpipe_swap_bits(cas_bits));

				/* this should probably be done for old libsangoma but I am not sure if the API is available and I'm lazy to check,
				   The poll rate is hard coded to 100 per second (done in the driver, is the max rate of polling allowed by wanpipe)
				 */
				if (sangoma_tdm_enable_rbs_events(chan->sockfd, &tdm_api, 100)) {
					ftdm_log(FTDM_LOG_ERROR, "Failed to enable RBS/CAS events in device %d:%d fd:%d\n", chan->span_id, chan->chan_id, sockfd);
					continue;
				}
				/* probably done by the driver but lets write defensive code this time */
				sangoma_flush_bufs(chan->sockfd, &tdm_api);
#else
				/* 
				 * With wanpipe 3.4.4.2 I get failure even though the events are enabled, /var/log/messages said:
				 * wanpipe4: WARNING: Event type 9 is already pending!
				 * wanpipe4: Failed to add new fe event 09 ch_map=FFFFFFFF!
				 * may be we should not send an error until that is fixed in the driver
				 */
				if (sangoma_tdm_enable_rbs_events(chan->sockfd, &tdm_api, 100)) {
					ftdm_log(FTDM_LOG_ERROR, "Failed to enable RBS/CAS events in device %d:%d fd:%d\n", chan->span_id, chan->chan_id, sockfd);
				}
				/* probably done by the driver but lets write defensive code this time */
				sangoma_tdm_flush_bufs(chan->sockfd, &tdm_api);
				sangoma_tdm_write_rbs(chan->sockfd,&tdm_api, wanpipe_swap_bits(cas_bits));
#endif
			}
			
			if (!ftdm_strlen_zero(name)) {
				ftdm_copy_string(chan->chan_name, name, sizeof(chan->chan_name));
			}

			if (!ftdm_strlen_zero(number)) {
				ftdm_copy_string(chan->chan_number, number, sizeof(chan->chan_number));
			}
			configured++;
			ftdm_log_chan(chan, FTDM_LOG_INFO, "configured wanpipe device s%dc%d as FreeTDM channel %d:%d fd:%d DTMF: %s\n",
				spanno, x, chan->span_id, chan->chan_id, sockfd, dtmf);

		} else {
			ftdm_log(FTDM_LOG_ERROR, "ftdm_span_add_channel failed for wanpipe span %d channel %d\n", spanno, x);
		}
	}
	
	return configured;
}
コード例 #5
0
static ftdm_status_t parse_trunkgroup(const char *_trunkgroup)
{
	int i;
	char *p, *name, *dchan_span, *backup_span, *trunkgroup;
	uint8_t num_spans = 0;
	ftdm_status_t ret = FTDM_SUCCESS;

	trunkgroup =  ftdm_strdup(_trunkgroup);

	p = name = dchan_span = backup_span = NULL;

	/* format: name, num_chans, dchan_span, [backup_span] */

	i = 0;
	for (p = strtok(trunkgroup, ","); p; p = strtok(NULL, ",")) {
		while (*p == ' ') {
			p++;
		}
		switch(i++) {
			case 0:
				name = ftdm_strdup(p);
				break;
			case 1:
				num_spans = atoi(p);
				break;
			case 2:
				dchan_span = ftdm_strdup(p);
				break;
			case 3:
				backup_span = ftdm_strdup(p);
		}
	}

	if (!name || !dchan_span || num_spans <= 0) {
		ftdm_log(FTDM_LOG_ERROR, "Invalid parameters for trunkgroup:%s\n", _trunkgroup);
		ret = FTDM_FAIL;
		goto done;
	}

	for (i = 0; i < g_sngisdn_data.num_nfas; i++) {
		if (!ftdm_strlen_zero(g_sngisdn_data.nfass[i].name) &&
		    !strcasecmp(g_sngisdn_data.nfass[i].name, name)) {

			/* We already configured this trunkgroup */
			goto done;
		}
	}

	/* Trunk group was not found, need to configure it */
	strncpy(g_sngisdn_data.nfass[i].name, name, sizeof(g_sngisdn_data.nfass[i].name));
	g_sngisdn_data.nfass[i].num_spans = num_spans;
	strncpy(g_sngisdn_data.nfass[i].dchan_span_name, dchan_span, sizeof(g_sngisdn_data.nfass[i].dchan_span_name));

	if (backup_span) {
		strncpy(g_sngisdn_data.nfass[i].backup_span_name, backup_span, sizeof(g_sngisdn_data.nfass[i].backup_span_name));
	}
	

	g_sngisdn_data.num_nfas++;
done:
	ftdm_safe_free(trunkgroup);
	ftdm_safe_free(name);
	ftdm_safe_free(dchan_span);
	ftdm_safe_free(backup_span);
	return ret;
}
コード例 #6
0
static ftdm_status_t parse_spanmap(const char *_spanmap, ftdm_span_t *span)
{
	int i;
	char *p, *name, *spanmap;
	uint8_t logical_span_id = 0;
	ftdm_status_t ret = FTDM_SUCCESS;
	sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data;

	spanmap = ftdm_strdup(_spanmap);

	p = name = NULL;

	i = 0;
	for (p = strtok(spanmap, ","); p; p = strtok(NULL, ",")) {
		while (*p == ' ') {
			p++;
		}
		switch(i++) {
			case 0:
				name = ftdm_strdup(p);
				break;
			case 1:
				logical_span_id = atoi(p);
				break;
		}
	}

	if (!name) {
		ftdm_log(FTDM_LOG_ERROR, "Invalid spanmap syntax %s\n", _spanmap);
		ret = FTDM_FAIL;
		goto done;
	}

	for (i = 0; i < g_sngisdn_data.num_nfas; i++) {
		if (!ftdm_strlen_zero(g_sngisdn_data.nfass[i].name) &&
			!strcasecmp(g_sngisdn_data.nfass[i].name, name)) {

			signal_data->nfas.trunk = &g_sngisdn_data.nfass[i];
			break;
		}
	}

	if (!signal_data->nfas.trunk) {
		ftdm_log(FTDM_LOG_ERROR, "Could not find trunkgroup with name %s\n", name);
		ret = FTDM_FAIL;
		goto done;
	}

	if (signal_data->nfas.trunk->spans[logical_span_id]) {
		ftdm_log(FTDM_LOG_ERROR, "trunkgroup:%s already had a span with logical span id:%d\n", name, logical_span_id);
	} else {
		signal_data->nfas.trunk->spans[logical_span_id] = signal_data;
		signal_data->nfas.interface_id = logical_span_id;
	}

	if (!strcasecmp(signal_data->ftdm_span->name, signal_data->nfas.trunk->dchan_span_name)) {

		signal_data->nfas.sigchan = SNGISDN_NFAS_DCHAN_PRIMARY;
		signal_data->nfas.trunk->dchan = signal_data;
	}

	if (!strcasecmp(signal_data->ftdm_span->name, signal_data->nfas.trunk->backup_span_name)) {

		signal_data->nfas.sigchan = SNGISDN_NFAS_DCHAN_BACKUP;
		signal_data->nfas.trunk->backup = signal_data;
	}

done:
	ftdm_safe_free(spanmap);
	ftdm_safe_free(name);
	return ret;
}
コード例 #7
0
static ftdm_status_t att_courtesy_vru(ftdm_channel_t *ftdmchan, sngisdn_transfer_type_t type, char* args)
{
	char dtmf_digits[64];
	ftdm_status_t status = FTDM_FAIL;
	sngisdn_chan_data_t  *sngisdn_info = ftdmchan->call_data;
	sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
	char *p = args;
	uint8_t forced_answer = 0;

	switch (signal_data->switchtype) {
		case SNGISDN_SWITCH_5ESS:
		case SNGISDN_SWITCH_4ESS:
			break;
		default:
			ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "AT&T Courtesy Transfer not supported for switchtype\n");
			return FTDM_FAIL;
	}

	while (!ftdm_strlen_zero(p)) {
		if (!isdigit(*p) && *p != 'w' && *p != 'W') {
			ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Cannot transfer to non-numeric number:%s\n", args);
			return FTDM_FAIL;
		}
		p++;
	}

	ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Performing AT&T Courtesy Transfer-VRU%s to %s\n", (type == SNGISDN_TRANSFER_ATT_COURTESY_VRU_DATA) ?"--data" : "", args);
	sprintf(dtmf_digits, "*8w%s", args);
	ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending digits %s\n", dtmf_digits);

	switch (ftdmchan->last_state) {
		case FTDM_CHANNEL_STATE_PROCEED:
		case FTDM_CHANNEL_STATE_PROGRESS:
		case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
			/* Call has to be in answered state - so send a CONNECT message if we did not answer this call yet */
			forced_answer++;
			sngisdn_snd_connect(ftdmchan);
			/* fall-through */
		case FTDM_CHANNEL_STATE_UP:
			memset(&sngisdn_info->transfer_data.tdata.att_courtesy_vru.dtmf_digits, 0, sizeof(sngisdn_info->transfer_data.tdata.att_courtesy_vru.dtmf_digits));
			sngisdn_info->transfer_data.type = type;

			/* We will be polling the channel for IO so that we can receive the DTMF events,
			 * Disable user RX otherwise it is a race between who calls channel_read */
			ftdm_set_flag(ftdmchan, FTDM_CHANNEL_RX_DISABLED);

			ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_DTMF_DETECT, NULL);
			ftdm_channel_command(ftdmchan, FTDM_COMMAND_SEND_DTMF, dtmf_digits);

			if (type == SNGISDN_TRANSFER_ATT_COURTESY_VRU_DATA) {
				/* We need to save transfer data, so we can send it in the disconnect msg */
				const char *val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "transfer_data");
				if (ftdm_strlen_zero(val)) {
					ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Cannot perform data transfer because transfer_data variable is not set\n");
					goto done;
				}
				if (strlen(val) > COURTESY_TRANSFER_MAX_DATA_SIZE) {
					ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Data exceeds max size (len:%"FTDM_SIZE_FMT" max:%d), cannot perform transfer\n", strlen(val), COURTESY_TRANSFER_MAX_DATA_SIZE);
					goto done;
				}
				memcpy(sngisdn_info->transfer_data.tdata.att_courtesy_vru.data, val, strlen(val));
			}

			ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP);
			if (forced_answer) {
				/* Notify the user that we answered the call */
				sngisdn_send_signal(sngisdn_info, FTDM_SIGEVENT_UP);
			}
			if (signal_data->transfer_timeout) {
				ftdm_sched_timer(((sngisdn_span_data_t*)ftdmchan->span->signal_data)->sched, "courtesy_transfer_timeout", signal_data->transfer_timeout, att_courtesy_transfer_timeout, (void*) sngisdn_info, &sngisdn_info->timers[SNGISDN_CHAN_TIMER_ATT_TRANSFER]);
			}

			status = FTDM_SUCCESS;
			break;
		default:
			ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Cannot perform transfer in state %s\n", ftdm_channel_state2str(ftdmchan->state));
			break;

	}
done:
	return status;
}
コード例 #8
0
ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_sngisdn_progind_t prog_ind)
{
	const char *str = NULL;
	int descr = prog_ind.descr;
	int loc = prog_ind.loc;
	
	str = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.prog_ind.descr");
	if (!ftdm_strlen_zero(str)) {
		/* User wants to override progress indicator */
		descr = ftdm_str2ftdm_sngisdn_progind_descr(str);
	}

	if (descr == SNGISDN_PROGIND_DESCR_INVALID) {
		/* User does not want to send progress indicator */
		return FTDM_SUCCESS;
	}

	str = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.prog_ind.loc");
	if (!ftdm_strlen_zero(str)) {
		loc = ftdm_str2ftdm_sngisdn_progind_loc(str);
	}
	if (loc == SNGISDN_PROGIND_LOC_INVALID) {
		loc = SNGISDN_PROGIND_LOC_USER;
	}

	progInd->eh.pres = PRSNT_NODEF;	
	progInd->codeStand0.pres = PRSNT_NODEF;
	progInd->codeStand0.val = IN_CSTD_CCITT;
	
	progInd->progDesc.pres = PRSNT_NODEF;
	switch(descr) {
		case SNGISDN_PROGIND_DESCR_NETE_ISDN:
			progInd->progDesc.val = IN_PD_NOTETEISDN;
			break;
		case SNGISDN_PROGIND_DESCR_DEST_NISDN:
			progInd->progDesc.val = IN_PD_DSTNOTISDN;
			break;
		case SNGISDN_PROGIND_DESCR_ORIG_NISDN:
			progInd->progDesc.val = IN_PD_ORGNOTISDN;
			break;
		case SNGISDN_PROGIND_DESCR_RET_ISDN:
			progInd->progDesc.val = IN_PD_CALLRET;
			break;
		case SNGISDN_PROGIND_DESCR_SERV_CHANGE:
			/* Trillium defines do not match ITU-T Q931 Progress descriptions,
			indicate a delayed response for now */
			progInd->progDesc.val = IN_PD_DELRESP;
			break;
		case SNGISDN_PROGIND_DESCR_IB_AVAIL:
			progInd->progDesc.val = IN_PD_IBAVAIL;
			break;
		default:
			ftdm_log(FTDM_LOG_WARNING, "Invalid prog_ind description:%d\n", descr);
			progInd->progDesc.val = IN_PD_NOTETEISDN;
			break;
	}

	progInd->location.pres = PRSNT_NODEF;
	switch (loc) {
		case SNGISDN_PROGIND_LOC_USER:
			progInd->location.val = IN_LOC_USER;
			break;
		case SNGISDN_PROGIND_LOC_PRIV_NET_LOCAL_USR:
			progInd->location.val = IN_LOC_PRIVNETLU;
			break;
		case SNGISDN_PROGIND_LOC_PUB_NET_LOCAL_USR:
			progInd->location.val = IN_LOC_PUBNETLU;
			break;
		case SNGISDN_PROGIND_LOC_TRANSIT_NET:
			progInd->location.val = IN_LOC_TRANNET;
			break;
		case SNGISDN_PROGIND_LOC_PUB_NET_REMOTE_USR:
			progInd->location.val = IN_LOC_PUBNETRU;
			break;
		case SNGISDN_PROGIND_LOC_PRIV_NET_REMOTE_USR:
			progInd->location.val = IN_LOC_PRIVNETRU;
			break;
		case SNGISDN_PROGIND_LOC_NET_BEYOND_INTRW:
			progInd->location.val = IN_LOC_NETINTER;
			break;
		default:
			ftdm_log(FTDM_LOG_WARNING, "Invalid prog_ind location:%d\n", loc);
			progInd->location.val = IN_LOC_USER;
	}
	return FTDM_SUCCESS;
}
コード例 #9
0
ftdm_status_t set_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb)
{
	const char* string = NULL;
	uint8_t len,val;
	ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
	
	string = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.cg_pty2.digits");
	if ((string == NULL) || !(*string)) {
		return FTDM_FAIL;
	}

	cgPtyNmb->eh.pres			= PRSNT_NODEF;
	
	len = strlen(string);
	cgPtyNmb->nmbDigits.len		= len;

	cgPtyNmb->nmbDigits.pres	= PRSNT_NODEF;
	memcpy(cgPtyNmb->nmbDigits.val, string, len);

	/* Screening Indicator */
	cgPtyNmb->screenInd.pres	= PRSNT_NODEF;

	val = FTDM_SCREENING_INVALID;
	string = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.cg_pty2.screening_ind");
	if (!ftdm_strlen_zero(string)) {
		val = ftdm_str2ftdm_screening(string);
	}

	/* isdn.cg_pty2.screen_ind does not exist or we could not parse its value */
	if (val == FTDM_SCREENING_INVALID) {		
		/* default to caller data screening ind */
		cgPtyNmb->screenInd.val = caller_data->screen;
	} else {
		cgPtyNmb->screenInd.val = val;
	}

	/* Presentation Indicator */
	cgPtyNmb->presInd0.pres = PRSNT_NODEF;
	
	val = FTDM_PRES_INVALID;
	string = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.cg_pty2.presentation_ind");
	if (!ftdm_strlen_zero(string)) {
		val = ftdm_str2ftdm_presentation(string);
	}

	if (val == FTDM_PRES_INVALID) {
		cgPtyNmb->presInd0.val = caller_data->pres;
	} else {
		cgPtyNmb->presInd0.val = val;
	}

	/* Numbering Plan Indicator */
	cgPtyNmb->nmbPlanId.pres	= PRSNT_NODEF;
	
	val = FTDM_NPI_INVALID;
	string = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.cg_pty2.npi");
	if (!ftdm_strlen_zero(string)) {
		val = ftdm_str2ftdm_npi(string);
	}

	if (val == FTDM_NPI_INVALID) {
		cgPtyNmb->nmbPlanId.val = caller_data->cid_num.plan;
	} else {
		cgPtyNmb->nmbPlanId.val = get_trillium_val(npi_codes, val, IN_NP_UNK);
	}

	cgPtyNmb->typeNmb1.pres		= PRSNT_NODEF;

	/* Type of Number */
	val = FTDM_TON_INVALID;
	string = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.cg_pty2.ton");
	if (!ftdm_strlen_zero(string)) {
		val = ftdm_str2ftdm_ton(string);
	}

	if (val == FTDM_TON_INVALID) {
		cgPtyNmb->typeNmb1.val = caller_data->cid_num.type;
	} else {
		cgPtyNmb->typeNmb1.val = get_trillium_val(ton_codes, val, IN_TON_UNK);
	}
	return FTDM_SUCCESS;
}