pespin has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/osmo-bsc/+/41993?usp=email )


Change subject: Lb: Handle N-PCSTATE.ind
......................................................................

Lb: Handle N-PCSTATE.ind

Change-Id: I16900b9c2b840d4c7d8471c1f69b19601e892b2d
---
M src/osmo-bsc/lb.c
1 file changed, 104 insertions(+), 0 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/93/41993/1

diff --git a/src/osmo-bsc/lb.c b/src/osmo-bsc/lb.c
index 14e3bd8..a413d2d 100644
--- a/src/osmo-bsc/lb.c
+++ b/src/osmo-bsc/lb.c
@@ -144,6 +144,17 @@
        return NULL;
 }

+/* Find an SMLC by its remote sigtran point code on a given cs7 instance. */
+static struct smlc_config *get_smlc_by_pc(uint32_t pc)
+{
+       struct smlc_config *smlc = bsc_gsmnet->smlc;
+       if ((smlc->smlc_addr.presence & OSMO_SCCP_ADDR_T_PC) == 0)
+               return NULL;
+       if (smlc->smlc_addr.pc != pc)
+               return NULL;
+       return smlc;
+}
+
 static int handle_notice_ind(const struct osmo_scu_notice_param *ni)
 {
        int rc = 0;
@@ -175,6 +186,95 @@
        return rc;
 }

+static void handle_pcstate_ind(struct osmo_ss7_instance *cs7, const struct 
osmo_scu_pcstate_param *pcst)
+{
+       struct smlc_config *smlc;
+       bool connected;
+       bool disconnected;
+
+       LOGP(DLCS, LOGL_DEBUG, "N-PCSTATE ind: affected_pc=%u=%s sp_status=%s 
remote_sccp_status=%s\n",
+            pcst->affected_pc, osmo_ss7_pointcode_print(cs7, 
pcst->affected_pc),
+            osmo_sccp_sp_status_name(pcst->sp_status),
+            osmo_sccp_rem_sccp_status_name(pcst->remote_sccp_status));
+
+       /* If we don't care about that point-code, ignore PCSTATE. */
+       smlc = get_smlc_by_pc(pcst->affected_pc);
+       if (!smlc)
+               return;
+
+       /* See if this marks the point code to have become available, or to 
have been lost.
+        *
+        * I want to detect two events:
+        * - connection event (both indicators say PC is reachable).
+        * - disconnection event (at least one indicator says the PC is not 
reachable).
+        *
+        * There are two separate incoming indicators with various possible 
values -- the incoming events can be:
+        *
+        * - neither connection nor disconnection indicated -- just indicating 
congestion
+        *   connected == false, disconnected == false --> do nothing.
+        * - both incoming values indicate that we are connected
+        *   --> trigger connected
+        * - both indicate we are disconnected
+        *   --> trigger disconnected
+        * - one value indicates 'connected', the other indicates 'disconnected'
+        *   --> trigger disconnected
+        *
+        * Congestion could imply that we're connected, but it does not 
indicate that a PC's reachability changed, so no need to
+        * trigger on that.
+        */
+       connected = false;
+       disconnected = false;
+
+       switch (pcst->sp_status) {
+       case OSMO_SCCP_SP_S_ACCESSIBLE:
+               connected = true;
+               break;
+       case OSMO_SCCP_SP_S_INACCESSIBLE:
+               disconnected = true;
+               break;
+       default:
+       case OSMO_SCCP_SP_S_CONGESTED:
+               /* Neither connecting nor disconnecting */
+               break;
+       }
+
+       switch (pcst->remote_sccp_status) {
+       case OSMO_SCCP_REM_SCCP_S_AVAILABLE:
+               if (!disconnected)
+                       connected = true;
+               break;
+       case OSMO_SCCP_REM_SCCP_S_UNAVAILABLE_UNKNOWN:
+       case OSMO_SCCP_REM_SCCP_S_UNEQUIPPED:
+       case OSMO_SCCP_REM_SCCP_S_INACCESSIBLE:
+               disconnected = true;
+               connected = false;
+               break;
+       default:
+       case OSMO_SCCP_REM_SCCP_S_CONGESTED:
+               /* Neither connecting nor disconnecting */
+               break;
+       }
+
+       if (disconnected && bssmap_reset_is_conn_ready(smlc->bssmap_reset)) {
+               LOGP(DLCS, LOGL_NOTICE,
+                    "now unreachable: N-PCSTATE ind: pc=%u=%s sp_status=%s 
remote_sccp_status=%s\n",
+                    pcst->affected_pc, osmo_ss7_pointcode_print(cs7, 
pcst->affected_pc),
+                    osmo_sccp_sp_status_name(pcst->sp_status),
+                    osmo_sccp_rem_sccp_status_name(pcst->remote_sccp_status));
+               /* A previously usable MSC has disconnected. Kick the BSSMAP 
back to DISC state. */
+               bssmap_reset_set_disconnected(smlc->bssmap_reset);
+       } else if (connected && 
!bssmap_reset_is_conn_ready(smlc->bssmap_reset)) {
+               LOGP(DLCS, LOGL_NOTICE,
+                    "now available: N-PCSTATE ind: pc=%u=%s sp_status=%s 
remote_sccp_status=%s\n",
+                    pcst->affected_pc, osmo_ss7_pointcode_print(cs7, 
pcst->affected_pc),
+                    osmo_sccp_sp_status_name(pcst->sp_status),
+                    osmo_sccp_rem_sccp_status_name(pcst->remote_sccp_status));
+               /* A previously unusable MSC has become reachable. Trigger 
immediate BSSMAP RESET -- we would resend a
+                * RESET either way, but we might as well do it now to speed up 
connecting. */
+               bssmap_reset_resend_reset(smlc->bssmap_reset);
+       }
+}
+
 static int sccp_sap_up(struct osmo_prim_hdr *oph, void *_scu)
 {
        struct osmo_scu_prim *scu_prim = (struct osmo_scu_prim *)oph;
@@ -257,6 +357,10 @@
                }
                break;

+       case OSMO_PRIM(OSMO_SCU_PRIM_N_PCSTATE, PRIM_OP_INDICATION):
+               handle_pcstate_ind(osmo_sccp_get_ss7(sccp), 
&scu_prim->u.pcstate);
+               break;
+
        default:
                LOGP(DLCS, LOGL_ERROR, "Unhandled SIGTRAN primitive %s.%s\n",
                     osmo_scu_prim_type_name(oph->primitive),

--
To view, visit https://gerrit.osmocom.org/c/osmo-bsc/+/41993?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings?usp=email

Gerrit-MessageType: newchange
Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: I16900b9c2b840d4c7d8471c1f69b19601e892b2d
Gerrit-Change-Number: 41993
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <[email protected]>

Reply via email to