aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmocom/bsc/Makefile.am1
-rw-r--r--include/osmocom/bsc/bsc_msc.h77
-rw-r--r--include/osmocom/bsc/bsc_msc_data.h10
-rw-r--r--include/osmocom/bsc/osmo_bsc_sigtran.h3
-rw-r--r--src/libbsc/Makefile.am2
-rw-r--r--src/libbsc/bsc_msc.c320
-rw-r--r--src/libbsc/bsc_subscr_conn_fsm.c1
-rw-r--r--src/libfilter/bsc_msg_filter.c1
-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
-rw-r--r--tests/bssap/bssap_test.c4
16 files changed, 182 insertions, 506 deletions
diff --git a/include/osmocom/bsc/Makefile.am b/include/osmocom/bsc/Makefile.am
index 80f9b01ea..bae13f0cb 100644
--- a/include/osmocom/bsc/Makefile.am
+++ b/include/osmocom/bsc/Makefile.am
@@ -5,7 +5,6 @@ noinst_HEADERS = \
abis_rsl.h \
acc_ramp.h \
arfcn_range_encode.h \
- bsc_msc.h \
bsc_msg_filter.h \
bsc_rll.h \
bsc_subscriber.h \
diff --git a/include/osmocom/bsc/bsc_msc.h b/include/osmocom/bsc/bsc_msc.h
deleted file mode 100644
index ceaea531a..000000000
--- a/include/osmocom/bsc/bsc_msc.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/* Routines to talk to the MSC using the IPA Protocol */
-/*
- * (C) 2010 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/>.
- *
- */
-
-#ifndef BSC_MSC_H
-#define BSC_MSC_H
-
-#include <osmocom/core/write_queue.h>
-#include <osmocom/core/timer.h>
-#include <osmocom/sigtran/sccp_sap.h>
-#include <osmocom/bsc/a_reset.h>
-
-#include <netinet/in.h>
-
-struct bsc_msc_dest {
- struct llist_head list;
-
- char *ip;
- int port;
- int dscp;
-};
-
-
-struct bsc_msc_connection {
- /* FIXME: Remove stuff that is no longer needed! */
- struct osmo_wqueue write_queue;
- int is_connected;
- int is_authenticated;
- int first_contact;
-
- struct llist_head *dests;
-
- const char *name;
-
- void (*connection_loss) (struct bsc_msc_connection *);
- void (*connected) (struct bsc_msc_connection *);
- struct osmo_timer_list reconnect_timer;
- struct osmo_timer_list timeout_timer;
-
- struct msgb *pending_msg;
-
- /* Sigtran connection data */
- struct osmo_sccp_instance *sccp;
- struct osmo_sccp_user *sccp_user;
- struct osmo_sccp_addr g_calling_addr;
- struct osmo_sccp_addr g_called_addr;
- struct a_reset_ctx *reset;
-
- int conn_id_counter;
-};
-
-struct bsc_msc_connection *bsc_msc_create(void *ctx, struct llist_head *dest);
-int bsc_msc_connect(struct bsc_msc_connection *);
-void bsc_msc_schedule_connect(struct bsc_msc_connection *);
-
-void bsc_msc_lost(struct bsc_msc_connection *);
-
-struct msgb *bsc_msc_id_get_resp(int fixed, const char *token, const uint8_t *res, int len);
-
-#endif
diff --git a/include/osmocom/bsc/bsc_msc_data.h b/include/osmocom/bsc/bsc_msc_data.h
index 2ace1786b..baa58e7b3 100644
--- a/include/osmocom/bsc/bsc_msc_data.h
+++ b/include/osmocom/bsc/bsc_msc_data.h
@@ -3,6 +3,7 @@
*
* (C) 2010-2015 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2010-2015 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
@@ -27,7 +28,6 @@
#ifndef _OSMO_MSC_DATA_H
#define _OSMO_MSC_DATA_H
-#include "bsc_msc.h"
#include "debug.h"
#include <osmocom/core/timer.h>
@@ -75,26 +75,20 @@ struct bsc_msc_data {
/* Connection data */
- struct bsc_msc_connection *msc_con;
struct osmo_plmn_id core_plmn;
int core_lac;
int core_ci;
int rtp_base;
+ bool is_authenticated;
/* audio codecs */
struct gsm48_multi_rate_conf amr_conf;
struct gsm_audio_support **audio_support;
int audio_length;
- /* destinations */
- struct llist_head dests;
-
/* ussd welcome text */
char *ussd_welcome_txt;
- /* mgcp agent */
- struct osmo_wqueue mgcp_agent;
-
int nr;
/* ussd msc connection lost text */
diff --git a/include/osmocom/bsc/osmo_bsc_sigtran.h b/include/osmocom/bsc/osmo_bsc_sigtran.h
index 80d4f5b8b..bd8b06398 100644
--- a/include/osmocom/bsc/osmo_bsc_sigtran.h
+++ b/include/osmocom/bsc/osmo_bsc_sigtran.h
@@ -41,3 +41,6 @@ void osmo_bsc_sigtran_reset(const struct bsc_msc_data *msc);
/* Send reset-ack to MSC */
void osmo_bsc_sigtran_tx_reset_ack(const struct bsc_msc_data *msc);
+
+/* 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);
diff --git a/src/libbsc/Makefile.am b/src/libbsc/Makefile.am
index 744278b6d..d215e14f9 100644
--- a/src/libbsc/Makefile.am
+++ b/src/libbsc/Makefile.am
@@ -47,7 +47,7 @@ libbsc_a_SOURCES = \
system_information.c \
e1_config.c \
bsc_api.c \
- bsc_msc.c bsc_vty.c \
+ bsc_vty.c \
gsm_04_08_utils.c \
gsm_04_80_utils.c \
bsc_init.c \
diff --git a/src/libbsc/bsc_msc.c b/src/libbsc/bsc_msc.c
deleted file mode 100644
index 648b3e641..000000000
--- a/src/libbsc/bsc_msc.c
+++ /dev/null
@@ -1,320 +0,0 @@
-/* Routines to talk to the MSC using the IPA Protocol */
-/*
- * (C) 2010 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 <osmocom/bsc/bsc_msc.h>
-#include <osmocom/bsc/debug.h>
-#include <osmocom/abis/ipaccess.h>
-
-#include <osmocom/core/write_queue.h>
-#include <osmocom/core/talloc.h>
-
-#include <osmocom/gsm/tlv.h>
-
-#include <arpa/inet.h>
-#include <sys/socket.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-static void connection_loss(struct bsc_msc_connection *con)
-{
- struct osmo_fd *fd;
-
- fd = &con->write_queue.bfd;
-
- if (con->pending_msg) {
- LOGP(DMSC, LOGL_ERROR,
- "MSC(%s) dropping incomplete message.\n", con->name);
- msgb_free(con->pending_msg);
- con->pending_msg = NULL;
- }
-
- close(fd->fd);
- fd->fd = -1;
- fd->cb = osmo_wqueue_bfd_cb;
- fd->when = 0;
-
- con->is_connected = 0;
- con->first_contact = 0;
- con->connection_loss(con);
-}
-
-static void msc_con_timeout(void *_con)
-{
- struct bsc_msc_connection *con = _con;
-
- LOGP(DMSC, LOGL_ERROR,
- "MSC(%s) Connection timeout.\n", con->name);
- bsc_msc_lost(con);
-}
-
-/* called in the case of a non blocking connect */
-static int msc_connection_connect(struct osmo_fd *fd, unsigned int what)
-{
- int rc;
- int val;
- struct bsc_msc_connection *con;
- struct osmo_wqueue *queue;
-
- socklen_t len = sizeof(val);
-
- queue = container_of(fd, struct osmo_wqueue, bfd);
- con = container_of(queue, struct bsc_msc_connection, write_queue);
-
- if ((what & BSC_FD_WRITE) == 0) {
- LOGP(DMSC, LOGL_ERROR,
- "MSC(%s) Callback but not writable.\n", con->name);
- return -1;
- }
-
- /* From here on we will either be connected or reconnect */
- osmo_timer_del(&con->timeout_timer);
-
- /* check the socket state */
- rc = getsockopt(fd->fd, SOL_SOCKET, SO_ERROR, &val, &len);
- if (rc != 0) {
- LOGP(DMSC, LOGL_ERROR,
- "getsockopt for the MSC(%s) socket failed.\n", con->name);
- goto error;
- }
- if (val != 0) {
- LOGP(DMSC, LOGL_ERROR,
- "Not connected to the MSC(%s): %d\n",
- con->name, val);
- goto error;
- }
-
-
- /* go to full operation */
- fd->cb = osmo_wqueue_bfd_cb;
- fd->when = BSC_FD_READ | BSC_FD_EXCEPT;
-
- con->is_connected = 1;
- LOGP(DMSC, LOGL_NOTICE,
- "(Re)Connected to the MSC(%s).\n", con->name);
- if (con->connected)
- con->connected(con);
- return 0;
-
-error:
- osmo_fd_unregister(fd);
- connection_loss(con);
- return -1;
-}
-static void setnonblocking(struct osmo_fd *fd)
-{
- int flags;
-
- flags = fcntl(fd->fd, F_GETFL);
- if (flags < 0) {
- perror("fcntl get failed");
- close(fd->fd);
- fd->fd = -1;
- return;
- }
-
- flags |= O_NONBLOCK;
- flags = fcntl(fd->fd, F_SETFL, flags);
- if (flags < 0) {
- perror("fcntl get failed");
- close(fd->fd);
- fd->fd = -1;
- return;
- }
-}
-
-int bsc_msc_connect(struct bsc_msc_connection *con)
-{
- struct bsc_msc_dest *dest;
- struct osmo_fd *fd;
- struct sockaddr_in sin;
- int on = 1, ret;
-
- if (llist_empty(con->dests)) {
- LOGP(DMSC, LOGL_ERROR,
- "No MSC(%s) connections configured.\n",
- con->name);
- connection_loss(con);
- return -1;
- }
-
- /* TODO: Why are we not using the libosmocore soecket
- * abstraction, or libosmo-netif? */
-
- /* move to the next connection */
- dest = (struct bsc_msc_dest *) con->dests->next;
- llist_del(&dest->list);
- llist_add_tail(&dest->list, con->dests);
-
- LOGP(DMSC, LOGL_NOTICE,
- "Attempting to connect MSC(%s) at %s:%d\n",
- con->name, dest->ip, dest->port);
-
- con->is_connected = 0;
-
- msgb_free(con->pending_msg);
- con->pending_msg = NULL;
-
- fd = &con->write_queue.bfd;
- fd->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- fd->priv_nr = 1;
-
- if (fd->fd < 0) {
- perror("Creating TCP socket failed");
- return fd->fd;
- }
-
- /* make it non blocking */
- setnonblocking(fd);
-
- /* set the socket priority */
- ret = setsockopt(fd->fd, IPPROTO_IP, IP_TOS,
- &dest->dscp, sizeof(dest->dscp));
- if (ret != 0)
- LOGP(DMSC, LOGL_ERROR,
- "Failed to set DSCP to %d on MSC(%s). %s\n",
- dest->dscp, con->name, strerror(errno));
-
- memset(&sin, 0, sizeof(sin));
- sin.sin_family = AF_INET;
- sin.sin_port = htons(dest->port);
- inet_aton(dest->ip, &sin.sin_addr);
-
- ret = setsockopt(fd->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
- if (ret != 0)
- LOGP(DMSC, LOGL_ERROR,
- "Failed to set SO_REUSEADDR socket option\n");
- ret = connect(fd->fd, (struct sockaddr *) &sin, sizeof(sin));
-
- if (ret == -1 && errno == EINPROGRESS) {
- LOGP(DMSC, LOGL_ERROR,
- "MSC(%s) Connection in progress\n", con->name);
- fd->when = BSC_FD_WRITE;
- fd->cb = msc_connection_connect;
- osmo_timer_setup(&con->timeout_timer, msc_con_timeout, con);
- osmo_timer_schedule(&con->timeout_timer, 20, 0);
- } else if (ret < 0) {
- perror("Connection failed");
- connection_loss(con);
- return ret;
- } else {
- fd->when = BSC_FD_READ | BSC_FD_EXCEPT;
- fd->cb = osmo_wqueue_bfd_cb;
- con->is_connected = 1;
- if (con->connected)
- con->connected(con);
- }
-
- ret = osmo_fd_register(fd);
- if (ret < 0) {
- perror("Registering the fd failed");
- close(fd->fd);
- return ret;
- }
-
- return ret;
-}
-
-struct bsc_msc_connection *bsc_msc_create(void *ctx, struct llist_head *dests)
-{
- struct bsc_msc_connection *con;
-
- con = talloc_zero(NULL, struct bsc_msc_connection);
- if (!con) {
- LOGP(DMSC, LOGL_FATAL, "Failed to create the MSC connection.\n");
- return NULL;
- }
-
- con->dests = dests;
- con->write_queue.bfd.fd = -1;
- con->name = "";
- osmo_wqueue_init(&con->write_queue, 100);
- return con;
-}
-
-void bsc_msc_lost(struct bsc_msc_connection *con)
-{
- osmo_wqueue_clear(&con->write_queue);
- osmo_timer_del(&con->timeout_timer);
- osmo_timer_del(&con->reconnect_timer);
-
- if (con->write_queue.bfd.fd >= 0)
- osmo_fd_unregister(&con->write_queue.bfd);
- connection_loss(con);
-}
-
-static void reconnect_msc(void *_msc)
-{
- struct bsc_msc_connection *con = _msc;
-
- LOGP(DMSC, LOGL_NOTICE,
- "Attempting to reconnect to the MSC(%s).\n", con->name);
- bsc_msc_connect(con);
-}
-
-void bsc_msc_schedule_connect(struct bsc_msc_connection *con)
-{
- LOGP(DMSC, LOGL_NOTICE,
- "Attempting to reconnect to the MSC(%s)\n", con->name);
- osmo_timer_setup(&con->reconnect_timer, reconnect_msc, con);
- osmo_timer_schedule(&con->reconnect_timer, 5, 0);
-}
-
-struct msgb *bsc_msc_id_get_resp(int fixed, const char *token, const uint8_t *res, int len)
-{
- struct msgb *msg;
-
- if (!token) {
- LOGP(DMSC, LOGL_ERROR, "No token specified.\n");
- return NULL;
- }
-
- msg = msgb_alloc_headroom(4096, 128, "id resp");
- if (!msg) {
- LOGP(DMSC, LOGL_ERROR, "Failed to create the message.\n");
- return NULL;
- }
-
- /*
- * The situation is bizarre. The encoding doesn't follow the
- * TLV structure. It is more like a LV and old versions had
- * it wrong but we want new versions to old servers so we
- * introduce the quirk here.
- */
- msg->l2h = msgb_v_put(msg, IPAC_MSGT_ID_RESP);
- if (fixed) {
- msgb_put_u8(msg, 0);
- msgb_put_u8(msg, strlen(token) + 2);
- msgb_tv_fixed_put(msg, IPAC_IDTAG_UNITNAME, strlen(token) + 1, (uint8_t *) token);
- if (len > 0) {
- msgb_put_u8(msg, 0);
- msgb_put_u8(msg, len + 1);
- msgb_tv_fixed_put(msg, 0x24, len, res);
- }
- } else {
- msgb_l16tv_put(msg, strlen(token) + 1,
- IPAC_IDTAG_UNITNAME, (uint8_t *) token);
- }
-
- return msg;
-}
diff --git a/src/libbsc/bsc_subscr_conn_fsm.c b/src/libbsc/bsc_subscr_conn_fsm.c
index 54224f75c..89ac48234 100644
--- a/src/libbsc/bsc_subscr_conn_fsm.c
+++ b/src/libbsc/bsc_subscr_conn_fsm.c
@@ -23,6 +23,7 @@
#include <osmocom/gsm/gsm0808_utils.h>
#include <osmocom/bsc/debug.h>
+#include <osmocom/bsc/a_reset.h>
#include <osmocom/bsc/bsc_api.h>
#include <osmocom/bsc/gsm_data.h>
#include <osmocom/bsc/handover.h>
diff --git a/src/libfilter/bsc_msg_filter.c b/src/libfilter/bsc_msg_filter.c
index 120169bf9..852067e33 100644
--- a/src/libfilter/bsc_msg_filter.c
+++ b/src/libfilter/bsc_msg_filter.c
@@ -23,7 +23,6 @@
#include <osmocom/bsc/bsc_msg_filter.h>
-#include <osmocom/bsc/bsc_msc.h>
#include <osmocom/bsc/gsm_data.h>
#include <osmocom/bsc/debug.h>
#include <osmocom/bsc/ipaccess.h>
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);
diff --git a/tests/bssap/bssap_test.c b/tests/bssap/bssap_test.c
index 00bc64cdc..c9e7075e2 100644
--- a/tests/bssap/bssap_test.c
+++ b/tests/bssap/bssap_test.c
@@ -156,3 +156,7 @@ int main(int argc, char **argv)
struct gsm_subscriber_connection *bsc_subscr_con_allocate(struct gsm_network *net) {
OSMO_ASSERT(0);
}
+
+int bsc_sccplite_rx_ctrl(struct osmo_ss7_asp *asp, struct msgb *msg) {
+ OSMO_ASSERT(0);
+}