<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>