Ejemplo n.º 1
0
static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_gsm_configure_span_signaling)
{
	wat_span_config_t span_config;
	ftdm_gsm_span_data_t *gsm_data = NULL;
	ftdm_iterator_t *chaniter = NULL;
	ftdm_iterator_t *citer = NULL;
	ftdm_channel_t *ftdmchan = NULL;
	ftdm_channel_t *dchan = NULL;
	ftdm_channel_t *bchan = NULL;

	unsigned paramindex = 0;
	const char *var = NULL;
	const char *val = NULL;
	
	/* libwat is smart enough to set good default values for the timers if they are set to 0 */
	memset(&span_config, 0, sizeof(span_config));
	
	/* set some span defaults */
	span_config.moduletype = WAT_MODULE_TELIT;

	if (FTDM_SUCCESS != init_wat_lib()) {
		return FTDM_FAIL;
	}

	if (!sig_cb) {
		ftdm_log(FTDM_LOG_ERROR, "No signaling callback provided\n");
		return FTDM_FAIL;
	}

	if (span->signal_type) {
		ftdm_log(FTDM_LOG_ERROR, "Span %s is already configured for another signaling\n", span->name);
		return FTDM_FAIL;
	}

	/* verify the span has one d-channel */
	chaniter = ftdm_span_get_chan_iterator(span, NULL);
	
	if (!chaniter) {
		ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name);
		return FTDM_FAIL;
	}

	citer = ftdm_span_get_chan_iterator(span, chaniter);
	for ( ; citer; citer = ftdm_iterator_next(citer)) {
		ftdmchan = ftdm_iterator_current(citer);
		
		if ((NULL == dchan) && FTDM_IS_DCHAN(ftdmchan)) {
			dchan = ftdmchan;
		}
		if ((NULL == bchan) && FTDM_IS_VOICE_CHANNEL(ftdmchan)) {
			bchan = ftdmchan;
		}

	}
	ftdm_iterator_free(chaniter);

	if (!dchan) {
		ftdm_log(FTDM_LOG_CRIT, "Could not find a d-channel for GSM span %s!\n", span->name);
		return FTDM_FAIL;
	}
	if (!bchan) {
		ftdm_log(FTDM_LOG_CRIT, "Could not find a b-channel for GSM span %s!\n", span->name);
		return FTDM_FAIL;
	}





	gsm_data = ftdm_calloc(1, sizeof(*gsm_data));
	if (!gsm_data) {
		return FTDM_FAIL;
	}
	gsm_data->dchan = dchan;
	gsm_data->bchan = bchan;

	//sprintf(gsm_data->dchan->chan_name, "%s\t\n", "GSM dchan");
	//sprintf(gsm_data->bchan->chan_name, "%s\r\n", "GSM bchan");

	for (paramindex = 0; ftdm_parameters[paramindex].var; paramindex++) {
		var = ftdm_parameters[paramindex].var;
		val = ftdm_parameters[paramindex].val;
		if (!ftdm_strlen_zero_buf(val)) {
			ftdm_log(FTDM_LOG_WARNING, "Ignoring empty GSM parameter %s for span %s\n", var, span->name);
			continue;
		}
		ftdm_log(FTDM_LOG_DEBUG, "Reading GSM parameter %s=%s for span %s\n", var, val, span->name);
		if (!strcasecmp(var, "moduletype")) {
			span_config.moduletype = wat_str2wat_moduletype(val);
			if (span_config.moduletype == WAT_MODULE_INVALID) {
				ftdm_log(FTDM_LOG_DEBUG, "Unknown GSM module type %s for span %s\n", val, span->name);
				continue;
			}
			ftdm_log(FTDM_LOG_DEBUG, "Configuring GSM span %s with moduletype %s\n", span->name, val);
		} else {
			ftdm_log(FTDM_LOG_ERROR, "Ignoring unknown GSM parameter '%s'", var);
		}
	}

	/* Bind function pointers for control operations */
	span->start = ftdm_gsm_start;
	span->stop = ftdm_gsm_stop;
	span->sig_read = NULL;
	span->sig_write = NULL;

	span->signal_cb = sig_cb;
	span->signal_type = FTDM_SIGTYPE_GSM;
	span->signal_data = gsm_data; /* Gideon, plz fill me with gsm span specific data (you allocate and free) */
	span->outgoing_call = gsm_outgoing_call;
	span->get_span_sig_status = ftdm_gsm_get_span_sig_status;
	span->set_span_sig_status = ftdm_gsm_set_span_sig_status;
	span->get_channel_sig_status = ftdm_gsm_get_channel_sig_status;
	span->set_channel_sig_status = ftdm_gsm_set_channel_sig_status;

	//printf("\r\nspan->state_map = &gsm_state_map;\r\n");
	span->state_map = &gsm_state_map;
	span->state_processor = ftdm_gsm_state_advance;

	/* use signals queue */
	ftdm_set_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE);
	ftdm_set_flag(span, FTDM_SPAN_USE_CHAN_QUEUE);

	/* we can skip states (going straight from RING to UP) */
	ftdm_set_flag(span, FTDM_SPAN_USE_SKIP_STATES);

	gsm_data->span = span;

#if 0
	/* setup the scheduler (create if needed) */
	snprintf(schedname, sizeof(schedname), "ftmod_r2_%s", span->name);
	ftdm_assert(ftdm_sched_create(&r2data->sched, schedname) == FTDM_SUCCESS, "Failed to create schedule!\n");
	spanpvt->sched = r2data->sched;
#endif

	
fprintf(stdout, "Configuring wat span %d %s \r\n", span->span_id, span->name);
	if (wat_span_config(span->span_id, &span_config)) {
		ftdm_log(FTDM_LOG_ERROR, "Failed to configure span %s for GSM signaling!!\n", span->name);
		return FTDM_FAIL;
	}

	{
		int codec		= FTDM_CODEC_SLIN;
		int interval	= 20;
		
		ftdm_channel_command(gsm_data->bchan, FTDM_COMMAND_SET_NATIVE_CODEC,  &codec);
		ftdm_channel_command(gsm_data->bchan, FTDM_COMMAND_SET_CODEC,  &codec);
		ftdm_channel_command(gsm_data->bchan, FTDM_COMMAND_SET_INTERVAL,  &interval);
	}

	return FTDM_SUCCESS;

}
Ejemplo n.º 2
0
static ftdm_status_t ftdm_pritap_sig_read(ftdm_channel_t *ftdmchan, void *data, ftdm_size_t size)
{
    ftdm_status_t status;
    fio_codec_t codec_func;
    ftdm_channel_t *peerchan = ftdmchan->call_data;
    pritap_t *pritap = ftdmchan->span->signal_data;
    int16_t chanbuf[size];
    int16_t peerbuf[size];
    int16_t mixedbuf[size];
    int i = 0;
    ftdm_size_t sizeread = size;

    if (!FTDM_IS_VOICE_CHANNEL(ftdmchan) || !ftdmchan->call_data) {
        return FTDM_SUCCESS;
    }

    if (pritap->mixaudio == PRITAP_MIX_SELF) {
        return FTDM_SUCCESS;
    }

    if (pritap->mixaudio == PRITAP_MIX_PEER) {
        /* start out by clearing the self audio to make sure we don't return audio we were
         * not supposed to in an error condition  */
        memset(data, FTDM_SILENCE_VALUE(ftdmchan), size);
    }

    if (ftdmchan->native_codec != peerchan->native_codec) {
        ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Invalid peer channel with format %d, ours = %d\n",
                      peerchan->native_codec, ftdmchan->native_codec);
        return FTDM_FAIL;
    }

    memcpy(chanbuf, data, size);
    status = peerchan->fio->read(peerchan, peerbuf, &sizeread);
    if (status != FTDM_SUCCESS) {
        ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to read from peer channel!\n");
        return FTDM_FAIL;
    }
    if (sizeread != size) {
        ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "read from peer channel only %"FTDM_SIZE_FMT" bytes!\n", sizeread);
        return FTDM_FAIL;
    }

    if (pritap->mixaudio == PRITAP_MIX_PEER) {
        /* only the peer audio is requested */
        memcpy(data, peerbuf, size);
        return FTDM_SUCCESS;
    }

    codec_func = peerchan->native_codec == FTDM_CODEC_ULAW ? fio_ulaw2slin : peerchan->native_codec == FTDM_CODEC_ALAW ? fio_alaw2slin : NULL;
    if (codec_func) {
        sizeread = size;
        codec_func(chanbuf, sizeof(chanbuf), &sizeread);
        sizeread = size;
        codec_func(peerbuf, sizeof(peerbuf), &sizeread);
    }

    for (i = 0; i < size; i++) {
        mixedbuf[i] = ftdm_saturated_add(chanbuf[i], peerbuf[i]);
    }

    codec_func = peerchan->native_codec == FTDM_CODEC_ULAW ? fio_slin2ulaw : peerchan->native_codec == FTDM_CODEC_ALAW ? fio_slin2alaw : NULL;
    if (codec_func) {
        size = sizeof(mixedbuf);
        codec_func(mixedbuf, size, &size);
    }
    memcpy(data, mixedbuf, size);
    return FTDM_SUCCESS;
}