[PATCH] openbsc[master]: V42BIS integration and unit test

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

dexter gerrit-no-reply at lists.osmocom.org
Wed Aug 17 14:28:46 UTC 2016


Hello Harald Welte, Jenkins Builder,

I'd like you to reexamine a change.  Please visit

    https://gerrit.osmocom.org/644

to look at the new patch set (#21).

V42BIS integration and unit test

The previously committed SPANDSP v42bis implementation has been edited
to function outside the SPANDSP library. Debug printf statements were
changed into DEBUGP statements. Als removed the assembely code
in top_bit().

Change-Id: I689413f2541b6def0625ce6bd96f1f488f05f99d
---
M openbsc/.gitignore
M openbsc/configure.ac
M openbsc/include/openbsc/Makefile.am
M openbsc/include/openbsc/debug.h
M openbsc/include/openbsc/v42bis.h
R openbsc/include/openbsc/v42bis_private.h
M openbsc/src/gprs/Makefile.am
M openbsc/src/gprs/sgsn_main.c
M openbsc/src/gprs/v42bis.c
M openbsc/tests/Makefile.am
M openbsc/tests/testsuite.at
A openbsc/tests/v42bis/Makefile.am
A openbsc/tests/v42bis/v42bis_test.c
A openbsc/tests/v42bis/v42bis_test.ok
14 files changed, 252 insertions(+), 24 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/44/644/21

diff --git a/openbsc/.gitignore b/openbsc/.gitignore
index e75b9eb..6fbd463 100644
--- a/openbsc/.gitignore
+++ b/openbsc/.gitignore
@@ -84,6 +84,7 @@
 tests/xid/xid_test
 tests/sndcp_xid/sndcp_xid_test
 tests/slhc/slhc_test
+tests/v42bis/v42bis_test
 
 tests/atconfig
 tests/atlocal
diff --git a/openbsc/configure.ac b/openbsc/configure.ac
index 18980b0..1df14fe 100644
--- a/openbsc/configure.ac
+++ b/openbsc/configure.ac
@@ -232,6 +232,7 @@
     tests/xid/Makefile
     tests/sndcp_xid/Makefile
     tests/slhc/Makefile
+    tests/v42bis/Makefile
     doc/Makefile
     doc/examples/Makefile
     Makefile)
diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am
index 88a7e2c..bc56d0d 100644
--- a/openbsc/include/openbsc/Makefile.am
+++ b/openbsc/include/openbsc/Makefile.am
@@ -19,7 +19,7 @@
 		 gprs_gsup_client.h bsc_msg_filter.h \
 		 oap.h oap_messages.h \
 		 gtphub.h gprs_llc_xid.h gprs_sndcp.h gprs_sndcp_xid.h \
-		slhc.h gprs_sndcp_comp.h gprs_sndcp_pcomp.h
+		slhc.h gprs_sndcp_comp.h gprs_sndcp_pcomp.h v42bis.h
 
 openbsc_HEADERS = gsm_04_08.h meas_rep.h bsc_api.h
 openbscdir = $(includedir)/openbsc
diff --git a/openbsc/include/openbsc/debug.h b/openbsc/include/openbsc/debug.h
index 90ddca5..ca3d4ad 100644
--- a/openbsc/include/openbsc/debug.h
+++ b/openbsc/include/openbsc/debug.h
@@ -37,6 +37,7 @@
 	DGTPHUB,
 	DRANAP,
 	DSUA,
+	DV42BIS,
 	Debug_LastEntry,
 };
 
diff --git a/openbsc/include/openbsc/v42bis.h b/openbsc/include/openbsc/v42bis.h
index f13e5c5..1025296 100644
--- a/openbsc/include/openbsc/v42bis.h
+++ b/openbsc/include/openbsc/v42bis.h
@@ -33,9 +33,13 @@
 \section v42bis_page_sec_2 How does it work?
 */
 
+#include <stdint.h>
+
 #if !defined(_SPANDSP_V42BIS_H_)
 #define _SPANDSP_V42BIS_H_
 
+#define SPAN_DECLARE(x) x
+
 #define V42BIS_MAX_BITS         12
 #define V42BIS_MAX_CODEWORDS    4096    /* 2^V42BIS_MAX_BITS */
 #define V42BIS_TABLE_SIZE       5021    /* This should be a prime >(2^V42BIS_MAX_BITS) */
diff --git a/openbsc/include/openbsc/private_v42bis.h b/openbsc/include/openbsc/v42bis_private.h
similarity index 100%
rename from openbsc/include/openbsc/private_v42bis.h
rename to openbsc/include/openbsc/v42bis_private.h
diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am
index 2910c02..f479d56 100644
--- a/openbsc/src/gprs/Makefile.am
+++ b/openbsc/src/gprs/Makefile.am
@@ -27,7 +27,7 @@
 			gprs_utils.c gprs_gsup_client.c \
 			sgsn_cdr.c sgsn_ares.c \
 			oap.c oap_messages.c gprs_llc_xid.c gprs_sndcp_xid.c \
-			slhc.c gprs_sndcp_comp.c gprs_sndcp_pcomp.c
+			slhc.c gprs_sndcp_comp.c gprs_sndcp_pcomp.c v42bis.c
 osmo_sgsn_LDADD = 	\
 			$(top_builddir)/src/libcommon/libcommon.a \
 			-lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) $(LIBCARES_LIBS) \
diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c
index 894ce84..44a8921 100644
--- a/openbsc/src/gprs/sgsn_main.c
+++ b/openbsc/src/gprs/sgsn_main.c
@@ -297,6 +297,11 @@
 		.description = "RFC1144 TCP/IP Header compression (SLHC)",
 		.enabled = 1, .loglevel = LOGL_DEBUG,
 	},
+	[DV42BIS] = {
+		.name = "DV42BIS",
+		.description = "V42.bis data compression (SNDCP)",
+		.enabled = 1, .loglevel = LOGL_DEBUG,
+	}
 };
 
 static const struct log_info gprs_log_info = {
diff --git a/openbsc/src/gprs/v42bis.c b/openbsc/src/gprs/v42bis.c
index 6d38916..de9c2af 100644
--- a/openbsc/src/gprs/v42bis.c
+++ b/openbsc/src/gprs/v42bis.c
@@ -31,9 +31,8 @@
 
 /*! \file */
 
-#if defined(HAVE_CONFIG_H)
-#include "config.h"
-#endif
+#define FALSE 0
+#define TRUE 1
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -44,13 +43,10 @@
 #include <ctype.h>
 #include <assert.h>
 
-#include "spandsp/telephony.h"
-#include "spandsp/logging.h"
-#include "spandsp/bit_operations.h"
-#include "spandsp/v42bis.h"
+#include <openbsc/v42bis.h>
+#include <openbsc/v42bis_private.h>
+#include <openbsc/debug.h>
 
-#include "spandsp/private/logging.h"
-#include "spandsp/private/v42bis.h"
 
 /* Fixed parameters from the spec. */
 #define V42BIS_N3               8   /* Character size (bits) */
@@ -310,7 +306,7 @@
                 {
                     if (ss->transparent)
                     {
-                        printf("Going compressed\n");
+                        DEBUGP(DV42BIS,"Going compressed\n");
                         /* 7.8.1 Transition to compressed mode */
                         /* Switch out of transparent now, between codes. We need to send the octet which did not
                         match, just before switching. */
@@ -332,7 +328,7 @@
                 {
                     if (!ss->transparent)
                     {
-                        printf("Going transparent\n");
+                        DEBUGP(DV42BIS,"Going transparent\n");
                         /* 7.8.2 Transition to transparent mode */
                         /* Switch into transparent now, between codes, and the unmatched octet should
                            go out in transparent mode, just below */
@@ -401,7 +397,7 @@
     {
         if (s->compress.dict[i].parent_code != 0xFFFF)
         {
-            printf("Entry %4x, prior %4x, leaves %d, octet %2x\n", i, s->compress.dict[i].parent_code, s->compress.dict[i].leaves, s->compress.dict[i].node_octet);
+            DEBUGP(DV42BIS,"Entry %4x, prior %4x, leaves %d, octet %2x\n", i, s->compress.dict[i].parent_code, s->compress.dict[i].leaves, s->compress.dict[i].node_octet);
         }
     }
     return 0;
@@ -454,13 +450,13 @@
                 ss->escaped = FALSE;
                 if (code == V42BIS_ECM)
                 {
-                    printf("Hit V42BIS_ECM\n");
+                    DEBUGP(DV42BIS,"Hit V42BIS_ECM\n");
                     ss->transparent = FALSE;
                     code_len = ss->v42bis_parm_c2;
                 }
                 else if (code == V42BIS_EID)
                 {
-                    printf("Hit V42BIS_EID\n");
+                    DEBUGP(DV42BIS,"Hit V42BIS_EID\n");
                     ss->output_buf[ss->output_octet_count++] = ss->escape_code - 1;
                     if (ss->output_octet_count >= ss->max_len - s->v42bis_parm_n7)
                     {
@@ -470,11 +466,11 @@
                 }
                 else if (code == V42BIS_RESET)
                 {
-                    printf("Hit V42BIS_RESET\n");
+                    DEBUGP(DV42BIS,"Hit V42BIS_RESET\n");
                 }
                 else
                 {
-                    printf("Hit V42BIS_???? - %" PRIu32 "\n", code);
+                    DEBUGP(DV42BIS,"Hit V42BIS_???? - %" PRIu32 "\n", code);
                 }
             }
             else if (code == ss->escape_code)
@@ -500,17 +496,17 @@
                 switch (new_code)
                 {
                 case V42BIS_ETM:
-                    printf("Hit V42BIS_ETM\n");
+                    DEBUGP(DV42BIS,"Hit V42BIS_ETM\n");
                     ss->transparent = TRUE;
                     code_len = 8;
                     break;
                 case V42BIS_FLUSH:
-                    printf("Hit V42BIS_FLUSH\n");
+                    DEBUGP(DV42BIS,"Hit V42BIS_FLUSH\n");
                     v42bis_decompress_flush(s);
                     break;
                 case V42BIS_STEPUP:
                     /* We need to increase the codeword size */
-                    printf("Hit V42BIS_STEPUP\n");
+                    DEBUGP(DV42BIS,"Hit V42BIS_STEPUP\n");
                     if (ss->v42bis_parm_c3 >= s->v42bis_parm_n2)
                     {
                         /* Invalid condition */
@@ -547,7 +543,7 @@
             /* Trace back through the octets which form the string, and output them. */
             while (code >= V42BIS_N5)
             {
-if (code > 4095) {printf("Code is 0x%" PRIu32 "\n", code); exit(2);}
+if (code > 4095) {DEBUGP(DV42BIS,"Code is 0x%" PRIu32 "\n", code); exit(2);}
                 *string-- = ss->dict[code].node_octet;
                 code = ss->dict[code].parent_code;
             }
@@ -631,7 +627,7 @@
     {
         if (s->decompress.dict[i].parent_code != 0xFFFF)
         {
-            printf("Entry %4x, prior %4x, leaves %d, octet %2x\n", i, s->decompress.dict[i].parent_code, s->decompress.dict[i].leaves, s->decompress.dict[i].node_octet);
+            DEBUGP(DV42BIS,"Entry %4x, prior %4x, leaves %d, octet %2x\n", i, s->decompress.dict[i].parent_code, s->decompress.dict[i].leaves, s->decompress.dict[i].node_octet);
         }
     }
     return 0;
diff --git a/openbsc/tests/Makefile.am b/openbsc/tests/Makefile.am
index d5aa356..7acebc0 100644
--- a/openbsc/tests/Makefile.am
+++ b/openbsc/tests/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = gsm0408 db channel mgcp gprs abis gbproxy trau subscr mm_auth xid sndcp_xid slhc
+SUBDIRS = gsm0408 db channel mgcp gprs abis gbproxy trau subscr mm_auth xid sndcp_xid slhc v42bis
 
 if BUILD_NAT
 SUBDIRS += bsc-nat bsc-nat-trie
diff --git a/openbsc/tests/testsuite.at b/openbsc/tests/testsuite.at
index 5f37b8e..f18b734 100644
--- a/openbsc/tests/testsuite.at
+++ b/openbsc/tests/testsuite.at
@@ -141,3 +141,9 @@
 cat $abs_srcdir/slhc/slhc_test.ok > expout
 AT_CHECK([$abs_top_builddir/tests/slhc/slhc_test], [], [expout], [ignore])
 AT_CLEANUP
+
+AT_SETUP([v42bis])
+AT_KEYWORDS([v42bis])
+cat $abs_srcdir/v42bis/v42bis_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/v42bis/v42bis_test], [], [expout], [ignore])
+AT_CLEANUP
diff --git a/openbsc/tests/v42bis/Makefile.am b/openbsc/tests/v42bis/Makefile.am
new file mode 100644
index 0000000..9001c0f
--- /dev/null
+++ b/openbsc/tests/v42bis/Makefile.am
@@ -0,0 +1,21 @@
+AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include
+AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBCARES_CFLAGS)
+
+EXTRA_DIST = v42bis_test.ok
+
+noinst_PROGRAMS = v42bis_test
+
+v42bis_test_SOURCES = v42bis_test.c
+
+v42bis_test_LDADD = \
+	$(top_builddir)/src/gprs/v42bis.o \
+	$(top_builddir)/src/libcommon/libcommon.a \
+	$(LIBOSMOABIS_LIBS) \
+	$(LIBOSMOCORE_LIBS) \
+	$(LIBOSMOGSM_LIBS) \
+	$(LIBOSMOGB_LIBS) \
+	$(LIBCARES_LIBS) \
+	$(LIBCRYPTO_LIBS) \
+	-lgtp -lrt -lm
+
+
diff --git a/openbsc/tests/v42bis/v42bis_test.c b/openbsc/tests/v42bis/v42bis_test.c
new file mode 100644
index 0000000..aad94e3
--- /dev/null
+++ b/openbsc/tests/v42bis/v42bis_test.c
@@ -0,0 +1,189 @@
+/* Test v42bis Compression/Decompression */
+
+/* (C) 2016 by Sysmocom s.f.m.c. GmbH
+ * All Rights Reserved
+ *
+ * Author: Philipp Maier
+ *
+ * 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 <openbsc/v42bis.h>
+#include <openbsc/v42bis_private.h>
+#include <openbsc/debug.h>
+
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/utils.h>
+
+#include <osmocom/core/application.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#define BLOCK_SIZE 100
+#define MAX_BLOCK_SIZE 2048
+
+/* A struct to capture the output data of compressor and decompressor */
+struct v42bis_output_buffer_t {
+	uint8_t *buf;
+	uint8_t *buf_pointer;
+	int len;
+};
+
+/* A simple testpattern generator */
+static void gen_test_pattern(uint8_t *data, int len)
+{
+	int i;
+	for (i = 0; i < len; i++)
+		data[i] = i & 0xF0;
+}
+
+/* Handler to capture the output data from the compressor */
+void tx_v42bis_frame_handler(void *user_data, const uint8_t *pkt, int len)
+{
+	struct v42bis_output_buffer_t *output_buffer =
+	    (struct v42bis_output_buffer_t *)user_data;
+	memcpy(output_buffer->buf_pointer, pkt, len);
+	output_buffer->buf_pointer += len;
+	output_buffer->len += len;
+	return;
+}
+
+/* Handler to capture the output data from the decompressor */
+void tx_v42bis_data_handler(void *user_data, const uint8_t *buf, int len)
+{
+	/* stub */
+	return;
+}
+
+/* Handler to capture the output data from the compressor */
+void rx_v42bis_frame_handler(void *user_data, const uint8_t *pkt, int len)
+{
+	/* stub */
+	return;
+}
+
+/* Handler to capture the output data from the decompressor */
+void rx_v42bis_data_handler(void *user_data, const uint8_t *buf, int len)
+{
+	struct v42bis_output_buffer_t *output_buffer =
+	    (struct v42bis_output_buffer_t *)user_data;
+	memcpy(output_buffer->buf_pointer, buf, len);
+	output_buffer->buf_pointer += len;
+	output_buffer->len += len;
+	return;
+}
+
+/* Test V42.bis compression and decompression */
+static void test_v42bis(const void *ctx)
+{
+	v42bis_state_t *tx_state;
+	v42bis_state_t *rx_state;
+
+	uint8_t uncompressed_original[BLOCK_SIZE];
+	uint8_t compressed[BLOCK_SIZE];
+	uint8_t uncompressed[BLOCK_SIZE];
+
+	int rc;
+	struct v42bis_output_buffer_t compressed_data;
+	struct v42bis_output_buffer_t uncompressed_data;
+
+	/* Initalize */
+	tx_state =
+	    v42bis_init(NULL, 3, MAX_BLOCK_SIZE, 6, &tx_v42bis_frame_handler,
+			NULL, MAX_BLOCK_SIZE, &tx_v42bis_data_handler, NULL,
+			MAX_BLOCK_SIZE);
+	OSMO_ASSERT(tx_state);
+	rx_state =
+	    v42bis_init(NULL, 3, MAX_BLOCK_SIZE, 6, &rx_v42bis_frame_handler,
+			NULL, MAX_BLOCK_SIZE, &rx_v42bis_data_handler, NULL,
+			MAX_BLOCK_SIZE);
+	OSMO_ASSERT(rx_state);
+	v42bis_compression_control(tx_state, V42BIS_COMPRESSION_MODE_ALWAYS);
+	v42bis_compression_control(rx_state, V42BIS_COMPRESSION_MODE_ALWAYS);
+
+	/* Generate test pattern for input */
+	gen_test_pattern(uncompressed_original, sizeof(uncompressed_original));
+
+	/* Run compressor */
+	compressed_data.buf = compressed;
+	compressed_data.buf_pointer = compressed;
+	compressed_data.len = 0;
+	tx_state->compress.user_data = (&compressed_data);
+	rc = v42bis_compress(tx_state, uncompressed_original,
+			     sizeof(uncompressed_original));
+	OSMO_ASSERT(rc == 0);
+	rc = v42bis_compress_flush(tx_state);
+	OSMO_ASSERT(rc == 0);
+
+	/* Decompress again */
+	uncompressed_data.buf = uncompressed;
+	uncompressed_data.buf_pointer = uncompressed;
+	uncompressed_data.len = 0;
+	rx_state->decompress.user_data = (&uncompressed_data);
+	rc = v42bis_decompress(rx_state, compressed_data.buf,
+			       compressed_data.len);
+	OSMO_ASSERT(rc == 0);
+	rc = v42bis_decompress_flush(rx_state);
+	OSMO_ASSERT(rc == 0);
+
+	/* Check results */
+	printf("uncompressed_original= %s\n",
+	       osmo_hexdump_nospc(uncompressed_original,
+				  sizeof(uncompressed_original)));
+	printf("uncompressed=          %s\n",
+	       osmo_hexdump_nospc(uncompressed_data.buf,
+				  uncompressed_data.len));
+	printf("compressed=            %s\n",
+	       osmo_hexdump_nospc(compressed_data.buf, compressed_data.len));
+	rc = memcmp(uncompressed, uncompressed_original, BLOCK_SIZE);
+	OSMO_ASSERT(rc == 0);
+}
+
+static struct log_info_cat gprs_categories[] = {
+	[DV42BIS] = {
+		     .name = "DV42BIS",
+		     .description = "V42.bis data compression (SNDCP)",
+		     .enabled = 1,.loglevel = LOGL_DEBUG,
+		     }
+};
+
+static struct log_info info = {
+	.cat = gprs_categories,
+	.num_cat = ARRAY_SIZE(gprs_categories),
+};
+
+int main(int argc, char **argv)
+{
+	void *v42bis_ctx;
+
+	osmo_init_logging(&info);
+
+	v42bis_ctx = talloc_named_const(NULL, 0, "v42bis_ctx");
+
+	test_v42bis(v42bis_ctx);
+	printf("Done\n");
+
+	talloc_report_full(v42bis_ctx, stderr);
+	OSMO_ASSERT(talloc_total_blocks(v42bis_ctx) == 1);
+	return 0;
+}
+
+/* stubs */
+struct osmo_prim_hdr;
+int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
+{
+	abort();
+}
diff --git a/openbsc/tests/v42bis/v42bis_test.ok b/openbsc/tests/v42bis/v42bis_test.ok
new file mode 100644
index 0000000..16c8612
--- /dev/null
+++ b/openbsc/tests/v42bis/v42bis_test.ok
@@ -0,0 +1,4 @@
+uncompressed_original= 00000000000000000000000000000000101010101010101010101010101010102020202020202020202020202020202030303030303030303030303030303030404040404040404040404040404040405050505050505050505050505050505060606060
+uncompressed=          00000000000000000000000000000000101010101010101010101010101010102020202020202020202020202020202030303030303030303030303030303030404040404040404040404040404040405050505050505050505050505050505060606060
+compressed=            0180e0703824120a1309c1e0f0884424462385c2e190c868cc670f87c4221112190e27138a4522a5329c5e2f188c464c6638d804
+Done

-- 
To view, visit https://gerrit.osmocom.org/644
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newpatchset
Gerrit-Change-Id: I689413f2541b6def0625ce6bd96f1f488f05f99d
Gerrit-PatchSet: 21
Gerrit-Project: openbsc
Gerrit-Branch: master
Gerrit-Owner: dexter <pmaier at sysmocom.de>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder



More information about the gerrit-log mailing list