pespin has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/libosmo-sigtran/+/41092?usp=email )


Change subject: Propagate rx M3UA SCON -> MTP-STATUS.ind -> N-PCSTATE.ind
......................................................................

Propagate rx M3UA SCON -> MTP-STATUS.ind -> N-PCSTATE.ind

Change-Id: I82541612c039b1cc0191cb44d2eecdcbb07fae96
---
M include/osmocom/sigtran/protocol/mtp.h
M src/sccp_internal.h
M src/sccp_scmg.c
M src/xua_snm.c
4 files changed, 74 insertions(+), 17 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/libosmo-sigtran 
refs/changes/92/41092/1

diff --git a/include/osmocom/sigtran/protocol/mtp.h 
b/include/osmocom/sigtran/protocol/mtp.h
index 2f0c7ac..408e442 100644
--- a/include/osmocom/sigtran/protocol/mtp.h
+++ b/include/osmocom/sigtran/protocol/mtp.h
@@ -24,11 +24,19 @@
 extern const struct value_string mtp_si_vals[];


-/* Chapter 15.17.5 of Q.705 */
+/* Chapter 15.17.5 of Q.704 */
 enum mtp_unavail_cause {
        MTP_UNAVAIL_C_UNKNOWN           = 0x0,
        MTP_UNAVAIL_C_UNEQUIP_REM_USER  = 0x1,
        MTP_UNAVAIL_C_INACC_REM_USER    = 0x2,
+       /* This field is not explicitly listed in Q.705 15.17.5, but it is
+        * expicitly described as one of four options in:
+        * Q.701 "TABLE 1" and 8.4
+        * Q.704 2.4.2
+        * Q.711 "Table 18" and 7.2.4
+        * Q.714 "Figure D.4"
+        */
+       MTP_UNAVAIL_C_CONGESTED         = 0x3,
        /* reserved */
 };

diff --git a/src/sccp_internal.h b/src/sccp_internal.h
index 045e49b..5b1b94d 100644
--- a/src/sccp_internal.h
+++ b/src/sccp_internal.h
@@ -80,5 +80,5 @@
 void sccp_scmg_rx_ssn_prohibited(struct osmo_sccp_instance *inst, uint32_t 
dpc, uint32_t ssn, uint32_t smi);
 void sccp_scmg_rx_mtp_pause(struct osmo_sccp_instance *inst, uint32_t dpc);
 void sccp_scmg_rx_mtp_resume(struct osmo_sccp_instance *inst, uint32_t dpc);
-void sccp_scmg_rx_mtp_status(struct osmo_sccp_instance *inst, uint32_t dpc, 
enum mtp_unavail_cause cause);
+void sccp_scmg_rx_mtp_status(struct osmo_sccp_instance *inst, uint32_t dpc, 
enum mtp_unavail_cause cause, uint8_t cong_level);
 int sccp_scmg_init(struct osmo_sccp_instance *inst);
diff --git a/src/sccp_scmg.c b/src/sccp_scmg.c
index 2ffedce..a0f9e1c 100644
--- a/src/sccp_scmg.c
+++ b/src/sccp_scmg.c
@@ -125,7 +125,8 @@
         * [this would require us to track SSNs at each PC, which we don't] */
 }

-void sccp_scmg_rx_mtp_status(struct osmo_sccp_instance *inst, uint32_t dpc, 
enum mtp_unavail_cause cause)
+/* ITU-T Q.701 8.4, ITU-T Q.711 7.2.4 */
+void sccp_scmg_rx_mtp_status(struct osmo_sccp_instance *inst, uint32_t dpc, 
enum mtp_unavail_cause cause, uint8_t cong_level)
 {
        struct osmo_scu_pcstate_param pcstate;
        /* 1) Informs the translation function to update the translation 
tables. */
@@ -142,20 +143,35 @@
        case MTP_UNAVAIL_C_UNKNOWN:
        case MTP_UNAVAIL_C_UNEQUIP_REM_USER:
        case MTP_UNAVAIL_C_INACC_REM_USER:
+               /* 4) local broadcast of "user-out-of-service" for each SSN at 
that dest
+               * [this would require us to track SSNs at each PC, which we 
don't] */
+
+               /* 6) local broadcast of "remote SCCP unavailable" */
+               pcstate = (struct osmo_scu_pcstate_param) {
+                       .affected_pc = dpc,
+                       /* cong_level/RIL doesn't apply here: */
+                       .restricted_importance_level = 0,
+                       .sp_status = OSMO_SCCP_SP_S_ACCESSIBLE,
+                       .remote_sccp_status = 
OSMO_SCCP_REM_SCCP_S_UNAVAILABLE_UNKNOWN,
+               };
+               sccp_lbcs_local_bcast_pcstate(inst, &pcstate);
+               break;
+       case MTP_UNAVAIL_C_CONGESTED:
+               /* ITU-T Q.714 5.2.4 Signalling point congested
+                * ITU-T Q.714 5.2.8 Inter- and Intra- SCCP management 
congestion reports procedure
+                * ITU-T Q.714 5.3.6.6 Restricted importance level reporting
+                * ITU-T Q.714 Figure D.4
+                * ITU-T Q.715 9.5 Coordination of congestion control measures 
between SCCP and other MTP users */
+               pcstate = (struct osmo_scu_pcstate_param) {
+                       .affected_pc = dpc,
+                       .restricted_importance_level = cong_level,
+                       .sp_status = OSMO_SCCP_SP_S_CONGESTED,
+                       .remote_sccp_status = (cong_level == 0) ? 
OSMO_SCCP_REM_SCCP_S_AVAILABLE :
+                                                                 
OSMO_SCCP_REM_SCCP_S_CONGESTED,
+               };
+               sccp_lbcs_local_bcast_pcstate(inst, &pcstate);
                break;
        }
-
-       /* 4) local broadcast of "user-out-of-service" for each SSN at that dest
-        * [this would require us to track SSNs at each PC, which we don't] */
-
-       /* 6) local broadcast of "remote SCCP unavailable" */
-       pcstate = (struct osmo_scu_pcstate_param) {
-               .affected_pc = dpc,
-               .restricted_importance_level = 0,
-               .sp_status = OSMO_SCCP_SP_S_ACCESSIBLE,
-               .remote_sccp_status = OSMO_SCCP_REM_SCCP_S_UNAVAILABLE_UNKNOWN,
-       };
-       sccp_lbcs_local_bcast_pcstate(inst, &pcstate);
 }

 const struct value_string sccp_scmg_msgt_names[] = {
diff --git a/src/xua_snm.c b/src/xua_snm.c
index 344cc63..fd2ef24 100644
--- a/src/xua_snm.c
+++ b/src/xua_snm.c
@@ -309,7 +309,7 @@

        /* Translate to MTP-STATUS.ind towards SCCP (will create N-PCSTATE.ind 
to SCU) */
        if (s7i->sccp && user == MTP_SI_SCCP)
-               sccp_scmg_rx_mtp_status(s7i->sccp, dpc, cause);
+               sccp_scmg_rx_mtp_status(s7i->sccp, dpc, cause, 0);

        /* inform remote ASPs via DUPU */
        llist_for_each_entry(asp, &s7i->asp_list, list) {
@@ -331,6 +331,34 @@
        }
 }

+/* ITU Q.701 8.4 "The level value is included if national options with 
congestion priorities or multiple signalling link states
+without congestion priorities as in Recommendation Q.704 are implemented" */
+static void xua_snm_scon_to_sccp(struct osmo_sccp_instance *sccp,
+                                const uint32_t *aff_pc, unsigned int 
num_aff_pc,
+                                uint8_t cong_level)
+{
+       int i;
+
+       for (i = 0; i < num_aff_pc; i++) {
+               /* 32bit "Affected Point Code" consists of a 7-bit mask 
followed by 14/16/24-bit SS7 PC,
+                * see RFC 4666 3.4.1 */
+               uint32_t _aff_pc = ntohl(aff_pc[i]);
+               uint32_t pc = _aff_pc & 0xffffff;
+               uint8_t mask = _aff_pc >> 24;
+
+               if (!mask) {
+                       sccp_scmg_rx_mtp_status(sccp, pc, 
MTP_UNAVAIL_C_CONGESTED, cong_level);
+               } else {
+                       /* we have to send one MTP primitive for each 
individual point
+                        * code within that mask */
+                       uint32_t maskbits = (1 << mask) - 1;
+                       uint32_t fullpc;
+                       for (fullpc = (pc & ~maskbits); fullpc <= (pc | 
maskbits); fullpc++)
+                               sccp_scmg_rx_mtp_status(sccp, fullpc, 
MTP_UNAVAIL_C_CONGESTED, cong_level);
+               }
+       }
+}
+
 static void xua_snm_scon(struct osmo_ss7_as *as, const uint32_t *aff_pc, 
unsigned int num_aff_pc,
                         const uint32_t *concerned_dpc, const uint8_t 
*cong_level, const char *info_string)
 {
@@ -339,7 +367,12 @@
        uint32_t rctx[OSMO_SS7_MAX_RCTX_COUNT];
        unsigned int num_rctx;

-       /* TODO: Translate to MTP-STATUS.ind towards SCCP (will create 
N-PCSTATE.ind to SCU) */
+       /* TODO: Change Congested level/state of related routes,
+        * see ITU Q.704 3.8.4 "Congestion status of signalling route sets" */
+
+       /* Translate to MTP-STATUS.ind towards SCCP (will create N-PCSTATE.ind 
to SCU) */
+       if (s7i->sccp)
+               xua_snm_scon_to_sccp(s7i->sccp, aff_pc, num_aff_pc, cong_level 
? *cong_level : 0);

        /* RFC4666 1.4.6: "When an SG receives a congestion message (SCON) from 
an ASP and the SG
         * determines that an SPMC is now encountering congestion, it MAY 
trigger SS7 MTP3 Transfer

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

Gerrit-MessageType: newchange
Gerrit-Project: libosmo-sigtran
Gerrit-Branch: master
Gerrit-Change-Id: I82541612c039b1cc0191cb44d2eecdcbb07fae96
Gerrit-Change-Number: 41092
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <[email protected]>

Reply via email to