alloc: Ignore slots with differing TSC if multiple slots are requested

According to TS 45.002, 6.4.2 the training sequence (TSC) must be the
same for all slots in a multi-slot set.

This commit updates find_possible_pdchs() to only consider slots with
the same TSC if more that 1 slot shall be assigned.

Note that the first PDCH's TSC will be used as reference, so if two
or more groups with a common TSC are configured, only the first will
be used. This restriction does not apply to algorithm A, since it
will not assign more than one slot and therefore sets the max_slots
parameter to 1.

Sponsored-by: On-Waves ehf
diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp
index 2ba920a..116cabe 100644
--- a/src/gprs_rlcmac_ts_alloc.cpp
+++ b/src/gprs_rlcmac_ts_alloc.cpp
@@ -101,10 +101,12 @@
 }
 
 static int find_possible_pdchs(struct gprs_rlcmac_trx *trx,
+	size_t max_slots,
 	uint8_t mask, const char *mask_reason = NULL)
 {
 	unsigned ts;
 	int valid_ts_set = 0;
+	int8_t last_tsc = -1; /* must be signed */
 
 	for (ts = 0; ts < ARRAY_SIZE(trx->pdch); ts++) {
 		struct gprs_rlcmac_pdch *pdch;
@@ -124,6 +126,21 @@
 			continue;
 		}
 
+		if (max_slots > 1) {
+			/* check if TSC changes, see TS 45.002, 6.4.2 */
+			if (last_tsc < 0)
+				last_tsc = pdch->tsc;
+			else if (last_tsc != pdch->tsc) {
+				LOGP(DRLCMAC, LOGL_ERROR,
+					"Skipping TS %d of TRX=%d, because it "
+					"has different TSC than lower TS of TRX. "
+					"In order to allow multislot, all "
+					"slots must be configured with the same "
+					"TSC!\n", ts, trx->trx_no);
+				continue;
+			}
+		}
+
 		valid_ts_set |= 1 << ts;
 	}
 
@@ -244,7 +261,7 @@
 	if (ts >= 0)
 		mask = 1 << ts;
 
-	mask = find_possible_pdchs(tbf->trx, mask, mask_reason);
+	mask = find_possible_pdchs(tbf->trx, 1, mask, mask_reason);
 	if (!mask)
 		return -EINVAL;