Change in osmo-tetra[master]: simplify and speed up the burst synchronizer

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/.

Jan Hrach gerrit-no-reply at lists.osmocom.org
Mon Jul 30 21:29:23 UTC 2018


Jan Hrach has uploaded this change for review. ( https://gerrit.osmocom.org/10271


Change subject: simplify and speed up the burst synchronizer
......................................................................

simplify and speed up the burst synchronizer

Rewrite the burst synchronizer so we simply jump to the next training sequence.
I believe the state machine is not needed, the only reason for it - speeding
up search for the next frame - has been fixed in ca6a3bc.

Simplifying the synchronizer allows it to be easily extended to support
uplink and direct modes.

Additionally, we process the entire buffer at once (the previous version used
64-byte chunks), so the overhead is much smaller (up to 20 times on sparse
channels).

Change-Id: I74a13ced4c11b6d98afa7916c1f4109875c20101
---
M src/phy/tetra_burst_sync.c
M src/phy/tetra_burst_sync.h
M src/tetra-rx.c
M src/tetra_common.h
4 files changed, 65 insertions(+), 94 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-tetra refs/changes/71/10271/1

diff --git a/src/phy/tetra_burst_sync.c b/src/phy/tetra_burst_sync.c
index ae210dc..f3b759f 100644
--- a/src/phy/tetra_burst_sync.c
+++ b/src/phy/tetra_burst_sync.c
@@ -21,6 +21,7 @@
 #include <stdint.h>
 #include <stdio.h>
 #include <string.h>
+#include <assert.h>
 
 #include <osmocom/core/utils.h>
 
@@ -35,7 +36,7 @@
 
 void tetra_burst_rx_cb(const uint8_t *burst, unsigned int len, enum tetra_train_seq type, void *priv);
 
-static void make_bitbuf_space(struct tetra_rx_state *trs, unsigned int len)
+static unsigned int make_bitbuf_space(struct tetra_rx_state *trs, unsigned int len)
 {
 	unsigned int bitbuf_space = sizeof(trs->bitbuf) - trs->bits_in_buf;
 
@@ -48,9 +49,20 @@
 		trs->bitbuf_start_bitnum += delta;
 		bitbuf_space = sizeof(trs->bitbuf) - trs->bits_in_buf;
 	}
+	return bitbuf_space;
 }
 
-/* input a raw bitstream into the tetra burst synchronizaer */
+static unsigned int conserve_bits(struct tetra_rx_state *trs, unsigned int howmany)
+{
+	assert(howmany < sizeof(trs->bitbuf));
+	return make_bitbuf_space(trs, sizeof(trs->bitbuf) - howmany);
+}
+
+/* input a raw bitstream into the tetra burst synchronizer
+ * returns the number which in absolute value is the number of bits
+ *  we can safely consume the next time
+ * if the result is negative, we are done with processing
+ */
 int tetra_burst_sync_in(struct tetra_rx_state *trs, uint8_t *bits, unsigned int len)
 {
 	int rc;
@@ -63,92 +75,35 @@
 	memcpy(trs->bitbuf + trs->bits_in_buf, bits, len);
 	trs->bits_in_buf += len;
 
-	switch (trs->state) {
-	case RX_S_UNLOCKED:
-		if (trs->bits_in_buf < TETRA_BITS_PER_TS*2) {
-			/* wait for more bits to arrive */
-			DEBUGP("-> waiting for more bits to arrive\n");
-			return len;
-		}
-		DEBUGP("-> trying to find training sequence between bit %u and %u\n",
-			trs->bitbuf_start_bitnum, trs->bits_in_buf);
-		rc = tetra_find_train_seq(trs->bitbuf, trs->bits_in_buf,
-					  (1 << TETRA_TRAIN_SYNC), &train_seq_offs);
-		if (rc < 0)
-			return rc;
-		printf("found SYNC training sequence in bit #%u\n", train_seq_offs);
-		trs->state = RX_S_KNOW_FSTART;
-		trs->next_frame_start_bitnum = trs->bitbuf_start_bitnum + train_seq_offs + 296;
-#if 0
-		if (train_seq_offs < 214) {
-			/* not enough leading bits for start of burst */
-			/* we just drop everything that we received so far */
-			trs->bitbuf_start_bitnum += trs->bits_in_buf;
-			trs->bits_in_buf = 0;
-		}
-#endif
+	rc = tetra_find_train_seq(trs->bitbuf+214, trs->bits_in_buf,
+				  (1 << TETRA_TRAIN_NORM_1)|
+				  (1 << TETRA_TRAIN_NORM_2)|
+				  (1 << TETRA_TRAIN_SYNC), &train_seq_offs);
+	train_seq_offs += 214;
+
+	if ((rc < 0) || (train_seq_offs + TETRA_BITS_PER_TS > trs->bits_in_buf))
+		return -conserve_bits(trs, 2*TETRA_BITS_PER_TS);
+
+	tetra_tdma_time_add_tn(&t_phy_state.time, 1);
+	printf("\nBURST @ %u", trs->bitbuf_start_bitnum+train_seq_offs);
+	DEBUGP(": %s", osmo_ubit_dump(trs->bitbuf, TETRA_BITS_PER_TS));
+	printf("\n");
+
+	switch (rc) {
+	case TETRA_TRAIN_SYNC:
+		if (train_seq_offs >= 214)
+			tetra_burst_rx_cb(trs->bitbuf+train_seq_offs-214, TETRA_BITS_PER_TS, rc, trs->burst_cb_priv);
 		break;
-	case RX_S_KNOW_FSTART:
-		/* we are locked, i.e. already know when the next frame should start */
-		if (trs->bitbuf_start_bitnum + trs->bits_in_buf < trs->next_frame_start_bitnum)
-			return 0;
-		else {
-			/* shift start of frame to start of bitbuf */
-			int offset = trs->next_frame_start_bitnum - trs->bitbuf_start_bitnum;
-			int bits_remaining = trs->bits_in_buf - offset;
-
-			memmove(trs->bitbuf, trs->bitbuf+offset, bits_remaining);
-			trs->bits_in_buf = bits_remaining;
-			trs->bitbuf_start_bitnum += offset;
-
-			trs->next_frame_start_bitnum += TETRA_BITS_PER_TS;
-			trs->state = RX_S_LOCKED;
-		}
-	case RX_S_LOCKED:
-		if (trs->bits_in_buf < TETRA_BITS_PER_TS) {
-			/* not sufficient data for the full frame yet */
-			return len;
-		} else {
-			/* we have successfully received (at least) one frame */
-			tetra_tdma_time_add_tn(&t_phy_state.time, 1);
-			printf("\nBURST");
-			DEBUGP(": %s", osmo_ubit_dump(trs->bitbuf, TETRA_BITS_PER_TS));
-			printf("\n");
-			rc = tetra_find_train_seq(trs->bitbuf, trs->bits_in_buf,
-						  (1 << TETRA_TRAIN_NORM_1)|
-						  (1 << TETRA_TRAIN_NORM_2)|
-						  (1 << TETRA_TRAIN_SYNC), &train_seq_offs);
-			switch (rc) {
-			case TETRA_TRAIN_SYNC:
-				if (train_seq_offs == 214)
-					tetra_burst_rx_cb(trs->bitbuf, TETRA_BITS_PER_TS, rc, trs->burst_cb_priv);
-				else {
-					fprintf(stderr, "#### SYNC burst at offset %u?!?\n", train_seq_offs);
-					trs->state = RX_S_UNLOCKED;
-				}
-				break;
-			case TETRA_TRAIN_NORM_1:
-			case TETRA_TRAIN_NORM_2:
-			case TETRA_TRAIN_NORM_3:
-				if (train_seq_offs == 244)
-					tetra_burst_rx_cb(trs->bitbuf, TETRA_BITS_PER_TS, rc, trs->burst_cb_priv);
-				else
-					fprintf(stderr, "#### SYNC burst at offset %u?!?\n", train_seq_offs);
-				break;
-			default:
-				fprintf(stderr, "#### could not find successive burst training sequence\n");
-				trs->state = RX_S_UNLOCKED;
-				break;
-			}
-
-			/* move remainder to start of buffer */
-			trs->bits_in_buf -= TETRA_BITS_PER_TS;
-			memmove(trs->bitbuf, trs->bitbuf+TETRA_BITS_PER_TS, trs->bits_in_buf);
-			trs->bitbuf_start_bitnum += TETRA_BITS_PER_TS;
-			trs->next_frame_start_bitnum += TETRA_BITS_PER_TS;
-		}
+	case TETRA_TRAIN_NORM_1:
+	case TETRA_TRAIN_NORM_2:
+	case TETRA_TRAIN_NORM_3:
+		if (train_seq_offs >= 244)
+			tetra_burst_rx_cb(trs->bitbuf+train_seq_offs-244, TETRA_BITS_PER_TS, rc, trs->burst_cb_priv);
 		break;
-
+	default:
+		fprintf(stderr, "#### unsupported burst training sequence\n");
+		break;
 	}
-	return len;
+	return train_seq_offs+1;
+
 }
diff --git a/src/phy/tetra_burst_sync.h b/src/phy/tetra_burst_sync.h
index 7862461..4ec8b53 100644
--- a/src/phy/tetra_burst_sync.h
+++ b/src/phy/tetra_burst_sync.h
@@ -3,6 +3,8 @@
 
 #include <stdint.h>
 
+#define BUFSIZE 4096
+
 enum rx_state {
 	RX_S_UNLOCKED,		/* we're completely unlocked */
 	RX_S_KNOW_FSTART,	/* we know the next frame start */
@@ -12,7 +14,7 @@
 struct tetra_rx_state {
 	enum rx_state state;
 	unsigned int bits_in_buf;		/* how many bits are currently in bitbuf */
-	uint8_t bitbuf[4096];
+	uint8_t bitbuf[BUFSIZE];
 	unsigned int bitbuf_start_bitnum;	/* bit number at first element in bitbuf */
 	unsigned int next_frame_start_bitnum;	/* frame start expected at this bitnum */
 
diff --git a/src/tetra-rx.c b/src/tetra-rx.c
index 8498f8c..78bdfea 100644
--- a/src/tetra-rx.c
+++ b/src/tetra-rx.c
@@ -95,19 +95,29 @@
 	if (pcap_file_path)
 		tetra_gsmtap_init_file(pcap_file_path);
 
-	while (1) {
-		uint8_t buf[64];
-		int len;
+	int to_consume = BUFSIZE;
+	uint8_t buf[BUFSIZE];
 
-		len = read(fd, buf, sizeof(buf));
+	while (1) {
+		int len, rlen;
+
+		len = read(fd, buf, to_consume);
 		if (len < 0) {
 			perror("read");
 			exit(1);
-		} else if (len == 0) {
+		}
+		rlen = len;
+		if (len == 0) {
+			memset(buf, 0, BUFSIZE);
+			rlen = to_consume;
+		}
+		int rc = tetra_burst_sync_in(trs, buf, rlen);
+
+		if (len == 0 && rc <= 0) {
 			printf("EOF");
 			break;
 		}
-		tetra_burst_sync_in(trs, buf, len);
+		to_consume = MIN(abs(rc), BUFSIZE);
 	}
 
 	free(tms->dumpdir);
diff --git a/src/tetra_common.h b/src/tetra_common.h
index a270a26..c63e6ca 100644
--- a/src/tetra_common.h
+++ b/src/tetra_common.h
@@ -11,6 +11,10 @@
 #define DEBUGP(x, args...)	do { } while(0)
 #endif
 
+#define MIN(a, b)		(((a) < (b))?(a):(b))
+#define MAX(a, b)		(((a) > (b))?(a):(b))
+#define CLAMP(x, lower, upper)	(MIN(upper, MAX(x, lower)))
+
 #define TETRA_SYM_PER_TS	255
 #define TETRA_BITS_PER_TS	(TETRA_SYM_PER_TS*2)
 

-- 
To view, visit https://gerrit.osmocom.org/10271
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-tetra
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I74a13ced4c11b6d98afa7916c1f4109875c20101
Gerrit-Change-Number: 10271
Gerrit-PatchSet: 1
Gerrit-Owner: Jan Hrach <jenda.2vf9h at hrach.eu>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20180730/edf4a6b8/attachment.htm>


More information about the gerrit-log mailing list