<p>laforge <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/libosmo-sccp/+/22835">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Jenkins Builder: Verified
pespin: Looks good to me, but someone else must approve
laforge: Looks good to me, approved
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">xua_snm: Implement handling of DUPU messages<br><br>A DUPU message in SUA and M3UA indicates the unavailability of<br>a (MTP-level) user, i.e. the entire SCCP, ISUP, ... is not available.<br><br>If we receive a DUPU (destination user part unavailable) message in ASP<br>role, then we must<br> * distribute it to any other ASPs for which we operate in SG mode<br> * pass it as MTP-STATUS.ind to SCCP, which can then generates<br> N-PCSTATE.ind to the SCCP User<br><br>Change-Id: I1559ed0f761a8495b222df48c6bd43798e220471<br>---<br>M include/osmocom/sigtran/protocol/mtp.h<br>M src/m3ua.c<br>M src/osmo_ss7.c<br>M src/sccp_internal.h<br>M src/sccp_scmg.c<br>M src/sua.c<br>M src/xua_internal.h<br>M src/xua_snm.c<br>8 files changed, 222 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/sigtran/protocol/mtp.h b/include/osmocom/sigtran/protocol/mtp.h</span><br><span>index 8b990c0..2f0c7ac 100644</span><br><span>--- a/include/osmocom/sigtran/protocol/mtp.h</span><br><span>+++ b/include/osmocom/sigtran/protocol/mtp.h</span><br><span>@@ -22,3 +22,18 @@</span><br><span> };</span><br><span> </span><br><span> extern const struct value_string mtp_si_vals[];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Chapter 15.17.5 of Q.705 */</span><br><span style="color: hsl(120, 100%, 40%);">+enum mtp_unavail_cause {</span><br><span style="color: hsl(120, 100%, 40%);">+ MTP_UNAVAIL_C_UNKNOWN = 0x0,</span><br><span style="color: hsl(120, 100%, 40%);">+ MTP_UNAVAIL_C_UNEQUIP_REM_USER = 0x1,</span><br><span style="color: hsl(120, 100%, 40%);">+ MTP_UNAVAIL_C_INACC_REM_USER = 0x2,</span><br><span style="color: hsl(120, 100%, 40%);">+ /* reserved */</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+extern const struct value_string mtp_unavail_cause_vals[];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static inline const char *mtp_unavail_cause_str(enum mtp_unavail_cause cs) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return get_value_string(mtp_unavail_cause_vals, cs);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/m3ua.c b/src/m3ua.c</span><br><span>index 6639c28..77326e0 100644</span><br><span>--- a/src/m3ua.c</span><br><span>+++ b/src/m3ua.c</span><br><span>@@ -812,8 +812,29 @@</span><br><span> }</span><br><span> #endif</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* 3.4.5 Destination User Part Unavailable (DUPU) */</span><br><span style="color: hsl(120, 100%, 40%);">+static struct xua_msg *m3ua_encode_dupu(const uint32_t *rctx, unsigned int num_rctx,</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t dpc, uint16_t user, uint16_t cause,</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *info_string)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct xua_msg *xua = xua_msg_alloc();</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t user_cause = (user << 16) | cause;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* TODO: 3.4.5 Destination User Part Unavailable (DUPU) */</span><br><span style="color: hsl(120, 100%, 40%);">+ xua->hdr = XUA_HDR(M3UA_MSGC_SNM, M3UA_SNM_DUNA);</span><br><span style="color: hsl(120, 100%, 40%);">+ xua->hdr.version = M3UA_VERSION;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rctx)</span><br><span style="color: hsl(120, 100%, 40%);">+ xua_msg_add_data(xua, M3UA_IEI_ROUTE_CTX, num_rctx * sizeof(*rctx), (const uint8_t *)rctx);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ xua_msg_add_u32(xua, M3UA_IEI_AFFECTED_PC, dpc);</span><br><span style="color: hsl(120, 100%, 40%);">+ xua_msg_add_u32(xua, M3UA_IEI_USER_CAUSE, user_cause);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (info_string) {</span><br><span style="color: hsl(120, 100%, 40%);">+ xua_msg_add_data(xua, M3UA_IEI_INFO_STRING,</span><br><span style="color: hsl(120, 100%, 40%);">+ strlen(info_string)+1,</span><br><span style="color: hsl(120, 100%, 40%);">+ (const uint8_t *) info_string);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ return xua;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span> </span><br><span> /*! Transmit SSNM DUNA/DAVA message indicating [un]availability of certain point code[s]</span><br><span> * \param[in] asp ASP through which to transmit message. Must be ACTIVE.</span><br><span>@@ -837,6 +858,21 @@</span><br><span> m3ua_tx_xua_asp(asp, xua);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! Transmit SSNM DUPU message indicating user unavailability.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] asp ASP through which to transmit message. Must be ACTIVE.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] rctx array of Routing Contexts in network byte order.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] num_rctx number of rctx</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] dpc affected point code</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] user the user (SI) that is unavailable</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] cause the cause of the user unavailability</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] info_string optional information string (can be NULL). */</span><br><span style="color: hsl(120, 100%, 40%);">+void m3ua_tx_dupu(struct osmo_ss7_asp *asp, const uint32_t *rctx, unsigned int num_rctx,</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t dpc, uint16_t user, uint16_t cause, const char *info_str)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct xua_msg *xua = m3ua_encode_dupu(rctx, num_rctx, dpc, user, cause, info_str);</span><br><span style="color: hsl(120, 100%, 40%);">+ m3ua_tx_xua_asp(asp, xua);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* received SNM message on ASP side */</span><br><span> static int m3ua_rx_snm_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua)</span><br><span> {</span><br><span>@@ -857,6 +893,8 @@</span><br><span> xua_snm_rx_dava(asp, as, xua);</span><br><span> break;</span><br><span> case M3UA_SNM_DUPU:</span><br><span style="color: hsl(120, 100%, 40%);">+ xua_snm_rx_dupu(asp, as, xua);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span> case M3UA_SNM_SCON:</span><br><span> case M3UA_SNM_DRST:</span><br><span> LOGPASP(asp, DLM3UA, LOGL_NOTICE, "Received unsupported M3UA SNM message type %u\n",</span><br><span>diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c</span><br><span>index e549708..a801cc9 100644</span><br><span>--- a/src/osmo_ss7.c</span><br><span>+++ b/src/osmo_ss7.c</span><br><span>@@ -59,6 +59,13 @@</span><br><span> static int32_t next_rctx = 1;</span><br><span> static int32_t next_l_rk_id = 1;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+const struct value_string mtp_unavail_cause_vals[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ { MTP_UNAVAIL_C_UNKNOWN, "unknown" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { MTP_UNAVAIL_C_UNEQUIP_REM_USER, "unequipped-remote-user" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { MTP_UNAVAIL_C_INACC_REM_USER, "inaccessible-remote-user" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0, NULL }</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> struct value_string osmo_ss7_as_traffic_mode_vals[] = {</span><br><span> { OSMO_SS7_AS_TMOD_BCAST, "broadcast" },</span><br><span> { OSMO_SS7_AS_TMOD_LOADSHARE, "loadshare" },</span><br><span>diff --git a/src/sccp_internal.h b/src/sccp_internal.h</span><br><span>index a95b07d..23b3ef3 100644</span><br><span>--- a/src/sccp_internal.h</span><br><span>+++ b/src/sccp_internal.h</span><br><span>@@ -4,6 +4,7 @@</span><br><span> #include <osmocom/core/prim.h></span><br><span> #include <osmocom/sigtran/sccp_sap.h></span><br><span> #include <osmocom/sigtran/osmo_ss7.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/sigtran/protocol/mtp.h></span><br><span> </span><br><span> #define SCCP_STR "Signalling Connection Control Part\n"</span><br><span> </span><br><span>@@ -141,4 +142,5 @@</span><br><span> void sccp_scmg_rx_ssn_prohibited(struct osmo_sccp_instance *inst, uint32_t dpc, uint32_t ssn, uint32_t smi);</span><br><span> void sccp_scmg_rx_mtp_pause(struct osmo_sccp_instance *inst, uint32_t dpc);</span><br><span> void sccp_scmg_rx_mtp_resume(struct osmo_sccp_instance *inst, uint32_t dpc);</span><br><span style="color: hsl(120, 100%, 40%);">+void sccp_scmg_rx_mtp_status(struct osmo_sccp_instance *inst, uint32_t dpc, enum mtp_unavail_cause cause);</span><br><span> int sccp_scmg_init(struct osmo_sccp_instance *inst);</span><br><span>diff --git a/src/sccp_scmg.c b/src/sccp_scmg.c</span><br><span>index 49e09ca..a5d6226 100644</span><br><span>--- a/src/sccp_scmg.c</span><br><span>+++ b/src/sccp_scmg.c</span><br><span>@@ -122,6 +122,39 @@</span><br><span> * [this would require us to track SSNs at each PC, which we don't] */</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+void sccp_scmg_rx_mtp_status(struct osmo_sccp_instance *inst, uint32_t dpc, enum mtp_unavail_cause cause)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_scu_pcstate_param pcstate;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* 1) Informs the translation function to update the translation tables. */</span><br><span style="color: hsl(120, 100%, 40%);">+ /* 2) In the case where the SCCP has received an MTP-STATUS indication primitive relating to</span><br><span style="color: hsl(120, 100%, 40%);">+ Mark the status of the SCCP and each SSN for the relevant destination to "prohibited"</span><br><span style="color: hsl(120, 100%, 40%);">+ and initiates a subsystem status test with SSN = 1. If the cause in the MTP-STATUS</span><br><span style="color: hsl(120, 100%, 40%);">+ indication primitive indicates "unequipped user", then no subsystem status test is</span><br><span style="color: hsl(120, 100%, 40%);">+ initiated. */</span><br><span style="color: hsl(120, 100%, 40%);">+ /* 3) Discontinues all subsystem status tests (including SSN = 1) if an MTP-STATUS</span><br><span style="color: hsl(120, 100%, 40%);">+ indication primitive is received with a cause of "unequipped SCCP". The SCCP</span><br><span style="color: hsl(120, 100%, 40%);">+ discontinues all subsystem status tests, except for SSN = 1, if an MTP-STATUS</span><br><span style="color: hsl(120, 100%, 40%);">+ indication primitive is received with a cause of either "unknown" or "inaccessible" */</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (cause) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case MTP_UNAVAIL_C_UNKNOWN:</span><br><span style="color: hsl(120, 100%, 40%);">+ case MTP_UNAVAIL_C_UNEQUIP_REM_USER:</span><br><span style="color: hsl(120, 100%, 40%);">+ case MTP_UNAVAIL_C_INACC_REM_USER:</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* 4) local broadcast of "user-out-of-service" for each SSN at that dest</span><br><span style="color: hsl(120, 100%, 40%);">+ * [this would require us to track SSNs at each PC, which we don't] */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* 6) local broadcast of "remote SCCP unavailable" */</span><br><span style="color: hsl(120, 100%, 40%);">+ pcstate = (struct osmo_scu_pcstate_param) {</span><br><span style="color: hsl(120, 100%, 40%);">+ .affected_pc = dpc,</span><br><span style="color: hsl(120, 100%, 40%);">+ .restricted_importance_level = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ .sp_status = OSMO_SCCP_SP_S_ACCESSIBLE,</span><br><span style="color: hsl(120, 100%, 40%);">+ .remote_sccp_status = OSMO_SCCP_REM_SCCP_S_UNAVAILABLE_UNKNOWN,</span><br><span style="color: hsl(120, 100%, 40%);">+ };</span><br><span style="color: hsl(120, 100%, 40%);">+ sccp_lbcs_local_bcast_pcstate(inst, &pcstate);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> const struct value_string sccp_scmg_msgt_names[] = {</span><br><span> { SCCP_SCMG_MSGT_SSA, "SSA (Subsystem Allowed)" },</span><br><span> { SCCP_SCMG_MSGT_SSP, "SSP (Subsystem Prohibited)" },</span><br><span>diff --git a/src/sua.c b/src/sua.c</span><br><span>index c9e880f..2ff5a9a 100644</span><br><span>--- a/src/sua.c</span><br><span>+++ b/src/sua.c</span><br><span>@@ -823,6 +823,28 @@</span><br><span> }</span><br><span> #endif</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* 3.4.5 Destination User Part Unavailable (DUPU) */</span><br><span style="color: hsl(120, 100%, 40%);">+static struct xua_msg *sua_encode_dupu(const uint32_t *rctx, unsigned int num_rctx,</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t dpc, uint16_t user, uint16_t cause,</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *info_string)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct xua_msg *xua = xua_msg_alloc();</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t user_cause = (user << 16) | cause;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ xua->hdr = XUA_HDR(SUA_MSGC_SNM, SUA_SNM_DUNA);</span><br><span style="color: hsl(120, 100%, 40%);">+ xua->hdr.version = SUA_VERSION;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rctx)</span><br><span style="color: hsl(120, 100%, 40%);">+ xua_msg_add_data(xua, SUA_IEI_ROUTE_CTX, num_rctx * sizeof(*rctx), (const uint8_t *)rctx);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ xua_msg_add_u32(xua, SUA_IEI_AFFECTED_PC, dpc);</span><br><span style="color: hsl(120, 100%, 40%);">+ xua_msg_add_u32(xua, SUA_IEI_USER_CAUSE, user_cause);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (info_string) {</span><br><span style="color: hsl(120, 100%, 40%);">+ xua_msg_add_data(xua, SUA_IEI_INFO_STRING, strlen(info_string)+1,</span><br><span style="color: hsl(120, 100%, 40%);">+ (const uint8_t *) info_string);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ return xua;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span> </span><br><span> /*! Transmit SSNM DUNA/DAVA message indicating [un]availability of certain point code[s]</span><br><span> * \param[in] asp ASP through whihc to transmit message. Must be ACTIVE.</span><br><span>@@ -848,6 +870,21 @@</span><br><span> sua_tx_xua_asp(asp, xua);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! Transmit SSNM DUPU message indicating user unavailability.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] asp ASP through which to transmit message. Must be ACTIVE.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] rctx array of Routing Contexts in network byte order.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] num_rctx number of rctx</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] dpc affected point code</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] user the user (SI) that is unavailable</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] cause the cause of the user unavailability</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] info_string optional information string (can be NULL). */</span><br><span style="color: hsl(120, 100%, 40%);">+void sua_tx_dupu(struct osmo_ss7_asp *asp, const uint32_t *rctx, unsigned int num_rctx,</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t dpc, uint16_t user, uint16_t cause, const char *info_str)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct xua_msg *xua = sua_encode_dupu(rctx, num_rctx, dpc, user, cause, info_str);</span><br><span style="color: hsl(120, 100%, 40%);">+ sua_tx_xua_asp(asp, xua);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* received SNM message on ASP side */</span><br><span> static int sua_rx_snm_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua)</span><br><span> {</span><br><span>@@ -867,6 +904,8 @@</span><br><span> xua_snm_rx_dava(asp, as, xua);</span><br><span> break;</span><br><span> case SUA_SNM_DUPU:</span><br><span style="color: hsl(120, 100%, 40%);">+ xua_snm_rx_dupu(asp, as, xua);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span> case SUA_SNM_SCON:</span><br><span> case SUA_SNM_DRST:</span><br><span> LOGPASP(asp, DLSUA, LOGL_NOTICE, "Received unsupported SUA SNM message type %u\n",</span><br><span>diff --git a/src/xua_internal.h b/src/xua_internal.h</span><br><span>index e76fddf..4c6bb29 100644</span><br><span>--- a/src/xua_internal.h</span><br><span>+++ b/src/xua_internal.h</span><br><span>@@ -21,6 +21,8 @@</span><br><span> void sua_tx_snm_available(struct osmo_ss7_asp *asp, const uint32_t *rctx, unsigned int num_rctx,</span><br><span> const uint32_t *aff_pc, unsigned int num_aff_pc, const uint32_t *aff_ssn,</span><br><span> const uint32_t *smi, const char *info_string, bool available);</span><br><span style="color: hsl(120, 100%, 40%);">+void sua_tx_dupu(struct osmo_ss7_asp *asp, const uint32_t *rctx, unsigned int num_rctx,</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t dpc, uint16_t user, uint16_t cause, const char *info_str);</span><br><span> </span><br><span> struct osmo_mtp_prim *m3ua_to_xfer_ind(struct xua_msg *xua);</span><br><span> int m3ua_hmdc_rx_from_l2(struct osmo_ss7_instance *inst, struct xua_msg *xua);</span><br><span>@@ -28,9 +30,12 @@</span><br><span> void m3ua_tx_snm_available(struct osmo_ss7_asp *asp, const uint32_t *rctx, unsigned int num_rctx,</span><br><span> const uint32_t *aff_pc, unsigned int num_aff_pc,</span><br><span> const char *info_string, bool available);</span><br><span style="color: hsl(120, 100%, 40%);">+void m3ua_tx_dupu(struct osmo_ss7_asp *asp, const uint32_t *rctx, unsigned int num_rctx,</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t dpc, uint16_t user, uint16_t cause, const char *info_str);</span><br><span> void xua_snm_rx_daud(struct osmo_ss7_asp *asp, struct xua_msg *xua);</span><br><span> void xua_snm_rx_duna(struct osmo_ss7_asp *asp, struct osmo_ss7_as *as, struct xua_msg *xua);</span><br><span> void xua_snm_rx_dava(struct osmo_ss7_asp *asp, struct osmo_ss7_as *as, struct xua_msg *xua);</span><br><span style="color: hsl(120, 100%, 40%);">+void xua_snm_rx_dupu(struct osmo_ss7_asp *asp, struct osmo_ss7_as *as, struct xua_msg *xua);</span><br><span> int m3ua_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg);</span><br><span> </span><br><span> struct msgb *m3ua_msgb_alloc(const char *name);</span><br><span>diff --git a/src/xua_snm.c b/src/xua_snm.c</span><br><span>index 2a383c7..0c14964 100644</span><br><span>--- a/src/xua_snm.c</span><br><span>+++ b/src/xua_snm.c</span><br><span>@@ -29,6 +29,7 @@</span><br><span> #include <osmocom/sigtran/osmo_ss7.h></span><br><span> #include <osmocom/sigtran/protocol/m3ua.h></span><br><span> #include <osmocom/sigtran/protocol/sua.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/sigtran/protocol/mtp.h></span><br><span> </span><br><span> #include "xua_internal.h"</span><br><span> #include "sccp_internal.h"</span><br><span>@@ -99,6 +100,22 @@</span><br><span> }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void xua_tx_upu(struct osmo_ss7_asp *asp, const uint32_t *rctx, unsigned int num_rctx,</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t dpc, uint16_t user, uint16_t cause, const char *info_str)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (asp->cfg.proto) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case OSMO_SS7_ASP_PROT_M3UA:</span><br><span style="color: hsl(120, 100%, 40%);">+ m3ua_tx_dupu(asp, rctx, num_rctx, dpc, user, cause, info_str);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case OSMO_SS7_ASP_PROT_SUA:</span><br><span style="color: hsl(120, 100%, 40%);">+ sua_tx_dupu(asp, rctx, num_rctx, dpc, user, cause, info_str);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* generate MTP-PAUSE / MTP-RESUME towards local SCCP users */</span><br><span> static void xua_snm_pc_available_to_sccp(struct osmo_sccp_instance *sccp,</span><br><span> const uint32_t *aff_pc, unsigned int num_aff_pc,</span><br><span>@@ -208,6 +225,37 @@</span><br><span> }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void xua_snm_upu(struct osmo_ss7_as *as, uint32_t dpc, uint16_t user, uint16_t cause,</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *info_str)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_ss7_instance *s7i = as->inst;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_ss7_asp *asp;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t rctx[32];</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int num_rctx;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Translate to MTP-STATUS.ind towards SCCP (will create N-PCSTATE.ind to SCU) */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (s7i->sccp && user == MTP_SI_SCCP)</span><br><span style="color: hsl(120, 100%, 40%);">+ sccp_scmg_rx_mtp_status(s7i->sccp, dpc, cause);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* inform remote ASPs via DUPU */</span><br><span style="color: hsl(120, 100%, 40%);">+ llist_for_each_entry(asp, &s7i->asp_list, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* SSNM is only permitted for ASPs in ACTIVE state */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!osmo_ss7_asp_active(asp))</span><br><span style="color: hsl(120, 100%, 40%);">+ continue;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* only send DAVA/DUNA if we locally are the SG and the remote is ASP */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (asp->cfg.role != OSMO_SS7_ASP_ROLE_SG)</span><br><span style="color: hsl(120, 100%, 40%);">+ continue;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ num_rctx = get_all_rctx_for_asp(rctx, ARRAY_SIZE(rctx), asp, as);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* this can happen if the given ASP is only in the AS that reports the change,</span><br><span style="color: hsl(120, 100%, 40%);">+ * which shall be excluded */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (num_rctx == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ continue;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ xua_tx_upu(asp, rctx, num_rctx, dpc, user, cause, info_str);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span> </span><br><span> /* receive DAUD from ASP; pc is 'affected PC' IE with mask in network byte order! */</span><br><span> void xua_snm_rx_daud(struct osmo_ss7_asp *asp, struct xua_msg *xua)</span><br><span>@@ -323,3 +371,37 @@</span><br><span> ie_aff_pc->len / sizeof(uint32_t), info_str, true);</span><br><span> }</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* an incoming SUA/M3UA DUPU was received from a remote SG */</span><br><span style="color: hsl(120, 100%, 40%);">+void xua_snm_rx_dupu(struct osmo_ss7_asp *asp, struct osmo_ss7_as *as, struct xua_msg *xua)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t aff_pc = xua_msg_get_u32(xua, SUA_IEI_AFFECTED_PC);</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *info_str = xua_msg_get_str(xua, SUA_IEI_INFO_STRING);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* TODO: should our processing depend on the RCTX included? I somehow don't think so */</span><br><span style="color: hsl(120, 100%, 40%);">+ //struct xua_msg_part *ie_rctx = xua_msg_find_tag(xua, SUA_IEI_ROUTE_CTX);</span><br><span style="color: hsl(120, 100%, 40%);">+ int log_ss = osmo_ss7_asp_get_log_subsys(asp);</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t cause_user;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t cause, user;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (asp->cfg.role != OSMO_SS7_ASP_ROLE_ASP)</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (asp->cfg.proto) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case OSMO_SS7_ASP_PROT_M3UA:</span><br><span style="color: hsl(120, 100%, 40%);">+ cause_user = xua_msg_get_u32(xua, M3UA_IEI_USER_CAUSE);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case OSMO_SS7_ASP_PROT_SUA:</span><br><span style="color: hsl(120, 100%, 40%);">+ cause_user = xua_msg_get_u32(xua, SUA_IEI_USER_CAUSE);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ cause = cause_user >> 16;</span><br><span style="color: hsl(120, 100%, 40%);">+ user = cause_user & 0xffff;</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPASP(asp, log_ss, LOGL_NOTICE, "Rx DUPU(%s) for %s User %s, cause %u\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ info_str ? info_str : "", osmo_ss7_pointcode_print(asp->inst, aff_pc),</span><br><span style="color: hsl(120, 100%, 40%);">+ get_value_string(mtp_si_vals, user), cause);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ xua_snm_upu(as, aff_pc, user, cause, info_str);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/libosmo-sccp/+/22835">change 22835</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/libosmo-sccp/+/22835"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: libosmo-sccp </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I1559ed0f761a8495b222df48c6bd43798e220471 </div>
<div style="display:none"> Gerrit-Change-Number: 22835 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-CC: fixeria <vyanitskiy@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>