int main(int argc, char *argv[]) { int pair[2]; pthread_t tmp; struct pri *pri; pri_set_message(testmsg); pri_set_error(testerr); if (socketpair(AF_LOCAL, SOCK_DGRAM, 0, pair)) { perror("socketpair"); exit(1); } if (!(pri = pri_new(pair[0], PRI_NETWORK, PRI_DEF_SWITCHTYPE))) { perror("pri(0)"); exit(1); } first = pri; pri_set_debug(pri, DEBUG_LEVEL); if (pthread_create(&tmp, NULL, dchan, pri)) { perror("thread(0)"); exit(1); } if (!(pri = pri_new(pair[1], PRI_CPE, PRI_DEF_SWITCHTYPE))) { perror("pri(1)"); exit(1); } pri_set_debug(pri, DEBUG_LEVEL); if (pthread_create(&tmp, NULL, dchan, pri)) { perror("thread(1)"); exit(1); } /* Wait for things to run */ sleep(5); exit(0); }
int lpwrap_init_bri(struct lpwrap_pri *spri, ftdm_span_t *span, ftdm_channel_t *dchan, int swtype, int node, int ptp, int debug) { int ret = -1; #ifdef HAVE_LIBPRI_BRI memset(spri, 0, sizeof(struct lpwrap_pri)); spri->dchan = dchan; spri->span = span; if (!spri->dchan) { ftdm_log(FTDM_LOG_ERROR, "No D-Channel available, unable to create BRI\n"); return ret; } if ((spri->pri = pri_new_bri_cb(spri->dchan->sockfd, ptp, node, swtype, __pri_lpwrap_read, __pri_lpwrap_write, spri))) { unsigned char buf[4] = { 0 }; size_t buflen = sizeof(buf), len = 0; pri_set_debug(spri->pri, debug); #ifdef HAVE_LIBPRI_AOC pri_aoc_events_enable(spri->pri, 1); #endif ftdm_channel_write(spri->dchan, buf, buflen, &len); ret = 0; } else { ftdm_log(FTDM_LOG_ERROR, "Unable to create BRI\n"); } #else ftdm_log(FTDM_LOG_ERROR, "Installed libpri version (%s) has no BRI support\n", pri_get_version()); #endif return ret; }
void pri_set_debug(struct pri *pri, int debug) { if (!pri) return; pri->debug = debug; if (pri->subchannel) pri_set_debug(pri->subchannel, debug); }
int sangoma_init_pri(struct sangoma_pri *spri, int span, int dchan, int swtype, int node, int debug) { int ret = -1; ftdm_socket_t dfd = 0; memset(spri, 0, sizeof(struct sangoma_pri)); if (ftdm_channel_open(span, dchan, &spri->zdchan) != FTDM_SUCCESS) { fprintf(stderr, "Unable to open DCHAN %d for span %d (%s)\n", dchan, span, strerror(errno)); } else { if ((spri->pri = pri_new_cb(spri->zdchan->sockfd, node, swtype, __pri_sangoma_read, __pri_sangoma_write, spri))){ spri->span = span; pri_set_debug(spri->pri, debug); ret = 0; } else { fprintf(stderr, "Unable to create PRI\n"); } } return ret; }
int sangoma_init_pri(struct sangoma_pri *spri, int span, int dchan, int swtype, int node, int debug) { int ret = -1; sng_fd_t dfd = 0; memset(spri, 0, sizeof(struct sangoma_pri)); if((dfd = sangoma_open_tdmapi_span_chan(span, dchan)) < 0) { sbridge_log(SBRIDGE_LOG_ERROR, "Unable to open PRI DCHAN %d for span %d (%s)\n", dchan, span, sbridge_os_get_last_error()); } else { if ((spri->pri = pri_new_cb((int)dfd, node, swtype, __pri_sangoma_read, __pri_sangoma_write, NULL))){ spri->span = span; pri_set_debug(spri->pri, debug); sbridge_mutex_initialize(&spri->lock); ret = 0; } else { sbridge_log(SBRIDGE_LOG_ERROR, "Unable to create PRI for span %d\n", span); } } return ret; }
static FIO_API_FUNCTION(ftdm_pritap_api) { char *mycmd = NULL, *argv[10] = { 0 }; int argc = 0; if (data) { mycmd = ftdm_strdup(data); argc = ftdm_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); } if (argc > 2) { if (!strcasecmp(argv[0], "debug")) { ftdm_span_t *span = NULL; if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS) { pritap_t *pritap = span->signal_data; if (span->start != ftdm_pritap_start) { stream->write_function(stream, "%s: -ERR invalid span.\n", __FILE__); goto done; } pri_set_debug(pritap->pri, parse_debug(argv[2])); stream->write_function(stream, "%s: +OK debug set.\n", __FILE__); goto done; } else { stream->write_function(stream, "%s: -ERR invalid span.\n", __FILE__); goto done; } } } stream->write_function(stream, "%s: -ERR invalid command.\n", __FILE__); done: ftdm_safe_free(mycmd); return FTDM_SUCCESS; }
int lpwrap_init_pri(struct lpwrap_pri *spri, zap_span_t *span, zap_channel_t *dchan, int swtype, int node, int debug) { int ret = -1; memset(spri, 0, sizeof(struct lpwrap_pri)); spri->dchan = dchan; spri->span = span; if ((spri->pri = pri_new_cb(spri->dchan->sockfd, node, swtype, __pri_lpwrap_read, __pri_lpwrap_write, spri))){ unsigned char buf[4] = { 0 }; size_t buflen = sizeof(buf), len = 0; pri_set_debug(spri->pri, debug); ret = 0; zap_set_flag(spri, LPWRAP_PRI_READY); zap_channel_write(spri->dchan, buf, buflen, &len); } else { fprintf(stderr, "Unable to create PRI\n"); } return ret; }
struct pri *__pri_new_tei(int fd, int node, int switchtype, struct pri *master, pri_io_cb rd, pri_io_cb wr, void *userdata, int tei, int bri) { struct pri *p; if (!(p = calloc(1, sizeof(*p)))) return NULL; p->bri = bri; p->fd = fd; p->read_func = rd; p->write_func = wr; p->userdata = userdata; p->localtype = node; p->switchtype = switchtype; p->cref = 1; p->sapi = (tei == Q921_TEI_GROUP) ? Q921_SAPI_LAYER2_MANAGEMENT : Q921_SAPI_CALL_CTRL; p->tei = tei; p->nsf = PRI_NSF_NONE; p->protodisc = Q931_PROTOCOL_DISCRIMINATOR; p->master = master; p->callpool = &p->localpool; pri_default_timers(p, switchtype); if (master) { pri_set_debug(p, master->debug); if (master->sendfacility) pri_facility_enable(p); } #ifdef LIBPRI_COUNTERS p->q921_rxcount = 0; p->q921_txcount = 0; p->q931_rxcount = 0; p->q931_txcount = 0; #endif if (switchtype == PRI_SWITCH_GR303_EOC) { p->protodisc = GR303_PROTOCOL_DISCRIMINATOR; p->sapi = Q921_SAPI_GR303_EOC; p->tei = Q921_TEI_GR303_EOC_OPS; p->subchannel = __pri_new_tei(-1, node, PRI_SWITCH_GR303_EOC_PATH, p, NULL, NULL, NULL, Q921_TEI_GR303_EOC_PATH, 0); if (!p->subchannel) { free(p); p = NULL; } } else if (switchtype == PRI_SWITCH_GR303_TMC) { p->protodisc = GR303_PROTOCOL_DISCRIMINATOR; p->sapi = Q921_SAPI_GR303_TMC_CALLPROC; p->tei = Q921_TEI_GR303_TMC_CALLPROC; p->subchannel = __pri_new_tei(-1, node, PRI_SWITCH_GR303_TMC_SWITCHING, p, NULL, NULL, NULL, Q921_TEI_GR303_TMC_SWITCHING, 0); if (!p->subchannel) { free(p); p = NULL; } } else if (switchtype == PRI_SWITCH_GR303_TMC_SWITCHING) { p->protodisc = GR303_PROTOCOL_DISCRIMINATOR; p->sapi = Q921_SAPI_GR303_TMC_SWITCHING; p->tei = Q921_TEI_GR303_TMC_SWITCHING; } else if (switchtype == PRI_SWITCH_GR303_EOC_PATH) { p->protodisc = GR303_PROTOCOL_DISCRIMINATOR; p->sapi = Q921_SAPI_GR303_EOC; p->tei = Q921_TEI_GR303_EOC_PATH; } /* Start Q.921 layer, Wait if we're the network */ if (p) q921_start(p, p->localtype == PRI_CPE); return p; }
static int run_pri(int dfd, int swtype, int node) { struct pri *pri; pri_event *e; struct timeval tv = {0,0}, *next; fd_set rfds, efds; int res,x; pri = pri_new_bri(dfd, 1, node, swtype); if (!pri) { fprintf(stderr, "Unable to create PRI\n"); return -1; } pri_set_debug(pri, -1); for (;;) { /* Run the D-Channel */ FD_ZERO(&rfds); FD_ZERO(&efds); FD_SET(dfd, &rfds); FD_SET(dfd, &efds); if ((next = pri_schedule_next(pri))) { gettimeofday(&tv, NULL); tv.tv_sec = next->tv_sec - tv.tv_sec; tv.tv_usec = next->tv_usec - tv.tv_usec; if (tv.tv_usec < 0) { tv.tv_usec += 1000000; tv.tv_sec -= 1; } if (tv.tv_sec < 0) { tv.tv_sec = 0; tv.tv_usec = 0; } } res = select(dfd + 1, &rfds, NULL, &efds, next ? &tv : NULL); e = NULL; if (!res) { e = pri_schedule_run(pri); } else if (res > 0) { e = pri_check_event(pri); } else if (errno == ELAST) { res = ioctl(dfd, ZT_GETEVENT, &x); printf("Got Zaptel event: %d\n", x); } else if (errno != EINTR) fprintf(stderr, "Error (%d) on select: %s\n", ELAST, strerror(errno)); if (e) { handle_pri_event(pri, e); } res = ioctl(dfd, ZT_GETEVENT, &x); if (!res && x) { fprintf(stderr, "Got event on PRI interface: %d\n", x); } /* Check for lines that need hangups */ for (x=0;x<MAX_CHAN;x++) if (chans[x].needhangup) { chans[x].needhangup = 0; pri_release(pri, chans[x].call, PRI_CAUSE_NORMAL_CLEARING); } } return 0; }
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; }