pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmo-sigtran/+/38640?usp=email )
Change subject: sigtran: Make osmo_ss7_user APIs private ......................................................................
sigtran: Make osmo_ss7_user APIs private
ss7_user objects are managed so far exclusively through libosmo-sigtran internal upper layers (SCCP), hence make the struct as well as all its APIs private.
Change-Id: I59d8f70aa81ba396159af40ffd7e8cc6c27cb864 --- M include/osmocom/sigtran/osmo_ss7.h M src/Makefile.am M src/osmo_ss7.c M src/osmo_ss7_hmrt.c A src/osmo_ss7_user.c M src/sccp_internal.h M src/sccp_user.c A src/ss7_user.h M tests/ss7/ss7_test.c 9 files changed, 162 insertions(+), 37 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-sigtran refs/changes/40/38640/1
diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 9a754cd..6fbe76c 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -98,28 +98,7 @@ * MTP Users (Users of MTP, such as SCCP or ISUP) ***********************************************************************/
-struct osmo_ss7_user { - /* pointer back to SS7 instance */ - struct osmo_ss7_instance *inst; - /* name of the user */ - const char *name; - /* primitive call-back for incoming MTP primitives */ - osmo_prim_cb prim_cb; - /* private data */ - void *priv; -}; - -int osmo_ss7_user_register(struct osmo_ss7_instance *inst, uint8_t service_ind, - struct osmo_ss7_user *user); - -int osmo_ss7_user_unregister(struct osmo_ss7_instance *inst, uint8_t service_ind, - struct osmo_ss7_user *user); - -int osmo_ss7_mtp_to_user(struct osmo_ss7_instance *inst, struct osmo_mtp_prim *omp); - -/* SS7 User wants to issue MTP-TRANSFER.req */ -int osmo_ss7_user_mtp_xfer_req(struct osmo_ss7_instance *inst, - struct osmo_mtp_prim *omp); +struct osmo_ss7_user;
/*********************************************************************** * SS7 Links diff --git a/src/Makefile.am b/src/Makefile.am index 6dd338e..8d074e9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -9,6 +9,7 @@ ss7_linkset.h \ ss7_route.h \ ss7_route_table.h \ + ss7_user.h \ xua_asp_fsm.h \ xua_as_fsm.h \ xua_internal.h \ @@ -45,6 +46,7 @@ osmo_ss7_xua_srv.c \ osmo_ss7_route.c \ osmo_ss7_route_table.c \ + osmo_ss7_user.h \ sccp2sua.c \ sccp_helpers.c \ sccp_lbcs.c \ diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 8f6d417..ab88780 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -423,7 +423,7 @@ * \param[in] service_ind Service (ISUP, SCCP, ...) * \param[in] user SS7 user (including primitive call-back) * \returns 0 on success; negative on error */ -int osmo_ss7_user_register(struct osmo_ss7_instance *inst, uint8_t service_ind, +int ss7_user_register(struct osmo_ss7_instance *inst, uint8_t service_ind, struct osmo_ss7_user *user) { if (service_ind >= ARRAY_SIZE(inst->user)) @@ -447,7 +447,7 @@ * \param[in] user (optional) SS7 user. If present, we will not * unregister other users * \returns 0 on success; negative on error */ -int osmo_ss7_user_unregister(struct osmo_ss7_instance *inst, uint8_t service_ind, +int ss7_user_unregister(struct osmo_ss7_instance *inst, uint8_t service_ind, struct osmo_ss7_user *user) { if (service_ind >= ARRAY_SIZE(inst->user)) @@ -467,7 +467,7 @@ }
/* deliver to a local MTP user */ -int osmo_ss7_mtp_to_user(struct osmo_ss7_instance *inst, struct osmo_mtp_prim *omp) +int ss7_mtp_to_user(struct osmo_ss7_instance *inst, struct osmo_mtp_prim *omp) { uint32_t service_ind; const struct osmo_ss7_user *osu; diff --git a/src/osmo_ss7_hmrt.c b/src/osmo_ss7_hmrt.c index b0208b0..e504cb1 100644 --- a/src/osmo_ss7_hmrt.c +++ b/src/osmo_ss7_hmrt.c @@ -39,6 +39,7 @@ #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 */ struct osmo_mtp_prim *m3ua_to_xfer_ind(struct xua_msg *xua) diff --git a/src/osmo_ss7_user.c b/src/osmo_ss7_user.c new file mode 100644 index 0000000..9d17d7a --- /dev/null +++ b/src/osmo_ss7_user.c @@ -0,0 +1,106 @@ +/* (C) 2015-2017 by Harald Welte laforge@gnumonks.org + * (C) 2023-2024 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 <errno.h> + +#include <osmocom/core/linuxlist.h> +#include <osmocom/core/logging.h> +#include <osmocom/sigtran/osmo_ss7.h> + +#include "ss7_internal.h" + +/*********************************************************************** + * MTP Users (Users of MTP, such as SCCP or ISUP) + ***********************************************************************/ + +/*! \brief Register a MTP user for a given service indicator + * \param[in] inst SS7 instance for which we register the user + * \param[in] service_ind Service (ISUP, SCCP, ...) + * \param[in] user SS7 user (including primitive call-back) + * \returns 0 on success; negative on error */ +int ss7_user_register(struct osmo_ss7_instance *inst, uint8_t service_ind, + struct osmo_ss7_user *user) +{ + if (service_ind >= ARRAY_SIZE(inst->user)) + return -EINVAL; + + if (inst->user[service_ind]) + return -EBUSY; + + DEBUGP(DLSS7, "registering user=%s for SI %u with priv %p\n", + user->name, service_ind, user->priv); + + user->inst = inst; + inst->user[service_ind] = user; + + return 0; +} + +/*! \brief Unregister a MTP user for a given service indicator + * \param[in] inst SS7 instance for which we register the user + * \param[in] service_ind Service (ISUP, SCCP, ...) + * \param[in] user (optional) SS7 user. If present, we will not + * unregister other users + * \returns 0 on success; negative on error */ +int ss7_user_unregister(struct osmo_ss7_instance *inst, uint8_t service_ind, + struct osmo_ss7_user *user) +{ + if (service_ind >= ARRAY_SIZE(inst->user)) + return -EINVAL; + + if (!inst->user[service_ind]) + return -ENODEV; + + if (user && (inst->user[service_ind] != user)) + return -EINVAL; + + if (user) + user->inst = NULL; + inst->user[service_ind] = NULL; + + return 0; +} + +/* deliver to a local MTP user */ +int ss7_mtp_to_user(struct osmo_ss7_instance *inst, struct osmo_mtp_prim *omp) +{ + uint32_t service_ind; + const struct osmo_ss7_user *osu; + + if (omp->oph.sap != MTP_SAP_USER || + omp->oph.primitive != OSMO_MTP_PRIM_TRANSFER || + omp->oph.operation != PRIM_OP_INDICATION) { + LOGP(DLSS7, LOGL_ERROR, "Unsupported Primitive\n"); + return -EINVAL; + } + + service_ind = omp->u.transfer.sio & 0xF; + osu = inst->user[service_ind]; + + if (!osu) { + LOGP(DLSS7, LOGL_NOTICE, "No MTP-User for SI %u\n", service_ind); + return -ENODEV; + } + + DEBUGP(DLSS7, "delivering MTP-TRANSFER.ind to user %s, priv=%p\n", + osu->name, osu->priv); + return osu->prim_cb(&omp->oph, (void *) osu->priv); +} diff --git a/src/sccp_internal.h b/src/sccp_internal.h index 0367fe1..6f1fdb9 100644 --- a/src/sccp_internal.h +++ b/src/sccp_internal.h @@ -11,6 +11,8 @@
#define SCCP_STR "Signalling Connection Control Part\n"
+#include "ss7_user.h" + /* Appendix C.4 of Q.714 */ enum osmo_sccp_timer { /* 0 kept unused on purpose since it's handled specially by osmo_fsm */ diff --git a/src/sccp_user.c b/src/sccp_user.c index 6edbfd1..1ca5f1c 100644 --- a/src/sccp_user.c +++ b/src/sccp_user.c @@ -250,7 +250,7 @@ return NULL; }
- osmo_ss7_user_register(ss7, MTP_SI_SCCP, &inst->ss7_user); + ss7_user_register(ss7, MTP_SI_SCCP, &inst->ss7_user);
llist_add_tail(&inst->list, &sccp_instances);
@@ -262,7 +262,7 @@ struct osmo_sccp_user *scu, *scu2;
inst->ss7->sccp = NULL; - osmo_ss7_user_unregister(inst->ss7, MTP_SI_SCCP, &inst->ss7_user); + ss7_user_unregister(inst->ss7, MTP_SI_SCCP, &inst->ss7_user);
llist_for_each_entry_safe(scu, scu2, &inst->users, list) { osmo_sccp_user_unbind(scu); diff --git a/src/ss7_user.h b/src/ss7_user.h new file mode 100644 index 0000000..34d7342 --- /dev/null +++ b/src/ss7_user.h @@ -0,0 +1,34 @@ +#pragma once + +#include <stdint.h> +#include <osmocom/core/prim.h> +#include <osmocom/sigtran/mtp_sap.h> + +/*********************************************************************** + * SS7 Linksets + ***********************************************************************/ + +struct osmo_ss7_instance; + +struct osmo_ss7_user { + /* pointer back to SS7 instance */ + struct osmo_ss7_instance *inst; + /* name of the user */ + const char *name; + /* primitive call-back for incoming MTP primitives */ + osmo_prim_cb prim_cb; + /* private data */ + void *priv; +}; + +int ss7_user_register(struct osmo_ss7_instance *inst, uint8_t service_ind, + struct osmo_ss7_user *user); + +int ss7_user_unregister(struct osmo_ss7_instance *inst, uint8_t service_ind, + struct osmo_ss7_user *user); + +int ss7_mtp_to_user(struct osmo_ss7_instance *inst, struct osmo_mtp_prim *omp); + +/* SS7 User wants to issue MTP-TRANSFER.req */ +int osmo_ss7_user_mtp_xfer_req(struct osmo_ss7_instance *inst, + struct osmo_mtp_prim *omp); diff --git a/tests/ss7/ss7_test.c b/tests/ss7/ss7_test.c index 7d4ec5f..6fd21d7 100644 --- a/tests/ss7/ss7_test.c +++ b/tests/ss7/ss7_test.c @@ -2,6 +2,7 @@ #include "../src/ss7_linkset.h" #include "../src/ss7_route.h" #include "../src/ss7_route_table.h" +#include "../src/ss7_user.h" #include "../src/xua_internal.h" #include "../src/xua_asp_fsm.h"
@@ -117,25 +118,25 @@ user.prim_cb = test_user_prim_cb;
/* registration */ - OSMO_ASSERT(osmo_ss7_user_register(s7i, 1, &user) == 0); - OSMO_ASSERT(osmo_ss7_user_register(s7i, 1, NULL) == -EBUSY); - OSMO_ASSERT(osmo_ss7_user_register(s7i, 255, NULL) == -EINVAL); + OSMO_ASSERT(ss7_user_register(s7i, 1, &user) == 0); + OSMO_ASSERT(ss7_user_register(s7i, 1, NULL) == -EBUSY); + OSMO_ASSERT(ss7_user_register(s7i, 255, NULL) == -EINVAL);
/* primitive delivery */ - OSMO_ASSERT(osmo_ss7_mtp_to_user(s7i, &omp) == 23); + OSMO_ASSERT(ss7_mtp_to_user(s7i, &omp) == 23);
/* cleanup */ - OSMO_ASSERT(osmo_ss7_user_unregister(s7i, 255, NULL) == -EINVAL); - OSMO_ASSERT(osmo_ss7_user_unregister(s7i, 10, NULL) == -ENODEV); - OSMO_ASSERT(osmo_ss7_user_unregister(s7i, 1, &user2) == -EINVAL); - OSMO_ASSERT(osmo_ss7_user_unregister(s7i, 1, &user) == 0); + OSMO_ASSERT(ss7_user_unregister(s7i, 255, NULL) == -EINVAL); + OSMO_ASSERT(ss7_user_unregister(s7i, 10, NULL) == -ENODEV); + OSMO_ASSERT(ss7_user_unregister(s7i, 1, &user2) == -EINVAL); + OSMO_ASSERT(ss7_user_unregister(s7i, 1, &user) == 0);
/* primitive delivery should fail now */ - OSMO_ASSERT(osmo_ss7_mtp_to_user(s7i, &omp) == -ENODEV); + OSMO_ASSERT(ss7_mtp_to_user(s7i, &omp) == -ENODEV);
/* wrong primitive delivery should also fail */ omp.oph.primitive = OSMO_MTP_PRIM_PAUSE; - OSMO_ASSERT(osmo_ss7_mtp_to_user(s7i, &omp) == -EINVAL); + OSMO_ASSERT(ss7_mtp_to_user(s7i, &omp) == -EINVAL); }
static void test_route(void)