diff options
author | Sylvain Munaut <tnt@246tNt.com> | 2011-10-19 08:34:25 +0200 |
---|---|---|
committer | Sylvain Munaut <tnt@246tNt.com> | 2011-10-19 08:34:25 +0200 |
commit | a41f64145764bb2eb056039e2a0ca7ca62535db2 (patch) | |
tree | 31c59c95eef86f0a8089483c2896aa16c978f819 /src/l1 | |
parent | 63e9d84adbc59047cb9bb27f0d89fab330e8b7f2 (diff) |
l1/ccch: Add CCCH (PCH/AGCH) channel coding
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
Diffstat (limited to 'src/l1')
-rw-r--r-- | src/l1/Makefile.am | 2 | ||||
-rw-r--r-- | src/l1/ccch.c | 113 |
2 files changed, 114 insertions, 1 deletions
diff --git a/src/l1/Makefile.am b/src/l1/Makefile.am index fcc8568..4857242 100644 --- a/src/l1/Makefile.am +++ b/src/l1/Makefile.am @@ -6,4 +6,4 @@ noinst_LIBRARIES = libgmr1-l1.a libgmr1_l1_a_SOURCES = \ conv.c crc.c interleave.c punct.c scramb.c \ - bcch.c + bcch.c ccch.c diff --git a/src/l1/ccch.c b/src/l1/ccch.c new file mode 100644 index 0000000..4ece592 --- /dev/null +++ b/src/l1/ccch.c @@ -0,0 +1,113 @@ +/* GMR-1 CCCH channel coding */ +/* See GMR-1 05.003 (ETSI TS 101 376-5-3 V1.2.1) - Section 6.2 & 6.3 */ + +/* (C) 2011 by Sylvain Munaut <tnt@246tNt.com> + * 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/>. + */ + +/*! \addtogroup ccch + * @{ + */ + +/*! \file l1/ccch.c + * \brief Osmocom GMR-1 CCCH (PCH/AGCH) channel coding implementation + */ + +#include <stdint.h> +#include <string.h> + +#include <osmocom/gmr1/l1/conv.h> +#include <osmocom/gmr1/l1/crc.h> +#include <osmocom/gmr1/l1/interleave.h> +#include <osmocom/gmr1/l1/scramb.h> + + +static struct osmo_conv_code gmr1_conv_ccch; +static int ccch_init_done = 0; + +static void +gmr1_ccch_init(void) +{ + /* Init convolutional coder */ + memcpy(&gmr1_conv_ccch, &gmr1_conv_12, sizeof(struct osmo_conv_code)); + gmr1_conv_ccch.len = 208; + + /* Init done */ + ccch_init_done = 1; +} + +#define GMR1_CCCH_CHECK_INIT if (!ccch_init_done) gmr1_ccch_init() + + +/*! \brief Stateless GMR-1 CCCH channel coder + * \param[out] bits_e Data bits of a burst + * \param[in] l2 L2 packet data + * + * L2 data is 24 byte long, and bits_e is a 432 hard bit array to be + * mapped on a burst. + */ +void +gmr1_ccch_encode(ubit_t *bits_e, uint8_t *l2) +{ + ubit_t bits_u[208]; + ubit_t bits_c[428]; + ubit_t bits_ep[432]; + int i; + + GMR1_CCCH_CHECK_INIT; + + for (i=0; i<4; i++) + bits_ep[i] = bits_ep[431-i] = 0; + + osmo_pbit2ubit_ext(bits_u, 0, l2, 0, 192, 1); + osmo_crc16gen_set_bits(&gmr1_crc16, bits_u, 192, bits_u+192); + osmo_conv_encode(&gmr1_conv_ccch, bits_u, bits_c); + gmr1_interleave_intra(&bits_ep[4], bits_c, 53); + gmr1_scramble_ubit(bits_e, bits_ep, 432); +} + +/*! \brief Stateless GMR-1 CCCH channel decoder + * \param[out] l2 L2 packet data + * \param[in] bits_e Data bits of a burst + * + * L2 data is 24 byte long, and bits_e is a 432 hard bit array to be + * mapped on a burst. + */ +int +gmr1_ccch_decode(uint8_t *l2, sbit_t *bits_e, int *conv_rv) +{ + sbit_t bits_ep[432]; + sbit_t bits_c[428]; + ubit_t bits_u[208]; + int rv; + + GMR1_CCCH_CHECK_INIT; + + gmr1_scramble_sbit(bits_ep, bits_e, 432); + gmr1_deinterleave_intra(bits_c, &bits_ep[4], 53); + + rv = osmo_conv_decode(&gmr1_conv_ccch, bits_c, bits_u); + if (conv_rv) + *conv_rv = rv; + + rv = osmo_crc16gen_check_bits(&gmr1_crc16, bits_u, 192, bits_u+192); + + osmo_ubit2pbit_ext(l2, 0, bits_u, 0, 192, 1); + + return rv; +} + +/*! }@ */ |