pespin has submitted this change. ( 
https://gerrit.osmocom.org/c/libosmo-sigtran/+/41949?usp=email )

Change subject: xua: Implement User Part Unavailable HMDT -> HMRT
......................................................................

xua: Implement User Part Unavailable HMDT -> HMRT

Related: OS#6891
Change-Id: Iab2ffc3a86243d5eeedcc4fd3d558796ede9afc3
---
M src/m3ua.c
M src/mtp3_hmdt.c
M src/sua.c
M src/xua_internal.h
4 files changed, 127 insertions(+), 8 deletions(-)

Approvals:
  pespin: Looks good to me, approved
  fixeria: Looks good to me, but someone else must approve
  Jenkins Builder: Verified
  laforge: Looks good to me, but someone else must approve




diff --git a/src/m3ua.c b/src/m3ua.c
index 2b7c1e7..e4173bd 100644
--- a/src/m3ua.c
+++ b/src/m3ua.c
@@ -910,9 +910,9 @@
 }

 /* 3.4.5 Destination User Part Unavailable (DUPU) */
-static struct xua_msg *m3ua_encode_dupu(const uint32_t *rctx, unsigned int 
num_rctx,
-                                       uint32_t dpc, uint16_t user, uint16_t 
cause,
-                                       const char *info_string)
+struct xua_msg *m3ua_encode_dupu(const uint32_t *rctx, unsigned int num_rctx,
+                                uint32_t dpc, uint16_t user, uint16_t cause,
+                                const char *info_string)
 {
        struct xua_msg *xua = xua_msg_alloc();
        uint32_t user_cause = (cause << 16) | user;
diff --git a/src/mtp3_hmdt.c b/src/mtp3_hmdt.c
index a6cf1b3..a844864 100644
--- a/src/mtp3_hmdt.c
+++ b/src/mtp3_hmdt.c
@@ -23,14 +23,124 @@
  *
  */

+#include <osmocom/core/logging.h>
+
 #include <osmocom/sigtran/protocol/m3ua.h>
+#include <osmocom/sigtran/protocol/sua.h>
+#include <osmocom/sigtran/osmo_ss7.h>
 #include <osmocom/sigtran/mtp_sap.h>

+#include "ss7_as.h"
 #include "ss7_instance.h"
+#include "ss7_internal.h"
+#include "ss7_route.h"
+#include "ss7_route_table.h"
 #include "ss7_user.h"
 #include "xua_internal.h"
 #include "xua_msg.h"

+/* Generate a DUPU message to be sent back to originator. */
+static struct xua_msg *gen_dupu_ret_msg(enum osmo_ss7_asp_protocol proto, 
uint8_t user_part, const struct xua_msg *orig_xua)
+{
+       struct xua_msg *xua;
+       struct xua_msg_part *rctx_ie;
+       unsigned int num_rctx = 0;
+       uint32_t rctx = 0;
+       const char *info_str = "(Local) User Part Unavailable";
+       const uint16_t cause = MTP_UNAVAIL_C_UNKNOWN;
+
+       switch (proto) {
+       case OSMO_SS7_ASP_PROT_M3UA:
+               if ((rctx_ie = xua_msg_find_tag(orig_xua, M3UA_IEI_ROUTE_CTX))) 
{
+                       rctx = xua_msg_part_get_u32(rctx_ie);
+                       num_rctx = 1;
+               }
+               xua = m3ua_encode_dupu(&rctx, num_rctx, orig_xua->mtp.dpc, 
user_part, cause, info_str);
+               break;
+       case OSMO_SS7_ASP_PROT_SUA:
+               if ((rctx_ie = xua_msg_find_tag(orig_xua, SUA_IEI_ROUTE_CTX))) {
+                       rctx = xua_msg_part_get_u32(rctx_ie);
+                       num_rctx = 1;
+               }
+               xua = sua_encode_dupu(&rctx, num_rctx, orig_xua->mtp.dpc, 
user_part, cause, info_str);
+               break;
+       default:
+               OSMO_ASSERT(0);
+       }
+       OSMO_ASSERT(xua);
+
+       xua->mtp = orig_xua->mtp;
+       xua->mtp.opc = orig_xua->mtp.dpc;
+       xua->mtp.dpc = orig_xua->mtp.opc;
+       return xua;
+}
+
+/* ITU Q.704 Figure 25/Q.704 (sheet 2 of 3) "User Part Unavailable HMDT -> 
HMRT"
+ * See also ITU Q.704 2.4.2 */
+static int mtp3_hmdt_rx_msg_for_local_unavailable_part(struct 
osmo_ss7_instance *inst, uint8_t user_part, const struct xua_msg *orig_xua)
+{
+       struct xua_msg *xua;
+       char buf_orig_opc[MAX_PC_STR_LEN];
+       char buf_orig_dpc[MAX_PC_STR_LEN];
+       struct osmo_ss7_route_label rtlabel;
+       struct osmo_ss7_route *rt;
+
+       if (osmo_ss7_pc_is_local(inst, orig_xua->mtp.opc)) {
+               /* This shouldn't happen, if a MTP3 User sends data down the
+                * stack it should also be there to receive it back and hence we
+                * shouldn't have entered this step... */
+               LOGSS7(inst, LOGL_ERROR, "Rx xUA message from local PC and 
unavailable part!\n");
+               return -1;
+       }
+
+       /* We should only be sending DUPU to M3UA peers, hence why we don't
+        * simply call  mtp3_hmrt_message_for_routing() here. */
+       rtlabel = (struct osmo_ss7_route_label){
+               .opc = orig_xua->mtp.dpc,
+               .dpc = orig_xua->mtp.opc,
+               .sls = orig_xua->mtp.sls,
+       };
+       rt = ss7_instance_lookup_route(inst, &rtlabel);
+       if (!rt) {
+               LOGSS7(inst, LOGL_NOTICE, "Tx DUPU %u=%s User %u=%s to 
concerned SP %u=%s: no route!\n",
+                      orig_xua->mtp.dpc, 
osmo_ss7_pointcode_print_buf(buf_orig_dpc, sizeof(buf_orig_dpc), inst, 
orig_xua->mtp.dpc),
+                      user_part, get_value_string(mtp_si_vals, user_part),
+                      orig_xua->mtp.opc, 
osmo_ss7_pointcode_print_buf(buf_orig_opc, sizeof(buf_orig_opc), inst, 
orig_xua->mtp.opc));
+               return 0;
+       }
+       if (!rt->dest.as) {
+               LOGSS7(inst, LOGL_ERROR, "Tx DUPU %u=%s User %u=%s to concerned 
SP %u=%s: unsupported for linkset!\n",
+                      orig_xua->mtp.dpc, 
osmo_ss7_pointcode_print_buf(buf_orig_dpc, sizeof(buf_orig_dpc), inst, 
orig_xua->mtp.dpc),
+                      user_part, get_value_string(mtp_si_vals, user_part),
+                      orig_xua->mtp.opc, 
osmo_ss7_pointcode_print_buf(buf_orig_opc, sizeof(buf_orig_opc), inst, 
orig_xua->mtp.opc));
+               return 0;
+       }
+
+       switch (rt->dest.as->cfg.proto) {
+       case OSMO_SS7_ASP_PROT_M3UA:
+       case OSMO_SS7_ASP_PROT_SUA:
+               LOGSS7(inst, LOGL_INFO, "Message received for unavailable SP 
%u=%s User %u=%s. Tx DUPU to concerned SP %u=%s\n",
+                      orig_xua->mtp.dpc, 
osmo_ss7_pointcode_print_buf(buf_orig_dpc, sizeof(buf_orig_dpc), inst, 
orig_xua->mtp.dpc),
+                      user_part, get_value_string(mtp_si_vals, user_part),
+                      orig_xua->mtp.opc, 
osmo_ss7_pointcode_print_buf(buf_orig_opc, sizeof(buf_orig_opc), inst, 
orig_xua->mtp.opc));
+               xua = gen_dupu_ret_msg(rt->dest.as->cfg.proto, user_part, 
orig_xua);
+               return m3ua_tx_xua_as(rt->dest.as, xua);
+       case OSMO_SS7_ASP_PROT_IPA:
+               /* FIXME: No DUPU in IPA, maybe send SUA CLDR (SCCP UDTS) 
instead? (see send_back_udts()) */
+               LOGSS7(inst, LOGL_INFO, "Message received for unavailable SP 
%u=%s User %u=%s, "
+                      "but concerned SP %u=%s is IPA-based and doesn't support 
DUPU\n",
+                      orig_xua->mtp.dpc, 
osmo_ss7_pointcode_print_buf(buf_orig_dpc, sizeof(buf_orig_dpc), inst, 
orig_xua->mtp.dpc),
+                      user_part, get_value_string(mtp_si_vals, user_part),
+                      orig_xua->mtp.opc, 
osmo_ss7_pointcode_print_buf(buf_orig_opc, sizeof(buf_orig_opc), inst, 
orig_xua->mtp.opc));
+               return 0;
+       default:
+               LOGSS7(inst, LOGL_ERROR, "DUPU message for ASP of unknown 
protocol %u\n",
+                       rt->dest.as->cfg.proto);
+               return 0;
+       }
+
+       return 0;
+}

 /* convert from M3UA message to MTP-TRANSFER.ind osmo_mtp_prim */
 static struct osmo_mtp_prim *m3ua_to_xfer_ind(struct xua_msg *xua)
@@ -86,6 +196,7 @@
        struct m3ua_data_hdr *mdh;
        const struct osmo_ss7_user *osu;
        uint32_t service_ind;
+       int rc;

        switch (xua->hdr.msg_class) {
        case M3UA_MSGC_XFER:
@@ -116,9 +227,10 @@
        if (!osu) {
                /* "Discard Message" */
                LOGSS7(inst, LOGL_NOTICE, "No MTP-User for SI %u\n", 
service_ind);
-               /* FIXME: User Part Unavailable HMDT -> HMRT */
+               /* User Part Unavailable HMDT -> HMRT */
+               rc = mtp3_hmdt_rx_msg_for_local_unavailable_part(inst, 
service_ind, xua);
                xua_msg_free(xua);
-               return -1;
+               return rc;
        }

        /* "MTP Transfer indication HMDT→L4" */
diff --git a/src/sua.c b/src/sua.c
index e81590d..eccecdd 100644
--- a/src/sua.c
+++ b/src/sua.c
@@ -886,9 +886,9 @@
 }

 /* 3.4.5 Destination User Part Unavailable (DUPU) */
-static struct xua_msg *sua_encode_dupu(const uint32_t *rctx, unsigned int 
num_rctx,
-                                       uint32_t dpc, uint16_t user, uint16_t 
cause,
-                                       const char *info_string)
+struct xua_msg *sua_encode_dupu(const uint32_t *rctx, unsigned int num_rctx,
+                               uint32_t dpc, uint16_t user, uint16_t cause,
+                               const char *info_string)
 {
        struct xua_msg *xua = xua_msg_alloc();
        uint32_t user_cause = (user << 16) | cause;
diff --git a/src/xua_internal.h b/src/xua_internal.h
index 8674ef5..c5bd009 100644
--- a/src/xua_internal.h
+++ b/src/xua_internal.h
@@ -37,6 +37,10 @@
 void sua_tx_dupu(struct osmo_ss7_asp *asp, const uint32_t *rctx, unsigned int 
num_rctx,
                 uint32_t dpc, uint16_t user, uint16_t cause, const char 
*info_str);

+struct xua_msg *sua_encode_dupu(const uint32_t *rctx, unsigned int num_rctx,
+                               uint32_t dpc, uint16_t user, uint16_t cause,
+                               const char *info_string);
+
 struct xua_msg *sua_gen_cldr(const struct xua_msg *xua_in, uint32_t route_ctx, 
uint32_t ret_cause);

 struct msgb *m3ua_to_msg(struct xua_msg *xua);
@@ -56,6 +60,9 @@
 struct xua_msg *m3ua_encode_duna(const uint32_t *rctx, unsigned int num_rctx,
                                 const uint32_t *aff_pc, unsigned int 
num_aff_pc,
                                 const char *info_string);
+struct xua_msg *m3ua_encode_dupu(const uint32_t *rctx, unsigned int num_rctx,
+                                uint32_t dpc, uint16_t user, uint16_t cause,
+                                const char *info_string);

 void xua_tx_snm_available(struct osmo_ss7_asp *asp, const uint32_t *rctx, 
unsigned int num_rctx,
                          const uint32_t *aff_pc, unsigned int num_aff_pc,

--
To view, visit https://gerrit.osmocom.org/c/libosmo-sigtran/+/41949?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings?usp=email

Gerrit-MessageType: merged
Gerrit-Project: libosmo-sigtran
Gerrit-Branch: master
Gerrit-Change-Id: Iab2ffc3a86243d5eeedcc4fd3d558796ede9afc3
Gerrit-Change-Number: 41949
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: daniel <[email protected]>
Gerrit-Reviewer: fixeria <[email protected]>
Gerrit-Reviewer: laforge <[email protected]>
Gerrit-Reviewer: osmith <[email protected]>
Gerrit-Reviewer: pespin <[email protected]>

Reply via email to