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;
}
Exemple #3
0
void pri_set_debug(struct pri *pri, int debug)
{
	if (!pri)
		return;
	pri->debug = debug;
	if (pri->subchannel)
		pri_set_debug(pri->subchannel, debug);
}
Exemple #4
0
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;
}
Exemple #5
0
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;
}
Exemple #6
0
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;
}
Exemple #7
0
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;
}
Exemple #8
0
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;
}
Exemple #9
0
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;
}
Exemple #10
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;
}