Implement downgrade to DL MCS1-4 when USF for GPRS_only MS

In previous status, if USF for GPRS-only MS was selected, then EGPRS
TBFs were skipped and either a GPRS TBF was selected or a Dummy Block
was sent. That means the behavior was unfair towards EGPRS TBFs, because
sometimes they were skipped in favor of GPRS ones.
This patch imporves the situation in the above mentioned USF scenario, by
first, under specific conditions, allowing selection of an EGPRS TBF and
then forcing it to transmit in EGPRS-GMSK (MCS1-4) so that the
USF-targeted MS can still decode the USF, while at the same time
providing more fairness by allowing the EGPRS TBF to transmit data.

The specific conditions mentioned above are, mainly, related to the fact
that once a DL data block has been sent, and hence a BSN was assigned to
it, it cannot be retransmitted later using another MCS, since lower
MCS1-4 wouldn't be able to contain higher MCS RLC payload.

The set of conditions could be expanded in the future by also selecting
the EGPRS TBF if retransmition is required and the block to be
retransmitted was originally transmitted as MCS1-4.

Related: OS#4544
Change-Id: I9af23e175435fe9ae7b0e4119ad52fcd4707b9ca
diff --git a/src/gprs_rlcmac_sched.cpp b/src/gprs_rlcmac_sched.cpp
index 537929b..84a5970 100644
--- a/src/gprs_rlcmac_sched.cpp
+++ b/src/gprs_rlcmac_sched.cpp
@@ -305,9 +305,6 @@
 		/* If a GPRS (CS1-4) Dl block is required, skip EGPRS(_GSMK) tbfs: */
 		if (req_mcs_kind == GPRS && tbf->is_egprs_enabled())
 			continue;
-		/* TODO: If a GPRS (CS1-4/MCS1-4) Dl block is required, downgrade MCS below instead of skipping */
-		if (req_mcs_kind == EGPRS_GMSK && (tbf->is_egprs_enabled() || tbf->ms()->mode() != GPRS))
-			continue;
 
 		age = tbf->frames_since_last_poll(fn);
 
@@ -316,6 +313,15 @@
 		if (prio == DL_PRIO_NONE)
 			continue;
 
+		/* If a GPRS (CS1-4/MCS1-4) Dl block is required, downgrade MCS
+		 * below instead of skipping. However, downgrade can only be
+		 * done on new data BSNs (not yet sent) and control blocks. */
+		if (req_mcs_kind == EGPRS_GMSK && tbf->is_egprs_enabled() &&
+		    (prio !=DL_PRIO_CONTROL && prio != DL_PRIO_NEW_DATA)) {
+			LOGP(DRLCMACSCHED, LOGL_DEBUG, "Cannot downgrade EGPRS TBF with prio %d\n", prio);
+			continue;
+		}
+
 		/* get the TBF with the highest priority */
 		if (prio > max_prio) {
 			prio_tfi = tfi;
@@ -326,12 +332,12 @@
 
 	if (prio_tbf) {
 		LOGP(DRLCMACSCHED, LOGL_DEBUG, "Scheduling data message at "
-			"RTS for DL TFI=%d (TRX=%d, TS=%d) prio=%d\n",
-			prio_tfi, trx, ts, max_prio);
+			"RTS for DL TFI=%d (TRX=%d, TS=%d) prio=%d mcs_mode_restrict=%s\n",
+			prio_tfi, trx, ts, max_prio, mode_name(req_mcs_kind));
 		/* next TBF to handle resource is the next one */
 		pdch->next_dl_tfi = (prio_tfi + 1) & 31;
 		/* generate DL data block */
-		msg = prio_tbf->create_dl_acked_block(fn, ts);
+		msg = prio_tbf->create_dl_acked_block(fn, ts, req_mcs_kind);
 		*is_egprs = prio_tbf->ms()->mode() != GPRS;
 	}