/* (C) 2015-2017 by Harald Welte * (C) 2023-2024 by sysmocom s.f.m.c. GmbH * 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 . * */ #include #include #include #include #include #include #include "ss7_user.h" #include "ss7_internal.h" /*********************************************************************** * MTP Users (Users of MTP, such as SCCP or ISUP) ***********************************************************************/ struct osmo_ss7_user *osmo_ss7_user_create(struct osmo_ss7_instance *inst, const char *name) { struct osmo_ss7_user *user; user = talloc_zero(inst, struct osmo_ss7_user); if (!user) return NULL; user->inst = inst; user->name = talloc_strdup(user, name ? : ""); return user; } void osmo_ss7_user_destroy(struct osmo_ss7_user *user) { talloc_free(user); } struct osmo_ss7_instance *osmo_ss7_user_get_instance(const struct osmo_ss7_user *user) { return user->inst; } void osmo_ss7_user_set_prim_cb(struct osmo_ss7_user *user, osmo_prim_cb prim_cb) { user->prim_cb = prim_cb; } void osmo_ss7_user_set_priv(struct osmo_ss7_user *user, void *priv) { user->priv = priv; } void *osmo_ss7_user_get_priv(const struct osmo_ss7_user *user) { return user->priv; } /*! \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 osmo_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 osmo_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); }