From 1733a385613b1c7c2db2c106d4e1daca7f795e74 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sun, 23 Jul 2017 17:26:17 +0200 Subject: [PATCH] Add missing BSSGP_Emulation.ttcn file --- gprs_gb/BSSGP_Emulation.ttcn | 220 +++++++++++++++++++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100644 gprs_gb/BSSGP_Emulation.ttcn diff --git a/gprs_gb/BSSGP_Emulation.ttcn b/gprs_gb/BSSGP_Emulation.ttcn new file mode 100644 index 000000000..25b96cda3 --- /dev/null +++ b/gprs_gb/BSSGP_Emulation.ttcn @@ -0,0 +1,220 @@ +module BSSGP_Emulation { + import from NS_Types all; + import from NS_Emulation all; + import from BSSGP_Types all; + import from BSSGP_Helper_Functions all; + import from IPL4asp_Types all; + + type record BssgpStatusIndication { + Nsei nsei, + BssgpBvci bvci, + BvcState state + } + + template BssgpStatusIndication t_BssgpStsInd(Nsei nsei, BssgpBvci bvci, BvcState state) := { + nsei := nsei, + bvci := bvci, + state := state + } + + type enumerated BvcState { + BVC_S_BLOCKED, + BVC_S_UNBLOCKED + }; + + /* port from our (internal) point of view */ + type port BSSGP_SP_PT message { + in BssgpPdu; + out BssgpPdu, + NsStatusIndication, + BssgpStatusIndication, + ASP_Event; + } with { extension "internal" }; + + /* port from the user point of view */ + type port BSSGP_PT message { + in ASP_Event, + NsStatusIndication, + BssgpStatusIndication, + BssgpPdu; + out BssgpPdu; + } with { extension "internal" }; + + function BssgpStart() runs on BSSGP_CT { + f_init(); + f_ScanEvents(); + } + + private function f_init() runs on BSSGP_CT { + /* Connect the UDP socket */ + f_change_state(BVC_S_BLOCKED); + } + + type component BSSGP_CT { + /* UDP port towards the bottom (IUT) */ + port NS_PT BSCP; + /* NS-User SAP towards the user */ + port BSSGP_SP_PT BSSGP_SP; + + var BvcState g_ptp_bvc_state := BVC_S_BLOCKED; + timer g_T1 := 15.0; + timer g_T2 := 60.0; + } + + modulepar { + Nsvci mp_nsei := 2342; + Nsvci mp_bvci := 2342; + BssgpCellId mp_cellid := { ra_id := { lai := { mcc_mnc := '234F04'H, lac := 200}, rac := 0 }, cell_id := 20960 }; + }; + + function f_BnsUdReq(template BssgpPdu pdu) return NsUnitdataRequest { + var NsUnitdataRequest udr := { + bvci := mp_bvci, + nsei := mp_nsei, + /* for some weird reason we get "Dynamic test case error: Text encoder: Encoding an + * unbound integer value." when trying to send the reocrd rather than the octetstring */ + //sdu := omit, + //bssgp := valueof(pdu) + sdu := f_BSSGP_compact_len(enc_BssgpPdu(valueof(pdu))), + bssgp := omit + } + return udr; + } + + function f_BnsUdInd(template BssgpPdu pdu) return template NsUnitdataIndication { + var template NsUnitdataIndication udi := { + bvci := mp_bvci, + nsei := mp_nsei, + sdu := *, + bssgp := pdu + } + return udi; + } + + private function f_change_state(BvcState new_state) runs on BSSGP_CT { + log("BSSGP State Transition: ", g_ptp_bvc_state, " -> ", new_state); + g_ptp_bvc_state := new_state; + BSSGP_SP.send(t_BssgpStsInd(mp_nsei, mp_bvci, g_ptp_bvc_state)); + } + + private function f_sendReset() runs on BSSGP_CT { + var BssgpPdu pdu := valueof(t_BVC_RESET(BSSGP_CAUSE_OM_INTERVENTION, mp_bvci, mp_cellid)); + log("PDU: ", pdu); + log("ENC: ", enc_BssgpPdu(pdu)); + + BSCP.send(f_BnsUdReq(pdu)); + g_T2.start; + //f_change_state(BVC_S_WAIT_RESET); + } + + private function f_sendUnblock() runs on BSSGP_CT { + BSCP.send(f_BnsUdReq(t_BVC_UNBLOCK(mp_bvci))); + g_T1.start; + } + + private function f_sendBlock(BssgpCause cause) runs on BSSGP_CT { + BSCP.send(f_BnsUdReq(t_BVC_BLOCK(mp_bvci, cause))); + g_T1.start; + } + + altstep as_allstate() runs on BSSGP_CT { + var NsUnitdataIndication udi; + var NsStatusIndication nsi; + var ASP_Event evt; + + /* Respond to BLOCK for wrong NSVCI */ + [] BSCP.receive(f_BnsUdInd(t_BVC_BLOCK(?, ?))) -> value udi { + log("Rx BVC-BLOCK for unknown BVCI"); + /* FIXME */ + } + + /* Respond to RESET with correct NSEI/NSVCI */ + [] BSCP.receive(f_BnsUdInd(t_BVC_RESET(?, mp_bvci, mp_cellid))) -> value udi { + f_change_state(BVC_S_UNBLOCKED); + BSCP.send(f_BnsUdReq(t_BVC_RESET_ACK(mp_bvci, mp_cellid))); + } + + /* Respond to RESET with wrong NSEI/NSVCI */ + [] BSCP.receive(f_BnsUdInd(t_BVC_RESET(?, ?, ?))) -> value udi { + log("Rx BVC-RESET for unknown BVCI"); + /* FIXME */ + } + + /* default case of handling unknown PDUs */ + [] BSCP.receive(f_BnsUdInd(?)) -> value udi { + log("Rx Unexpected BSSGP PDU ", udi.bssgp," in state ", g_ptp_bvc_state); + BSCP.send(f_BnsUdReq(t_BSSGP_STATUS({ + t_BSSGP_IE_Cause(BSSGP_CAUSE_PDU_NOT_COMPATIBLE_WITH_PROTOCOL_STATE), + t_BSSGP_IE_Bvci(mp_bvci), t_BSSGP_IE_PDU(udi.bssgp)}))); + } + /* Forwarding of ASP_Event and NsStatusIndication to user */ + [] BSCP.receive(ASP_Event:?) -> value evt { BSSGP_SP.send(evt); } + [] BSCP.receive(NsStatusIndication:?) -> value nsi { + /* if we just became NS-unblocked, send a BCC-RESET */ + if (nsi.old_state != NSE_S_ALIVE_UNBLOCKED and nsi.new_state == NSE_S_ALIVE_UNBLOCKED) { + f_sendReset(); + } + BSSGP_SP.send(nsi); + } + } + + private function f_ScanEvents() runs on BSSGP_CT { + var NsUnitdataIndication udi; + var BssgpPdu bs_pdu; + var default d; + + d := activate(as_allstate()); + + while (true) { + if (g_ptp_bvc_state == BVC_S_BLOCKED) { + alt { + [] g_T1.timeout { + f_sendUnblock(); + } + [] BSCP.receive(f_BnsUdInd(t_BVC_UNBLOCK_ACK(mp_bvci))) { + g_T1.stop; + f_change_state(BVC_S_UNBLOCKED); + } + } + } else if (g_ptp_bvc_state == BVC_S_UNBLOCKED) { + alt { + /* bogus unblock, just respond with ACK */ + [] BSCP.receive(f_BnsUdInd(t_BVC_UNBLOCK(mp_bvci))) -> value udi { + BSCP.send(f_BnsUdReq(t_BVC_UNBLOCK_ACK(mp_bvci))); + } + /* Respond to BLOCK with BLOCK-ACK + change state */ + [] BSCP.receive(f_BnsUdInd(t_BVC_BLOCK(mp_bvci, ?))) -> value udi { + BSCP.send(f_BnsUdReq(t_BVC_BLOCK_ACK(mp_bvci))); + g_T1.stop; + f_change_state(BVC_S_BLOCKED); + } + [] g_T1.timeout { + f_sendBlock(BSSGP_CAUSE_OM_INTERVENTION); + } + [] BSCP.receive(f_BnsUdInd(t_BVC_BLOCK_ACK(mp_bvci))) -> value udi { + g_T1.stop; + f_change_state(BVC_S_BLOCKED); + } + [] BSCP.receive(f_BnsUdInd(t_BVC_RESET_ACK(mp_bvci, mp_cellid))) -> value udi { + g_T2.stop; + f_change_state(BVC_S_UNBLOCKED); + } + /* BSSGP-UNITDATA PDUs from network to NS-UNITDATA.ind to user */ + [] BSCP.receive(f_BnsUdInd(tr_BSSGP_type(DL_UNITDATA))) -> value udi { + BSSGP_SP.send(udi.bssgp); + } + [] BSCP.receive(f_BnsUdInd(tr_BSSGP_type(UL_UNITDATA))) -> value udi { + BSSGP_SP.send(udi.bssgp); + } + /* pass virtually any PDU from user to NS-UNITDATA PDU on network */ + [] BSSGP_SP.receive(BssgpPdu:?) -> value bs_pdu { + BSCP.send(f_BnsUdReq(bs_pdu)); + } + + } + } + + } /* while */ + //deactivate(d); + } +}