Change in osmo-e1d[master]: add e1-prbs-test

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

laforge gerrit-no-reply at lists.osmocom.org
Sat Jan 4 21:08:57 UTC 2020


laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-e1d/+/16735 )


Change subject: add e1-prbs-test
......................................................................

add e1-prbs-test

Change-Id: Ib25d266e61e0d70919cc4e65d5b1bf0bc9ec7d00
---
A contrib/e1-prbs-test/Makefile
A contrib/e1-prbs-test/README
A contrib/e1-prbs-test/internal.h
A contrib/e1-prbs-test/prbs.c
A contrib/e1-prbs-test/rx.c
A contrib/e1-prbs-test/tx.c
A contrib/e1-prbs-test/utils.c
7 files changed, 668 insertions(+), 0 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-e1d refs/changes/35/16735/1

diff --git a/contrib/e1-prbs-test/Makefile b/contrib/e1-prbs-test/Makefile
new file mode 100644
index 0000000..e692880
--- /dev/null
+++ b/contrib/e1-prbs-test/Makefile
@@ -0,0 +1,19 @@
+LIBOSMO_CFLAGS:=$(shell pkg-config --cflags libosmocore)
+LIBOSMO_LIBS:=$(shell pkg-config --libs libosmocore)
+
+CFLAGS=-O2 -g -Wall -Werror $(LIBOSMO_CFLAGS)
+LIBS=$(LIBOSMO_LIBS)
+
+all: e1-prbs-test-tx e1-prbs-test-rx
+
+e1-prbs-test-tx: tx.o prbs.o utils.o
+	$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
+
+e1-prbs-test-rx: rx.o prbs.o utils.o
+	$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
+
+%.o: %.c
+	$(CC) $(CFLAGS) -o $@ -c $^
+
+clean:
+	@rm -f e1-prbs-test-tx e1-prbs-test-rx *.o
diff --git a/contrib/e1-prbs-test/README b/contrib/e1-prbs-test/README
new file mode 100644
index 0000000..c2f78df
--- /dev/null
+++ b/contrib/e1-prbs-test/README
@@ -0,0 +1,32 @@
+e1-prbs-test - Utility to test for bit errors on E1 lines using DAHDI
+======================================================================
+
+e1-prbs-test can be used to test for bit errors in E1 transmission
+lines. It consists of a sender (e1-prbs-test-tx) and a receiver
+(e1-prbs-test-rx), which should be used on either end of the E1 line.
+
+Transmitter and receiver can be on the same machine, or on different
+machines.
+
+The code currently works directly on DAHDI, so only DAHDI-supported E1
+cards are supported at this point.
+
+The test works by sending timeslot-specific PRBS sequences of 512 bit
+(64byte) length on the transmit side, and by correlating to those PRBS
+sequences on the receiver side.
+
+The use is relatively simple:
+
+For the transmit side, assuming you would want to use DAHDI span 1:
+  e1-prbs-test-tx /dev/dahdi/chan/001
+
+For the transmit side, assuming you would want to use DAHDI span 2:
+  e1-prbs-test-rx /dev/dahdi/chan/002
+
+The test will run indefinitely.
+
+If you'd like to get an interim report, send a SIGHUP to
+e1-prbs-test-rx.  If you'd like to stop, simply press ctrl+c on
+e1-prbs-test-rx.  Make sure you terminate e1-prbs-test-rx first.  If you
+terminate e1-prbs-test-tx before e1-prbs-test-rx, it will negatively
+affect your test results.
diff --git a/contrib/e1-prbs-test/internal.h b/contrib/e1-prbs-test/internal.h
new file mode 100644
index 0000000..b3f1874
--- /dev/null
+++ b/contrib/e1-prbs-test/internal.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#define PRBS_LEN	512
+
+struct prbs_precomp {
+	uint8_t bytes[PRBS_LEN/8];
+};
+
+/* prbs.c */
+#include <osmocom/core/prbs.h>
+void prbs_for_ts_nr(struct osmo_prbs *prbs, uint8_t ts_nr);
+
+void prbs_precomp(struct prbs_precomp *out, const struct osmo_prbs *prbs);
+
+/* utils.c */
+uint8_t bits_set_in_byte(uint8_t byte);
+void cfg_dahdi_buffer(int fd);
+void set_realtime(int rt_prio);
diff --git a/contrib/e1-prbs-test/prbs.c b/contrib/e1-prbs-test/prbs.c
new file mode 100644
index 0000000..1a2c3d3
--- /dev/null
+++ b/contrib/e1-prbs-test/prbs.c
@@ -0,0 +1,103 @@
+/* (C) 2019 by Harald Welte <laforge at gnumonks.org>
+ * All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdint.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/core/prbs.h>
+
+#include "internal.h"
+
+/* according to https://users.ece.cmu.edu/~koopman/lfsr/index.html all below
+ * coefficients should render maximal length LFSRs of 9bit (512) length */
+
+const uint32_t  prbs9_coeff[] = {
+	0x108,
+	0x10D,
+	0x110,
+	0x116,
+	0x119,
+	0x12C,
+	0x12F,
+	0x134,
+	0x137,
+	0x13B,
+	0x13E,
+	0x143,
+	0x14A,
+	0x151,
+	0x152,
+	0x157,
+	0x15B,
+	0x15E,
+	0x167,
+	0x168,
+	0x16D,
+	0x17A,
+	0x17C,
+	0x189,
+	0x18A,
+	0x18F,
+	0x191,
+	0x198,
+	0x19D,
+	0x1A7,
+	0x1AD,
+	0x1B0,
+	0x1B5,
+	0x1B6,
+	0x1B9,
+	0x1BF,
+	0x1C2,
+	0x1C7,
+	0x1DA,
+	0x1DC,
+	0x1E3,
+	0x1E5,
+	0x1E6,
+	0x1EA,
+	0x1EC,
+	0x1F1,
+	0x1F4,
+	0x1FD
+};
+
+/* build the PRBS description for a given timeslot number */
+void prbs_for_ts_nr(struct osmo_prbs *prbs, uint8_t ts_nr)
+{
+	OSMO_ASSERT(ts_nr < ARRAY_SIZE(prbs9_coeff));
+
+	prbs->name = "custom";
+	prbs->len = 9;
+	prbs->coeff = prbs9_coeff[ts_nr];
+}
+
+/* compute one full sequence of the given PRBS */
+void prbs_precomp(struct prbs_precomp *out, const struct osmo_prbs *prbs)
+{
+	struct osmo_prbs_state prbs_s;
+	int i;
+
+	osmo_prbs_state_init(&prbs_s, prbs);
+	for (i = 0; i < sizeof(out->bytes); i++) {
+		ubit_t ubit[8];
+		osmo_prbs_get_ubits(ubit, sizeof(ubit), &prbs_s);
+		osmo_ubit2pbit(&out->bytes[i], ubit, sizeof(ubit));
+	}
+}
diff --git a/contrib/e1-prbs-test/rx.c b/contrib/e1-prbs-test/rx.c
new file mode 100644
index 0000000..29fbcbe
--- /dev/null
+++ b/contrib/e1-prbs-test/rx.c
@@ -0,0 +1,261 @@
+/* (C) 2019 by Harald Welte <laforge at gnumonks.org>
+ * All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#define _GNU_SOURCE
+#include <string.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <time.h>
+#include <signal.h>
+#include <dahdi/user.h>
+
+#include <osmocom/core/select.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/core/bits.h>
+#include <osmocom/core/prbs.h>
+
+#include "internal.h"
+
+#define MAX_NR_TS 31
+
+struct timeslot_state {
+	struct osmo_fd ofd;
+	struct osmo_prbs prbs;			/* PRBS definition */
+	struct prbs_precomp prbs_pc[8];		/* bit-shifted pre-computed PRBS sequences */
+	struct {
+		bool has_sync;			/* do we have a PRBS sync? */
+		struct timespec ts_sync;	/* time at which sync was established */
+		unsigned int prbs_pc_num;	/* index to prbs_pc[] array */
+		unsigned int prbs_pc_offset;	/* offset of next byte into prbs_pc[pc_num].bytes[] */
+
+		unsigned int num_bit_err;	/* bit errors since last sync */
+		unsigned int num_sync_loss;	/* number of sync losses since start */
+	} sync_state;
+};
+
+struct test_state {
+	struct timeslot_state ts[MAX_NR_TS];
+	unsigned int next_unused_ts;
+};
+static struct test_state g_tst;
+
+static uint8_t next_prbs_pc_byte(struct timeslot_state *ts)
+{
+	const struct prbs_precomp *pc = &ts->prbs_pc[ts->sync_state.prbs_pc_num];
+	uint8_t ret = pc->bytes[ts->sync_state.prbs_pc_offset];
+	ts->sync_state.prbs_pc_offset = (ts->sync_state.prbs_pc_offset + 1) % sizeof(pc->bytes);
+	return ret;
+}
+
+/* compare if received buffer matches PRBS; count number of different bits */
+static unsigned int compare_buf(struct timeslot_state *ts, const uint8_t *data, unsigned int len)
+{
+	unsigned int i, num_wrong_bits = 0;
+
+	for (i = 0; i < len; i++) {
+		uint8_t bt = next_prbs_pc_byte(ts);
+		if (data[i] != bt) {
+			uint8_t x = data[i] ^ bt;
+			num_wrong_bits += bits_set_in_byte(x);
+		}
+	}
+	return num_wrong_bits;
+}
+
+/* process incoming received data; try to correlate with prbs sequence */
+static void process_rx(struct timeslot_state *ts, const uint8_t *data, unsigned int len)
+{
+	if (!ts->sync_state.has_sync) {
+		unsigned int pc_num;
+		/* we haven't synced yet and must attempt to sync to the pattern.  We will try
+		 * to match each pattern */
+		for (pc_num = 0; pc_num < ARRAY_SIZE(ts->prbs_pc); pc_num++) {
+			const struct prbs_precomp *pc = &ts->prbs_pc[pc_num];
+			uint8_t *found;
+			long int offset;
+
+			OSMO_ASSERT(len > sizeof(pc->bytes));
+			found = memmem(data, len, pc->bytes, sizeof(pc->bytes));
+			if (!found)
+				continue;
+
+			offset = (found - data);
+			printf("E1TS(%02u) FOUND SYNC (pc_num=%u, offset=%li)\n", ts->ofd.priv_nr,
+				pc_num, offset);
+			clock_gettime(CLOCK_MONOTONIC, &ts->sync_state.ts_sync);
+			ts->sync_state.has_sync = true;
+			ts->sync_state.prbs_pc_num = pc_num;
+			ts->sync_state.prbs_pc_offset = (sizeof(pc->bytes) - offset) % sizeof(pc->bytes);
+			ts->sync_state.num_bit_err = 0;
+			/* we will compare the full buffer below in the 'has_sync' path */
+			break;
+		}
+	}
+	if (ts->sync_state.has_sync) {
+		unsigned int num_wrong_bits;
+		/* we already have sync */
+		num_wrong_bits = compare_buf(ts, data, len);
+		if (num_wrong_bits >= len*8/4) { /* more than 25% of wrong bits */
+			struct timespec ts_now;
+			clock_gettime(CLOCK_MONOTONIC, &ts_now);
+			printf("E1TS(%02u) LOST SYNC after %u of %u wrong bits in one buffer; "
+				"until now, total bit errors %u in %lu seconds\n",
+				ts->ofd.priv_nr, num_wrong_bits, len*8, ts->sync_state.num_bit_err,
+				ts_now.tv_sec - ts->sync_state.ts_sync.tv_sec);
+			ts->sync_state.has_sync = false;
+			ts->sync_state.num_sync_loss++;
+		}
+		ts->sync_state.num_bit_err += num_wrong_bits;
+	}
+}
+
+static int e1_fd_cb(struct osmo_fd *ofd, unsigned int what)
+{
+	struct timeslot_state *ts = ofd->data;
+	uint8_t buf[4096];
+	int rc, len;
+
+	OSMO_ASSERT(what & OSMO_FD_READ);
+
+	/* read whatever data */
+	rc = read(ofd->fd, buf, sizeof(buf));
+	if (rc < 0) {
+		fprintf(stderr, "E1TS(%d) read: %d (%s)\n", ofd->priv_nr, rc, strerror(errno));
+		return rc;
+	}
+	len = rc;
+	process_rx(ts, buf, len);
+
+	return 0;
+}
+
+static int open_slots(struct test_state *tst, const char *basedir)
+{
+	DIR *dir = opendir(basedir);
+	struct dirent *ent;
+	int rc, num_slots = 0;
+
+	if (!dir)
+		return -ENOENT;
+
+	while ((ent = readdir(dir))) {
+		struct timeslot_state *ts;
+		switch (ent->d_type) {
+		case DT_CHR:
+		case DT_FIFO:
+		case DT_SOCK:
+			break;
+		default:
+			printf("%s: skipping\n", ent->d_name);
+			continue;
+		}
+
+		rc = openat(dirfd(dir), ent->d_name, O_RDWR);
+		if (rc < 0) {
+			fprintf(stderr, "Error opening %s: %d (%s)\n", ent->d_name, rc, strerror(errno));
+			return -1;
+		}
+		ts = &tst->ts[tst->next_unused_ts++];
+
+		/* open the respective file descriptor */
+		osmo_fd_setup(&ts->ofd, rc, BSC_FD_READ, e1_fd_cb, ts, atoi(ent->d_name));
+		osmo_fd_register(&ts->ofd);
+		printf("E1TS(%02u) opened\n", ts->ofd.priv_nr);
+
+		/* initialize the PRNG for this slot */
+		ubit_t ubit[PRBS_LEN*2];
+		prbs_for_ts_nr(&ts->prbs, ts->ofd.priv_nr);
+		prbs_precomp(&ts->prbs_pc[0], &ts->prbs);
+		osmo_pbit2ubit(ubit, ts->prbs_pc[0].bytes, PRBS_LEN);
+		/* copy buffer twice back-to-back */
+		memcpy(ubit+PRBS_LEN, ubit, PRBS_LEN);
+
+		cfg_dahdi_buffer(ts->ofd.fd);
+		struct dahdi_bufferinfo bi;
+		rc = ioctl(ts->ofd.fd, DAHDI_GET_BUFINFO, &bi);
+		OSMO_ASSERT(rc == 0);
+		printf("tx_pol=%d, rx_pol=%d, num=%d, size=%d, nread=%d, nwrite=%d\n",
+			bi.txbufpolicy, bi.rxbufpolicy, bi.numbufs, bi.bufsize, bi.readbufs, bi.writebufs); 
+		/* pre-compute bit-shifted versions */
+		for (int i = 1; i < ARRAY_SIZE(ts->prbs_pc); i++) {
+			osmo_ubit2pbit_ext(ts->prbs_pc[i].bytes, 0, ubit, i, PRBS_LEN, 0);
+			//printf("%d: %s\n", i, osmo_hexdump_nospc(ts->prbs_pc[i].bytes, sizeof(ts->prbs_pc[i].bytes)));
+		}
+		num_slots++;
+	}
+	closedir(dir);
+	return num_slots;
+}
+
+static void print_report(void)
+{
+	struct timespec ts_now;
+	int i;
+
+	clock_gettime(CLOCK_MONOTONIC, &ts_now);
+
+	for (i = 0; i < ARRAY_SIZE(g_tst.ts); i++) {
+		const struct timeslot_state *ts = &g_tst.ts[i];
+		printf("E1TS(%02u) STATS: sync_losses=%u, bit_errs=%u in %lu seconds\n",
+			ts->ofd.priv_nr, ts->sync_state.num_sync_loss, ts->sync_state.num_bit_err,
+			ts_now.tv_sec - ts->sync_state.ts_sync.tv_sec);
+	}
+}
+
+static void sig_handler(int signal)
+{
+	switch (signal) {
+	case SIGINT:
+		print_report();
+		exit(0);
+		break;
+	case SIGHUP:
+		print_report();
+		break;
+	}
+}
+
+int main(int argc, char **argv)
+{
+	char *basedir;
+	int rc;
+
+	if (argc < 2)
+		exit(1);
+	basedir = argv[1];
+
+	set_realtime(10);
+	rc = open_slots(&g_tst, basedir);
+	printf("==> opened a total of %d slots\n", rc);
+
+	signal(SIGINT, sig_handler);
+	signal(SIGHUP, sig_handler);
+	while (1) {
+		osmo_select_main(0);
+	}
+}
diff --git a/contrib/e1-prbs-test/tx.c b/contrib/e1-prbs-test/tx.c
new file mode 100644
index 0000000..5848e76
--- /dev/null
+++ b/contrib/e1-prbs-test/tx.c
@@ -0,0 +1,169 @@
+/* (C) 2019 by Harald Welte <laforge at gnumonks.org>
+ * All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+
+#include <osmocom/core/select.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/core/bits.h>
+#include <osmocom/core/prbs.h>
+
+#include "internal.h"
+
+#define MAX_NR_TS 31
+
+/* pre-compute the PRBS sequences only once at startup */
+#define PRBS_PRECOMP
+
+struct timeslot_state {
+	struct osmo_fd ofd;
+	struct osmo_prbs prbs;
+#ifdef PRBS_PRECOMP
+	struct prbs_precomp prbs_pc;
+	unsigned int prbs_pc_idx;
+#else
+	struct osmo_prbs_state prbs_s;
+#endif
+};
+
+struct test_state {
+	struct timeslot_state ts[MAX_NR_TS];
+	unsigned int next_unused_ts;
+};
+static struct test_state g_tst;
+
+
+static void e1_fd_write(struct timeslot_state *ts, int len)
+{
+	uint8_t buf[4096];
+	int i, rc;
+
+	for (i = 0; i < len; i++) {
+#ifdef PRBS_PRECOMP
+		buf[i] = ts->prbs_pc.bytes[ts->prbs_pc_idx];
+		ts->prbs_pc_idx = (ts->prbs_pc_idx + 1) % sizeof(ts->prbs_pc);
+#else
+		ubit_t ubit[8];
+                osmo_prbs_get_ubits(ubit, sizeof(ubit), &ts->prbs_s);
+                osmo_ubit2pbit(&buf[i], ubit, sizeof(ubit));
+#endif
+	}
+	rc = write(ts->ofd.fd, buf, len);
+	if (rc != len)
+		fprintf(stderr, "E1TS(%02u) write: %d bytes less than %d\n", ts->ofd.priv_nr, rc, len);
+}
+
+static int e1_fd_cb(struct osmo_fd *ofd, unsigned int what)
+{
+	struct timeslot_state *ts = ofd->data;
+	uint8_t buf[4096];
+	int rc, len;
+
+	OSMO_ASSERT(what & OSMO_FD_READ);
+
+	/* read whatever data */
+	rc = read(ofd->fd, buf, sizeof(buf));
+	if (rc < 0) {
+		fprintf(stderr, "E1TS(%02u) read: %d (%s)\n", ofd->priv_nr, rc, strerror(errno));
+		return rc;
+	}
+	len = rc;
+
+	/* generate as many bytes as were read */
+	e1_fd_write(ts, len);
+	return 0;
+}
+
+static int open_slots(struct test_state *tst, const char *basedir)
+{
+	DIR *dir = opendir(basedir);
+	struct dirent *ent;
+	int rc, num_slots = 0;
+
+	if (!dir)
+		return -ENOENT;
+
+	while ((ent = readdir(dir))) {
+		struct timeslot_state *ts;
+		switch (ent->d_type) {
+		case DT_CHR:
+		case DT_FIFO:
+		case DT_SOCK:
+			break;
+		default:
+			printf("%s: skipping\n", ent->d_name);
+			continue;
+		}
+
+		rc = openat(dirfd(dir), ent->d_name, O_RDWR);
+		if (rc < 0) {
+			fprintf(stderr, "Error opening %s: %d (%s)\n", ent->d_name, rc, strerror(errno));
+			return -1;
+		}
+		ts = &tst->ts[tst->next_unused_ts++];
+
+		/* open the respective file descriptor */
+		osmo_fd_setup(&ts->ofd, rc, BSC_FD_READ, e1_fd_cb, ts, atoi(ent->d_name));
+		osmo_fd_register(&ts->ofd);
+		printf("E1TS(%02u) opened\n", ts->ofd.priv_nr);
+
+		/* start to put something into the transmit queue, before we get read-triggered
+		 * later on */
+		e1_fd_write(ts, 1024);
+
+		/* initialize the PRNG for this slot */
+		prbs_for_ts_nr(&ts->prbs, ts->ofd.priv_nr);
+#ifdef PRBS_PRECOMP
+		prbs_precomp(&ts->prbs_pc, &ts->prbs);
+#else
+		osmo_prbs_state_init(&ts->prbs_s, &ts->prbs);
+#endif
+
+		num_slots++;
+	}
+	closedir(dir);
+	return num_slots;
+}
+
+int main(int argc, char **argv)
+{
+	char *basedir;
+	int rc;
+
+	if (argc < 2)
+		exit(1);
+	basedir = argv[1];
+
+	set_realtime(11);
+	rc = open_slots(&g_tst, basedir);
+	printf("opened a total of %d slots\n", rc);
+
+	while (1) {
+		osmo_select_main(0);
+	}
+}
diff --git a/contrib/e1-prbs-test/utils.c b/contrib/e1-prbs-test/utils.c
new file mode 100644
index 0000000..5610e80
--- /dev/null
+++ b/contrib/e1-prbs-test/utils.c
@@ -0,0 +1,66 @@
+/* (C) 2019 by Harald Welte <laforge at gnumonks.org>
+ * All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <sched.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <dahdi/user.h>
+
+#include <osmocom/core/utils.h>
+
+/* we could generate a lookup table at start ... */
+uint8_t bits_set_in_byte(uint8_t byte)
+{
+	uint8_t ret = 0;
+	int i;
+
+	for (i = 0; i < 8; i++) {
+		if (byte & (1 << i))
+			ret += 1;
+	}
+	return ret;
+}
+
+void cfg_dahdi_buffer(int fd)
+{
+	struct dahdi_bufferinfo bi = {
+		.txbufpolicy = DAHDI_POLICY_WHEN_FULL, /* default is immediate */
+		.rxbufpolicy = DAHDI_POLICY_WHEN_FULL, /* default is immediate */
+		.numbufs = 8, /* default is 2 */
+		.bufsize = 1024, /* default is 1024 */
+		.readbufs = -1,
+		.writebufs = -1,
+	};
+	OSMO_ASSERT(ioctl(fd, DAHDI_SET_BUFINFO, &bi) == 0);
+}
+
+void set_realtime(int rt_prio)
+{
+	struct sched_param param;
+	int rc;
+
+	memset(&param, 0, sizeof(param));
+	param.sched_priority = rt_prio;
+	rc = sched_setscheduler(getpid(), SCHED_RR, &param);
+	OSMO_ASSERT(rc == 0);
+}

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-e1d/+/16735
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-e1d
Gerrit-Branch: master
Gerrit-Change-Id: Ib25d266e61e0d70919cc4e65d5b1bf0bc9ec7d00
Gerrit-Change-Number: 16735
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge at osmocom.org>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200104/d935d200/attachment.htm>


More information about the gerrit-log mailing list