gprs_rlc_ts_alloc: ensure no rolling slots are allocated

When allocating multiple slots for a UE the following example
is not allowed 'UU----UU' for a UE class 12.
The time slot number can not roll over 7 and move to 0.
44.060 or 45.002 only specifies contigous however it was unclear
it this is an allowed pattern.

Only the example 45.002 B.3 in release 12 cleared this up.
It gives an example for a multi slot class 5 UE which has 7 possible
configuration this means the rolled over is not allowed.

Multislot class type 2 UE doesn't have this limitation.
Further if a UE supports 8 time slots this is not a limitation because
the window size (45.002 B.1) can include all time slots.

Releated: SYS#5073
Change-Id: I16019bdbe741b37b83b62749b840a3b7f4ddc6c7
diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp
index 1ef32f2..ae4ac4b 100644
--- a/src/gprs_rlcmac_ts_alloc.cpp
+++ b/src/gprs_rlcmac_ts_alloc.cpp
@@ -518,7 +518,7 @@
 {
 	uint8_t Tx = mslot_class_get_tx(mslot_class),   /* Max number of Tx slots */
 		Sum = mslot_class_get_sum(mslot_class), /* Max number of Tx + Rx slots */
-		max_slots, num_tx, mask_sel, pdch_slots, ul_ts, dl_ts;
+		max_slots, num_rx, num_tx, mask_sel, pdch_slots, ul_ts, dl_ts;
 	int16_t rx_window, tx_window;
 	char slot_info[9] = {0};
 	int max_capacity = -1;
@@ -570,6 +570,13 @@
 			/* Wrap valid window */
 			tx_valid_win = mslot_wrap_window(tx_valid_win);
 
+			/* for multislot type 1: don't split the window to wrap around.
+			 * E.g. 'UU-----U' is invalid for a 4 TN window. Except 8 TN window.
+			 * See 45.002 B.1 */
+			if (mslot_class_get_type(mslot_class) == 1 && num_tx < 8 &&
+					tx_valid_win & (1 << 0) && tx_valid_win & (1 << 7))
+				continue;
+
 			tx_window = tx_valid_win;
 
 			/* Filter out unavailable slots */
@@ -583,13 +590,21 @@
 			if ((tx_window & (1 << ((ul_ts+num_tx-1) % 8))) == 0)
 				continue;
 
-			rx_valid_win = (1 << OSMO_MIN(mslot_class_get_rx(mslot_class), Sum - num_tx)) - 1;
+			num_rx = OSMO_MIN(mslot_class_get_rx(mslot_class), Sum - num_tx);
+			rx_valid_win = (1 << num_rx) - 1;
 
 			/* Rotate group of RX slots: DDD-----, -DDD----, ..., DD-----D */
 			for (dl_ts = 0; dl_ts < 8; dl_ts += 1, rx_valid_win <<= 1) {
 				/* Wrap valid window */
 				rx_valid_win = (rx_valid_win | rx_valid_win >> 8) & 0xff;
 
+				/* for multislot type 1: don't split the window to wrap around.
+				 * E.g. 'DD-----D' is invalid for a 4 TN window. Except 8 TN window.
+				 * See 45.002 B.1 */
+				if (mslot_class_get_type(mslot_class) == 1 && num_rx < 8 &&
+						(rx_valid_win & (1 << 0)) && (rx_valid_win & (1 << 7)))
+					continue;
+
 				/* Validate with both Tta/Ttb/Trb and Ttb/Tra/Trb */
 				for (mask_sel = MASK_TT; mask_sel <= MASK_TR; mask_sel += 1) {
 					int capacity;