From 68e4be9c845e25f53aea511b1c57340a9da5825c Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sat, 26 May 2018 22:42:29 +0200 Subject: 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 --- src/libbsc/Makefile.am | 2 +- src/libbsc/bsc_msc.c | 320 --------------------------------------- src/libbsc/bsc_subscr_conn_fsm.c | 1 + src/libfilter/bsc_msg_filter.c | 1 - src/osmo-bsc/osmo_bsc_api.c | 1 + src/osmo-bsc/osmo_bsc_ctrl.c | 144 +++++++++++++++--- src/osmo-bsc/osmo_bsc_filter.c | 2 +- src/osmo-bsc/osmo_bsc_main.c | 4 - src/osmo-bsc/osmo_bsc_msc.c | 12 +- src/osmo-bsc/osmo_bsc_sigtran.c | 35 +++++ src/osmo-bsc/osmo_bsc_vty.c | 71 +-------- 11 files changed, 173 insertions(+), 420 deletions(-) delete mode 100644 src/libbsc/bsc_msc.c (limited to 'src') 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 - * (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 . - * - */ - -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -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 #include +#include #include #include #include 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 -#include #include #include #include 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 #include +#include #include #include 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 #include -#include + +#include + +#include +#include #include #include #include #include -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 + * (C) 2008-2018 by Harald Welte * (C) 2009-2015 by Holger Hans Peter Freyther * (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 #include #include +#include #include #include #include @@ -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 * 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); -- cgit v1.2.3