From dc0a090ae14004b363f058b2c9992eeade2abb62 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 10 Nov 2020 21:03:29 +0100 Subject: NS+BSSGP: Only send BVC-RESET when _first_ NSVC of NSVCG becomes unblocked In case of a NS-VCG with multiple NS-VC, we must BVC-RESET only when the first NS-VC becomes unblocked, i.e. as soon as we have any connection to the peer at all. Whether we have further additional links doesn't matter, at least not in the sense that all state should be reset. Change-Id: I69b2e9bd919fc981f189b6671b4234c3642e2449 --- library/BSSGP_Emulation.ttcnpp | 6 +++--- library/NS_Emulation.ttcnpp | 46 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/library/BSSGP_Emulation.ttcnpp b/library/BSSGP_Emulation.ttcnpp index a4a939d2..1370958d 100644 --- a/library/BSSGP_Emulation.ttcnpp +++ b/library/BSSGP_Emulation.ttcnpp @@ -359,7 +359,7 @@ altstep as_sig_unblocked() runs on BSSGP_CT { /* We are in BVC_S_WAIT_NS_ALIVE_UNBLOCKED (only happens in BSS role) */ altstep as_sig_wait_ns_alive_unblocked() runs on BSSGP_CT { var NsStatusIndication nsi; - [] BSCP.receive(NsStatusIndication:{g_cfg.nsei,?, complement (NSVC_S_ALIVE_UNBLOCKED), NSVC_S_ALIVE_UNBLOCKED}) -> value nsi { + [] BSCP.receive(NsStatusIndication:{g_cfg.nsei,?, complement (NSVC_S_ALIVE_UNBLOCKED), NSVC_S_ALIVE_UNBLOCKED, true}) -> value nsi { /* if we just became NS-unblocked, send a BCC-RESET */ if (g_cfg.sgsn_role == false) { BSCP.send(f_BnsUdReq(ts_BVC_RESET(BSSGP_CAUSE_OM_INTERVENTION, 0, omit), 0)); @@ -450,9 +450,9 @@ altstep as_sig_allstate() runs on BSSGP_CT { } } /* Keep NS Status Indicaitons to us; no need to inform per-BVC components [for now?] */ - [] BSCP.receive(NsStatusIndication:{g_cfg.nsei, ?, ?, ?}) -> value nsi { } + [] BSCP.receive(tr_NsStsInd(g_cfg.nsei)) -> value nsi { } /* We should never see any different NSEI: There's one BSSGP_CT per NSE */ - [] BSCP.receive(NsStatusIndication:{?, ?, ?, ?}) -> value nsi { + [] BSCP.receive(tr_NsStsInd(?)) -> value nsi { setverdict(fail, "Rx NsStatusInd for wrong NSEI ", nsi); } diff --git a/library/NS_Emulation.ttcnpp b/library/NS_Emulation.ttcnpp index e2869458..79589384 100644 --- a/library/NS_Emulation.ttcnpp +++ b/library/NS_Emulation.ttcnpp @@ -73,25 +73,30 @@ module NS_Emulation { Nsei nsei, Nsvci nsvci, NsvcState old_state, - NsvcState new_state + NsvcState new_state, + boolean first_or_last } template (present) NsStatusIndication tr_NsStsInd(template (present) Nsei nsei := ?, template (present) Nsvci nsvci := ?, template (present) NsvcState old_state := ?, - template (present) NsvcState state := ?) := { + template (present) NsvcState state := ?, + template (present) boolean first_or_last := ?) := { nsei := nsei, nsvci := nsvci, old_state := old_state, - new_state := state + new_state := state, + first_or_last := first_or_last } - template (value) NsStatusIndication ts_NsStsInd(Nsei nsei, Nsvci nsvci, NsvcState old_state, NsvcState state) := { + template (value) NsStatusIndication ts_NsStsInd(Nsei nsei, Nsvci nsvci, NsvcState old_state, NsvcState state, + boolean first_or_last := false) := { nsei := nsei, nsvci := nsvci, old_state := old_state, - new_state := state + new_state := state, + first_or_last := first_or_last } type enumerated NsvcState { @@ -247,12 +252,41 @@ module NS_Emulation { } } + function f_count_nsvcs_in_state(template NsvcState state := ?) runs on NS_CT return integer { + var integer i; + var integer res := 0; + for (i := 0; i < lengthof(g_nsvcs); i := i+1) { + if (match(g_nsvcs[i].state, state)) { + res := res + 1; + } + } + return res; + } + private altstep as_ns_common() runs on NS_CT { var NsStatusIndication rx_nssi; var NsUnitdataIndication rx_nsudi; var NsUnitdataRequest rx_nsudr; /* pass from NS-VCs up to user */ - [] NSVC.receive(tr_NsStsInd(g_config.nsei)) -> value rx_nssi { + [] NSVC.receive(tr_NsStsInd(g_config.nsei, ?, ?, NSVC_S_ALIVE_UNBLOCKED)) -> value rx_nssi { + /* check if this one is the first to be unblocked */ + var integer num_nsvc_unblocked := f_count_nsvcs_in_state(NSVC_S_ALIVE_UNBLOCKED); + f_nsvc_update_state(rx_nssi.nsvci, rx_nssi.new_state); + if (num_nsvc_unblocked == 0) { + rx_nssi.first_or_last := true; + } + NS_SP.send(rx_nssi); + } + [] NSVC.receive(tr_NsStsInd(g_config.nsei, ?, ?, NSVC_S_DEAD_BLOCKED)) -> value rx_nssi { + f_nsvc_update_state(rx_nssi.nsvci, rx_nssi.new_state); + /* check if this one is the last to be blocked */ + var integer num_nsvc_unblocked := f_count_nsvcs_in_state(NSVC_S_ALIVE_UNBLOCKED); + if (num_nsvc_unblocked == 0) { + rx_nssi.first_or_last := true; + } + NS_SP.send(rx_nssi); + } + [] NSVC.receive(tr_NsStsInd(g_config.nsei, ?, ?, ?)) -> value rx_nssi { f_nsvc_update_state(rx_nssi.nsvci, rx_nssi.new_state); NS_SP.send(rx_nssi); } -- cgit v1.2.3