[MERGED] osmo-ttcn3-hacks[master]: Migrate Gb (NS/BSSGP) code over to Ericsson NS/BSSGP modules

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Harald Welte gerrit-no-reply at lists.osmocom.org
Fri Feb 16 19:03:32 UTC 2018


Harald Welte has submitted this change and it was merged.

Change subject: Migrate Gb (NS/BSSGP) code over to Ericsson NS/BSSGP modules
......................................................................


Migrate Gb (NS/BSSGP) code over to Ericsson NS/BSSGP modules

When we started out, Ericsson hadn't released yet their NS and BSSGP
modules.  Let's port our logic over to their encoder/decoders, as they
are more complete (but less regular / more difficult to use).

Change-Id: Icbc4f5d24f3419f99c9a4805f836bddd2849f492
---
M gprs_gb/Test.ttcn
M gprs_gb/gen_links.sh
M gprs_gb/regen_makefile.sh
M library/BSSGP_Emulation.ttcn
M library/NS_CodecPort.ttcn
M library/NS_Emulation.ttcn
A library/Osmocom_Gb_Types.ttcn
7 files changed, 737 insertions(+), 143 deletions(-)

Approvals:
  Harald Welte: Looks good to me, approved
  Jenkins Builder: Verified



diff --git a/gprs_gb/Test.ttcn b/gprs_gb/Test.ttcn
index 1c3fb50..19cfd26 100644
--- a/gprs_gb/Test.ttcn
+++ b/gprs_gb/Test.ttcn
@@ -4,7 +4,7 @@
 	import from Osmocom_Types all;
 	import from GSM_Types all;
 	import from GSM_RR_Types all;
-	import from BSSGP_Helper_Functions all;
+	import from Osmocom_Gb_Types all;
 	import from BSSGP_Types all;
 	import from BSSGP_Emulation all;
 	import from NS_Types all;
@@ -16,7 +16,7 @@
 
 	type record MmContext {
 		octetstring	imsi optional,
-		BssgpTlli	tlli,
+		GprsTlli	tlli,
 		uint9_t		n_u
 	};
 
@@ -59,24 +59,9 @@
 		lapdm_component.start(LAPDmStart());
 	}
 
-	function f_bssgp_assert_prepr(in octetstring a, in octetstring b) {
-		log("BSSGP Input: ", a);
-		log("BSSGP Expected: ", b);
-		var octetstring a_preprocessed := f_BSSGP_expand_len(a);
-		log("BSSGP Preprocessed: ", a_preprocessed);
-
-		if (a_preprocessed != b) {
-			setverdict(fail);
-		} else {
-			setverdict(pass);
-		}
-	}
-
 	function f_bssgp_dec_and_log(in octetstring inp) {
 		log("BSSGP Input: ", inp);
-		var octetstring inp_p := f_BSSGP_expand_len(inp);
-		log("BSSGP Preprocessed: ", inp_p);
-		var BssgpPdu dec := dec_BssgpPdu(inp_p);
+		var PDU_BSSGP dec := dec_PDU_BSSGP(inp);
 		log("BSSGP Decoded: ", dec);
 	}
 
@@ -97,18 +82,6 @@
 		const octetstring c_gmm_mt_det_req := '00bb146ddd0050001682ffff0a8204030e8941c00908050215f0b6'O;
 		const octetstring c_gmm_mo_att_cpl := '01fb146ddd000004088832f44000c80051e000800e000801c009080339d7bc'O;
 
-		/* single byte length to two byte length */
-		f_bssgp_assert_prepr('04058101'O, '0405000101'O);
-		f_bssgp_assert_prepr('040589000102030405060708'O, '04050009000102030405060708'O);
-		/* two byte length to two byte length */
-		f_bssgp_assert_prepr('0405000101'O, '0405000101'O);
-		/* special case: DL-UD + UL-UD */
-		f_bssgp_assert_prepr('00aabbccddeeffaa29822342'O, '00aabbccddeeffaa2900022342'O);
-		f_bssgp_assert_prepr('01aabbccddeeffaa29822342'O, '01aabbccddeeffaa2900022342'O);
-		/* multiple TLVs */
-		f_bssgp_assert_prepr('234281aa4382bbbb'O, '23420001aa430002bbbb'O);
-		f_bssgp_assert_prepr('230080'O, '23000000'O);
-
 		f_bssgp_dec_and_log(c_bvc_reset_pcu);
 		f_bssgp_dec_and_log(c_bvc_reset_q);
 		f_bssgp_dec_and_log(c_status_pcu);
@@ -125,16 +98,14 @@
 		f_bssgp_dec_and_log(c_gmm_mt_det_req);
 		f_bssgp_dec_and_log(c_gmm_mo_att_cpl);
 
-		log(t_BSSGP_PS_PAGING_IMSI(196, '262420123456789'H));
+		log(ts_BSSGP_PS_PAGING_IMSI(196, '262420123456789'H));
 	}
 
 	function f_ns_assert_prepr(in octetstring a, in octetstring b) {
 		log("NS Input: ", a);
 		log("NS Expected: ", b);
-		var octetstring a_preprocessed := f_NS_expand_len(a);
-		log("NS Preprocessed: ", a_preprocessed);
 
-		if (a_preprocessed != b) {
+		if (a != b) {
 			setverdict(fail);
 		} else {
 			setverdict(pass);
@@ -143,9 +114,7 @@
 
 	function f_ns_dec_and_log(in octetstring inp) {
 		log("NS Input: ", inp);
-		var octetstring inp_p := f_NS_expand_len(inp);
-		log("NS Preprocessed: ", inp_p);
-		var NsPdu dec := dec_NsPdu(inp_p);
+		var PDU_NS dec := dec_PDU_NS(inp);
 		log("NS Decoded: ", dec);
 	}
 
@@ -167,57 +136,6 @@
 		f_ns_dec_and_log(c_ns_reset_pcu);
 	}
 
-	const BssgpQosProfile c_DefaultQos := { r := 80, spare := '00'B, c_r := false, t := false, a := false, precedence := 0 };
-	template BssgpTLV c_DefaultLifetimeTLV := t_BSSGP_IE_Lifetime(65535);
-
-	template BssgpTLV t_BSSGP_IE_LLC_PDU(LlcPdu llc) := t_BssgpIE(LLC_PDU, { other := f_LLC_append_fcs(enc_LlcPdu(llc)) });
-
-	template BssgpPdu t_BSSGP_DL_UD(BssgpTlli tlli, LlcPdu llc, BssgpTLVs opt_tlvs := {}) := {
-		pdu_type := DL_UNITDATA,
-		u := {
-			dl_unitdata := {
-				tlli := tlli,
-				qos_profile := c_DefaultQos,
-				pdu_lifetime := c_DefaultLifetimeTLV,
-				//tlvs := opt_tlvs & { t_BSSGP_IE_LLC_PDU(llc) }
-				tlvs := { t_BSSGP_IE_LLC_PDU(llc) }
-			}
-		}
-	};
-
-	template BssgpPdu t_BSSGP_UL_UD(template BssgpTlli tlli, template BssgpCellId cell_id, template octetstring payload) := {
-		pdu_type := UL_UNITDATA,
-		u := {
-			ul_unitdata := {
-				tlli := tlli,
-				qos_profile := ?,
-				cell_id := { iei := CELL_ID, len := 8, u := { cell_id := cell_id } },
-				tlvs := {
-						{ iei := ALIGNMENT_OCTETS, len := ?, u := { other := ? } },
-						{ iei := LLC_PDU, len := ?, u := { other := payload } }
-				}
-			}
-		}
-	}
-
-	template BssgpPdu t_BSSGP_PS_PAGING_IMSI(BssgpBvci bvci, hexstring imsi) := {
-		pdu_type := PAGING_PS,
-		u := {
-			other := {
-				tlvs := { t_BSSGP_IE_Imsi(imsi), t_BSSGP_IE_Bvci(bvci), t_BSSGP_IE_Qos(c_DefaultQos) }
-			}
-		}
-	};
-
-	template BssgpPdu t_BSSGP_PS_PAGING_PTMSI(BssgpBvci bvci, hexstring imsi, GsmTmsi ptmsi) := {
-		pdu_type := PAGING_PS,
-		u := {
-			other := {
-				tlvs := { t_BSSGP_IE_Imsi(imsi), t_BSSGP_IE_Bvci(bvci), t_BSSGP_IE_Qos(c_DefaultQos), t_BSSGP_IE_Tmsi(ptmsi) }
-			}
-		}
-	};
-
 	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 {
@@ -231,9 +149,9 @@
 		log(llc);
 		g_mmctx.n_u := g_mmctx.n_u + 1;
 
-		log(t_BSSGP_DL_UD(g_mmctx.tlli, llc));
+		log(ts_BSSGP_DL_UD(g_mmctx.tlli, enc_LlcPdu(llc)));
 
-		BSSGP.send(t_BSSGP_DL_UD(g_mmctx.tlli, llc));
+		BSSGP.send(ts_BSSGP_DL_UD(g_mmctx.tlli, enc_LlcPdu(llc)));
 	}
 
 	function f_bssgp_establish() runs on dummy_CT {
@@ -257,13 +175,13 @@
 
 		f_bssgp_establish();
 
-		BSSGP.send(t_BSSGP_PS_PAGING_IMSI(bvci, imsi));
-		BSSGP.send(t_BSSGP_PS_PAGING_PTMSI(bvci, imsi, tmsi));
+		BSSGP.send(ts_BSSGP_PS_PAGING_IMSI(bvci, imsi));
+		BSSGP.send(ts_BSSGP_PS_PAGING_PTMSI(bvci, imsi, tmsi));
 
 		while (true) {
-			var BssgpPdu pdu;
+			var PDU_BSSGP pdu;
 			alt {
-				[] BSSGP.receive(BssgpPdu:?) -> value pdu {
+				[] BSSGP.receive(PDU_BSSGP:?) -> value pdu {
 					log("BSSGP Rx: ", pdu);
 				}
 				[] BSSGP.receive(t_BssgpStsInd(?, ?, BVC_S_UNBLOCKED)) { repeat; }
@@ -404,7 +322,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(t_BSSGP_UL_UD(tlli, ?, payload));
+		BSSGP.receive(tr_BSSGP_UL_UD(tlli, ?, payload));
 
 		/* ensure the MS eceives an UL_ACK_NACK */
 		alt {
@@ -428,11 +346,11 @@
 		f_single_ul_block(CS1);
 
 		while (true) {
-			var BssgpPdu pdu;
+			var PDU_BSSGP pdu;
 			var RLCMAC_ph_data_ind dl_msg;
 			alt {
 
-				[] BSSGP.receive(BssgpPdu:?) -> value pdu {
+				[] BSSGP.receive(PDU_BSSGP:?) -> value pdu {
 					log("BSSGP Rx: ", pdu);
 				}
 				[] BSSGP.receive(t_BssgpStsInd(?, ?, BVC_S_UNBLOCKED)) { repeat; }
@@ -451,12 +369,12 @@
 		f_bssgp_establish();
 
 		while (true) {
-			var BssgpPdu pdu;
+			var PDU_BSSGP pdu;
 			alt {
-				[] BSSGP.receive(BssgpPdu:?) -> value pdu {
+				[] BSSGP.receive(PDU_BSSGP:?) -> value pdu {
 					log("BSSGP Rx: ", pdu);
 					//log("GMM Rx: ", dec_PDU_L3_MS_SGSN(pdu.payload));
-					g_mmctx.tlli := pdu.u.ul_unitdata.tlli;
+					g_mmctx.tlli := oct2int(pdu.pDU_BSSGP_UL_UNITDATA.tLLI);
 					tx_gmm(LLC_CR_DL_CMD, gmm_auth_req);
 				}
 				[] BSSGP.receive(t_BssgpStsInd(?, ?, BVC_S_UNBLOCKED)) { repeat; }
@@ -494,7 +412,7 @@
 
 		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);
+		//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));
diff --git a/gprs_gb/gen_links.sh b/gprs_gb/gen_links.sh
index 32f892f..53b50fa 100755
--- a/gprs_gb/gen_links.sh
+++ b/gprs_gb/gen_links.sh
@@ -31,8 +31,17 @@
 FILES="UD_PT.cc  UD_PT.hh  UD_PortType.ttcn  UD_Types.ttcn"
 gen_links $DIR $FILES
 
+DIR=$BASEDIR/titan.ProtocolModules.NS_v7.3.0/src
+FILES="NS_Types.ttcn"
+gen_links $DIR $FILES
+
+DIR=$BASEDIR/titan.ProtocolModules.BSSGP_v13.0.0/src
+FILES="BSSGP_EncDec.cc  BSSGP_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_Types.ttcn NS_Emulation.ttcn NS_CodecPort.ttcn NS_CodecPort_CtrlFunct.ttcn NS_CodecPort_CtrlFunctDef.cc "
-FILES+="BSSGP_Emulation.ttcn BSSGP_Helper.cc BSSGP_Helper_Functions.ttcn BSSGP_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 "
 gen_links $DIR $FILES
diff --git a/gprs_gb/regen_makefile.sh b/gprs_gb/regen_makefile.sh
index b883d1e..656726b 100755
--- a/gprs_gb/regen_makefile.sh
+++ b/gprs_gb/regen_makefile.sh
@@ -1,5 +1,5 @@
 #!/bin/sh
 
-FILES="*.ttcn BSSGP_Helper.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"
 
 ../regen-makefile.sh Test.ttcn $FILES
diff --git a/library/BSSGP_Emulation.ttcn b/library/BSSGP_Emulation.ttcn
index ac7beb8..70c9c80 100644
--- a/library/BSSGP_Emulation.ttcn
+++ b/library/BSSGP_Emulation.ttcn
@@ -2,7 +2,7 @@
 	import from NS_Types all;
 	import from NS_Emulation all;
 	import from BSSGP_Types all;
-	import from BSSGP_Helper_Functions all;
+	import from Osmocom_Gb_Types all;
 	import from IPL4asp_Types all;
 
 	type record BssgpStatusIndication {
@@ -24,8 +24,8 @@
 
 	/* port from our (internal) point of view */
 	type port BSSGP_SP_PT message {
-		in	BssgpPdu;
-		out	BssgpPdu,
+		in	PDU_BSSGP;
+		out	PDU_BSSGP,
 			NsStatusIndication,
 			BssgpStatusIndication,
 			ASP_Event;
@@ -36,8 +36,8 @@
 		in	ASP_Event,
 			NsStatusIndication,
 			BssgpStatusIndication,
-			BssgpPdu;
-		out	BssgpPdu;
+			PDU_BSSGP;
+		out	PDU_BSSGP;
 	} with { extension "internal" };
 
 	function BssgpStart() runs on BSSGP_CT {
@@ -65,10 +65,10 @@
 	modulepar {
 		Nsvci mp_nsei := 96;
 		Nsvci mp_bvci := 196;
-		BssgpCellId mp_cellid := { ra_id := { lai := { mcc_mnc := '262F42'H, lac := 13135}, rac := 0 }, cell_id := 20960 };
+		BssgpCellId mp_cellid := { ra_id := { lai := { mcc_mnc := '26242F'H, lac := 13135}, rac := 0 }, cell_id := 20960 };
 	};
 
-	function f_BnsUdReq(template BssgpPdu pdu, BssgpBvci bvci := mp_bvci) return NsUnitdataRequest {
+	function f_BnsUdReq(template PDU_BSSGP pdu, BssgpBvci bvci := mp_bvci) return NsUnitdataRequest {
 		var NsUnitdataRequest udr := {
 			bvci := bvci,
 			nsei := mp_nsei,
@@ -76,13 +76,13 @@
 			 * unbound integer value." when trying to send the reocrd rather than the octetstring */
 			//sdu := omit,
 			//bssgp := valueof(pdu)
-			sdu := f_BSSGP_compact_len(enc_BssgpPdu(valueof(pdu))),
+			sdu := enc_PDU_BSSGP(valueof(pdu)),
 			bssgp := omit
 		}
 		return udr;
 	}
 
-	function f_BnsUdInd(template BssgpPdu pdu, template BssgpBvci bvci := mp_bvci) return template NsUnitdataIndication {
+	function f_BnsUdInd(template PDU_BSSGP pdu, template BssgpBvci bvci := mp_bvci) return template NsUnitdataIndication {
 		var template NsUnitdataIndication udi := {
 			bvci := bvci,
 			nsei := mp_nsei,
@@ -99,9 +99,9 @@
 	}
 
 	private function f_sendReset() runs on BSSGP_CT {
-		var BssgpPdu pdu := valueof(t_BVC_RESET(BSSGP_CAUSE_OM_INTERVENTION, mp_bvci, mp_cellid));
+		var PDU_BSSGP pdu := valueof(ts_BVC_RESET(BSSGP_CAUSE_OM_INTERVENTION, mp_bvci, mp_cellid));
 		log("PDU: ", pdu);
-		log("ENC: ", enc_BssgpPdu(pdu));
+		log("ENC: ", enc_PDU_BSSGP(pdu));
 
 		/* BVC-RESET is always sent via the SIGNALLING BVCI, see Table 5.4.1 */
 		BSCP.send(f_BnsUdReq(pdu, 0));
@@ -119,9 +119,9 @@
 		g_T1.start;
 	}
 
-	private function f_sendStatus(BssgpCause cause, BssgpPdu pdu) runs on BSSGP_CT {
+	private function f_sendStatus(BssgpCause cause, PDU_BSSGP pdu) runs on BSSGP_CT {
 		/* FIXME: Make sure correct Signaling or PTP BVCI is used! */
-		BSCP.send(f_BnsUdReq(t_BSSGP_STATUS({ t_BSSGP_IE_Cause(cause), t_BSSGP_IE_Bvci(mp_bvci), t_BSSGP_IE_PDU(pdu)})));
+		BSCP.send(f_BnsUdReq(ts_BSSGP_STATUS(mp_bvci, cause, pdu)));
 	}
 
 	altstep as_allstate() runs on BSSGP_CT {
@@ -136,20 +136,20 @@
 		}
 
 		/* Respond to RESET with correct BVCI/CellID */
-		[] BSCP.receive(f_BnsUdInd(t_BVC_RESET(?, mp_bvci, mp_cellid), 0)) -> value udi {
+		[] BSCP.receive(f_BnsUdInd(tr_BVC_RESET(?, mp_bvci, mp_cellid), 0)) -> value udi {
 			log("Rx BVC-RESET for Our BVCI=", mp_bvci);
-			BSCP.send(f_BnsUdReq(t_BVC_RESET_ACK(mp_bvci, mp_cellid), 0));
+			BSCP.send(f_BnsUdReq(ts_BVC_RESET_ACK(mp_bvci, mp_cellid), 0));
 			f_change_state(BVC_S_UNBLOCKED);
 		}
 
 		/* Respond to RESET for signalling BVCI 0 */
-		[] BSCP.receive(f_BnsUdInd(t_BVC_RESET(?, 0, mp_cellid), 0)) -> value udi {
+		[] BSCP.receive(f_BnsUdInd(tr_BVC_RESET(?, 0, mp_cellid), 0)) -> value udi {
 			log("Rx BVC-RESET for Signaling BVCI=0");
-			BSCP.send(f_BnsUdReq(t_BVC_RESET_ACK(0, mp_cellid), 0));
+			BSCP.send(f_BnsUdReq(ts_BVC_RESET_ACK(0, mp_cellid), 0));
 		}
 
 		/* Respond to RESET with wrong NSEI/NSVCI */
-		[] BSCP.receive(f_BnsUdInd(t_BVC_RESET(?, ?, ?), 0)) -> value udi {
+		[] BSCP.receive(f_BnsUdInd(tr_BVC_RESET(?, ?, ?), 0)) -> value udi {
 			log("Rx BVC-RESET for unknown BVCI");
 			f_sendStatus(BSSGP_CAUSE_BVCI_UNKNOWN, udi.bssgp);
 		}
@@ -175,11 +175,11 @@
 
 	private function f_ScanEvents() runs on BSSGP_CT {
 		var NsUnitdataIndication udi;
-		var BssgpPdu bs_pdu;
+		var PDU_BSSGP bs_pdu;
 		var default d;
 
 
-		log("matching against ", t_BVC_RESET(?, mp_bvci, mp_cellid));
+		log("matching against ", tr_BVC_RESET(?, mp_bvci, mp_cellid));
 
 		d := activate(as_allstate());
 
@@ -213,28 +213,30 @@
 					g_T1.stop;
 					f_change_state(BVC_S_BLOCKED);
 				}
-				[] BSCP.receive(f_BnsUdInd(t_BVC_RESET_ACK(mp_bvci, mp_cellid), 0)) -> value udi {
+				[] BSCP.receive(f_BnsUdInd(tr_BVC_RESET_ACK(mp_bvci, mp_cellid), 0)) -> value udi {
 					g_T2.stop;
 					f_change_state(BVC_S_UNBLOCKED);
 				}
 
 				/* simply acknowledge all Flow Control Messages */
+/*
 				[g_sgsn_role] BSCP.receive(f_BnsUdInd(t_BVC_FC_BVC)) {
 					BSCP.send(f_BnsUdReq(t_BVC_FC_BVC_ACK));
 				}
 				[g_sgsn_role] BSCP.receive(f_BnsUdInd(t_BVC_FC_MS)) {
 					BSCP.send(f_BnsUdReq(t_BVC_FC_MS_ACK));
 				}
+*/
 
 				/* BSSGP-UNITDATA PDUs from network to NS-UNITDATA.ind to user */
-				[] BSCP.receive(f_BnsUdInd(tr_BSSGP_type(DL_UNITDATA))) -> value udi {
+				[not g_sgsn_role] BSCP.receive(f_BnsUdInd(tr_BSSGP_DL_UD)) -> value udi {
 					BSSGP_SP.send(udi.bssgp);
 				}
-				[] BSCP.receive(f_BnsUdInd(tr_BSSGP_type(UL_UNITDATA))) -> value udi {
+				[g_sgsn_role] BSCP.receive(f_BnsUdInd(tr_BSSGP_UL_UD)) -> value udi {
 					BSSGP_SP.send(udi.bssgp);
 				}
 				/* pass virtually any PDU from user to NS-UNITDATA PDU on network */
-				[] BSSGP_SP.receive(BssgpPdu:?) -> value bs_pdu {
+				[] BSSGP_SP.receive(PDU_BSSGP:?) -> value bs_pdu {
 					BSCP.send(f_BnsUdReq(bs_pdu));
 				}
 
diff --git a/library/NS_CodecPort.ttcn b/library/NS_CodecPort.ttcn
index 29f8aa5..82ba55b 100644
--- a/library/NS_CodecPort.ttcn
+++ b/library/NS_CodecPort.ttcn
@@ -2,7 +2,6 @@
 
 	import from IPL4asp_PortType all;
 	import from IPL4asp_Types all;
-	import from BSSGP_Helper_Functions all;
 	import from NS_Types all;
 
 	type record NS_RecvFrom {
@@ -11,10 +10,10 @@
 		PortNumber	remPort,
 		HostName	locName,
 		PortNumber	locPort,
-		NsPdu		msg
+		PDU_NS		msg
 	}
 
-	template NS_RecvFrom t_NS_RecvFrom(template NsPdu pdu) := {
+	template NS_RecvFrom t_NS_RecvFrom(template PDU_NS pdu) := {
 		connId := ?,
 		remName := ?,
 		remPort := ?,
@@ -25,10 +24,10 @@
 
 	type record NS_Send {
 		ConnectionId	connId,
-		NsPdu		msg
+		PDU_NS		msg
 	}
 
-	template NS_Send t_NS_Send(template ConnectionId connId, template NsPdu msg) := {
+	template NS_Send t_NS_Send(template ConnectionId connId, template PDU_NS msg) := {
 		connId := connId,
 		msg := msg
 	}
@@ -39,13 +38,13 @@
 		pout.remPort := pin.remPort;
 		pout.locName := pin.locName;
 		pout.locPort := pin.locPort;
-		pout.msg := dec_NsPdu(f_NS_expand_len(pin.msg));
+		pout.msg := dec_PDU_NS(pin.msg);
 	} with { extension "prototype(fast)" };
 
 	private function NS_to_IPL4_Send(in NS_Send pin, out ASP_Send pout) {
 		pout.connId := pin.connId;
 		pout.proto := { udp := {} };
-		pout.msg := f_NS_compact_len(enc_NsPdu(pin.msg));
+		pout.msg := enc_PDU_NS(pin.msg);
 	} with { extension "prototype(fast)" };
 
 	type port NS_CODEC_PT message {
diff --git a/library/NS_Emulation.ttcn b/library/NS_Emulation.ttcn
index 253c91e..5924bbe 100644
--- a/library/NS_Emulation.ttcn
+++ b/library/NS_Emulation.ttcn
@@ -1,7 +1,7 @@
 module NS_Emulation {
 	import from NS_Types all;
 	import from BSSGP_Types all;
-	import from BSSGP_Helper_Functions all;
+	import from Osmocom_Gb_Types all;
 	import from NS_CodecPort all;
 	import from NS_CodecPort_CtrlFunct all;
 	import from IPL4asp_Types all;
@@ -10,11 +10,11 @@
 		BssgpBvci	bvci,
 		Nsei		nsei,
 		octetstring	sdu optional,
-		BssgpPdu	bssgp optional
+		PDU_BSSGP	bssgp optional
 	}
 
 	template NsUnitdataRequest t_NsUdReq(template Nsei nsei, template BssgpBvci bvci, template octetstring sdu,
-					     template BssgpPdu bssgp) := {
+					     template PDU_BSSGP bssgp) := {
 		bvci := bvci,
 		nsei := nsei,
 		sdu := sdu,
@@ -25,14 +25,14 @@
 		BssgpBvci	bvci,
 		Nsei		nsei,
 		octetstring	sdu optional,
-		BssgpPdu	bssgp optional
+		PDU_BSSGP	bssgp optional
 	}
 
 	template NsUnitdataIndication t_NsUdInd(Nsei nsei, BssgpBvci bvci, octetstring sdu) := {
 		bvci := bvci,
 		nsei := nsei,
 		sdu := sdu,
-		bssgp := dec_BssgpPdu(f_BSSGP_expand_len(sdu))
+		bssgp := dec_PDU_BSSGP(sdu)
 	}
 
 	type record NsStatusIndication {
@@ -186,7 +186,7 @@
 		/* default case of handling unknown PDUs */
 		[] NSCP.receive(t_NS_RecvFrom(?)) -> value rf {
 			log("Rx Unexpected NS PDU ", rf.msg," in state ", g_state);
-			NSCP.send(t_NS_Send(g_conn_id, t_NS_STATUS(NS_CAUSE_PDU_NOT_COMPATIBLE_WITH_PROTOCOL_STATE, rf.msg)));
+			NSCP.send(t_NS_Send(g_conn_id, ts_NS_STATUS(NS_CAUSE_PDU_NOT_COMPATIBLE_WITH_PROTOCOL_STATE, rf.msg)));
 		}
 		/* Forwarding of ASP_Evet to user */
 		[] NSCP.receive(ASP_Event:?) -> value evt { NS_SP.send(evt); }
@@ -250,7 +250,9 @@
 				}
 				/* NS-UNITDATA PDU from network to NS-UNITDATA.ind to user */
 				[] NSCP.receive(t_NS_RecvFrom(t_NS_UNITDATA(?, ?, ?))) -> value rf {
-					NS_SP.send(t_NsUdInd(mp_nsei, rf.msg.u.unitdata.bvci, rf.msg.u.unitdata.sdu));
+					NS_SP.send(t_NsUdInd(mp_nsei,
+							     oct2int(rf.msg.pDU_NS_Unitdata.bVCI),
+							     rf.msg.pDU_NS_Unitdata.nS_SDU));
 				}
 				/* NS-UNITDATA.req from user to NS-UNITDATA PDU on network */
 				[] NS_SP.receive(t_NsUdReq(mp_nsei, ?, ?, omit)) -> value ud_req {
@@ -259,7 +261,7 @@
 				}
 				[] NS_SP.receive(t_NsUdReq(mp_nsei, ?, omit, ?)) -> value ud_req {
 					/* using decoded BSSGP PDU that we need to encode first */
-					var octetstring enc := f_BSSGP_compact_len(enc_BssgpPdu(ud_req.bssgp));
+					var octetstring enc := enc_PDU_BSSGP(ud_req.bssgp);
 					NSCP.send(t_NS_Send(g_conn_id, t_NS_UNITDATA(t_SduCtrlB, ud_req.bvci, enc)));
 				}
 			}
diff --git a/library/Osmocom_Gb_Types.ttcn b/library/Osmocom_Gb_Types.ttcn
new file mode 100644
index 0000000..641e562
--- /dev/null
+++ b/library/Osmocom_Gb_Types.ttcn
@@ -0,0 +1,664 @@
+module Osmocom_Gb_Types {
+
+	/* This module contains additional definitions and templates that we use on top of the
+	 * TITAN NS + BSSGP modules */
+
+	import from General_Types all;
+	import from Osmocom_Types all;
+	import from GSM_Types all;
+	import from GSM_RR_Types all;
+	import from BSSGP_Types all
+	import from NS_Types all
+
+	type uint16_t Nsvci;
+	type uint16_t Nsei;
+	type uint16_t BssgpBvci;
+
+	/* TS 48.016 10.3.7 */
+	type enumerated NsPduType {
+		NS_PDUT_NS_UNITDATA	('00000000'B),
+		NS_PDUT_NS_RESET	('00000010'B),
+		NS_PDUT_NS_RESET_ACK	('00000011'B),
+		NS_PDUT_NS_BLOCK	('00000100'B),
+		NS_PDUT_NS_BLOCK_ACK	('00000101'B),
+		NS_PDUT_NS_UNBLOCK	('00000110'B),
+		NS_PDUT_NS_UNBLOCK_ACK	('00000111'B),
+		NS_PDUT_NS_STATUS	('00001000'B),
+		NS_PDUT_NS_ALIVE	('00001010'B),
+		NS_PDUT_NS_ALIVE_ACK	('00001011'B)
+		/* FIXME: SNS */
+	} with { variant "FIELDLENGTH(8)" };
+
+	/* TS 48.016 10.3 */
+	type enumerated NsIEI {
+		NS_IEI_CAUSE		('00000000'B),
+		NS_IEI_NSVCI		('00000001'B),
+		NS_IEI_NS_PDU		('00000010'B),
+		NS_IEI_BVCI		('00000011'B),
+		NS_IEI_NSEI		('00000100'B),
+		NS_IEI_LIST_IPv4	('00000101'B),
+		NS_IEI_LIST_IPv6	('00000110'B),
+		NS_IEI_MAX_NUM_NSVC	('00000111'B),
+		NS_IEI_NUM_IPv4_EP	('00001000'B),
+		NS_IEI_NUM_IPv6_EP	('00001001'B),
+		NS_IEI_RESET_FLAG	('00001010'B),
+		NS_IEI_IP_ADDRESS	('00001011'B)
+	} with { variant "FIELDLENGTH(8)" };
+
+	/* TS 48.016 10.3.2 */
+	type enumerated NsCause {
+		NS_CAUSE_TRANSIT_NETWORK_FAILURE		('00000000'B),
+		NS_CAUSE_OM_INTERVENTION			('00000001'B),
+		NS_CAUSE_EQUIPMENT_FAILURE			('00000010'B),
+		NS_CAUSE_NSVC_BLOCKED				('00000011'B),
+		NS_CAUSE_NSVC_UNKNOWN				('00000100'B),
+		NS_CAUSE_BVCI_UNKNOWN_AT_NSE			('00000101'B),
+		NS_CAUSE_SEMANTICALLY_INCORRECT_PDU		('00001000'B),
+		NS_CAUSE_PDU_NOT_COMPATIBLE_WITH_PROTOCOL_STATE	('00001010'B),
+		NS_CAUSE_PROTOCOL_ERROR_UNSPEIFIED		('00001011'B),
+		NS_CAUSE_INVALID_ESSENTIAL_IE			('00001100'B),
+		NS_CAUSE_MISSING_ESSENTIAL_IE			('00001101'B),
+		NS_CAUSE_INVALID_NR_OF_IPv4_ENDPOINTS		('00001110'B),
+		NS_CAUSE_INVALID_NR_OF_IPv6_ENDPOINTS		('00001111'B),
+		NS_CAUSE_INVALID_NR_OF_NSVCS			('00010000'B),
+		NS_CAUSE_INVALID_WEIGHTS			('00010001'B),
+		NS_CAUSE_UNKNOWN_IP_ENDPOINT			('00010010'B),
+		NS_CAUSE_UNKNOWN_IP_ADDRESS			('00010011'B),
+		NS_CAUSE_IP_TEST_FAILEDA			('00010100'B)
+	} with { variant "FIELDLENGTH(8)" };
+
+	template NS_SDU_ControlBits t_SduCtrlB := {
+		rBit := '0'B,
+		cBit := '0'B,
+		spare := '000000'B
+	}
+
+	function t_NS_IE_CAUSE(template NsCause cause) return template CauseNS {
+		var template CauseNS ret;
+		ret.iEI := '00'O;
+		ret.ext := '1'B;
+		ret.lengthIndicator := { length1 := 1 };
+		if (isvalue(cause)) {
+			ret.cause := int2oct(enum2int(valueof(cause)), 1);
+		} else {
+			ret.cause := ?
+		}
+		return ret;
+	}
+
+	private function f_oct_or_wc(template integer inp, integer len) return template octetstring {
+		if (isvalue(inp)) {
+			return int2oct(valueof(inp), len);
+		} else {
+			return ?
+		}
+	}
+
+	template NS_VCI t_NS_IE_NSVCI(template Nsvci nsvci) := {
+		iEI := '01'O,
+		ext := '1'B,
+		lengthIndicator := {
+			length1 := 2
+		},
+		nS_VCI := f_oct_or_wc(nsvci, 2)
+	}
+
+	template NSEI_NS t_NS_IE_NSEI(template Nsei nsei) := {
+		iEI:= '04'O,
+		ext := '1'B,
+		lengthIndicator := {
+			length1 := 2
+		},
+		nSEI := f_oct_or_wc(nsei, 2)
+	}
+
+	template PDU_NS t_NS_RESET(template NsCause cause, template Nsvci nsvci, template Nsei nsei) := {
+		pDU_NS_Reset := {
+			nsPduType := '02'O,
+			causeNS := t_NS_IE_CAUSE(cause),
+			nS_VCI := t_NS_IE_NSVCI(nsvci),
+			nSEI_NS := t_NS_IE_NSEI(nsei)
+		}
+	}
+
+	template PDU_NS t_NS_RESET_ACK(template Nsvci nsvci, template Nsei nsei) := {
+		pDU_NS_Reset_Ack := {
+			nsPduType := '03'O,
+			nS_VCI := t_NS_IE_NSVCI(nsvci),
+			nSEI_NS := t_NS_IE_NSEI(nsei)
+		}
+	}
+
+	template PDU_NS t_NS_BLOCK(template NsCause cause, template Nsvci nsvci) := {
+		pDU_NS_Block := {
+			nsPduType := '04'O,
+			causeNS := t_NS_IE_CAUSE(cause),
+			nS_VCI := t_NS_IE_NSVCI(nsvci)
+		}
+	}
+
+	template PDU_NS t_NS_BLOCK_ACK(template Nsvci nsvci) := {
+		pDU_NS_Block_Ack := {
+			nsPduType := '05'O,
+			nS_VCI := t_NS_IE_NSVCI(nsvci)
+		}
+	}
+
+	template PDU_NS t_NS_UNBLOCK := {
+		pDU_NS_Unblock := {
+			nsPduType := '06'O
+		}
+	}
+
+	template PDU_NS t_NS_UNBLOCK_ACK := {
+		pDU_NS_Unblock_Ack := {
+			nsPduType := '07'O
+		}
+	}
+
+	template PDU_NS t_NS_ALIVE := {
+		pDU_NS_Alive := {
+			nsPduType := '0A'O
+		}
+	}
+
+	template PDU_NS t_NS_ALIVE_ACK := {
+		pDU_NS_Alive_Ack := {
+			nsPduType := '0B'O
+		}
+	}
+
+	template PDU_NS ts_NS_STATUS(NsCause cause, PDU_NS pdu) := {
+		pDU_NS_Status := {
+			nsPduType := '08'O,
+			causeNS := t_NS_IE_CAUSE(cause),
+			nS_VCI := omit,
+			nS_PDU := {
+				iEI := '02'O,
+				ext := '1'B,
+				lengthIndicator := {
+					length1 := 0 /* overwritten */
+				},
+				ns_PDU := enc_PDU_NS(pdu)
+			},
+			bVCI_NS := omit,
+			listofIP4Elements := omit,
+			listofIP6Elements := omit
+		}
+	}
+
+	template PDU_NS t_NS_UNITDATA(template NS_SDU_ControlBits bits, template BssgpBvci bvci, template
+octetstring sdu) := {
+		pDU_NS_Unitdata := {
+			nsPduType := '00'O,
+			nS_SDU_ControlBits := bits,
+			bVCI := f_oct_or_wc(bvci, 2),
+			nS_SDU := sdu
+		}
+	}
+
+
+	type record BssgpCellId {
+		RoutingAreaIdentification	ra_id,
+		CellIdentity			cell_id
+	} with { variant "" };
+
+	type enumerated BssgpCause {
+		BSSGP_CAUSE_PROC_OVERLOAD			('00'H),
+		BSSGP_CAUSE_EQUIMENT_FAILURE			('01'H),
+		BSSGP_CAUSE_TRANSIT_NETWORK_FAILURE		('02'H),
+		BSSGP_CAUSE_NET_SV_CAP_MOD_GT_ZERO_KBPS		('03'H),
+		BSSGP_CAUSE_UNKNOWN_MS				('04'H),
+		BSSGP_CAUSE_BVCI_UNKNOWN			('05'H),
+		BSSGP_CAUSE_CELL_TRAFFIC_CONGESTION		('06'H),
+		BSSGP_CAUSE_SGSN_CONGESTION			('07'H),
+		BSSGP_CAUSE_OM_INTERVENTION			('08'H),
+		BSSGP_CAUSE_BVCI_BLOCKED			('09'H),
+		BSSGP_CAUSE_PFC_CREATE_FAILURE			('0a'H),
+		BSSGP_CAUSE_PFC_PREEMPTED			('0b'H),
+		BSSGP_CAUSE_ABQP_NO_MORE_SUPPORTED		('0c'H),
+		BSSGP_CAUSE_SEMANTICALLY_INCORRECT_PDU		('20'H),
+		BSSGP_CAUSE_INVALID_MANDATORY_IE		('21'H),
+		BSSGP_CAUSE_MISSING_MANDATORY_IE		('22'H),
+		BSSGP_CAUSE_MISSING_CONDITIONAL_IE		('23'H),
+		BSSGP_CAUSE_UNEXPECTED_CONDITIONAL_IE		('24'H),
+		BSSGP_CAUSE_CONDITIONAL_IE_ERROR		('25'H),
+		BSSGP_CAUSE_PDU_NOT_COMPATIBLE_WITH_PROTOCOL_STATE ('26'H),
+		BSSGP_CAUSE_PROTOCOL_ERROR_UNSPECIFIED		('27'H),
+		BSSGP_CAUSE_PDU_NOT_COMPATIBLE_WITH_FEATURE_SET	('28'H),
+		BSSGP_CAUSE_REQUESTED_INFO_NOT_AVAILABLE	('29'H),
+		BSSGP_CAUSE_UNKNOWN_DESTINATION_ADDRESS		('2a'H),
+		BSSGP_CAUSE_UNKNOWN_RIM_APP_IDENTITY		('2b'H),
+		BSSGP_CAUSE_INVALID_CONTAINER_UNIT_INFO		('2c'H),
+		BSSGP_CAUSE_PFC_QUEUING				('2d'H),
+		BSSGP_CAUSE_PFC_CREATED_SUCCESSFULLY		('2e'H),
+		BSSGP_CAUSE_T12_EXPIRY				('2f'H),
+		BSSGP_CAUSE_MS_UNDER_PS_HANDOVER_TREATMENT	('30'H),
+		BSSGP_CAUSE_UPLINK_QUALITY			('31'H),
+		BSSGP_CAUSE_UPLINK_STRENGTH			('32'H),
+		BSSGP_CAUSE_DOWNLINK_QUALITY			('33'H),
+		BSSGP_CAUSE_DOWNLINK_STRENGTH			('34'H),
+		BSSGP_CAUSE_DISTANCE				('35'H),
+		BSSGP_CAUSE_BETTER_CELL				('36'H),
+		BSSGP_CAUSE_TRAFFIC				('37'H),
+		BSSGP_CAUSE_OM_INTERVENTION2			('38'H),
+		BSSGP_CAUSE_MS_BACK_ON_OLD_CHANNEL		('39'H),
+		BSSGP_CAUSE_T13_EXPIRY				('3a'H),
+		BSSGP_CAUSE_T14_EXPIRY				('3b'H),
+		BSSGP_CAUSE_NOT_ALL_REQUESTED_PFC_CREATED	('3c'H)
+	} with { variant "FIELDLENGTH(8)" };
+
+
+	template BVCI t_BSSGP_BVCI(template BssgpBvci bvci) := {
+		iEI := '04'O,
+		ext := '1'B,
+		lengthIndicator := {
+			length1 := 2
+		},
+		unstructured_value := f_oct_or_wc(bvci, 2)
+	}
+
+	template IMSI_BSSGP tr_BSSGP_IMSI(template hexstring imsi) := {
+		iEI := '0D'O,
+		ext := '1'B,
+		lengthIndicator := ?,
+		type_of_Identity := '001'B,
+		oddevenIndicator := ?,
+		digits := imsi
+	}
+
+	template IMSI_BSSGP ts_BSSGP_IMSI(hexstring imsi) := {
+		iEI := '0D'O,
+		ext := '1'B,
+		lengthIndicator := { length1 := 0 /* overwritten */ },
+		type_of_Identity := '001'B,
+		oddevenIndicator := f_hex_is_odd_length(imsi),
+		digits := imsi
+	}
+
+	template TMSI_BSSGP ts_BSSGP_TMSI(GsmTmsi tmsi) := {
+		iEI := '20'O,
+		ext := '1'B,
+		lengthIndicator := { length1 := 4 },
+		tMSI_Value := int2oct(tmsi, 4)
+	}
+
+	function f_bssgp_length_ind(integer len) return LIN2_2a {
+		var LIN2_2a ret;
+		if (len > 255) {
+			ret := { length2 := len };
+		} else {
+			ret := { length1 := len };
+		}
+		return ret;
+	}
+
+	template LLC_PDU ts_BSSGP_LLC_PDU(octetstring pdu) := {
+		iEI := '0D'O,
+		ext := '1'B,
+		lengthIndicator := f_bssgp_length_ind(lengthof(pdu)),
+		lLC_PDU := pdu
+	}
+
+	template LLC_PDU tr_BSSGP_LLC_PDU(template octetstring pdu := ?) := {
+		iEI := '0D'O,
+		ext := '1'B,
+		lengthIndicator := ?,
+		lLC_PDU := pdu
+	}
+
+	function t_BSSGP_CAUSE(template BssgpCause cause) return template Cause_BSSGP {
+		var template Cause_BSSGP ret;
+		ret.iEI := '08'O;
+		ret.ext := '1'B;
+		ret.lengthIndicator := { length1 := 1 };
+		if (isvalue(cause)) {
+			ret.cause_Value := int2oct(enum2int(valueof(cause)), 1);
+		} else {
+			ret.cause_Value := ?
+		}
+		return ret;
+	}
+
+	function t_BSSGP_IE_CellId(template BssgpCellId cid) return template Cell_Identifier {
+		var template Cell_Identifier ret := {
+			iEI := '08'O,
+			ext := '1'B,
+			lengthIndicator := { length1 := 8 },
+			mccDigit1 := ?,
+			mccDigit2 := ?,
+			mccDigit3 := ?,
+			mncDigit3 := ?,
+			mncDigit1 := ?,
+			mncDigit2 := ?,
+			lac := ?,
+			rac := ?,
+			cI_value := ?
+		}
+		if (istemplatekind(cid, "omit")) {
+			return omit;
+		} else if (istemplatekind(cid, "*")) {
+			return *;
+		} else if (istemplatekind(cid, "?")) {
+			return ?;
+		}
+		if (isvalue(cid) and isvalue(cid.ra_id) and isvalue(cid.ra_id.lai)) {
+			if (isvalue(cid.ra_id.lai.mcc_mnc)) {
+				ret.mccDigit1 := cid.ra_id.lai.mcc_mnc[0];
+				ret.mccDigit2 := cid.ra_id.lai.mcc_mnc[1];
+				ret.mccDigit3 := cid.ra_id.lai.mcc_mnc[2];
+				ret.mncDigit3 := cid.ra_id.lai.mcc_mnc[5];
+				ret.mncDigit2 := cid.ra_id.lai.mcc_mnc[4];
+				ret.mncDigit1 := cid.ra_id.lai.mcc_mnc[3];
+			}
+			if (isvalue(cid.ra_id.lai.lac)) {
+				ret.lac := f_oct_or_wc(cid.ra_id.lai.lac, 2);
+			}
+		}
+		if (isvalue(cid) and isvalue(cid.ra_id)) {
+			ret.rac := f_oct_or_wc(cid.ra_id.rac, 1);
+		}
+		if (isvalue(cid)) {
+			ret.cI_value := f_oct_or_wc(cid.cell_id, 2);
+		}
+		return ret;
+	}
+
+	template PDU_BSSGP ts_BVC_RESET(BssgpCause cause, BssgpBvci bvci,
+					template BssgpCellId cell_id) := {
+		pDU_BSSGP_BVC_RESET := {
+			bssgpPduType := '22'O,
+			bVCI := t_BSSGP_BVCI(bvci),
+			cause := t_BSSGP_CAUSE(cause),
+			cell_Identifier := t_BSSGP_IE_CellId(cell_id),
+			feature_bitmap := omit,
+			extended_Feature_Bitmap := omit
+		}
+	}
+
+	template PDU_BSSGP tr_BVC_RESET(template BssgpCause cause, template BssgpBvci bvci,
+					template BssgpCellId cell_id) := {
+		pDU_BSSGP_BVC_RESET := {
+			bssgpPduType := '22'O,
+			bVCI := t_BSSGP_BVCI(bvci),
+			cause := t_BSSGP_CAUSE(cause),
+			cell_Identifier := t_BSSGP_IE_CellId(cell_id),
+			feature_bitmap := *,
+			extended_Feature_Bitmap := *
+		}
+	}
+
+	template PDU_BSSGP ts_BVC_RESET_ACK(BssgpBvci bvci, template BssgpCellId cell_id) := {
+		pDU_BSSGP_BVC_RESET_ACK := {
+			bssgpPduType := '23'O,
+			bVCI := t_BSSGP_BVCI(bvci),
+			cell_Identifier := t_BSSGP_IE_CellId(cell_id),
+			feature_bitmap := omit,
+			extended_Feature_Bitmap := omit
+		}
+	}
+
+	template PDU_BSSGP tr_BVC_RESET_ACK(template BssgpBvci bvci, template BssgpCellId cell_id) := {
+		pDU_BSSGP_BVC_RESET_ACK := {
+			bssgpPduType := '23'O,
+			bVCI := t_BSSGP_BVCI(bvci),
+			cell_Identifier := t_BSSGP_IE_CellId(cell_id),
+			feature_bitmap := *,
+			extended_Feature_Bitmap := *
+		}
+	}
+
+
+	template PDU_BSSGP t_BVC_UNBLOCK(template BssgpBvci bvci) := {
+		pDU_BSSGP_BVC_UNBLOCK := {
+			bssgpPduType := '24'O,
+			bVCI := t_BSSGP_BVCI(bvci)
+		}
+	}
+
+	template PDU_BSSGP t_BVC_UNBLOCK_ACK(template BssgpBvci bvci) := {
+		pDU_BSSGP_BVC_UNBLOCK_ACK := {
+			bssgpPduType := '25'O,
+			bVCI := t_BSSGP_BVCI(bvci)
+		}
+	}
+
+	template PDU_BSSGP t_BVC_BLOCK(template BssgpBvci bvci, template BssgpCause cause) := {
+		pDU_BSSGP_BVC_BLOCK := {
+			bssgpPduType := '20'O,
+			bVCI := t_BSSGP_BVCI(bvci),
+			cause := t_BSSGP_CAUSE(cause)
+		}
+	}
+
+	template PDU_BSSGP t_BVC_BLOCK_ACK(template BssgpBvci bvci) := {
+		pDU_BSSGP_BVC_BLOCK_ACK := {
+			bssgpPduType := '21'O,
+			bVCI := t_BSSGP_BVCI(bvci)
+		}
+	}
+
+	template PDU_BSSGP t_BVC_FC_BVC(uint16_t bmax, uint16_t bucket_leak_rate,
+					uint16_t bmax_default_ms, uint16_t r_default_ms, OCT1 tag) := {
+		pDU_BSSGP_FLOW_CONTROL_BVC := {
+			bssgpPduType := '26'O,
+			tag := {
+				iEI := '1E'O,
+				ext := '1'B,
+				lengthIndicator := {
+					length1 := 2
+				},
+				unstructured_Value := tag
+			},
+			bVC_Bucket_Size := {
+				iEI := '05'O,
+				ext := '1'B,
+				lengthIndicator := {
+					length1 := 2
+				},
+				bmax := f_oct_or_wc(bmax, 2)
+			},
+			bucket_Leak_Rate := {
+				iEI := '03'O,
+				ext := '1'B,
+				lengthIndicator := {
+					length1 := 1
+				},
+				r_Value := f_oct_or_wc(bucket_leak_rate, 2)
+			},
+			bmax_default_MS := {
+				iEI := '01'O,
+				ext := '1'B,
+				lengthIndicator := {
+					length1 := 2
+				},
+				bmax := f_oct_or_wc(bmax_default_ms, 2)
+			},
+			r_default_MS := {
+				iEI := '1C'O,
+				ext := '1'B,
+				lengthIndicator := {
+					length1 := 2
+				},
+				r_default_MS_value := f_oct_or_wc(r_default_ms, 2)
+			},
+			bucket_Full_Ratio := omit,
+			bVC_Measurement := omit,
+			flow_Control_Granularity := omit
+		}
+	}
+	template PDU_BSSGP t_BVC_FC_BVC_ACK(template OCT1 tag) := {
+		pDU_BSSGP_FLOW_CONTROL_BVC_ACK := {
+			bssgpPduType := '27'O,
+			tag := {
+				iEI := '1E'O,
+				ext := '1'B,
+				lengthIndicator := {
+					length1 := 2
+				},
+				unstructured_Value := tag
+			}
+		}
+	}
+
+	template PDU_BSSGP ts_BSSGP_STATUS(template BssgpBvci bvci, template BssgpCause cause,
+					   PDU_BSSGP pdu) := {
+		pDU_BSSGP_STATUS := {
+			bssgpPduType := '0A'O,
+			cause := t_BSSGP_CAUSE(cause),
+			bVCI := t_BSSGP_BVCI(bvci),
+			pDU_in_Error := {
+				iEI := '15'O,
+				ext := '1'B,
+				lengthIndicator := {
+					length1 := 0 /* overwritten */
+				},
+				erroneous_BSSGP_PDU := enc_PDU_BSSGP(pdu)
+			}
+		}
+	}
+
+	template QoS_Profile_V t_defaultQos := {
+		peak_Bit_Rate := int2oct(80, 2),
+		precedence := '000'B,
+		a_bit := '0'B,
+		t_bit := '0'B,
+		c_r_bit := '0'B,
+		peakBitRateGranularity := '00'B
+	}
+
+	template QoS_Profile ts_QoS_TLV(template QoS_Profile_V qos) := {
+		iEI := '18'O,
+		ext := '1'B,
+		lengthIndicator := { length1 := 3 },
+		peak_Bit_Rate := qos.peak_Bit_Rate,
+		precedence := qos.precedence,
+		a_bit := qos.a_bit,
+		t_bit := qos.t_bit,
+		c_r_bit := qos.c_r_bit,
+		peakBitRateGranularity := qos.peakBitRateGranularity
+	}
+
+	template PDU_Lifetime t_DefaultLifetime(uint16_t delay := 65535) := {
+		iEI := '16'O,
+		ext := '1'B,
+		lengthIndicator := {
+			length1 := 2
+		},
+		delay_Value := f_oct_or_wc(delay, 2)
+	}
+
+	template PDU_BSSGP ts_BSSGP_DL_UD(GprsTlli tlli, octetstring pdu) := {
+		pDU_BSSGP_DL_UNITDATA := {
+			bssgpPduType := '00'O,
+			tLLI_current := f_oct_or_wc(tlli, 4),
+			qoS_Profile := t_defaultQos,
+			pDU_Lifetime := t_DefaultLifetime(65535),
+			mS_Radio_Access_Capability := omit,
+			priority := omit,
+			dRX_Parameters := omit,
+			iMSI := omit,
+			tLLI_old := omit,
+			pFI := omit,
+			lSA_Information := omit,
+			service_UTRAN_CCO := omit,
+			service_Class_Indicator := omit,
+			subscriber_Profile_ID_For_RAT_Priority := omit,
+			redirection_Indication := omit,
+			redirection_Completed := omit,
+			unconfirmed_Send_State_Variable := omit,
+			sCI := omit,
+			gGSN_PGW_Location := omit,
+			eDRX_Paremeters := omit,
+			old_Routing_Area_Identification := omit,
+			attach_Indicator := omit,
+			alignment_octets := omit,
+			lLC_PDU := ts_BSSGP_LLC_PDU(pdu),
+			initialLLC_PDU := omit
+		}
+	}
+
+	template PDU_BSSGP tr_BSSGP_DL_UD := {
+		pDU_BSSGP_DL_UNITDATA := {
+			bssgpPduType := '00'O,
+			tLLI_current := ?,
+			qoS_Profile := ?,
+			pDU_Lifetime := ?,
+			mS_Radio_Access_Capability := *,
+			priority := *,
+			dRX_Parameters := *,
+			iMSI := *,
+			tLLI_old := *,
+			pFI := *,
+			lSA_Information := *,
+			service_UTRAN_CCO := *,
+			service_Class_Indicator := *,
+			subscriber_Profile_ID_For_RAT_Priority := *,
+			redirection_Indication := *,
+			redirection_Completed := *,
+			unconfirmed_Send_State_Variable := *,
+			sCI := *,
+			gGSN_PGW_Location := *,
+			eDRX_Paremeters := *,
+			old_Routing_Area_Identification := *,
+			attach_Indicator := *,
+			alignment_octets := *,
+			lLC_PDU := tr_BSSGP_LLC_PDU,
+			initialLLC_PDU := *
+		}
+	}
+
+	template PDU_BSSGP tr_BSSGP_UL_UD(template GprsTlli tlli := ?, template BssgpCellId cell_id := ?,
+					  template octetstring payload := ?) := {
+		pDU_BSSGP_UL_UNITDATA := {
+			bssgpPduType := '01'O,
+			tLLI := f_oct_or_wc(tlli, 4),
+			qoS_Profile := ?,
+			cell_Identifier := t_BSSGP_IE_CellId(cell_id),
+			pFI := *,
+			lSA_Identifier_List := *,
+			redirect_Attempt_Flag := *,
+			iMSI_BSSGP := *,
+			unconfirmed_Send_State_Variable := *,
+			selected_PLMN_ID := *,
+			selected_Operator := *,
+			cS_Registered_Operator := *,
+			alignment_octets := *,
+			lLC_PDU := tr_BSSGP_LLC_PDU(payload)
+		}
+	}
+
+	template PDU_BSSGP ts_BSSGP_PS_PAGING_IMSI(BssgpBvci bvci, hexstring imsi) := {
+		pDU_BSSGP_PAGING_PS := {
+			bssgpPduType := '06'O,
+			iMSI := ts_BSSGP_IMSI(imsi),
+			dRX_Parameters := omit,
+			paging_Field4 := {
+				bVCI := t_BSSGP_BVCI(bvci)
+			},
+			pFI := omit,
+			aBQP := omit,
+			qoS_Profile := ts_QoS_TLV(t_defaultQos),
+			pTMSI := omit,
+			eDRX_Paremeters := omit
+		}
+	}
+
+	template PDU_BSSGP ts_BSSGP_PS_PAGING_PTMSI(BssgpBvci bvci, hexstring imsi, GsmTmsi tmsi) := {
+		pDU_BSSGP_PAGING_PS := {
+			bssgpPduType := '06'O,
+			iMSI := ts_BSSGP_IMSI(imsi),
+			dRX_Parameters := omit,
+			paging_Field4 := {
+				bVCI := t_BSSGP_BVCI(bvci)
+			},
+			pFI := omit,
+			aBQP := omit,
+			qoS_Profile := ts_QoS_TLV(t_defaultQos),
+			pTMSI := ts_BSSGP_TMSI(tmsi),
+			eDRX_Paremeters := omit
+		}
+	}
+
+
+} with { encode "RAW" };

-- 
To view, visit https://gerrit.osmocom.org/6401
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Icbc4f5d24f3419f99c9a4805f836bddd2849f492
Gerrit-PatchSet: 6
Gerrit-Project: osmo-ttcn3-hacks
Gerrit-Branch: master
Gerrit-Owner: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder



More information about the gerrit-log mailing list