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

<div style="display:none"> Gerrit-Project: osmo-trx </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I2300f909bbfda10a7053320edfd1deaea763759a </div>
<div style="display:none"> Gerrit-Change-Number: 18005 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>