Harald Welte has uploaded this change for review. ( 
https://gerrit.osmocom.org/9340


Change subject: Remove 'struct bsc_msc_connection' + fix IPA-encapsulated CTRL
......................................................................

Remove 'struct bsc_msc_connection' + fix IPA-encapsulated CTRL

The bsc_msc_connection dates back to the old pre-libosmo-sigtran
days, and 90% of the field members weren't used at all (even the
new sigtran specific ones!).  Let's merge what remains into struct
bsc_msc_data.

As a side effect, the already dysfunctional "dest A.B.C.D" VTY
command has been removed from the MSC node.

There's quite a bit of fall-out in the CTRL interface, which was
the code with strongest ties to bsc_msc_connection.  This was
resolved by properly porting CTRL handling over to libosmo-sigtran,
meaning that an IPA/SCCPlite connected MSC can now again send CTRL
GET/SET commands, and can also receive those selective few TRAPs
that old osmo-bsc-sccplite also sent to its MSC[s].

Change-Id: I6b7354f3b23a26bb4eab12213ca3d3b614c8154f
Related: OS#2012
---
M include/osmocom/bsc/Makefile.am
D include/osmocom/bsc/bsc_msc.h
M include/osmocom/bsc/bsc_msc_data.h
M include/osmocom/bsc/osmo_bsc_sigtran.h
M src/libbsc/Makefile.am
D src/libbsc/bsc_msc.c
M src/libbsc/bsc_subscr_conn_fsm.c
M src/libfilter/bsc_msg_filter.c
M src/osmo-bsc/osmo_bsc_api.c
M src/osmo-bsc/osmo_bsc_ctrl.c
M src/osmo-bsc/osmo_bsc_filter.c
M src/osmo-bsc/osmo_bsc_main.c
M src/osmo-bsc/osmo_bsc_msc.c
M src/osmo-bsc/osmo_bsc_sigtran.c
M src/osmo-bsc/osmo_bsc_vty.c
M tests/bssap/bssap_test.c
16 files changed, 179 insertions(+), 509 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/40/9340/1

diff --git a/include/osmocom/bsc/Makefile.am b/include/osmocom/bsc/Makefile.am
index 80f9b01..bae13f0 100644
--- a/include/osmocom/bsc/Makefile.am
+++ b/include/osmocom/bsc/Makefile.am
@@ -5,7 +5,6 @@
        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 ceaea53..0000000
--- 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 <ze...@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 2ace178..baa58e7 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 <ze...@selfish.org>
  * (C) 2010-2015 by On-Waves
+ * (C) 2018 by Harald Welte <lafo...@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 @@


        /* 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 80d4f5b..bd8b063 100644
--- a/include/osmocom/bsc/osmo_bsc_sigtran.h
+++ b/include/osmocom/bsc/osmo_bsc_sigtran.h
@@ -41,3 +41,6 @@

 /* 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 744278b..d215e14 100644
--- a/src/libbsc/Makefile.am
+++ b/src/libbsc/Makefile.am
@@ -47,7 +47,7 @@
        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 648b3e6..0000000
--- 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 <ze...@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 54224f7..89ac482 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 120169b..852067e 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 8c16bde..8081ea4 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 5f88b85..471f9d0 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,15 +158,18 @@
 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;
        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)
-               cmd->reply = "connected";
-       else
-               cmd->reply = "disconnected";
+       cmd->reply = talloc_strdup(cmd, osmo_fsm_inst_state_name(as->fi));
        return CTRL_CMD_REPLY;
 }

@@ -80,14 +179,15 @@

 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 +284,12 @@

 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 +313,7 @@
                                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 +322,7 @@
        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 +637,7 @@
                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 +725,7 @@

        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 5f60989..0d0fc29 100644
--- a/src/osmo-bsc/osmo_bsc_filter.c
+++ b/src/osmo-bsc/osmo_bsc_filter.c
@@ -161,7 +161,7 @@

 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 db6bcdb..095a07a 100644
--- a/src/osmo-bsc/osmo_bsc_main.c
+++ b/src/osmo-bsc/osmo_bsc_main.c
@@ -248,8 +248,6 @@
 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 @@
        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 10f602a..e00c9ef 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 <lafo...@gnumonks.org>
+ * (C) 2008-2018 by Harald Welte <lafo...@gnumonks.org>
  * (C) 2009-2015 by Holger Hans Peter Freyther <ze...@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 @@
        /* 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 2c3507d..c33124f 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 @@
             "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 bda89c1..d1a82ba 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 <lafo...@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(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 @@

        }

-       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 @@
        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 @@
 {
        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 @@
        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 00bc64c..c9e7075 100644
--- a/tests/bssap/bssap_test.c
+++ b/tests/bssap/bssap_test.c
@@ -156,3 +156,7 @@
 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);
+}

--
To view, visit https://gerrit.osmocom.org/9340
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I6b7354f3b23a26bb4eab12213ca3d3b614c8154f
Gerrit-Change-Number: 9340
Gerrit-PatchSet: 1
Gerrit-Owner: Harald Welte <lafo...@gnumonks.org>

Reply via email to