First actual SGSN test case

Change-Id: Id66ddf8dbe1c5cfa96a087235588ba67763b7f05
diff --git a/gprs_gb/LLC_Types.ttcn b/gprs_gb/LLC_Types.ttcn
deleted file mode 100644
index 8ca8f39..0000000
--- a/gprs_gb/LLC_Types.ttcn
+++ /dev/null
@@ -1,165 +0,0 @@
-module LLC_Types {
-	import from General_Types all;
-	import from Osmocom_Types all;
-
-	/* TS 44.064 Chapter 6.2 */
-	type record LlcAddressField {
-		BIT1 pd ('0'B),
-		boolean c_r,
-		BIT2 reserved,
-		LlcSapi sapi
-	} with {
-		variant (c_r) "FIELDLENGTH(1)"
-	};
-
-	template LlcAddressField t_LLC_Addr(template boolean c_r, template LlcSapi sapi) := {
-		pd := '0'B,
-		c_r := c_r,
-		reserved := '00'B,
-		sapi := sapi
-	};
-
-	const boolean LLC_CR_DL_CMD := true;
-	const boolean LLC_CR_DL_RSP := false;
-	const boolean LLC_CR_UL_CMD := false;
-	const boolean LLC_CR_UL_RSP := true;
-
-	template LlcAddressField t_LLC_Addr_DlCmd(template LlcSapi sapi) := t_LLC_Addr(true, sapi);
-	template LlcAddressField t_LLC_Addr_DlRsp(template LlcSapi sapi) := t_LLC_Addr(false, sapi);
-	template LlcAddressField t_LLC_Addr_UlCmd(template LlcSapi sapi) := t_LLC_Addr(false, sapi);
-	template LlcAddressField t_LLC_Addr_UlRsp(template LlcSapi sapi) := t_LLC_Addr(true, sapi);
-
-	type enumerated LlcSapi {
-		LLC_SAPI_RESERVED_0	('0000'B),
-		LLC_SAPI_GMM		('0001'B),
-		LLC_SAPI_TOM2		('0010'B),
-		LLC_SAPI_LL3		('0011'B),
-		LLC_SAPI_RESERVED_4	('0100'B),
-		LLC_SAPI_LL5		('0101'B),
-		LLC_SAPI_RESERVED_6	('0110'B),
-		LLC_SAPI_SMS		('0111'B),
-		LLC_SAPI_TOM8		('1000'B),
-		LLC_SAPI_LL9		('1001'B),
-		LLC_SAPI_RESERVED_10	('1010'B),
-		LLC_SAPI_LL11		('1011'B),
-		LLC_SAPI_RESERVED_12	('1100'B),
-		LLC_SAPI_RESERVED_13	('1101'B),
-		LLC_SAPI_RESERVED_14	('1110'B),
-		LLC_SAPI_RESERVED_15	('1111'B)
-	} with { variant "FIELDLENGTH(4)" };
-
-	/* TS 44.064 Chapter 6.3 */
-	type record LlcCtrlFieldI {
-		BIT1 presence ('0'B),
-		boolean a,
-		BIT1 spare,
-		uint9_t n_s,
-		BIT1 spare2,
-		uint9_t n_r,
-		LlcCtrlS s
-	} with { variant
-		(a) "FIELDLENGTH(1)"
-	};
-
-	/* TS 44.064 Chapter 6.3 */
-	type record LlcCtrlFieldS {
-		BIT2 presence ('10'B),
-		boolean a,
-		BIT2 spare,
-		uint9_t  n_r,
-		LlcCtrlS s
-	} with {
-		variant (a) "FIELDLENGTH(1)"
-	};
-
-	/* TS 44.064 Chapter 6.3 */
-	type record LlcCtrlFieldUI {
-		BIT3 presence ('110'B),
-		BIT2 spare,
-		uint9_t n_u,
-		boolean e,
-		boolean pm
-	} with {
-		variant (e) "FIELDLENGTH(1)"
-		variant (pm) "FIELDLENGTH(1)"
-	};
-
-	template LlcCtrlFieldUI t_LlcCtrlUI(template uint8_t n_u) := {
-		presence := '110'B,
-		spare := '00'B,
-		n_u := n_u,
-		e := false,
-		pm := true
-	};
-
-	/* TS 44.064 Chapter 6.3 */
-	type record LlcCtrlFieldU {
-		BIT3 presence ('111'B),
-		boolean p_f,
-		LlcCtrlM m
-	} with {
-		variant (p_f) "FIELDLENGTH(1)"
-	};
-
-
-	/* TS 44.064 Chapter 6.4 */
-	type enumerated LlcCtrlS {
-		LLC_S_RR	('00'B),
-		LLC_S_ACK	('01'B),
-		LLC_S_RNR	('10'B),
-		LLC_S_SACK	('11'B)
-	} with { variant "FIELDLENGTH(2)" };
-
-	/* TS 44.064 Chapter 6.4 */
-	type enumerated LlcCtrlM {
-		LLC_M_DM	('0001'B),
-		LLC_M_DISC	('0100'B),
-		LLC_M_UA	('0110'B),
-		LLC_M_SABM	('0111'B),
-		LLC_M_FRMR	('1000'B),
-		LLC_M_XID	('1011'B),
-		LLC_M_NULL	('0000'B)
-	} with { variant "FIELDLENGTH(4)" };
-
-	type union LlcCtrlUnion {
-		LlcCtrlFieldI	i,
-		LlcCtrlFieldS	s,
-		LlcCtrlFieldUI	ui,
-		LlcCtrlFieldU	u
-	} with { variant "TAG(i, presence = '0'B;
-			      s, presence = '10'B;
-			      ui, presence = '110'B;
-			      u, presence = '111'B)"
-		 variant "FIELDORDER(msb)"
-	};
-
-	external function enc_LlcCtrlUnion(in LlcCtrlUnion pdu) return octetstring
-		with { extension "prototype(convert) encode(RAW)" };
-	external function dec_LlcCtrlUnion(in octetstring stream) return LlcCtrlUnion
-		with { extension "prototype(convert) decode(RAW)" };
-
-
-	type uint24_t LlcFcs;
-
-	type record LlcPdu {
-		LlcAddressField	addr,
-		LlcCtrlUnion	ctrl,
-		octetstring	payload//,
-		//LlcFcs		fcs
-	} with { variant "" };
-
-	external function enc_LlcPdu(in LlcPdu pdu) return octetstring
-		with { extension "prototype(convert) encode(RAW)" };
-	external function dec_LlcPdu(in octetstring stream) return LlcPdu
-		with { extension "prototype(convert) decode(RAW)" };
-
-
-	template LlcPdu t_LLC_UI(template boolean c_r, template uint8_t n_u, template octetstring payload,
-				 template LlcSapi sapi := LLC_SAPI_GMM) := {
-		addr := t_LLC_Addr(c_r, sapi),
-		ctrl := {
-			ui := t_LlcCtrlUI(n_u)
-		},
-		payload := payload
-	};
-} with { encode "RAW"; variant "FIELDORDER(msb)" }
diff --git a/gprs_gb/Test.ttcn b/gprs_gb/Test.ttcn
index 19cfd26..732b3f5 100644
--- a/gprs_gb/Test.ttcn
+++ b/gprs_gb/Test.ttcn
@@ -10,10 +10,28 @@
 	import from NS_Types all;
 	import from NS_Emulation all;
 	import from LLC_Types all;
+	import from LLC_Templates all;
 	import from RLCMAC_Types all;
 	import from RLCMAC_CSN1_Types all;
 	import from LAPDm_RAW_PT all;
 
+	modulepar {
+		BssgpConfig mp_gb_cfg := {
+			nsei := 96,
+			bvci := 196,
+			cell_id := {
+				ra_id := {
+					lai := {
+						mcc_mnc := '26242F'H, lac := 13135
+					},
+					rac := 0
+				},
+				cell_id := 20960
+			},
+			sgsn_role := true
+		};
+	}
+
 	type record MmContext {
 		octetstring	imsi optional,
 		GprsTlli	tlli,
@@ -51,7 +69,7 @@
 		/* connect lower-end of NS emulation to NS_CODEC_PORT (on top of IPl4) */
 		map(ns_component:NSCP, system:NS_CODEC_PORT);
 		ns_component.start(NSStart());
-		bssgp_component.start(BssgpStart());
+		bssgp_component.start(BssgpStart(mp_gb_cfg));
 
 		lapdm_component := lapdm_CT.create;
 		connect(self:L1, lapdm_component:LAPDM_SP);
@@ -138,20 +156,19 @@
 
 	const octetstring gmm_auth_req := '081200102198c72477ea104895e8b959acc58b108182'O;
 
-	function tx_gmm(boolean c_r, in octetstring gmm_pdu, LlcSapi sapi := LLC_SAPI_GMM) runs on dummy_CT {
-		var LlcPdu llc;
+	function tx_gmm(BIT1 c_r, in octetstring gmm_pdu, BIT4 sapi := c_LLC_SAPI_LLGMM) runs on dummy_CT {
+		var PDU_LLC llc;
 
 		//log("GMM Tx: ", dec_PDU_L3_SGSN_MS(gmm_pdu));
 
 		log(c_r, g_mmctx.n_u, gmm_pdu, sapi);
-		log(t_LLC_UI(c_r, g_mmctx.n_u, gmm_pdu, sapi));
-		llc := valueof(t_LLC_UI(c_r, g_mmctx.n_u, gmm_pdu, sapi));
+		llc := valueof(ts_LLC_UI(gmm_pdu, sapi, c_r, g_mmctx.n_u));
 		log(llc);
 		g_mmctx.n_u := g_mmctx.n_u + 1;
 
-		log(ts_BSSGP_DL_UD(g_mmctx.tlli, enc_LlcPdu(llc)));
+		log(ts_BSSGP_DL_UD(g_mmctx.tlli, enc_PDU_LLC(llc)));
 
-		BSSGP.send(ts_BSSGP_DL_UD(g_mmctx.tlli, enc_LlcPdu(llc)));
+		BSSGP.send(ts_BSSGP_DL_UD(g_mmctx.tlli, enc_PDU_LLC(llc)));
 	}
 
 	function f_bssgp_establish() runs on dummy_CT {
@@ -179,10 +196,10 @@
 		BSSGP.send(ts_BSSGP_PS_PAGING_PTMSI(bvci, imsi, tmsi));
 
 		while (true) {
-			var PDU_BSSGP pdu;
+			var BssgpDecoded bd;
 			alt {
-				[] BSSGP.receive(PDU_BSSGP:?) -> value pdu {
-					log("BSSGP Rx: ", pdu);
+				[] BSSGP.receive(tr_BD_L3_MT(?)) -> value bd {
+					log("BSSGP Rx: ", bd);
 				}
 				[] BSSGP.receive(t_BssgpStsInd(?, ?, BVC_S_UNBLOCKED)) { repeat; }
 				[] BSSGP.receive { repeat; }
@@ -322,7 +339,7 @@
 		var template RlcmacUlBlock blk := t_RLCMAC_UL_DATA_TLLI(0, 0, 0, {t_RLCMAC_LLCBLOCK(payload)}, false, tlli);
 		L1.send(RLCMAC_ph_data_req:{tbf_id := 0, cs := cs, block := blk});
 		/* ensure that this LLC-PDU arrives from the right TLLI at the (simulated) SGSN */
-		BSSGP.receive(tr_BSSGP_UL_UD(tlli, ?, payload));
+		BSSGP.receive(tr_BD_BSSGP(tr_BSSGP_UL_UD(tlli, ?, payload)));
 
 		/* ensure the MS eceives an UL_ACK_NACK */
 		alt {
@@ -346,12 +363,12 @@
 		f_single_ul_block(CS1);
 
 		while (true) {
-			var PDU_BSSGP pdu;
+			var BssgpDecoded bd;
 			var RLCMAC_ph_data_ind dl_msg;
 			alt {
 
-				[] BSSGP.receive(PDU_BSSGP:?) -> value pdu {
-					log("BSSGP Rx: ", pdu);
+				[] BSSGP.receive(tr_BD_BSSGP(?)) -> value bd {
+					log("BSSGP Rx: ", bd);
 				}
 				[] BSSGP.receive(t_BssgpStsInd(?, ?, BVC_S_UNBLOCKED)) { repeat; }
 				[] BSSGP.receive { repeat; }
@@ -369,12 +386,12 @@
 		f_bssgp_establish();
 
 		while (true) {
-			var PDU_BSSGP pdu;
+			var BssgpDecoded bd;
 			alt {
-				[] BSSGP.receive(PDU_BSSGP:?) -> value pdu {
-					log("BSSGP Rx: ", pdu);
+				[] BSSGP.receive(tr_BD_BSSGP(?)) -> value bd {
+					log("BSSGP Rx: ", bd);
 					//log("GMM Rx: ", dec_PDU_L3_MS_SGSN(pdu.payload));
-					g_mmctx.tlli := oct2int(pdu.pDU_BSSGP_UL_UNITDATA.tLLI);
+					g_mmctx.tlli := oct2int(bd.bssgp.pDU_BSSGP_UL_UNITDATA.tLLI);
 					tx_gmm(LLC_CR_DL_CMD, gmm_auth_req);
 				}
 				[] BSSGP.receive(t_BssgpStsInd(?, ?, BVC_S_UNBLOCKED)) { repeat; }
@@ -386,7 +403,7 @@
 
 	function f_llc_dec_and_log(in octetstring inp) {
 		log("LLC Input: ", inp);
-		var LlcPdu dec := dec_LlcPdu(inp);
+		var PDU_LLC dec := dec_PDU_LLC(inp);
 		log("LLC Decoded: ", dec);
 	}
 
@@ -405,17 +422,13 @@
 	testcase TC_selftest_llc() runs on dummy_CT {
 		const octetstring c_gmm_att_pcu := '01c001080103e5e000210a0005f4fb146ddd32f44000c8001d1b53432b37159ef9090070000dd9c6321200e00019b32c642401c00020170580460b'O;
 		const octetstring c_gmm_att_pcu_nofcs := '01c001080103e5e000210a0005f4fb146ddd32f44000c8001d1b53432b37159ef9090070000dd9c6321200e00019b32c642401c000201705'O;
-		const octetstring c_ctrl_ui := 'c001'O;
-
-		log(dec_LlcCtrlUnion(c_ctrl_ui));
-		f_llc_assert(enc_LlcCtrlUnion({ ui := { presence := '110'B, spare := '00'B, n_u := 0, e := false, pm := true } }), c_ctrl_ui);
 
 		f_llc_dec_and_log(c_gmm_att_pcu);
 
 		//f_llc_assert(f_LLC_append_fcs(c_gmm_att_pcu_nofcs), c_gmm_att_pcu);
 
-		log(valueof(t_LLC_UI(LLC_CR_DL_CMD, g_mmctx.n_u, gmm_auth_req, LLC_SAPI_GMM)));
-		log(t_LLC_UI(LLC_CR_DL_CMD, g_mmctx.n_u, gmm_auth_req, LLC_SAPI_GMM));
+		log(valueof(ts_LLC_UI(gmm_auth_req, c_LLC_SAPI_LLGMM, LLC_CR_DL_CMD, g_mmctx.n_u)));
+		log(ts_LLC_UI(gmm_auth_req, c_LLC_SAPI_LLGMM, LLC_CR_DL_CMD, g_mmctx.n_u));
 	}
 
 	testcase TC_selftest_rlcmac() runs on dummy_CT {
diff --git a/gprs_gb/gen_links.sh b/gprs_gb/gen_links.sh
index 53b50fa..85a35ab 100755
--- a/gprs_gb/gen_links.sh
+++ b/gprs_gb/gen_links.sh
@@ -39,9 +39,17 @@
 FILES="BSSGP_EncDec.cc  BSSGP_Types.ttcn"
 gen_links $DIR $FILES
 
+DIR=$BASEDIR/titan.ProtocolModules.MobileL3_v13.4.0/src
+FILES="MobileL3_CC_Types.ttcn MobileL3_CommonIE_Types.ttcn MobileL3_GMM_SM_Types.ttcn MobileL3_MM_Types.ttcn MobileL3_RRM_Types.ttcn MobileL3_SMS_Types.ttcn MobileL3_SS_Types.ttcn MobileL3_Types.ttcn"
+gen_links $DIR $FILES
+
+DIR=$BASEDIR/titan.ProtocolModules.LLC_v7.1.0/src
+FILES="LLC_EncDec.cc LLC_Types.ttcn"
+gen_links $DIR $FILES
 
 DIR=../library
 FILES="General_Types.ttcn GSM_Types.ttcn GSM_RR_Types.ttcn Osmocom_Types.ttcn RLCMAC_Types.ttcn RLCMAC_CSN1_Types.ttcn RLCMAC_EncDec.cc L1CTL_Types.ttcn L1CTL_PortType.ttcn LAPDm_RAW_PT.ttcn LAPDm_Types.ttcn "
 FILES+="NS_Emulation.ttcn NS_CodecPort.ttcn NS_CodecPort_CtrlFunct.ttcn NS_CodecPort_CtrlFunctDef.cc "
 FILES+="BSSGP_Emulation.ttcn Osmocom_Gb_Types.ttcn "
+FILES+="LLC_Templates.ttcn L3_Templates.ttcn L3_Common.ttcn "
 gen_links $DIR $FILES
diff --git a/gprs_gb/regen_makefile.sh b/gprs_gb/regen_makefile.sh
index 656726b..8b79d73 100755
--- a/gprs_gb/regen_makefile.sh
+++ b/gprs_gb/regen_makefile.sh
@@ -1,5 +1,5 @@
 #!/bin/sh
 
-FILES="*.ttcn BSSGP_EncDec.cc IPL4asp_PT.cc IPL4asp_discovery.cc TCCConversion.cc TCCInterface.cc NS_CodecPort_CtrlFunctDef.cc UD_PT.cc RLCMAC_EncDec.cc"
+FILES="*.ttcn BSSGP_EncDec.cc IPL4asp_PT.cc IPL4asp_discovery.cc TCCConversion.cc TCCInterface.cc NS_CodecPort_CtrlFunctDef.cc UD_PT.cc RLCMAC_EncDec.cc LLC_EncDec.cc"
 
 ../regen-makefile.sh Test.ttcn $FILES