library/RSL_Types: RSL_SpeechAlgo: support CSD

Prepare to test CSD in BSC_Tests.ttcn. After sending a BSSAP assignment
request to the BSC with channel type data, the BSC will send a channel
activation via RSL to the BTS (which is emulated by the testsuite).

Without CSD support in the RSL template, the testsuite is unable to
decode the message, prints "Data remained at the end of the stream
after successful decoding" and the test fails.

Related: OS#4393
Change-Id: Ief2d95c7e9d71afb26fa74da755294226c8e158d
diff --git a/bsc/BSC_Tests.ttcn b/bsc/BSC_Tests.ttcn
index b9182e3..31b733f 100644
--- a/bsc/BSC_Tests.ttcn
+++ b/bsc/BSC_Tests.ttcn
@@ -4342,30 +4342,30 @@
 			dtx_u := ?,
 			spd_ind := RSL_SPDI_SPEECH,
 			ch_rate_type := -,
-			coding_alg_rate := -
+			u := { speech := - }
 		}
 	}
 
 	select (a_elem.codecType) {
 	case (GSM_FR) {
 		mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
-		mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
+		mode_ie.chan_mode.u.speech := RSL_CMOD_SP_GSM1;
 	}
 	case (GSM_HR) {
 		mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
-		mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
+		mode_ie.chan_mode.u.speech := RSL_CMOD_SP_GSM1;
 	}
 	case (GSM_EFR) {
 		mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
-		mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM2;
+		mode_ie.chan_mode.u.speech := RSL_CMOD_SP_GSM2;
 	}
 	case (FR_AMR) {
 		mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
-		mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
+		mode_ie.chan_mode.u.speech := RSL_CMOD_SP_GSM3;
 	}
 	case (HR_AMR) {
 		mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
-		mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
+		mode_ie.chan_mode.u.speech := RSL_CMOD_SP_GSM3;
 	}
 	}
 	return mode_ie;
diff --git a/bts/BTS_Tests.ttcn b/bts/BTS_Tests.ttcn
index 1859eed..e1281bb 100644
--- a/bts/BTS_Tests.ttcn
+++ b/bts/BTS_Tests.ttcn
@@ -871,7 +871,7 @@
 		ch_act.ies := ch_act.ies & { valueof(t_RSL_IE(RSL_IE_ENCR_INFO, RSL_IE_Body:{encr_info :=
 encr_info})) };
 	}
-	if (mode.coding_alg_rate == RSL_CMOD_SP_GSM3) {
+	if (ischosen(mode.u.speech) and mode.u.speech == RSL_CMOD_SP_GSM3) {
 		ch_act.ies := ch_act.ies & { valueof(t_RSL_IE(RSL_IE_MR_CONFIG,
 							      RSL_IE_Body:{multirate_cfg := g_pars.mr_conf})) };
 	}
@@ -2542,18 +2542,24 @@
 		var uint8_t amr_start_codec := 0;
 		var BIT8 amr_codecs_bitmask := '00000000'B;
 
-		select (g_pars.chan_mode.coding_alg_rate) {
-		case (RSL_CMOD_NO_RESOURCE) { tch_mode := L1CTL_CHAN_MODE_SIGN; }
-		case (RSL_CMOD_SP_GSM1) { tch_mode := L1CTL_CHAN_MODE_SPEECH_V1; }
-		case (RSL_CMOD_SP_GSM2) { tch_mode := L1CTL_CHAN_MODE_SPEECH_V2; }
-		case (RSL_CMOD_SP_GSM3) { tch_mode := L1CTL_CHAN_MODE_SPEECH_V3;
-					  amr_codecs_bitmask := g_pars.mr_conf.codec_modes;
-					}
-		case else {
-			log("RSL channel mode := ", g_pars.chan_mode.coding_alg_rate,
-			    " is not supported by the L1, falling back to signalling");
+		if (ischosen(g_pars.chan_mode.u.sign) and g_pars.chan_mode.u.sign == RSL_CMOD_NO_RESOURCE) {
 			tch_mode := L1CTL_CHAN_MODE_SIGN;
+		} else if (ischosen(g_pars.chan_mode.u.speech)) {
+			select (g_pars.chan_mode.u.speech) {
+			case (RSL_CMOD_SP_GSM1) { tch_mode := L1CTL_CHAN_MODE_SPEECH_V1; }
+			case (RSL_CMOD_SP_GSM2) { tch_mode := L1CTL_CHAN_MODE_SPEECH_V2; }
+			case (RSL_CMOD_SP_GSM3) { tch_mode := L1CTL_CHAN_MODE_SPEECH_V3;
+						  amr_codecs_bitmask := g_pars.mr_conf.codec_modes;
+						}
+			case else {
+				log("RSL channel mode := ", g_pars.chan_mode.u.speech,
+				    " is not supported by the L1, falling back to signalling");
+				tch_mode := L1CTL_CHAN_MODE_SIGN;
+				}
 			}
+		} else {
+			log("RSL channel mode is not supported by the L1, falling back to signalling");
+			tch_mode := L1CTL_CHAN_MODE_SIGN;
 		}
 
 		f_L1CTL_TCH_MODE(L1CTL,
diff --git a/bts/BTS_Tests_VAMOS.ttcn b/bts/BTS_Tests_VAMOS.ttcn
index 2d03411..c4bd171 100644
--- a/bts/BTS_Tests_VAMOS.ttcn
+++ b/bts/BTS_Tests_VAMOS.ttcn
@@ -174,7 +174,7 @@
 		for (var integer ch := 0; ch < lengthof(test[i]); ch := ch + 1) {
 			pars[ch] := valueof(t_Pars(test[i][ch].chan_nr,
 						   test[i][ch].chan_mode));
-			if (test[i][ch].chan_mode.coding_alg_rate == RSL_CMOD_SP_GSM3) {
+			if (ischosen(test[i][ch].chan_mode.u.speech) and test[i][ch].chan_mode.u.speech == RSL_CMOD_SP_GSM3) {
 				pars[ch].mr_conf := valueof(ts_RSL_MultirateCfg);
 			}
 			vc_conn[ch] := f_start_handler(handler, pars[ch], l1ctl := false);
@@ -248,10 +248,10 @@
 	/* If we're in signalling mode, modify to speech */
 	if (g_pars.chan_mode.spd_ind == RSL_SPDI_SIGN) {
 		g_pars.chan_mode.spd_ind := RSL_SPDI_SPEECH;
-		g_pars.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
+		g_pars.chan_mode.u.speech := RSL_CMOD_SP_GSM1;
 	} else { /* ... or vice versa */
 		g_pars.chan_mode.spd_ind := RSL_SPDI_SIGN;
-		g_pars.chan_mode.coding_alg_rate := RSL_CMOD_NO_RESOURCE;
+		g_pars.chan_mode.u.sign := RSL_CMOD_NO_RESOURCE;
 	}
 
 	var RSL_Message rsl := valueof(ts_RSL_MODE_MODIFY_REQ(g_chan_nr, g_pars.chan_mode));
diff --git a/library/RSL_Types.ttcn b/library/RSL_Types.ttcn
index cad8a34..fff87f2 100644
--- a/library/RSL_Types.ttcn
+++ b/library/RSL_Types.ttcn
@@ -386,8 +386,10 @@
 		RSL_CHRT_OSMO_TCH_F_VAMOS	('10001000'B),
 		RSL_CHRT_OSMO_TCH_H_VAMOS	('10001001'B)
 	} with { variant "FIELDLENGTH(8)" };
-	type enumerated RSL_SpeechAlgo {
-		RSL_CMOD_NO_RESOURCE	('00000000'B),
+	type enumerated RSL_ChanModeOct6Signalling {
+		RSL_CMOD_NO_RESOURCE	('00000000'B)
+	} with { variant "FIELDLENGTH(8)" };
+	type enumerated RSL_ChanModeOct6SpeechAlgo {
 		RSL_CMOD_SP_GSM1	('00000001'B),
 		RSL_CMOD_SP_GSM2	('00010001'B),
 		RSL_CMOD_SP_GSM3	('00100001'B),
@@ -395,6 +397,33 @@
 		RSL_CMOD_SP_GSM5	('00001001'B),
 		RSL_CMOD_SP_GSM6	('00001101'B)
 	} with { variant "FIELDLENGTH(8)" };
+	type enumerated RSL_ChanModeOct6DataRate {
+		RSL_CMOD_CSD_NTA_43k5_14k5	('01100001'B),
+		RSL_CMOD_CSD_NTA_29k0_14k5	('01100010'B),
+		RSL_CMOD_CSD_NTA_43k5_29k0	('01100011'B),
+		RSL_CMOD_CSD_NTA_14k5_43k5	('01101001'B),
+		RSL_CMOD_CSD_NTA_14k5_29k0	('01101010'B),
+		RSL_CMOD_CSD_NTA_29k0_43k5	('01101011'B),
+		RSL_CMOD_CSD_NT_43k5		('01110100'B),
+		RSL_CMOD_CSD_NT_28k8		('01110001'B),
+		RSL_CMOD_CSD_NT_14k5		('01011000'B),
+		RSL_CMOD_CSD_NT_12k0		('01010000'B),
+		RSL_CMOD_CSD_NT_6k0		('01010001'B),
+		RSL_CMOD_CSD_T_32k0		('00111000'B),
+		RSL_CMOD_CSD_T_29k0		('00111001'B),
+		RSL_CMOD_CSD_T_14k4		('00011000'B),
+		RSL_CMOD_CSD_T_9k6		('00010000'B),
+		RSL_CMOD_CSD_T_4k8		('00010001'B),
+		RSL_CMOD_CSD_T_2k4		('00010010'B),
+		RSL_CMOD_CSD_T_1k2		('00010011'B),
+		RSL_CMOD_CSD_T_600		('00010100'B),
+		RSL_CMOD_CSD_T_1200_75		('00010101'B)
+	} with { variant "FIELDLENGTH(8)" };
+	type union RSL_ChanModeOct6 {
+		RSL_ChanModeOct6Signalling sign,
+		RSL_ChanModeOct6SpeechAlgo speech,
+		RSL_ChanModeOct6DataRate data
+	};
 	type record RSL_IE_ChannelMode {
 		uint8_t		len,
 		BIT6		reserved,
@@ -402,8 +431,13 @@
 		boolean		dtx_u,
 		RSL_SpeechDataInd spd_ind,
 		RSL_ChanRateType  ch_rate_type,
-		RSL_SpeechAlgo	coding_alg_rate
-	} with { variant (len) "LENGTHTO(reserved,dtx_d,dtx_u,spd_ind,ch_rate_type,coding_alg_rate)" }
+		RSL_ChanModeOct6  u
+	} with { variant (len) "LENGTHTO(reserved,dtx_d,dtx_u,spd_ind,ch_rate_type,u)"
+		 variant (u) "CROSSTAG(
+				sign, spd_ind = RSL_SPDI_SIGN;
+				speech, spd_ind = RSL_SPDI_SPEECH;
+				data, spd_ind = RSL_SPDI_DATA;
+			      )"}
 
 	template (value) RSL_IE_ChannelMode ts_RSL_ChanMode_SIGN(RSL_ChanRateType t := RSL_CHRT_SDCCH,
 								 boolean dtx_downlink := false) := {
@@ -413,10 +447,10 @@
 		dtx_u := false,
 		spd_ind := RSL_SPDI_SIGN,
 		ch_rate_type := t,
-		coding_alg_rate := RSL_CMOD_NO_RESOURCE
+		u := { sign := RSL_CMOD_NO_RESOURCE }
 	}
 
-	template (value) RSL_IE_ChannelMode ts_RSL_ChanMode(RSL_ChanRateType t, RSL_SpeechAlgo alg,
+	template (value) RSL_IE_ChannelMode ts_RSL_ChanMode(RSL_ChanRateType t, RSL_ChanModeOct6SpeechAlgo alg,
 							    boolean dtx_downlink := false) := {
 		len := 0,	/* overwritten */
 		reserved := '000000'B,
@@ -424,17 +458,17 @@
 		dtx_u := false,
 		spd_ind := RSL_SPDI_SPEECH,
 		ch_rate_type := t,
-		coding_alg_rate := alg
+		u := { speech := alg }
 	}
 	template RSL_IE_ChannelMode tr_RSL_ChanMode(template RSL_ChanRateType t,
-						    template RSL_SpeechAlgo alg) := {
+						    template RSL_ChanModeOct6SpeechAlgo alg) := {
 		len := ?,
 		reserved := '000000'B,
 		dtx_d := ?,
 		dtx_u := ?,
 		spd_ind := RSL_SPDI_SPEECH,
 		ch_rate_type := t,
-		coding_alg_rate := alg
+		u := { speech := alg }
 	}
 
 	/* 9.3.4 BS Power IE */