Change in osmo-trx[master]: PRBS tool sending PRBS sequence to TRX

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
Wed May 6 19:39:48 UTC 2020


laforge has submitted this change. ( https://gerrit.osmocom.org/c/osmo-trx/+/18005 )

Change subject: PRBS tool sending PRBS sequence to TRX
......................................................................

PRBS tool sending PRBS sequence to TRX

Change-Id: I2300f909bbfda10a7053320edfd1deaea763759a
---
M Makefile.am
M configure.ac
A utils/Makefile.am
A utils/prbs-tool.c
4 files changed, 327 insertions(+), 1 deletion(-)

Approvals:
  pespin: Looks good to me, but someone else must approve
  laforge: Looks good to me, approved
  Jenkins Builder: Verified



diff --git a/Makefile.am b/Makefile.am
index 8b55e79..9462fa8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -33,7 +33,8 @@
 	GSM \
 	Transceiver52M \
 	contrib \
-	tests
+	tests \
+	utils
 
 EXTRA_DIST = \
 	LEGAL \
diff --git a/configure.ac b/configure.ac
index b7b0d00..d0cfe44 100644
--- a/configure.ac
+++ b/configure.ac
@@ -92,6 +92,7 @@
 PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.3.0)
 PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.3.0)
 PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.3.0)
+PKG_CHECK_MODULES(LIBOSMOCODING, libosmocoding >= 1.3.0)
 
 AC_ARG_ENABLE(sanitize,
 	[AS_HELP_STRING(
@@ -327,6 +328,7 @@
     tests/Makefile \
     tests/CommonLibs/Makefile \
     tests/Transceiver52M/Makefile \
+    utils/Makefile \
     doc/Makefile \
     doc/examples/Makefile \
     contrib/Makefile \
diff --git a/utils/Makefile.am b/utils/Makefile.am
new file mode 100644
index 0000000..0b8bda0
--- /dev/null
+++ b/utils/Makefile.am
@@ -0,0 +1,7 @@
+AM_CPPFLAGS = $(LIBOSMOCODING_CFLAGS)
+AM_CFLAGS = -Wall
+
+noinst_PROGRAMS = osmo-prbs-tool
+
+osmo_prbs_tool_SOURCES = prbs-tool.c
+osmo_prbs_tool_LDADD = $(LIBOSMOCODING_LIBS)
diff --git a/utils/prbs-tool.c b/utils/prbs-tool.c
new file mode 100644
index 0000000..de68f0b
--- /dev/null
+++ b/utils/prbs-tool.c
@@ -0,0 +1,316 @@
+/* Dummy TRX for sening PRBS test sequences into osmo-bts-trx to test
+ * the decoder/receiver processing in osmo-bts-trx as well as any
+ * additional PRBS testing code.
+ *
+ * The purpose of this program is to use it as a mock dummy MS-side
+ * transmitter of GSM bursts that contain encoded PRBS sequences,
+ * similar to what one would normally do with an arbitrary
+ * function/waveform generator or BERT tester in hardware.
+ *
+ * (C) 2017 by Harald Welte <laforge at gnumonks.org>
+ * All Rights Reserved
+ *
+ * Licensed under terms of the GNU Generral Public License, Version 2,
+ * or (at your option) any later version.
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <netinet/in.h>
+
+#include <osmocom/core/bits.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/core/prbs.h>
+#include <osmocom/core/socket.h>
+#include <osmocom/gsm/gsm_utils.h>
+#include <osmocom/coding/gsm0503_coding.h>
+
+/***********************************************************************
+ * GSM Constants
+ ***********************************************************************/
+
+#define GSM_FR_BYTES	33
+#define GSM_BURST_BITS	116
+#define GSM_4BURST_BITS	(GSM_BURST_BITS*4)
+#define GSM_BURST_LEN	148
+
+
+/***********************************************************************
+ * TRX Interface / Protocol
+ ***********************************************************************/
+
+#define TRX_BASE_PORT	5700
+/* DATA port on the TRX side */
+#define	TRX_PORT_CTRL_TRX(C) 	(TRX_BASE_PORT+(2*(C))+1)
+#define	TRX_PORT_DATA_TRX(C) 	(TRX_BASE_PORT+(2*(C))+2)
+#define	TRX_PORT_CTRL_BTS(C) 	(TRX_PORT_CTRL_TRX(C)+100)
+#define	TRX_PORT_DATA_BTS(C) 	(TRX_PORT_DATA_TRX(C)+100)
+
+struct trx_ul_msg {
+	uint8_t		ts;
+	uint32_t	fn;
+	uint8_t		rssi;
+	uint16_t	t_offs;
+	sbit_t		bits[148];
+} __attribute__((packed));
+
+struct trx_dl_msg {
+	uint8_t		ts;
+	uint32_t	fn;
+	uint8_t		att_db;
+	ubit_t		bits[148];
+} __attribute__((packed));
+
+
+/***********************************************************************
+ * Helper Functions
+ ***********************************************************************/
+
+static int ubits2trxbits(uint8_t *sbits, const ubit_t *ubits, unsigned int count)
+{
+	unsigned int i;
+
+	for (i = 0; i < count; i++) {
+		if ((*ubits++) & 1) {
+			*sbits++ = 255;
+		} else {
+			*sbits++ = 0;
+		}
+	}
+
+	return count;
+}
+
+static int __attribute__((__unused__)) dec(const ubit_t *bursts_u)
+{
+	sbit_t bursts_s[GSM_4BURST_BITS*2];
+	uint8_t dec_tch_data[GSM_FR_BYTES];
+	int n_errors, n_bits_total;
+	int rc;
+
+	/* convert from u_bit (tx) to s_bit (rx)  */
+	osmo_ubit2sbit(bursts_s, bursts_u, sizeof(bursts_s));
+
+	rc = gsm0503_tch_fr_decode(dec_tch_data, bursts_s, 1, 0, &n_errors, &n_bits_total);
+	printf("rc=%d, n_errors=%d, n_bits_total=%d: %s\n", rc, n_errors, n_bits_total,
+		osmo_hexdump(dec_tch_data, sizeof(dec_tch_data)));
+
+	return rc;
+}
+
+/*! \brief Training Sequences (TS 05.02 Chapter 5.2.3) */
+static const ubit_t _sched_tsc[8][26] = {
+	{ 0,0,1,0,0,1,0,1,1,1,0,0,0,0,1,0,0,0,1,0,0,1,0,1,1,1, },
+	{ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,1,0,0,0,1,0,1,1,0,1,1,1, },
+	{ 0,1,0,0,0,0,1,1,1,0,1,1,1,0,1,0,0,1,0,0,0,0,1,1,1,0, },
+	{ 0,1,0,0,0,1,1,1,1,0,1,1,0,1,0,0,0,1,0,0,0,1,1,1,1,0, },
+	{ 0,0,0,1,1,0,1,0,1,1,1,0,0,1,0,0,0,0,0,1,1,0,1,0,1,1, },
+	{ 0,1,0,0,1,1,1,0,1,0,1,1,0,0,0,0,0,1,0,0,1,1,1,0,1,0, },
+	{ 1,0,1,0,0,1,1,1,1,1,0,1,1,0,0,0,1,0,1,0,0,1,1,1,1,1, },
+	{ 1,1,1,0,1,1,1,1,0,0,0,1,0,0,1,0,1,1,1,0,1,1,1,1,0,0, },
+};
+
+/***********************************************************************
+ * state + processing functions
+ ***********************************************************************/
+
+/* state we have to keep for one physical channel */
+struct pchan_data {
+	/* PRBS state */
+	struct osmo_prbs_state st;
+	/* unpacked PRBS bits, generated from PRBS */
+	ubit_t prbs_u[4+260];
+	/* packed frame (to be sent) */
+	uint8_t tch_data[GSM_FR_BYTES];
+	/* burst bits (ubit) to be transmitted */
+	ubit_t bursts[GSM_4BURST_BITS*2]; /* 116 * 8 */
+	/* burst bits (sbit) 'as if received' */
+	sbit_t bursts_s[GSM_4BURST_BITS*2];
+	/* next to-be transmitted burst number */
+	unsigned int burst_nr;
+	/* training sequence code */
+	unsigned int tsc;
+};
+
+struct ts_data {
+	struct pchan_data pchan[2];
+};
+
+struct trx_data {
+	struct ts_data ts[8];
+};
+
+static struct trx_data g_trx_data;
+
+/* initialize the state for one TRX */
+static void trx_data_init(struct trx_data *trx)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
+		struct ts_data *ts = &trx->ts[i];
+		int j;
+		for (j = 0; j < ARRAY_SIZE(ts->pchan); j++) {
+			struct pchan_data *pchan = &ts->pchan[j];
+
+			memset(pchan, 0, sizeof(*pchan));
+			osmo_prbs_state_init(&pchan->st, &osmo_prbs9);
+			pchan->tsc = 7;
+		}
+	}
+}
+
+/*! obtain the next to-be-transmitted burst for the given pchan
+ *  \param pchan physical channel on which we operate
+ *  \param[in] fn frame number
+ *  \param[out] burst_out caller-provided buffer for 148 unpacked output bits
+ *  \retruns number of bits stored in \a burst_out */
+static int pchan_get_next_burst(struct pchan_data *pchan, uint32_t fn, ubit_t *burst_out)
+{
+	uint32_t fn26 = fn % 26;
+	int rc;
+
+	if (fn26 == 0 || fn26 == 4 || fn26 == 8 || fn26 == 13 || fn26 == 17 || fn26 == 21)
+		pchan->burst_nr = 0;
+
+	if (fn26 == 12 || fn26 == 25) {
+		memset(burst_out, 0, GSM_BURST_LEN);
+		return GSM_BURST_LEN;
+	}
+
+	if (pchan->burst_nr == 0) {
+		/* generate PRBS output in ubit format, skipping first nibble for 260-264 padding */
+		const uint8_t prefix[] = { 0xd0 };
+		osmo_pbit2ubit(pchan->prbs_u, prefix, 4);
+		rc = osmo_prbs_get_ubits(pchan->prbs_u+4, sizeof(pchan->prbs_u)-4, &pchan->st);
+		OSMO_ASSERT(rc == sizeof(pchan->prbs_u)-4);
+		/* pack to PBIT format */
+		rc = osmo_ubit2pbit(pchan->tch_data, pchan->prbs_u, sizeof(pchan->prbs_u));
+		//memset(pchan->tch_data, 0xff, sizeof(pchan->tch_data));
+
+		printf("%s\n", osmo_hexdump(pchan->tch_data, GSM_FR_BYTES));
+
+		/* shift buffer by 4 bursts for interleaving */
+		memcpy(pchan->bursts, pchan->bursts + GSM_4BURST_BITS, GSM_4BURST_BITS);
+		memset(pchan->bursts + GSM_4BURST_BITS, 0, GSM_4BURST_BITS);
+
+		/* encode block (codec frame) into four bursts */
+		rc = gsm0503_tch_fr_encode(pchan->bursts, pchan->tch_data, GSM_FR_BYTES, 1);
+		OSMO_ASSERT(rc == 0);
+
+		for (int i = 0; i < sizeof(pchan->bursts); i += GSM_BURST_BITS)
+			printf("\t%s\n", osmo_ubit_dump(pchan->bursts + i, GSM_BURST_BITS));
+
+//		dec(pchan->bursts);
+	}
+
+	/* for all bursts: format 148 symbols from 116 input bits */
+	ubit_t *burst = pchan->bursts  + pchan->burst_nr * GSM_BURST_BITS;
+	printf("TX(%u): %s\n", pchan->burst_nr, osmo_ubit_dump(burst, GSM_BURST_BITS));
+	memset(burst_out, 0, 3);		/* guard bits */
+	memcpy(burst_out+3, burst, 58);		/* firrst half */
+	memcpy(burst_out+61, _sched_tsc[pchan->tsc], 26);	/* midamble */
+	memcpy(burst_out+87, burst+58, 58);	/* second half */
+	memset(burst_out+145, 0, 3);		/* guard bits */
+
+	/* increment burst number for next call */
+	pchan->burst_nr += 1;
+#if 0
+	if (pchan->burst_nr == 4)
+		pchan->burst_nr = 0;
+#endif
+
+	return GSM_BURST_LEN;
+}
+
+static int pchan_process_ts_fn(struct pchan_data *pchan, uint32_t fn, uint8_t *burst_t)
+{
+	ubit_t burst_u[GSM_BURST_LEN];
+	int rc;
+
+	rc = pchan_get_next_burst(pchan, fn, burst_u);
+	OSMO_ASSERT(rc == sizeof(burst_u));
+
+	/* convert from u_bit (tx) to s_bit (rx)  */
+	ubits2trxbits(burst_t, burst_u, GSM_BURST_LEN);
+
+	return GSM_BURST_LEN;
+}
+
+/* read TRX DL data from BTS, write TRX UL data to BTS */
+static int read_and_process(int fd)
+{
+	/* receive (downlink) buffer */
+	uint8_t rx_dl_buf[1024];
+	struct trx_dl_msg *dl_msg = (struct trx_dl_msg *) rx_dl_buf;
+	/* transmit (uplink) buffer */
+	uint8_t tx_ul_buf[1024];
+	struct trx_ul_msg *ul_msg = (struct trx_ul_msg *) tx_ul_buf;
+	/* other variables */
+	struct pchan_data *pchan;
+	uint8_t rc;
+
+	/* do a blocking read on the socket and receive DL from BTS */
+	rc = read(fd, rx_dl_buf, sizeof(rx_dl_buf));
+	if (rc < sizeof(*dl_msg))
+		return rc;
+
+	dl_msg->fn = ntohl(dl_msg->fn);
+
+	if (dl_msg->ts >= ARRAY_SIZE(g_trx_data.ts))
+		return -ENODEV;
+
+	if (dl_msg->ts != 2)
+		return 0;
+
+	printf("FN=%s TS=%u\n", gsm_fn_as_gsmtime_str(dl_msg->fn), dl_msg->ts);
+
+	/* FIXME: second pchan for TCH/H */
+	pchan = &g_trx_data.ts[dl_msg->ts].pchan[0];
+
+	rc = pchan_process_ts_fn(pchan, dl_msg->fn, (uint8_t *) ul_msg->bits);
+	OSMO_ASSERT(rc == sizeof(ul_msg->bits));
+
+	/* copy over timeslot and frame number */
+	ul_msg->fn = htonl(dl_msg->fn);
+	ul_msg->ts = dl_msg->ts;
+
+	/* write uplink message towards BTS */
+	rc = write(fd, tx_ul_buf, sizeof(*ul_msg));
+	if (rc < sizeof(*ul_msg))
+		return -EIO;
+
+	return 0;
+}
+
+static int open_trx_data_sock(unsigned int trx_nr, const char *bts_host)
+{
+	int rc;
+
+	rc = osmo_sock_init2(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, TRX_PORT_DATA_TRX(trx_nr),
+				bts_host, TRX_PORT_DATA_BTS(trx_nr),
+				OSMO_SOCK_F_CONNECT | OSMO_SOCK_F_BIND);
+	return rc;
+}
+
+
+int main(int argc, char **argv)
+{
+	int fd;
+
+	trx_data_init(&g_trx_data);
+
+	fd = open_trx_data_sock(0, "127.0.0.1");
+	if (fd < 0)
+		exit(1);
+
+	while (1) {
+		read_and_process(fd);
+	}
+
+	return 0;
+}

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

Gerrit-Project: osmo-trx
Gerrit-Branch: master
Gerrit-Change-Id: I2300f909bbfda10a7053320edfd1deaea763759a
Gerrit-Change-Number: 18005
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge at osmocom.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: pespin <pespin at sysmocom.de>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200506/0625caad/attachment.htm>


More information about the gerrit-log mailing list