pespin has uploaded this change for review.

View Change

Usse gsup_client_mux from libosmo-gsup-client

gsup_client_mux code was cloned a couple months ago to
libosmo-gsup-client, use it in osmo-msc and drop its own copy.

The code was not dropped at the time because it required tweaking the
unit tests, because they were wrapping some underlaying functions which
cannot be wrapped anymore since the code using them is now inside the
separate already-linked libosmo-gsup-client.so.
Solve it by actually wrapping one layer up in the gsup_client_mux itself
since it now something we mantain here anymore.

Change-Id: I34d02ae219f3ec8daf47942c46f52b21eab21242
---
M TODO-RELEASE
M include/osmocom/msc/Makefile.am
D include/osmocom/msc/gsup_client_mux.h
M src/libmsc/Makefile.am
M src/libmsc/e_link.c
M src/libmsc/gsm_04_11_gsup.c
M src/libmsc/gsm_09_11.c
D src/libmsc/gsup_client_mux.c
M src/libmsc/msc_net_init.c
M src/libvlr/vlr.c
M src/osmo-msc/msc_main.c
M tests/msc_vlr/Makefile.am
M tests/msc_vlr/msc_vlr_tests.c
13 files changed, 47 insertions(+), 249 deletions(-)

git pull ssh://gerrit.osmocom.org:29418/osmo-msc refs/changes/19/39019/1
diff --git a/TODO-RELEASE b/TODO-RELEASE
index 35467f3..f351fab 100644
--- a/TODO-RELEASE
+++ b/TODO-RELEASE
@@ -8,3 +8,4 @@
# If any interfaces have been removed or changed since the last public release: c:r:0.
#library what description / commit summary line
libosmo-sigtran >2.0.1 osmo_ss7_instance_get_id(), osmo_ss7_instance_get_name(), osmo_ss7_instance_get_pc_fmt(), osmo_ss7_instance_get_primary_pc()
+libosmo-gsuo-client >1.8.0 gsup_client_mux.h
\ No newline at end of file
diff --git a/include/osmocom/msc/Makefile.am b/include/osmocom/msc/Makefile.am
index b6901b9..61ed586 100644
--- a/include/osmocom/msc/Makefile.am
+++ b/include/osmocom/msc/Makefile.am
@@ -17,7 +17,6 @@
gsm_data.h \
gsm_data_shared.h \
gsm_subscriber.h \
- gsup_client_mux.h \
mncc.h \
mncc_call.h \
mncc_int.h \
diff --git a/include/osmocom/msc/gsup_client_mux.h b/include/osmocom/msc/gsup_client_mux.h
deleted file mode 100644
index f327786..0000000
--- a/include/osmocom/msc/gsup_client_mux.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#pragma once
-
-#include <osmocom/gsm/gsup.h>
-
-struct gsup_client_mux;
-struct ipaccess_unit;
-
-struct gsup_client_mux_rx_cb {
- int (* func )(struct gsup_client_mux *gcm, void *data, const struct osmo_gsup_message *gsup_msg);
- void *data;
-};
-
-/* A GSUP client shared between code paths for various GSUP Message Classes.
- * The main task is to dispatch GSUP messages to code paths corresponding to the respective Message Class, i.e.
- * subscriber management, SMS, SS/USSD and inter-MSC messaging.
- * If a GSUP Message Class IE is present in the message, the received message is dispatched directly to the rx_cb entry
- * for that Message Class. Otherwise, the Message Class is determined by a switch() on the Message Type.*/
-struct gsup_client_mux {
- struct osmo_gsup_client *gsup_client;
-
- /* Target clients by enum osmo_gsup_message_class */
- struct gsup_client_mux_rx_cb rx_cb[OSMO_GSUP_MESSAGE_CLASS_ARRAYSIZE];
-};
-
-struct gsup_client_mux *gsup_client_mux_alloc(void *talloc_ctx);
-int gsup_client_mux_start(struct gsup_client_mux *gcm, const char *gsup_server_addr_str, uint16_t gsup_server_port,
- struct ipaccess_unit *ipa_dev);
-
-int gsup_client_mux_tx(struct gsup_client_mux *gcm, const struct osmo_gsup_message *gsup_msg);
-void gsup_client_mux_tx_set_source(const struct gsup_client_mux *gcm, struct osmo_gsup_message *gsup_msg);
-void gsup_client_mux_tx_error_reply(struct gsup_client_mux *gcm, const struct osmo_gsup_message *gsup_orig,
- enum gsm48_gmm_cause cause);
-
-int gsup_client_mux_rx(struct osmo_gsup_client *gsup_client, struct msgb *msg);
diff --git a/src/libmsc/Makefile.am b/src/libmsc/Makefile.am
index 3cda322..22543cb 100644
--- a/src/libmsc/Makefile.am
+++ b/src/libmsc/Makefile.am
@@ -41,7 +41,6 @@
gsm_04_14.c \
gsm_04_80.c \
gsm_09_11.c \
- gsup_client_mux.c \
mncc.c \
mncc_builtin.c \
mncc_sock.c \
diff --git a/src/libmsc/e_link.c b/src/libmsc/e_link.c
index 5107c22..4b61ec7 100644
--- a/src/libmsc/e_link.c
+++ b/src/libmsc/e_link.c
@@ -25,7 +25,7 @@
#include <osmocom/gsupclient/gsup_client.h>

#include <osmocom/msc/gsm_data.h>
-#include <osmocom/msc/gsup_client_mux.h>
+#include <osmocom/gsupclient/gsup_client_mux.h>
#include <osmocom/msc/e_link.h>
#include <osmocom/msc/msub.h>
#include <osmocom/msc/msc_roles.h>
diff --git a/src/libmsc/gsm_04_11_gsup.c b/src/libmsc/gsm_04_11_gsup.c
index 3566e76..96fdbc6 100644
--- a/src/libmsc/gsm_04_11_gsup.c
+++ b/src/libmsc/gsm_04_11_gsup.c
@@ -32,7 +32,7 @@
#include <osmocom/msc/debug.h>
#include <osmocom/vlr/vlr.h>
#include <osmocom/msc/msub.h>
-#include <osmocom/msc/gsup_client_mux.h>
+#include <osmocom/gsupclient/gsup_client_mux.h>
#include <osmocom/msc/msc_a.h>

/* Common helper for preparing to be encoded GSUP message */
diff --git a/src/libmsc/gsm_09_11.c b/src/libmsc/gsm_09_11.c
index 86b4a4f..0b85cbd 100644
--- a/src/libmsc/gsm_09_11.c
+++ b/src/libmsc/gsm_09_11.c
@@ -50,7 +50,7 @@
#include <osmocom/msc/msc_a.h>
#include <osmocom/msc/msub.h>
#include <osmocom/msc/paging.h>
-#include <osmocom/msc/gsup_client_mux.h>
+#include <osmocom/gsupclient/gsup_client_mux.h>

/* FIXME: choose a proper range */
static uint32_t new_callref = 0x20000001;
diff --git a/src/libmsc/gsup_client_mux.c b/src/libmsc/gsup_client_mux.c
deleted file mode 100644
index e27b664..0000000
--- a/src/libmsc/gsup_client_mux.c
+++ /dev/null
@@ -1,191 +0,0 @@
-/* Directing individual GSUP messages to their respective handlers. */
-/*
- * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
- * All Rights Reserved
- *
- * Author: Neels Hofmeyr
- *
- * SPDX-License-Identifier: AGPL-3.0+
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation; either version 3 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 Affero General Public License for more details.
- */
-#include <errno.h>
-
-#include <osmocom/gsupclient/gsup_client.h>
-
-#include <osmocom/msc/debug.h>
-#include <osmocom/msc/gsup_client_mux.h>
-
-static enum osmo_gsup_message_class gsup_client_mux_classify(struct gsup_client_mux *gcm,
- const struct osmo_gsup_message *gsup_msg)
-{
- if (gsup_msg->message_class)
- return gsup_msg->message_class;
-
- LOGP(DLGSUP, LOGL_DEBUG, "No explicit GSUP Message Class, trying to guess from message type %s\n",
- osmo_gsup_message_type_name(gsup_msg->message_type));
-
- switch (gsup_msg->message_type) {
- case OSMO_GSUP_MSGT_PROC_SS_REQUEST:
- case OSMO_GSUP_MSGT_PROC_SS_RESULT:
- case OSMO_GSUP_MSGT_PROC_SS_ERROR:
- return OSMO_GSUP_MESSAGE_CLASS_USSD;
-
- /* GSM 04.11 code implementing MO SMS */
- case OSMO_GSUP_MSGT_MO_FORWARD_SM_ERROR:
- case OSMO_GSUP_MSGT_MO_FORWARD_SM_RESULT:
- case OSMO_GSUP_MSGT_READY_FOR_SM_ERROR:
- case OSMO_GSUP_MSGT_READY_FOR_SM_RESULT:
- case OSMO_GSUP_MSGT_MT_FORWARD_SM_REQUEST:
- return OSMO_GSUP_MESSAGE_CLASS_SMS;
-
- default:
- return OSMO_GSUP_MESSAGE_CLASS_SUBSCRIBER_MANAGEMENT;
- }
-}
-
-/* Non-static for unit tests */
-int gsup_client_mux_rx(struct osmo_gsup_client *gsup_client, struct msgb *msg)
-{
- struct gsup_client_mux *gcm = gsup_client->data;
- struct osmo_gsup_message gsup;
- enum osmo_gsup_message_class message_class;
- int rc;
-
- rc = osmo_gsup_decode(msgb_l2(msg), msgb_l2len(msg), &gsup);
- if (rc < 0) {
- LOGP(DLGSUP, LOGL_ERROR, "Failed to decode GSUP message: '%s' (%d) [ %s]\n",
- get_value_string(gsm48_gmm_cause_names, -rc), -rc, osmo_hexdump(msg->data, msg->len));
- goto msgb_free_and_return;
- }
-
- if (!gsup.imsi[0]) {
- LOGP(DLGSUP, LOGL_ERROR, "Failed to decode GSUP message: missing IMSI\n");
- if (OSMO_GSUP_IS_MSGT_REQUEST(gsup.message_type))
- gsup_client_mux_tx_error_reply(gcm, &gsup, GMM_CAUSE_INV_MAND_INFO);
- rc = -GMM_CAUSE_INV_MAND_INFO;
- goto msgb_free_and_return;
- }
-
- message_class = gsup_client_mux_classify(gcm, &gsup);
-
- if (message_class <= OSMO_GSUP_MESSAGE_CLASS_UNSET || message_class >= ARRAY_SIZE(gcm->rx_cb)) {
- LOGP(DLGSUP, LOGL_ERROR, "Failed to classify GSUP message target\n");
- rc = -EINVAL;
- goto msgb_free_and_return;
- }
-
- if (!gcm->rx_cb[message_class].func) {
- LOGP(DLGSUP, LOGL_ERROR, "No receiver set up for GSUP Message Class %s\n", osmo_gsup_message_class_name(message_class));
- rc = -ENOTSUP;
- goto msgb_free_and_return;
- }
-
- rc = gcm->rx_cb[message_class].func(gcm, gcm->rx_cb[message_class].data, &gsup);
-
-msgb_free_and_return:
- msgb_free(msg);
- return rc;
-}
-
-/* Make it clear that struct gsup_client_mux should be talloc allocated, so that it can be used as talloc parent. */
-struct gsup_client_mux *gsup_client_mux_alloc(void *talloc_ctx)
-{
- return talloc_zero(talloc_ctx, struct gsup_client_mux);
-}
-
-/* Start a GSUP client to serve this gsup_client_mux. */
-int gsup_client_mux_start(struct gsup_client_mux *gcm, const char *gsup_server_addr_str, uint16_t gsup_server_port,
- struct ipaccess_unit *ipa_dev)
-{
- gcm->gsup_client = osmo_gsup_client_create2(gcm, ipa_dev,
- gsup_server_addr_str,
- gsup_server_port,
- &gsup_client_mux_rx, NULL);
- if (!gcm->gsup_client)
- return -ENOMEM;
- gcm->gsup_client->data = gcm;
- return 0;
-}
-
-int gsup_client_mux_tx(struct gsup_client_mux *gcm, const struct osmo_gsup_message *gsup_msg)
-{
- struct msgb *msg;
- int rc;
-
- if (!gcm || !gcm->gsup_client) {
- LOGP(DLGSUP, LOGL_ERROR, "GSUP link is down, cannot send GSUP message\n");
- return -ENOTSUP;
- }
-
- msg = osmo_gsup_client_msgb_alloc();
- rc = osmo_gsup_encode(msg, gsup_msg);
- if (rc < 0) {
- LOGP(DLGSUP, LOGL_ERROR, "Failed to encode GSUP message: '%s'\n", strerror(-rc));
- return rc;
- }
-
- return osmo_gsup_client_send(gcm->gsup_client, msg);
-}
-
-/* Set GSUP source_name to our local IPA name */
-void gsup_client_mux_tx_set_source(const struct gsup_client_mux *gcm,
- struct osmo_gsup_message *gsup_msg)
-{
- const char *local_msc_name;
-
- if (!gcm)
- return;
- if (!gcm->gsup_client)
- return;
- if (!gcm->gsup_client->ipa_dev)
- return;
- local_msc_name = gcm->gsup_client->ipa_dev->serno;
- if (!local_msc_name)
- return;
- gsup_msg->source_name = (const uint8_t *) local_msc_name;
- gsup_msg->source_name_len = strlen(local_msc_name) + 1;
-}
-
-/* Transmit GSUP error in response to original message */
-void gsup_client_mux_tx_error_reply(struct gsup_client_mux *gcm, const struct osmo_gsup_message *gsup_orig,
- enum gsm48_gmm_cause cause)
-{
- struct osmo_gsup_message gsup_reply;
-
- /* No need to answer if we couldn't parse an ERROR message type, only REQUESTs need an error reply. */
- if (!OSMO_GSUP_IS_MSGT_REQUEST(gsup_orig->message_type))
- return;
-
- gsup_reply = (struct osmo_gsup_message){
- .cause = cause,
- .message_type = OSMO_GSUP_TO_MSGT_ERROR(gsup_orig->message_type),
- .message_class = gsup_orig->message_class,
- .destination_name = gsup_orig->source_name,
- .destination_name_len = gsup_orig->source_name_len,
-
- /* RP-Message-Reference is mandatory for SM Service */
- .sm_rp_mr = gsup_orig->sm_rp_mr,
- };
-
- OSMO_STRLCPY_ARRAY(gsup_reply.imsi, gsup_orig->imsi);
- gsup_client_mux_tx_set_source(gcm, &gsup_reply);
-
- /* For SS/USSD, it's important to keep both session state and ID IEs */
- if (gsup_orig->session_state != OSMO_GSUP_SESSION_STATE_NONE) {
- gsup_reply.session_state = OSMO_GSUP_SESSION_STATE_END;
- gsup_reply.session_id = gsup_orig->session_id;
- }
-
- if (osmo_gsup_client_enc_send(gcm->gsup_client, &gsup_reply))
- LOGP(DLGSUP, LOGL_ERROR, "Failed to send Error reply (imsi=%s)\n",
- osmo_quote_str(gsup_orig->imsi, -1));
-}
diff --git a/src/libmsc/msc_net_init.c b/src/libmsc/msc_net_init.c
index 5f10e6c..8edca05 100644
--- a/src/libmsc/msc_net_init.c
+++ b/src/libmsc/msc_net_init.c
@@ -29,7 +29,7 @@
#include <osmocom/msc/gsm_data.h>
#include <osmocom/vlr/vlr.h>
#include <osmocom/msc/debug.h>
-#include <osmocom/msc/gsup_client_mux.h>
+#include <osmocom/gsupclient/gsup_client_mux.h>
#include <osmocom/msc/gsm_04_11_gsup.h>
#include <osmocom/msc/gsm_09_11.h>

diff --git a/src/libvlr/vlr.c b/src/libvlr/vlr.c
index 8a1dee5..32c2fbb 100644
--- a/src/libvlr/vlr.c
+++ b/src/libvlr/vlr.c
@@ -34,7 +34,7 @@
#include <osmocom/gsupclient/gsup_client.h>
#include <osmocom/vlr/vlr_sgs.h>
#include <osmocom/vlr/vlr.h>
-#include <osmocom/msc/gsup_client_mux.h>
+#include <osmocom/gsupclient/gsup_client_mux.h>
#include <osmocom/msc/paging.h>

#include <netinet/in.h>
diff --git a/src/osmo-msc/msc_main.c b/src/osmo-msc/msc_main.c
index 5e99b4d..2238e2b 100644
--- a/src/osmo-msc/msc_main.c
+++ b/src/osmo-msc/msc_main.c
@@ -71,7 +71,7 @@
#include <osmocom/msc/msub.h>
#include <osmocom/msc/call_leg.h>
#include <osmocom/msc/msc_ho.h>
-#include <osmocom/msc/gsup_client_mux.h>
+#include <osmocom/gsupclient/gsup_client_mux.h>
#include <osmocom/msc/e_link.h>
#include <osmocom/msc/mncc_call.h>

diff --git a/tests/msc_vlr/Makefile.am b/tests/msc_vlr/Makefile.am
index cbdd6a4..1e332ef 100644
--- a/tests/msc_vlr/Makefile.am
+++ b/tests/msc_vlr/Makefile.am
@@ -20,8 +20,8 @@
$(NULL)

AM_LDFLAGS = \
- -Wl,--wrap=osmo_gsup_client_create2 \
- -Wl,--wrap=osmo_gsup_client_send \
+ -Wl,--wrap=gsup_client_mux_start \
+ -Wl,--wrap=gsup_client_mux_tx \
-Wl,--wrap=gsm340_gen_scts \
-Wl,--wrap=osmo_get_rand_id \
-Wl,--wrap=ran_peers_down_paging \
diff --git a/tests/msc_vlr/msc_vlr_tests.c b/tests/msc_vlr/msc_vlr_tests.c
index c1ae650..6c15b71 100644
--- a/tests/msc_vlr/msc_vlr_tests.c
+++ b/tests/msc_vlr/msc_vlr_tests.c
@@ -30,7 +30,7 @@
#include <osmocom/core/application.h>
#include <osmocom/gsm/protocol/gsm_04_11.h>
#include <osmocom/gsm/gsup.h>
-#include <osmocom/msc/gsup_client_mux.h>
+#include <osmocom/gsupclient/gsup_client_mux.h>
#include <osmocom/msc/gsm_04_11.h>
#include <osmocom/msc/debug.h>
#include <osmocom/msc/gsm_04_08.h>
@@ -136,6 +136,26 @@
gsm48_hdr_msg_type(gh));
}

+static int _gsup_client_mux_rx(struct gsup_client_mux *gcm, struct msgb *msg)
+{
+ struct osmo_gsup_message gsup;
+ int rc;
+
+ rc = osmo_gsup_decode(msgb_l2(msg), msgb_l2len(msg), &gsup);
+ if (rc < 0) {
+ LOGP(DLGSUP, LOGL_ERROR, "Failed to decode GSUP message: '%s' (%d) [ %s]\n",
+ get_value_string(gsm48_gmm_cause_names, -rc), -rc, osmo_hexdump(msg->data, msg->len));
+ goto msgb_free_and_return;
+ }
+
+ OSMO_ASSERT(gcm->rx_cb[gsup.message_class].func);
+ rc = gcm->rx_cb[gsup.message_class].func(gcm, gcm->rx_cb[gsup.message_class].data, &gsup);
+
+msgb_free_and_return:
+ msgb_free(msg);
+ return rc;
+}
+
void gsup_rx(const char *rx_hex, const char *expect_tx_hex)
{
int rc;
@@ -149,7 +169,7 @@
fprintf(stderr, "<-- GSUP rx %s: %s\n", label,
osmo_hexdump_nospc(msgb_l2(msg), msgb_l2len(msg)));
/* GSUP read cb takes ownership of msgb */
- rc = gsup_client_mux_rx(net->gcm->gsup_client, msg);
+ rc = _gsup_client_mux_rx(net->gcm, msg);
fprintf(stderr, "<-- GSUP rx %s: vlr_gsupc_read_cb() returns %d\n",
label, rc);
if (expect_tx_hex)
@@ -811,26 +831,30 @@
}

struct osmo_gsup_client *
-__real_osmo_gsup_client_create2(struct ipaccess_unit *ipa_dev, const char *ip_addr,
- unsigned int tcp_port, osmo_gsup_client_read_cb_t read_cb,
- struct osmo_oap_client_config *oap_config);
+__real_gsup_client_mux_start(struct gsup_client_mux *gcm, const char *gsup_server_addr_str, uint16_t gsup_server_port,
+ struct ipaccess_unit *ipa_dev);
struct osmo_gsup_client *
-__wrap_osmo_gsup_client_create2(struct ipaccess_unit *ipa_dev, const char *ip_addr,
- unsigned int tcp_port, osmo_gsup_client_read_cb_t read_cb,
- struct osmo_oap_client_config *oap_config)
+__wrap_gsup_client_mux_start(struct gsup_client_mux *gcm, const char *gsup_server_addr_str, uint16_t gsup_server_port,
+ struct ipaccess_unit *ipa_dev)
{
- struct osmo_gsup_client *gsupc;
- gsupc = talloc_zero(msc_vlr_tests_ctx, struct osmo_gsup_client);
- OSMO_ASSERT(gsupc);
- return gsupc;
+ return 0;
}

/* override, requires '-Wl,--wrap=gsup_client_send' */
-int __real_osmo_gsup_client_send(struct osmo_gsup_client *gsupc, struct msgb *msg);
-int __wrap_osmo_gsup_client_send(struct osmo_gsup_client *gsupc, struct msgb *msg)
+int __real_gsup_client_mux_tx(struct gsup_client_mux *gcm, const struct osmo_gsup_message *gsup_msg);
+int __wrap_gsup_client_mux_tx(struct gsup_client_mux *gcm, const struct osmo_gsup_message *gsup_msg)
{
uint8_t buf[512];
int len;
+ struct msgb *msg;
+ int rc;
+
+ msg = osmo_gsup_client_msgb_alloc();
+ rc = osmo_gsup_encode(msg, gsup_msg);
+ if (rc < 0) {
+ fprintf(stderr, "Failed to encode GSUP message: '%s'\n", strerror(-rc));
+ return rc;
+ }

fprintf(stderr, "GSUP --> HLR: %s: %s\n",
osmo_gsup_message_type_name(msg->data[0]), osmo_hexdump_nospc(msg->data, msg->len));

To view, visit change 39019. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: newchange
Gerrit-Project: osmo-msc
Gerrit-Branch: master
Gerrit-Change-Id: I34d02ae219f3ec8daf47942c46f52b21eab21242
Gerrit-Change-Number: 39019
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin@sysmocom.de>