/* S1AP Templates in TTCN-3
 * (C) 2019 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
 */

module S1AP_Templates {

import from S1AP_IEs all;
import from S1AP_CommonDataTypes all;
import from S1AP_Constants all;
import from S1AP_Containers all;
import from S1AP_PDU_Contents all;
import from S1AP_PDU_Descriptions all;

/*********************************************************************************
 * non-UE related
 *********************************************************************************/

/*********************************************************************************
 * 9.1.8 Management Messages
 *********************************************************************************/

/* 9.1.8.4 S1 SETUP REQUEST */
template (value) S1AP_PDU
ts_S1AP_SetupReq(template (value) Global_ENB_ID p_global_ENB_ID,
		 template (value) SupportedTAs p_supportedTAs,
		 template (value) PagingDRX p_pagingDRXs) := {
	initiatingMessage := {
		procedureCode := id_S1Setup,
		criticality := reject,
		value_ := {
			S1SetupRequest := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_Global_ENB_ID,
						criticality := ignore,
						value_ := { Global_ENB_ID := p_global_ENB_ID }
					}, {
						id := S1AP_Constants.id_SupportedTAs,
						criticality := reject,
						value_ := {SupportedTAs := p_supportedTAs}
            				} /* HACK: work around nextepc bug
					  , {
						id := S1AP_Constants.id_pagingDRX,
						criticality := ignore,
						value_ := {PagingDRX := p_pagingDRXs}
            				} */
				}
			}
		}
	}
}
template (present) S1AP_PDU
tr_S1AP_SetupReq(template (present) Global_ENB_ID p_global_ENB_ID := ?,
		 template (present) SupportedTAs p_supportedTAs := ?,
		 template (present) PagingDRX p_pagingDRXs := ?) := {
	initiatingMessage := {
		procedureCode := id_S1Setup,
		criticality := reject,
		value_ := {
			S1SetupRequest := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_Global_ENB_ID,
						criticality := ignore,
						value_ := { Global_ENB_ID := p_global_ENB_ID }
					}, *, {
						id := S1AP_Constants.id_SupportedTAs,
						criticality := reject,
						value_ := {SupportedTAs := p_supportedTAs}
            				}, *
				}
			}
		}
	}
}

/* 9.1.8.5 S1 SETUP RESPONSE */
template (value) ServedGUMMEIsItem
ts_S1AP_ServedGUMMEIsItem(template (value) ServedPLMNs servedPLMNs,
			  template (value) ServedGroupIDs servedGroupIDs,
			  template (value) ServedMMECs servedMMECs) := {
	servedPLMNs := servedPLMNs,
	servedGroupIDs := servedGroupIDs,
	servedMMECs := servedMMECs,
	iE_Extensions := omit
}
template (present) ServedGUMMEIsItem
tr_S1AP_ServedGUMMEIsItem(template (present) ServedPLMNs servedPLMNs := ?,
			  template (present) ServedGroupIDs servedGroupIDs := ?,
			  template (present) ServedMMECs servedMMECs := ?) := {
	servedPLMNs := servedPLMNs,
	servedGroupIDs := servedGroupIDs,
	servedMMECs := servedMMECs,
	iE_Extensions := *
}
template (value) S1AP_PDU
ts_S1AP_SetupResp(template (value) ServedGUMMEIs served_gummeis,
		  template (value) RelativeMMECapacity rel_mme_capacity) := {
	successfulOutcome := {
		procedureCode := id_S1Setup,
		criticality := reject,
		value_ := {
			S1SetupResponse := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_ServedGUMMEIs,
						criticality := reject,
						value_ := { ServedGUMMEIs := served_gummeis }
					}, {
						id := S1AP_Constants.id_RelativeMMECapacity,
						criticality := ignore,
						value_ := { RelativeMMECapacity := rel_mme_capacity }
					}
				}
			}
		}
	}
}
template (present) S1AP_PDU
tr_S1AP_SetupResp(template (present) ServedGUMMEIs served_gummeis := ?,
		  template (present) RelativeMMECapacity rel_mme_capacity := ?) := {
	successfulOutcome := {
		procedureCode := id_S1Setup,
		criticality := reject,
		value_ := {
			S1SetupResponse := {
				protocolIEs := {
					*, {
						id := S1AP_Constants.id_ServedGUMMEIs,
						criticality := reject,
						value_ := { ServedGUMMEIs := served_gummeis }
					}, {
						id := S1AP_Constants.id_RelativeMMECapacity,
						criticality := ignore,
						value_ := { RelativeMMECapacity := rel_mme_capacity }
					}, *
				}
			}
		}
	}
}

/* 9.1.8.6 S1 SETUP FAILURE */
template (value) S1AP_PDU
ts_S1AP_SetupFail(template (value) Cause cause) := {
	unsuccessfulOutcome := {
		procedureCode := id_S1Setup,
		criticality := reject,
		value_ := {
			S1SetupFailure := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_Cause,
						criticality := ignore,
						value_ := { Cause := cause }
					}
				}
			}
		}
	}
}
template (present) S1AP_PDU
tr_S1AP_SetupFail(template (present) Cause cause := ?) := {
	unsuccessfulOutcome := {
		procedureCode := id_S1Setup,
		criticality := reject,
		value_ := {
			S1SetupFailure := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_Cause,
						criticality := ignore,
						value_ := { Cause := cause }
					}, *
				}
			}
		}
	}
}

/* 9.1.8.1 RESET */
template (value) S1AP_PDU
ts_S1AP_Reset(template (value) Cause cause,
	      template (value) ResetType reset_type) := {
	initiatingMessage := {
		procedureCode := id_Reset,
		criticality := reject,
		value_ := {
			Reset := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_Cause,
						criticality := ignore,
						value_ := { Cause := cause }
					} , {
						id := S1AP_Constants.id_ResetType,
						criticality := reject,
						value_ := { resetType := reset_type }
					}
				}
			}
		}
	}
}
template (present) S1AP_PDU
tr_S1AP_Reset(template (present) Cause cause := ?,
	      template (present) ResetType reset_type := ?) := {
	initiatingMessage := {
		procedureCode := id_Reset,
		criticality := reject,
		value_ := {
			Reset := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_Cause,
						criticality := ignore,
						value_ := { Cause := cause }
					}, {
						id := S1AP_Constants.id_ResetType,
						criticality := reject,
						value_ := { resetType := reset_type }
					}, *
				}
			}
		}
	}
}

/* 9.1.8.2 RESET ACKNOWLEDGE */
template (value) S1AP_PDU
ts_S1AP_ResetAck(template (value) UE_associatedLogicalS1_ConnectionListResAck val) := {
	successfulOutcome := {
		procedureCode := id_Reset,
		criticality := reject,
		value_ := {
			ResetAcknowledge := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_UE_associatedLogicalS1_ConnectionListResAck,
						criticality := ignore,
						value_ := { UE_associatedLogicalS1_ConnectionListResAck := val }
					}
				}
			}
		}
	}
}
template (present) S1AP_PDU
tr_S1AP_ResetAck(template (present) UE_associatedLogicalS1_ConnectionListResAck val := ?) := {
	successfulOutcome := {
		procedureCode := id_Reset,
		criticality := reject,
		value_ := {
			ResetAcknowledge := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_UE_associatedLogicalS1_ConnectionListResAck,
						criticality := ignore,
						value_ := { UE_associatedLogicalS1_ConnectionListResAck := val }
					}, *
				}
			}
		}
	}
}
template (present) S1AP_PDU
tr_S1AP_ResetAck_any := {
	successfulOutcome := {
		procedureCode := id_Reset,
		criticality := reject,
		value_ := {
			ResetAcknowledge := {
				protocolIEs := ?
			}
		}
	}
}


/*********************************************************************************
 * 9.1.7 NAS Transport
 *********************************************************************************/

/* 9.1.7.1 INITIAL UE MESSAGE */
template (value) S1AP_PDU
ts_S1AP_InitialUE(template (value) ENB_UE_S1AP_ID p_eNB_value,
		  template (value) NAS_PDU p_nasPdu,
		  template (value) TAI p_tAI,
		  template (value) EUTRAN_CGI  p_eUTRAN_CGI,
		  template (value) RRC_Establishment_Cause p_rrcCause) := {
	initiatingMessage := {
		procedureCode := id_initialUEMessage,
		criticality := ignore,
		value_ := {
			InitialUEMessage := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_eNB_UE_S1AP_ID,
						criticality := reject,
						value_ := {ENB_UE_S1AP_ID := p_eNB_value}
					}, {
						id := S1AP_Constants.id_NAS_PDU,
						criticality := reject,
						value_ := {nAS_PDU := p_nasPdu}
					}, {
						id := S1AP_Constants.id_TAI,
						criticality := ignore,
						value_ := {TAI := p_tAI}
					}, {
						id := S1AP_Constants.id_EUTRAN_CGI,
						criticality := ignore,
						value_ := {EUTRAN_CGI := p_eUTRAN_CGI}
					}, {
						id := S1AP_Constants.id_RRC_Establishment_Cause,
						criticality := ignore,
						value_ := {RRC_Establishment_Cause := p_rrcCause}
					}
				}
			}
		}
	}
}
template (present) S1AP_PDU
tr_S1AP_InitialUE(template (present) ENB_UE_S1AP_ID p_eNB_value := ?,
		  template (present) NAS_PDU p_nasPdu := ?,
		  template (present) TAI p_tAI := ?,
		  template (present) EUTRAN_CGI p_eUTRAN_CGI := ?,
		  template (present) RRC_Establishment_Cause p_rrcCause := ?) := {
	initiatingMessage := {
		procedureCode := id_initialUEMessage,
		criticality := ignore,
		value_ := {
			InitialUEMessage := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_eNB_UE_S1AP_ID,
						criticality := reject,
						value_ := {ENB_UE_S1AP_ID := p_eNB_value}
					}, {
						id := S1AP_Constants.id_NAS_PDU,
						criticality := reject,
						value_ := {nAS_PDU := p_nasPdu}
					}, {
						id := S1AP_Constants.id_TAI,
						criticality := ignore,
						value_ := {TAI := p_tAI}
					}, {
						id := S1AP_Constants.id_EUTRAN_CGI,
						criticality := ignore,
						value_ := {EUTRAN_CGI := p_eUTRAN_CGI}
					}, {
						id := S1AP_Constants.id_RRC_Establishment_Cause,
						criticality := ignore,
						value_ := {RRC_Establishment_Cause := p_rrcCause}
					}, *
				}
			}
		}
	}
}


/* 9.1.7.2 DOWNLINK NAS TRANSPORT */
template (value) S1AP_PDU
ts_S1AP_DlNasTransport(template (value) MME_UE_S1AP_ID mme_id,
		       template (value) ENB_UE_S1AP_ID enb_id,
		       template (value) octetstring p_nasPdu) := {
	initiatingMessage := {
		procedureCode := id_downlinkNASTransport,
		criticality := ignore,
		value_ := {
			DownlinkNASTransport := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_MME_UE_S1AP_ID,
						criticality := reject,
						value_ := {MME_UE_S1AP_ID := mme_id}
					}, {
						id := S1AP_Constants.id_eNB_UE_S1AP_ID,
						criticality := reject,
						value_ := {ENB_UE_S1AP_ID := enb_id}
					}, {
						id := S1AP_Constants.id_NAS_PDU,
						criticality := reject,
						value_ := {nAS_PDU := p_nasPdu}
					}
				}
			}
		}
	}
}
template (present) S1AP_PDU
tr_S1AP_DlNasTransport(template (present) MME_UE_S1AP_ID mme_id := ?,
		       template (present) ENB_UE_S1AP_ID enb_id := ?,
		       template (present) octetstring p_nasPdu := ?) := {
	initiatingMessage := {
		procedureCode := id_downlinkNASTransport,
		criticality := ignore,
		value_ := {
			DownlinkNASTransport := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_MME_UE_S1AP_ID,
						criticality := reject,
						value_ := {MME_UE_S1AP_ID := mme_id}
					}, {
						id := S1AP_Constants.id_eNB_UE_S1AP_ID,
						criticality := reject,
						value_ := {ENB_UE_S1AP_ID := enb_id}
					}, {
						id := S1AP_Constants.id_NAS_PDU,
						criticality := reject,
						value_ := {nAS_PDU := p_nasPdu}
					}, *
				}
			}
		}
	}
}


/* 9.1.7.3 UPNLINK NAS TRANSPORT */
template (value) S1AP_PDU
ts_S1AP_UlNasTransport(template (value) MME_UE_S1AP_ID mme_id,
		       template (value) ENB_UE_S1AP_ID enb_id,
		       template (value) octetstring p_nasPdu,
		       template (value) EUTRAN_CGI p_eUTRAN_CGI,
		       template (value) TAI p_tAI) := {
	initiatingMessage := {
		procedureCode := id_uplinkNASTransport,
		criticality := ignore,
		value_ := {
			UplinkNASTransport := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_MME_UE_S1AP_ID,
						criticality := reject,
						value_ := {MME_UE_S1AP_ID := mme_id}
					}, {
						id := S1AP_Constants.id_eNB_UE_S1AP_ID,
						criticality := reject,
						value_ := {ENB_UE_S1AP_ID := enb_id}
					}, {
						id := S1AP_Constants.id_NAS_PDU,
						criticality := reject,
						value_ := {nAS_PDU := p_nasPdu}
					}, {
						id := S1AP_Constants.id_EUTRAN_CGI,
						criticality := ignore,
						value_ := {EUTRAN_CGI := p_eUTRAN_CGI}
					}, {
						id := S1AP_Constants.id_TAI,
						criticality := ignore,
						value_ := {TAI := p_tAI}
					}
				}
			}
		}
	}
}
template (present) S1AP_PDU
tr_S1AP_UlNasTransport(template (present) MME_UE_S1AP_ID mme_id := ?,
		       template (present) ENB_UE_S1AP_ID enb_id := ?,
		       template (present) octetstring p_nasPdu := ?,
		       template (present) EUTRAN_CGI p_eUTRAN_CGI := ?,
		       template (present) TAI p_tAI := ?) := {
	initiatingMessage := {
		procedureCode := id_uplinkNASTransport,
		criticality := ignore,
		value_ := {
			UplinkNASTransport := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_MME_UE_S1AP_ID,
						criticality := reject,
						value_ := {MME_UE_S1AP_ID := mme_id}
					}, {
						id := S1AP_Constants.id_eNB_UE_S1AP_ID,
						criticality := reject,
						value_ := {ENB_UE_S1AP_ID := enb_id}
					}, {
						id := S1AP_Constants.id_NAS_PDU,
						criticality := reject,
						value_ := {nAS_PDU := p_nasPdu}
					}, {
						id := S1AP_Constants.id_EUTRAN_CGI,
						criticality := ignore,
						value_ := {EUTRAN_CGI := p_eUTRAN_CGI}
					}, {
						id := S1AP_Constants.id_TAI,
						criticality := ignore,
						value_ := {TAI := p_tAI}
					}, *
				}
			}
		}
	}
}

/*********************************************************************************
 * 9.1.4 Context Management
 *********************************************************************************/

template (value) UEAggregateMaximumBitrate
ts_UEAggregateMaximumBitrate(template (value) BitRate dl := 1073741824,
			     template (value) BitRate ul := 1073741824) := {
	uEaggregateMaximumBitRateDL := dl,
	uEaggregateMaximumBitRateUL := ul,
	iE_Extensions := omit
}
template (present) UEAggregateMaximumBitrate
tr_UEAggregateMaximumBitrate(template (present) BitRate dl := ?,
			     template (present) BitRate ul := ?) := {
	uEaggregateMaximumBitRateDL := dl,
	uEaggregateMaximumBitRateUL := ul,
	iE_Extensions := *
}

template (value) UESecurityCapabilities
ts_UESecurityCapabilities(template (value) EncryptionAlgorithms eea := '1110000000000000'B,
			  template (value) IntegrityProtectionAlgorithms eia := '1110000000000000'B) := {
	encryptionAlgorithms := eea,
	integrityProtectionAlgorithms := eia,
	iE_Extensions := omit
}
template (present) UESecurityCapabilities
tr_UESecurityCapabilities(template (present) EncryptionAlgorithms eea := ?,
			  template (present) IntegrityProtectionAlgorithms eia := ?) := {
	encryptionAlgorithms := eea,
	integrityProtectionAlgorithms := eia,
	iE_Extensions := *
}

template (value) E_RABToBeSetupItemCtxtSUReq
ts_E_RABToBeSetupItemCtxtSUReq(template (value) E_RAB_ID rab_id,
			       template (value) E_RABLevelQoSParameters qos_params,
			       template (value) TransportLayerAddress tla,
			       template (value) GTP_TEID gtp_teid,
			       template (omit) NAS_PDU nas_pdu) := {
	e_RAB_ID := rab_id,
	e_RABlevelQoSParameters := qos_params,
	transportLayerAddress := tla,
	gTP_TEID := gtp_teid,
	nAS_PDU := nas_pdu,
	iE_Extensions := omit
}
template (present) E_RABToBeSetupItemCtxtSUReq
tr_E_RABToBeSetupItemCtxtSUReq(template (present) E_RAB_ID rab_id := ?,
			       template (present) E_RABLevelQoSParameters qos_params := ?,
			       template (present) TransportLayerAddress tla := ?,
			       template (present) GTP_TEID gtp_teid := ?,
			       template NAS_PDU nas_pdu := *) := {
	e_RAB_ID := rab_id,
	e_RABlevelQoSParameters := qos_params,
	transportLayerAddress := tla,
	gTP_TEID := gtp_teid,
	nAS_PDU := nas_pdu,
	iE_Extensions := *
}

template (value) E_RABToBeSetupListCtxtSUReq
ts_E_RABToBeSetupListCtxtSUReq(template (value) E_RABToBeSetupItemCtxtSUReq it) := {
	{
		id := S1AP_Constants.id_E_RABToBeSetupItemCtxtSUReq,
		criticality := reject,
		value_ := { E_RABToBeSetupItemCtxtSUReq := it }
	}
}
template (present) E_RABToBeSetupListCtxtSUReq
tr_E_RABToBeSetupListCtxtSUReq(template (present) E_RABToBeSetupItemCtxtSUReq it) := {
	{
		id := S1AP_Constants.id_E_RABToBeSetupItemCtxtSUReq,
		criticality := reject,
		value_ := { E_RABToBeSetupItemCtxtSUReq := it }
	}
}

/* 9.1.4.1 INITIAL CONTEXT SETUP REQ */
template (value) S1AP_PDU
ts_S1AP_IntialCtxSetupReq(template (value) MME_UE_S1AP_ID mme_id,
			  template (value) ENB_UE_S1AP_ID enb_id,
			  template (value) UEAggregateMaximumBitrate max_br,
			  template (value) E_RABToBeSetupListCtxtSUReq rab_setup_items,
			  template (value) UESecurityCapabilities ue_sec_par,
			  template (value) SecurityKey sec_key) := {
	initiatingMessage := {
		procedureCode := id_InitialContextSetup,
		criticality := reject,
		value_ := {
			initialContextSetupRequest := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_MME_UE_S1AP_ID,
						criticality := reject,
						value_ := {MME_UE_S1AP_ID := mme_id}
					}, {
						id := S1AP_Constants.id_eNB_UE_S1AP_ID,
						criticality := reject,
						value_ := {ENB_UE_S1AP_ID := enb_id}
					}, {
						id := S1AP_Constants.id_uEaggregateMaximumBitrate,
						criticality := reject,
						value_ := {UEAggregateMaximumBitrate := max_br}
					}, {
						id := S1AP_Constants.id_E_RABToBeSetupListCtxtSUReq,
						criticality := reject,
						value_ := {E_RABToBeSetupListCtxtSUReq := rab_setup_items}
					}, {
						id := S1AP_Constants.id_UESecurityCapabilities,
						criticality := reject,
						value_ := {UESecurityCapabilities := ue_sec_par}
					}, {
						id := S1AP_Constants.id_SecurityKey,
						criticality := reject,
						value_ := {SecurityKey := sec_key}
					}
				}
			}
		}
	}
}
template (present) S1AP_PDU
tr_S1AP_IntialCtxSetupReq(template (present) MME_UE_S1AP_ID mme_id := ?,
			  template (present) ENB_UE_S1AP_ID enb_id := ?,
			  template (present) UEAggregateMaximumBitrate max_br := ?,
			  template (present) E_RABToBeSetupListCtxtSUReq rab_setup_items := ?,
			  template (present) UESecurityCapabilities ue_sec_par := ?,
			  template (present) SecurityKey sec_key := ?) := {
	initiatingMessage := {
		procedureCode := id_InitialContextSetup,
		criticality := reject,
		value_ := {
			initialContextSetupRequest := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_MME_UE_S1AP_ID,
						criticality := reject,
						value_ := {MME_UE_S1AP_ID := mme_id}
					}, {
						id := S1AP_Constants.id_eNB_UE_S1AP_ID,
						criticality := reject,
						value_ := {ENB_UE_S1AP_ID := enb_id}
					}, {
						id := S1AP_Constants.id_uEaggregateMaximumBitrate,
						criticality := reject,
						value_ := {UEAggregateMaximumBitrate := max_br}
					}, {
						id := S1AP_Constants.id_E_RABToBeSetupListCtxtSUReq,
						criticality := reject,
						value_ := {E_RABToBeSetupListCtxtSUReq := rab_setup_items}
					}, {
						id := S1AP_Constants.id_UESecurityCapabilities,
						criticality := reject,
						value_ := {UESecurityCapabilities := ue_sec_par}
					}, {
						id := S1AP_Constants.id_SecurityKey,
						criticality := reject,
						value_ := {SecurityKey := sec_key}
					}, *
				}
			}
		}
	}
}

/* 9.1.4.3 INITIAL CONTEXT SETUP RESPONSE */
template (value) E_RABSetupItemCtxtSURes
ts_S1AP_RABSetupItemCtxtSURes(template (value) E_RAB_ID rab_id,
			      template (value) TransportLayerAddress tla,
			      template (value) GTP_TEID gtp_teid) := {
	e_RAB_ID := rab_id,
	transportLayerAddress := tla,
	gTP_TEID := gtp_teid,
	iE_Extensions := omit
}
template (present) E_RABSetupItemCtxtSURes
tr_S1AP_RABSetupItemCtxtSURes(template (present) E_RAB_ID rab_id := ?,
			      template (present) TransportLayerAddress tla := ?,
			      template (present) GTP_TEID gtp_teid := ?) := {
	e_RAB_ID := rab_id,
	transportLayerAddress := tla,
	gTP_TEID := gtp_teid,
	iE_Extensions := *
}

template (value) E_RABSetupListCtxtSURes
ts_S1AP_RABSetupListCtxtSURes(template (value) E_RABSetupItemCtxtSURes it) := {
	{
		id := S1AP_Constants.id_E_RABSetupItemCtxtSURes,
		criticality := ignore,
		value_ := { E_RABSetupItemCtxtSURes := it }
	}
}
template (present) E_RABSetupListCtxtSURes
tr_S1AP_RABSetupListCtxtSURes(template (present) E_RABSetupItemCtxtSURes it := ?) := {
	{
		id := S1AP_Constants.id_E_RABSetupItemCtxtSURes,
		criticality := ignore,
		value_ := { E_RABSetupItemCtxtSURes := it }
	}
}

template (value) S1AP_PDU
ts_S1AP_InitialCtxSetupResp(template (value) MME_UE_S1AP_ID mme_id,
			    template (value) ENB_UE_S1AP_ID enb_id,
			    template (value) E_RABSetupListCtxtSURes rab_setup_items
			    /* OPTIONAL: template (omit) E_RABList rab_failed_items */
			    ) := {
	successfulOutcome := {
		procedureCode := id_InitialContextSetup,
		criticality := reject,
		value_ := {
			InitialContextSetupResponse := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_MME_UE_S1AP_ID,
						criticality := reject,
						value_ := {MME_UE_S1AP_ID := mme_id}
					}, {
						id := S1AP_Constants.id_eNB_UE_S1AP_ID,
						criticality := reject,
						value_ := {ENB_UE_S1AP_ID := enb_id}
					}, {
						id := S1AP_Constants.id_E_RABSetupListCtxtSURes,
						criticality := ignore,
						value_ := {E_RABSetupListCtxtSURes := rab_setup_items}
					}
					/*, {
						id := S1AP_Constants.id_E_RABFailedToSetupListCtxtSURes,
						criticality := ignore,
						value_ := {E_RABList := rab_failed_items}
					}*/
				}
			}
		}
	}
}
template (present) S1AP_PDU
tr_S1AP_InitialCtxSetupResp(template (present) MME_UE_S1AP_ID mme_id := ?,
			    template (present) ENB_UE_S1AP_ID enb_id := ?,
			    template (present) E_RABSetupListCtxtSURes rab_setup_items := ?
			    /* OPTIONAL: template E_RABList rab_failed_items := * */
			    ) := {
	successfulOutcome := {
		procedureCode := id_InitialContextSetup,
		criticality := reject,
		value_ := {
			InitialContextSetupResponse := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_MME_UE_S1AP_ID,
						criticality := reject,
						value_ := {MME_UE_S1AP_ID := mme_id}
					}, {
						id := S1AP_Constants.id_eNB_UE_S1AP_ID,
						criticality := reject,
						value_ := {ENB_UE_S1AP_ID := enb_id}
					}, {
						id := S1AP_Constants.id_E_RABSetupListCtxtSURes,
						criticality := ignore,
						value_ := {E_RABSetupListCtxtSURes := rab_setup_items}
					},
					/*, {
						id := S1AP_Constants.id_E_RABFailedToSetupListCtxtSURes,
						criticality := ignore,
						value_ := {E_RABList := rab_items}
					}, */
					*
				}
			}
		}
	}
}

/* 9.1.4.4 INITIAL CONTEXT SETUP FAILURE */
template (value) S1AP_PDU
ts_S1AP_InitialCtxSetupFail(template (value) MME_UE_S1AP_ID mme_id,
			    template (value) ENB_UE_S1AP_ID enb_id,
			    template (value) Cause cause) := {
	unsuccessfulOutcome := {
		procedureCode := id_InitialContextSetup,
		criticality := reject,
		value_ := {
			InitialContextSetupFailure := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_MME_UE_S1AP_ID,
						criticality := ignore,
						value_ := {MME_UE_S1AP_ID := mme_id}
					}, {
						id := S1AP_Constants.id_eNB_UE_S1AP_ID,
						criticality := ignore,
						value_ := {ENB_UE_S1AP_ID := enb_id}
					}, {
						id := S1AP_Constants.id_Cause,
						criticality := ignore,
						value_ := {Cause := cause}
					}
				}
			}
		}
	}
}
template (present) S1AP_PDU
tr_S1AP_InitialCtxSetupFail(template (present) MME_UE_S1AP_ID mme_id := ?,
			    template (present) ENB_UE_S1AP_ID enb_id := ?,
			    template (present) Cause cause := ?) := {
	unsuccessfulOutcome := {
		procedureCode := id_InitialContextSetup,
		criticality := reject,
		value_ := {
			InitialContextSetupFailure := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_MME_UE_S1AP_ID,
						criticality := ignore,
						value_ := {MME_UE_S1AP_ID := mme_id}
					}, {
						id := S1AP_Constants.id_eNB_UE_S1AP_ID,
						criticality := ignore,
						value_ := {ENB_UE_S1AP_ID := enb_id}
					}, {
						id := S1AP_Constants.id_Cause,
						criticality := ignore,
						value_ := {Cause := cause}
					}, *
				}
			}
		}
	}
}

/* 9.1.4.5 UE CONTEXT RELEASE REQUEST */
template (value) S1AP_PDU
ts_S1AP_UeContextReleaseReq(template (value) MME_UE_S1AP_ID mme_id,
			    template (value) ENB_UE_S1AP_ID enb_id,
			    template (value) Cause cause) := {
	initiatingMessage := {
		procedureCode := id_UEContextReleaseRequest,
		criticality := ignore,
		value_ := {
			UEContextReleaseRequest := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_MME_UE_S1AP_ID,
						criticality := reject,
						value_ := {MME_UE_S1AP_ID := mme_id}
					}, {
						id := S1AP_Constants.id_eNB_UE_S1AP_ID,
						criticality := reject,
						value_ := {ENB_UE_S1AP_ID := enb_id}
					}, {
						id := S1AP_Constants.id_Cause,
						criticality := ignore,
						value_ := {Cause := cause}
					}
				}
			}
		}
	}
}
template (present) S1AP_PDU
tr_S1AP_UeContextReleaseReq(template (present) MME_UE_S1AP_ID mme_id := ?,
			    template (present) ENB_UE_S1AP_ID enb_id := ?,
			    template (present) Cause cause := ?) := {
	initiatingMessage := {
		procedureCode := id_UEContextReleaseRequest,
		criticality := ignore,
		value_ := {
			UEContextReleaseRequest := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_MME_UE_S1AP_ID,
						criticality := reject,
						value_ := {MME_UE_S1AP_ID := mme_id}
					}, {
						id := S1AP_Constants.id_eNB_UE_S1AP_ID,
						criticality := reject,
						value_ := {ENB_UE_S1AP_ID := enb_id}
					}, {
						id := S1AP_Constants.id_Cause,
						criticality := ignore,
						value_ := {Cause := cause}
					}, *
				}
			}
		}
	}
}

/* 9.1.4.6 UE CONTEXT RELEASE COMMAND */
template (value) S1AP_PDU
ts_S1AP_UeContextReleaseCmd(template (value) UE_S1AP_IDs mme_ids,
			    template (value) Cause cause) := {
	initiatingMessage := {
		procedureCode := id_UEContextRelease,
		criticality := reject,
		value_ := {
			UEContextReleaseCommand := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_UE_S1AP_IDs,
						criticality := reject,
						value_ := {UE_S1AP_IDs := mme_ids}
					}, {
						id := S1AP_Constants.id_Cause,
						criticality := ignore,
						value_ := {Cause := cause}
					}
				}
			}
		}
	}
}
template (present) S1AP_PDU
tr_S1AP_UeContextReleaseCmd(template (present) UE_S1AP_IDs ue_ids := ?,
			    template (present) Cause cause := ?) := {
	initiatingMessage := {
		procedureCode := id_UEContextRelease,
		criticality := reject,
		value_ := {
			UEContextReleaseCommand := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_UE_S1AP_IDs,
						criticality := reject,
						value_ := {UE_S1AP_IDs := ue_ids}
					}, {
						id := S1AP_Constants.id_Cause,
						criticality := ignore,
						value_ := {Cause := cause}
					}, *
				}
			}
		}
	}
}

/* 9.1.4.7 UE CONTEXT RELEASE COMPLETE */
template (value) S1AP_PDU
ts_S1AP_UeContextReleaseCompl(template (value) MME_UE_S1AP_ID mme_id,
			      template (value) ENB_UE_S1AP_ID enb_id) := {
	successfulOutcome := {
		procedureCode := id_UEContextRelease,
		criticality := reject,
		value_ := {
			UEContextReleaseComplete := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_MME_UE_S1AP_ID,
						criticality := ignore,
						value_ := {MME_UE_S1AP_ID := mme_id}
					}, {
						id := S1AP_Constants.id_eNB_UE_S1AP_ID,
						criticality := ignore,
						value_ := {ENB_UE_S1AP_ID := enb_id}
					}
				}
			}
		}
	}
}
template (present) S1AP_PDU
tr_S1AP_UeContextReleaseCompl(template (present) MME_UE_S1AP_ID mme_id := ?,
			      template (present) ENB_UE_S1AP_ID enb_id := ?) := {
	successfulOutcome := {
		procedureCode := id_UEContextRelease,
		criticality := reject,
		value_ := {
			UEContextReleaseComplete := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_MME_UE_S1AP_ID,
						criticality := ignore,
						value_ := {MME_UE_S1AP_ID := mme_id}
					}, {
						id := S1AP_Constants.id_eNB_UE_S1AP_ID,
						criticality := ignore,
						value_ := {ENB_UE_S1AP_ID := enb_id}
					}, *
				}
			}
		}
	}
}

/* 9.1.4.20 CONNECTION ESTABLISHMENT INDICATION */
template (value) S1AP_PDU
ts_S1AP_ConnEstInd(template (value) MME_UE_S1AP_ID mme_id,
		   template (value) ENB_UE_S1AP_ID enb_id) := {
	initiatingMessage := {
		procedureCode := id_ConnectionEstablishmentIndication,
		criticality := reject,
		value_ := {
			ConnectionEstablishmentIndication := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_MME_UE_S1AP_ID,
						criticality := ignore,
						value_ := {MME_UE_S1AP_ID := mme_id}
					}, {
						id := S1AP_Constants.id_eNB_UE_S1AP_ID,
						criticality := ignore,
						value_ := {ENB_UE_S1AP_ID := enb_id}
					}
				}
			}
		}
	}
}
template (present) S1AP_PDU
tr_S1AP_ConnEstInd(template (present) MME_UE_S1AP_ID mme_id := ?,
		   template (present) ENB_UE_S1AP_ID enb_id := ?) := {
	initiatingMessage := {
		procedureCode := id_ConnectionEstablishmentIndication,
		criticality := reject,
		value_ := {
			ConnectionEstablishmentIndication := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_MME_UE_S1AP_ID,
						criticality := ignore,
						value_ := {MME_UE_S1AP_ID := mme_id}
					}, {
						id := S1AP_Constants.id_eNB_UE_S1AP_ID,
						criticality := ignore,
						value_ := {ENB_UE_S1AP_ID := enb_id}
					}, *
				}
			}
		}
	}
}

/* 9.1.14 eNB DIRECT INFORMATION TRANSFER */
template (value) S1AP_PDU
ts_S1AP_eNBDirectInfTrans(template (value) Inter_SystemInformationTransferType inf) := {
	initiatingMessage := {
		procedureCode := id_eNBDirectInformationTransfer,
		criticality := reject,
		value_ := {
			eNBDirectInformationTransfer := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_Inter_SystemInformationTransferTypeEDT,
						criticality := ignore,
						value_ := {Inter_SystemInformationTransferType := inf}
					}
				}
			}
		}
	}
}

/* 9.1.15 MME DIRECT INFORMATION TRANSFER */
template (present) S1AP_PDU
tr_S1AP_MMEDirectInfTrans(template (present) Inter_SystemInformationTransferType inf := ?) := {
	initiatingMessage := {
		procedureCode := id_MMEDirectInformationTransfer,
		criticality := ignore,
		value_ := {
			MMEDirectInformationTransfer := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_Inter_SystemInformationTransferTypeMDT,
						criticality := reject,
						value_ := {Inter_SystemInformationTransferType := inf}
					}, *
				}
			}
		}
	}
}

/* all non-UE-related S1AP messages */
template (present) S1AP_PDU
tr_S1AP_nonUErelated := (tr_S1AP_SetupReq, tr_S1AP_SetupResp, tr_S1AP_SetupFail,
			 tr_S1AP_Reset, tr_S1AP_ResetAck, tr_S1AP_ResetAck_any, tr_S1AP_MMEDirectInfTrans
			);


template (value) E_RABLevelQoSParameters
ts_E_RABLevelQoSParameters(template (value) QCI qci := 5,
			   template (value) PriorityLevel prio := 1) := {
	qCI := qci,
	allocationRetentionPriority := {
		priorityLevel := prio,
		pre_emptionCapability := shall_not_trigger_pre_emption,
		pre_emptionVulnerability := not_pre_emptable,
		iE_Extensions := omit
	},
	gbrQosInformation := omit,
	iE_Extensions := omit
}

/* 9.1.3.1 E-RAB SETUP REQUEST */
template (value) E_RABToBeSetupItemBearerSUReq
ts_S1AP_RABToBeSetupItemBearerSUReq(template (value) E_RAB_ID rab_id,
				    template (value) E_RABLevelQoSParameters qos_params,
				    template (value) TransportLayerAddress tla,
				    template (value) GTP_TEID gtp_teid,
				    template (value) NAS_PDU nas_pdu) := {
	e_RAB_ID := rab_id,
	e_RABlevelQoSParameters := qos_params,
	transportLayerAddress := tla,
	gTP_TEID := gtp_teid,
	nAS_PDU := nas_pdu,
	iE_Extensions := omit
}
template (present) E_RABToBeSetupItemBearerSUReq
tr_S1AP_RABToBeSetupItemBearerSUReq(template (present) E_RAB_ID rab_id := ?,
				    template (present) E_RABLevelQoSParameters qos_params := ?,
				    template (present) TransportLayerAddress tla := ?,
				    template (present) GTP_TEID gtp_teid := ?,
				    template (present) NAS_PDU nas_pdu := ?) := {
	e_RAB_ID := rab_id,
	e_RABlevelQoSParameters := qos_params,
	transportLayerAddress := tla,
	gTP_TEID := gtp_teid,
	nAS_PDU := nas_pdu,
	iE_Extensions := *
}

template (value) E_RABToBeSetupListBearerSUReq
ts_S1AP_RABToBeSetupListBearerSUReq(template (value) E_RABToBeSetupItemBearerSUReq it) := {
	{
		id := S1AP_Constants.id_E_RABToBeSetupItemBearerSUReq,
		criticality := reject,
		value_ := { E_RABToBeSetupItemBearerSUReq := it }
	}
}
template (present) E_RABToBeSetupListBearerSUReq
tr_S1AP_RABToBeSetupListBearerSUReq(template (present) E_RABToBeSetupItemBearerSUReq it := ?) := {
	{
		id := S1AP_Constants.id_E_RABToBeSetupItemBearerSUReq,
		criticality := reject,
		value_ := { E_RABToBeSetupItemBearerSUReq := it }
	}
}

template (value) S1AP_PDU
ts_S1AP_RABSetupReq(template (value) MME_UE_S1AP_ID mme_id,
		    template (value) ENB_UE_S1AP_ID enb_id,
		    template (value) E_RABToBeSetupListBearerSUReq rab_setup_items) := {
	initiatingMessage := {
		procedureCode := S1AP_Constants.id_E_RABSetup,
		criticality := reject,
		value_ := {
			E_RABSetupRequest := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_MME_UE_S1AP_ID,
						criticality := reject,
						value_ := { MME_UE_S1AP_ID := mme_id }
					}, {
						id := S1AP_Constants.id_eNB_UE_S1AP_ID,
						criticality := reject,
						value_ := { ENB_UE_S1AP_ID := enb_id }
					}, {
						id := S1AP_Constants.id_E_RABToBeSetupListBearerSUReq,
						criticality := reject,
						value_ := { E_RABToBeSetupListBearerSUReq := rab_setup_items }
					}
				}
			}
		}
	}
}
template (present) S1AP_PDU
tr_S1AP_RABSetupReq(template (present) MME_UE_S1AP_ID mme_id := ?,
		    template (present) ENB_UE_S1AP_ID enb_id := ?,
		    template (present) E_RABToBeSetupListBearerSUReq rab_setup_items := ?) := {
	initiatingMessage := {
		procedureCode := S1AP_Constants.id_E_RABSetup,
		criticality := reject,
		value_ := {
			E_RABSetupRequest := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_MME_UE_S1AP_ID,
						criticality := reject,
						value_ := { MME_UE_S1AP_ID := mme_id }
					}, {
						id := S1AP_Constants.id_eNB_UE_S1AP_ID,
						criticality := reject,
						value_ := { ENB_UE_S1AP_ID := enb_id }
					}, {
						id := S1AP_Constants.id_E_RABToBeSetupListBearerSUReq,
						criticality := reject,
						value_ := { E_RABToBeSetupListBearerSUReq := rab_setup_items }
					}, *
				}
			}
		}
	}
}

/* 9.1.3.2 E-RAB SETUP RESPONSE */
template (value) E_RABSetupItemBearerSURes
ts_S1AP_RABSetupItemBearerSURes(template (value) E_RAB_ID rab_id,
				template (value) TransportLayerAddress tla,
				template (value) GTP_TEID gtp_teid) := {
	e_RAB_ID := rab_id,
	transportLayerAddress := tla,
	gTP_TEID := gtp_teid,
	iE_Extensions := omit
}
template (present) E_RABSetupItemBearerSURes
tr_S1AP_RABSetupItemBearerSURes(template (present) E_RAB_ID rab_id := ?,
				template (present) TransportLayerAddress tla := ?,
				template (present) GTP_TEID gtp_teid := ?) := {
	e_RAB_ID := rab_id,
	transportLayerAddress := tla,
	gTP_TEID := gtp_teid,
	iE_Extensions := *
}

template (value) E_RABSetupListBearerSURes
ts_S1AP_RABSetupListBearerSURes(template (value) E_RABSetupItemBearerSURes it) := {
	{
		id := S1AP_Constants.id_E_RABSetupItemBearerSURes,
		criticality := reject,
		value_ := { E_RABSetupItemBearerSURes := it }
	}
}
template (present) E_RABSetupListBearerSURes
tr_S1AP_RABSetupListBearerSURes(template (present) E_RABSetupItemBearerSURes it := ?) := {
	{
		id := S1AP_Constants.id_E_RABSetupItemBearerSURes,
		criticality := reject,
		value_ := { E_RABSetupItemBearerSURes := it }
	}
}

private function
f_ts_S1AP_RABSetupRsp(template (value) MME_UE_S1AP_ID mme_id,
		      template (value) ENB_UE_S1AP_ID enb_id,
		      template (omit) E_RABSetupListBearerSURes rab_setup_items := omit,
		      template (omit) E_RABList rab_failed_items := omit)
return template (value) E_RABSetupResponse
{
	var template (value) E_RABSetupResponse rsp := {
		protocolIEs := {
			{
				id := S1AP_Constants.id_MME_UE_S1AP_ID,
				criticality := ignore,
				value_ := { MME_UE_S1AP_ID := mme_id }
			}, {
				id := S1AP_Constants.id_eNB_UE_S1AP_ID,
				criticality := ignore,
				value_ := { ENB_UE_S1AP_ID := enb_id }
			}
		}
	};

	var integer idx := lengthof(rsp.protocolIEs);
	if (isvalue(rab_setup_items)) {
		rsp.protocolIEs[idx] := {
			id := S1AP_Constants.id_E_RABSetupListBearerSURes,
			criticality := ignore,
			value_ := { e_RABSetupListBearerSURes := rab_setup_items }
		};
		idx := idx + 1;
	}
	if (isvalue(rab_failed_items)) {
		rsp.protocolIEs[idx] := {
			id := S1AP_Constants.id_E_RABFailedToSetupListBearerSURes,
			criticality := ignore,
			value_ := { e_RABList := rab_failed_items }
		};
		idx := idx + 1;
	}

	return rsp;
}
private function
f_tr_S1AP_RABSetupRsp(template (present) MME_UE_S1AP_ID mme_id,
		      template (present) ENB_UE_S1AP_ID enb_id,
		      template E_RABSetupListBearerSURes rab_setup_items := *,
		      template E_RABList rab_failed_items := *)
return template E_RABSetupResponse
{
	var template E_RABSetupResponse rsp := {
		protocolIEs := {
			{
				id := S1AP_Constants.id_MME_UE_S1AP_ID,
				criticality := ignore,
				value_ := { MME_UE_S1AP_ID := mme_id }
			}, {
				id := S1AP_Constants.id_eNB_UE_S1AP_ID,
				criticality := ignore,
				value_ := { ENB_UE_S1AP_ID := enb_id }
			}
		}
	};

	var integer idx := lengthof(rsp.protocolIEs);
	if (ispresent(rab_setup_items)) {
		rsp.protocolIEs[idx] := {
			id := S1AP_Constants.id_E_RABSetupListBearerSURes,
			criticality := ignore,
			value_ := { e_RABSetupListBearerSURes := rab_setup_items }
		};
		idx := idx + 1;
	}
	if (ispresent(rab_failed_items)) {
		rsp.protocolIEs[idx] := {
			id := S1AP_Constants.id_E_RABFailedToSetupListBearerSURes,
			criticality := ignore,
			value_ := { e_RABList := rab_failed_items }
		};
		idx := idx + 1;
	}
	/* ignore the remaining IEs */
	rsp.protocolIEs[idx] := *;

	return rsp;
}

template (value) S1AP_PDU
ts_S1AP_RABSetupRsp(template (value) MME_UE_S1AP_ID mme_id,
		    template (value) ENB_UE_S1AP_ID enb_id,
		    template (omit) E_RABSetupListBearerSURes rab_setup_items := omit,
		    template (omit) E_RABList rab_failed_items := omit) := {
	successfulOutcome := {
		procedureCode := S1AP_Constants.id_E_RABSetup,
		criticality := reject,
		value_ := {
			e_RABSetupResponse := f_ts_S1AP_RABSetupRsp(mme_id, enb_id,
								    rab_setup_items,
								    rab_failed_items)
		}
	}
}
template (present) S1AP_PDU
tr_S1AP_RABSetupRsp(template (present) MME_UE_S1AP_ID mme_id := ?,
		    template (present) ENB_UE_S1AP_ID enb_id := ?,
		    template E_RABSetupListBearerSURes rab_setup_items := *,
		    template E_RABList rab_failed_items := *) := {
	successfulOutcome := {
		procedureCode := S1AP_Constants.id_E_RABSetup,
		criticality := reject,
		value_ := {
			e_RABSetupResponse := f_tr_S1AP_RABSetupRsp(mme_id, enb_id,
								    rab_setup_items,
								    rab_failed_items)
		}
	}
}

/* 9.1.3.3 E-RAB MODIFY REQUEST */
template (value) E_RABToBeModifiedItemBearerModReq
ts_E_RABToBeModifiedItemBearerModReq(template (value) E_RAB_ID rab_id,
				     template (value) E_RABLevelQoSParameters qos_params,
				     template (value) NAS_PDU nas_pdu) := {
	e_RAB_ID := rab_id,
	e_RABLevelQoSParameters := qos_params,
	nAS_PDU := nas_pdu,
	iE_Extensions := omit
}
template (present) E_RABToBeModifiedItemBearerModReq
tr_E_RABToBeModifiedItemBearerModReq(template (present) E_RAB_ID rab_id := ?,
				     template (present) E_RABLevelQoSParameters qos_params := ?,
				     template (present) NAS_PDU nas_pdu := ?) := {
	e_RAB_ID := rab_id,
	e_RABLevelQoSParameters := qos_params,
	nAS_PDU := nas_pdu,
	iE_Extensions := *
}

template (value) E_RABToBeModifiedItemBearerModReq
ts_E_RABToBeModifiedItemBearerModReqExt(template (value) E_RAB_ID rab_id,
					template (value) E_RABLevelQoSParameters qos_params,
					template (value) NAS_PDU nas_pdu,
					template (value) TransportLayerAddress tla,
					template (value) GTP_TEID gtp_teid)
modifies ts_E_RABToBeModifiedItemBearerModReq := {
	iE_Extensions := {
		{
			id := S1AP_Constants.id_TransportInformation,
			criticality := reject,
			extensionValue := {
				TransportInformation := {
					transportLayerAddress := tla,
					uL_GTP_TEID := gtp_teid
				}
			}
		}
	}
}
template (present) E_RABToBeModifiedItemBearerModReq
tr_E_RABToBeModifiedItemBearerModReqExt(template (present) E_RAB_ID rab_id := ?,
					template (present) E_RABLevelQoSParameters qos_params := ?,
					template (present) NAS_PDU nas_pdu := ?,
					template (present) TransportLayerAddress tla := ?,
					template (present) GTP_TEID gtp_teid := ?)
modifies tr_E_RABToBeModifiedItemBearerModReq := {
	iE_Extensions := {
		{
			id := S1AP_Constants.id_TransportInformation,
			criticality := reject,
			extensionValue := {
				TransportInformation := {
					transportLayerAddress := tla,
					uL_GTP_TEID := gtp_teid
				}
			}
		}
	}
}

template (value) E_RABToBeModifiedListBearerModReq
ts_E_RABToBeModifiedListBearerModReq(template (value) E_RABToBeModifiedItemBearerModReq it) := {
	{
		id := S1AP_Constants.id_E_RABToBeModifiedItemBearerModReq,
		criticality := reject,
		value_ := { E_RABToBeModifiedItemBearerModReq := it }
	}
}
template (present) E_RABToBeModifiedListBearerModReq
tr_E_RABToBeModifiedListBearerModReq(template (present) E_RABToBeModifiedItemBearerModReq it := ?) := {
	{
		id := S1AP_Constants.id_E_RABToBeModifiedItemBearerModReq,
		criticality := reject,
		value_ := { E_RABToBeModifiedItemBearerModReq := it }
	}
}

private function
f_ts_S1AP_RABModifyReq(template (value) MME_UE_S1AP_ID mme_id,
		       template (value) ENB_UE_S1AP_ID enb_id,
		       template (value) E_RABToBeModifiedListBearerModReq rab_modify_items,
		       template (omit) UEAggregateMaximumBitrate max_br := omit)
return template (value) E_RABModifyRequest
{
	var template (value) E_RABModifyRequest req := {
		protocolIEs := {
			{
				id := S1AP_Constants.id_MME_UE_S1AP_ID,
				criticality := reject,
				value_ := { MME_UE_S1AP_ID := mme_id }
			}, {
				id := S1AP_Constants.id_eNB_UE_S1AP_ID,
				criticality := reject,
				value_ := { ENB_UE_S1AP_ID := enb_id }
			}
		}
	};

	var integer idx := lengthof(req.protocolIEs);
	if (isvalue(max_br)) {
		req.protocolIEs[idx] := {
			id := S1AP_Constants.id_uEaggregateMaximumBitrate,
			criticality := reject,
			value_ := { UEAggregateMaximumBitrate := max_br }
		};
		idx := idx + 1;
	}

	req.protocolIEs[idx] := {
		id := S1AP_Constants.id_E_RABToBeModifiedListBearerModReq,
		criticality := reject,
		value_ := { E_RABToBeModifiedListBearerModReq := rab_modify_items }
	};
	idx := idx + 1;

	return req;
}
private function
f_tr_S1AP_RABModifyReq(template (present) MME_UE_S1AP_ID mme_id,
		       template (present) ENB_UE_S1AP_ID enb_id,
		       template (present) E_RABToBeModifiedListBearerModReq rab_modify_items,
		       template UEAggregateMaximumBitrate max_br := *)
return template E_RABModifyRequest
{
	var template E_RABModifyRequest req := {
		protocolIEs := {
			{
				id := S1AP_Constants.id_MME_UE_S1AP_ID,
				criticality := reject,
				value_ := { MME_UE_S1AP_ID := mme_id }
			}, {
				id := S1AP_Constants.id_eNB_UE_S1AP_ID,
				criticality := reject,
				value_ := { ENB_UE_S1AP_ID := enb_id }
			}
		}
	};

	var integer idx := lengthof(req.protocolIEs);
	if (ispresent(max_br)) {
		req.protocolIEs[idx] := {
			id := S1AP_Constants.id_uEaggregateMaximumBitrate,
			criticality := reject,
			value_ := { UEAggregateMaximumBitrate := max_br }
		};
		idx := idx + 1;
	} else if (istemplatekind(max_br, "*")) {
		req.protocolIEs[idx] := *;
		idx := idx + 1;
	}

	req.protocolIEs[idx] := {
		id := S1AP_Constants.id_E_RABToBeModifiedListBearerModReq,
		criticality := reject,
		value_ := { E_RABToBeModifiedListBearerModReq := rab_modify_items }
	};
	idx := idx + 1;

	/* ignore the remaining IEs */
	req.protocolIEs[idx] := *;

	return req;
}

template (value) S1AP_PDU
ts_S1AP_RABModifyReq(template (value) MME_UE_S1AP_ID mme_id,
		     template (value) ENB_UE_S1AP_ID enb_id,
		     template (value) E_RABToBeModifiedListBearerModReq rab_modify_items,
		     template (omit) UEAggregateMaximumBitrate max_br := omit) := {
	initiatingMessage := {
		procedureCode := S1AP_Constants.id_E_RABModify,
		criticality := reject,
		value_ := {
			E_RABModifyRequest := f_ts_S1AP_RABModifyReq(mme_id, enb_id,
								     rab_modify_items,
								     max_br)
		}
	}
}
template (present) S1AP_PDU
tr_S1AP_RABModifyReq(template (present) MME_UE_S1AP_ID mme_id := ?,
		     template (present) ENB_UE_S1AP_ID enb_id := ?,
		     template (present) E_RABToBeModifiedListBearerModReq rab_modify_items := ?,
		     template UEAggregateMaximumBitrate max_br := *) := {
	initiatingMessage := {
		procedureCode := S1AP_Constants.id_E_RABModify,
		criticality := reject,
		value_ := {
			E_RABModifyRequest := f_tr_S1AP_RABModifyReq(mme_id, enb_id,
								     rab_modify_items,
								     max_br)
		}
	}
}

/* 9.1.3.4 E-RAB MODIFY RESPONSE */
template (value) E_RABModifyItemBearerModRes
ts_E_RABModifyItemBearerModRes(template (value) E_RAB_ID rab_id) := {
	e_RAB_ID := rab_id,
	iE_Extensions := omit
}
template (present) E_RABModifyItemBearerModRes
tr_E_RABModifyItemBearerModRes(template (present) E_RAB_ID rab_id := ?) := {
	e_RAB_ID := rab_id,
	iE_Extensions := *
}

template (value) E_RABModifyListBearerModRes
ts_E_RABModifyListBearerModRes(template (value) E_RABModifyItemBearerModRes it) := {
	{
		id := S1AP_Constants.id_E_RABModifyItemBearerModRes,
		criticality := ignore,
		value_ := { E_RABModifyItemBearerModRes := it }
	}
}
template (present) E_RABModifyListBearerModRes
tr_E_RABModifyListBearerModRes(template (present) E_RABModifyItemBearerModRes it := ?) := {
	{
		id := S1AP_Constants.id_E_RABModifyItemBearerModRes,
		criticality := ignore,
		value_ := { E_RABModifyItemBearerModRes := it }
	}
}

private function
f_ts_S1AP_RABModifyRsp(template (value) MME_UE_S1AP_ID mme_id,
		       template (value) ENB_UE_S1AP_ID enb_id,
		       template (value) E_RABModifyListBearerModRes rab_modified_items,
		       template (omit) E_RABList rab_failed_items := omit)
return template (value) E_RABModifyResponse
{
	var template (value) E_RABModifyResponse rsp := {
		protocolIEs := {
			{
				id := S1AP_Constants.id_MME_UE_S1AP_ID,
				criticality := ignore,
				value_ := { MME_UE_S1AP_ID := mme_id }
			}, {
				id := S1AP_Constants.id_eNB_UE_S1AP_ID,
				criticality := ignore,
				value_ := { ENB_UE_S1AP_ID := enb_id }
			}, {
				id := S1AP_Constants.id_E_RABModifyListBearerModRes,
				criticality := ignore,
				value_ := { E_RABModifyListBearerModRes := rab_modified_items }
			}
		}
	};

	var integer idx := lengthof(rsp.protocolIEs);
	if (isvalue(rab_failed_items)) {
		rsp.protocolIEs[idx] := {
			id := S1AP_Constants.id_E_RABFailedToModifyList,
			criticality := ignore,
			value_ := { e_RABList := rab_failed_items }
		};
		idx := idx + 1;
	}

	return rsp;
}
private function
f_tr_S1AP_RABModifyRsp(template (present) MME_UE_S1AP_ID mme_id,
		       template (present) ENB_UE_S1AP_ID enb_id,
		       template (present) E_RABModifyListBearerModRes rab_modified_items,
		       template E_RABList rab_failed_items := *)
return template E_RABModifyResponse
{
	var template E_RABModifyResponse rsp := {
		protocolIEs := {
			{
				id := S1AP_Constants.id_MME_UE_S1AP_ID,
				criticality := ignore,
				value_ := { MME_UE_S1AP_ID := mme_id }
			}, {
				id := S1AP_Constants.id_eNB_UE_S1AP_ID,
				criticality := ignore,
				value_ := { ENB_UE_S1AP_ID := enb_id }
			}, {
				id := S1AP_Constants.id_E_RABModifyListBearerModRes,
				criticality := ignore,
				value_ := { E_RABModifyListBearerModRes := rab_modified_items }
			}
		}
	};

	var integer idx := lengthof(rsp.protocolIEs);
	if (ispresent(rab_failed_items)) {
		rsp.protocolIEs[idx] := {
			id := S1AP_Constants.id_E_RABFailedToModifyList,
			criticality := ignore,
			value_ := { e_RABList := rab_failed_items }
		};
		idx := idx + 1;
	}
	/* ignore the remaining IEs */
	rsp.protocolIEs[idx] := *;

	return rsp;
}

template (value) S1AP_PDU
ts_S1AP_RABModifyRsp(template (value) MME_UE_S1AP_ID mme_id,
		     template (value) ENB_UE_S1AP_ID enb_id,
		     template (value) E_RABModifyListBearerModRes rab_modified_items,
		     template (omit) E_RABList rab_failed_items := omit) := {
	successfulOutcome := {
		procedureCode := S1AP_Constants.id_E_RABModify,
		criticality := reject,
		value_ := {
			E_RABModifyResponse := f_ts_S1AP_RABModifyRsp(mme_id, enb_id,
								      rab_modified_items,
								      rab_failed_items)
		}
	}
}
template (present) S1AP_PDU
tr_S1AP_RABModifyRsp(template (present) MME_UE_S1AP_ID mme_id := ?,
		     template (present) ENB_UE_S1AP_ID enb_id := ?,
		     template (present) E_RABModifyListBearerModRes rab_modified_items := ?,
		     template E_RABList rab_failed_items := *) := {
	successfulOutcome := {
		procedureCode := S1AP_Constants.id_E_RABModify,
		criticality := reject,
		value_ := {
			E_RABModifyResponse := f_tr_S1AP_RABModifyRsp(mme_id, enb_id,
								      rab_modified_items,
								      rab_failed_items)
		}
	}
}

/* 9.1.3.5 E-RAB RELEASE COMMAND */
template (value) S1AP_PDU
ts_S1AP_RABReleaseCmd(template (value) MME_UE_S1AP_ID mme_id,
		      template (value) ENB_UE_S1AP_ID enb_id,
		      template (value) E_RABList rab_items) := {
	initiatingMessage := {
		procedureCode := S1AP_Constants.id_E_RABRelease,
		criticality := reject,
		value_ := {
			e_RABReleaseCommand := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_MME_UE_S1AP_ID,
						criticality := reject,
						value_ := { MME_UE_S1AP_ID := mme_id }
					}, {
						id := S1AP_Constants.id_eNB_UE_S1AP_ID,
						criticality := reject,
						value_ := { ENB_UE_S1AP_ID := enb_id }
					}, {
						id := S1AP_Constants.id_E_RABToBeReleasedList,
						criticality := ignore,
						value_ := { e_RABList := rab_items }
					}
				}
			}
		}
	}
}
template (present) S1AP_PDU
tr_S1AP_RABReleaseCmd(template (present) MME_UE_S1AP_ID mme_id := ?,
		      template (present) ENB_UE_S1AP_ID enb_id := ?,
		      template (present) E_RABList rab_items := ?) := {
	initiatingMessage := {
		procedureCode := S1AP_Constants.id_E_RABRelease,
		criticality := reject,
		value_ := {
			e_RABReleaseCommand := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_MME_UE_S1AP_ID,
						criticality := reject,
						value_ := { MME_UE_S1AP_ID := mme_id }
					}, {
						id := S1AP_Constants.id_eNB_UE_S1AP_ID,
						criticality := reject,
						value_ := { ENB_UE_S1AP_ID := enb_id }
					}, {
						id := S1AP_Constants.id_E_RABToBeReleasedList,
						criticality := ignore,
						value_ := { e_RABList := rab_items }
					}
				}
			}
		}
	}
}

/* 9.1.3.6 E-RAB RELEASE RESPONSE */
template (value) S1AP_PDU
ts_S1AP_RABReleaseRsp(template (value) MME_UE_S1AP_ID mme_id,
		      template (value) ENB_UE_S1AP_ID enb_id,
		      template (value) E_RABReleaseListBearerRelComp rab_items) := {
	successfulOutcome := {
		procedureCode := S1AP_Constants.id_E_RABRelease,
		criticality := reject,
		value_ := {
			e_RABReleaseResponse := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_MME_UE_S1AP_ID,
						criticality := ignore,
						value_ := { MME_UE_S1AP_ID := mme_id }
					}, {
						id := S1AP_Constants.id_eNB_UE_S1AP_ID,
						criticality := ignore,
						value_ := { ENB_UE_S1AP_ID := enb_id }
					}, {
						id := S1AP_Constants.id_E_RABReleaseListBearerRelComp,
						criticality := ignore,
						value_ := { e_RABReleaseListBearerRelComp := rab_items }
					}
				}
			}
		}
	}
}
template (present) S1AP_PDU
tr_S1AP_RABReleaseRsp(template (present) MME_UE_S1AP_ID mme_id := ?,
		      template (present) ENB_UE_S1AP_ID enb_id := ?,
		      template (present) E_RABReleaseListBearerRelComp rab_items := ?) := {
	successfulOutcome := {
		procedureCode := S1AP_Constants.id_E_RABRelease,
		criticality := reject,
		value_ := {
			e_RABReleaseResponse := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_MME_UE_S1AP_ID,
						criticality := ignore,
						value_ := { MME_UE_S1AP_ID := mme_id }
					}, {
						id := S1AP_Constants.id_eNB_UE_S1AP_ID,
						criticality := ignore,
						value_ := { ENB_UE_S1AP_ID := enb_id }
					}, {
						id := S1AP_Constants.id_E_RABReleaseListBearerRelComp,
						criticality := ignore,
						value_ := { e_RABReleaseListBearerRelComp := rab_items }
					}
				}
			}
		}
	}
}

/* 9.1.3.7 E-RAB RELEASE INDICATION */
template (value) S1AP_PDU
ts_S1AP_RABReleaseInd(template (value) MME_UE_S1AP_ID mme_id,
		      template (value) ENB_UE_S1AP_ID enb_id,
		      template (value) E_RABList rab_items) := {
	initiatingMessage := {
		procedureCode := S1AP_Constants.id_E_RABReleaseIndication,
		criticality := reject,
		value_ := {
			e_RABReleaseIndication := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_MME_UE_S1AP_ID,
						criticality := reject,
						value_ := { MME_UE_S1AP_ID := mme_id }
					}, {
						id := S1AP_Constants.id_eNB_UE_S1AP_ID,
						criticality := reject,
						value_ := { ENB_UE_S1AP_ID := enb_id }
					}, {
						id := S1AP_Constants.id_E_RABReleasedList,
						criticality := ignore,
						value_ := { E_RABList := rab_items }
					}
				}
			}
		}
	}
}
template (present) S1AP_PDU
tr_S1AP_RABReleaseInd(template (present) MME_UE_S1AP_ID mme_id := ?,
		      template (present) ENB_UE_S1AP_ID enb_id := ?,
		      template (present) E_RABList rab_items := ?) := {
	initiatingMessage := {
		procedureCode := S1AP_Constants.id_E_RABReleaseIndication,
		criticality := reject,
		value_ := {
			e_RABReleaseIndication := {
				protocolIEs := {
					{
						id := S1AP_Constants.id_MME_UE_S1AP_ID,
						criticality := reject,
						value_ := { MME_UE_S1AP_ID := mme_id }
					}, {
						id := S1AP_Constants.id_eNB_UE_S1AP_ID,
						criticality := reject,
						value_ := { ENB_UE_S1AP_ID := enb_id }
					}, {
						id := S1AP_Constants.id_E_RABReleasedList,
						criticality := ignore,
						value_ := { E_RABList := rab_items }
					}
				}
			}
		}
	}
}

/* 9.2.1.36 E-RAB List */
template (value) E_RABList
ts_E_RABList(template (value) E_RABItem it) := {
	{
		id := S1AP_Constants.id_E_RABItem,
		criticality := ignore,
		value_ := { E_RABItem := it }
	}
}
template (present) E_RABList
tr_E_RABList(template (present) E_RABItem it := ?) := {
	{
		id := S1AP_Constants.id_E_RABItem,
		criticality := ignore,
		value_ := { E_RABItem := it }
	}
}

template (value) E_RABItem
ts_E_RABItem(template (value) E_RAB_ID rab_id,
	     template (value) Cause cause := {nas := normal_release}) := {
	e_RAB_ID := rab_id,
	cause := cause,
	iE_Extensions := omit
}
template (present) E_RABItem
tr_E_RABItem(template (present) E_RAB_ID rab_id := ?,
	     template (present) Cause cause := ?) := {
	e_RAB_ID := rab_id,
	cause := cause,
	iE_Extensions := *
}

/* E-RAB Release List */
template (value) E_RABReleaseListBearerRelComp
ts_E_RABReleaseListBearerRelComp(template (value) E_RABReleaseItemBearerRelComp it) := {
	{
		id := S1AP_Constants.id_E_RABReleaseItemBearerRelComp,
		criticality := ignore,
		value_ := { E_RABReleaseItemBearerRelComp := it }
	}
}
template (present) E_RABReleaseListBearerRelComp
tr_E_RABReleaseListBearerRelComp(template (present) E_RABReleaseItemBearerRelComp it := ?) := {
	{
		id := S1AP_Constants.id_E_RABReleaseItemBearerRelComp,
		criticality := ignore,
		value_ := { E_RABReleaseItemBearerRelComp := it }
	}
}

template (value) E_RABReleaseItemBearerRelComp
ts_E_RABReleaseItemBearerRelComp(template (value) E_RAB_ID rab_id) := {
	e_RAB_ID := rab_id,
	iE_Extensions := omit
}
template (present) E_RABReleaseItemBearerRelComp
tr_E_RABReleaseItemBearerRelComp(template (present) E_RAB_ID rab_id := ?) := {
	e_RAB_ID := rab_id,
	iE_Extensions := *
}

/* 9.1.3.8 E-RAB MODIFICATION INDICATION */
template (value) S1AP_PDU
ts_S1AP_RABModifyInd(template (value) MME_UE_S1AP_ID mme_id,
		     template (value) ENB_UE_S1AP_ID enb_id,
		     template (value) E_RABToBeModifiedListBearerModInd rab_do_modify_items,
		     template (omit) E_RABNotToBeModifiedListBearerModInd rab_no_modify_items := omit) := {
	initiatingMessage := {
		procedureCode := S1AP_Constants.id_E_RABModificationIndication,
		criticality := reject,
		value_ := {
			e_RABModificationIndication := f_ts_S1AP_RABModifyInd(mme_id, enb_id,
									      rab_do_modify_items,
									      rab_no_modify_items)
		}
	}
}
template (present) S1AP_PDU
tr_S1AP_RABModifyInd(template (present) MME_UE_S1AP_ID mme_id := ?,
		     template (present) ENB_UE_S1AP_ID enb_id := ?,
		     template (present) E_RABToBeModifiedListBearerModInd rab_do_modify_items := ?,
		     template E_RABNotToBeModifiedListBearerModInd rab_no_modify_items := *) := {
	initiatingMessage := {
		procedureCode := S1AP_Constants.id_E_RABModificationIndication,
		criticality := reject,
		value_ := {
			e_RABModificationIndication := f_tr_S1AP_RABModifyInd(mme_id, enb_id,
									      rab_do_modify_items,
									      rab_no_modify_items)
		}
	}
}

private function
f_ts_S1AP_RABModifyInd(template (value) MME_UE_S1AP_ID mme_id,
		       template (value) ENB_UE_S1AP_ID enb_id,
		       template (value) E_RABToBeModifiedListBearerModInd rab_do_modify_items,
		       template (omit) E_RABNotToBeModifiedListBearerModInd rab_no_modify_items)
return template (value) E_RABModificationIndication
{
	var template (value) E_RABModificationIndication ind := {
		protocolIEs := {
			{
				id := S1AP_Constants.id_MME_UE_S1AP_ID,
				criticality := reject,
				value_ := { MME_UE_S1AP_ID := mme_id }
			}, {
				id := S1AP_Constants.id_eNB_UE_S1AP_ID,
				criticality := reject,
				value_ := { ENB_UE_S1AP_ID := enb_id }
			}, {
				id := S1AP_Constants.id_E_RABToBeModifiedListBearerModInd,
				criticality := reject,
				value_ := { e_RABToBeModifiedListBearerModInd := rab_do_modify_items }
			}
		}
	};

	var integer idx := lengthof(ind.protocolIEs);
	if (isvalue(rab_no_modify_items)) {
		ind.protocolIEs[idx] := {
			id := S1AP_Constants.id_E_RABNotToBeModifiedListBearerModInd,
			criticality := reject,
			value_ := { e_RABNotToBeModifiedListBearerModInd := rab_no_modify_items }
		};
		idx := idx + 1;
	}

	return ind;
}
private function
f_tr_S1AP_RABModifyInd(template (present) MME_UE_S1AP_ID mme_id,
		       template (present) ENB_UE_S1AP_ID enb_id,
		       template (present) E_RABToBeModifiedListBearerModInd rab_do_modify_items,
		       template E_RABNotToBeModifiedListBearerModInd rab_no_modify_items)
return template E_RABModificationIndication
{
	var template E_RABModificationIndication ind := {
		protocolIEs := {
			{
				id := S1AP_Constants.id_MME_UE_S1AP_ID,
				criticality := reject,
				value_ := { MME_UE_S1AP_ID := mme_id }
			}, {
				id := S1AP_Constants.id_eNB_UE_S1AP_ID,
				criticality := reject,
				value_ := { ENB_UE_S1AP_ID := enb_id }
			}, {
				id := S1AP_Constants.id_E_RABToBeModifiedListBearerModInd,
				criticality := reject,
				value_ := { e_RABToBeModifiedListBearerModInd := rab_do_modify_items }
			}
		}
	};

	var integer idx := lengthof(ind.protocolIEs);
	if (ispresent(rab_no_modify_items)) {
		ind.protocolIEs[idx] := {
			id := S1AP_Constants.id_E_RABNotToBeModifiedListBearerModInd,
			criticality := reject,
			value_ := { e_RABNotToBeModifiedListBearerModInd := rab_no_modify_items }
		};
		idx := idx + 1;
	}

	/* ignore the remaining IEs */
	ind.protocolIEs[idx] := *;

	return ind;
}

template (value) E_RABToBeModifiedListBearerModInd
ts_E_RABToBeModifiedListBearerModInd(template (value) E_RABToBeModifiedItemBearerModInd it) := {
	{
		id := S1AP_Constants.id_E_RABToBeModifiedItemBearerModInd,
		criticality := reject,
		value_ := { e_RABToBeModifiedItemBearerModInd := it }
	}
}
template (present) E_RABToBeModifiedListBearerModInd
tr_E_RABToBeModifiedListBearerModInd(template (present) E_RABToBeModifiedItemBearerModInd it := ?) := {
	{
		id := S1AP_Constants.id_E_RABToBeModifiedItemBearerModInd,
		criticality := reject,
		value_ := { e_RABToBeModifiedItemBearerModInd := it }
	}
}

template (value) E_RABToBeModifiedItemBearerModInd
ts_E_RABToBeModifiedItemBearerModInd(template (value) E_RAB_ID rab_id,
				     template (value) TransportLayerAddress tla,
				     template (value) GTP_TEID gtp_teid) := {
	e_RAB_ID := rab_id,
	transportLayerAddress := tla,
	dL_GTP_TEID := gtp_teid,
	iE_Extensions := omit
}
template (present) E_RABToBeModifiedItemBearerModInd
tr_E_RABToBeModifiedItemBearerModInd(template (present) E_RAB_ID rab_id,
				     template (present) TransportLayerAddress tla,
				     template (present) GTP_TEID gtp_teid) := {
	e_RAB_ID := rab_id,
	transportLayerAddress := tla,
	dL_GTP_TEID := gtp_teid,
	iE_Extensions := *
}

template (value) E_RABNotToBeModifiedListBearerModInd
ts_E_RABNotToBeModifiedListBearerModInd(template (value) E_RABNotToBeModifiedItemBearerModInd it) := {
	{
		id := S1AP_Constants.id_E_RABNotToBeModifiedItemBearerModInd,
		criticality := reject,
		value_ := { e_RABNotToBeModifiedItemBearerModInd := it }
	}
}
template (present) E_RABNotToBeModifiedListBearerModInd
tr_E_RABNotToBeModifiedListBearerModInd(template (present) E_RABNotToBeModifiedItemBearerModInd it := ?) := {
	{
		id := S1AP_Constants.id_E_RABNotToBeModifiedItemBearerModInd,
		criticality := reject,
		value_ := { e_RABNotToBeModifiedItemBearerModInd := it }
	}
}

template (value) E_RABNotToBeModifiedItemBearerModInd
ts_E_RABNotToBeModifiedItemBearerModInd(template (value) E_RAB_ID rab_id,
					template (value) TransportLayerAddress tla,
					template (value) GTP_TEID gtp_teid) := {
	e_RAB_ID := rab_id,
	transportLayerAddress := tla,
	dL_GTP_TEID := gtp_teid,
	iE_Extensions := omit
}
template (present) E_RABNotToBeModifiedItemBearerModInd
tr_E_RABNotToBeModifiedItemBearerModInd(template (present) E_RAB_ID rab_id,
					template (present) TransportLayerAddress tla,
					template (present) GTP_TEID gtp_teid) := {
	e_RAB_ID := rab_id,
	transportLayerAddress := tla,
	dL_GTP_TEID := gtp_teid,
	iE_Extensions := *
}

/* 9.1.3.9 E-RAB MODIFICATION CONFIRMATION */
template (value) S1AP_PDU
ts_S1AP_RABModifyCnf(template (value) MME_UE_S1AP_ID mme_id,
		     template (value) ENB_UE_S1AP_ID enb_id,
		     template (omit) E_RABModifyListBearerModConf rab_modified_items := omit,
		     template (omit) E_RABList rab_failed_items := omit,
		     template (omit) E_RABList rab_release_items := omit) := {
	successfulOutcome := {
		procedureCode := S1AP_Constants.id_E_RABModificationIndication,
		criticality := reject,
		value_ := {
			e_RABModificationConfirm := f_ts_S1AP_RABModifyCnf(mme_id, enb_id,
									   rab_modified_items,
									   rab_failed_items,
									   rab_release_items)
		}
	}
}
template (present) S1AP_PDU
tr_S1AP_RABModifyCnf(template (present) MME_UE_S1AP_ID mme_id := ?,
		     template (present) ENB_UE_S1AP_ID enb_id := ?,
		     template E_RABModifyListBearerModConf rab_modified_items := *,
		     template E_RABList rab_failed_items := *,
		     template E_RABList rab_release_items := *) := {
	successfulOutcome := {
		procedureCode := S1AP_Constants.id_E_RABModificationIndication,
		criticality := reject,
		value_ := {
			e_RABModificationConfirm := f_tr_S1AP_RABModifyCnf(mme_id, enb_id,
									   rab_modified_items,
									   rab_failed_items,
									   rab_release_items)
		}
	}
}

private function
f_ts_S1AP_RABModifyCnf(template (value) MME_UE_S1AP_ID mme_id,
		       template (value) ENB_UE_S1AP_ID enb_id,
		       template (omit) E_RABModifyListBearerModConf rab_modified_items,
		       template (omit) E_RABList rab_failed_items,
		       template (omit) E_RABList rab_release_items)
return template (value) E_RABModificationConfirm
{
	var template (value) E_RABModificationConfirm cnf := {
		protocolIEs := {
			{
				id := S1AP_Constants.id_MME_UE_S1AP_ID,
				criticality := ignore,
				value_ := { MME_UE_S1AP_ID := mme_id }
			}, {
				id := S1AP_Constants.id_eNB_UE_S1AP_ID,
				criticality := ignore,
				value_ := { ENB_UE_S1AP_ID := enb_id }
			}
		}
	};

	var integer idx := lengthof(cnf.protocolIEs);
	if (isvalue(rab_modified_items)) {
		cnf.protocolIEs[idx] := {
			id := S1AP_Constants.id_E_RABModifyListBearerModConf,
			criticality := ignore,
			value_ := { e_RABModifyListBearerModConf := rab_modified_items }
		};
		idx := idx + 1;
	}
	if (isvalue(rab_failed_items)) {
		cnf.protocolIEs[idx] := {
			id := S1AP_Constants.id_E_RABFailedToModifyListBearerModConf,
			criticality := ignore,
			value_ := { e_RABList := rab_failed_items }
		};
		idx := idx + 1;
	}
	if (isvalue(rab_release_items)) {
		cnf.protocolIEs[idx] := {
			id := S1AP_Constants.id_E_RABToBeReleasedListBearerModConf,
			criticality := ignore,
			value_ := { e_RABList := rab_release_items }
		};
		idx := idx + 1;
	}

	return cnf;
}
private function
f_tr_S1AP_RABModifyCnf(template (present) MME_UE_S1AP_ID mme_id,
		       template (present) ENB_UE_S1AP_ID enb_id,
		       template E_RABModifyListBearerModConf rab_modified_items,
		       template E_RABList rab_failed_items,
		       template E_RABList rab_release_items)
return template E_RABModificationConfirm
{
	var template E_RABModificationConfirm cnf := {
		protocolIEs := {
			{
				id := S1AP_Constants.id_MME_UE_S1AP_ID,
				criticality := ignore,
				value_ := { MME_UE_S1AP_ID := mme_id }
			}, {
				id := S1AP_Constants.id_eNB_UE_S1AP_ID,
				criticality := ignore,
				value_ := { ENB_UE_S1AP_ID := enb_id }
			}
		}
	};

	var integer idx := lengthof(cnf.protocolIEs);
	if (ispresent(rab_modified_items)) {
		cnf.protocolIEs[idx] := {
			id := S1AP_Constants.id_E_RABModifyListBearerModConf,
			criticality := ignore,
			value_ := { e_RABModifyListBearerModConf := rab_modified_items }
		};
		idx := idx + 1;
	} else if (istemplatekind(rab_modified_items, "*")) {
		cnf.protocolIEs[idx] := *;
		idx := idx + 1;
	}

	if (ispresent(rab_failed_items)) {
		cnf.protocolIEs[idx] := {
			id := S1AP_Constants.id_E_RABFailedToModifyListBearerModConf,
			criticality := ignore,
			value_ := { e_RABList := rab_failed_items }
		};
		idx := idx + 1;
	} else if (istemplatekind(rab_failed_items, "*")) {
		cnf.protocolIEs[idx] := *;
		idx := idx + 1;
	}

	if (ispresent(rab_release_items)) {
		cnf.protocolIEs[idx] := {
			id := S1AP_Constants.id_E_RABToBeReleasedListBearerModConf,
			criticality := ignore,
			value_ := { e_RABList := rab_release_items }
		};
		idx := idx + 1;
	}

	/* ignore the remaining IEs */
	cnf.protocolIEs[idx] := *;

	return cnf;
}

template (value) E_RABModifyListBearerModConf
ts_E_RABModifyListBearerModConf(template (value) E_RABModifyItemBearerModConf it) := {
	{
		id := S1AP_Constants.id_E_RABModifyItemBearerModConf,
		criticality := ignore,
		value_ := { e_RABModifyItemBearerModConf := it }
	}
}
template (present) E_RABModifyListBearerModConf
tr_E_RABModifyListBearerModConf(template (present) E_RABModifyItemBearerModConf it := ?) := {
	{
		id := S1AP_Constants.id_E_RABModifyItemBearerModConf,
		criticality := ignore,
		value_ := { e_RABModifyItemBearerModConf := it }
	}
}

template (value) E_RABModifyItemBearerModConf
ts_E_RABModifyItemBearerModConf(template (value) E_RAB_ID rab_id) := {
	e_RAB_ID := rab_id,
	iE_Extensions := omit
}
template (present) E_RABModifyItemBearerModConf
tr_E_RABModifyItemBearerModConf(template (present) E_RAB_ID rab_id) := {
	e_RAB_ID := rab_id,
	iE_Extensions := *
}

}