Project

General

Profile

tetra.patch

jenda, 04/10/2017 12:52 AM

View differences:

src/phy/tetra_burst.c
23 23
#include <stdint.h>
24 24
#include <string.h>
25 25
#include <stdio.h>
26
#include <stdbool.h>
26 27

  
27 28
#include <phy/tetra_burst.h>
28 29

  
......
266 267
	return cur - buf;
267 268
}
268 269

  
270
/*
271
 * Initialize a fast filter for searching for training sequences.
272
 * After this function is called, each element of @tsq_all contains the first
273
 * @FILTER_LOOKAHEAD_LEN bits of a given training sequence.
274
 * Then, we can search for a given sequence using a single compare.
275
 */
276
uint32_t tsq_all[5];
277
#define FILTER_LOOKAHEAD_LEN 16
278
#define FILTER_LOOKAHEAD_MASK 0xFFFF
279
void tetra_init_train_seq_filter() {
280
	for(int i = 0; i<FILTER_LOOKAHEAD_LEN; i++) {
281
		tsq_all[0] = (tsq_all[0] << 1) | y_bits[i];
282
		tsq_all[1] = (tsq_all[1] << 1) | n_bits[i];
283
		tsq_all[2] = (tsq_all[2] << 1) | p_bits[i];
284
		tsq_all[3] = (tsq_all[3] << 1) | q_bits[i];
285
		tsq_all[4] = (tsq_all[4] << 1) | x_bits[i];
286
	}
287
	for(int i = 0; i < 5; i++) {
288
		tsq_all[i] &= FILTER_LOOKAHEAD_MASK;
289
	}
290
}
291

  
269 292
int tetra_find_train_seq(const uint8_t *in, unsigned int end_of_in,
270 293
			 uint32_t mask_of_train_seq, unsigned int *offset)
271 294
{
272 295
	const uint8_t *cur;
273 296

  
297
	uint32_t filter = 0;
298

  
299
	for (int i = 0; i<FILTER_LOOKAHEAD_LEN-2; i++) {
300
		filter = (filter << 1) | in[i];
301
	}
302

  
274 303
	for (cur = in; cur < in + end_of_in; cur++) {
304
		/*
305
		 * We are shifting the incoming bitstream into @filter.
306
		 * Then, we compare the filter for the beginning of all the training sequence.
307
		 * When this simple comparison matches, we use a full-blown memcmp for the
308
		 * whole sequence.
309
		 */
310
		filter = ((filter << 1) | cur[FILTER_LOOKAHEAD_LEN-1]) & FILTER_LOOKAHEAD_MASK;
311
		bool match = false;
312
		for(int i = 0; i<5; i++) {
313
			if(filter == tsq_all[i]) {
314
				match = true;
315
			}
316
		}
317
		if(!match) {
318
			continue;
319
		}
320

  
275 321
		int remain_len = (in + end_of_in) - cur;
276 322

  
277 323
		if (mask_of_train_seq & (1 << TETRA_TRAIN_SYNC) &&
src/phy/tetra_burst.h
31 31
/* find a TETRA training sequence in the burst buffer indicated */
32 32
int tetra_find_train_seq(const uint8_t *in, unsigned int end_of_in,
33 33
			 uint32_t mask_of_train_seq, unsigned int *offset);
34
void tetra_init_train_seq_filter();
34 35

  
35 36
#endif /* TETRA_BURST_H */
src/phy/tetra_burst_sync.c
35 35

  
36 36
void tetra_burst_rx_cb(const uint8_t *burst, unsigned int len, enum tetra_train_seq type, void *priv);
37 37

  
38
static void make_bitbuf_space(struct tetra_rx_state *trs, unsigned int len)
39
{
40
	unsigned int bitbuf_space = sizeof(trs->bitbuf) - trs->bits_in_buf;
41

  
42
	if (bitbuf_space < len) {
43
		unsigned int delta = len - bitbuf_space;
44

  
45
		DEBUGP("bitbuf left: %u, shrinking by %u\n", bitbuf_space, delta);
46
		memmove(trs->bitbuf, trs->bitbuf + delta, trs->bits_in_buf - delta);
47
		trs->bits_in_buf -= delta;
48
		trs->bitbuf_start_bitnum += delta;
49
		bitbuf_space = sizeof(trs->bitbuf) - trs->bits_in_buf;
50
	}
51
}
52

  
53
/* input a raw bitstream into the tetra burst synchronizaer */
54
int tetra_burst_sync_in(struct tetra_rx_state *trs, uint8_t *bits, unsigned int len)
38
/* input a raw bitstream file into the tetra burst synchronizaer */
39
int tetra_burst_sync_in(struct tetra_rx_state *trs, FILE *infile)
55 40
{
56 41
	int rc;
57 42
	unsigned int train_seq_offs;
43
	int len;
44
	int bits_free = sizeof(trs->bitbuf) - trs->bits_in_buf;
58 45

  
59
	DEBUGP("burst_sync_in: %u bits, state %u\n", len, trs->state);
46
	len = fread(trs->bitbuf + trs->bits_in_buf, 1, bits_free, infile);
47

  
48
	if (len < 0) {
49
		perror("read");
50
		exit(1);
51
	} else if (feof(infile) && trs->bits_in_buf < TETRA_BITS_PER_TS) {
52
		printf("EOF");
53
		return -1;
54
	}
60 55

  
61
	/* First: append the data to the bitbuf */
62
	make_bitbuf_space(trs, len);
63
	memcpy(trs->bitbuf + trs->bits_in_buf, bits, len);
64 56
	trs->bits_in_buf += len;
57
	DEBUGP("burst_sync_in: %u bits, state %u\n", len, trs->state);
65 58

  
66 59
	switch (trs->state) {
67 60
	case RX_S_UNLOCKED:
68 61
		if (trs->bits_in_buf < TETRA_BITS_PER_TS*2) {
69 62
			/* wait for more bits to arrive */
70 63
			DEBUGP("-> waiting for more bits to arrive\n");
71
			return len;
64
			return trs->bits_in_buf;
72 65
		}
73 66
		DEBUGP("-> trying to find training sequence between bit %u and %u\n",
74 67
			trs->bitbuf_start_bitnum, trs->bits_in_buf);
75 68
		rc = tetra_find_train_seq(trs->bitbuf, trs->bits_in_buf,
76 69
					  (1 << TETRA_TRAIN_SYNC), &train_seq_offs);
77
		if (rc < 0)
70
		if (rc < 0) {
71
			memmove(trs->bitbuf,
72
				trs->bitbuf + trs->bits_in_buf - TETRA_BITS_PER_TS*2,
73
				TETRA_BITS_PER_TS*2);
74
			trs->bits_in_buf = TETRA_BITS_PER_TS*2;
78 75
			return rc;
76
		}
79 77
		printf("found SYNC training sequence in bit #%u\n", train_seq_offs);
80 78
		trs->state = RX_S_KNOW_FSTART;
81 79
		trs->next_frame_start_bitnum = trs->bitbuf_start_bitnum + train_seq_offs + 296;
......
91 89
	case RX_S_KNOW_FSTART:
92 90
		/* we are locked, i.e. already know when the next frame should start */
93 91
		if (trs->bitbuf_start_bitnum + trs->bits_in_buf < trs->next_frame_start_bitnum)
94
			return 0;
92
			return trs->bits_in_buf;
95 93
		else {
96 94
			/* shift start of frame to start of bitbuf */
97 95
			int offset = trs->next_frame_start_bitnum - trs->bitbuf_start_bitnum;
......
107 105
	case RX_S_LOCKED:
108 106
		if (trs->bits_in_buf < TETRA_BITS_PER_TS) {
109 107
			/* not sufficient data for the full frame yet */
110
			return len;
108
			return trs->bits_in_buf;
111 109
		} else {
112 110
			/* we have successfully received (at least) one frame */
113 111
			tetra_tdma_time_add_tn(&t_phy_state.time, 1);
......
150 148
		break;
151 149

  
152 150
	}
153
	return len;
151
	return trs->bits_in_buf;
154 152
}
src/phy/tetra_burst_sync.h
21 21

  
22 22

  
23 23
/* input a raw bitstream into the tetra burst synchronizaer */
24
int tetra_burst_sync_in(struct tetra_rx_state *trs, uint8_t *bits, unsigned int len);
24
int tetra_burst_sync_in(struct tetra_rx_state *trs, FILE *infile);
25 25

  
26 26
#endif /* TETRA_BURST_SYNC_H */
src/tetra-rx.c
38 38

  
39 39
int main(int argc, char **argv)
40 40
{
41
	int fd;
41
	FILE *infile;
42 42
	struct tetra_rx_state *trs;
43 43
	struct tetra_mac_state *tms;
44 44

  
......
47 47
		exit(1);
48 48
	}
49 49

  
50
	fd = open(argv[1], O_RDONLY);
51
	if (fd < 0) {
52
		perror("open");
50
	infile = fopen(argv[1], "r");
51
	if (infile < 0) {
52
		perror("fopen");
53 53
		exit(2);
54 54
	}
55 55

  
......
61 61
	trs = talloc_zero(tetra_tall_ctx, struct tetra_rx_state);
62 62
	trs->burst_cb_priv = tms;
63 63

  
64
	while (1) {
65
		uint8_t buf[64];
66
		int len;
67

  
68
		len = read(fd, buf, sizeof(buf));
69
		if (len < 0) {
70
			perror("read");
71
			exit(1);
72
		} else if (len == 0) {
73
			printf("EOF");
74
			break;
75
		}
76
		tetra_burst_sync_in(trs, buf, len);
64
	tetra_init_train_seq_filter();
65

  
66
	int rc;
67
	while (!(feof(infile) && rc <= 0)) {
68
		rc = tetra_burst_sync_in(trs, infile);
77 69
	}
70
	fclose(infile);
78 71

  
79 72
	talloc_free(trs);
80 73
	talloc_free(tms);
Add picture from clipboard (Maximum size: 48.8 MB)