pespin has submitted this change. ( https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/42326?usp=email )
Change subject: 5gc: Introduce TC_handover_inter_ngran_n2 ......................................................................
5gc: Introduce TC_handover_inter_ngran_n2
Change-Id: I90c7cc6c92864732a36556163aed692b2a1531b0 --- M 5gc/C5G_Tests.ttcn M 5gc/ConnHdlr.ttcn M 5gc/expected-results.xml M library/NGAP_Emulation.ttcn M library/NGAP_Functions.ttcn M library/ngap/NGAP_EncDec.cc M library/ngap/NGAP_Types.ttcn 7 files changed, 370 insertions(+), 31 deletions(-)
Approvals: osmith: Looks good to me, but someone else must approve pespin: Looks good to me, approved Jenkins Builder: Verified
diff --git a/5gc/C5G_Tests.ttcn b/5gc/C5G_Tests.ttcn index 028178d..bf3cfd3 100644 --- a/5gc/C5G_Tests.ttcn +++ b/5gc/C5G_Tests.ttcn @@ -676,6 +676,90 @@ vc_conn[1].done; }
+/* 3GPP TS 23.502 4.9.1.3 Inter NG-RAN node N2 based handover */ +private function f_TC_handover_inter_ngran_n2_source() runs on ConnHdlr { + f_register(); + f_pdu_sess_establish(); + f_sleep(1.0); + f_ping4(g_pars.ue_pars.sess_pars.run_prog_pars.ping_hostname); + + var NG_NAS_UE_State nus := f_ngap_obtain_nus(g_pars.ue_pars.ran_id); + + COORD.send(Handover_n2_Pars:{ + guti := g_pars.ue_pars.guti, + pti := g_pars.ue_pars.pti, + sess_pars := g_pars.ue_pars.sess_pars, + kset_id := g_pars.kset_id, + nus := nus + }); + + /* 3GPP TS 23.502 4.9.1.3.2 step 1: */ + f_n2_handover_required(m_targetID_targetRANNodeID(m_targetRANNodeID(g_pars.ngran_pars[1].global_ngran_id, + ts_ngran_NGAP_TAI(g_pars.ngran_pars[1])) + )); + /* 3GPP TS 23.502 4.9.1.3.3 step 1: */ + f_n2_handover_command(); + /* 3GPP TS 23.502 4.9.1.3.3 step 2: */ + COORD.send("HANDOVER_COMMAND_CONFIRM"); + + /* 3GPP TS 23.502 4.9.1.3.3 step 14a + 14b: */ + as_ngap_handle_UeContextReleaseCmd(exp_cause := mw_cause_radioNetwork(successful_handover)); +} +private function f_TC_handover_inter_ngran_n2_target() runs on ConnHdlr { + var Handover_n2_Pars ho_n2_pars; + + /* Redirect Handover Request from AMF containing new AMF ID to our target ConnHdlr: */ + f_create_ngap_expect_proc(id_HandoverResourceAllocation, self); + + COORD.receive(Handover_n2_Pars:?) -> value ho_n2_pars; + g_pars.ue_pars.guti := ho_n2_pars.guti; + g_pars.ue_pars.pti := ho_n2_pars.pti; + g_pars.ue_pars.sess_pars.id := ho_n2_pars.sess_pars.id; + g_pars.ue_pars.sess_pars.qos_rules := ho_n2_pars.sess_pars.qos_rules; + g_pars.ue_pars.sess_pars.ue_ip := ho_n2_pars.sess_pars.ue_ip; + g_pars.kset_id := ho_n2_pars.kset_id; + + + /* 3GPP TS 23.502 4.9.1.3.2 step 9+10: */ + f_n2_handover_request(); + + /* 3GPP TS 23.502 4.9.1.3.3 step 4 */ + COORD.receive("HANDOVER_COMMAND_CONFIRM"); + f_ngap_set_nus(g_pars.ue_pars.ran_id, ho_n2_pars.nus); + + /* 3GPP TS 23.502 4.9.1.3.3 step 5: */ + f_n2_handover_notify(); + + f_sleep(1.0); + + f_pdu_sess_create_tun(); + f_ping4(g_pars.ue_pars.sess_pars.run_prog_pars.ping_hostname); + + f_pdu_sess_release(); + f_deregister(); +} +testcase TC_handover_inter_ngran_n2() runs on MTC_CT { + var ConnHdlr vc_conn[2]; + var integer i; + + f_init(); + f_ngap_setup(0); + f_ngap_setup(1); + + var ConnHdlrPars pars := f_init_pars(ue_idx := 0, c5g_idx := 0); + vc_conn[0] := f_start_handler_create(ngap_idx := 0); + vc_conn[1] := f_start_handler_create(ngap_idx := 1); + connect(vc_conn[0]:COORD, vc_conn[1]:COORD); + + f_start_handler_run(vc_conn[0], refers(f_TC_handover_inter_ngran_n2_source), pars); + pars.c5g_idx := 1; + pars.ue_pars.sess_pars.ran_gtpu_teid := int2oct(oct2int(pars.ue_pars.sess_pars.ran_gtpu_teid) + 1, 4); + f_start_handler_run(vc_conn[1], refers(f_TC_handover_inter_ngran_n2_target), pars); + + vc_conn[0].done; + vc_conn[1].done; +} + control { execute( TC_ng_setup() ); execute( TC_ng_setup_unknown_global_gnb_id_plmn() ); @@ -702,7 +786,7 @@ execute( TC_connection_suspend() );
execute( TC_handover_inter_ngran_xn() ); - + execute( TC_handover_inter_ngran_n2() ); }
/* TODO: diff --git a/5gc/ConnHdlr.ttcn b/5gc/ConnHdlr.ttcn index da0d3d9..e6621f8 100644 --- a/5gc/ConnHdlr.ttcn +++ b/5gc/ConnHdlr.ttcn @@ -123,9 +123,18 @@ NG_NAS_UE_State nus /* 3GPP TS 38.423 9.2.1.13 UE Context Information */ };
+/* Pass needed UE context state between ConnHdlr */ +type record Handover_n2_Pars { + octetstring guti, + ProcedureTransactionIdentifier pti, + PDUSessionParams sess_pars, + NAS_KeySetIdentifier kset_id, + NG_NAS_UE_State nus /* 3GPP TS 38.423 9.2.1.13 UE Context Information */ +}; + type port ConnHdlr_Coord_PT message { - inout charstring, Handover_Xn_Pars; + inout charstring, Handover_Xn_Pars, Handover_n2_Pars; } with { extension "internal" };
type component ConnHdlr extends NGAP_ConnHdlr, GTP1U_ConnHdlr { @@ -140,7 +149,7 @@
type function void_fn() runs on ConnHdlr;
-private template (value) NGAP_IEs.TAI ts_ngran_NGAP_TAI(NGRANParams ngran_pars) := { +template (value) NGAP_IEs.TAI ts_ngran_NGAP_TAI(NGRANParams ngran_pars) := { pLMNIdentity := ngran_pars.global_ngran_id.globalGNB_ID.pLMNIdentity, tAC := ngran_pars.supported_ta_list[0].tAC, iE_Extensions := omit @@ -182,6 +191,15 @@ return valueof(p_ueLocInf); }
+private function f_UPTLI() runs on ConnHdlr return UPTransportLayerInformation { + var template (value) UPTransportLayerInformation uptli; + + uptli := m_uPTransportLayerInformation_gTPTunnel( + m_gTPTunnel(p_tla := oct2bit(f_inet_addr(g_pars.ue_pars.sess_pars.ran_gtpu_ip)), + p_gtp_teid := g_pars.ue_pars.sess_pars.ran_gtpu_teid)); + return valueof(uptli); +} + private function f_tr_ConnHdlr_kset_id() runs on ConnHdlr return template (present) NAS_KeySetIdentifier { /* KSI not yet set, expect whatever assignment from network: */ if (g_pars.kset_id.nasKeySetId == tsc_NasKsi_NoKey) { @@ -350,12 +368,19 @@ var template (value) UPTransportLayerInformation utla; var template (value) QosFlowPerTNLInformation qos; var NGAP_IEs.PDUSessionResourceSetupResponseTransfer setup_resp_transf; + var integer qos_id := 0;
for (var integer i := 0; i < lengthof(setup_req_transf.protocolIEs); i := i + 1) { - if (setup_req_transf.protocolIEs[i].id == id_UL_NGU_UP_TNLInformation) { + select (setup_req_transf.protocolIEs[i].id) { + case (id_UL_NGU_UP_TNLInformation) { var UPTransportLayerInformation utli := setup_req_transf.protocolIEs[i].value_.uPTransportLayerInformation; g_pars.ue_pars.sess_pars.cn_gtpu_ip := f_inet_ntoa(bit2oct(utli.gTPTunnel.transportLayerAddress)); g_pars.ue_pars.sess_pars.cn_gtpu_teid := utli.gTPTunnel.gTP_TEID; + } + case (id_QosFlowSetupRequestList) { + var QosFlowSetupRequestList qos_req_li := setup_req_transf.protocolIEs[i].value_.QosFlowSetupRequestList; + qos_id := qos_req_li[0].qosFlowIdentifier; + } } }
@@ -363,7 +388,7 @@ utla := m_uPTransportLayerInformation_gTPTunnel( m_gTPTunnel(p_tla := oct2bit(f_inet_addr(g_pars.ue_pars.sess_pars.ran_gtpu_ip)), p_gtp_teid := g_pars.ue_pars.sess_pars.ran_gtpu_teid)); - qos := m_qosFlowPerTNLInformation(utla, { m_associatedQosFlowItem(1) }); + qos := m_qosFlowPerTNLInformation(utla, { m_associatedQosFlowItem(qos_id) }); setup_resp_transf := valueof(m_pDUSessionResourceSetupResponseTransfer(qos));
return setup_resp_transf; @@ -815,7 +840,7 @@ }
/* 3GPP TS 38.413 8.3.3 UE Context Release (AMF initiated) */ -private altstep as_ngap_handle_UeContextReleaseCmd(template (present) Cause exp_cause := ?) runs on ConnHdlr { +altstep as_ngap_handle_UeContextReleaseCmd(template (present) Cause exp_cause := ?) runs on ConnHdlr { var NGAP_PDU rx_ngap; var template (present) NGAP_PDU exp_ngap := mw_ngap_initMsg(mw_n2_UEContextReleaseCommand( @@ -914,17 +939,13 @@ * 3GPP TS 23.502 4.9.1.2.2 Xn based inter NG-RAN handover without User Plane function re-allocation */ function f_n2_path_switch(AMF_UE_NGAP_ID source_amf_id) runs on ConnHdlr { - var template (value) UPTransportLayerInformation utla; var template (value) PathSwitchRequestTransfer transfer; var octetstring transfer_enc; var template (value) PDUSessionResourceToBeSwitchedDLItem it; var template (value) NGAP_PDU tx_pdu; var NGAP_PDU rx_pdu;
- utla := m_uPTransportLayerInformation_gTPTunnel( - m_gTPTunnel(p_tla := oct2bit(f_inet_addr(g_pars.ue_pars.sess_pars.ran_gtpu_ip)), - p_gtp_teid := g_pars.ue_pars.sess_pars.ran_gtpu_teid)); - transfer := m_pathSwitchRequestTransfer(p_dL_NGU_UP_TNLInformation := utla, + transfer := m_pathSwitchRequestTransfer(p_dL_NGU_UP_TNLInformation := f_UPTLI(), p_qosFlowAcceptedList := { m_qosFlowAcceptedItem(1) }, p_dL_NGU_TNLInformationReused := omit, p_userPlaneSecurityInformation := omit); @@ -946,6 +967,115 @@ g_pars.ue_pars.amf_id := path_switch_ack.protocolIEs[0].value_.aMF_UE_NGAP_ID; }
+/* 3GPP TS 38.413 8.4.1 Handover Preparation + * 3GPP TS 38.413 9.2.3.1 HANDOVER REQUIRED + * 3GPP TS 38.413 9.3.4.14 Handover Required Transfer */ +function f_n2_handover_required(template (value) TargetID target_id) runs on ConnHdlr +{ + var template (value) HandoverRequiredTransfer transfer; + var octetstring transfer_enc; + var template (value) PDUSessionResourceItemHORqd it; + var template (value) NGAP_PDU tx_pdu; + + transfer := m_handoverRequiredTransfer(omit); + transfer_enc := enc_NGAP_HandoverRequiredTransfer(valueof(transfer)); + it := m_pDUSessionResourceItemHORqd(g_pars.ue_pars.sess_pars.id, + transfer_enc); + + tx_pdu := m_ngap_initMsg( + m_n2_HandoverRequired( + g_pars.ue_pars.amf_id, + g_pars.ue_pars.ran_id, + intra5gs, + m_cause_radioNetwork(resource_optimisation_handover), + target_id, + { it }, + '1234'O /* random string, transparent to the AMF */)); + NGAP.send(tx_pdu); +} + +/* 3GPP TS 38.413 9.2.3.4 HANDOVER REQUEST + * 3GPP TS 23.502 4.9.1.3.2 step 9+10 */ +function f_n2_handover_request() runs on ConnHdlr +{ + var template (value) QosFlowItemWithDataForwarding qos; + var template (value) HandoverRequestAcknowledgeTransfer transfer; + var octetstring transfer_enc; + var template (value) PDUSessionResourceAdmittedItem it; + var template (value) NGAP_PDU tx_pdu; + var NGAP_PDU rx_pdu; + var HandoverRequest ho_req; + var QosFlowIdentifier qos_id := 0; + + NGAP.receive(mw_ngap_initMsg( + mw_n2_HandoverRequest(? /* AMF ID not known yet here*/, + intra5gs))) -> value rx_pdu; + ho_req := rx_pdu.initiatingMessage.value_.handoverRequest; + + for (var integer i := 0; i < lengthof(ho_req.protocolIEs); i := i + 1) { + select(ho_req.protocolIEs[i].id) { + case (id_AMF_UE_NGAP_ID) { + /* Update amf_id: */ + g_pars.ue_pars.amf_id := ho_req.protocolIEs[i].value_.aMF_UE_NGAP_ID; + } + case (id_PDUSessionResourceSetupListHOReq) { + var PDUSessionResourceSetupListHOReq res_li := ho_req.protocolIEs[i].value_.PDUSessionResourceSetupListHOReq; + var PDUSessionResourceSetupItemHOReq res_it := res_li[0]; + var NGAP_IEs.PDUSessionResourceSetupRequestTransfer setup_req_transf; + var NGAP_IEs.PDUSessionResourceSetupResponseTransfer setup_resp_transf; + setup_req_transf := dec_NGAP_PDUSessionResourceSetupRequestTransfer(res_it.handoverRequestTransfer); + setup_resp_transf := f_pdu_handle_PDUSessionResourceSetupRequestTransfer(setup_req_transf); + qos_id := setup_resp_transf.dLQosFlowPerTNLInformation.associatedQosFlowList[0].qosFlowIdentifier; + } + } + } + + qos := m_qosFlowItemWithDataForwarding(qos_id); + transfer := m_handoverRequestAcknowledgeTransfer(f_UPTLI(), {qos}); + transfer_enc := enc_NGAP_HandoverRequestAcknowledgeTransfer(valueof(transfer)); + it := m_pDUSessionResourceAdmittedItem(g_pars.ue_pars.sess_pars.id, transfer_enc); + tx_pdu := mw_ngap_succMsg(m_n2_HandoverRequestAcknowledge( + g_pars.ue_pars.amf_id, + g_pars.ue_pars.ran_id, + { it }, + '1234'O)); + NGAP.send(tx_pdu); +} + +/* 3GPP TS 38.413 9.2.3.2 HANDOVER COMMAND + * 3GPP TS 23.502 4.9.1.3.3 step 1 */ +function f_n2_handover_command() runs on ConnHdlr +{ + var NGAP_PDU rx_pdu; + + NGAP.receive(mw_ngap_succMsg(mw_n2_HandoverCommand( + g_pars.ue_pars.amf_id, + g_pars.ue_pars.ran_id, + intra5gs, + ?))) -> value rx_pdu; +} + +/* 3GPP TS 23.502 9.2.3.7 HANDOVER NOTIFY + * 3GPP TS 23.502 4.9.1.3.3 step 5 */ +function f_n2_handover_notify() runs on ConnHdlr +{ + var template (value) HandoverRequiredTransfer transfer; + var octetstring transfer_enc; + var template (value) PDUSessionResourceItemHORqd it; + var template (value) NGAP_PDU tx_pdu; + + transfer := m_handoverRequiredTransfer(omit); + transfer_enc := enc_NGAP_HandoverRequiredTransfer(valueof(transfer)); + it := m_pDUSessionResourceItemHORqd(g_pars.ue_pars.sess_pars.id, + transfer_enc); + + tx_pdu := m_ngap_initMsg(m_n2_HandoverNotify( + g_pars.ue_pars.amf_id, + g_pars.ue_pars.ran_id, + f_ULI())); + NGAP.send(tx_pdu); +} + /* Handle a PDUSessionResourceSetupRequestTransfer contained inside NGAP InitialContextSetupRequest and return a Result for InitialContextSetupResponse */ private function f_pdu_handle_session_resource_released_item(PDUSessionResourceToReleaseItemRelCmd cmd) runs on ConnHdlr return PDUSessionResourceReleasedItemRelRes { diff --git a/5gc/expected-results.xml b/5gc/expected-results.xml index 2333f8d..03bbd43 100644 --- a/5gc/expected-results.xml +++ b/5gc/expected-results.xml @@ -24,4 +24,5 @@ </failure> </testcase> <testcase classname='C5G_Tests' name='TC_handover_inter_ngran_xn' time='MASKED'/> + <testcase classname='C5G_Tests' name='TC_handover_inter_ngran_n2' time='MASKED'/> </testsuite> diff --git a/library/NGAP_Emulation.ttcn b/library/NGAP_Emulation.ttcn index d050d2f..f493260 100644 --- a/library/NGAP_Emulation.ttcn +++ b/library/NGAP_Emulation.ttcn @@ -154,6 +154,13 @@ return ret; } } + + /* Try by message type. This is useful for Handover Request, where network sends a new AMF Id. */ + ret := NGapExpectTableProc_get_conn(msg); + if (ret != null) { + return ret; + } + setverdict(fail, "Couldn't find Expect for ", msg); mtc.stop; } @@ -273,17 +280,22 @@ Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Unexpected call f_assoc_id_by_ngap_ids(omit, omit)"); } for (var integer i := 0; i < sizeof(NGapAssociationTable); i := i+1) { - if (not isvalue(NGapAssociationTable[i].ran_ue_ngap_id)) { - continue; - } - if (not istemplatekind(ran_id, "omit") and - not match(NGapAssociationTable[i].ran_ue_ngap_id, ran_id)) { - continue; + if (not istemplatekind(ran_id, "omit")) { + if (not ispresent(NGapAssociationTable[i].ran_ue_ngap_id)) { + continue; + } + if (not match(NGapAssociationTable[i].ran_ue_ngap_id, ran_id)) { + continue; + } } /* ran_id matched, check amf_id now: */ - if (not istemplatekind(amf_id, "omit") and - not match(NGapAssociationTable[i].amf_ue_ngap_id, amf_id)) { - continue; + if (not istemplatekind(amf_id, "omit")) { + if (not ispresent(NGapAssociationTable[i].amf_ue_ngap_id)) { + continue; + } + if (not match(NGapAssociationTable[i].amf_ue_ngap_id, amf_id)) { + continue; + } } return i; } @@ -317,12 +329,18 @@
private function f_ngap_id_table_add(NGAP_ConnHdlr comp_ref, template (omit) AMF_UE_NGAP_ID amf_id, - RAN_UE_NGAP_ID ran_id) + template (omit) RAN_UE_NGAP_ID ran_id) runs on NGAP_Emulation_CT return integer { var integer i; for (i := 0; i < sizeof(NGapAssociationTable); i := i+1) { - if (not isvalue(NGapAssociationTable[i].ran_ue_ngap_id)) { - NGapAssociationTable[i].ran_ue_ngap_id := ran_id; + if (not isvalue(NGapAssociationTable[i].ran_ue_ngap_id) and + not isvalue(NGapAssociationTable[i].amf_ue_ngap_id)) { + if (istemplatekind(ran_id, "omit")) { + NGapAssociationTable[i].ran_ue_ngap_id := omit; + } else { + NGapAssociationTable[i].ran_ue_ngap_id := valueof(ran_id); + } + if (istemplatekind(amf_id, "omit")) { NGapAssociationTable[i].amf_ue_ngap_id := omit; } else { @@ -407,9 +425,9 @@ } }
-private function SendToNGapExpectTableProc(NGAP_PDU msg) runs on NGAP_Emulation_CT { - var integer procedureCode; - var NGAP_ConnHdlr vc_conn; +private function ngap_pdu_get_procedure_code(NGAP_PDU msg) return integer +{ + var integer procedureCode := 0;
if (ispresent(msg.initiatingMessage.procedureCode)) { procedureCode := msg.initiatingMessage.procedureCode; @@ -417,10 +435,32 @@ procedureCode := msg.unsuccessfulOutcome.procedureCode; } else if (ispresent(msg.successfulOutcome.procedureCode)) { procedureCode := msg.successfulOutcome.procedureCode; - } else { - return; }
+ return procedureCode; +} + +private function NGapExpectTableProc_get_conn(NGAP_PDU msg) +runs on NGAP_Emulation_CT return NGAP_ConnHdlr { + var NGAP_ConnHdlr vc_conn; + var integer procedureCode := ngap_pdu_get_procedure_code(msg); + + for (var integer i := 0; i < sizeof(NGapExpectTableProc); i := i+1) { + if (NGapExpectTableProc[i].procedureCode == procedureCode) { + vc_conn := NGapExpectTableProc[i].vc_conn; + if (vc_conn != null) { + return vc_conn; + } + } + } + + return null; +} + +private function SendToNGapExpectTableProc(NGAP_PDU msg) runs on NGAP_Emulation_CT { + var NGAP_ConnHdlr vc_conn; + var integer procedureCode := ngap_pdu_get_procedure_code(msg); + for (var integer i := 0; i < sizeof(NGapExpectTableProc); i := i+1) { if (NGapExpectTableProc[i].procedureCode == procedureCode) { vc_conn := NGapExpectTableProc[i].vc_conn; @@ -537,6 +577,23 @@ /* Pass message through */ NGAP.send(t_NGAP_Send(g_ngap_conn_id, msg)); } + /* NGAP from client: HandoverRequestAcknowledge */ + [] NGAP_CLIENT.receive(mw_ngap_succMsg(mw_n2_HandoverRequestAcknowledge)) -> value msg sender vc_conn { + /* Update table entry with ran_id; oly amf_id was known through HandoverReq so far: */ + ai := f_assoc_id_by_ngap_ids(valueof(f_NGAP_get_AMF_UE_NGAP_ID(msg)), omit); + NGapAssociationTable[ai].ran_ue_ngap_id := valueof(f_NGAP_get_RAN_UE_NGAP_ID(msg)); + /* Pass message through */ + NGAP.send(t_NGAP_Send(g_ngap_conn_id, msg)); + } + /* NGAP from client: HandoverNotify */ + [] NGAP_CLIENT.receive(mw_ngap_initMsg(mw_n2_HandoverNotify)) -> value msg sender vc_conn { + /* create a table entry about this connection */ + ai := f_assoc_id_by_ngap_ids(valueof(f_NGAP_get_AMF_UE_NGAP_ID(msg)), valueof(f_NGAP_get_RAN_UE_NGAP_ID(msg))); + /* Store ULI so we can use it for generating UlNasTransport from NAS */ + NGapAssociationTable[ai].uli := msg.initiatingMessage.value_.HandoverNotify.protocolIEs[2].value_.userLocationInformation; + /* Pass message through */ + NGAP.send(t_NGAP_Send(g_ngap_conn_id, msg)); + } /* NAS from client: Wrap in NGAP Uplink NAS Transport */ [] NGAP_CLIENT.receive(NG_NAS_UL_Message_Type:?) -> value ul_nas_msg sender vc_conn { var integer assoc_id := f_assoc_id_by_comp(vc_conn); @@ -608,7 +665,7 @@ } else { /* if not, call create_cb so it can create new ConnHdlr */ vc_conn := ops.create_cb.apply(mrf.msg, amf_ue_id, ran_ue_id, id); - f_ngap_id_table_add(vc_conn, amf_ue_id, valueof(ran_ue_id)); + f_ngap_id_table_add(vc_conn, amf_ue_id, ran_ue_id); NGAP_CLIENT.send(mrf.msg) to vc_conn; } if (match(mrf.msg, mw_ngap_initMsg(mw_n2_UEContextReleaseCommand))) { @@ -714,7 +771,7 @@ /* client/conn_hdlr side function to use procedure port to create expect (PDU) in emulation */ function f_create_ngap_expect_proc(integer procedureCode, NGAP_ConnHdlr hdlr) runs on NGAP_ConnHdlr { - NGAP_PROC.call(NGAPEM_register_proc:{procedureCode, self}) { + NGAP_PROC.call(NGAPEM_register_proc:{procedureCode, hdlr}) { [] NGAP_PROC.getreply(NGAPEM_register_proc:{?,?}) {}; }
diff --git a/library/NGAP_Functions.ttcn b/library/NGAP_Functions.ttcn index 5d45c43..64e1450 100644 --- a/library/NGAP_Functions.ttcn +++ b/library/NGAP_Functions.ttcn @@ -40,6 +40,12 @@ case (id_PDUSessionResourceRelease) { return im.value_.pDUSessionResourceReleaseCommand.protocolIEs[0].value_.aMF_UE_NGAP_ID; } + case (id_HandoverResourceAllocation) { + return im.value_.handoverRequest.protocolIEs[0].value_.aMF_UE_NGAP_ID; + } + case (id_HandoverNotification) { + return im.value_.HandoverNotify.protocolIEs[0].value_.aMF_UE_NGAP_ID; + } /* TODO */ } } else if (ischosen(ngap.successfulOutcome)) { @@ -48,10 +54,15 @@ case (id_PathSwitchRequest) { return so.value_.PathSwitchRequestAcknowledge.protocolIEs[0].value_.aMF_UE_NGAP_ID; } + case (id_HandoverResourceAllocation) { + return so.value_.HandoverRequestAcknowledge.protocolIEs[0].value_.aMF_UE_NGAP_ID; + } + case (id_HandoverPreparation) { + return so.value_.HandoverCommand.protocolIEs[0].value_.aMF_UE_NGAP_ID; + } case (?) { return omit; /* TODO */ - /* return im.value_.SuccessfulOutcome.protocolIEs[0].value_.AMF_UE_NGAP_ID; */ } /* TODO */ } @@ -98,6 +109,9 @@ case (id_PathSwitchRequest) { return im.value_.PathSwitchRequest.protocolIEs[0].value_.RAN_UE_NGAP_ID; } + case (id_HandoverNotification) { + return im.value_.HandoverNotify.protocolIEs[1].value_.RAN_UE_NGAP_ID; + } /* TODO */ } } else if (ischosen(ngap.successfulOutcome)) { @@ -106,6 +120,12 @@ case (id_PathSwitchRequest) { return so.value_.PathSwitchRequestAcknowledge.protocolIEs[1].value_.rAN_UE_NGAP_ID; } + case (id_HandoverResourceAllocation) { + return so.value_.HandoverRequestAcknowledge.protocolIEs[1].value_.rAN_UE_NGAP_ID; + } + case (id_HandoverPreparation) { + return so.value_.HandoverCommand.protocolIEs[1].value_.rAN_UE_NGAP_ID; + } case (?) { return omit; /* TODO */ diff --git a/library/ngap/NGAP_EncDec.cc b/library/ngap/NGAP_EncDec.cc index 9e3ccd2..b024c32 100644 --- a/library/ngap/NGAP_EncDec.cc +++ b/library/ngap/NGAP_EncDec.cc @@ -149,4 +149,44 @@ return ret; }
+OCTETSTRING enc__NGAP__HandoverRequiredTransfer(const NGAP__IEs::HandoverRequiredTransfer &p) +{ + TTCN_Buffer TTCN_buf; + TTCN_buf.clear(); + p.encode(NGAP__IEs::HandoverRequiredTransfer_descr_, TTCN_buf, + TTCN_EncDec::CT_PER, PER_ALIGNED); + return OCTETSTRING(TTCN_buf.get_len(), TTCN_buf.get_data()); +} + +NGAP__IEs::HandoverRequiredTransfer dec__NGAP__HandoverRequiredTransfer(const OCTETSTRING &stream) +{ + NGAP__IEs::HandoverRequiredTransfer ret; + TTCN_Buffer TTCN_buf; + TTCN_buf.clear(); + TTCN_buf.put_os(stream); + ret.decode(NGAP__IEs::HandoverRequiredTransfer_descr_, TTCN_buf, + TTCN_EncDec::CT_PER, PER_ALIGNED); + return ret; +} + +OCTETSTRING enc__NGAP__HandoverRequestAcknowledgeTransfer(const NGAP__IEs::HandoverRequestAcknowledgeTransfer &p) +{ + TTCN_Buffer TTCN_buf; + TTCN_buf.clear(); + p.encode(NGAP__IEs::HandoverRequestAcknowledgeTransfer_descr_, TTCN_buf, + TTCN_EncDec::CT_PER, PER_ALIGNED); + return OCTETSTRING(TTCN_buf.get_len(), TTCN_buf.get_data()); +} + +NGAP__IEs::HandoverRequestAcknowledgeTransfer dec__NGAP__HandoverRequestAcknowledgeTransfer(const OCTETSTRING &stream) +{ + NGAP__IEs::HandoverRequestAcknowledgeTransfer ret; + TTCN_Buffer TTCN_buf; + TTCN_buf.clear(); + TTCN_buf.put_os(stream); + ret.decode(NGAP__IEs::HandoverRequestAcknowledgeTransfer_descr_, TTCN_buf, + TTCN_EncDec::CT_PER, PER_ALIGNED); + return ret; +} + } diff --git a/library/ngap/NGAP_Types.ttcn b/library/ngap/NGAP_Types.ttcn index 394cb24..e4a9f4e 100644 --- a/library/ngap/NGAP_Types.ttcn +++ b/library/ngap/NGAP_Types.ttcn @@ -23,4 +23,11 @@
external function enc_NGAP_PathSwitchRequestTransfer(NGAP_IEs.PathSwitchRequestTransfer p) return octetstring; external function dec_NGAP_PathSwitchRequestTransfer(in octetstring pdu) return NGAP_IEs.PathSwitchRequestTransfer; + + external function enc_NGAP_HandoverRequiredTransfer(NGAP_IEs.HandoverRequiredTransfer p) return octetstring; + external function dec_NGAP_HandoverRequiredTransfer(in octetstring pdu) return NGAP_IEs.HandoverRequiredTransfer; + + external function enc_NGAP_HandoverRequestAcknowledgeTransfer(NGAP_IEs.HandoverRequestAcknowledgeTransfer p) return octetstring; + external function dec_NGAP_HandoverRequestAcknowledgeTransfer(in octetstring pdu) return NGAP_IEs.HandoverRequestAcknowledgeTransfer; + }