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