Add missing BSSGP_Emulation.ttcn file
diff --git a/gprs_gb/BSSGP_Emulation.ttcn b/gprs_gb/BSSGP_Emulation.ttcn
new file mode 100644
index 0000000..25b96cd
--- /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);
+ }
+}