aboutsummaryrefslogtreecommitdiffstats
path: root/src/gb/gprs_ns2_sns.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gb/gprs_ns2_sns.c')
-rw-r--r--src/gb/gprs_ns2_sns.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/src/gb/gprs_ns2_sns.c b/src/gb/gprs_ns2_sns.c
index 22ca7b2a..c1be0ab8 100644
--- a/src/gb/gprs_ns2_sns.c
+++ b/src/gb/gprs_ns2_sns.c
@@ -201,6 +201,7 @@ static void _sns_failed(struct osmo_fsm_inst *fi, const char *reason, const char
if (reason)
LOGPFSMLSRC(fi, LOGL_ERROR, file, line, "NSE %d: SNS failed: %s\n", gss->nse->nsei, reason);
+ gss->alive = false;
if (gss->role == GPRS_SNS_ROLE_SGSN) {
if (!gss->nse->persistent)
gprs_ns2_free_nse(gss->nse);
@@ -2599,19 +2600,33 @@ void ns2_sns_notify_alive(struct gprs_ns2_nse *nse, struct gprs_ns2_vc *nsvc, bo
if (gss->block_no_nsvc_events)
return;
- if (alive == gss->alive)
+ if (gss->alive && nse->sum_sig_weight == 0) {
+ sns_failed(nse->bss_sns_fi, "No signalling NSVC available");
return;
+ }
/* check if this is the current SNS NS-VC */
- if (nsvc == gss->sns_nsvc) {
+ if (nsvc == gss->sns_nsvc && !alive) {
/* only replace the SNS NS-VC if there are other alive NS-VC.
* There aren't any other alive NS-VC when the SNS fsm just reached CONFIGURED
* and couldn't confirm yet if the NS-VC comes up */
- if (gss->alive && !alive)
- ns2_sns_replace_nsvc(nsvc);
+ llist_for_each_entry(tmp, &nse->nsvc, list) {
+ if (nsvc == tmp)
+ continue;
+ if (ns2_vc_is_unblocked(nsvc)) {
+ ns2_sns_replace_nsvc(nsvc);
+ break;
+ }
+ }
}
+ if (alive == gss->alive)
+ return;
+
if (alive) {
+ /* we need at least a signalling NSVC before become alive */
+ if (nse->sum_sig_weight == 0)
+ return;
gss->alive = true;
osmo_fsm_inst_dispatch(nse->bss_sns_fi, NS2_SNS_EV_REQ_NSVC_ALIVE, NULL);
} else {