static void *run_main_schedule(ftdm_thread_t *thread, void *data) { int32_t timeto; int32_t sleepms; ftdm_status_t status; ftdm_sched_t *current = NULL; #ifdef __WINDOWS__ UNREFERENCED_PARAMETER(data); UNREFERENCED_PARAMETER(thread); #endif while (ftdm_running()) { sleepms = SCHED_MAX_SLEEP; ftdm_mutex_lock(sched_globals.mutex); if (!sched_globals.freeruns) { /* there are no free runs, wait a bit and check again (FIXME: use ftdm_interrupt_t for this) */ ftdm_mutex_unlock(sched_globals.mutex); if (ftdm_running()) { ftdm_sleep(sleepms); } } for (current = sched_globals.freeruns; current; current = current->next) { if (!ftdm_running()) { break; } /* first run the schedule */ ftdm_sched_run(current); /* now find out how much time to sleep until running them again */ status = ftdm_sched_get_time_to_next_timer(current, &timeto); if (status != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_WARNING, "Failed to get time to next timer for schedule %s, skipping\n", current->name); continue; } /* if timeto == -1 we don't want to sleep forever, so keep the last sleepms */ if (timeto != -1 && sleepms > timeto) { sleepms = timeto; } } ftdm_mutex_unlock(sched_globals.mutex); if (ftdm_running()) { ftdm_sleep(sleepms); } } ftdm_log(FTDM_LOG_NOTICE, "Main scheduling thread going out ...\n"); sched_globals.running = 0; return NULL; }
int main(int argc, char *argv[]) { ftdm_conf_parameter_t parameters[20]; ftdm_span_t *span; int local_port, remote_port; local_port = remote_port = 53000; ftdm_global_set_default_logger(FTDM_LOG_LEVEL_DEBUG); #if 0 if (argc < 2) { printf("invalid arguments\n"); exit(-1); } #endif if (ftdm_global_init() != FTDM_SUCCESS) { fprintf(stderr, "Error loading FreeTDM\n"); exit(-1); } if (ftdm_global_configuration() != FTDM_SUCCESS) { fprintf(stderr, "Error configuring FreeTDM\n"); exit(-1); } printf("FreeTDM loaded\n"); if (ftdm_span_find_by_name("wp1", &span) != FTDM_SUCCESS) { fprintf(stderr, "Error finding FreeTDM span %s\n", argv[1]); goto done; } parameters[0].var = "sigmod"; parameters[0].val = "sangoma_prid"; parameters[1].var = "switchtype"; parameters[1].val = "euroisdn"; parameters[1].var = "signalling"; parameters[1].val = "pri_cpe"; parameters[2].var = NULL; if (ftdm_configure_span_signaling("sangoma_boost", span, on_signal, parameters) == FTDM_SUCCESS) { ftdm_span_start(span); } else { fprintf(stderr, "Error starting SS7_BOOST\n"); goto done; } while(ftdm_running() && R) { ftdm_sleep(1 * 1000); } done: ftdm_global_destroy(); return 0; }
int main(int argc, char *argv[]) { ftdm_span_t *span; int span_id; int digit_timeout = 2000; int max_dialstr = 11; if (argc < 2) { printf("usage %s <spanno>\n", argv[0]); exit(-1); } span_id = atoi(argv[1]); ftdm_global_set_default_logger(FTDM_LOG_LEVEL_DEBUG); if (ftdm_global_init() != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_ERROR, "Error loading FreeTDM\n"); exit(-1); } ftdm_log(FTDM_LOG_DEBUG, "FreeTDM loaded\n"); if (ftdm_span_find(span_id, &span) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_ERROR, "Error finding FreeTDM span\n"); goto done; } if (ftdm_configure_span("analog", span, on_signal, "tonemap", "us", "digit_timeout", &digit_timeout, "max_dialstr", &max_dialstr, TAG_END ) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_ERROR, "Error configuring FreeTDM span\n"); goto done; } ftdm_span_start(span); R = 1; while(ftdm_running() && R) { ftdm_sleep(1 * 1000); } done: ftdm_global_destroy(); return 0; }
static void *ftdm_gsm_run(ftdm_thread_t *me, void *obj) { ftdm_log(FTDM_LOG_INFO,"ftdm_gsm_run\r\n"); ftdm_channel_t *ftdmchan = NULL; ftdm_span_t *span = (ftdm_span_t *) obj; ftdm_gsm_span_data_t *gsm_data = NULL; ftdm_interrupt_t *data_sources[2] = {NULL, NULL}; int waitms = 0; gsm_data = span->signal_data; ftdm_assert_return(gsm_data != NULL, NULL, "No gsm data attached to span\n"); ftdm_log(FTDM_LOG_DEBUG, "GSM monitor thread for span %s started\n", span->name); if (!gsm_data->dchan || ftdm_channel_open_chan(gsm_data->dchan) != FTDM_SUCCESS) { ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to open GSM d-channel of span %s!\n", span->name); gsm_data->dchan = NULL; goto done; } while (ftdm_running()) { wat_span_run(span->span_id); waitms = wat_span_schedule_next(span->span_id); if (waitms > GSM_POLL_INTERVAL_MS) { waitms = GSM_POLL_INTERVAL_MS; } ///////////////////// { ftdm_wait_flag_t flags = FTDM_READ | FTDM_EVENTS; ftdm_status_t status = ftdm_channel_wait(gsm_data->dchan, &flags, waitms); /* double check that this channel has a state change pending */ ftdm_channel_lock(gsm_data->bchan); ftdm_channel_advance_states(gsm_data->bchan); if(FTDM_SUCCESS == status ) { if(flags &FTDM_READ ) { char buffer[1025]; int n = 0, m = 0; memset(buffer, 0, sizeof(buffer)); n = read_channel(gsm_data->dchan, buffer, sizeof(buffer)-1); m = strlen(buffer); wat_span_process_read(span->span_id, buffer, m); #if LOG_SIG_DATA printf("<<======================= incomming data len = %d, %s\r\n", n, buffer); #endif } } ftdm_channel_advance_states(gsm_data->bchan); ftdm_channel_unlock(gsm_data->bchan); } ftdm_span_trigger_signals(span); } done: if (data_sources[0]) { ftdm_interrupt_destroy(&data_sources[0]); } ftdm_log(FTDM_LOG_DEBUG, "GSM thread ending.\n"); return NULL; }
static void *ftdm_pritap_run(ftdm_thread_t *me, void *obj) { ftdm_span_t *span = (ftdm_span_t *) obj; ftdm_span_t *peer = NULL; pritap_t *pritap = span->signal_data; pritap_t *p_pritap = NULL; pri_event *event = NULL; struct pollfd dpoll[2]; int rc = 0; ftdm_log(FTDM_LOG_DEBUG, "Tapping PRI thread started on span %s\n", span->name); pritap->span = span; ftdm_set_flag(span, FTDM_SPAN_IN_THREAD); if (ftdm_channel_open(span->span_id, pritap->dchan->chan_id, &pritap->dchan) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_ERROR, "Failed to open D-channel for span %s\n", span->name); goto done; } if ((pritap->pri = pri_new_cb(pritap->dchan->sockfd, PRI_NETWORK, PRI_SWITCH_NI2, pri_io_read, pri_io_write, pritap))) { pri_set_debug(pritap->pri, pritap->debug); } else { ftdm_log(FTDM_LOG_CRIT, "Failed to create tapping PRI\n"); goto done; } /* The last span starting runs the show ... * This simplifies locking and avoid races by having multiple threads for a single tapped link * Since both threads really handle a single tapped link there is no benefit on multi-threading, just complications ... */ peer = pritap->peerspan; p_pritap = peer->signal_data; if (!ftdm_test_flag(pritap, PRITAP_MASTER)) { ftdm_log(FTDM_LOG_DEBUG, "Running dummy thread on span %s\n", span->name); while (ftdm_running() && !ftdm_test_flag(span, FTDM_SPAN_STOP_THREAD)) { poll(NULL, 0, 100); } } else { memset(&dpoll, 0, sizeof(dpoll)); dpoll[0].fd = pritap->dchan->sockfd; dpoll[1].fd = p_pritap->dchan->sockfd; ftdm_log(FTDM_LOG_DEBUG, "Master tapping thread on span %s (fd1=%d, fd2=%d)\n", span->name, pritap->dchan->sockfd, p_pritap->dchan->sockfd); while (ftdm_running() && !ftdm_test_flag(span, FTDM_SPAN_STOP_THREAD)) { pritap_check_state(span); pritap_check_state(peer); dpoll[0].revents = 0; dpoll[0].events = POLLIN; dpoll[1].revents = 0; dpoll[1].events = POLLIN; rc = poll(&dpoll[0], 2, 10); if (rc < 0) { if (errno == EINTR) { ftdm_log(FTDM_LOG_DEBUG, "D-channel waiting interrupted, continuing ...\n"); continue; } ftdm_log(FTDM_LOG_ERROR, "poll failed: %s\n", strerror(errno)); continue; } pri_schedule_run(pritap->pri); pri_schedule_run(p_pritap->pri); pritap_check_state(span); pritap_check_state(peer); if (rc) { if (dpoll[0].revents & POLLIN) { event = pri_read_event(pritap->pri); if (event) { handle_pri_passive_event(pritap, event); pritap_check_state(span); } } if (dpoll[1].revents & POLLIN) { event = pri_read_event(p_pritap->pri); if (event) { handle_pri_passive_event(p_pritap, event); pritap_check_state(peer); } } } } } done: ftdm_log(FTDM_LOG_DEBUG, "Tapping PRI thread ended on span %s\n", span->name); ftdm_clear_flag(span, FTDM_SPAN_IN_THREAD); ftdm_clear_flag(pritap, PRITAP_RUNNING); ftdm_clear_flag(pritap, PRITAP_MASTER); return NULL; }