diff options
Diffstat (limited to 'tests')
36 files changed, 2391 insertions, 0 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 00000000..eff1ac44 --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1,47 @@ +if ENABLE_TESTS +SUBDIRS = timer sms ussd smscb bits a5 conv auth lapd gsm0808 +if ENABLE_MSGFILE +SUBDIRS += msgfile +endif + + +# The `:;' works around a Bash 3.2 bug when the output is not writeable. +$(srcdir)/package.m4: $(top_srcdir)/configure.ac + :;{ \ + echo '# Signature of the current package.' && \ + echo 'm4_define([AT_PACKAGE_NAME],' && \ + echo ' [$(PACKAGE_NAME)])' && \ + echo 'm4_define([AT_PACKAGE_TARNAME],' && \ + echo ' [$(PACKAGE_TARNAME)])' && \ + echo 'm4_define([AT_PACKAGE_VERSION],' && \ + echo ' [$(PACKAGE_VERSION)])' && \ + echo 'm4_define([AT_PACKAGE_STRING],' && \ + echo ' [$(PACKAGE_STRING)])' && \ + echo 'm4_define([AT_PACKAGE_BUGREPORT],' && \ + echo ' [$(PACKAGE_BUGREPORT)])'; \ + echo 'm4_define([AT_PACKAGE_URL],' && \ + echo ' [$(PACKAGE_URL)])'; \ + } >'$(srcdir)/package.m4' + +EXTRA_DIST = testsuite.at $(srcdir)/package.m4 $(TESTSUITE) +TESTSUITE = $(srcdir)/testsuite + +check-local: atconfig $(TESTSUITE) + $(SHELL) '$(TESTSUITE)' $(TESTSUITEFLAGS) + +installcheck-local: atconfig $(TESTSUITE) + $(SHELL) '$(TESTSUITE)' AUTOTEST_PATH='$(bindir)' \ + $(TESTSUITEFLAGS) + +clean-local: + test ! -f '$(TESTSUITE)' || \ + $(SHELL) '$(TESTSUITE)' --clean + $(RM) -f atconfig + +AUTOM4TE = $(SHELL) $(top_srcdir)/missing --run autom4te +AUTOTEST = $(AUTOM4TE) --language=autotest +$(TESTSUITE): $(srcdir)/testsuite.at $(srcdir)/package.m4 + $(AUTOTEST) -I '$(srcdir)' -o $@.tmp $@.at + mv $@.tmp $@ + +endif diff --git a/tests/a5/Makefile.am b/tests/a5/Makefile.am new file mode 100644 index 00000000..3c6e6ba4 --- /dev/null +++ b/tests/a5/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = $(all_includes) -I$(top_srcdir)/include +noinst_PROGRAMS = a5_test +EXTRA_DIST = a5_test.ok + +a5_test_SOURCES = a5_test.c +a5_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la diff --git a/tests/a5/a5_test.c b/tests/a5/a5_test.c new file mode 100644 index 00000000..14436f19 --- /dev/null +++ b/tests/a5/a5_test.c @@ -0,0 +1,98 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> + +#include <osmocom/core/bits.h> +#include <osmocom/core/utils.h> +#include <osmocom/gsm/a5.h> + +static const uint8_t key[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }; +static const uint32_t fn = 123456; +static const uint8_t dl[] = { + /* A5/0 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* A5/1 */ + 0xcb, 0xa2, 0x55, 0x76, 0x17, 0x5d, 0x3b, 0x1c, + 0x7b, 0x2f, 0x29, 0xa8, 0xc1, 0xb6, 0x00, + + /* A5/2 */ + 0x45, 0x9c, 0x88, 0xc3, 0x82, 0xb7, 0xff, 0xb3, + 0x98, 0xd2, 0xf9, 0x6e, 0x0f, 0x14, 0x80, +}; +static const uint8_t ul[] = { + /* A5/0 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* A5/1 */ + 0xd9, 0x03, 0x5e, 0x0f, 0x2a, 0xec, 0x13, 0x9a, + 0x05, 0xd4, 0xa8, 0x7b, 0xb1, 0x64, 0x80, + + /* A5/2 */ + 0xf0, 0x3a, 0xac, 0xde, 0xe3, 0x5b, 0x5e, 0x65, + 0x80, 0xba, 0xab, 0xc0, 0x59, 0x26, 0x40, +}; + +static const char * +binstr(ubit_t *d, int n) +{ + static char str[256]; + int i; + + for (i=0; i<n; i++) + str[i] = d[i] ? '1' : '0'; + + str[i] = '\0'; + + return str; +} + +int main(int argc, char **argv) +{ + ubit_t exp[114]; + ubit_t out[114]; + int n, i; + + for (n=0; n<3; n++) { + /* "Randomize" */ + for (i=0; i<114; i++) + out[i] = i & 1; + + /* DL */ + osmo_pbit2ubit(exp, &dl[15*n], 114); + + osmo_a5(n, key, fn, out, NULL); + + printf("A5/%d - DL: %s", n, binstr(out, 114)); + + if (!memcmp(exp, out, 114)) + printf(" => OK\n"); + else { + printf(" => BAD\n"); + printf(" Expected: %s", binstr(out, 114)); + fprintf(stderr, "[!] A5/%d DL failed", n); + exit(1); + } + + /* UL */ + osmo_pbit2ubit(exp, &ul[15*n], 114); + + osmo_a5(n, key, fn, NULL, out); + + printf("A5/%d - UL: %s", n, binstr(out, 114)); + + if (!memcmp(exp, out, 114)) + printf(" => OK\n"); + else { + printf(" => BAD\n"); + printf(" Expected: %s", binstr(out, 114)); + fprintf(stderr, "[!] A5/%d UL failed", n); + exit(1); + } + } + + return 0; +} diff --git a/tests/a5/a5_test.ok b/tests/a5/a5_test.ok new file mode 100644 index 00000000..4497e14a --- /dev/null +++ b/tests/a5/a5_test.ok @@ -0,0 +1,6 @@ +A5/0 - DL: 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 => OK +A5/0 - UL: 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 => OK +A5/1 - DL: 110010111010001001010101011101100001011101011101001110110001110001111011001011110010100110101000110000011011011000 => OK +A5/1 - UL: 110110010000001101011110000011110010101011101100000100111001101000000101110101001010100001111011101100010110010010 => OK +A5/2 - DL: 010001011001110010001000110000111000001010110111111111111011001110011000110100101111100101101110000011110001010010 => OK +A5/2 - UL: 111100000011101010101100110111101110001101011011010111100110010110000000101110101010101111000000010110010010011001 => OK diff --git a/tests/auth/Makefile.am b/tests/auth/Makefile.am new file mode 100644 index 00000000..52976d02 --- /dev/null +++ b/tests/auth/Makefile.am @@ -0,0 +1,8 @@ +INCLUDES = $(all_includes) -I$(top_srcdir)/include +noinst_PROGRAMS = milenage_test +EXTRA_DIST = milenage_test.ok + +milenage_test_SOURCES = milenage_test.c +milenage_test_LDADD = $(top_builddir)/src/libosmocore.la \ + $(top_builddir)/src/gsm/libosmogsm.la + diff --git a/tests/auth/milenage_test.c b/tests/auth/milenage_test.c new file mode 100644 index 00000000..7c996f02 --- /dev/null +++ b/tests/auth/milenage_test.c @@ -0,0 +1,98 @@ + +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> + +#include <osmocom/crypt/auth.h> +#include <osmocom/core/utils.h> + +static void dump_auth_vec(struct osmo_auth_vector *vec) +{ + printf("RAND:\t%s\n", osmo_hexdump(vec->rand, sizeof(vec->rand))); + + if (vec->auth_types & OSMO_AUTH_TYPE_UMTS) { + printf("AUTN:\t%s\n", osmo_hexdump(vec->autn, sizeof(vec->autn))); + printf("IK:\t%s\n", osmo_hexdump(vec->ik, sizeof(vec->ik))); + printf("CK:\t%s\n", osmo_hexdump(vec->ck, sizeof(vec->ck))); + printf("RES:\t%s\n", osmo_hexdump(vec->res, vec->res_len)); + } + + if (vec->auth_types & OSMO_AUTH_TYPE_GSM) { + printf("SRES:\t%s\n", osmo_hexdump(vec->sres, sizeof(vec->sres))); + printf("Kc:\t%s\n", osmo_hexdump(vec->kc, sizeof(vec->kc))); + } +} + +static struct osmo_sub_auth_data test_aud = { + .type = OSMO_AUTH_TYPE_UMTS, + .algo = OSMO_AUTH_ALG_MILENAGE, + .u.umts = { + .opc = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + .k = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + .amf = { 0x00, 0x00 }, + .sqn = 0x22, + }, +}; + +static int opc_test(const struct osmo_sub_auth_data *aud) +{ + int rc; + uint8_t opc[16]; +#if 0 + const uint8_t op[16] = { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }; +#else + const uint8_t op[16] = { 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0 }; +#endif + + rc = milenage_opc_gen(opc, aud->u.umts.k, op); + + printf("OP:\t%s\n", osmo_hexdump(op, sizeof(op))); + printf("OPC:\t%s\n", osmo_hexdump(opc, sizeof(opc))); + return rc; +} + +int main(int argc, char **argv) +{ + struct osmo_auth_vector _vec; + struct osmo_auth_vector *vec = &_vec; + uint8_t _rand[16]; + int rc; + +#if 0 + srand(time(NULL)); + *(uint32_t *)&_rand[0] = rand(); + *(uint32_t *)(&_rand[4]) = rand(); + *(uint32_t *)(&_rand[8]) = rand(); + *(uint32_t *)(&_rand[12]) = rand(); +#else + memset(_rand, 0, sizeof(_rand)); +#endif + memset(vec, 0, sizeof(*vec)); + + rc = osmo_auth_gen_vec(vec, &test_aud, _rand); + if (rc < 0) { + fprintf(stderr, "error generating auth vector\n"); + exit(1); + } + + dump_auth_vec(vec); + + const uint8_t auts[14] = { 0x87, 0x11, 0xa0, 0xec, 0x9e, 0x16, 0x37, 0xdf, + 0x17, 0xf8, 0x0b, 0x38, 0x4e, 0xe4 }; + + rc = osmo_auth_gen_vec_auts(vec, &test_aud, auts, _rand, _rand); + if (rc < 0) { + printf("AUTS failed\n"); + } else { + printf("AUTS success: SEQ.MS = %lu\n", test_aud.u.umts.sqn); + } + + opc_test(&test_aud); + + exit(0); + +} diff --git a/tests/auth/milenage_test.ok b/tests/auth/milenage_test.ok new file mode 100644 index 00000000..00ffc222 --- /dev/null +++ b/tests/auth/milenage_test.ok @@ -0,0 +1,10 @@ +RAND: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +AUTN: ec 93 20 c2 c2 12 00 00 c8 b7 de 2a 34 49 f1 bd +IK: 12 cb 2d d3 e0 ec 83 78 f6 fc 1d 60 6c 61 9f 47 +CK: 72 00 a1 84 d8 f2 c7 58 fb df 87 90 0d db f2 75 +RES: e9 fc 88 cc c8 a3 53 81 +SRES: 21 5f db 4d +Kc: 6d e8 16 a7 59 a4 29 12 +AUTS success: SEQ.MS = 33 +OP: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +OPC: c6 a1 3b 37 87 8f 5b 82 6f 4f 81 62 a1 c8 d8 79 diff --git a/tests/bits/Makefile.am b/tests/bits/Makefile.am new file mode 100644 index 00000000..d6fb2f2f --- /dev/null +++ b/tests/bits/Makefile.am @@ -0,0 +1,7 @@ +INCLUDES = $(all_includes) -I$(top_srcdir)/include +noinst_PROGRAMS = bitrev_test +EXTRA_DIST = bitrev_test.ok + +bitrev_test_SOURCES = bitrev_test.c +bitrev_test_LDADD = $(top_builddir)/src/libosmocore.la + diff --git a/tests/bits/bitrev_test.c b/tests/bits/bitrev_test.c new file mode 100644 index 00000000..5eca990a --- /dev/null +++ b/tests/bits/bitrev_test.c @@ -0,0 +1,36 @@ + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> + +#include <osmocom/core/utils.h> +#include <osmocom/core/bits.h> + +static const uint8_t input[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; +static const uint8_t exp_out[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; + +int main(int argc, char **argv) +{ + uint8_t out[ARRAY_SIZE(input)]; + unsigned int offs; + + for (offs = 0; offs < sizeof(out); offs++) { + uint8_t *start = out + offs; + uint8_t len = sizeof(out) - offs; + + memcpy(out, input, sizeof(out)); + + printf("INORDER: %s\n", osmo_hexdump(start, len)); + osmo_revbytebits_buf(start, len); + printf("REVERSED: %s\n", osmo_hexdump(start, len)); + if (memcmp(start, exp_out + offs, len)) { + printf("EXPECTED: %s\n", osmo_hexdump(exp_out+offs, len)); + fprintf(stderr, "REVERSED != EXPECTED!\n"); + exit(1); + } + printf("\n"); + } + + return 0; +} diff --git a/tests/bits/bitrev_test.ok b/tests/bits/bitrev_test.ok new file mode 100644 index 00000000..47f402f4 --- /dev/null +++ b/tests/bits/bitrev_test.ok @@ -0,0 +1,24 @@ +INORDER: 01 02 04 08 10 20 40 80 +REVERSED: 80 40 20 10 08 04 02 01 + +INORDER: 02 04 08 10 20 40 80 +REVERSED: 40 20 10 08 04 02 01 + +INORDER: 04 08 10 20 40 80 +REVERSED: 20 10 08 04 02 01 + +INORDER: 08 10 20 40 80 +REVERSED: 10 08 04 02 01 + +INORDER: 10 20 40 80 +REVERSED: 08 04 02 01 + +INORDER: 20 40 80 +REVERSED: 04 02 01 + +INORDER: 40 80 +REVERSED: 02 01 + +INORDER: 80 +REVERSED: 01 + diff --git a/tests/conv/Makefile.am b/tests/conv/Makefile.am new file mode 100644 index 00000000..75cfec8d --- /dev/null +++ b/tests/conv/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = $(all_includes) -I$(top_srcdir)/include +noinst_PROGRAMS = conv_test +EXTRA_DIST = conv_test.ok + +conv_test_SOURCES = conv_test.c +conv_test_LDADD = $(top_builddir)/src/libosmocore.la diff --git a/tests/conv/conv_test.c b/tests/conv/conv_test.c new file mode 100644 index 00000000..54e043e9 --- /dev/null +++ b/tests/conv/conv_test.c @@ -0,0 +1,486 @@ +#include <stdio.h> +#include <stdlib.h> +#include <time.h> + +#include <osmocom/core/bits.h> +#include <osmocom/core/conv.h> +#include <osmocom/core/utils.h> + +#define MAX_LEN_BITS 512 +#define MAX_LEN_BYTES (512/8) + + +/* ------------------------------------------------------------------------ */ +/* Test codes */ +/* ------------------------------------------------------------------------ */ + +/* GSM xCCH -> Non-recursive code, flushed, not punctured */ +static const uint8_t conv_gsm_xcch_next_output[][2] = { + { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 }, + { 3, 0 }, { 2, 1 }, { 3, 0 }, { 2, 1 }, + { 3, 0 }, { 2, 1 }, { 3, 0 }, { 2, 1 }, + { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 }, +}; + +static const uint8_t conv_gsm_xcch_next_state[][2] = { + { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 }, + { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 }, + { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 }, + { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 }, +}; + +static const struct osmo_conv_code conv_gsm_xcch = { + .N = 2, + .K = 5, + .len = 224, + .term = CONV_TERM_FLUSH, + .next_output = conv_gsm_xcch_next_output, + .next_state = conv_gsm_xcch_next_state, +}; + + +/* GSM TCH/AFS 7.95 -> Recursive code, flushed, with puncturing */ +static const uint8_t conv_gsm_tch_afs_7_95_next_output[][2] = { + { 0, 7 }, { 3, 4 }, { 2, 5 }, { 1, 6 }, + { 2, 5 }, { 1, 6 }, { 0, 7 }, { 3, 4 }, + { 3, 4 }, { 0, 7 }, { 1, 6 }, { 2, 5 }, + { 1, 6 }, { 2, 5 }, { 3, 4 }, { 0, 7 }, + { 3, 4 }, { 0, 7 }, { 1, 6 }, { 2, 5 }, + { 1, 6 }, { 2, 5 }, { 3, 4 }, { 0, 7 }, + { 0, 7 }, { 3, 4 }, { 2, 5 }, { 1, 6 }, + { 2, 5 }, { 1, 6 }, { 0, 7 }, { 3, 4 }, + { 0, 7 }, { 3, 4 }, { 2, 5 }, { 1, 6 }, + { 2, 5 }, { 1, 6 }, { 0, 7 }, { 3, 4 }, + { 3, 4 }, { 0, 7 }, { 1, 6 }, { 2, 5 }, + { 1, 6 }, { 2, 5 }, { 3, 4 }, { 0, 7 }, + { 3, 4 }, { 0, 7 }, { 1, 6 }, { 2, 5 }, + { 1, 6 }, { 2, 5 }, { 3, 4 }, { 0, 7 }, + { 0, 7 }, { 3, 4 }, { 2, 5 }, { 1, 6 }, + { 2, 5 }, { 1, 6 }, { 0, 7 }, { 3, 4 }, +}; + +static const uint8_t conv_gsm_tch_afs_7_95_next_state[][2] = { + { 0, 1 }, { 2, 3 }, { 5, 4 }, { 7, 6 }, + { 9, 8 }, { 11, 10 }, { 12, 13 }, { 14, 15 }, + { 16, 17 }, { 18, 19 }, { 21, 20 }, { 23, 22 }, + { 25, 24 }, { 27, 26 }, { 28, 29 }, { 30, 31 }, + { 33, 32 }, { 35, 34 }, { 36, 37 }, { 38, 39 }, + { 40, 41 }, { 42, 43 }, { 45, 44 }, { 47, 46 }, + { 49, 48 }, { 51, 50 }, { 52, 53 }, { 54, 55 }, + { 56, 57 }, { 58, 59 }, { 61, 60 }, { 63, 62 }, + { 1, 0 }, { 3, 2 }, { 4, 5 }, { 6, 7 }, + { 8, 9 }, { 10, 11 }, { 13, 12 }, { 15, 14 }, + { 17, 16 }, { 19, 18 }, { 20, 21 }, { 22, 23 }, + { 24, 25 }, { 26, 27 }, { 29, 28 }, { 31, 30 }, + { 32, 33 }, { 34, 35 }, { 37, 36 }, { 39, 38 }, + { 41, 40 }, { 43, 42 }, { 44, 45 }, { 46, 47 }, + { 48, 49 }, { 50, 51 }, { 53, 52 }, { 55, 54 }, + { 57, 56 }, { 59, 58 }, { 60, 61 }, { 62, 63 }, +}; + +static const uint8_t conv_gsm_tch_afs_7_95_next_term_output[] = { + 0, 3, 5, 6, 5, 6, 0, 3, 3, 0, 6, 5, 6, 5, 3, 0, + 4, 7, 1, 2, 1, 2, 4, 7, 7, 4, 2, 1, 2, 1, 7, 4, + 7, 4, 2, 1, 2, 1, 7, 4, 4, 7, 1, 2, 1, 2, 4, 7, + 3, 0, 6, 5, 6, 5, 3, 0, 0, 3, 5, 6, 5, 6, 0, 3, +}; + +static const uint8_t conv_gsm_tch_afs_7_95_next_term_state[] = { + 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, + 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, + 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, + 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, +}; + +static int conv_gsm_tch_afs_7_95_puncture[] = { + 1, 2, 4, 5, 8, 22, 70, 118, 166, 214, 262, 310, + 317, 319, 325, 332, 334, 341, 343, 349, 356, 358, 365, 367, + 373, 380, 382, 385, 389, 391, 397, 404, 406, 409, 413, 415, + 421, 428, 430, 433, 437, 439, 445, 452, 454, 457, 461, 463, + 469, 476, 478, 481, 485, 487, 490, 493, 500, 502, 503, 505, + 506, 508, 509, 511, 512, + -1, /* end */ +}; + +static const struct osmo_conv_code conv_gsm_tch_afs_7_95 = { + .N = 3, + .K = 7, + .len = 165, + .term = CONV_TERM_FLUSH, + .next_output = conv_gsm_tch_afs_7_95_next_output, + .next_state = conv_gsm_tch_afs_7_95_next_state, + .next_term_output = conv_gsm_tch_afs_7_95_next_term_output, + .next_term_state = conv_gsm_tch_afs_7_95_next_term_state, + .puncture = conv_gsm_tch_afs_7_95_puncture, +}; + + +/* GMR-1 TCH3 Speech -> Non recursive code, tail-biting, punctured */ +static const uint8_t conv_gmr1_tch3_speech_next_output[][2] = { + { 0, 3 }, { 1, 2 }, { 3, 0 }, { 2, 1 }, + { 3, 0 }, { 2, 1 }, { 0, 3 }, { 1, 2 }, + { 0, 3 }, { 1, 2 }, { 3, 0 }, { 2, 1 }, + { 3, 0 }, { 2, 1 }, { 0, 3 }, { 1, 2 }, + { 2, 1 }, { 3, 0 }, { 1, 2 }, { 0, 3 }, + { 1, 2 }, { 0, 3 }, { 2, 1 }, { 3, 0 }, + { 2, 1 }, { 3, 0 }, { 1, 2 }, { 0, 3 }, + { 1, 2 }, { 0, 3 }, { 2, 1 }, { 3, 0 }, + { 3, 0 }, { 2, 1 }, { 0, 3 }, { 1, 2 }, + { 0, 3 }, { 1, 2 }, { 3, 0 }, { 2, 1 }, + { 3, 0 }, { 2, 1 }, { 0, 3 }, { 1, 2 }, + { 0, 3 }, { 1, 2 }, { 3, 0 }, { 2, 1 }, + { 1, 2 }, { 0, 3 }, { 2, 1 }, { 3, 0 }, + { 2, 1 }, { 3, 0 }, { 1, 2 }, { 0, 3 }, + { 1, 2 }, { 0, 3 }, { 2, 1 }, { 3, 0 }, + { 2, 1 }, { 3, 0 }, { 1, 2 }, { 0, 3 }, +}; + +static const uint8_t conv_gmr1_tch3_speech_next_state[][2] = { + { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 }, + { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 }, + { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 }, + { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 }, + { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 }, + { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 }, + { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 }, + { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 }, + { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 }, + { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 }, + { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 }, + { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 }, + { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 }, + { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 }, + { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 }, + { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 }, +}; + +static const int conv_gmr1_tch3_speech_puncture[] = { + 3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, + 51, 55, 59, 63, 67, 71, 75, 79, 83, 87, 91, 95, + -1, /* end */ +}; + +static const struct osmo_conv_code conv_gmr1_tch3_speech = { + .N = 2, + .K = 7, + .len = 48, + .term = CONV_TERM_TAIL_BITING, + .next_output = conv_gmr1_tch3_speech_next_output, + .next_state = conv_gmr1_tch3_speech_next_state, + .puncture = conv_gmr1_tch3_speech_puncture, +}; + + +/* WiMax FCH -> Non recursive code, tail-biting, non-punctured */ +static const uint8_t conv_wimax_fch_next_output[][2] = { + { 0, 3 }, { 2, 1 }, { 3, 0 }, { 1, 2 }, + { 3, 0 }, { 1, 2 }, { 0, 3 }, { 2, 1 }, + { 0, 3 }, { 2, 1 }, { 3, 0 }, { 1, 2 }, + { 3, 0 }, { 1, 2 }, { 0, 3 }, { 2, 1 }, + { 1, 2 }, { 3, 0 }, { 2, 1 }, { 0, 3 }, + { 2, 1 }, { 0, 3 }, { 1, 2 }, { 3, 0 }, + { 1, 2 }, { 3, 0 }, { 2, 1 }, { 0, 3 }, + { 2, 1 }, { 0, 3 }, { 1, 2 }, { 3, 0 }, + { 3, 0 }, { 1, 2 }, { 0, 3 }, { 2, 1 }, + { 0, 3 }, { 2, 1 }, { 3, 0 }, { 1, 2 }, + { 3, 0 }, { 1, 2 }, { 0, 3 }, { 2, 1 }, + { 0, 3 }, { 2, 1 }, { 3, 0 }, { 1, 2 }, + { 2, 1 }, { 0, 3 }, { 1, 2 }, { 3, 0 }, + { 1, 2 }, { 3, 0 }, { 2, 1 }, { 0, 3 }, + { 2, 1 }, { 0, 3 }, { 1, 2 }, { 3, 0 }, + { 1, 2 }, { 3, 0 }, { 2, 1 }, { 0, 3 }, +}; + +static const uint8_t conv_wimax_fch_next_state[][2] = { + { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 }, + { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 }, + { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 }, + { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 }, + { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 }, + { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 }, + { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 }, + { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 }, + { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 }, + { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 }, + { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 }, + { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 }, + { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 }, + { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 }, + { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 }, + { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 }, +}; + +static const struct osmo_conv_code conv_wimax_fch = { + .N = 2, + .K = 7, + .len = 48, + .term = CONV_TERM_TAIL_BITING, + .next_output = conv_wimax_fch_next_output, + .next_state = conv_wimax_fch_next_state, +}; + + +/* Random code -> Non recursive code, direct truncation, non-punctured */ +static const struct osmo_conv_code conv_trunc = { + .N = 2, + .K = 5, + .len = 224, + .term = CONV_TERM_TRUNCATION, + .next_output = conv_gsm_xcch_next_output, + .next_state = conv_gsm_xcch_next_state, +}; + + +/* ------------------------------------------------------------------------ */ +/* Test vectors */ +/* ------------------------------------------------------------------------ */ + +struct conv_test_vector { + const char *name; + const struct osmo_conv_code *code; + int in_len; + int out_len; + int has_vec; + pbit_t vec_in[MAX_LEN_BYTES]; + pbit_t vec_out[MAX_LEN_BYTES]; +}; + +static const struct conv_test_vector tests[] = { + { + .name = "GSM xCCH (non-recursive, flushed, not punctured)", + .code = &conv_gsm_xcch, + .in_len = 224, + .out_len = 456, + .has_vec = 1, + .vec_in = { 0xf3, 0x1d, 0xb4, 0x0c, 0x4d, 0x1d, 0x9d, 0xae, + 0xc0, 0x0a, 0x42, 0x57, 0x13, 0x60, 0x80, 0x96, + 0xef, 0x23, 0x7e, 0x4c, 0x1d, 0x96, 0x24, 0x19, + 0x17, 0xf2, 0x44, 0x99 }, + .vec_out = { 0xe9, 0x4d, 0x70, 0xab, 0xa2, 0x87, 0xf0, 0xe7, + 0x04, 0x14, 0x7c, 0xab, 0xaf, 0x6b, 0xa1, 0x16, + 0xeb, 0x30, 0x00, 0xde, 0xc8, 0xfd, 0x0b, 0x85, + 0x80, 0x41, 0x4a, 0xcc, 0xd3, 0xc0, 0xd0, 0xb6, + 0x26, 0xe5, 0x4e, 0x32, 0x49, 0x69, 0x38, 0x17, + 0x33, 0xab, 0xaf, 0xb6, 0xc1, 0x08, 0xf3, 0x9f, + 0x8c, 0x75, 0x6a, 0x4e, 0x08, 0xc4, 0x20, 0x5f, + 0x8f }, + }, + { + .name = "GSM TCH/AFS 7.95 (recursive, flushed, punctured)", + .code = &conv_gsm_tch_afs_7_95, + .in_len = 165, + .out_len = 448, + .has_vec = 1, + .vec_in = { 0x87, 0x66, 0xc3, 0x58, 0x09, 0xd4, 0x06, 0x59, + 0x10, 0xbf, 0x6b, 0x7f, 0xc8, 0xed, 0x72, 0xaa, + 0xc1, 0x3d, 0xf3, 0x1e, 0xb0 }, + .vec_out = { 0x92, 0xbc, 0xde, 0xa0, 0xde, 0xbe, 0x01, 0x2f, + 0xbe, 0xe4, 0x61, 0x32, 0x4d, 0x4f, 0xdc, 0x41, + 0x43, 0x0d, 0x15, 0xe0, 0x23, 0xdd, 0x18, 0x91, + 0xe5, 0x36, 0x2d, 0xb7, 0xd9, 0x78, 0xb8, 0xb1, + 0xb7, 0xcb, 0x2f, 0xc0, 0x52, 0x8f, 0xe2, 0x8c, + 0x6f, 0xa6, 0x79, 0x88, 0xed, 0x0c, 0x2e, 0x9e, + 0xa1, 0x5f, 0x45, 0x4a, 0xfb, 0xe6, 0x5a, 0x9c }, + }, + { + .name = "GMR-1 TCH3 Speech (non-recursive, tail-biting, punctured)", + .code = &conv_gmr1_tch3_speech, + .in_len = 48, + .out_len = 72, + .has_vec = 1, + .vec_in = { 0x4d, 0xcb, 0xfc, 0x72, 0xf4, 0x8c }, + .vec_out = { 0xc0, 0x86, 0x63, 0x4b, 0x8b, 0xd4, 0x6a, 0x76, 0xb2 }, + }, + { + .name = "WiMax FCH (non-recursive, tail-biting, not punctured)", + .code = &conv_wimax_fch, + .in_len = 48, + .out_len = 96, + .has_vec = 1, + .vec_in = { 0xfc, 0xa0, 0xa0, 0xfc, 0xa0, 0xa0 }, + .vec_out = { 0x19, 0x42, 0x8a, 0xed, 0x21, 0xed, 0x19, 0x42, + 0x8a, 0xed, 0x21, 0xed }, + }, + { + .name = "??? (non-recursive, direct truncation, not punctured)", + .code = &conv_trunc, + .in_len = 224, + .out_len = 448, + .has_vec = 1, + .vec_in = { 0xe5, 0xe0, 0x85, 0x7e, 0xf7, 0x08, 0x19, 0x5a, + 0xb9, 0xad, 0x82, 0x37, 0x98, 0x8b, 0x26, 0xb9, + 0x81, 0x26, 0x9c, 0x75, 0xaf, 0xf3, 0xcb, 0x07, + 0xac, 0x63, 0xe2, 0x9c, + }, + .vec_out = { 0xea, 0x3b, 0x55, 0x0c, 0xd3, 0xf7, 0x85, 0x69, + 0xe5, 0x79, 0x83, 0xd3, 0xc3, 0x9f, 0xb8, 0x61, + 0x21, 0x63, 0x51, 0x18, 0xac, 0xcd, 0x32, 0x49, + 0x53, 0x5c, 0x13, 0x1d, 0xbe, 0x05, 0x11, 0x63, + 0x5c, 0xc3, 0x42, 0x05, 0x1c, 0x68, 0x0a, 0xb4, + 0x61, 0x15, 0xaa, 0x4d, 0x94, 0xed, 0xb3, 0x3a, + 0x5d, 0x1b, 0x09, 0xc2, 0x99, 0x01, 0xec, 0x68 }, + }, + { /* end */ }, +}; + + + + +/* ------------------------------------------------------------------------ */ +/* Main */ +/* ------------------------------------------------------------------------ */ + +static void +fill_random(ubit_t *b, int n) +{ + int i; + for (i=0; i<n; i++) + b[i] = random() & 1; +} + +static void +ubit_to_sbit(sbit_t *dst, ubit_t *src, int n) +{ + int i; + for (i=0; i<n; i++) + dst[i] = src[i] ? -127 : 127; +} + +static void +sbit_to_ubit(ubit_t *dst, sbit_t *src, int n) +{ + int i; + for (i=0; i<n; i++) + dst[i] = src[i] < 0; +} + + +int main(int argc, char argv[]) +{ + const struct conv_test_vector *tst; + ubit_t *bu0, *bu1; + sbit_t *bs; + + srandom(time(NULL)); + + bu0 = mall |
