daniel has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/27111 )
Change subject: hnbgw: Add tests for Iuh->Iu disconnect ......................................................................
hnbgw: Add tests for Iuh->Iu disconnect
Change-Id: I8c1858382483af94542af9eb6977d360f26fdaef --- M hnbgw/HNBGW_Tests.ttcn M library/RUA_Emulation.ttcn 2 files changed, 108 insertions(+), 2 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-ttcn3-hacks refs/changes/11/27111/1
diff --git a/hnbgw/HNBGW_Tests.ttcn b/hnbgw/HNBGW_Tests.ttcn index 59cda1a..6b87f72 100644 --- a/hnbgw/HNBGW_Tests.ttcn +++ b/hnbgw/HNBGW_Tests.ttcn @@ -461,6 +461,44 @@ return rx; }
+function f_iuh2iu_disconnect(template (present) RANAP_PDU tx, RUA_IEs.Cause cause, + template RANAP_PDU exp_rx := omit) +runs on ConnHdlr return RANAP_PDU { + var RANAP_PDU rx + timer T := 5.0; + + if (istemplatekind(exp_rx, "omit")) { + exp_rx := tx; + } + + /* send it via Iuh (creating a RUA connection) */ + RUA.send(RUA_Disc_Req:{tx, cause}); + + /* expect to receive it on the Iu side */ + T.start; + alt { + [] BSSAP.receive(exp_rx) -> value rx { + } + [] T.timeout { + setverdict(fail, "Timeout waiting for Iu ", exp_rx); + return rx; + } + } + + /* expect disconnect on the Iu side */ + alt { + [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) { + setverdict(pass); + } + [] T.timeout { + setverdict(fail, "Timeout waiting for Iu disconnect"); + return rx; + } + + } + return rx; +} + /* build a RANAP InitialUE based on the TestHdlrParams */ friend function f_build_initial_ue(TestHdlrParams pars) return RANAP_PDU { var LAI lai := { @@ -624,6 +662,40 @@ }
+private function f_tc_ranap_mo_disconnect(charstring id, TestHdlrParams pars) runs on ConnHdlr { + f_init_handler(pars); + + /* HNB -> MSC: InitialUE */ + f_iuh2iu_connect(f_build_initial_ue(g_pars)); + + /* MSC <- HNB: DirectTransfer */ + f_iu2iuh(ts_RANAP_DirectTransfer(f_rnd_octstring(10))); + /* MSC -> HNB: DirectTransfer */ + f_iuh2iu(ts_RANAP_DirectTransfer(f_rnd_octstring(10))); + + /* MSC <- HNB: RUA disconnect */ + f_iuh2iu_disconnect(ts_RANAP_IuReleaseComplete, RUA_IEs.Cause:{misc:=processing_overload}); +} +testcase TC_ranap_cs_mo_disconnect() runs on test_CT { + var ConnHdlr vc_conn; + + f_init(); + f_start_hnbs(); + + vc_conn := f_start_handler_with_pars(refers(f_tc_ranap_mo_disconnect), t_pars(5)); + vc_conn.done; +} +testcase TC_ranap_ps_mo_disconnect() runs on test_CT { + var ConnHdlr vc_conn; + + f_init(); + f_start_hnbs(); + + vc_conn := f_start_handler_with_pars(refers(f_tc_ranap_mo_disconnect), t_pars(6)); + vc_conn.done; +} + +
control { @@ -632,6 +704,8 @@ execute(TC_ranap_ps_initial_ue()); execute(TC_ranap_cs_bidir()); execute(TC_ranap_ps_bidir()); + execute(TC_ranap_cs_mo_disconnect()); + execute(TC_ranap_ps_mo_disconnect()); }
} diff --git a/library/RUA_Emulation.ttcn b/library/RUA_Emulation.ttcn index 23b4a7a..98e5a1f 100644 --- a/library/RUA_Emulation.ttcn +++ b/library/RUA_Emulation.ttcn @@ -53,11 +53,12 @@ port RUA_Conn_PT RUA; }
- /* port between individual per-connection components and this dispatcher */ type port RUA_Conn_PT message { inout RANAP_PDU, - RUA_Conn_Req; + RUA_Conn_Req, + RUA_Disc_Req, + RUA_Disc_Ind; } with { extension "internal" };
type record RUA_Conn_Req { @@ -65,6 +66,15 @@ RANAP_PDU ranap };
+type record RUA_Disc_Req { + RANAP_PDU ranap, + RUA_IEs.Cause cause +}; + +type record RUA_Disc_Ind { + RUA_IEs.Cause cause +}; + type bitstring ContextId length(24); // with { variant "FIELDLENGTH(24)" };
/* represents a single RANAP connection over RUA */ @@ -257,6 +267,8 @@ var RUA_IEs.CN_DomainIndicator domain_ind; var RUA_ConnHdlr vc_conn; var RUA_Conn_Req creq; + var RUA_Disc_Req dreq; + var RUA_IEs.Cause cause;
/* RUA -> Client: UNIT-DATA (connectionless RUA) from CN */ [] RUA.receive(tr_RUA_ConnectionlessTransfer) -> value rua { @@ -277,6 +289,7 @@ vc_conn := g_rua_ops.create_cb.apply(context_id, domain_ind, g_rua_id); /* store mapping between client components and RUA contextId */ f_conn_table_add(vc_conn, domain_ind, context_id); + /* TODO: notify user about incoming connection? */ /* handle user payload */ f_handle_userData_RANAP(vc_conn, ranap); } @@ -291,6 +304,15 @@
/* RUA -> Client: disconnect of an existing connection */ [] RUA.receive(tr_RUA_Disconnect) -> value rua { + cause := rua.initiatingMessage.value_.disconnect_.protocolIEs[2].value_.cause; + context_id := rua.initiatingMessage.value_.disconnect_.protocolIEs[1].value_.context_ID; + vc_conn := f_comp_by_context_id(context_id); + /* send contained RANAP message to user */ + ranap_enc := rua.initiatingMessage.value_.disconnect_.protocolIEs[3].value_.rANAP_Message; + f_handle_userData_RANAP(vc_conn, dec_RANAP_PDU(ranap_enc)); + /* notify user of disconnect */ + CLIENT.send(RUA_Disc_Ind:{cause}); + f_conn_table_del(context_id); }
/* RANAP from client through an existing RANAP connection */ @@ -301,6 +323,16 @@ RUA.send(ts_RUA_DirectTransfer(domain_ind, context_id, enc_RANAP_PDU(ranap))); }
+ /* Disconnect request from client */ + [] CLIENT.receive(RUA_Disc_Req:?) -> value dreq sender vc_conn { + var octetstring enc_ranap := enc_RANAP_PDU(dreq.ranap); + var integer idx := f_idx_by_comp(vc_conn); + context_id := int2bit(ConnectionTable[idx].context_id, 24); + domain_ind := ConnectionTable[idx].domain; + RUA.send(ts_RUA_Disconnect(domain_ind, context_id, dreq.cause, enc_ranap)); + f_conn_table_del(context_id); + } + /* RANAP from client, for a new RANAP connection */ [] CLIENT.receive(RUA_Conn_Req:?) -> value creq sender vc_conn { var octetstring enc_ranap := enc_RANAP_PDU(creq.ranap);