int main(int argc, char *argv[]) { ftdm_status_t status; custom_data_t data; ftdm_sched_t *sched; signal(SIGINT, trap); ftdm_global_set_default_logger(FTDM_LOG_LEVEL_DEBUG); ftdm_cpu_monitor_disable(); if (ftdm_global_init() != FTDM_SUCCESS) { fprintf(stderr, "Error loading FreeTDM\n"); exit(-1); } status = ftdm_sched_create(&sched, "testsched"); if (status != FTDM_SUCCESS) { fprintf(stderr, "Error creating sched\n"); exit(-1); } data.sched = sched; data.counter = 10; data.beat = 5000; data.callback = handle_heartbeat; status = ftdm_sched_timer(sched, "heartbeat", data.beat, data.callback, &data, &data.heartbeat_timer); if (status != FTDM_SUCCESS) { fprintf(stderr, "Error creating heartbeat timer\n"); exit(-1); } ftdm_sched_free_run(sched); while (running) { ftdm_sleep(10); } ftdm_global_destroy(); printf("Done, press any key to die!\n"); getchar(); return 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; }