Add missing BSSGP_Emulation.ttcn file

This commit is contained in:
Harald Welte 2017-07-23 17:26:17 +02:00
parent 0667eb1797
commit 1733a38561
1 changed files with 220 additions and 0 deletions

View File

@ -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);
}
}