<p>laforge has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/libosmo-sccp/+/22833">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">sua: per-ssn DUNA/DAVA notification<br><br>Unlike M3UA, in SUA a DUNA/DAVA message can contain not just the point<br>code that became available / unavailable, but it can also include a SSN.<br><br>In that case, it is just the SSN that became available/unavailable, and<br>not the entire point code.  Hence, a N-STATE.ind and not a N-PCSTATE.ind<br>must be delivered to the SCCP user.<br><br>Change-Id: Ie9a45b905bc17e7b695e15fe12ba4bbadcd032bf<br>---<br>M src/sccp_internal.h<br>M src/sccp_scmg.c<br>M src/xua_snm.c<br>3 files changed, 120 insertions(+), 2 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/33/22833/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/sccp_internal.h b/src/sccp_internal.h</span><br><span>index 6bd2af9..a95b07d 100644</span><br><span>--- a/src/sccp_internal.h</span><br><span>+++ b/src/sccp_internal.h</span><br><span>@@ -137,6 +137,8 @@</span><br><span>                                 const struct osmo_scu_state_param *state);</span><br><span> </span><br><span> /* SCCP Management (SCMG) */</span><br><span style="color: hsl(120, 100%, 40%);">+void sccp_scmg_rx_ssn_allowed(struct osmo_sccp_instance *inst, uint32_t dpc, uint32_t ssn, uint32_t smi);</span><br><span style="color: hsl(120, 100%, 40%);">+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> 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 0e3905d..ed16fe7 100644</span><br><span>--- a/src/sccp_scmg.c</span><br><span>+++ b/src/sccp_scmg.c</span><br><span>@@ -36,6 +36,45 @@</span><br><span> #include "xua_internal.h"</span><br><span> #include "sccp_internal.h"</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* ITU-T Q.714 5.3.3 Subsystem allowed */</span><br><span style="color: hsl(120, 100%, 40%);">+void sccp_scmg_rx_ssn_allowed(struct osmo_sccp_instance *inst, uint32_t dpc, uint32_t ssn, uint32_t smi)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    struct osmo_scu_state_param state;</span><br><span style="color: hsl(120, 100%, 40%);">+    /* 1) Instruct the translation function to update the translation tables */</span><br><span style="color: hsl(120, 100%, 40%);">+   /* 2) Mark as "allowed" the status of that subsystem. */</span><br><span style="color: hsl(120, 100%, 40%);">+    /* 3) Initiate a local broadcast of "User-in-service" information for the allowed subsystem */</span><br><span style="color: hsl(120, 100%, 40%);">+      state = (struct osmo_scu_state_param) {</span><br><span style="color: hsl(120, 100%, 40%);">+               .affected_pc = dpc,</span><br><span style="color: hsl(120, 100%, 40%);">+           .affected_ssn = ssn,</span><br><span style="color: hsl(120, 100%, 40%);">+          .user_in_service = true,</span><br><span style="color: hsl(120, 100%, 40%);">+              .ssn_multiplicity_ind = smi,</span><br><span style="color: hsl(120, 100%, 40%);">+  };</span><br><span style="color: hsl(120, 100%, 40%);">+    sccp_lbcs_local_bcast_state(inst, &state);</span><br><span style="color: hsl(120, 100%, 40%);">+        /* 4) Discontinue the subsystem status test if such a test was in progress */</span><br><span style="color: hsl(120, 100%, 40%);">+ /* 5) Initiate a broadcast of Subsystem-Allowed messages to concerned signalling points. */</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%);">+/* ITU-T Q.714 5.3.2 Subsystem prohibited */</span><br><span style="color: hsl(120, 100%, 40%);">+void sccp_scmg_rx_ssn_prohibited(struct osmo_sccp_instance *inst, uint32_t dpc, uint32_t ssn, uint32_t smi)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        struct osmo_scu_state_param state;</span><br><span style="color: hsl(120, 100%, 40%);">+    /* 1) instruct the translation function to update the translation tables */</span><br><span style="color: hsl(120, 100%, 40%);">+   /* 2) mark as "prohibited" the status of that subsystem */</span><br><span style="color: hsl(120, 100%, 40%);">+  /* 3) initiate a local broadcast of "User-out-of-service" information */</span><br><span style="color: hsl(120, 100%, 40%);">+    state = (struct osmo_scu_state_param) {</span><br><span style="color: hsl(120, 100%, 40%);">+               .affected_pc = dpc,</span><br><span style="color: hsl(120, 100%, 40%);">+           .affected_ssn = ssn,</span><br><span style="color: hsl(120, 100%, 40%);">+          .user_in_service = false,</span><br><span style="color: hsl(120, 100%, 40%);">+             .ssn_multiplicity_ind = smi,</span><br><span style="color: hsl(120, 100%, 40%);">+  };</span><br><span style="color: hsl(120, 100%, 40%);">+    sccp_lbcs_local_bcast_state(inst, &state);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* 4) initiate the subsystem status test procedure if the prohibited subsystem is not local */</span><br><span style="color: hsl(120, 100%, 40%);">+        /* 5) initiate a broadcast of Subsystem-Prohibited messages to concerned SP */</span><br><span style="color: hsl(120, 100%, 40%);">+        /* 6) cancel "ignore subsystem status test" and the associated timer if in progress and if</span><br><span style="color: hsl(120, 100%, 40%);">+   *    the newly prohibited subsystem resides at the local node. */</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! brief MTP -> SNM (MTP-PAUSE.ind) - inability to providing MTP service Q.714 5.2.2 */</span><br><span> void sccp_scmg_rx_mtp_pause(struct osmo_sccp_instance *inst, uint32_t dpc)</span><br><span> {</span><br><span>diff --git a/src/xua_snm.c b/src/xua_snm.c</span><br><span>index e3efc8e..2a383c7 100644</span><br><span>--- a/src/xua_snm.c</span><br><span>+++ b/src/xua_snm.c</span><br><span>@@ -162,6 +162,53 @@</span><br><span>    }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* generate SS-PROHIBITED / SS-ALLOWED towards local SCCP users */</span><br><span style="color: hsl(120, 100%, 40%);">+static void sua_snm_ssn_available_to_sccp(struct osmo_sccp_instance *sccp, uint32_t aff_pc,</span><br><span style="color: hsl(120, 100%, 40%);">+                                     uint32_t aff_ssn, uint32_t smi, bool available)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  if (available)</span><br><span style="color: hsl(120, 100%, 40%);">+                sccp_scmg_rx_ssn_allowed(sccp, aff_pc, aff_ssn, smi);</span><br><span style="color: hsl(120, 100%, 40%);">+ else</span><br><span style="color: hsl(120, 100%, 40%);">+          sccp_scmg_rx_ssn_prohibited(sccp, aff_pc, aff_ssn, smi);</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%);">+/* advertise availability of a single subsystem */</span><br><span style="color: hsl(120, 100%, 40%);">+static void sua_snm_ssn_available(struct osmo_ss7_as *as, uint32_t aff_pc, uint32_t aff_ssn,</span><br><span style="color: hsl(120, 100%, 40%);">+                                 const uint32_t *smi, const char *info_str, bool available)</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%);">+        uint32_t _smi = smi ? *smi : 0; /* 0 == reserved/unknown in SUA */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if (s7i->sccp)</span><br><span style="color: hsl(120, 100%, 40%);">+             sua_snm_ssn_available_to_sccp(s7i->sccp, aff_pc, aff_ssn, _smi, available);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* inform remote SUA ASPs via DUNA/DAVA */</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%);">+           /* DUNA/DAVA for SSN only exists in SUA */</span><br><span style="color: hsl(120, 100%, 40%);">+            if (asp->cfg.proto != OSMO_SS7_ASP_PROT_SUA)</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%);">+             sua_tx_snm_available(asp, rctx, num_rctx, &aff_pc, 1, &aff_ssn, smi, info_str, available);</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> /* 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> {</span><br><span>@@ -211,6 +258,7 @@</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> {</span><br><span>       struct xua_msg_part *ie_aff_pc = xua_msg_find_tag(xua, M3UA_IEI_AFFECTED_PC);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct xua_msg_part *ie_ssn = xua_msg_find_tag(xua, SUA_IEI_SSN);</span><br><span>    const char *info_str = xua_msg_get_str(xua, M3UA_IEI_INFO_STRING);</span><br><span>   /* TODO: should our processing depend on the RCTX included? I somehow don't think so */</span><br><span>  //struct xua_msg_part *ie_rctx = xua_msg_find_tag(xua, M3UA_IEI_ROUTE_CTX);</span><br><span>@@ -224,13 +272,28 @@</span><br><span>  LOGPASP(asp, log_ss, LOGL_NOTICE, "Rx DUNA(%s) for %s\n", info_str ? info_str : "",</span><br><span>              format_affected_pcs_c(xua, asp->inst, ie_aff_pc));</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       xua_snm_pc_available(as, (const uint32_t *)ie_aff_pc->dat, ie_aff_pc->len/4, info_str, false);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA && ie_ssn) {</span><br><span style="color: hsl(120, 100%, 40%);">+           /* when the SSN is included, DUNA corresponds to the SCCP N-STATE primitive */</span><br><span style="color: hsl(120, 100%, 40%);">+                uint32_t ssn = xua_msg_part_get_u32(ie_ssn);</span><br><span style="color: hsl(120, 100%, 40%);">+          const uint32_t *aff_pc = (const uint32_t *)ie_aff_pc->dat;</span><br><span style="color: hsl(120, 100%, 40%);">+         uint32_t pc, smi;</span><br><span style="color: hsl(120, 100%, 40%);">+             /* The Affected Point Code can only contain one point code when SSN is present */</span><br><span style="color: hsl(120, 100%, 40%);">+             if (ie_aff_pc->len/sizeof(uint32_t) != 1)</span><br><span style="color: hsl(120, 100%, 40%);">+                  return;</span><br><span style="color: hsl(120, 100%, 40%);">+               pc = ntohl(aff_pc[0]) & 0xffffff;</span><br><span style="color: hsl(120, 100%, 40%);">+         sua_snm_ssn_available(as, pc, ssn, xua_msg_get_u32p(xua, SUA_IEI_SMI, &smi), info_str, false);</span><br><span style="color: hsl(120, 100%, 40%);">+    } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              /* when the SSN is not included, DUNA corresponds to the SCCP N-PCSTATE primitive */</span><br><span style="color: hsl(120, 100%, 40%);">+          xua_snm_pc_available(as, (const uint32_t *)ie_aff_pc->dat,</span><br><span style="color: hsl(120, 100%, 40%);">+                              ie_aff_pc->len / sizeof(uint32_t), info_str, false);</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span> }</span><br><span> </span><br><span> /* an incoming xUA DAVA was received from a remote SG */</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> {</span><br><span>   struct xua_msg_part *ie_aff_pc = xua_msg_find_tag(xua, M3UA_IEI_AFFECTED_PC);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct xua_msg_part *ie_ssn = xua_msg_find_tag(xua, SUA_IEI_SSN);</span><br><span>    const char *info_str = xua_msg_get_str(xua, M3UA_IEI_INFO_STRING);</span><br><span>   /* TODO: should our processing depend on the RCTX included? I somehow don't think so */</span><br><span>  //struct xua_msg_part *ie_rctx = xua_msg_find_tag(xua, M3UA_IEI_ROUTE_CTX);</span><br><span>@@ -244,5 +307,19 @@</span><br><span>   LOGPASP(asp, log_ss, LOGL_NOTICE, "Rx DAVA(%s) for %s\n", info_str ? info_str : "",</span><br><span>              format_affected_pcs_c(xua, asp->inst, ie_aff_pc));</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       xua_snm_pc_available(as, (const uint32_t *)ie_aff_pc->dat, ie_aff_pc->len/4, info_str, true);</span><br><span style="color: hsl(120, 100%, 40%);">+   if (asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA && ie_ssn) {</span><br><span style="color: hsl(120, 100%, 40%);">+           /* when the SSN is included, DAVA corresponds to the SCCP N-STATE primitive */</span><br><span style="color: hsl(120, 100%, 40%);">+                uint32_t ssn = xua_msg_part_get_u32(ie_ssn);</span><br><span style="color: hsl(120, 100%, 40%);">+          const uint32_t *aff_pc = (const uint32_t *)ie_aff_pc->dat;</span><br><span style="color: hsl(120, 100%, 40%);">+         uint32_t pc, smi;</span><br><span style="color: hsl(120, 100%, 40%);">+             /* The Affected Point Code can only contain one point code when SSN is present */</span><br><span style="color: hsl(120, 100%, 40%);">+             if (ie_aff_pc->len/sizeof(uint32_t) != 1)</span><br><span style="color: hsl(120, 100%, 40%);">+                  return;</span><br><span style="color: hsl(120, 100%, 40%);">+               pc = ntohl(aff_pc[0]) & 0xffffff;</span><br><span style="color: hsl(120, 100%, 40%);">+         sua_snm_ssn_available(as, pc, ssn, xua_msg_get_u32p(xua, SUA_IEI_SMI, &smi), info_str, true);</span><br><span style="color: hsl(120, 100%, 40%);">+     } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              /* when the SSN is not included, DAVA corresponds to the SCCP N-PCSTATE primitive */</span><br><span style="color: hsl(120, 100%, 40%);">+          xua_snm_pc_available(as, (const uint32_t *)ie_aff_pc->dat,</span><br><span style="color: hsl(120, 100%, 40%);">+                              ie_aff_pc->len / sizeof(uint32_t), info_str, true);</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span> }</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/libosmo-sccp/+/22833">change 22833</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/+/22833"/><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: Ie9a45b905bc17e7b695e15fe12ba4bbadcd032bf </div>
<div style="display:none"> Gerrit-Change-Number: 22833 </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-MessageType: newchange </div>