mirror of
https://github.com/brmlab/osmo-tetra.git
synced 2025-06-12 03:44:18 +02:00
initial import of Osmocom TETRA phy and lower MAC code
This commit is contained in:
parent
a4c4e5a1ab
commit
7ee08faee0
45 changed files with 4217 additions and 0 deletions
141
src/phy/tetra_burst_sync.c
Normal file
141
src/phy/tetra_burst_sync.c
Normal file
|
@ -0,0 +1,141 @@
|
|||
/* Implementation of TETRA burst synchronization */
|
||||
|
||||
/* (C) 2011 by Harald Welte <laforge@gnumonks.org>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <osmocore/utils.h>
|
||||
|
||||
//#define DEBUG
|
||||
|
||||
#include <tetra_common.h>
|
||||
#include <phy/tetra_burst.h>
|
||||
#include <tetra_tdma.h>
|
||||
#include <phy/tetra_burst_sync.h>
|
||||
|
||||
struct tetra_phy_state t_phy_state;
|
||||
|
||||
void tetra_burst_rx_cb(const uint8_t *burst, unsigned int len, enum tetra_train_seq type, void *priv);
|
||||
|
||||
/* input a raw bitstream into the tetra burst synchronizaer */
|
||||
int tetra_burst_sync_in(struct tetra_rx_state *trs, uint8_t *bits, unsigned int len)
|
||||
{
|
||||
int rc;
|
||||
unsigned int train_seq_offs;
|
||||
int cpy_len;
|
||||
|
||||
DEBUGP("burst_sync_in: %u bits, state %u\n", len, trs->state);
|
||||
|
||||
/* First: append the data to the bitbuf */
|
||||
if (sizeof(trs->bitbuf) - trs->bits_in_buf < len)
|
||||
cpy_len = sizeof(trs->bitbuf) - trs->bits_in_buf;
|
||||
else
|
||||
cpy_len = len;
|
||||
memcpy(trs->bitbuf + trs->bits_in_buf, bits, cpy_len);
|
||||
trs->bits_in_buf += cpy_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 cpy_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
|
||||
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 cpy_len;
|
||||
} else {
|
||||
/* we have successfully received (at least) one frame */
|
||||
tetra_tdma_time_add_tn(&t_phy_state.time, 1);
|
||||
printf("\nBURST: %s\n", bitdump(trs->bitbuf, TETRA_BITS_PER_TS));
|
||||
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;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
return cpy_len;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue