falconia has uploaded this change for review.

View Change

trau: factor out V.110 frame conversion functions

Implementation of CSD conversion between TRAU frames and CLEARMODE
inside osmo_trau2rtp() and osmo_rtp2trau() contains lower-level
functions for conversion of individual V.110 frames and for alignment
checking. Factor these functions out into API, as they are useful
for other applications besides TRAU<->RTP conversion:

* Compression and decompression functions that convert between
standard (but inefficient) CLEARMODE and compressed-CSD RTP format
of TW-TS-007;

* Implementations of IWFs that terminate CSD RTP streams at the CN
and support both CLEARMODE and TW-TS-007.

Change-Id: I3f51254b4b985a0f8499c375b61069ca24f77ae8
---
M include/Makefile.am
A include/osmocom/trau/csd_v110.h
M src/Makefile.am
A src/trau/csd_v110.c
4 files changed, 160 insertions(+), 0 deletions(-)

git pull ssh://gerrit.osmocom.org:29418/libosmo-abis refs/changes/59/41159/1
diff --git a/include/Makefile.am b/include/Makefile.am
index 565e3cb..862292e 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -27,6 +27,7 @@
osmocom/trau/clearmode.h \
osmocom/trau/csd_ra2.h \
osmocom/trau/csd_raa_prime.h \
+ osmocom/trau/csd_v110.h \
osmocom/trau/tfo_frame.h \
osmocom/trau/trau_frame.h \
osmocom/trau/trau_pcu_ericsson.h \
diff --git a/include/osmocom/trau/csd_v110.h b/include/osmocom/trau/csd_v110.h
new file mode 100644
index 0000000..05d4ed5
--- /dev/null
+++ b/include/osmocom/trau/csd_v110.h
@@ -0,0 +1,40 @@
+/*
+ * This header file defines the public API for some helper functions that
+ * work with CSD V.110 frames represented in the standard 64 kbit/s CLEARMODE
+ * format of 3GPP TS 48.103, _without_ compression per TW-TS-007, but _with_
+ * Osmocom-introduced constraint that the pair or quadruple of V.110 frames
+ * in RA2 encoding has to be naturally aligned within each 20 ms RTP packet.
+ *
+ * Author: Mychaela N. Falconia <falcon@freecalypso.org>, 2025 - 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.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <osmocom/core/bits.h>
+
+/* conversion from distilled 63-bit format (as used in TRAU frames) to full
+ * 80-bit V.110 format, with or without RA2. */
+
+void osmo_csd_63bits_to_v110_bits(ubit_t *out, const ubit_t *in);
+void osmo_csd_63bits_to_v110_ir8(uint8_t *out, const ubit_t *in);
+void osmo_csd_63bits_to_v110_ir16(uint8_t *out, const ubit_t *in);
+
+/* functions to verify V.110 frame alignment after RA2 decoding, and to convert
+ * to our distilled 63-bit format. */
+
+bool osmo_csd_check_v110_align(const ubit_t *ra_bits);
+void osmo_csd_v110_to_63bits(ubit_t *out, const ubit_t *ra_bits);
diff --git a/src/Makefile.am b/src/Makefile.am
index fc5b59b..6683d44 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -53,6 +53,7 @@
$(NULL)
libosmotrau_la_LIBADD = $(COMMONLIBS) $(LIBOSMOCODEC_LIBS) $(ORTP_LIBS)
libosmotrau_la_SOURCES = trau/csd_ra2.c \
+ trau/csd_v110.c \
trau/raa_prime_decode.c \
trau/raa_prime_encode.c \
trau/tfo_frame.c \
diff --git a/src/trau/csd_v110.c b/src/trau/csd_v110.c
new file mode 100644
index 0000000..431073c
--- /dev/null
+++ b/src/trau/csd_v110.c
@@ -0,0 +1,118 @@
+/*
+ * This C module contains the implementation of CSD V.110 helper functions
+ * for CLEARMODE defined in <osmocom/trau/csd_v110.h>.
+ *
+ * Author: Mychaela N. Falconia <falcon@freecalypso.org>, 2025 - 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 <stdbool.h>
+#include <string.h>
+
+#include <osmocom/core/bits.h>
+#include <osmocom/trau/csd_ra2.h>
+#include <osmocom/trau/csd_v110.h>
+
+/*! Convert V.110 frame from distilled 63-bit form (as it appears in TRAU
+ * frames) to full 80-bit form by adding sync pattern bits.
+ * \param[out] out buffer of size 80 ubit_t
+ * \param[in] in 63-bit distilled V.110 frame
+ */
+void osmo_csd_63bits_to_v110_bits(ubit_t *out, const ubit_t *in)
+{
+ int i;
+
+ /* the first 8 bits are sync zeros */
+ memset(out, 0, 8);
+ out += 8;
+ /* for the rest, we have to expand 63 bits into 72 */
+ for (i = 0; i < 9; i++) {
+ *out++ = 1;
+ memcpy(out, in, 7);
+ in += 7;
+ out += 7;
+ }
+}
+
+/*! Convert V.110 frame from distilled 63-bit form (as it appears in TRAU
+ * frames) to external octet form (RA2 with 8 kbit/s IR) form by adding
+ * sync pattern bits and applying RA2.
+ * \param[out] out buffer of size 80 octets
+ * \param[in] in 63-bit distilled V.110 frame
+ */
+void osmo_csd_63bits_to_v110_ir8(uint8_t *out, const ubit_t *in)
+{
+ ubit_t ra_bits[80];
+
+ osmo_csd_63bits_to_v110_bits(ra_bits, in);
+ /* RA2: 1 bit per output byte */
+ osmo_csd_ra2_8k_pack(out, ra_bits, 80);
+}
+
+/*! Convert V.110 frame from distilled 63-bit form (as it appears in TRAU
+ * frames) to external octet form (RA2 with 16 kbit/s IR) form by adding
+ * sync pattern bits and applying RA2.
+ * \param[out] out buffer of size 40 octets
+ * \param[in] in 63-bit distilled V.110 frame
+ */
+void osmo_csd_63bits_to_v110_ir16(uint8_t *out, const ubit_t *in)
+{
+ ubit_t ra_bits[80];
+
+ osmo_csd_63bits_to_v110_bits(ra_bits, in);
+ /* RA2: 2 bits per output byte */
+ osmo_csd_ra2_16k_pack(out, ra_bits, 40);
+}
+
+/*! Check alignment of unpacked 80-bit V.110 frame.
+ * \param[in] ra_bits candidate V.110 frame in standard 80-bit form
+ * \returns true if V.110 alignment pattern is correct, false otherwise
+ */
+bool osmo_csd_check_v110_align(const ubit_t *ra_bits)
+{
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ if (ra_bits[i])
+ return false;
+ }
+ for (i = 1; i < 10; i++) {
+ if (!ra_bits[i * 8])
+ return false;
+ }
+ return true;
+}
+
+/*! Convert V.110 frame from standard 80-bit form (unpacked) to
+ * our distilled 63-bit form (as it appears in TRAU frames).
+ * \param[out] out buffer of size 63 ubit_t
+ * \param[in] in 80-bit standard V.110 frame
+ *
+ * This function ignores all 17 sync pattern bits and assumes that the
+ * V.110 frame is correctly aligned. Therefore, this function should
+ * be called after osmo_csd_check_v110_align().
+ */
+void osmo_csd_v110_to_63bits(ubit_t *out, const ubit_t *ra_bits)
+{
+ memcpy(out, ra_bits + 9, 7);
+ memcpy(out + 7, ra_bits + 17, 7);
+ memcpy(out + 14, ra_bits + 25, 7);
+ memcpy(out + 21, ra_bits + 33, 7);
+ memcpy(out + 28, ra_bits + 41, 7);
+ memcpy(out + 35, ra_bits + 49, 7);
+ memcpy(out + 42, ra_bits + 57, 7);
+ memcpy(out + 49, ra_bits + 65, 7);
+ memcpy(out + 56, ra_bits + 73, 7);
+}

To view, visit change 41159. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: newchange
Gerrit-Project: libosmo-abis
Gerrit-Branch: master
Gerrit-Change-Id: I3f51254b4b985a0f8499c375b61069ca24f77ae8
Gerrit-Change-Number: 41159
Gerrit-PatchSet: 1
Gerrit-Owner: falconia <falcon@freecalypso.org>