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