aboutsummaryrefslogtreecommitdiffstats
path: root/src/osmo-bsc
diff options
context:
space:
mode:
Diffstat (limited to 'src/osmo-bsc')
-rw-r--r--src/osmo-bsc/osmo_bsc_api.c1
-rw-r--r--src/osmo-bsc/osmo_bsc_ctrl.c144
-rw-r--r--src/osmo-bsc/osmo_bsc_filter.c2
-rw-r--r--src/osmo-bsc/osmo_bsc_main.c4
-rw-r--r--src/osmo-bsc/osmo_bsc_msc.c12
-rw-r--r--src/osmo-bsc/osmo_bsc_sigtran.c35
-rw-r--r--src/osmo-bsc/osmo_bsc_vty.c71
7 files changed, 171 insertions, 98 deletions
diff --git a/src/osmo-bsc/osmo_bsc_api.c b/src/osmo-bsc/osmo_bsc_api.c
index 8c16bde25..8081ea410 100644
--- a/src/osmo-bsc/osmo_bsc_api.c
+++ b/src/osmo-bsc/osmo_bsc_api.c
@@ -24,6 +24,7 @@
#include <osmocom/bsc/gsm_04_80.h>
#include <osmocom/bsc/gsm_04_08_utils.h>
+#include <osmocom/bsc/a_reset.h>
#include <osmocom/gsm/protocol/gsm_08_08.h>
#include <osmocom/gsm/gsm0808.h>
diff --git a/src/osmo-bsc/osmo_bsc_ctrl.c b/src/osmo-bsc/osmo_bsc_ctrl.c
index 5f88b85f7..7891cf427 100644
--- a/src/osmo-bsc/osmo_bsc_ctrl.c
+++ b/src/osmo-bsc/osmo_bsc_ctrl.c
@@ -30,30 +30,126 @@
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/signal.h>
-#include <osmocom/core/talloc.h>
+
+#include <osmocom/ctrl/control_if.h>
+
+#include <osmocom/gsm/protocol/ipaccess.h>
+#include <osmocom/gsm/ipa.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
-void osmo_bsc_send_trap(struct ctrl_cmd *cmd, struct bsc_msc_connection *msc_con)
+extern struct gsm_network *bsc_gsmnet;
+
+/* Obtain SS7 application server currently handling given MSC (DPC) */
+static struct osmo_ss7_as *msc_get_ss7_as(struct bsc_msc_data *msc)
+{
+ struct osmo_ss7_route *rt;
+ struct osmo_ss7_instance *ss7 = osmo_sccp_get_ss7(msc->a.sccp);
+ rt = osmo_ss7_route_lookup(ss7, msc->a.msc_addr.pc);
+ if (!rt)
+ return NULL;
+ return rt->dest.as;
+}
+
+
+/* Encode a CTRL command and send it to the given ASP
+ * \param[in] asp ASP through which we shall send the encoded message
+ * \param[in] cmd decoded CTRL command to be encoded and sent. Ownership is *NOT*
+ * transferred, to permit caller to send the same CMD to several ASPs.
+ * Caller must hence free 'cmd' itself.
+ * \returns 0 on success; negative on error */
+static int sccplite_asp_ctrl_cmd_send(struct osmo_ss7_asp *asp, struct ctrl_cmd *cmd)
+{
+ /* this is basically like libosmoctrl:ctrl_cmd_send(), not for a dedicated
+ * CTRL connection but for the CTRL piggy-back on the IPA/SCCPlite link */
+ struct msgb *msg;
+
+ /* don't attempt to send CTRL on a non-SCCPlite ASP */
+ if (asp->cfg.proto != OSMO_SS7_ASP_PROT_IPA)
+ return 0;
+
+ msg = ctrl_cmd_make(cmd);
+ if (!msg)
+ return -1;
+
+ ipa_prepend_header_ext(msg, IPAC_PROTO_EXT_CTRL);
+ ipa_prepend_header(msg, IPAC_PROTO_OSMO);
+
+ return osmo_ss7_asp_send(asp, msg);
+}
+
+/* Ownership of 'cmd' is *NOT* transferred, to permit caller to send the same CMD to several ASPs.
+ * Caller must hence free 'cmd' itself. */
+static int sccplite_msc_ctrl_cmd_send(struct bsc_msc_data *msc, struct ctrl_cmd *cmd)
+{
+ struct osmo_ss7_as *as;
+ struct osmo_ss7_asp *asp;
+ unsigned int i;
+
+ as = msc_get_ss7_as(msc);
+ if (!as)
+ return -1;
+
+ /* don't attempt to send CTRL on a non-SCCPlite AS */
+ if (as->cfg.proto != OSMO_SS7_ASP_PROT_IPA)
+ return 0;
+
+ /* FIXME: unify with xua_as_transmit_msg() and perform proper ASP lookup */
+ for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) {
+ asp = as->cfg.asps[i];
+ if (!asp)
+ continue;
+ /* FIXME: deal with multiple ASPs per AS */
+ return sccplite_asp_ctrl_cmd_send(asp, cmd);
+ }
+ return -1;
+}
+
+/* receive + process a CTRL command from the piggy-back on the IPA/SCCPlite link */
+int bsc_sccplite_rx_ctrl(struct osmo_ss7_asp *asp, struct msgb *msg)
+{
+ struct ctrl_cmd *cmd;
+ int rc;
+
+ /* caller has already ensured ipaccess_head + ipaccess_head_ext */
+ OSMO_ASSERT(msg->l2h);
+
+ /* prase raw (ASCII) CTRL command into ctrl_cmd */
+ cmd = ctrl_cmd_parse2(asp, msg);
+ OSMO_ASSERT(cmd);
+ msgb_free(msg);
+ if (cmd->type == CTRL_TYPE_ERROR)
+ goto send_reply;
+
+ /* handle the CTRL command */
+ ctrl_cmd_handle(bsc_gsmnet->ctrl, cmd, bsc_gsmnet);
+
+send_reply:
+ rc = sccplite_asp_ctrl_cmd_send(asp, cmd);
+ talloc_free(cmd);
+ return rc;
+}
+
+
+void osmo_bsc_send_trap(struct ctrl_cmd *cmd, struct bsc_msc_data *msc_data)
{
struct ctrl_cmd *trap;
struct ctrl_handle *ctrl;
- struct bsc_msc_data *msc_data;
- msc_data = (struct bsc_msc_data *) msc_con->write_queue.bfd.data;
ctrl = msc_data->network->ctrl;
trap = ctrl_cmd_trap(cmd);
if (!trap) {
+
LOGP(DCTRL, LOGL_ERROR, "Failed to create trap.\n");
return;
}
ctrl_cmd_send_to_all(ctrl, trap);
- ctrl_cmd_send(&msc_con->write_queue, trap);
+ sccplite_msc_ctrl_cmd_send(msc_data, trap);
talloc_free(trap);
}
@@ -62,12 +158,21 @@ CTRL_CMD_DEFINE_RO(msc_connection_status, "connection_status");
static int get_msc_connection_status(struct ctrl_cmd *cmd, void *data)
{
struct bsc_msc_data *msc = (struct bsc_msc_data *)cmd->node;
+ struct osmo_ss7_as *as;
+ const char *as_state_name;
+
if (msc == NULL) {
cmd->reply = "msc not found";
return CTRL_CMD_ERROR;
}
+ as = msc_get_ss7_as(msc);
+ if (!as) {
+ cmd->reply = "AS not found for MSC";
+ return CTRL_CMD_ERROR;
+ }
- if (msc->msc_con->is_connected)
+ as_state_name = osmo_fsm_inst_state_name(as->fi);
+ if (!strcmp(as_state_name, "AS_ACTIVE"))
cmd->reply = "connected";
else
cmd->reply = "disconnected";
@@ -80,14 +185,15 @@ static int msc_connection_status = 0; /* XXX unused */
static int get_msc0_connection_status(struct ctrl_cmd *cmd, void *data)
{
- struct gsm_network *gsmnet = data;
- struct bsc_msc_data *msc = osmo_msc_data_find(gsmnet, 0);
+ struct bsc_msc_data *msc = osmo_msc_data_find(bsc_gsmnet, 0);
+ void *old_node = cmd->node;
+ int rc;
- if (msc->msc_con->is_connected)
- cmd->reply = "connected";
- else
- cmd->reply = "disconnected";
- return CTRL_CMD_REPLY;
+ cmd->node = msc;
+ rc = get_msc_connection_status(cmd, data);
+ cmd->node = old_node;
+
+ return rc;
}
static int msc_connection_status_trap_cb(unsigned int subsys, unsigned int signal, void *handler_data, void *signal_data)
@@ -184,12 +290,12 @@ static int bts_connection_status_trap_cb(unsigned int subsys, unsigned int signa
static int get_bts_loc(struct ctrl_cmd *cmd, void *data);
-static void generate_location_state_trap(struct gsm_bts *bts, struct bsc_msc_connection *msc_con)
+static void generate_location_state_trap(struct gsm_bts *bts, struct bsc_msc_data *msc)
{
struct ctrl_cmd *cmd;
const char *oper, *admin, *policy;
- cmd = ctrl_cmd_create(msc_con, CTRL_TYPE_TRAP);
+ cmd = ctrl_cmd_create(msc, CTRL_TYPE_TRAP);
if (!cmd) {
LOGP(DCTRL, LOGL_ERROR, "Failed to create TRAP command.\n");
return;
@@ -213,7 +319,7 @@ static void generate_location_state_trap(struct gsm_bts *bts, struct bsc_msc_con
osmo_mnc_name(bts->network->plmn.mnc,
bts->network->plmn.mnc_3_digits));
- osmo_bsc_send_trap(cmd, msc_con);
+ osmo_bsc_send_trap(cmd, msc);
talloc_free(cmd);
}
@@ -222,7 +328,7 @@ void bsc_gen_location_state_trap(struct gsm_bts *bts)
struct bsc_msc_data *msc;
llist_for_each_entry(msc, &bts->network->bsc_data->mscs, entry)
- generate_location_state_trap(bts, msc->msc_con);
+ generate_location_state_trap(bts, msc);
}
static int location_equal(struct bts_location *a, struct bts_location *b)
@@ -537,7 +643,7 @@ static int set_net_inform_msc(struct ctrl_cmd *cmd, void *data)
trap->id = "0";
trap->variable = "inform-msc-v1";
trap->reply = talloc_strdup(trap, cmd->value);
- ctrl_cmd_send(&msc->msc_con->write_queue, trap);
+ sccplite_msc_ctrl_cmd_send(msc, trap);
talloc_free(trap);
}
@@ -625,7 +731,7 @@ static int msc_signal_handler(unsigned int subsys, unsigned int signal,
net = msc->data->network;
llist_for_each_entry(bts, &net->bts_list, list)
- generate_location_state_trap(bts, msc->data->msc_con);
+ generate_location_state_trap(bts, msc->data);
return 0;
}
diff --git a/src/osmo-bsc/osmo_bsc_filter.c b/src/osmo-bsc/osmo_bsc_filter.c
index 5f60989a7..0d0fc29c6 100644
--- a/src/osmo-bsc/osmo_bsc_filter.c
+++ b/src/osmo-bsc/osmo_bsc_filter.c
@@ -161,7 +161,7 @@ struct bsc_msc_data *bsc_find_msc(struct gsm_subscriber_connection *conn,
round_robin:
llist_for_each_entry(msc, &bsc->mscs, entry) {
- if (!msc->msc_con->is_authenticated)
+ if (!msc->is_authenticated)
continue;
if (!is_emerg && msc->type != MSC_CON_TYPE_NORMAL)
continue;
diff --git a/src/osmo-bsc/osmo_bsc_main.c b/src/osmo-bsc/osmo_bsc_main.c
index db6bcdb2c..095a07a16 100644
--- a/src/osmo-bsc/osmo_bsc_main.c
+++ b/src/osmo-bsc/osmo_bsc_main.c
@@ -248,8 +248,6 @@ static struct vty_app_info vty_info = {
extern int bsc_shutdown_net(struct gsm_network *net);
static void signal_handler(int signal)
{
- struct bsc_msc_data *msc;
-
fprintf(stdout, "signal %u received\n", signal);
switch (signal) {
@@ -270,8 +268,6 @@ static void signal_handler(int signal)
case SIGUSR2:
if (!bsc_gsmnet->bsc_data)
return;
- llist_for_each_entry(msc, &bsc_gsmnet->bsc_data->mscs, entry)
- bsc_msc_lost(msc->msc_con);
break;
default:
break;
diff --git a/src/osmo-bsc/osmo_bsc_msc.c b/src/osmo-bsc/osmo_bsc_msc.c
index 10f602a09..e00c9ef81 100644
--- a/src/osmo-bsc/osmo_bsc_msc.c
+++ b/src/osmo-bsc/osmo_bsc_msc.c
@@ -1,6 +1,6 @@
/*
* Handle the connection to the MSC. This include ping/timeout/reconnect
- * (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2008-2018 by Harald Welte <laforge@gnumonks.org>
* (C) 2009-2015 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2009-2015 by On-Waves
* All Rights Reserved
@@ -41,19 +41,12 @@
int osmo_bsc_msc_init(struct bsc_msc_data *data)
{
- data->msc_con = bsc_msc_create(data, &data->dests);
- if (!data->msc_con) {
- LOGP(DMSC, LOGL_ERROR, "Creating the MSC network connection failed.\n");
- return -1;
- }
-
/* FIXME: This is a leftover from the old architecture that used
* sccp-lite with osmocom specific authentication. Since we now
* changed to AoIP the connected status and the authentication
* status is managed differently. However osmo_bsc_filter.c still
* needs the flags to be set to one. See also: OS#3112 */
- data->msc_con->is_connected = 1;
- data->msc_con->is_authenticated = 1;
+ data->is_authenticated = 1;
return 0;
}
@@ -86,7 +79,6 @@ struct bsc_msc_data *osmo_msc_data_alloc(struct gsm_network *net, int nr)
/* Init back pointer */
msc_data->network = net;
- INIT_LLIST_HEAD(&msc_data->dests);
msc_data->core_plmn = (struct osmo_plmn_id){
.mcc = GSM_MCC_MNC_INVALID,
.mnc = GSM_MCC_MNC_INVALID,
diff --git a/src/osmo-bsc/osmo_bsc_sigtran.c b/src/osmo-bsc/osmo_bsc_sigtran.c
index 2c3507d9e..c33124f70 100644
--- a/src/osmo-bsc/osmo_bsc_sigtran.c
+++ b/src/osmo-bsc/osmo_bsc_sigtran.c
@@ -24,6 +24,7 @@
#include <osmocom/sigtran/sccp_sap.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/gsm/gsm0808.h>
+#include <osmocom/gsm/protocol/ipaccess.h>
#include <osmocom/core/msgb.h>
#include <osmocom/bsc/bsc_msc_data.h>
#include <osmocom/bsc/debug.h>
@@ -512,3 +513,37 @@ fail_auto_cofiguration:
"A-interface: More than one invalid/inclomplete configuration detected, unable to revover - check config file!\n");
return -EINVAL;
}
+
+/* this function receives all messages received on an ASP for a PPID / StreamID that
+ * libosmo-sigtran doesn't know about, such as piggy-backed CTRL and/or MGCP */
+int osmo_ss7_asp_rx_unknown(struct osmo_ss7_asp *asp, int ppid_mux, struct msgb *msg)
+{
+ struct ipaccess_head *iph;
+ struct ipaccess_head_ext *iph_ext;
+
+ if (asp->cfg.proto != OSMO_SS7_ASP_PROT_IPA) {
+ msgb_free(msg);
+ return 0;
+ }
+
+ switch (ppid_mux) {
+ case IPAC_PROTO_OSMO:
+ if (msg->len < sizeof(*iph) + sizeof(*iph_ext)) {
+ LOGP(DMSC, LOGL_ERROR, "The message is too short.\n");
+ msgb_free(msg);
+ return -EINVAL;
+ }
+ iph = (struct ipaccess_head *) msg->data;
+ iph_ext = (struct ipaccess_head_ext *) iph->data;
+ msg->l2h = iph_ext->data;
+ switch (iph_ext->proto) {
+ case IPAC_PROTO_EXT_CTRL:
+ return bsc_sccplite_rx_ctrl(asp, msg);
+ }
+ break;
+ default:
+ break;
+ }
+ msgb_free(msg);
+ return 0; /* OSMO_SS7_UNKNOWN? */
+}
diff --git a/src/osmo-bsc/osmo_bsc_vty.c b/src/osmo-bsc/osmo_bsc_vty.c
index bda89c142..d1a82ba92 100644
--- a/src/osmo-bsc/osmo_bsc_vty.c
+++ b/src/osmo-bsc/osmo_bsc_vty.c
@@ -1,6 +1,7 @@
/* Osmo BSC VTY Configuration */
/* (C) 2009-2015 by Holger Hans Peter Freyther
* (C) 2009-2014 by On-Waves
+ * (C) 2018 by Harald Welte <laforge@gnumonks.org>
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@@ -105,8 +106,6 @@ static void write_msc_amr_options(struct vty *vty, struct bsc_msc_data *msc)
static void write_msc(struct vty *vty, struct bsc_msc_data *msc)
{
- struct bsc_msc_dest *dest;
-
vty_out(vty, "msc %d%s", msc->nr, VTY_NEWLINE);
if (msc->core_plmn.mnc != GSM_MCC_MNC_INVALID)
vty_out(vty, " core-mobile-network-code %s%s",
@@ -154,10 +153,6 @@ static void write_msc(struct vty *vty, struct bsc_msc_data *msc)
}
- llist_for_each_entry(dest, &msc->dests, list)
- vty_out(vty, " dest %s %d %d%s", dest->ip, dest->port,
- dest->dscp, VTY_NEWLINE);
-
vty_out(vty, " type %s%s", msc->type == MSC_CON_TYPE_NORMAL ?
"normal" : "local", VTY_NEWLINE);
vty_out(vty, " allow-emergency %s%s", msc->allow_emerg ?
@@ -337,58 +332,6 @@ error:
return CMD_ERR_INCOMPLETE;
}
-DEFUN(cfg_net_msc_dest,
- cfg_net_msc_dest_cmd,
- "dest A.B.C.D <1-65000> <0-255>",
- "Add a destination to a MUX/MSC\n"
- "IP Address\n" "Port\n" "DSCP\n")
-{
- struct bsc_msc_dest *dest;
- struct bsc_msc_data *data = bsc_msc_data(vty);
-
- dest = talloc_zero(osmo_bsc_data(vty), struct bsc_msc_dest);
- if (!dest) {
- vty_out(vty, "%%Failed to create structure.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- dest->ip = talloc_strdup(dest, argv[0]);
- if (!dest->ip) {
- vty_out(vty, "%%Failed to copy dest ip.%s", VTY_NEWLINE);
- talloc_free(dest);
- return CMD_WARNING;
- }
-
- dest->port = atoi(argv[1]);
- dest->dscp = atoi(argv[2]);
- llist_add_tail(&dest->list, &data->dests);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_net_msc_no_dest,
- cfg_net_msc_no_dest_cmd,
- "no dest A.B.C.D <1-65000> <0-255>",
- NO_STR "Remove a destination to a MUX/MSC\n"
- "IP Address\n" "Port\n" "DSCP\n")
-{
- struct bsc_msc_dest *dest, *tmp;
- struct bsc_msc_data *data = bsc_msc_data(vty);
-
- int port = atoi(argv[1]);
- int dscp = atoi(argv[2]);
-
- llist_for_each_entry_safe(dest, tmp, &data->dests, list) {
- if (port != dest->port || dscp != dest->dscp
- || strcmp(dest->ip, argv[0]) != 0)
- continue;
-
- llist_del(&dest->list);
- talloc_free(dest);
- }
-
- return CMD_SUCCESS;
-}
-
DEFUN(cfg_net_msc_welcome_ussd,
cfg_net_msc_welcome_ussd_cmd,
"bsc-welcome-text .TEXT",
@@ -787,10 +730,12 @@ DEFUN(show_mscs,
{
struct bsc_msc_data *msc;
llist_for_each_entry(msc, &bsc_gsmnet->bsc_data->mscs, entry) {
- vty_out(vty, "MSC Nr: %d is connected: %d auth: %d.%s",
- msc->nr,
- msc->msc_con ? msc->msc_con->is_connected : -1,
- msc->msc_con ? msc->msc_con->is_authenticated : -1,
+ vty_out(vty, "%d %s %s ",
+ msc->a.cs7_instance,
+ osmo_ss7_asp_protocol_name(msc->a.asp_proto),
+ osmo_sccp_inst_addr_name(msc->a.sccp, &msc->a.bsc_addr));
+ vty_out(vty, "%s%s",
+ osmo_sccp_inst_addr_name(msc->a.sccp, &msc->a.msc_addr),
VTY_NEWLINE);
}
@@ -943,8 +888,6 @@ int bsc_vty_init_extra(void)
install_element(MSC_NODE, &cfg_net_bsc_ci_cmd);
install_element(MSC_NODE, &cfg_net_bsc_rtp_base_cmd);
install_element(MSC_NODE, &cfg_net_bsc_codec_list_cmd);
- install_element(MSC_NODE, &cfg_net_msc_dest_cmd);
- install_element(MSC_NODE, &cfg_net_msc_no_dest_cmd);
install_element(MSC_NODE, &cfg_net_msc_welcome_ussd_cmd);
install_element(MSC_NODE, &cfg_net_msc_no_welcome_ussd_cmd);
install_element(MSC_NODE, &cfg_net_msc_lost_ussd_cmd);