mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw.git
synced 2025-10-23 08:12:01 +00:00
mscsplit: getting grips on header scopes
This commit is contained in:
@@ -19,7 +19,7 @@ noinst_HEADERS = abis_nm.h abis_rsl.h db.h gsm_04_08.h gsm_data.h \
|
||||
gprs_gsup_client.h bsc_msg_filter.h \
|
||||
oap.h oap_messages.h \
|
||||
gtphub.h \
|
||||
iu.h iu_cs.h \
|
||||
msc_ifaces.h iu.h iu_cs.h \
|
||||
common.h
|
||||
|
||||
openbsc_HEADERS = gsm_04_08.h meas_rep.h bsc_api.h
|
||||
|
@@ -6,5 +6,3 @@ struct gsm_subscriber_connection *subscr_conn_allocate_iu(struct gsm_network *ne
|
||||
uint8_t link_id,
|
||||
uint32_t conn_id);
|
||||
|
||||
int iucs_submit_dtap(struct gsm_subscriber_connection *conn,
|
||||
struct msgb *msg);
|
||||
|
@@ -9,28 +9,55 @@
|
||||
* 2G will use the A-interface,
|
||||
* 3G aka UMTS will use the Iu-interface (for the MSC, it's IuCS).
|
||||
*
|
||||
* Below callback structures allows linking parts of the MSC code without
|
||||
* Below callback structures allow linking parts of the MSC code without
|
||||
* having to include entire infrastructures of external libraries. For example,
|
||||
* a unit test does not need to link against external ASN1 libraries if it is
|
||||
* never going to encode actual outgoing messages. It is up to each building
|
||||
* scope to plug real world functions or to have mere dummy implementations. */
|
||||
* scope to plug real world functions or to have mere dummy implementations.
|
||||
*
|
||||
* For example, for msc_tx_foo(ifaces, conn, msg), depending on
|
||||
* conn->via_iface, either ifaces->a.tx() or ifaces.iu_cs.tx() is called to
|
||||
* dispatch the msg.
|
||||
*
|
||||
* To replace the default dummy implementations, a user would do the likes of:
|
||||
*
|
||||
* int my_iu_cs_tx(...)
|
||||
* {
|
||||
* ...
|
||||
* }
|
||||
*
|
||||
* int main(void)
|
||||
* {
|
||||
* global_msc_ifaces->network = my_network;
|
||||
* global_msc_ifaces->iu_cs.tx = my_iu_cs_tx;
|
||||
* ...
|
||||
* }
|
||||
*
|
||||
* (or use readily available implementations like iu_tx() from libiu)
|
||||
*/
|
||||
|
||||
extern struct {
|
||||
struct msc_ifaces {
|
||||
|
||||
/* global gsm_network to lookup BSC|RNC connections etc. */
|
||||
struct gsm_network *network;
|
||||
|
||||
struct {
|
||||
/* libmsc calls this to send out messages to an A-interface */
|
||||
int (*tx)(struct msgb *msg, uint8_t sapi);
|
||||
/* TODO: I don't understand sapi yet, may not apply to A-iface */
|
||||
} a;
|
||||
|
||||
struct {
|
||||
/* libmsc calls this to send out messages to an Iu-interface */
|
||||
int (*tx)(struct msgb *msg, uint8_t sapi);
|
||||
/* TODO: I don't understand sapi yet */
|
||||
} iu_cs;
|
||||
|
||||
} msc_ifaces;
|
||||
};
|
||||
|
||||
extern struct msc_ifaces *global_msc_ifaces;
|
||||
|
||||
|
||||
int msc_tx_dtap(struct gsm_subscriber_connection *conn,
|
||||
struct msgb *msg);
|
||||
|
||||
/* Depending on conn->via_iface (A or IuCS), submit msg to the proper link api. */
|
||||
extern int msc_submit_dtap(struct gsm_subscriber_connection *conn,
|
||||
struct msgb *msg);
|
||||
|
@@ -242,6 +242,8 @@ static int handle_new_assignment(struct gsm_subscriber_connection *conn, int cha
|
||||
|
||||
/* Allocate a subscriber connection for A-interface link. For Iu-CS see
|
||||
* subscr_con_allocate_iu(). */
|
||||
/* TODO this shall move to libmsc, behind an actual A-interface, and lchan will
|
||||
* not be involved. */
|
||||
struct gsm_subscriber_connection *subscr_con_allocate(struct gsm_lchan *lchan)
|
||||
{
|
||||
struct gsm_subscriber_connection *conn;
|
||||
|
@@ -21,7 +21,7 @@ libmsc_a_SOURCES = auth.c \
|
||||
vty_interface_layer3.c \
|
||||
transaction.c \
|
||||
osmo_msc.c ctrl_commands.c meas_feed.c \
|
||||
msc_api.c iu_cs.c
|
||||
msc_api.c msc_ifaces.c iu_cs.c
|
||||
|
||||
if BUILD_SMPP
|
||||
noinst_HEADERS += smpp_smsc.h
|
||||
|
@@ -109,11 +109,3 @@ int gsm0408_rcvmsg_iucs(struct gsm_network *network, struct msgb *msg)
|
||||
}
|
||||
|
||||
|
||||
int iucs_submit_dtap(struct gsm_subscriber_connection *conn,
|
||||
struct msgb *msg)
|
||||
{
|
||||
OSMO_ASSERT(conn->via_iface == IFACE_IU);
|
||||
msg->dst = conn->iu.ue_ctx;
|
||||
return iu_tx(msg, 0);
|
||||
}
|
||||
|
||||
|
51
openbsc/src/libmsc/msc_api.c
Normal file
51
openbsc/src/libmsc/msc_api.c
Normal file
@@ -0,0 +1,51 @@
|
||||
/* Implementations for receiving or sending MM|CC|... messages from/to the
|
||||
* BSC|RNC direction, regardless of which particular external interface is
|
||||
* actually involved (A or IuCS). */
|
||||
|
||||
/* (C) 2016 by sysmocom s.m.f.c GmbH <info@sysmocom.de>
|
||||
*
|
||||
* Based on parts of osmo_msc.c:
|
||||
* (C) 2010,2013 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2010 by On-Waves
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <openbsc/msc_api.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
|
||||
int msc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg,
|
||||
uint16_t chosen_channel)
|
||||
{
|
||||
gsm0408_new_conn(conn);
|
||||
gsm0408_dispatch(conn, msg);
|
||||
|
||||
/*
|
||||
* If this is a silent call we want the channel to remain open as long as
|
||||
* possible and this is why we accept this connection regardless of any
|
||||
* pending transaction or ongoing operation.
|
||||
*/
|
||||
if (conn->silent_call)
|
||||
return MSC_CONN_ACCEPT;
|
||||
if (conn->loc_operation || conn->sec_operation || conn->anch_operation)
|
||||
return MSC_CONN_ACCEPT;
|
||||
if (trans_has_conn(conn))
|
||||
return MSC_CONN_ACCEPT;
|
||||
|
||||
LOGP(DRR, LOGL_INFO, "MSC Complete L3: Rejecting connection.\n");
|
||||
return MSC_CONN_REJECT;
|
||||
}
|
||||
|
@@ -2,9 +2,22 @@
|
||||
|
||||
/* These functions receive or send MM|CC|... messages from/to the BSC|RNC
|
||||
* direction, while they are not concerned with which particular external
|
||||
* interface is actually involved (A or IuCS). */
|
||||
* interface is actually involved (A or IuCS).
|
||||
*
|
||||
* For the interface specific decisions see msc_iface.[hc] */
|
||||
|
||||
/* receive a Level 3 Complete message */
|
||||
#include <stdint.h>
|
||||
|
||||
struct gsm_subscriber_connection;
|
||||
struct msgb;
|
||||
|
||||
enum {
|
||||
MSC_CONN_ACCEPT = 0,
|
||||
MSC_CONN_REJECT = 1,
|
||||
};
|
||||
|
||||
/* receive a Level 3 Complete message and return MSC_CONN_ACCEPT or
|
||||
* MSC_CONN_REJECT */
|
||||
int msc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg,
|
||||
uint16_t chosen_channel);
|
||||
/* TODO: is chosen_channel NITB legacy? */
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/* MSC decisions which interface to send messages out on. */
|
||||
/* Implementation for MSC decisions which interface to send messages out on. */
|
||||
|
||||
/* (C) 2016 by sysmocom s.m.f.c GmbH <info@sysmocom.de>
|
||||
*
|
||||
@@ -16,35 +16,63 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <osmocom/core/logging.h>
|
||||
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/iu_cs.h>
|
||||
#include <openbsc/msc_ifaces.h>
|
||||
|
||||
#include "msc_api.h"
|
||||
static int tx_dummy_a(struct msgb *msg, uint8_t sapi)
|
||||
{
|
||||
LOGP(DMSC, LOGL_ERROR,
|
||||
"attempt to send message via uninitialized A-interface\n");
|
||||
return -1
|
||||
}
|
||||
|
||||
int msc_submit_dtap(struct gsm_subscriber_connection *conn, struct msgb *msg)
|
||||
static int tx_dummy_iu_cs(struct msgb *msg, uint8_t sapi)
|
||||
{
|
||||
LOGP(DMSC, LOGL_ERROR,
|
||||
"attempt to send message via uninitialized IuCS-interface\n");
|
||||
return -1
|
||||
}
|
||||
|
||||
struct msc_ifaces *global_msc_ifaces = {
|
||||
.a = {
|
||||
.tx = tx_dummy_a,
|
||||
},
|
||||
.iu_cs = {
|
||||
.tx = tx_dummy_iu_cs,
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static int msc_tx(struct msc_ifaces *ifaces,
|
||||
struct gsm_subscriber_connection *conn,
|
||||
struct msgb *msg)
|
||||
{
|
||||
switch (conn->via_iface) {
|
||||
case IFACE_A:
|
||||
//return gsm0808_submit_dtap(conn, msg, link_id, allow_sacch);
|
||||
LOGP(DMSC, LOGL_ERROR,
|
||||
"submit dtap: A-interface not implemented\n");
|
||||
return -1;
|
||||
/* TODO: msg->dst = <A-iface token> */
|
||||
return ifaces->a.tx(msg, 0);
|
||||
|
||||
case IFACE_IUCS:
|
||||
return iucs_submit_dtap(conn, msg);
|
||||
msg->dst = conn->iu.ue_ctx;
|
||||
return ifaces->iu_cs.tx(msg, 0);
|
||||
|
||||
default:
|
||||
LOGP(DMSC, LOGL_ERROR,
|
||||
"submit dtap: conn->via_iface invalid (%d)\n",
|
||||
"msc_tx(): conn->via_iface invalid (%d)\n",
|
||||
conn->via_iface);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int msc_tx_dtap(struct gsm_subscriber_connection *conn,
|
||||
struct msgb *msg)
|
||||
{
|
||||
msc_tx(global_msc_ifaces, conn, msg);
|
||||
}
|
||||
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#include <openbsc/transaction.h>
|
||||
#include <openbsc/db.h>
|
||||
|
||||
#include <openbsc/msc_api.h>
|
||||
#include <openbsc/gsm_04_11.h>
|
||||
|
||||
static void msc_sapi_n_reject(struct gsm_subscriber_connection *conn, int dlci)
|
||||
@@ -42,28 +43,6 @@ static int msc_clear_request(struct gsm_subscriber_connection *conn, uint32_t ca
|
||||
return 1;
|
||||
}
|
||||
|
||||
int msc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg,
|
||||
uint16_t chosen_channel)
|
||||
{
|
||||
gsm0408_new_conn(conn);
|
||||
gsm0408_dispatch(conn, msg);
|
||||
|
||||
/*
|
||||
* If this is a silent call we want the channel to remain open as long as
|
||||
* possible and this is why we accept this connection regardless of any
|
||||
* pending transaction or ongoing operation.
|
||||
*/
|
||||
if (conn->silent_call)
|
||||
return BSC_API_CONN_POL_ACCEPT;
|
||||
if (conn->loc_operation || conn->sec_operation || conn->anch_operation)
|
||||
return BSC_API_CONN_POL_ACCEPT;
|
||||
if (trans_has_conn(conn))
|
||||
return BSC_API_CONN_POL_ACCEPT;
|
||||
|
||||
LOGP(DRR, LOGL_INFO, "MSC Complete L3: Rejecting connection.\n");
|
||||
return BSC_API_CONN_POL_REJECT;
|
||||
}
|
||||
|
||||
static void msc_dtap(struct gsm_subscriber_connection *conn, uint8_t link_id, struct msgb *msg)
|
||||
{
|
||||
gsm0408_dispatch(conn, msg);
|
||||
|
Reference in New Issue
Block a user