tests/conv: separate test logic

To be able to add some more tests, related to convolutional coding,
without duplication of code, the test logic was separated from the
conv_test.c into conv.c and conv.h.

Change-Id: Idbdc7e19cb9b9a36cd1fccd621cd858e87530d98
diff --git a/tests/conv/conv.c b/tests/conv/conv.c
new file mode 100644
index 0000000..7dac155
--- /dev/null
+++ b/tests/conv/conv.c
@@ -0,0 +1,143 @@
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <time.h>
+
+#include <osmocom/core/bits.h>
+#include <osmocom/core/conv.h>
+#include <osmocom/core/utils.h>
+
+#include "conv.h"
+
+static void fill_random(ubit_t *b, int n)
+{
+	int i;
+
+	for (i = 0; i < n; i++)
+		b[i] = random() & 1;
+}
+
+int do_check(const struct conv_test_vector *test)
+{
+	ubit_t *bu0, *bu1;
+	sbit_t *bs;
+	int len, j;
+
+	bu0 = malloc(sizeof(ubit_t) * MAX_LEN_BITS);
+	bu1 = malloc(sizeof(ubit_t) * MAX_LEN_BITS);
+	bs  = malloc(sizeof(sbit_t) * MAX_LEN_BITS);
+
+	srandom(time(NULL));
+
+	/* Test name */
+	printf("[+] Testing: %s\n", test->name);
+
+	/* Check length */
+	len = osmo_conv_get_input_length(test->code, 0);
+	printf("[.] Input length  : ret = %3d  exp = %3d -> %s\n",
+		len, test->in_len, len == test->in_len ? "OK" : "Bad !");
+
+	if (len != test->in_len) {
+		fprintf(stderr, "[!] Failure for input length computation\n");
+		return -1;
+	}
+
+	len = osmo_conv_get_output_length(test->code, 0);
+	printf("[.] Output length : ret = %3d  exp = %3d -> %s\n",
+		len, test->out_len, len == test->out_len ? "OK" : "Bad !");
+
+	if (len != test->out_len) {
+		fprintf(stderr, "[!] Failure for output length computation\n");
+		return -1;
+	}
+
+	/* Check pre-computed vector */
+	if (test->has_vec) {
+		printf("[.] Pre computed vector checks:\n");
+
+		printf("[..] Encoding: ");
+
+		osmo_pbit2ubit(bu0, test->vec_in, test->in_len);
+
+		len = osmo_conv_encode(test->code, bu0, bu1);
+		if (len != test->out_len) {
+			printf("ERROR !\n");
+			fprintf(stderr, "[!] Failed encoding length check\n");
+			return -1;
+		}
+
+		osmo_pbit2ubit(bu0, test->vec_out, test->out_len);
+
+		if (memcmp(bu0, bu1, test->out_len)) {
+			printf("ERROR !\n");
+			fprintf(stderr, "[!] Failed encoding: Results don't match\n");
+			return -1;
+		};
+
+		printf("OK\n");
+
+
+		printf("[..] Decoding: ");
+
+		osmo_ubit2sbit(bs, bu0, len);
+
+		len = osmo_conv_decode(test->code, bs, bu1);
+		if (len != 0) {
+			printf("ERROR !\n");
+			fprintf(stderr, "[!] Failed decoding: non-zero path (%d)\n", len);
+			return -1;
+		}
+
+		osmo_pbit2ubit(bu0, test->vec_in, test->in_len);
+
+		if (memcmp(bu0, bu1, test->in_len)) {
+			printf("ERROR !\n");
+			fprintf(stderr, "[!] Failed decoding: Results don't match\n");
+			return -1;
+		}
+
+		printf("OK\n");
+	}
+
+	/* Check random vector */
+	printf("[.] Random vector checks:\n");
+
+	for (j = 0; j < 3; j++) {
+		printf("[..] Encoding / Decoding cycle : ");
+
+		fill_random(bu0, test->in_len);
+
+		len = osmo_conv_encode(test->code, bu0, bu1);
+		if (len != test->out_len) {
+			printf("ERROR !\n");
+			fprintf(stderr, "[!] Failed encoding length check\n");
+			return -1;
+		}
+
+		osmo_ubit2sbit(bs, bu1, len);
+
+		len = osmo_conv_decode(test->code, bs, bu1);
+		if (len != 0) {
+			printf("ERROR !\n");
+			fprintf(stderr, "[!] Failed decoding: non-zero path (%d)\n", len);
+			return -1;
+		}
+
+		if (memcmp(bu0, bu1, test->in_len)) {
+			printf("ERROR !\n");
+			fprintf(stderr, "[!] Failed decoding: Results don't match\n");
+			return -1;
+		}
+
+		printf("OK\n");
+	}
+
+	/* Spacing */
+	printf("\n");
+
+	free(bs);
+	free(bu1);
+	free(bu0);
+
+	return 0;
+}