falconia has uploaded this change for review. ( 
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/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(-)



  git pull ssh://gerrit.osmocom.org:29418/libosmo-abis refs/changes/93/38293/1

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/raa_prime.h b/include/osmocom/trau/raa_prime.h
index 43bfe4e..7c3e817 100644
--- a/include/osmocom/trau/raa_prime.h
+++ b/include/osmocom/trau/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..b34c67a
--- /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/raa_prime.h>.
+ *
+ * Author: Mychaela N. Falconia <[email protected]>, 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/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..8f9b092
--- /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 <[email protected]>, 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/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: newchange
Gerrit-Project: libosmo-abis
Gerrit-Branch: master
Gerrit-Change-Id: I1347a25ce97d5022502ee9112caded66315b09a4
Gerrit-Change-Number: 38293
Gerrit-PatchSet: 1
Gerrit-Owner: falconia <[email protected]>

Reply via email to