pespin submitted this change.

View Change

Approvals: Jenkins Builder: Verified pespin: Looks good to me, approved
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(-)

diff --git a/include/osmocom/sigtran/protocol/mtp.h b/include/osmocom/sigtran/protocol/mtp.h
index 2f0c7ac..4542289 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.704 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 change 41092. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: merged
Gerrit-Project: libosmo-sigtran
Gerrit-Branch: master
Gerrit-Change-Id: I82541612c039b1cc0191cb44d2eecdcbb07fae96
Gerrit-Change-Number: 41092
Gerrit-PatchSet: 2
Gerrit-Owner: pespin <pespin@sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy@sysmocom.de>
Gerrit-Reviewer: laforge <laforge@osmocom.org>
Gerrit-Reviewer: pespin <pespin@sysmocom.de>