Exemple #1
0
FT_DECLARE(ftdm_status_t) ftdm_conf_node_create(const char *name, ftdm_conf_node_t **node, ftdm_conf_node_t *parent)
{
	ftdm_conf_node_t *newnode;
	ftdm_conf_node_t *sibling = NULL;

	ftdm_assert_return(name != NULL, FTDM_FAIL, "null node name");

	newnode = ftdm_calloc(1, sizeof(**node));
	if (!newnode) {
		return FTDM_MEMERR;
	}

	strncpy(newnode->name, name, sizeof(newnode->name)-1);	
	newnode->name[sizeof(newnode->name)-1] = 0;

	newnode->parameters = ftdm_calloc(PARAMETERS_CHUNK_SIZE, sizeof(*newnode->parameters));
	if (!newnode->parameters) {
		ftdm_safe_free(newnode);
		return FTDM_MEMERR;
	}
	newnode->t_parameters = PARAMETERS_CHUNK_SIZE;

	if (parent) {
		/* store who my parent is */
		newnode->parent = parent;

		/* arrange them in FIFO order (newnode should be last) */
		if (!parent->child) {
			/* we're the first node being added */
			parent->child = newnode;
		} else {
			if (!parent->last) {
				/* we're the second node being added */
				parent->last = newnode;
				parent->child->next = newnode;
				newnode->prev = parent->child;
			} else {
				/* we're the third or Nth node to be added */
				sibling = parent->last;
				sibling->next = newnode;
				parent->last = newnode;
				newnode->prev = sibling;
			}
		}
	}

	*node = newnode;

	return FTDM_SUCCESS;
}
void sngisdn_trace_interpreted_q931(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len)
{
    char *data_str = ftdm_calloc(1,MAX_DECODE_STR_LEN); /* TODO Find a proper size */
    sngisdn_decode_q931(data_str, data, data_len);
    ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q931] %s FRAME %s:%s\n", signal_data->ftdm_span->name, ftdm_trace_dir2str(dir), data_str);
    ftdm_safe_free(data_str);
}
ftdm_status_t sngisdn_add_raw_data(sngisdn_chan_data_t *sngisdn_info, uint8_t* data, ftdm_size_t data_len)
{
	ftdm_assert_return(!sngisdn_info->raw_data, FTDM_FAIL, "Overwriting existing raw data\n");
	
	sngisdn_info->raw_data = ftdm_calloc(1, data_len);
	ftdm_assert_return(sngisdn_info->raw_data, FTDM_FAIL, "Failed to allocate raw data\n");

	memcpy(sngisdn_info->raw_data, data, data_len);
	sngisdn_info->raw_data_len = data_len;
	return FTDM_SUCCESS;
}
Exemple #4
0
FT_DECLARE(ftdm_status_t) ftdm_interrupt_create(ftdm_interrupt_t **ininterrupt, ftdm_socket_t device)
{
	ftdm_interrupt_t *interrupt = NULL;
#ifndef WIN32
	int fds[2];
#endif

	ftdm_assert_return(ininterrupt != NULL, FTDM_FAIL, "interrupt double pointer is null!\n");

	interrupt = ftdm_calloc(1, sizeof(*interrupt));
	if (!interrupt) {
		ftdm_log(FTDM_LOG_ERROR, "Failed to allocate interrupt memory\n");
		return FTDM_FAIL;
	}

	interrupt->device = device;
#ifdef WIN32
	interrupt->event = CreateEvent(NULL, FALSE, FALSE, NULL);
	if (!interrupt->event) {
		ftdm_log(FTDM_LOG_ERROR, "Failed to allocate interrupt event\n");
		goto failed;
	}
#else
	if (pipe(fds)) {
		ftdm_log(FTDM_LOG_ERROR, "Failed to allocate interrupt pipe: %s\n", strerror(errno));
		goto failed;
	}
	interrupt->readfd = fds[0];
	interrupt->writefd = fds[1];
#endif

	*ininterrupt = interrupt;
	return FTDM_SUCCESS;

failed:
	if (interrupt) {
#ifndef WIN32
		if (interrupt->readfd) {
			close(interrupt->readfd);
			close(interrupt->writefd);
			interrupt->readfd = -1;
			interrupt->writefd = -1;
		}
#endif
		ftdm_safe_free(interrupt);
	}
	return FTDM_FAIL;
}
FT_DECLARE(ftdm_status_t) ftdm_sched_create(ftdm_sched_t **sched, const char *name)
{
	ftdm_sched_t *newsched = NULL;

	ftdm_assert_return(sched != NULL, FTDM_EINVAL, "invalid pointer\n");
	ftdm_assert_return(name != NULL, FTDM_EINVAL, "invalid sched name\n");

	*sched = NULL;

	newsched = ftdm_calloc(1, sizeof(*newsched));
	if (!newsched) {
		return FTDM_MEMERR;
	}

	if (ftdm_mutex_create(&newsched->mutex) != FTDM_SUCCESS) {
		goto failed;
	}

	ftdm_set_string(newsched->name, name);
	newsched->currid = 1;

	*sched = newsched;
	ftdm_log(FTDM_LOG_DEBUG, "Created schedule %s\n", name);
	return FTDM_SUCCESS;

failed:
	ftdm_log(FTDM_LOG_CRIT, "Failed to create schedule\n");

	if (newsched) {
		if (newsched->mutex) {
			ftdm_mutex_destroy(&newsched->mutex);
		}
		ftdm_safe_free(newsched);
	}
	return FTDM_FAIL;
}
Exemple #6
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;

}
Exemple #7
0
void *on_wat_calloc(size_t nmemb, size_t size)
{
	return ftdm_calloc(nmemb, size);
}	
FT_DECLARE(ftdm_status_t) ftdm_sched_timer(ftdm_sched_t *sched, const char *name, 
		int ms, ftdm_sched_callback_t callback, void *data, ftdm_timer_id_t *timerid)
{
	ftdm_status_t status = FTDM_FAIL;
	struct timeval now;
	int rc = 0;
	ftdm_timer_t *newtimer;

	ftdm_assert_return(sched != NULL, FTDM_EINVAL, "sched is null!\n");
	ftdm_assert_return(name != NULL, FTDM_EINVAL, "timer name is null!\n");
	ftdm_assert_return(callback != NULL, FTDM_EINVAL, "sched callback is null!\n");
	ftdm_assert_return(ms > 0, FTDM_EINVAL, "milliseconds must be bigger than 0!\n");

	if (timerid) {
		*timerid = 0;
	}

	rc = gettimeofday(&now, NULL);
	if (rc == -1) {
		ftdm_log(FTDM_LOG_ERROR, "Failed to retrieve time of day\n");
		return FTDM_FAIL;
	}

	ftdm_mutex_lock(sched->mutex);

	newtimer = ftdm_calloc(1, sizeof(*newtimer));
	if (!newtimer) {
		goto done;
	}
	newtimer->id = sched->currid;
	sched->currid++;
	if (!sched->currid) {
		ftdm_log(FTDM_LOG_NOTICE, "Timer id wrap around for sched %s\n", sched->name);
		/* we do not want currid to be zero since is an invalid id 
		 * TODO: check that currid does not exists already in the context, it'd be insane
		 * though, having a timer to live all that time */
		sched->currid++;
	}

	ftdm_set_string(newtimer->name, name);
	newtimer->callback = callback;
	newtimer->usrdata = data;

	newtimer->time.tv_sec = now.tv_sec + (ms / 1000);
	newtimer->time.tv_usec = now.tv_usec + (ms % 1000) * 1000;
	if (newtimer->time.tv_usec >= FTDM_MICROSECONDS_PER_SECOND) {
		newtimer->time.tv_sec += 1;
		newtimer->time.tv_usec -= FTDM_MICROSECONDS_PER_SECOND;
	}

	if (!sched->timers) {
		sched->timers = newtimer;
	}  else {
		newtimer->next = sched->timers;
		sched->timers->prev = newtimer;
		sched->timers = newtimer;
	}

	if (timerid) {
		*timerid = newtimer->id;
	}

	status = FTDM_SUCCESS;
done:

	ftdm_mutex_unlock(sched->mutex);
#ifdef __WINDOWS__
	UNREFERENCED_PARAMETER(sched);
	UNREFERENCED_PARAMETER(name);
	UNREFERENCED_PARAMETER(ms);
	UNREFERENCED_PARAMETER(callback);
	UNREFERENCED_PARAMETER(data);
	UNREFERENCED_PARAMETER(timerid);
#endif
	return status;
}
Exemple #9
0
static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_pritap_configure_span)
{
    uint32_t i;
    const char *var, *val;
    const char *debug = NULL;
    pritap_mix_mode_t mixaudio = PRITAP_MIX_BOTH;
    ftdm_channel_t *dchan = NULL;
    pritap_t *pritap = NULL;
    ftdm_span_t *peerspan = NULL;
    pritap_iface_t iface = PRITAP_IFACE_UNKNOWN;
    unsigned paramindex = 0;

    if (span->trunk_type >= FTDM_TRUNK_NONE) {
        ftdm_log(FTDM_LOG_WARNING, "Invalid trunk type '%s' defaulting to T1.\n", ftdm_trunk_type2str(span->trunk_type));
        span->trunk_type = FTDM_TRUNK_T1;
    }

    for (i = 1; i <= span->chan_count; i++) {
        if (span->channels[i]->type == FTDM_CHAN_TYPE_DQ921) {
            dchan = span->channels[i];
        }
    }

    if (!dchan) {
        ftdm_log(FTDM_LOG_ERROR, "No d-channel specified in freetdm.conf!\n");
        return FTDM_FAIL;
    }

    for (paramindex = 0; ftdm_parameters[paramindex].var; paramindex++) {
        var = ftdm_parameters[paramindex].var;
        val = ftdm_parameters[paramindex].val;
        ftdm_log(FTDM_LOG_DEBUG, "Tapping PRI key=value, %s=%s\n", var, val);

        if (!strcasecmp(var, "debug")) {
            debug = val;
        } else if (!strcasecmp(var, "mixaudio")) {
            if (ftdm_true(val) || !strcasecmp(val, "both")) {
                ftdm_log(FTDM_LOG_DEBUG, "Setting mix audio mode to 'both' for span %s\n", span->name);
                mixaudio = PRITAP_MIX_BOTH;
            } else if (!strcasecmp(val, "peer")) {
                ftdm_log(FTDM_LOG_DEBUG, "Setting mix audio mode to 'peer' for span %s\n", span->name);
                mixaudio = PRITAP_MIX_PEER;
            } else {
                ftdm_log(FTDM_LOG_DEBUG, "Setting mix audio mode to 'self' for span %s\n", span->name);
                mixaudio = PRITAP_MIX_SELF;
            }
        } else if (!strcasecmp(var, "interface")) {
            if (!strcasecmp(val, "cpe")) {
                iface = PRITAP_IFACE_CPE;
            } else if (!strcasecmp(val, "net")) {
                iface = PRITAP_IFACE_NET;
            } else {
                ftdm_log(FTDM_LOG_WARNING, "Ignoring invalid tapping interface type %s\n", val);
            }
        } else if (!strcasecmp(var, "peerspan")) {
            if (ftdm_span_find_by_name(val, &peerspan) != FTDM_SUCCESS) {
                ftdm_log(FTDM_LOG_ERROR, "Invalid tapping peer span %s\n", val);
                break;
            }
        } else {
            ftdm_log(FTDM_LOG_ERROR,  "Unknown pri tapping parameter [%s]", var);
        }
    }

    if (!peerspan) {
        ftdm_log(FTDM_LOG_ERROR, "No valid peerspan was specified!\n");
        return FTDM_FAIL;
    }

    pritap = ftdm_calloc(1, sizeof(*pritap));
    if (!pritap) {
        return FTDM_FAIL;
    }

    pritap->debug = parse_debug(debug);
    pritap->dchan = dchan;
    pritap->peerspan = peerspan;
    pritap->mixaudio = mixaudio;
    pritap->iface = iface;

    span->start = ftdm_pritap_start;
    span->stop = ftdm_pritap_stop;
    span->sig_read = ftdm_pritap_sig_read;
    span->signal_cb = sig_cb;

    span->signal_data = pritap;
    span->signal_type = FTDM_SIGTYPE_ISDN;
    span->outgoing_call = pritap_outgoing_call;

    span->get_channel_sig_status = pritap_get_channel_sig_status;
    span->get_span_sig_status = pritap_get_span_sig_status;

    span->state_map = &pritap_state_map;
    span->state_processor = state_advance;

    return FTDM_SUCCESS;
}