Add EFR support to TRAU muxer + test case

Decoding and encoding of FR and EFR TRAU frames are put into seperate
functions. CRC check is done to detect bad EFR TRAU frames.

The test case includes FR and EFR transcoding.

EFR support was tested with Nokia InSite BTS and Siemens BS11.
diff --git a/openbsc/tests/Makefile.am b/openbsc/tests/Makefile.am
index 7f51bfa..d4bb954 100644
--- a/openbsc/tests/Makefile.am
+++ b/openbsc/tests/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = gsm0408 db channel mgcp gprs si abis gbproxy
+SUBDIRS = gsm0408 db channel mgcp gprs si abis gbproxy trau
 
 if BUILD_NAT
 SUBDIRS += bsc-nat bsc-nat-trie
diff --git a/openbsc/tests/testsuite.at b/openbsc/tests/testsuite.at
index 76110f5..652cfe9 100644
--- a/openbsc/tests/testsuite.at
+++ b/openbsc/tests/testsuite.at
@@ -81,3 +81,9 @@
 cat $abs_srcdir/gbproxy/gbproxy_test.ok > expout
 AT_CHECK([$abs_top_builddir/tests/gbproxy/gbproxy_test], [], [expout], [ignore])
 AT_CLEANUP
+
+AT_SETUP([trau])
+AT_KEYWORDS([trau])
+cat $abs_srcdir/trau/trau_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/trau/trau_test], [], [expout], [ignore])
+AT_CLEANUP
diff --git a/openbsc/tests/trau/Makefile.am b/openbsc/tests/trau/Makefile.am
new file mode 100644
index 0000000..d4aa1c3
--- /dev/null
+++ b/openbsc/tests/trau/Makefile.am
@@ -0,0 +1,17 @@
+AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include
+AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBSMPP34_CFLAGS) $(COVERAGE_CFLAGS)
+AM_LDFLAGS = $(COVERAGE_LDFLAGS)
+
+EXTRA_DIST = trau_test.ok
+
+noinst_PROGRAMS = trau_test
+
+trau_test_SOURCES = trau_test.c
+trau_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \
+		$(top_builddir)/src/libmsc/libmsc.a \
+		$(top_builddir)/src/libbsc/libbsc.a \
+		$(top_builddir)/src/libtrau/libtrau.a \
+		$(top_builddir)/src/libcommon/libcommon.a \
+		$(LIBOSMOCORE_LIBS) $(LIBOSMOABIS_LIBS) \
+		$(LIBOSMOGSM_LIBS) $(LIBSMPP34_LIBS) $(LIBOSMOVTY_LIBS) -ldl -ldbi
+
diff --git a/openbsc/tests/trau/trau_test.c b/openbsc/tests/trau/trau_test.c
new file mode 100644
index 0000000..f8a48db
--- /dev/null
+++ b/openbsc/tests/trau/trau_test.c
@@ -0,0 +1,82 @@
+/* (C) 2013 by Andreas Eversberg <jolly@eversberg.eu>
+ * 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 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 <osmocom/abis/trau_frame.h>
+#include <openbsc/trau_mux.h>
+#include <osmocom/core/msgb.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+void test_trau_fr_efr(unsigned char *data)
+{
+	struct decoded_trau_frame tf;
+	struct msgb *msg;
+	struct gsm_data_frame *frame;
+
+	printf("Testing TRAU FR transcoding.\n");
+	data[0] = 0xd0;
+	trau_encode_fr(&tf, data);
+	tf.c_bits[11] = 0; /* clear BFI */
+	msg = trau_decode_fr(1, &tf);
+	OSMO_ASSERT(msg != NULL);
+	frame = (struct gsm_data_frame *)msg->data;
+	OSMO_ASSERT(frame->msg_type == GSM_TCHF_FRAME);
+	OSMO_ASSERT(!memcmp(frame->data, data, 33));
+	msgb_free(msg);
+
+	printf("Testing TRAU EFR transcoding.\n");
+	data[0] = 0xc0;
+	trau_encode_efr(&tf, data);
+	OSMO_ASSERT(tf.d_bits[0] == 1); /* spare bit must be 1 */
+	tf.c_bits[11] = 0; /* clear BFI */
+	msg = trau_decode_efr(1, &tf);
+	OSMO_ASSERT(msg != NULL);
+	frame = (struct gsm_data_frame *)msg->data;
+	OSMO_ASSERT(frame->msg_type == GSM_TCHF_FRAME_EFR);
+	OSMO_ASSERT(!memcmp(frame->data, data, 31));
+
+	printf("Testing TRAU EFR decoding with CRC error.\n");
+	tf.d_bits[0] = 0; /* spare bit must be included */
+	msg = trau_decode_efr(1, &tf);
+	OSMO_ASSERT(msg != NULL);
+	frame = (struct gsm_data_frame *)msg->data;
+	OSMO_ASSERT(frame->msg_type == GSM_TCHF_BAD_FRAME);
+	msgb_free(msg);
+}
+
+int main()
+{
+	unsigned char data[33];
+	int i;
+
+	memset(data, 0x00, sizeof(data));
+	test_trau_fr_efr(data);
+	memset(data, 0xff, sizeof(data));
+	test_trau_fr_efr(data);
+	srandom(42);
+	for (i = 0; i < sizeof(data); i++)
+		data[i] = random();
+	test_trau_fr_efr(data);
+	printf("Done\n");
+	return 0;
+}
+
+/* stubs */
+void vty_out() {}
diff --git a/openbsc/tests/trau/trau_test.ok b/openbsc/tests/trau/trau_test.ok
new file mode 100644
index 0000000..ef71230
--- /dev/null
+++ b/openbsc/tests/trau/trau_test.ok
@@ -0,0 +1,10 @@
+Testing TRAU FR transcoding.
+Testing TRAU EFR transcoding.
+Testing TRAU EFR decoding with CRC error.
+Testing TRAU FR transcoding.
+Testing TRAU EFR transcoding.
+Testing TRAU EFR decoding with CRC error.
+Testing TRAU FR transcoding.
+Testing TRAU EFR transcoding.
+Testing TRAU EFR decoding with CRC error.
+Done