coding: fix _tch_csd_burst_map(): do not overwrite FACCH

As was demonstrated in the unit test [1], FACCH bitstealing does not
work as expected in conjunction CSD specific encoding functions.

The problem is in _tch_csd_burst_map(): we don't check the stealing
flags hu(B) and hl(B) and overwrite both odd and even numbered bits
unconditionally.  Even worse, we reset these stealing flags to 0.

* Do not overwrite the hu(B) and hl(B) flags.
* Copy *even* numbered bits only if hu(B) is not set.
* Copy *odd* numbered bits only if hl(B) is not set.

Change-Id: Ib5395c70e3e725469c18ff7d4c47c62ddfdbd55d
Related: [1] Idc6decec3b84981d2aab4e27caab9ad65180f945
Related: OS#1572
diff --git a/src/coding/gsm0503_coding.c b/src/coding/gsm0503_coding.c
index 5badbd0..a34cd92 100644
--- a/src/coding/gsm0503_coding.c
+++ b/src/coding/gsm0503_coding.c
@@ -3298,13 +3298,23 @@
 
 static inline void _tch_csd_burst_map(ubit_t *burst, const ubit_t *iB)
 {
-	for (unsigned int i = 0; i < 57; i++) {
-		burst[i] |= iB[i];
-		burst[59 + i] |= iB[57 + i];
+	unsigned int i;
+
+	/* hu(B): copy *even* numbered bits if not stolen by FACCH */
+	if (burst[58] == 0) {
+		for (i = 0; i < 57; i += 2)
+			burst[i] |= iB[i];
+		for (i = 58; i < 114; i += 2)
+			burst[i + 2] |= iB[i];
 	}
 
-	burst[57] = 0; /* hl(B) */
-	burst[58] = 0; /* hu(B) */
+	/* hl(B): copy *odd* numbered bits if not stolen by FACCH */
+	if (burst[57] == 0) {
+		for (i = 1; i < 57; i += 2)
+			burst[i] |= iB[i];
+		for (i = 57; i < 114; i += 2)
+			burst[i + 2] |= iB[i];
+	}
 }
 
 /*! Perform channel encoding of a TCH/F9.6 channel as per section 3.3.
diff --git a/tests/coding/coding_test.c b/tests/coding/coding_test.c
index e53c8ad..7cef7b3 100644
--- a/tests/coding/coding_test.c
+++ b/tests/coding/coding_test.c
@@ -640,10 +640,7 @@
 			rc = gsm0503_tch_fr_facch_decode(&data[0], &bursts_s[116 * 4],
 							 &n_errors, &n_bits_total);
 		}
-#if 0
-		/* FIXME: there's something wrong with CSD mapping */
 		CHECK_RC_OR_RET(rc == GSM_MACBLOCK_LEN, "decoding FACCH");
-#endif
 
 		printf("%s(%s): FACCH/%c (pattern 0x2b): n_errors=%d / n_bits_total=%d\n",
 		       __func__, tc->name, tc->half_rate ? 'H' : 'F', n_errors, n_bits_total);
diff --git a/tests/coding/coding_test.ok b/tests/coding/coding_test.ok
index c9c6bb7..c5c145d 100644
--- a/tests/coding/coding_test.ok
+++ b/tests/coding/coding_test.ok
@@ -489,13 +489,13 @@
 01010101 01010101 01010101 01010101 01010101 01010101 00101011 01010101
 01010101 01010101 01010101 01010101 01010101 01010101 01010101 01010101
 01010101 01010101 01010101 01010101 01010101 01010101
-test_csd(TCH/F9.6): block #2 (pattern 0xff): n_errors=6 / n_bits_total=456
-11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111
+test_csd(TCH/F9.6): block #2 (pattern 0xff): n_errors=14 / n_bits_total=456
+11111111 11111111 11111111 11110111 11111111 11111111 11111111 11111111
 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111
 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111
 11111111 11111111 11111111 11111111 11111111 11111111
-test_csd(TCH/F9.6): FACCH/F (pattern 0x2b): n_errors=0 / n_bits_total=0
-01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 
+test_csd(TCH/F9.6): FACCH/F (pattern 0x2b): n_errors=0 / n_bits_total=456
+2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 
 
 test_csd(TCH/F4.8): block #0 (pattern 0x00): n_errors=38 / n_bits_total=456
 00000000 00000000 01010000 00000000 00000000 00000000 00000000 00000000
@@ -503,11 +503,11 @@
 test_csd(TCH/F4.8): block #1 (pattern 0xaa): n_errors=37 / n_bits_total=456
 01010101 01010101 01010101 01010101 01010101 01010101 01010101 01010101
 01010101 01010101 01010101 01010101 01010101 01010101 01010101
-test_csd(TCH/F4.8): block #2 (pattern 0xff): n_errors=1 / n_bits_total=456
+test_csd(TCH/F4.8): block #2 (pattern 0xff): n_errors=13 / n_bits_total=456
 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111
 11111111 11111111 11111111 11111111 11111111 11111111 11111111
-test_csd(TCH/F4.8): FACCH/F (pattern 0x2b): n_errors=0 / n_bits_total=0
-01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 
+test_csd(TCH/F4.8): FACCH/F (pattern 0x2b): n_errors=0 / n_bits_total=456
+2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 
 
 test_csd(TCH/H4.8): block #0 (pattern 0x00): n_errors=35 / n_bits_total=456
 00000000 00000000 00000000 00000000 00111000 10000000 00000000 00000000
@@ -519,12 +519,12 @@
 01010101 01010101 01010101 01010101 01010101 01010101 00101011 01010101
 01010101 01010101 01010101 00111010 01010101 01010101 01010101 01010101
 01010101 01010101 01010101 01010101 01010101 01010101
-test_csd(TCH/H4.8): block #2 (pattern 0xff): n_errors=1 / n_bits_total=456
+test_csd(TCH/H4.8): block #2 (pattern 0xff): n_errors=3 / n_bits_total=456
 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111
 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111
 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111
 11111111 11111111 11111111 11111111 11111111 11111111
-test_csd(TCH/H4.8): FACCH/H (pattern 0x2b): n_errors=2 / n_bits_total=456
+test_csd(TCH/H4.8): FACCH/H (pattern 0x2b): n_errors=0 / n_bits_total=456
 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 
 
 test_csd(TCH/H2.4): block #0 (pattern 0x00): n_errors=38 / n_bits_total=456
@@ -535,11 +535,11 @@
 01010101 01010101 01010101 01010101 01010101 01010101 01010101 01010101
 01010101 01010101 01010101 01010101 01010101 01010101 01010101 01010101
 01010101 01010101
-test_csd(TCH/H2.4): block #2 (pattern 0xff): n_errors=0 / n_bits_total=456
+test_csd(TCH/H2.4): block #2 (pattern 0xff): n_errors=2 / n_bits_total=456
 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111
 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111
 11111111 11111111
-test_csd(TCH/H2.4): FACCH/H (pattern 0x2b): n_errors=2 / n_bits_total=456
+test_csd(TCH/H2.4): FACCH/H (pattern 0x2b): n_errors=0 / n_bits_total=456
 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 
 
 test_csd(TCH/F14.4): block #0 (pattern 0x00): n_errors=27 / n_bits_total=456
@@ -554,13 +554,13 @@
 11000110 00001010 01010101 01010101 11101101 11010101 01010100 01010101
 01010101 01010101 00101001 00100101 01010101 01010101 01010101 01010101
 01010101 01010101 01010101 01010101 01
-test_csd(TCH/F14.4): block #2 (pattern 0xff): n_errors=3 / n_bits_total=456
+test_csd(TCH/F14.4): block #2 (pattern 0xff): n_errors=10 / n_bits_total=456
 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111
 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111
 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111
 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111
 11111111 11111111 11111111 11111111 11
-test_csd(TCH/F14.4): FACCH/F (pattern 0x2b): n_errors=0 / n_bits_total=0
-01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 
+test_csd(TCH/F14.4): FACCH/F (pattern 0x2b): n_errors=0 / n_bits_total=456
+2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 
 
 Success