stp: Introduce STP_Tests*.ttcn for testing OsmoSTP

In the past, we were automatically running [large parts of] the nplab
M3UA and SUA test suites, but those implement only a fraction of the
functionality.  Particularly, they don't cover the non-standard IPA
behavior, and they don't cover RKM (routing key management).

Let's introduce an initial set of STP tests with this patch.  We try
to not duplicate nplab here, and implement bits not covered there.

Change-Id: I628a87385cac0dfe708a0d74a5088fbd5a4790cd
diff --git a/library/M3UA_Templates.ttcn b/library/M3UA_Templates.ttcn
new file mode 100644
index 0000000..02b493c
--- /dev/null
+++ b/library/M3UA_Templates.ttcn
@@ -0,0 +1,771 @@
+module M3UA_Templates {
+
+/* M3UA Templates, building on top of M3UA_Types from Ericsson.
+ *
+ * (C) 2019 by Harald Welte <laforge@gnumonks.org>
+ * All rights reserved.
+ *
+ * Released under the terms of GNU General Public License, Version 2 or
+ * (at your option) any later version.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+import from M3UA_Types all;
+import from General_Types all;
+import from Osmocom_Types all;
+
+const OCT1 c_M3UA_VERSION := '01'O;
+
+const OCT2 c_M3UA_ST_T_STATE_CHG := '0001'O;
+const OCT2 c_M3UA_ST_I_RESERVED := '0001'O;
+const OCT2 c_M3UA_ST_I_AS_INACTIVE := '0002'O;
+const OCT2 c_M3UA_ST_I_AS_ACTIVE := '0003'O;
+const OCT2 c_M3UA_ST_I_AS_PENDING := '0004'O;
+
+const OCT2 c_M3UA_ST_T_OTHER := '0002'O;
+const OCT2 c_M3UA_ST_I_INSUFF_RESRC := '0001'O
+const OCT2 c_M3UA_ST_I_ALTERNATE_ASP := '0002'O
+const OCT2 c_M3UA_ST_I_ASP_FAILUREP := '0003'O
+
+private function f_aspid_or_omit(template (omit) OCT4 aspid)
+return template (omit) M3UA_ASP_Identifier {
+	var template (omit) M3UA_ASP_Identifier id;
+	if (istemplatekind(aspid, "omit")) {
+		return omit;
+	} else {
+		id.tag := '0011'O;
+		id.lengthInd := 8;
+		id.aSPIdentifier := aspid;
+		return id;
+	}
+}
+
+function tr_M3UA_asp_id(template OCT4 aspid)
+return template M3UA_ASP_Identifier {
+	var template M3UA_ASP_Identifier id := {
+		tag := '0011'O,
+		lengthInd := 8,
+		aSPIdentifier := aspid
+	};
+	if (istemplatekind(aspid, "omit")) {
+		return omit;
+	} else if (istemplatekind(aspid, "*")) {
+		return *;
+	} else {
+		return id;
+	}
+}
+
+
+/***********************************************************************
+ * ASPSM Class
+ ***********************************************************************/
+
+template (value) PDU_M3UA ts_M3UA_ASPUP(template (omit) OCT4 aspid := omit,
+					template (omit) octetstring infostr := omit) := {
+	m3UA_ASPUP := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0301'O,
+		messageLength := 0, // overwritten
+		messageParameters := {
+			aSP_Identifier := f_aspid_or_omit(aspid),
+			info_String := omit
+		}
+	}
+}
+template (present) PDU_M3UA tr_M3UA_ASPUP(template OCT4 aspid := *,
+					  template octetstring infostr := omit) := {
+	m3UA_ASPUP := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0301'O,
+		messageLength := 0, // overwritten
+		messageParameters := {
+			aSP_Identifier := tr_M3UA_asp_id(aspid),
+			info_String := *
+		}
+	}
+}
+
+template (value) PDU_M3UA ts_M3UA_ASPUP_ACK := {
+	m3UA_ASPUP_Ack := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0304'O,
+		messageLength := 0, // overwritten
+		messageParameters := {
+			info_String := omit
+		}
+	}
+}
+template (present) PDU_M3UA tr_M3UA_ASPUP_ACK := {
+	m3UA_ASPUP_Ack := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0304'O,
+		messageLength := ?,
+		messageParameters := {
+			info_String := *
+		}
+	}
+}
+
+template (value) PDU_M3UA ts_M3UA_ASPDN := {
+	m3UA_ASPDN := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0302'O,
+		messageLength := 0, // overwritten
+		messageParameters := {
+			info_String := omit
+		}
+	}
+}
+template (present) PDU_M3UA tr_M3UA_ASPDN := {
+	m3UA_ASPDN := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0302'O,
+		messageLength := ?,
+		messageParameters := {
+			info_String := *
+		}
+	}
+}
+
+template (value) PDU_M3UA ts_M3UA_ASPDN_ACK := {
+	m3UA_ASPUP_Ack := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0305'O,
+		messageLength := 0, // overwritten
+		messageParameters := {
+			info_String := omit
+		}
+	}
+}
+template (present) PDU_M3UA tr_M3UA_ASPDN_ACK := {
+	m3UA_ASPUP_Ack := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0305'O,
+		messageLength := ?,
+		messageParameters := {
+			info_String := *
+		}
+	}
+}
+
+template (value) M3UA_Heartbeat_Data ts_M3UA_hb_data(template (value) octetstring hb_data) := {
+	tag := '0009'O,
+	lengthInd := 0, // overwritten
+	heartbeat_Data := hb_data
+}
+
+template (present) M3UA_Heartbeat_Data tr_M3UA_hb_data(template (present) octetstring hb_data) := {
+	tag := '0009'O,
+	lengthInd := ?,
+	heartbeat_Data := hb_data
+}
+
+template (value) PDU_M3UA ts_M3UA_BEAT(template (omit) M3UA_Heartbeat_Data hbd := omit) := {
+	m3UA_BEAT := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0303'O,
+		messageLength := 0, // overwritten
+		messageParameters := {
+			heartbeat_Data := hbd
+		}
+	}
+}
+template (present) PDU_M3UA tr_M3UA_BEAT(template M3UA_Heartbeat_Data hbd := *) := {
+	m3UA_BEAT := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0303'O,
+		messageLength := ?,
+		messageParameters := {
+			heartbeat_Data := hbd
+		}
+	}
+}
+
+template (value) PDU_M3UA ts_M3UA_BEAT_ACK(template (omit) M3UA_Heartbeat_Data hb_data)  := {
+	m3UA_BEAT_Ack := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0306'O,
+		messageLength := 0, // overwritten
+		messageParameters := {
+			heartbeat_Data := hb_data
+		}
+	}
+}
+template (present) PDU_M3UA tr_M3UA_BEAT_ACK(template M3UA_Heartbeat_Data hb_data := *) := {
+	m3UA_BEAT_Ack := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0306'O,
+		messageLength := ?,
+		messageParameters := {
+			heartbeat_Data := hb_data
+		}
+	}
+}
+
+
+
+
+/***********************************************************************
+ * ASPTM Class
+ ***********************************************************************/
+
+
+const M3UA_Traffic_Mode_Type c_M3UA_TMT_override := {
+	tag := '000B'O,
+	lengthInd := 8,
+	trafficModeType := int2oct(1, 4)
+}
+
+const M3UA_Traffic_Mode_Type c_M3UA_TMT_loadshare := {
+	tag := '000B'O,
+	lengthInd := 8,
+	trafficModeType := int2oct(2, 4)
+}
+
+const M3UA_Traffic_Mode_Type c_M3UA_TMT_broadcast := {
+	tag := '000B'O,
+	lengthInd := 8,
+	trafficModeType := int2oct(3, 4)
+}
+
+function ts_M3UA_routing_ctx(template (omit) octetstring rctx)
+return template (omit) M3UA_Routing_Context {
+	var template (omit) M3UA_Routing_Context id;
+	if (istemplatekind(rctx, "omit")) {
+		return omit;
+	} else {
+		id.tag := '0006'O;
+		id.lengthInd := 0; // overwritten
+		id.routingContext := rctx;
+		return id;
+	}
+}
+
+function tr_M3UA_routing_ctx(template octetstring rctx)
+return template M3UA_Routing_Context {
+	var template M3UA_Routing_Context id;
+	if (istemplatekind(rctx, "omit")) {
+		return omit;
+	} else if (istemplatekind(rctx, "*")) {
+		return *;
+	} else {
+		id.tag := '0006'O;
+		id.lengthInd := ?;
+		id.routingContext := rctx;
+		return id;
+	}
+}
+
+template (value) PDU_M3UA ts_M3UA_ASPAC(template (omit) M3UA_Traffic_Mode_Type tmt,
+					template (omit) OCT4 rctx) := {
+	m3UA_ASPAC := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0401'O,
+		messageLength := 0, // overwritten
+		messageParameters := {
+			traffic_Mode_Type := tmt,
+			routing_Context := ts_M3UA_routing_ctx(rctx),
+			info_String := omit
+		}
+	}
+}
+template (present) PDU_M3UA tr_M3UA_ASPAC(template M3UA_Traffic_Mode_Type tmt,
+					  template OCT4 rctx) := {
+	m3UA_ASPAC := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0401'O,
+		messageLength := ?,
+		messageParameters := {
+			traffic_Mode_Type := tmt,
+			routing_Context := tr_M3UA_routing_ctx(rctx),
+			info_String := *
+		}
+	}
+}
+
+template (value) PDU_M3UA ts_M3UA_ASPAC_ACK(template (omit) M3UA_Traffic_Mode_Type tmt,
+					template (omit) OCT4 rctx) := {
+	m3UA_ASPAC_Ack := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0403'O,
+		messageLength := 0, // overwritten
+		messageParameters := {
+			traffic_Mode_Type := tmt,
+			routing_Context := ts_M3UA_routing_ctx(rctx),
+			info_String := omit
+		}
+	}
+}
+template (present) PDU_M3UA tr_M3UA_ASPAC_ACK(template M3UA_Traffic_Mode_Type tmt,
+					      template OCT4 rctx) := {
+	m3UA_ASPAC_Ack := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0403'O,
+		messageLength := ?,
+		messageParameters := {
+			traffic_Mode_Type := tmt,
+			routing_Context := tr_M3UA_routing_ctx(rctx),
+			info_String := *
+		}
+	}
+}
+
+template (value) PDU_M3UA ts_M3UA_ASPIA(template (omit) OCT4 rctx) := {
+	m3UA_ASPIA := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0402'O,
+		messageLength := 0, // overwritten
+		messageParameters := {
+			routing_Context := ts_M3UA_routing_ctx(rctx),
+			info_String := omit
+		}
+	}
+}
+template (present) PDU_M3UA tr_M3UA_ASPIA(template OCT4 rctx) := {
+	m3UA_ASPIA := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0402'O,
+		messageLength := ?,
+		messageParameters := {
+			routing_Context := tr_M3UA_routing_ctx(rctx),
+			info_String := *
+		}
+	}
+}
+
+
+template (value) PDU_M3UA ts_M3UA_ASPIA_ACK(template (omit) OCT4 rctx) := {
+	m3UA_ASPIA_Ack := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0404'O,
+		messageLength := 0, // overwritten
+		messageParameters := {
+			routing_Context := ts_M3UA_routing_ctx(rctx),
+			info_String := omit
+		}
+	}
+}
+template (present) PDU_M3UA tr_M3UA_ASPIA_ACK(template OCT4 rctx) := {
+	m3UA_ASPIA_Ack := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0404'O,
+		messageLength := ?,
+		messageParameters := {
+			routing_Context := tr_M3UA_routing_ctx(rctx),
+			info_String := *
+		}
+	}
+}
+
+
+/***********************************************************************
+ * MGMT Class
+ ***********************************************************************/
+
+template (value) M3UA_Error_Code ts_M3UA_err_code(template (value) OCT4 val) := {
+	tag := '000C'O,
+	lengthInd := 8,
+	errorCode := val
+}
+template (present) M3UA_Error_Code tr_M3UA_err_code(template (present) OCT4 val) := {
+	tag := '000C'O,
+	lengthInd := 8,
+	errorCode := val
+}
+
+template (value) M3UA_Status ts_M3UA_status(template (value) OCT2 status_type,
+					    template (value) OCT2 status_info) := {
+	tag := '000D'O,
+	lengthInd := 8,
+	statusType := status_type,
+	statusInfo := status_info
+}
+
+template (present) M3UA_Status tr_M3UA_status(template (present) OCT2 status_type,
+					      template (present) OCT2 status_info) := {
+	tag := '000D'O,
+	lengthInd := 8,
+	statusType := status_type,
+	statusInfo := status_info
+}
+
+
+template (value) PDU_M3UA ts_M3UA_ERR(template (value) OCT4 err_code,
+				      template (omit) OCT4 rctx) := {
+	m3UA_ERR := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0000'O,
+		messageLength := 0, // overwritten
+		messageParameters := {
+			error_Code := ts_M3UA_err_code(err_code),
+			routing_Context := ts_M3UA_routing_ctx(rctx),
+			affected_Point_Codes := omit,
+			network_Appearance := omit,
+			diagnostic_information := omit
+		}
+	}
+}
+template (present) PDU_M3UA tr_M3UA_ERR(template (present) OCT4 err_code,
+				      template OCT4 rctx) := {
+	m3UA_ERR := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0000'O,
+		messageLength := ?,
+		messageParameters := {
+			error_Code := tr_M3UA_err_code(err_code),
+			routing_Context := tr_M3UA_routing_ctx(rctx),
+			affected_Point_Codes := *,
+			network_Appearance := *,
+			diagnostic_information := *
+		}
+	}
+}
+
+
+template (value) PDU_M3UA ts_M3UA_NOTIFY(template (value) OCT2 status_type,
+					 template (value) OCT2 status_info,
+					 template (omit) OCT4 rctx,
+					 template (omit) OCT4 aspid := omit,
+					 template (omit) octetstring infostr := omit) := {
+	m3UA_NOTIFY := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0001'O,
+		messageLength := 0, // overwritten
+		messageParameters := {
+			status := ts_M3UA_status(status_type, status_info),
+			aSP_Identifier := f_aspid_or_omit(aspid),
+			routing_Context := ts_M3UA_routing_ctx(rctx),
+			info_String := omit
+		}
+	}
+}
+template (present) PDU_M3UA tr_M3UA_NOTIFY(template (present) OCT2 status_type,
+					   template (present) OCT2 status_info,
+					   template OCT4 rctx,
+					   template OCT4 aspid := *,
+					   template octetstring infostr := *) := {
+	m3UA_NOTIFY := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0001'O,
+		messageLength := ?,
+		messageParameters := {
+			status := tr_M3UA_status(status_type, status_info),
+			aSP_Identifier := *,
+			routing_Context := tr_M3UA_routing_ctx(rctx),
+			info_String := *
+		}
+	}
+}
+
+/***********************************************************************
+ * Message Transfer Class
+ ***********************************************************************/
+
+template (value) M3UA_Protocol_Data ts_M3UA_protocol_data(template (value) OCT4 opc,
+							  template (value) OCT4 dpc,
+							  template (value) OCT1 si,
+							  template (value) OCT1 ni,
+							  template (value) OCT1 mp,
+							  template (value) OCT1 sls,
+							  template (value) octetstring data) := {
+	tag := '0210'O,
+	lengthInd := 0, // overwritten
+	oPC := opc,
+	dPC := dpc,
+	sI := si,
+	nI := ni,
+	mP := mp,
+	sLS := sls,
+	userProtocolData := data
+}
+template (present) M3UA_Protocol_Data tr_M3UA_protocol_data(template (present) OCT4 opc,
+							  template (present) OCT4 dpc,
+							  template (present) OCT1 si,
+							  template (present) OCT1 ni,
+							  template (present) OCT1 mp,
+							  template (present) OCT1 sls,
+							  template (present) octetstring data) := {
+	tag := '0210'O,
+	lengthInd := ?,
+	oPC := opc,
+	dPC := dpc,
+	sI := si,
+	nI := ni,
+	mP := mp,
+	sLS := sls,
+	userProtocolData := data
+}
+
+
+template (value) PDU_M3UA ts_M3UA_DATA(template (omit) OCT4 rctx,
+				       template (value) M3UA_Protocol_Data data) := {
+	m3UA_DATA := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0101'O,
+		messageLength := 0, // overwritten
+		messageParameters :={
+			network_Appearance := omit,
+			routing_Context := ts_M3UA_routing_ctx(rctx),
+			protocol_Data := data,
+			correlation_ID := omit
+		}
+	}
+}
+template (present) PDU_M3UA tr_M3UA_DATA(template OCT4 rctx,
+				       template (present) M3UA_Protocol_Data data) := {
+	m3UA_DATA := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0101'O,
+		messageLength := ?, // overwritten
+		messageParameters := {
+			network_Appearance := *,
+			routing_Context := tr_M3UA_routing_ctx(rctx),
+			protocol_Data := data,
+			correlation_ID := *
+		}
+	}
+}
+
+/***********************************************************************
+ * Routing Key Management
+ ***********************************************************************/
+
+template (value) M3UA_Local_Routing_Key_Id ts_M3UA_lrkid(template (value) OCT4 id) := {
+	tag := '020a'O,
+	lengthInd := 8,
+	localRkId := id
+}
+
+template (present) M3UA_Local_Routing_Key_Id tr_M3UA_lrkid(template (present) OCT4 id) := {
+	tag := '020a'O,
+	lengthInd := 8,
+	localRkId := id
+}
+
+
+template (value) M3UA_Routing_Key ts_M3UA_rkey(OCT4 id, OCT3 dpc,
+						template (omit) M3UA_Traffic_Mode_Type tmt := omit,
+						template (omit) OCT4 rctx := omit) := {
+	tag := '0207'O,
+	lengthInd := 0, // overwritten
+	routingKey := {
+		local_Routing_Key_Id := ts_M3UA_lrkid(id),
+		routing_Context := ts_M3UA_routing_ctx(rctx),
+		traffic_Mode_Type := tmt,
+		destination_Point_Code := {
+			tag := '020b'O,
+			lengthInd := 8,
+			pointCode := { '00'O, dpc }
+		},
+		network_Appearance := omit,
+		service_Indicators := omit,
+		opc_List := omit
+	}
+}
+template (present) M3UA_Routing_Key tr_M3UA_rkey(template (present) OCT4 id, template (present) OCT3 dpc,
+						template M3UA_Traffic_Mode_Type tmt := *,
+						template OCT4 rctx := *) := {
+	tag := '0207'O,
+	lengthInd := ?,
+	routingKey := {
+		local_Routing_Key_Id := tr_M3UA_lrkid(id),
+		routing_Context := tr_M3UA_routing_ctx(rctx),
+		traffic_Mode_Type := tmt,
+		destination_Point_Code := {
+			tag := '020b'O,
+			lengthInd := 8,
+			pointCode := { '00'O, dpc }
+		},
+		network_Appearance := omit,
+		service_Indicators := omit,
+		opc_List := omit
+	}
+}
+
+
+const OCT4 c_M3UA_REGSTS_SUCCESS := '00000000'O;
+const OCT4 c_M3UA_REGSTS_ERR_UNKNOWN := '00000001'O;
+const OCT4 c_M3UA_REGSTS_ERR_INVAL_DPC := '00000002'O;
+const OCT4 c_M3UA_REGSTS_ERR_INVAL_NA := '00000003'O;
+const OCT4 c_M3UA_REGSTS_ERR_INVAL_RKEY := '00000004'O;
+const OCT4 c_M3UA_REGSTS_ERR_EPERM := '00000005'O;
+// ...
+
+const OCT4 c_m3UA_DEREGSTS_SUCCESS := '00000000'O;
+const OCT4 c_m3UA_DEREGSTS_ERR_UNKNOWN := '00000001'O;
+const OCT4 c_m3UA_DEREGSTS_ERR_INVAL_RCTX := '00000002'O;
+const OCT4 c_m3UA_DEREGSTS_ERR_EPERM := '00000003'O;
+const OCT4 c_m3UA_DEREGSTS_ERR_NOT_REG := '00000004'O;
+const OCT4 c_m3UA_DEREGSTS_ERR_ASP_ACTIVE := '00000005'O;
+
+template (value) M3UA_Registration_Result ts_M3UA_reg_res(template (value) OCT4 id,
+							    template (value) OCT4 status,
+							    template (value) OCT4 rctx) := {
+	tag := '0208'O,
+	lengthInd := 0, // overwritten
+	registrationResult := {
+		local_Routing_Key_Id := ts_M3UA_lrkid(id),
+		registration_Status := {
+			tag := '0212'O,
+			lengthInd := 8,
+			registrationStatus := status
+		},
+		routing_Context := ts_M3UA_routing_ctx(rctx)
+	}
+}
+template (present) M3UA_Registration_Result tr_M3UA_reg_res(template (present) OCT4 id,
+							    template (present) OCT4 status,
+							    template (present) OCT4 rctx) := {
+	tag := '0208'O,
+	lengthInd := ?,
+	registrationResult := {
+		local_Routing_Key_Id := tr_M3UA_lrkid(id),
+		registration_Status := {
+			tag := '0212'O,
+			lengthInd := 8,
+			registrationStatus := status
+		},
+		routing_Context := tr_M3UA_routing_ctx(rctx)
+	}
+}
+
+template (value) M3UA_Deregistration_Result ts_M3UA_dereg_res(template (value) OCT4 rctx,
+							      template (value) OCT4 status) := {
+	tag := '0209'O,
+	lengthInd := 0, // overwritten
+	deregistrationResult := {
+		routing_Context := ts_M3UA_routing_ctx(rctx),
+		deregistration_Status := {
+			tag := '0213'O,
+			lengthInd := 8,
+			deregistrationStatus := status
+		}
+	}
+}
+template (present) M3UA_Deregistration_Result tr_M3UA_dereg_res(template (present) OCT4 rctx,
+								template (present) OCT4 status) := {
+	tag := '0209'O,
+	lengthInd := ?,
+	deregistrationResult := {
+		routing_Context := tr_M3UA_routing_ctx(rctx),
+		deregistration_Status := {
+			tag := '0213'O,
+			lengthInd := 8,
+			deregistrationStatus := status
+		}
+	}
+}
+
+
+template (value) PDU_M3UA ts_M3UA_REG_REQ(template (value) M3UA_Routing_Keys rkeys) := {
+	m3UA_REG_REQ := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0901'O,
+		messageLength := 0, // overwritten
+		messageParameters := rkeys
+	}
+}
+template (present) PDU_M3UA tr_M3UA_REG_REQ(template (present) M3UA_Routing_Keys rkeys) := {
+	m3UA_REG_REQ := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0901'O,
+		messageLength := ?,
+		messageParameters := rkeys
+	}
+}
+
+
+template (value) PDU_M3UA ts_M3UA_REG_RSP(template (value) M3UA_Registration_Results res) := {
+	m3UA_REG_RSP := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0902'O,
+		messageLength := 0, // overwritten
+		messageParameters := res
+	}
+}
+template (present) PDU_M3UA tr_M3UA_REG_RSP(template (present) M3UA_Registration_Results res) := {
+	m3UA_REG_RSP := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0902'O,
+		messageLength := ?,
+		messageParameters := res
+	}
+}
+
+template (value) PDU_M3UA ts_M3UA_DEREG_REQ(template (value) M3UA_Routing_Context rctx) := {
+	m3UA_DEREG_REQ := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0903'O,
+		messageLength := 0, // overwritten
+		messageParameters := {
+			routing_Context := rctx
+		}
+	}
+}
+template (present) PDU_M3UA tr_M3UA_DEREG_REQ(template (present) M3UA_Routing_Context rctx) := {
+	m3UA_DEREG_REQ := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0903'O,
+		messageLength := ?,
+		messageParameters := {
+			routing_Context := rctx
+		}
+	}
+}
+
+template (value) PDU_M3UA ts_M3UA_DEREG_RSP(template (value) M3UA_Deregistration_Results res) := {
+	m3UA_DEREG_RSP := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0904'O,
+		messageLength := 0, // overwritten
+		messageParameters := res
+	}
+}
+template (present) PDU_M3UA tr_M3UA_DEREG_RSP(template (present) M3UA_Deregistration_Results res) := {
+	m3UA_DEREG_RSP := {
+		version := c_M3UA_VERSION,
+		reserved := '00'O,
+		messageClassAndType := '0904'O,
+		messageLength := ?,
+		messageParameters := res
+	}
+}
+
+
+
+}