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; }
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; }
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; }
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; }
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; }