pespin has uploaded this change for review.
Split ss7_hmrt.c into mtp3_hm{dc,dt,rt}.c
ITU Q.704 (MTP level 3) spec clearly splits the functionality between
subsystems/block, and they coordinate through specific events/messages.
Let's split our current code base in different files to follow the
module split, so it becomes a lot easier to match the spec and extend it
with more blocks in the future.
The new naming also clarifies this logic happens within the MTP layer3,
which communicates with layer2 (MTP2, SCTP in M3UA, etc.) and layer
3 (eg. SCCP).
Change-Id: I1b94c1474722b49ce29796681cfbcfce65c95388
---
M src/Makefile.am
M src/ipa.c
M src/m3ua.c
A src/mtp3_hmdc.c
A src/mtp3_hmdc.h
A src/mtp3_hmdt.c
A src/mtp3_hmdt.h
A src/mtp3_hmrt.c
A src/mtp3_hmrt.h
M src/mtp_sap.c
D src/ss7_hmrt.c
M src/xua_internal.h
12 files changed, 358 insertions(+), 262 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-sigtran refs/changes/21/41521/1
diff --git a/src/Makefile.am b/src/Makefile.am
index de3d02e..29cf10a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -3,6 +3,9 @@
$(LIBOSMONETIF_CFLAGS)
noinst_HEADERS = \
+ mtp3_hmdc.h \
+ mtp3_hmdt.h \
+ mtp3_hmrt.h \
sccp_connection.h \
sccp_scoc_fsm.h \
sccp_instance.h \
@@ -47,6 +50,9 @@
ipa.c \
m3ua.c \
mtp_sap.c \
+ mtp3_hmdc.c \
+ mtp3_hmdt.c \
+ mtp3_hmrt.c \
sccp2sua.c \
sccp_connection.c \
sccp_helpers.c \
@@ -68,7 +74,6 @@
ss7_asp_vty.c \
ss7_asp_peer.c \
ss7_combined_linkset.c \
- ss7_hmrt.c \
ss7_instance.c \
ss7_link.c \
ss7_linkset.c \
diff --git a/src/ipa.c b/src/ipa.c
index 2e74414..2083d09 100644
--- a/src/ipa.c
+++ b/src/ipa.c
@@ -37,7 +37,6 @@
//#include <osmocom/netif/stream.h>
#include <osmocom/netif/ipa.h>
-#include "xua_msg.h"
#include <osmocom/sigtran/mtp_sap.h>
#include <osmocom/sigtran/sccp_sap.h>
@@ -46,11 +45,13 @@
#include <osmocom/sigtran/protocol/sua.h>
#include <osmocom/sigtran/protocol/mtp.h>
-#include "xua_internal.h"
+#include "mtp3_hmdc.h"
#include "ss7_as.h"
#include "ss7_asp.h"
#include "ss7_internal.h"
#include "xua_asp_fsm.h"
+#include "xua_internal.h"
+#include "xua_msg.h"
/* generate a msgb containing an IPA CCM PING message */
struct msgb *ipa_gen_ping(void)
@@ -344,7 +345,7 @@
/* Pass on as if we had received it from an M3UA ASP.
* xua ownership is passed here: */
- rc = m3ua_hmdc_rx_from_l2(asp->inst, xua);
+ rc = mtp3_hmdc_rx_from_l2(asp->inst, xua);
return rc;
}
diff --git a/src/m3ua.c b/src/m3ua.c
index 8e93515..36018e1 100644
--- a/src/m3ua.c
+++ b/src/m3ua.c
@@ -33,7 +33,6 @@
#include <osmocom/core/socket.h>
#include <osmocom/netif/stream.h>
-#include "xua_msg.h"
#include <osmocom/sigtran/mtp_sap.h>
#include <osmocom/sigtran/sccp_sap.h>
@@ -41,12 +40,14 @@
#include <osmocom/sigtran/protocol/m3ua.h>
#include <osmocom/sigtran/protocol/sua.h>
+#include "mtp3_hmdc.h"
#include "xua_as_fsm.h"
#include "xua_asp_fsm.h"
#include "xua_internal.h"
#include "ss7_as.h"
#include "ss7_asp.h"
#include "ss7_internal.h"
+#include "xua_msg.h"
#define M3UA_MSGB_SIZE 1500
@@ -667,7 +668,7 @@
}
/* xua ownership is passed here: */
- return m3ua_hmdc_rx_from_l2(asp->inst, xua);
+ return mtp3_hmdc_rx_from_l2(asp->inst, xua);
ret_free:
xua_msg_free(xua);
diff --git a/src/mtp3_hmdc.c b/src/mtp3_hmdc.c
new file mode 100644
index 0000000..68154a2
--- /dev/null
+++ b/src/mtp3_hmdc.c
@@ -0,0 +1,52 @@
+/***********************************************************************
+ * MTP Level 3 - Message Discrimination (HMDC), ITU Q.704 Figure 24
+ ***********************************************************************/
+
+/* (C) 2015-2017 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2025 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
+ * All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <stdint.h>
+
+#include <osmocom/core/logging.h>
+
+#include "mtp3_hmdc.h"
+#include "mtp3_hmdt.h"
+#include "mtp3_hmrt.h"
+#include "ss7_instance.h"
+#include "xua_msg.h"
+
+
+/* HMDC: Received Message L2 -> L3; Figure 24/Q.704 */
+/* This means a message was received from L2 and we have to decide if it
+ * is for the local stack (HMDT) or for routng (HMRT)
+ * Ownership of xua_msg passed is transferred to this function. */
+int mtp3_hmdc_rx_from_l2(struct osmo_ss7_instance *inst, struct xua_msg *xua)
+{
+ uint32_t dpc = xua->mtp.dpc;
+ if (osmo_ss7_pc_is_local(inst, dpc)) {
+ LOGSS7(inst, LOGL_DEBUG, "%s(): found dpc=%u=%s as local\n",
+ __func__, dpc, osmo_ss7_pointcode_print(inst, dpc));
+ return mtp3_hmdt_message_for_distribution(inst, xua);
+ }
+ LOGSS7(inst, LOGL_DEBUG, "%s(): dpc=%u=%s not local, message is for routing\n",
+ __func__, dpc, osmo_ss7_pointcode_print(inst, dpc));
+ return mtp3_hmrt_message_for_routing(inst, xua);
+}
diff --git a/src/mtp3_hmdc.h b/src/mtp3_hmdc.h
new file mode 100644
index 0000000..9f882c5
--- /dev/null
+++ b/src/mtp3_hmdc.h
@@ -0,0 +1,6 @@
+#pragma once
+
+#include "ss7_instance.h"
+#include "xua_msg.h"
+
+int mtp3_hmdc_rx_from_l2(struct osmo_ss7_instance *inst, struct xua_msg *xua);
diff --git a/src/mtp3_hmdt.c b/src/mtp3_hmdt.c
new file mode 100644
index 0000000..a6cf1b3
--- /dev/null
+++ b/src/mtp3_hmdt.c
@@ -0,0 +1,126 @@
+/***********************************************************************
+ * MTP Level 3 - Message Distribution (HMDT), ITU Q.704 Figure 25
+ ***********************************************************************/
+
+/* (C) 2015-2017 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2025 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
+ * All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <osmocom/sigtran/protocol/m3ua.h>
+#include <osmocom/sigtran/mtp_sap.h>
+
+#include "ss7_instance.h"
+#include "ss7_user.h"
+#include "xua_internal.h"
+#include "xua_msg.h"
+
+
+/* convert from M3UA message to MTP-TRANSFER.ind osmo_mtp_prim */
+static struct osmo_mtp_prim *m3ua_to_xfer_ind(struct xua_msg *xua)
+{
+ struct xua_msg_part *data_ie = xua_msg_find_tag(xua, M3UA_IEI_PROT_DATA);
+ struct osmo_mtp_prim *prim;
+ struct m3ua_data_hdr *data_hdr;
+
+ if (!data_ie || data_ie->len < sizeof(*data_hdr)) {
+ /* FIXME: ERROR message */
+ return NULL;
+ }
+ data_hdr = (struct m3ua_data_hdr *) data_ie->dat;
+
+ prim = mtp_prim_xfer_ind_alloc(NULL,
+ data_ie->dat + sizeof(*data_hdr),
+ data_ie->len - sizeof(*data_hdr));
+ m3ua_dh_to_xfer_param(&prim->u.transfer, data_hdr);
+
+ return prim;
+}
+
+/* delivery given XUA message to given SS7 user
+ * Ownership of xua_msg passed is transferred to this function.
+ */
+static int deliver_to_mtp_user(const struct osmo_ss7_user *osu, struct xua_msg *xua)
+{
+ struct osmo_mtp_prim *prim;
+ int rc;
+
+ /* Create MTP-TRANSFER.ind and feed to user */
+ prim = m3ua_to_xfer_ind(xua);
+ if (!prim) {
+ rc = -1;
+ goto ret_free;
+ }
+ prim->u.transfer = xua->mtp;
+
+ rc = ss7_user_mtp_sap_prim_up(osu, prim);
+
+ret_free:
+ xua_msg_free(xua);
+ return rc;
+}
+
+/* HMDC -> HMDT: Message for distribution; Figure 25/Q.704 */
+/* This means it is a message we received from remote/L2, and it is to
+ * be routed to a local user part.
+ * Ownership of xua_msg passed is transferred to this function.
+ */
+int mtp3_hmdt_message_for_distribution(struct osmo_ss7_instance *inst, struct xua_msg *xua)
+{
+ struct m3ua_data_hdr *mdh;
+ const struct osmo_ss7_user *osu;
+ uint32_t service_ind;
+
+ switch (xua->hdr.msg_class) {
+ case M3UA_MSGC_XFER:
+ switch (xua->hdr.msg_type) {
+ case M3UA_XFER_DATA:
+ mdh = data_hdr_from_m3ua(xua);
+ service_ind = mdh->si & 0xf;
+ break;
+ default:
+ LOGSS7(inst, LOGL_ERROR, "Unknown M3UA XFER Message Type %u\n", xua->hdr.msg_type);
+ xua_msg_free(xua);
+ return -1;
+ }
+ break;
+ case M3UA_MSGC_SNM:
+ /* FIXME */
+ /* FIXME: SI = Signalling Network Management -> SRM/SLM/STM */
+ /* FIXME: SI = Signalling Network Testing and Maintenance -> SLTC */
+ default:
+ /* Discard Message */
+ LOGSS7(inst, LOGL_ERROR, "Unknown M3UA Message Class %u\n", xua->hdr.msg_class);
+ xua_msg_free(xua);
+ return -1;
+ }
+
+ /* "User Part Available?" */
+ osu = osmo_ss7_user_find_by_si(inst, service_ind);
+ if (!osu) {
+ /* "Discard Message" */
+ LOGSS7(inst, LOGL_NOTICE, "No MTP-User for SI %u\n", service_ind);
+ /* FIXME: User Part Unavailable HMDT -> HMRT */
+ xua_msg_free(xua);
+ return -1;
+ }
+
+ /* "MTP Transfer indication HMDT→L4" */
+ return deliver_to_mtp_user(osu, xua);
+}
diff --git a/src/mtp3_hmdt.h b/src/mtp3_hmdt.h
new file mode 100644
index 0000000..ab8854a
--- /dev/null
+++ b/src/mtp3_hmdt.h
@@ -0,0 +1,6 @@
+#pragma once
+
+#include "ss7_instance.h"
+#include "xua_msg.h"
+
+int mtp3_hmdt_message_for_distribution(struct osmo_ss7_instance *inst, struct xua_msg *xua);
diff --git a/src/mtp3_hmrt.c b/src/mtp3_hmrt.c
new file mode 100644
index 0000000..9ab7e33
--- /dev/null
+++ b/src/mtp3_hmrt.c
@@ -0,0 +1,140 @@
+/***********************************************************************
+ * MTP Level 3 - Message Routing (HMRT), ITU Q.704 Figure 26
+ ***********************************************************************/
+
+/* (C) 2015-2017 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2025 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
+ * All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <stdbool.h>
+#include <string.h>
+#include <errno.h>
+
+#include <arpa/inet.h>
+
+#include <osmocom/core/linuxlist.h>
+#include <osmocom/core/logging.h>
+#include <osmocom/sigtran/mtp_sap.h>
+#include <osmocom/sigtran/osmo_ss7.h>
+#include <osmocom/sigtran/protocol/m3ua.h>
+
+#include "mtp3_hmdc.h"
+#include "xua_internal.h"
+#include "ss7_as.h"
+#include "ss7_asp.h"
+#include "ss7_linkset.h"
+#include "ss7_route.h"
+#include "ss7_route_table.h"
+#include "ss7_internal.h"
+#include "ss7_user.h"
+
+/* HMDC->HMRT Msg For Routing; Figure 26/Q.704 */
+/* local message was receive d from L4, SRM, SLM, STM or SLTC, or
+ * remote message received from L2 and HMDC determined msg for routing
+ * Ownership of xua_msg passed is transferred to this function.
+ */
+int mtp3_hmrt_message_for_routing(struct osmo_ss7_instance *inst, struct xua_msg *xua)
+{
+ uint32_t dpc = xua->mtp.dpc;
+ struct osmo_ss7_route_label rtlabel = {
+ .opc = xua->mtp.opc,
+ .dpc = xua->mtp.dpc,
+ .sls = xua->mtp.sls,
+ };
+ struct osmo_ss7_route *rt;
+
+ /* find route for OPC+DPC+SLS: */
+ /* FIXME: unify with gen_mtp_transfer_req_xua() */
+ rt = ss7_instance_lookup_route(inst, &rtlabel);
+ if (rt) {
+ /* FIXME: DPC SP restart? */
+ /* FIXME: DPC Congested? */
+ /* FIXME: Select link based on SLS */
+ /* FIXME: Transmit over respective Link */
+ if (rt->dest.as) {
+ struct osmo_ss7_as *as = rt->dest.as;
+
+ if (log_check_level(DLSS7, LOGL_DEBUG)) {
+ /* osmo_ss7_route_name() calls osmo_ss7_pointcode_print() and
+ * osmo_ss7_pointcode_print2(), guard against its static buffer being
+ * overwritten. */
+ const char *rt_name = osmo_ss7_route_name(rt, false);
+ LOGSS7(inst, LOGL_DEBUG, "Found route for dpc=%u=%s: %s\n",
+ dpc, osmo_ss7_pointcode_print(inst, dpc), rt_name);
+ }
+
+ rate_ctr_inc2(as->ctrg, SS7_AS_CTR_TX_MSU_TOTAL);
+ OSMO_ASSERT(xua->mtp.sls <= 0xf);
+ rate_ctr_inc2(as->ctrg, SS7_AS_CTR_TX_MSU_SLS_0 + xua->mtp.sls);
+
+ switch (as->cfg.proto) {
+ case OSMO_SS7_ASP_PROT_M3UA:
+ LOGSS7(inst, LOGL_DEBUG, "rt->dest.as proto is M3UA for dpc=%u=%s\n",
+ dpc, osmo_ss7_pointcode_print(inst, dpc));
+ return m3ua_tx_xua_as(as, xua);
+ case OSMO_SS7_ASP_PROT_IPA:
+ return ipa_tx_xua_as(as, xua);
+ default:
+ LOGSS7(inst, LOGL_ERROR, "MTP message for ASP of unknown protocol %u\n",
+ as->cfg.proto);
+ break;
+ }
+ } else if (rt->dest.linkset) {
+ if (log_check_level(DLSS7, LOGL_ERROR)) {
+ /* osmo_ss7_route_name() calls osmo_ss7_pointcode_print() and
+ * osmo_ss7_pointcode_print2(), guard against its static buffer being
+ * overwritten. */
+ const char *rt_name = osmo_ss7_route_name(rt, false);
+ LOGSS7(inst, LOGL_ERROR,
+ "Found route for dpc=%u=%s: %s, but MTP-TRANSFER.req unsupported for linkset.\n",
+ dpc, osmo_ss7_pointcode_print(inst, dpc), rt_name);
+ }
+ } else
+ OSMO_ASSERT(0);
+ } else {
+ LOGSS7(inst, LOGL_ERROR, "MTP-TRANSFER.req for dpc=%u=%s: no route!\n",
+ dpc, osmo_ss7_pointcode_print(inst, dpc));
+ /* DPC unknown HMRT -> MGMT */
+ /* Message Received for inaccesible SP HMRT ->RTPC */
+ /* Discard Message */
+ }
+ xua_msg_free(xua);
+ return -1;
+}
+
+/* Figure 26/Q.704 (sheet 1 of 5) "MTP Transfer request L4→L3" */
+int mtp3_hmrt_mtp_xfer_request_l4_to_l3(struct osmo_ss7_instance *inst, const struct osmo_mtp_transfer_param *param, uint8_t *user_data, size_t user_data_len)
+{
+ struct m3ua_data_hdr data_hdr;
+ struct xua_msg *xua;
+
+ /* convert from osmo_mtp_prim MTP-TRANSFER.req to xua_msg */
+ mtp_xfer_param_to_m3ua_dh(&data_hdr, param);
+ xua = m3ua_xfer_from_data(&data_hdr, user_data, user_data_len);
+ OSMO_ASSERT(xua);
+ xua->mtp = *param;
+
+ /* normally we would call mtp3_hmrt_message_for_routing() here, if we were to follow the state
+ * diagrams of the ITU-T Q.70x specifications. However, what if a local MTP user sends a
+ * MTP-TRANSFER.req to a local SSN? This wouldn't work as per the spec, but I believe it
+ * is a very useful feature (aka "loopback device" in IPv4). So we call
+ * mtp3_hmdc_rx_from_l2() just like the MTP-TRANSFER had been received from L2. */
+ return mtp3_hmdc_rx_from_l2(inst, xua);
+}
diff --git a/src/mtp3_hmrt.h b/src/mtp3_hmrt.h
new file mode 100644
index 0000000..4e51570
--- /dev/null
+++ b/src/mtp3_hmrt.h
@@ -0,0 +1,12 @@
+#pragma once
+
+#include <stdint.h>
+#include <unistd.h>
+
+#include <osmocom/sigtran/mtp_sap.h>
+
+#include "ss7_instance.h"
+#include "xua_msg.h"
+
+int mtp3_hmrt_mtp_xfer_request_l4_to_l3(struct osmo_ss7_instance *inst, const struct osmo_mtp_transfer_param *param, uint8_t *user_data, size_t user_data_len);
+int mtp3_hmrt_message_for_routing(struct osmo_ss7_instance *inst, struct xua_msg *xua);
diff --git a/src/mtp_sap.c b/src/mtp_sap.c
index 8c21f53..69838dd 100644
--- a/src/mtp_sap.c
+++ b/src/mtp_sap.c
@@ -27,6 +27,7 @@
#include <osmocom/sigtran/osmo_ss7.h>
#include <osmocom/sigtran/mtp_sap.h>
+#include "mtp3_hmrt.h"
#include "ss7_user.h"
#include "ss7_internal.h"
#include "xua_internal.h"
@@ -220,8 +221,8 @@
switch (OSMO_PRIM_HDR(&omp->oph)) {
case OSMO_PRIM(OSMO_MTP_PRIM_TRANSFER, PRIM_OP_REQUEST):
- rc = hmrt_mtp_xfer_request_l4_to_l3(osu->inst, &omp->u.transfer,
- msgb_l2(msg), msgb_l2len(msg));
+ rc = mtp3_hmrt_mtp_xfer_request_l4_to_l3(osu->inst, &omp->u.transfer,
+ msgb_l2(msg), msgb_l2len(msg));
break;
default:
LOGPSS7U(osu, LOGL_ERROR, "Ignoring unknown primitive %u:%u\n",
diff --git a/src/ss7_hmrt.c b/src/ss7_hmrt.c
deleted file mode 100644
index 72b26d8..0000000
--- a/src/ss7_hmrt.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/***********************************************************************
- * MTP Level 3 - Signalling message handling (SMH) Figure 23/Q.704
- ***********************************************************************/
-
-/* (C) 2015-2017 by Harald Welte <laforge@gnumonks.org>
- * All Rights Reserved
- *
- * SPDX-License-Identifier: GPL-2.0+
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <stdbool.h>
-#include <string.h>
-#include <errno.h>
-
-#include <arpa/inet.h>
-
-#include <osmocom/core/linuxlist.h>
-#include <osmocom/core/logging.h>
-#include <osmocom/sigtran/mtp_sap.h>
-#include <osmocom/sigtran/osmo_ss7.h>
-#include <osmocom/sigtran/protocol/m3ua.h>
-
-#include "xua_internal.h"
-#include "ss7_as.h"
-#include "ss7_asp.h"
-#include "ss7_linkset.h"
-#include "ss7_route.h"
-#include "ss7_route_table.h"
-#include "ss7_internal.h"
-#include "ss7_user.h"
-
-/* convert from M3UA message to MTP-TRANSFER.ind osmo_mtp_prim */
-static struct osmo_mtp_prim *m3ua_to_xfer_ind(struct xua_msg *xua)
-{
- struct xua_msg_part *data_ie = xua_msg_find_tag(xua, M3UA_IEI_PROT_DATA);
- struct osmo_mtp_prim *prim;
- struct m3ua_data_hdr *data_hdr;
-
- if (!data_ie || data_ie->len < sizeof(*data_hdr)) {
- /* FIXME: ERROR message */
- return NULL;
- }
- data_hdr = (struct m3ua_data_hdr *) data_ie->dat;
-
- prim = mtp_prim_xfer_ind_alloc(NULL,
- data_ie->dat + sizeof(*data_hdr),
- data_ie->len - sizeof(*data_hdr));
- m3ua_dh_to_xfer_param(&prim->u.transfer, data_hdr);
-
- return prim;
-}
-
-/* delivery given XUA message to given SS7 user
- * Ownership of xua_msg passed is transferred to this function.
- */
-static int deliver_to_mtp_user(const struct osmo_ss7_user *osu, struct xua_msg *xua)
-{
- struct osmo_mtp_prim *prim;
- int rc;
-
- /* Create MTP-TRANSFER.ind and feed to user */
- prim = m3ua_to_xfer_ind(xua);
- if (!prim) {
- rc = -1;
- goto ret_free;
- }
- prim->u.transfer = xua->mtp;
-
- rc = ss7_user_mtp_sap_prim_up(osu, prim);
-
-ret_free:
- xua_msg_free(xua);
- return rc;
-}
-
-/* HMDC -> HMDT: Message for distribution; Figure 25/Q.704 */
-/* This means it is a message we received from remote/L2, and it is to
- * be routed to a local user part.
- * Ownership of xua_msg passed is transferred to this function.
- */
-static int hmdt_message_for_distribution(struct osmo_ss7_instance *inst, struct xua_msg *xua)
-{
- struct m3ua_data_hdr *mdh;
- const struct osmo_ss7_user *osu;
- uint32_t service_ind;
-
- switch (xua->hdr.msg_class) {
- case M3UA_MSGC_XFER:
- switch (xua->hdr.msg_type) {
- case M3UA_XFER_DATA:
- mdh = data_hdr_from_m3ua(xua);
- service_ind = mdh->si & 0xf;
- break;
- default:
- LOGSS7(inst, LOGL_ERROR, "Unknown M3UA XFER Message Type %u\n", xua->hdr.msg_type);
- xua_msg_free(xua);
- return -1;
- }
- break;
- case M3UA_MSGC_SNM:
- /* FIXME */
- /* FIXME: SI = Signalling Network Management -> SRM/SLM/STM */
- /* FIXME: SI = Signalling Network Testing and Maintenance -> SLTC */
- default:
- /* Discard Message */
- LOGSS7(inst, LOGL_ERROR, "Unknown M3UA Message Class %u\n", xua->hdr.msg_class);
- xua_msg_free(xua);
- return -1;
- }
-
- /* "User Part Available?" */
- osu = osmo_ss7_user_find_by_si(inst, service_ind);
- if (!osu) {
- /* "Discard Message" */
- LOGSS7(inst, LOGL_NOTICE, "No MTP-User for SI %u\n", service_ind);
- /* FIXME: User Part Unavailable HMDT -> HMRT */
- xua_msg_free(xua);
- return -1;
- }
-
- /* "MTP Transfer indication HMDT→L4" */
- return deliver_to_mtp_user(osu, xua);
-}
-
-/* HMDC->HMRT Msg For Routing; Figure 26/Q.704 */
-/* local message was receive d from L4, SRM, SLM, STM or SLTC, or
- * remote message received from L2 and HMDC determined msg for routing
- * Ownership of xua_msg passed is transferred to this function.
- */
-static int hmrt_message_for_routing(struct osmo_ss7_instance *inst,
- struct xua_msg *xua)
-{
- uint32_t dpc = xua->mtp.dpc;
- struct osmo_ss7_route_label rtlabel = {
- .opc = xua->mtp.opc,
- .dpc = xua->mtp.dpc,
- .sls = xua->mtp.sls,
- };
- struct osmo_ss7_route *rt;
-
- /* find route for OPC+DPC+SLS: */
- /* FIXME: unify with gen_mtp_transfer_req_xua() */
- rt = ss7_instance_lookup_route(inst, &rtlabel);
- if (rt) {
- /* FIXME: DPC SP restart? */
- /* FIXME: DPC Congested? */
- /* FIXME: Select link based on SLS */
- /* FIXME: Transmit over respective Link */
- if (rt->dest.as) {
- struct osmo_ss7_as *as = rt->dest.as;
-
- if (log_check_level(DLSS7, LOGL_DEBUG)) {
- /* osmo_ss7_route_name() calls osmo_ss7_pointcode_print() and
- * osmo_ss7_pointcode_print2(), guard against its static buffer being
- * overwritten. */
- const char *rt_name = osmo_ss7_route_name(rt, false);
- LOGSS7(inst, LOGL_DEBUG, "Found route for dpc=%u=%s: %s\n",
- dpc, osmo_ss7_pointcode_print(inst, dpc), rt_name);
- }
-
- rate_ctr_inc2(as->ctrg, SS7_AS_CTR_TX_MSU_TOTAL);
- OSMO_ASSERT(xua->mtp.sls <= 0xf);
- rate_ctr_inc2(as->ctrg, SS7_AS_CTR_TX_MSU_SLS_0 + xua->mtp.sls);
-
- switch (as->cfg.proto) {
- case OSMO_SS7_ASP_PROT_M3UA:
- LOGSS7(inst, LOGL_DEBUG, "rt->dest.as proto is M3UA for dpc=%u=%s\n",
- dpc, osmo_ss7_pointcode_print(inst, dpc));
- return m3ua_tx_xua_as(as, xua);
- case OSMO_SS7_ASP_PROT_IPA:
- return ipa_tx_xua_as(as, xua);
- default:
- LOGSS7(inst, LOGL_ERROR, "MTP message for ASP of unknown protocol %u\n",
- as->cfg.proto);
- break;
- }
- } else if (rt->dest.linkset) {
- if (log_check_level(DLSS7, LOGL_ERROR)) {
- /* osmo_ss7_route_name() calls osmo_ss7_pointcode_print() and
- * osmo_ss7_pointcode_print2(), guard against its static buffer being
- * overwritten. */
- const char *rt_name = osmo_ss7_route_name(rt, false);
- LOGSS7(inst, LOGL_ERROR,
- "Found route for dpc=%u=%s: %s, but MTP-TRANSFER.req unsupported for linkset.\n",
- dpc, osmo_ss7_pointcode_print(inst, dpc), rt_name);
- }
- } else
- OSMO_ASSERT(0);
- } else {
- LOGSS7(inst, LOGL_ERROR, "MTP-TRANSFER.req for dpc=%u=%s: no route!\n",
- dpc, osmo_ss7_pointcode_print(inst, dpc));
- /* DPC unknown HMRT -> MGMT */
- /* Message Received for inaccesible SP HMRT ->RTPC */
- /* Discard Message */
- }
- xua_msg_free(xua);
- return -1;
-}
-
-/* HMDC: Received Message L2 -> L3; Figure 24/Q.704 */
-/* This means a message was received from L2 and we have to decide if it
- * is for the local stack (HMDT) or for routng (HMRT)
- * Ownership of xua_msg passed is transferred to this function. */
-int m3ua_hmdc_rx_from_l2(struct osmo_ss7_instance *inst, struct xua_msg *xua)
-{
- uint32_t dpc = xua->mtp.dpc;
- if (osmo_ss7_pc_is_local(inst, dpc)) {
- LOGSS7(inst, LOGL_DEBUG, "%s(): found dpc=%u=%s as local\n",
- __func__, dpc, osmo_ss7_pointcode_print(inst, dpc));
- return hmdt_message_for_distribution(inst, xua);
- } else {
- LOGSS7(inst, LOGL_DEBUG, "%s(): dpc=%u=%s not local, message is for routing\n",
- __func__, dpc, osmo_ss7_pointcode_print(inst, dpc));
- return hmrt_message_for_routing(inst, xua);
- }
-}
-
-/* Figure 26/Q.704 (sheet 1 of 5) "MTP Transfer request L4→L3" */
-int hmrt_mtp_xfer_request_l4_to_l3(struct osmo_ss7_instance *inst, const struct osmo_mtp_transfer_param *param, uint8_t *user_data, size_t user_data_len)
-{
- struct m3ua_data_hdr data_hdr;
- struct xua_msg *xua;
-
- /* convert from osmo_mtp_prim MTP-TRANSFER.req to xua_msg */
- mtp_xfer_param_to_m3ua_dh(&data_hdr, param);
- xua = m3ua_xfer_from_data(&data_hdr, user_data, user_data_len);
- OSMO_ASSERT(xua);
- xua->mtp = *param;
-
- /* normally we would call hmrt_message_for_routing() here, if we were to follow the state
- * diagrams of the ITU-T Q.70x specifications. However, what if a local MTP user sends a
- * MTP-TRANSFER.req to a local SSN? This wouldn't work as per the spec, but I believe it
- * is a very useful feature (aka "loopback device" in IPv4). So we call
- * m3ua_hmdc_rx_from_l2() just like the MTP-TRANSFER had been received from L2. */
- return m3ua_hmdc_rx_from_l2(inst, xua);
-}
diff --git a/src/xua_internal.h b/src/xua_internal.h
index 54172ff..a1023c1 100644
--- a/src/xua_internal.h
+++ b/src/xua_internal.h
@@ -39,7 +39,6 @@
struct xua_msg *sua_gen_cldr(const struct xua_msg *xua_in, uint32_t route_ctx, uint32_t ret_cause);
-int m3ua_hmdc_rx_from_l2(struct osmo_ss7_instance *inst, struct xua_msg *xua);
struct msgb *m3ua_to_msg(struct xua_msg *xua);
int m3ua_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua);
void m3ua_tx_snm_available(struct osmo_ss7_asp *asp, const uint32_t *rctx, unsigned int num_rctx,
@@ -73,9 +72,6 @@
const struct m3ua_data_hdr *mdh);
void mtp_xfer_param_to_m3ua_dh(struct m3ua_data_hdr *mdh,
const struct osmo_mtp_transfer_param *param);
-int hmrt_mtp_xfer_request_l4_to_l3(struct osmo_ss7_instance *inst,
- const struct osmo_mtp_transfer_param *param,
- uint8_t *user_data, size_t user_data_len);
extern const struct xua_msg_class m3ua_msg_class_mgmt;
To view, visit change 41521. To unsubscribe, or for help writing mail filters, visit settings.