/* EPC (Evolved Packet Core) NAS (Non-Access Stratum) 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 NAS_Templates {

import from General_Types all;
import from NAS_EPS_Types all;

template (value) PDU_NAS_EPS
ts_NAS_SM(template (value) EPS_SessionManagement sm) := {
	protocolDiscriminator := '0010'B,
	ePS_messages := {
		ePS_SessionManagement := sm
	}
}
template (present) PDU_NAS_EPS
tr_NAS_SM(template (present) EPS_SessionManagement sm) := {
	protocolDiscriminator := '0010'B,
	ePS_messages := {
		ePS_SessionManagement := sm
	}
}

template (value) PDU_NAS_EPS
ts_NAS_MM(template (value) EPS_MobilityManagement mm) := {
	protocolDiscriminator := c_EPS_NAS_PD_EMM,
	ePS_messages := {
		ePS_MobilityManagement := mm
	}
}
template (present) PDU_NAS_EPS
tr_NAS_MM(template (present) EPS_MobilityManagement mm) := {
	protocolDiscriminator := c_EPS_NAS_PD_EMM,
	ePS_messages := {
		ePS_MobilityManagement := mm
	}
}

const BIT4 c_EPS_SEC_NONE := '0000'B;
const BIT4 c_EPS_NAS_PD_EMM := '0111'B;
const BIT4 c_EPS_NAS_PD_ESM := '0010'B;

private template (value) ESM_MessageContainerLVE
ts_NAS_EsmMsgContLVE(template (value) octetstring inp) := {
	lengthIndicator := 0,
	content := inp
}
private template (present) ESM_MessageContainerLVE
tr_NAS_EsmMsgContLVE(template (present) octetstring inp) := {
	lengthIndicator := ?,
	content := inp
}

private template (value) MobileIdentityLV
ts_NAS_MobileIdLV(template (value) MobileIdentityV mid) := {
	lengthIndicator := 0,
	mobileIdentityV := mid
}
private template (present) MobileIdentityLV
tr_NAS_MobileIdLV(template (present) MobileIdentityV mid) := {
	lengthIndicator := ?,
	mobileIdentityV := mid
}

private function f_enc_IMSI_NAS(hexstring digits) return IMSI {
	var IMSI l3;
	var integer len := lengthof(digits);
	if (len rem 2 == 1) {	/* modulo remainder */
		l3.oddevenIndicator := '1'B;
		l3.fillerDigit := omit;
	} else {
		l3.oddevenIndicator := '0'B;
		l3.fillerDigit := '1111'B;
	}
	l3.digits := digits;
	return l3;
}

private function f_enc_IMEI_NAS(hexstring digits) return IMEI {
	var IMEI l3;
	var integer len := lengthof(digits);
	if (len rem 2 == 1) {	/* modulo remainder */
		l3.oddevenIndicator := '1'B;
	} else {
		l3.oddevenIndicator := '0'B;
	}
	l3.digits := digits;
	return l3;
}

private function f_enc_IMEI_SV(hexstring digits) return IMEI_SV {
	var IMEI_SV l3;
	var integer len := lengthof(digits);
	if (len rem 2 == 1) {	/* modulo remainder */
		l3.oddevenIndicator := '1'B;
	} else {
		l3.oddevenIndicator := '0'B;
	}
	l3.digits := digits;
	l3.fillerDigit := '1111'B;
	return l3;
}

template (value) GUTI ts_NAS_GUTI(hexstring mcc_mnc, OCT2 mmegi, OCT1 mmec, OCT4 tmsi) := {
	oddevenIndicator := '0'B,
	spare := '1111'B,
	/* mcc_mnc specified in format 262f42 */
	mccDigit1 := mcc_mnc[0],
	mccDigit2 := mcc_mnc[1],
	mccDigit3 := mcc_mnc[2],
	mncDigit3 := mcc_mnc[5],
	mncDigit1 := mcc_mnc[3],
	mncDigit2 := mcc_mnc[4],
	mMEGI := mmegi,
	mMEC := mmec,
	mTMSI := tmsi
}

template (value) EPS_MobileIdentityV
ts_NAS_MobileId_IMSI(hexstring imsi) := {
	typeOfIdentity := '001'B,
	oddEvenInd_identity := {
		imsi := f_enc_IMSI_NAS(imsi)
	}
}

template (value) EPS_MobileIdentityV
ts_NAS_MobileId_IMEI(hexstring imei) := {
	typeOfIdentity := '011'B,
	oddEvenInd_identity := {
		imei := f_enc_IMEI_NAS(imei)
	}
}

template (value) EPS_MobileIdentityV
ts_NAS_MobileId_GUTI(hexstring mcc_mnc, OCT2 mmegi, OCT1 mmec, OCT4 tmsi) := {
	typeOfIdentity := '110'B,
	oddEvenInd_identity := {
		guti := ts_NAS_GUTI(mcc_mnc, mmegi, mmec, tmsi)
	}
}

template (value) PDU_NAS_EPS
ts_NAS_EMM_SecurityProtected(BIT4 sec_hdr_t, integer seq_nr, octetstring inner_nas) := {
	protocolDiscriminator := c_EPS_NAS_PD_EMM,
	ePS_messages := {
		ePS_MobilityManagement := {
			pDU_NAS_EPS_SecurityProtectedNASMessage := {
				securityHeaderType := sec_hdr_t,
				messageAuthenticationCode := '00000000'O,
				sequenceNumber := seq_nr,
				nAS_Message := inner_nas
			}
		}
	}
}
template (present) PDU_NAS_EPS
tr_NAS_EMM_SecurityProtected := {
	protocolDiscriminator := c_EPS_NAS_PD_EMM,
	ePS_messages := {
		ePS_MobilityManagement := {
			pDU_NAS_EPS_SecurityProtectedNASMessage := ?
		}
	}
}

const BIT3 NAS_PDN_T_IPv4 := '001'B;
const BIT3 NAS_PDN_T_IPv6 := '010'B;
const BIT3 NAS_PDN_T_IPv4v6 := '011'B;
const BIT3 NAS_PDN_T_NonIP := '101'B;


/*********************************************************************************
 * Mobility Management
 *********************************************************************************/

/* 8.2.1 Attach Accept */
template (value) PDU_NAS_EPS
ts_NAS_AttachAccept(template (value) EPS_AttachResultV result,
		    template (value) GPRSTimerV t3412,
		    template (value) TAI_Lists tai_lists,
		    template (value) octetstring esm_enc) := {
	protocolDiscriminator := c_EPS_NAS_PD_EMM,
	ePS_messages := {
		ePS_MobilityManagement := {
			pDU_NAS_EPS_AttachAccept := {
				securityHeaderType := c_EPS_SEC_NONE,
				messageType := '01000010'B,
				ePS_AttachResult := result,
				spare := '0000'B,
				t3412 := t3412,
				tAI_List := {
					lengthIndicator := 0,
					trackingAreaIdentityLists := tai_lists
				},
				eSM_MessageContainer := ts_NAS_EsmMsgContLVE(esm_enc),
				gUTI := omit,
				locationAreaIdentification := omit,
				msIdentity := omit,
				eMMCause := omit,
				t3402 := omit,
				t3423 := omit,
				equivalentPLMNs := omit,
				emergencyNumberList := omit,
				ePS_NetworkFeatureSupport := omit,
				additionalUpdateResult := omit,
				t3412_Extended := omit,
				t3324 := omit,
				extendedDRXParameters := omit,
				dNCID := omit,
				sMS_ServiceStatus := omit,
				non3GPP_NW_ProvidedPolicies := omit,
				t3448 := omit,
				networkPolicy := omit,
				t3447 := omit,
				extendedEmergencyNumberList := omit
			}
		}
	}
}
template (present) PDU_NAS_EPS
tr_NAS_AttachAccept(template (present) EPS_AttachResultV result := ?,
		    template (present) GPRSTimerV t3412 := ?,
		    template (present) TAI_Lists tai_lists := ?,
		    template (present) octetstring esm_enc := ?) := {
	protocolDiscriminator := c_EPS_NAS_PD_EMM,
	ePS_messages := {
		ePS_MobilityManagement := {
			pDU_NAS_EPS_AttachAccept := {
				securityHeaderType := c_EPS_SEC_NONE,
				messageType := '01000010'B,
				ePS_AttachResult := result,
				spare := ?,
				t3412 := t3412,
				tAI_List := {
					lengthIndicator := ?,
					trackingAreaIdentityLists := tai_lists
				},
				eSM_MessageContainer := tr_NAS_EsmMsgContLVE(esm_enc),
				gUTI := *,
				locationAreaIdentification := *,
				msIdentity := *,
				eMMCause := *,
				t3402 := *,
				t3423 := *,
				equivalentPLMNs := *,
				emergencyNumberList := *,
				ePS_NetworkFeatureSupport := *,
				additionalUpdateResult := *,
				t3412_Extended := *,
				t3324 := *,
				extendedDRXParameters := *,
				dNCID := *,
				sMS_ServiceStatus := *,
				non3GPP_NW_ProvidedPolicies := *,
				t3448 := *,
				networkPolicy := *,
				t3447 := *,
				extendedEmergencyNumberList := *
			}
		}
	}
}


/* 8.2.2 Attach Complete */
template (value) PDU_NAS_EPS
ts_NAS_AttachComplete(template (value) octetstring esm_enc) := {
	protocolDiscriminator := c_EPS_NAS_PD_EMM,
	ePS_messages := {
		ePS_MobilityManagement := {
			pDU_NAS_EPS_AttachComplete := {
				securityHeaderType := c_EPS_SEC_NONE,
				messageType := '01000011'B,
				eSM_MessageContainer := ts_NAS_EsmMsgContLVE(esm_enc)
			}
		}
	}
}
template (present) PDU_NAS_EPS
tr_NAS_AttachComplete(template (present) octetstring esm_enc := ?) := {
	protocolDiscriminator := c_EPS_NAS_PD_EMM,
	ePS_messages := {
		ePS_MobilityManagement := {
			pDU_NAS_EPS_AttachComplete := {
				securityHeaderType := c_EPS_SEC_NONE,
				messageType := '01000011'B,
				eSM_MessageContainer := tr_NAS_EsmMsgContLVE(esm_enc)
			}
		}
	}
}


/* 8.2.3 Attach Reject */
template (value) PDU_NAS_EPS
ts_NAS_AttachReject(template (value) EMM_CauseV cause) := {
	protocolDiscriminator := c_EPS_NAS_PD_EMM,
	ePS_messages := {
		ePS_MobilityManagement := {
			pDU_NAS_EPS_AttachReject := {
				securityHeaderType := c_EPS_SEC_NONE,
				messageType := '01000100'B,
				emmCause := cause,
				eSM_MessageContainer := omit,
				t3346 := omit,
				t3402 := omit,
				extendedEmmCause := omit
			}
		}
	}
}
template (present) PDU_NAS_EPS
tr_NAS_AttachReject(template (present) EMM_CauseV cause := ?) := {
	protocolDiscriminator := c_EPS_NAS_PD_EMM,
	ePS_messages := {
		ePS_MobilityManagement := {
			pDU_NAS_EPS_AttachReject := {
				securityHeaderType := c_EPS_SEC_NONE,
				messageType := '01000100'B,
				emmCause := cause,
				eSM_MessageContainer := omit,
				t3346 := omit,
				t3402 := omit,
				extendedEmmCause := omit
			}
		}
	}
}

/* 8.2.4 Attach Request */
template (value) PDU_NAS_EPS
ts_NAS_AttachRequest(template (value) BIT3 att_type,
		     template (value) BIT3 kset_id,
		     template (value) EPS_MobileIdentityV mobile_id,
		     template (value) UENetworkCapabilityV ue_net_cap,
		     template (value) octetstring esm_enc) := {
	protocolDiscriminator := c_EPS_NAS_PD_EMM,
	ePS_messages := {
		ePS_MobilityManagement := {
			pDU_NAS_EPS_AttachRequest := {
				securityHeaderType := c_EPS_SEC_NONE,
				messageType := '01000001'B,
				ePS_attachType := {
					typeOfAttach := att_type,
					spare := '0'B
				},
				nasKeySetId := {
					identifier := kset_id,
					tSC := '1'B
				},
				ePSMobileId := {
					lengthIndicator := 0,
					ePS_MobileIdentity := mobile_id
				},
				uENetworkCapability := {
					lengthIndicator := 0,
					uENetworkCapabilityV := ue_net_cap
				},
				eSM_MessageContainer := ts_NAS_EsmMsgContLVE(esm_enc),
				old_P_TMSISignature := omit,
				additionalGUTI := omit,
				lastVisitedRegisteredTAI := omit,
				dRXParameter := omit,
				mSNetworkCapability := omit,
				oldLocationAreaIdentification := omit,
				tMSIStatusTV := omit,
				mobileStationClassmark2 := omit,
				mobileStationClassmark3 := omit,
				supportedCodecList := omit,
				additionalUpdateType := omit,
				voiceDomainPrefandUEsettings := omit,
				deviceProperties := omit,
				oldGUTI_Type := omit,
				mS_NetworkFeatureSupport := omit,
				tMSIBasedNRIContainer := omit,
				t3324 := omit,
				t3412_Extended := omit,
				extendedDRXParameters := omit,
				uEAdditionalSecurityCapability := omit
			}
		}
	}
}
template (present) PDU_NAS_EPS
tr_NAS_AttachRequest(template (present) BIT3 att_type := ?,
		    template (present) BIT3 kset_id := ?,
		    template (present) EPS_MobileIdentityV mobile_id := ?,
		    template (present) UENetworkCapabilityV ue_net_cap := ?,
		    template (present) octetstring esm_enc := ?) := {
	protocolDiscriminator := c_EPS_NAS_PD_EMM,
	ePS_messages := {
		ePS_MobilityManagement := {
			pDU_NAS_EPS_AttachRequest := {
				securityHeaderType := ?,
				messageType := '01000001'B,
				ePS_attachType := {
					typeOfAttach := att_type,
					spare := ?
				},
				nasKeySetId := {
					identifier := kset_id,
					tSC := ?
				},
				ePSMobileId := {
					lengthIndicator := ?,
					ePS_MobileIdentity := mobile_id
				},
				uENetworkCapability := {
					lengthIndicator := ?,
					uENetworkCapabilityV := ue_net_cap
				},
				eSM_MessageContainer := tr_NAS_EsmMsgContLVE(esm_enc),
				old_P_TMSISignature := *,
				additionalGUTI := *,
				lastVisitedRegisteredTAI := *,
				dRXParameter := *,
				mSNetworkCapability := *,
				oldLocationAreaIdentification := *,
				tMSIStatusTV := *,
				mobileStationClassmark2 := *,
				mobileStationClassmark3 := *,
				supportedCodecList := *,
				additionalUpdateType := *,
				voiceDomainPrefandUEsettings := *,
				deviceProperties := *,
				oldGUTI_Type := *,
				mS_NetworkFeatureSupport := *,
				tMSIBasedNRIContainer := *,
				t3324 := *,
				t3412_Extended := *,
				extendedDRXParameters := *,
				uEAdditionalSecurityCapability := *
			}
		}
	}
}


/* 8.2.5 Authentication Failure */
template (value) PDU_NAS_EPS
ts_NAS_AuthFail(template (value) EMM_CauseV cause /* template (omit) OCT14 auth_fail_par */) := {
	protocolDiscriminator := c_EPS_NAS_PD_EMM,
	ePS_messages := {
		ePS_MobilityManagement := {
			pDU_NAS_EPS_AuthenticationFailure := {
				securityHeaderType := c_EPS_SEC_NONE,
				messageType := '01011100'B,
				emmCause := cause,
				authenticationFailureParameter := omit
			}
		}
	}
}
template (value) PDU_NAS_EPS
ts_NAS_AuthFail_par(template (value) EMM_CauseV cause,
		    template (value) OCT14 auth_fail_par) := {
	protocolDiscriminator := c_EPS_NAS_PD_EMM,
	ePS_messages := {
		ePS_MobilityManagement := {
			pDU_NAS_EPS_AuthenticationFailure := {
				securityHeaderType := c_EPS_SEC_NONE,
				messageType := '01011100'B,
				emmCause := cause,
				authenticationFailureParameter := {
					elementIdentifier := '30'O,
					lengthIndicator := lengthof(auth_fail_par),
					authenticationFailureParameter := auth_fail_par
				}
			}
		}
	}
}

/* 8.2.6 Authentication Reject */
template (value) PDU_NAS_EPS
ts_NAS_AuthRej := {
	protocolDiscriminator := c_EPS_NAS_PD_EMM,
	ePS_messages := {
		ePS_MobilityManagement := {
			pDU_NAS_EPS_AuthenticationReject := {
				securityHeaderType := c_EPS_SEC_NONE,
				messageType := '01010100'B
			}
		}
	}
}
template (present) PDU_NAS_EPS
tr_NAS_AuthRej := {
	protocolDiscriminator := c_EPS_NAS_PD_EMM,
	ePS_messages := {
		ePS_MobilityManagement := {
			pDU_NAS_EPS_AuthenticationReject := {
				securityHeaderType := ?,
				messageType := '01010100'B
			}
		}
	}
}

/* 8.2.7 Authentication Request */
template (value) PDU_NAS_EPS
ts_NAS_AuthReq(template (value) NAS_KeySetIdentifierV kset_id,
	       OCT16 rand, OCT16 autn) := {
	protocolDiscriminator := c_EPS_NAS_PD_EMM,
	ePS_messages := {
		ePS_MobilityManagement := {
			pDU_NAS_EPS_AuthenticationRequest := {
				securityHeaderType := c_EPS_SEC_NONE,
				messageType := '01010010'B,
				nasKeySetId := kset_id,
				spare := '0000'B,
				authenticationParameterRAND := {
					rAND := rand
				},
				authenticationParameterAUTN := {
					lengthIndicator := lengthof(autn),
					aUTN := autn
				}
			}
		}
	}
}
template (present) PDU_NAS_EPS
tr_NAS_AuthReq(template (present) NAS_KeySetIdentifierV kset_id := ?,
	       template (present) OCT16 rand := ?,
	       template (present) OCT16 autn := ?) := {
	protocolDiscriminator := c_EPS_NAS_PD_EMM,
	ePS_messages := {
		ePS_MobilityManagement := {
			pDU_NAS_EPS_AuthenticationRequest := {
				securityHeaderType := ?,
				messageType := '01010010'B,
				nasKeySetId := kset_id,
				spare := '0000'B,
				authenticationParameterRAND := {
					rAND := rand
				},
				authenticationParameterAUTN := {
					lengthIndicator := ?,
					aUTN := autn
				}
			}
		}
	}
}

/* 8.2.8 Authentication Response */
template (value) PDU_NAS_EPS
ts_NAS_AuthResp(octetstring res) := {
	protocolDiscriminator := c_EPS_NAS_PD_EMM,
	ePS_messages := {
		ePS_MobilityManagement := {
			pDU_NAS_EPS_AuthenticationResponse := {
				securityHeaderType := c_EPS_SEC_NONE,
				messageType := '01010011'B,
				authenticationResponseParameter := {
					lengthIndicator := lengthof(res),
					authenticationResponseParameter := {
						rES := res
					}
				}
			}
		}
	}
}
template (present) PDU_NAS_EPS
tr_NAS_AuthResp(template OCT16 res := ?) := {
	protocolDiscriminator := c_EPS_NAS_PD_EMM,
	ePS_messages := {
		ePS_MobilityManagement := {
			pDU_NAS_EPS_AuthenticationResponse := {
				securityHeaderType := ?,
				messageType := '01010011'B,
				authenticationResponseParameter := {
					lengthIndicator := ?,
					authenticationResponseParameter := {
						rES := res
					}
				}
			}
		}
	}
}

/* 8.2.18 Identity Request */
template (value) PDU_NAS_EPS
ts_NAS_IdentityReq(template (value) IdentityType2V id_type) := {
	protocolDiscriminator := c_EPS_NAS_PD_EMM,
	ePS_messages := {
		ePS_MobilityManagement := {
			pDU_NAS_EPS_IdentityRequest := {
				securityHeaderType := c_EPS_SEC_NONE,
				messageType := '01010101'B,
				identityType := id_type,
				spareHalfOctet := '0000'B
			}
		}
	}
}
template (present) PDU_NAS_EPS
tr_NAS_IdentityReq(template (present) IdentityType2V id_type := ?) := {
	protocolDiscriminator := c_EPS_NAS_PD_EMM,
	ePS_messages := {
		ePS_MobilityManagement := {
			pDU_NAS_EPS_IdentityRequest := {
				securityHeaderType := c_EPS_SEC_NONE,
				messageType := '01010101'B,
				identityType := id_type,
				spareHalfOctet := ?
			}
		}
	}
}

/* 8.2.19 Identity Response */
template (value) PDU_NAS_EPS
ts_NAS_IdentityResp(template (value) MobileIdentityV mobile_id) := {
	protocolDiscriminator := c_EPS_NAS_PD_EMM,
	ePS_messages := {
		ePS_MobilityManagement := {
			pDU_NAS_EPS_IdentityResponse := {
				securityHeaderType := c_EPS_SEC_NONE,
				messageType := '01010110'B,
				mobileIdentity := ts_NAS_MobileIdLV(mobile_id)
			}
		}
	}
}
template (present) PDU_NAS_EPS
tr_NAS_IdentityResp(template (present) MobileIdentityV mobile_id := ?) := {
	protocolDiscriminator := c_EPS_NAS_PD_EMM,
	ePS_messages := {
		ePS_MobilityManagement := {
			pDU_NAS_EPS_IdentityResponse := {
				securityHeaderType := c_EPS_SEC_NONE,
				messageType := '01010110'B,
				mobileIdentity := tr_NAS_MobileIdLV(mobile_id)
			}
		}
	}
}




/* 8.2.20 Security Mode Command */
template (value) PDU_NAS_EPS
ts_NAS_SecModeCmd(template (value) NAS_SecurityAlgorithmsV alg,
		  template (value) NAS_KeySetIdentifierV kset_id,
		  template (value) UESecurityCapabilityLV ue_sec_cap) := {
	protocolDiscriminator := c_EPS_NAS_PD_EMM,
	ePS_messages := {
		ePS_MobilityManagement := {
			pDU_NAS_EPS_SecurityModeCommand := {
				securityHeaderType := c_EPS_SEC_NONE,
				messageType := '01011101'B,
				selected_NAS_SecurityAlgorithms := alg,
				nasKeySetId := kset_id,
				spareHalfOctet := '0000'B,
				replayed_UE_SecurityCapability := ue_sec_cap,
				iMEISV_Request := omit,
				replayedNonceUE := omit,
				nonceMME := omit,
				hashMME := omit,
				uEAdditionalSecurityCapability := omit
			}
		}
	}
}
template (present) PDU_NAS_EPS
tr_NAS_SecModeCmd(template (present) NAS_SecurityAlgorithmsV alg := ?,
		  template (present) NAS_KeySetIdentifierV kset_id := ?,
		  template (present) UESecurityCapabilityLV ue_sec_cap := ?) := {
	protocolDiscriminator := c_EPS_NAS_PD_EMM,
	ePS_messages := {
		ePS_MobilityManagement := {
			pDU_NAS_EPS_SecurityModeCommand := {
				securityHeaderType := c_EPS_SEC_NONE,
				messageType := '01011101'B,
				selected_NAS_SecurityAlgorithms := alg,
				nasKeySetId := kset_id,
				spareHalfOctet := ?,
				replayed_UE_SecurityCapability := ue_sec_cap,
				iMEISV_Request := *,
				replayedNonceUE := *,
				nonceMME := *,
				hashMME := *,
				uEAdditionalSecurityCapability := *
			}
		}
	}
}

/* 8.2.21 Security Mode Complete */
template (value) PDU_NAS_EPS
ts_NAS_SecModeCmpl := {
	protocolDiscriminator := c_EPS_NAS_PD_EMM,
	ePS_messages := {
		ePS_MobilityManagement := {
			pDU_NAS_EPS_SecurityModeComplete := {
				securityHeaderType := c_EPS_SEC_NONE,
				messageType := '01011110'B,
				iMEISV := omit,
				replayedNASMessageContainer := omit
			}
		}
	}
}
template (present) PDU_NAS_EPS
tr_NAS_SecModeCmpl := {
	protocolDiscriminator := c_EPS_NAS_PD_EMM,
	ePS_messages := {
		ePS_MobilityManagement := {
			pDU_NAS_EPS_SecurityModeComplete := {
				securityHeaderType := c_EPS_SEC_NONE,
				messageType := '01011110'B,
				iMEISV := *,
				replayedNASMessageContainer := *
			}
		}
	}
}

/*********************************************************************************
 * Session Management
 *********************************************************************************/

/* 9.9.4.11 - 10.5.6.3/24.008 */
private function ts_NAS_PCO_TLV(template (omit) ProtocolConfigOptionsV pco)
return template (omit) ProtocolConfigOptionsTLV {
	var template (value) ProtocolConfigOptionsTLV ret;
	if (istemplatekind(pco, "omit")) {
		return omit;
	}
	ret := {
		elementIdentifier := '27'O,
		protocolConfigOptions := {
			lengthIndicator := 0,
			protocolConfigOptionsV := pco
		}
	}
	return ret;
}
private function tr_NAS_PCO_TLV(template ProtocolConfigOptionsV pco := ?)
return template ProtocolConfigOptionsTLV {
	var template ProtocolConfigOptionsTLV ret := {
		elementIdentifier := '27'O,
		protocolConfigOptions := {
			lengthIndicator := ?,
			protocolConfigOptionsV := pco
		}
	}
	if (istemplatekind(pco, "omit")) {
		return omit;
	} else if (istemplatekind(pco, "*")) {
		return *;
	} else {
		return ret;
	}
}



/* 8.3.20 PDN Connectivity Request */
template (value) PDU_NAS_EPS
ts_NAS_PdnConnReq(template (value) BIT4 bearer_id,
		  template (value) BIT8 proc_tid,
		  template (value) BIT3 pdn_type,
		  template (value) BIT3 req_type) := {
	protocolDiscriminator := c_EPS_NAS_PD_ESM,
	ePS_messages := {
		ePS_SessionManagement := {
			pDU_NAS_EPS_PDN_ConnectivityRequest := {
				ePSBearerIdentity := bearer_id,
				procedureTransactionIdentifier := proc_tid,
				messageType := '11010000'B,
				requestType := {
					requestTypeValue := req_type,
					spare := '0'B
				},
				pDN_Type := {
					pDN_TypeValue := pdn_type,
					spare := '0'B
				},
				eSM_InformationTransferFlag := omit,
				accessPointName := omit,
				protocolConfigOptions := omit,
				deviceProperties := omit,
				nBIFOMContainer := omit,
				headerCompressinConfiguration := omit,
				extendedProtocolConfigurationOptions := omit
			}
		}
	}
}
template (present) PDU_NAS_EPS
tr_NAS_PdnConnReq(template (present) BIT4 bearer_id := ?,
		  template (present) BIT8 proc_tid := ?,
		  template (present) BIT3 pdn_type := ?,
		  template (present) BIT3 req_type := ?) := {
	protocolDiscriminator := c_EPS_NAS_PD_ESM,
	ePS_messages := {
		ePS_SessionManagement := {
			pDU_NAS_EPS_PDN_ConnectivityRequest := {
				ePSBearerIdentity := bearer_id,
				procedureTransactionIdentifier := proc_tid,
				messageType := '11010000'B,
				requestType := {
					requestTypeValue := req_type,
					spare := '0'B
				},
				pDN_Type := {
					pDN_TypeValue := pdn_type,
					spare := '0'B
				},
				eSM_InformationTransferFlag := omit,
				accessPointName := omit,
				protocolConfigOptions := omit,
				deviceProperties := omit,
				nBIFOMContainer := omit,
				headerCompressinConfiguration := omit,
				extendedProtocolConfigurationOptions := omit
			}
		}
	}
}

/* 8.3.19 PDN Connectivity Reject */
template (value) PDU_NAS_EPS
ts_NAS_PdnConnRej(template (value) BIT4 bearer_id,
		  template (value) BIT8 proc_tid,
		  template (value) ESM_CauseV cause) := {
	protocolDiscriminator := c_EPS_NAS_PD_ESM,
	ePS_messages := {
		ePS_SessionManagement := {
			pDU_NAS_EPS_PDN_ConnectivityReject := {
				ePSBearerIdentity := bearer_id,
				procedureTransactionIdentifier := proc_tid,
				messageType := '11010001'B,
				esmCause := cause,
				protocolConfigOptions := omit,
				backOffTimer := omit,
				reAttemptIndicator := omit,
				nBIFOMContainer := omit,
				extendedProtocolConfigurationOptions := omit
			}
		}
	}
}
template (present) PDU_NAS_EPS
tr_NAS_PdnConnRej(template (present) BIT4 bearer_id := ?,
		  template (present) BIT8 proc_tid := ?,
		  template (present) ESM_CauseV cause := ?) := {
	protocolDiscriminator := c_EPS_NAS_PD_ESM,
	ePS_messages := {
		ePS_SessionManagement := {
			pDU_NAS_EPS_PDN_ConnectivityReject := {
				ePSBearerIdentity := bearer_id,
				procedureTransactionIdentifier := proc_tid,
				messageType := '11010001'B,
				esmCause := cause,
				protocolConfigOptions := *,
				backOffTimer := *,
				reAttemptIndicator := *,
				nBIFOMContainer := *,
				extendedProtocolConfigurationOptions := *
			}
		}
	}
}


/* 8.3.6 Activate Default EPS Bearer Context Request */
template (value) PDU_NAS_EPS
ts_NAS_ActDefEpsBearCtxReq(template (value) BIT4 bearer_id,
			   template (value) BIT8 proc_tid,
			   template (value) EPS_QualityOfServiceV qos,
			   template (value) octetstring apn,
			   template (value) BIT3 addr_type,
			   template (value) octetstring addr_info) := {
	protocolDiscriminator := c_EPS_NAS_PD_ESM,
	ePS_messages := {
		ePS_SessionManagement := {
			pDU_NAS_EPS_ActDefEPSBearerContextRequest := {
				ePSBearerIdentity := bearer_id,
				procedureTransactionIdentifier := proc_tid,
				messageType := '11000001'B,
				ePS_QoS := {
					lengthIndicator := 0,
					ePS_QualityOfServiceV := qos
				},
				accessPointName := {
					lengthIndicator := 0,
					accessPointNameValue := apn
				},
				pDN_Address := {
					lengthIndicator := 0,
					typeValue := addr_type,
					spare := '00000'B,
					addressInformation := addr_info
				},
				transactionIdentifier := omit,
				negotiatedQoS := omit,
				negotiated_LLC_SAPI := omit,
				radioPriority := omit,
				packetFlowID := omit,
				aPN_AMBR := omit,
				esmCause := omit,
				protocolConfigOptions := omit,
				connectivityType := omit,
				wLANOffloadIndication := omit,
				nBIFOMContainer := omit,
				headerCompressinConfiguration := omit,
				controlPlaneOnlyIndication := omit,
				extendedProtocolConfigurationOptions := omit,
				servingPLMNRateControl := omit,
				extended_APN_AMBR := omit,
				extendedQoS := omit
			}
		}
	}
}

/* 8.3.4 Activate Default EPS Bearer Context Accept */
template (value) PDU_NAS_EPS
ts_NAS_ActDefEpsBearCtxAck(template (value) BIT4 bearer_id,
			   template (value) BIT8 proc_tid,
			   template (omit) ProtocolConfigOptionsV pco) := {
	protocolDiscriminator := c_EPS_NAS_PD_ESM,
	ePS_messages := {
		ePS_SessionManagement := {
			pDU_NAS_EPS_ActDefEPSBearerContextAccept := {
				ePSBearerIdentity := bearer_id,
				procedureTransactionIdentifier := proc_tid,
				messageType := '11000010'B,
				protocolConfigOptions := ts_NAS_PCO_TLV(pco),
				extendedProtocolConfigurationOptions := omit
			}
		}
	}
}
template (present) PDU_NAS_EPS
tr_NAS_ActDefEpsBearCtxAck(template (present) BIT4 bearer_id := ?,
			   template (present) BIT8 proc_tid := ?,
			   template ProtocolConfigOptionsV pco := *) := {
	protocolDiscriminator := c_EPS_NAS_PD_ESM,
	ePS_messages := {
		ePS_SessionManagement := {
			pDU_NAS_EPS_ActDefEPSBearerContextAccept := {
				ePSBearerIdentity := bearer_id,
				procedureTransactionIdentifier := proc_tid,
				messageType := '11000010'B,
				protocolConfigOptions := tr_NAS_PCO_TLV(pco),
				extendedProtocolConfigurationOptions := *
			}
		}
	}
}


/* 8.3.5 Activate Default EPS Bearer Context Reject */
template (value) PDU_NAS_EPS
ts_NAS_ActDefEpsBearCtxRej(template (value) BIT4 bearer_id,
			   template (value) BIT8 proc_tid,
			   template (value) ESM_CauseV cause) := {
	protocolDiscriminator := c_EPS_NAS_PD_ESM,
	ePS_messages := {
		ePS_SessionManagement := {
			pDU_NAS_EPS_ActDefEPSBearerContextReject := {
				ePSBearerIdentity := bearer_id,
				procedureTransactionIdentifier := proc_tid,
				messageType := '11000011'B,
				esmCause := cause,
				protocolConfigOptions := omit,
				extendedProtocolConfigurationOptions := omit
			}
		}
	}
}
template (present) PDU_NAS_EPS
tr_NAS_ActDefEpsBearCtxRej(template (present) BIT4 bearer_id := ?,
			   template (present) BIT8 proc_tid := ?,
			   template (present) ESM_CauseV cause := ?) := {
	protocolDiscriminator := c_EPS_NAS_PD_ESM,
	ePS_messages := {
		ePS_SessionManagement := {
			pDU_NAS_EPS_ActDefEPSBearerContextReject := {
				ePSBearerIdentity := bearer_id,
				procedureTransactionIdentifier := proc_tid,
				messageType := '11000011'B,
				esmCause := cause,
				protocolConfigOptions := *,
				extendedProtocolConfigurationOptions := *
			}
		}
	}
}





}
