pespin has submitted this change. ( https://gerrit.osmocom.org/c/libosmo-sigtran/+/41419?usp=email )
Change subject: mtp: Submit MTP-STATUS.ind up over MTP SAP ......................................................................
mtp: Submit MTP-STATUS.ind up over MTP SAP
This allows supporting MTP users other than existing internal SCCP stack.
Change-Id: I5e810451481e50f2942b3a1bf88212326b8d124e --- M include/osmocom/sigtran/mtp_sap.h M src/mtp_sap.c M src/sccp_instance.c M src/ss7_user.h M src/xua_snm.c 5 files changed, 66 insertions(+), 12 deletions(-)
Approvals: osmith: Looks good to me, but someone else must approve laforge: Looks good to me, approved Jenkins Builder: Verified
diff --git a/include/osmocom/sigtran/mtp_sap.h b/include/osmocom/sigtran/mtp_sap.h index 4cc280d..1816b2d 100644 --- a/include/osmocom/sigtran/mtp_sap.h +++ b/include/osmocom/sigtran/mtp_sap.h @@ -56,7 +56,9 @@
struct osmo_mtp_status_param { uint32_t affected_dpc; - uint32_t cause; + uint32_t cause; /* enum mtp_unavail_cause */ + bool congestion_level_present; + uint8_t congestion_level; };
struct osmo_mtp_prim { diff --git a/src/mtp_sap.c b/src/mtp_sap.c index 844b544..8c21f53 100644 --- a/src/mtp_sap.c +++ b/src/mtp_sap.c @@ -95,6 +95,26 @@ return prim; }
+struct osmo_mtp_prim *mtp_prim_status_ind_alloc(uint32_t dpc, + enum mtp_unavail_cause cause, + bool cong_level_present, + uint8_t cong_level) +{ + struct msgb *upmsg = mtp_prim_msgb_alloc(); + struct osmo_mtp_prim *prim; + + OSMO_ASSERT(upmsg); + prim = (struct osmo_mtp_prim *) msgb_put(upmsg, sizeof(*prim)); + osmo_prim_init(&prim->oph, MTP_SAP_USER, + OSMO_MTP_PRIM_STATUS, + PRIM_OP_INDICATION, upmsg); + prim->u.status.affected_dpc = dpc; + prim->u.status.cause = cause; + prim->u.status.congestion_level_present = cong_level_present; + prim->u.status.congestion_level = cong_level; + return prim; +} + struct osmo_mtp_prim *mtp_prim_xfer_ind_alloc(const struct osmo_mtp_transfer_param *param, const uint8_t *user_data, size_t user_data_len) { @@ -158,6 +178,19 @@ } }
+void mtp_status_ind_up_to_all_users(struct osmo_ss7_instance *s7i, + uint32_t dpc, enum mtp_unavail_cause cause, + bool cong_level_present, uint8_t cong_level) +{ + for (unsigned int service_ind = 0; service_ind < ARRAY_SIZE(s7i->user); service_ind++) { + struct osmo_mtp_prim *omp; + if (!s7i->user[service_ind]) + continue; + omp = mtp_prim_status_ind_alloc(dpc, cause, cong_level_present, cong_level); + ss7_user_mtp_sap_prim_up(s7i->user[service_ind], omp); + } +} + /*! \brief Send a MTP SAP Primitive up to the MTP User * \param[in] osu MTP User to whom to send the primitive * \param[in] prim Primitive to send to the user diff --git a/src/sccp_instance.c b/src/sccp_instance.c index a093308..6388b4b 100644 --- a/src/sccp_instance.c +++ b/src/sccp_instance.c @@ -285,6 +285,11 @@ case OSMO_PRIM(OSMO_MTP_PRIM_PAUSE, PRIM_OP_INDICATION): sccp_scmg_rx_mtp_pause(inst, omp->u.pause.affected_dpc); break; + case OSMO_PRIM(OSMO_MTP_PRIM_STATUS, PRIM_OP_INDICATION): + sccp_scmg_rx_mtp_status(inst, omp->u.status.affected_dpc, + omp->u.status.cause, + omp->u.status.congestion_level); + break; default: LOGPSCI(inst, LOGL_ERROR, "Unknown primitive %u:%u receivd\n", oph->primitive, oph->operation); diff --git a/src/ss7_user.h b/src/ss7_user.h index 0da1eea..bec6c22 100644 --- a/src/ss7_user.h +++ b/src/ss7_user.h @@ -3,6 +3,7 @@ #include <stdint.h> #include <unistd.h> #include <osmocom/core/prim.h> +#include <osmocom/sigtran/protocol/mtp.h> #include <osmocom/sigtran/mtp_sap.h>
/*********************************************************************** @@ -29,8 +30,15 @@ struct osmo_mtp_prim *mtp_prim_xfer_ind_alloc(const struct osmo_mtp_transfer_param *param, const uint8_t *user_data, size_t user_data_len);
+struct osmo_mtp_prim *mtp_prim_status_ind_alloc(uint32_t dpc, + enum mtp_unavail_cause cause, + bool cong_level_present, + uint8_t cong_level); void mtp_resume_ind_up_to_all_users(struct osmo_ss7_instance *s7i, uint32_t pc); void mtp_pause_ind_up_to_all_users(struct osmo_ss7_instance *s7i, uint32_t pc); +void mtp_status_ind_up_to_all_users(struct osmo_ss7_instance *s7i, + uint32_t dpc, enum mtp_unavail_cause cause, + bool cong_level_present, uint8_t cong_level);
#define _LOGPSS7U(osu, subsys, level, fmt, args ...) \ diff --git a/src/xua_snm.c b/src/xua_snm.c index adaa7ff..4890f79 100644 --- a/src/xua_snm.c +++ b/src/xua_snm.c @@ -303,13 +303,17 @@ const char *info_str) { struct osmo_ss7_instance *s7i = as->inst; + struct osmo_ss7_user *osu; struct osmo_ss7_asp *asp; uint32_t rctx[OSMO_SS7_MAX_RCTX_COUNT]; unsigned int num_rctx;
- /* 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, 0); + /* Translate to MTP-STATUS.ind towards MTP-User (SCCP will create N-PCSTATE.ind to SCU) */ + osu = ss7_user_find(s7i, user); + if (osu) { + struct osmo_mtp_prim *omp = mtp_prim_status_ind_alloc(dpc, cause, false, 0); + ss7_user_mtp_sap_prim_up(osu, omp); + }
/* inform remote ASPs via DUPU */ llist_for_each_entry(asp, &s7i->asp_list, list) { @@ -333,9 +337,10 @@
/* 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) +static void xua_snm_scon_to_mtp_users(struct osmo_ss7_instance *s7i, + const uint32_t *aff_pc, unsigned int num_aff_pc, + bool cong_level_present, + uint8_t cong_level) { int i;
@@ -347,14 +352,16 @@ uint8_t mask = _aff_pc >> 24;
if (!mask) { - sccp_scmg_rx_mtp_status(sccp, pc, MTP_UNAVAIL_C_CONGESTED, cong_level); + mtp_status_ind_up_to_all_users(s7i, pc, MTP_UNAVAIL_C_CONGESTED, + cong_level_present, 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); + mtp_status_ind_up_to_all_users(s7i, fullpc, MTP_UNAVAIL_C_CONGESTED, + cong_level_present, cong_level); } } } @@ -370,9 +377,8 @@ /* 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); + /* Translate to MTP-STATUS.ind towards MTP Users (SCCP will create N-PCSTATE.ind to SCU) */ + xua_snm_scon_to_mtp_users(s7i, aff_pc, num_aff_pc, !!cong_level, 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