falconia has submitted this change. (
https://gerrit.osmocom.org/c/libosmo-abis/+/38293?usp=email )
Change subject: libosmotrau: implement RAA' decoder function
......................................................................
libosmotrau: implement RAA' decoder function
The previous patch implements RAA' encoder function;
now comes the decoder.
Related: OS#6167
Change-Id: I1347a25ce97d5022502ee9112caded66315b09a4
---
M .gitignore
M include/osmocom/trau/csd_raa_prime.h
M src/Makefile.am
A src/trau/raa_prime_decode.c
M tests/Makefile.am
A tests/raa_prime/test_dec.c
M tests/testsuite.at
7 files changed, 280 insertions(+), 0 deletions(-)
Approvals:
falconia: Looks good to me, approved
Jenkins Builder: Verified
diff --git a/.gitignore b/.gitignore
index 2f3ba99..fd0974d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -40,6 +40,7 @@
tests/subchan_demux/.dirstamp
tests/subchan_demux/subchan_demux_test
tests/ipa_recv/ipa_recv_test
+tests/raa_prime/test_dec
tests/raa_prime/test_enc
tests/trau_pcu_ericsson/trau_pcu_ericsson_test
tests/trau_conv/trau16_to_rtp
diff --git a/include/osmocom/trau/csd_raa_prime.h b/include/osmocom/trau/csd_raa_prime.h
index 43bfe4e..7c3e817 100644
--- a/include/osmocom/trau/csd_raa_prime.h
+++ b/include/osmocom/trau/csd_raa_prime.h
@@ -55,3 +55,31 @@
void osmo_csd144_to_atrau_ra2(uint8_t *out_bytes, const ubit_t *m_bits,
const ubit_t *d_bits, ubit_t atrau_c4,
ubit_t atrau_c5);
+
+/*! Decode aligned A-TRAU frame into user form of 288 D-bits and
+ * two M-bits; the A-TRAU frame input is given in unpacked bit form.
+ *
+ * \param[out] m_bits caller-provided buffer for 2 M-bits
+ * \param[out] d_bits caller-provided buffer for 288 user data bits
+ * \param[out] atrau_c4 return of A-TRAU frame bit C4 (NULL pointer OK)
+ * \param[out] atrau_c5 return of A-TRAU frame bit C5 (NULL pointer OK)
+ * \param[in] atrau_bits A-TRAU frame as 320 unpacked bits
+ * \return 0 if A-TRAU frame is good; negative if it is invalid
+ */
+int osmo_csd144_from_atrau_bits(ubit_t *m_bits, ubit_t *d_bits,
+ ubit_t *atrau_c4, ubit_t *atrau_c5,
+ const ubit_t *atrau_bits);
+
+/*! Decode aligned A-TRAU frame into user form of 288 D-bits and
+ * two M-bits; the A-TRAU frame input is given in RA2 octet form.
+ *
+ * \param[out] m_bits caller-provided buffer for 2 M-bits
+ * \param[out] d_bits caller-provided buffer for 288 user data bits
+ * \param[out] atrau_c4 return of A-TRAU frame bit C4 (NULL pointer OK)
+ * \param[out] atrau_c5 return of A-TRAU frame bit C5 (NULL pointer OK)
+ * \param[in] atrau_bytes A-TRAU frame as 160 RA2 octets
+ * \return 0 if A-TRAU frame is good; negative if it is invalid
+ */
+int osmo_csd144_from_atrau_ra2(ubit_t *m_bits, ubit_t *d_bits,
+ ubit_t *atrau_c4, ubit_t *atrau_c5,
+ const uint8_t *atrau_bytes);
diff --git a/src/Makefile.am b/src/Makefile.am
index 6d8bc98..3a6b83d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -42,6 +42,7 @@
$(NULL)
libosmotrau_la_LIBADD = $(COMMONLIBS) $(LIBOSMOCODEC_LIBS) $(ORTP_LIBS)
libosmotrau_la_SOURCES = trau/csd_ra2.c \
+ trau/raa_prime_decode.c \
trau/raa_prime_encode.c \
trau/trau_frame.c \
trau/trau_pcu_ericsson.c \
diff --git a/src/trau/raa_prime_decode.c b/src/trau/raa_prime_decode.c
new file mode 100644
index 0000000..65d916e
--- /dev/null
+++ b/src/trau/raa_prime_decode.c
@@ -0,0 +1,121 @@
+/*
+ * This C module contains the implementation of RAA' (RAA-prime) function
+ * in the decoding direction, from an A-TRAU frame to user bits.
+ * The interface is defined in <osmocom/trau/csd_raa_prime.h>.
+ *
+ * Author: Mychaela N. Falconia <falcon(a)freecalypso.org>rg>, 2024 - however,
+ * Mother Mychaela's contributions are NOT subject to copyright.
+ * No rights reserved, all rights relinquished.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <osmocom/core/bits.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/trau/csd_raa_prime.h>
+#include <osmocom/trau/csd_ra2.h>
+
+static int decode_zsp(const ubit_t *atrau_bits, unsigned *pos)
+{
+ unsigned pos1, n;
+
+ /* guard bits must be set */
+ if (!atrau_bits[0] || !atrau_bits[7])
+ return -EINVAL;
+ pos1 = 0;
+ for (n = 0; n < 5; n++) {
+ pos1 <<= 1;
+ pos1 |= atrau_bits[2 + n];
+ }
+ if (pos1 < 1 || pos1 > 29)
+ return -EINVAL;
+ *pos = pos1 - 1;
+ return 0;
+}
+
+static int decode_subframe(ubit_t *d_bits, const ubit_t *atrau_bits)
+{
+ ubit_t zi, cbit;
+ unsigned pos, z_pos, numd;
+ int rc;
+
+ /* consume Zi bit and weed out the trivial case */
+ zi = *atrau_bits++;
+ if (zi) {
+ memcpy(d_bits, atrau_bits, 36);
+ return 0;
+ }
+ pos = 0;
+ for (;;) {
+ if (pos > 28)
+ return -EINVAL;
+ rc = decode_zsp(atrau_bits + pos, &z_pos);
+ if (rc < 0)
+ return rc;
+ cbit = atrau_bits[pos + 1];
+ if (z_pos < pos)
+ return -EINVAL;
+ numd = z_pos - pos;
+ memcpy(d_bits + pos, atrau_bits + 8 + pos, numd);
+ memset(d_bits + pos + numd, 0, 8);
+ pos += numd + 8;
+ if (cbit)
+ break;
+ }
+ OSMO_ASSERT(pos <= 36);
+ numd = 36 - pos;
+ memcpy(d_bits + pos, atrau_bits + pos, numd);
+ return 0;
+}
+
+int osmo_csd144_from_atrau_bits(ubit_t *m_bits, ubit_t *d_bits,
+ ubit_t *atrau_c4, ubit_t *atrau_c5,
+ const ubit_t *atrau_bits)
+{
+ static const ubit_t header_bits[20] = {0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 1, 1};
+ int subf, rc;
+
+ if (memcmp(atrau_bits, header_bits, 20) != 0)
+ return -EINVAL;
+ if (atrau_c4)
+ *atrau_c4 = atrau_bits[20];
+ if (atrau_c5)
+ *atrau_c5 = atrau_bits[21];
+ m_bits[0] = atrau_bits[22];
+ m_bits[1] = atrau_bits[23];
+
+ /* done with the header, do the 8 subframes */
+ atrau_bits += 24;
+ for (subf = 0; subf < 8; subf++) {
+ rc = decode_subframe(d_bits, atrau_bits);
+ if (rc < 0)
+ return rc;
+ atrau_bits += 37;
+ d_bits += 36;
+ }
+ return 0;
+}
+
+int osmo_csd144_from_atrau_ra2(ubit_t *m_bits, ubit_t *d_bits,
+ ubit_t *atrau_c4, ubit_t *atrau_c5,
+ const uint8_t *atrau_bytes)
+{
+ ubit_t atrau_bits[OSMO_ATRAU_FRAME_BITS];
+
+ osmo_csd_ra2_16k_unpack(atrau_bits, atrau_bytes, OSMO_ATRAU_RA2_OCTETS);
+ return osmo_csd144_from_atrau_bits(m_bits, d_bits, atrau_c4, atrau_c5,
+ atrau_bits);
+}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index d50b09a..fd264d0 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -7,6 +7,7 @@
ipa_proxy_test \
subchan_demux/subchan_demux_test \
ipa_recv/ipa_recv_test \
+ raa_prime/test_dec \
raa_prime/test_enc \
trau_conv/trau16_to_rtp \
trau_sync/trau_sync_test \
@@ -39,6 +40,10 @@
$(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) \
$(LIBOSMOVTY_LIBS)
+raa_prime_test_dec_SOURCES = raa_prime/test_dec.c
+raa_prime_test_dec_LDADD = $(top_builddir)/src/libosmotrau.la \
+ $(LIBOSMOCORE_LIBS)
+
raa_prime_test_enc_SOURCES = raa_prime/test_enc.c
raa_prime_test_enc_LDADD = $(top_builddir)/src/libosmotrau.la \
$(LIBOSMOCORE_LIBS)
diff --git a/tests/raa_prime/test_dec.c b/tests/raa_prime/test_dec.c
new file mode 100644
index 0000000..9ca1b02
--- /dev/null
+++ b/tests/raa_prime/test_dec.c
@@ -0,0 +1,118 @@
+/*
+ * This C module is a unit test program for libosmotrau implementation
+ * of RAA' function in the decoding direction.
+ *
+ * Author: Mychaela N. Falconia <falcon(a)freecalypso.org>rg>, 2024 - however,
+ * Mother Mychaela's contributions are NOT subject to copyright.
+ * No rights reserved, all rights relinquished.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <osmocom/core/bits.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/trau/csd_raa_prime.h>
+
+static uint8_t frame_buf[OSMO_ATRAU_RA2_OCTETS];
+static unsigned hex_chunk_count;
+
+static void process_frame(void)
+{
+ ubit_t m_bits[2], d_bits[288];
+ uint8_t d_bits_packed[36];
+ int rc, i;
+
+ rc = osmo_csd144_from_atrau_ra2(m_bits, d_bits, NULL, NULL, frame_buf);
+ if (rc < 0) {
+ printf("Bad A-TRAU frame!\n");
+ return;
+ }
+ osmo_ubit2pbit(d_bits_packed, d_bits, 288);
+ printf("%u%u ", m_bits[0], m_bits[1]);
+ for (i = 0; i < 36; i++)
+ printf("%02x", d_bits_packed[i]);
+ putchar('\n');
+}
+
+static void process_hex_input(const char *hex_str)
+{
+ osmo_hexparse(hex_str, frame_buf + hex_chunk_count * 40, 40);
+ hex_chunk_count++;
+ if (hex_chunk_count >= 4) {
+ process_frame();
+ hex_chunk_count = 0;
+ }
+}
+
+static void process_line(char *linebuf, const char *infname, int lineno)
+{
+ char *cp = linebuf, *hex_str;
+ int ndig;
+
+ while (isspace(*cp))
+ cp++;
+ if (*cp == '\0' || *cp == '#')
+ return;
+ /* expect string of 80 hex digits */
+ hex_str = cp;
+ for (ndig = 0; ndig < 80; ndig++) {
+ if (!isxdigit(*cp))
+ goto inv;
+ cp++;
+ }
+ if (*cp) {
+ if (!isspace(*cp))
+ goto inv;
+ *cp++ = '\0';
+ }
+ /* must be end of non-comment line */
+ while (isspace(*cp))
+ cp++;
+ if (*cp != '\0' && *cp != '#')
+ goto inv;
+
+ process_hex_input(hex_str);
+ return;
+
+inv: fprintf(stderr, "%s line %d: invalid syntax\n", infname, lineno);
+ exit(1);
+}
+
+int main(int argc, char **argv)
+{
+ const char *infname;
+ FILE *inf;
+ char linebuf[256];
+ int lineno;
+
+ if (argc != 2) {
+ fprintf(stderr, "usage: %s input-file\n", argv[0]);
+ exit(1);
+ }
+ infname = argv[1];
+ inf = fopen(infname, "r");
+ if (!inf) {
+ perror(infname);
+ exit(1);
+ }
+
+ for (lineno = 1; fgets(linebuf, sizeof(linebuf), inf); lineno++)
+ process_line(linebuf, infname, lineno);
+ fclose(inf);
+ exit(0);
+}
diff --git a/tests/testsuite.at b/tests/testsuite.at
index c430220..70e7f25 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -36,6 +36,12 @@
AT_CHECK([$abs_top_builddir/tests/raa_prime/test_enc
$abs_srcdir/raa_prime/d144-ul-input.asc], [0], [expout], [ignore])
AT_CLEANUP
+AT_SETUP([raa_prime_decode])
+AT_KEYWORDS([raa_prime_decode])
+cat $abs_srcdir/raa_prime/d144-ul-input.asc > expout
+AT_CHECK([$abs_top_builddir/tests/raa_prime/test_dec
$abs_srcdir/raa_prime/nokia-tcsm2-atrau.hex], [0], [expout], [ignore])
+AT_CLEANUP
+
AT_SETUP([trau_sync])
AT_KEYWORDS([trau_sync])
cat $abs_srcdir/trau_sync/trau_sync_test.ok > expout
--
To view, visit
https://gerrit.osmocom.org/c/libosmo-abis/+/38293?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: merged
Gerrit-Project: libosmo-abis
Gerrit-Branch: master
Gerrit-Change-Id: I1347a25ce97d5022502ee9112caded66315b09a4
Gerrit-Change-Number: 38293
Gerrit-PatchSet: 5
Gerrit-Owner: falconia <falcon(a)freecalypso.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: falconia <falcon(a)freecalypso.org>
Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: pespin <pespin(a)sysmocom.de>