diff options
-rw-r--r-- | include/osmocom/msc/Makefile.am | 1 | ||||
-rw-r--r-- | include/osmocom/msc/gsm_data.h | 4 | ||||
-rw-r--r-- | include/osmocom/msc/msc_lac.h | 16 | ||||
-rw-r--r-- | src/libmsc/Makefile.am | 1 | ||||
-rw-r--r-- | src/libmsc/a_iface_bssap.c | 5 | ||||
-rw-r--r-- | src/libmsc/msc_lac.c | 51 | ||||
-rw-r--r-- | src/libmsc/msc_vty.c | 41 | ||||
-rw-r--r-- | src/libmsc/osmo_msc.c | 1 |
8 files changed, 120 insertions, 0 deletions
diff --git a/include/osmocom/msc/Makefile.am b/include/osmocom/msc/Makefile.am index b1a4810df..7e0a2961f 100644 --- a/include/osmocom/msc/Makefile.am +++ b/include/osmocom/msc/Makefile.am @@ -20,6 +20,7 @@ noinst_HEADERS = \ mncc.h \ mncc_int.h \ msc_ifaces.h \ + msc_lac.h \ msc_mgcp.h \ openbscdefines.h \ a_reset.h \ diff --git a/include/osmocom/msc/gsm_data.h b/include/osmocom/msc/gsm_data.h index c79adde59..d8a84d17d 100644 --- a/include/osmocom/msc/gsm_data.h +++ b/include/osmocom/msc/gsm_data.h @@ -347,6 +347,10 @@ struct gsm_network { /* MSISDN to which to route MO emergency calls */ char *route_to_msisdn; } emergency; + + /* A list head to keep track on the LACs that are assoctiated with + * this network */ + struct llist_head lac_contexts; }; struct osmo_esme; diff --git a/include/osmocom/msc/msc_lac.h b/include/osmocom/msc/msc_lac.h new file mode 100644 index 000000000..4b825236d --- /dev/null +++ b/include/osmocom/msc/msc_lac.h @@ -0,0 +1,16 @@ +#pragma once + +#include <stdint.h> +#include <osmocom/core/linuxlist.h> +#include <osmocom/msc/gsm_data.h> + +/* A struct to keep a context information about the LACs a specific BSC is + * associated with */ +struct lac_context { + struct llist_head list; + uint16_t lac; + enum ran_type ran_type; + struct bsc_context *bsc_context; +}; + +void msc_lac_update_a(struct gsm_network *network, uint16_t lac, struct bsc_context *bsc_context); diff --git a/src/libmsc/Makefile.am b/src/libmsc/Makefile.am index a2560ea21..1ebcd7963 100644 --- a/src/libmsc/Makefile.am +++ b/src/libmsc/Makefile.am @@ -42,6 +42,7 @@ libmsc_a_SOURCES = \ mncc_builtin.c \ mncc_sock.c \ msc_ifaces.c \ + msc_lac.c \ msc_mgcp.c \ rrlp.c \ silent_call.c \ diff --git a/src/libmsc/a_iface_bssap.c b/src/libmsc/a_iface_bssap.c index 1ace43dae..cb7bdec52 100644 --- a/src/libmsc/a_iface_bssap.c +++ b/src/libmsc/a_iface_bssap.c @@ -36,6 +36,7 @@ #include <osmocom/msc/a_reset.h> #include <osmocom/msc/transaction.h> #include <osmocom/msc/msc_mgcp.h> +#include <osmocom/msc/msc_lac.h> #include <errno.h> @@ -349,6 +350,10 @@ static int bssmap_rx_l3_compl(struct osmo_sccp_user *scu, const struct a_conn_in if (rc == MSC_CONN_ACCEPT) { LOGP(DMSC, LOGL_INFO, "User has been accepted by MSC.\n"); + + /* Record the LAC in a list for later use (related to other, future operations) */ + msc_lac_update_a(network, lac, a_conn_info->bsc); + return 0; } else if (rc == MSC_CONN_REJECT) LOGP(DMSC, LOGL_INFO, "User has been rejected by MSC.\n"); diff --git a/src/libmsc/msc_lac.c b/src/libmsc/msc_lac.c new file mode 100644 index 000000000..bf62ee87c --- /dev/null +++ b/src/libmsc/msc_lac.c @@ -0,0 +1,51 @@ +/* (C) 2018 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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/msc/msc_lac.h> +#include <stdint.h> + +/* Update list with LAC information for a particular BSC */ +void msc_lac_update_a(struct gsm_network *network, uint16_t lac, struct bsc_context *bsc_context) +{ + struct lac_context *lac_context; + bool create_lac_context = true; + + /* Try to find the lac_context list entry based on the given LAC, + * if one exist, we do not need to create a new one */ + llist_for_each_entry(lac_context, &network->lac_contexts, list) { + if (lac_context->lac == lac) { + create_lac_context = false; + break; + } + } + + /* We failed to find an existing LAC context, so we create a new one */ + if (create_lac_context) { + lac_context = talloc_zero(network, struct lac_context); + lac_context->lac = lac; + llist_add_tail(&lac_context->list, &network->lac_contexts); + } + + /* Update context info */ + lac_context->bsc_context = bsc_context; + lac_context->ran_type = RAN_GERAN_A; + + /* TODO: Add some statistical information like timestamps, when created? when last seen? */ +} diff --git a/src/libmsc/msc_vty.c b/src/libmsc/msc_vty.c index 3cbb0014d..830896a9a 100644 --- a/src/libmsc/msc_vty.c +++ b/src/libmsc/msc_vty.c @@ -53,6 +53,9 @@ #include <osmocom/msc/gsm_04_14.h> #include <osmocom/msc/signal.h> #include <osmocom/msc/mncc_int.h> +#include <osmocom/msc/a_iface.h> +#include <osmocom/msc/msc_lac.h> +#include <osmocom/sigtran/sccp_helpers.h> static struct gsm_network *gsmnet = NULL; @@ -505,6 +508,43 @@ DEFUN(show_msc_conn, show_msc_conn_cmd, return CMD_SUCCESS; } +DEFUN(show_lac, show_lac_cmd, "show lac", SHOW_STR "LAC Information\n") +{ + struct lac_context *lac_context; + char *sccp_addr_str; + char *ran_str; + uint16_t lac; + struct osmo_sccp_addr *bsc_addr; + struct osmo_ss7_instance *ss7; + + vty_out(vty, "--LAC RAN ------------Remote SCCP Address%s", + VTY_NEWLINE); + + llist_for_each_entry(lac_context, &gsmnet->lac_contexts, list) { + + lac = lac_context->lac; + sccp_addr_str = "(error)"; + + if (lac_context->ran_type == RAN_GERAN_A) { + ran_str = "A"; + bsc_addr = &lac_context->bsc_context->bsc_addr; + ss7 = osmo_ss7_instance_find(gsmnet->a.cs7_instance); + if (bsc_addr && ss7) + sccp_addr_str = + osmo_sccp_addr_name(ss7, bsc_addr); + } else { + /* FIXME: Also add printing for Iu RNC addresses */ + ran_str = "Iu"; + sccp_addr_str = "(fixme)"; + } + + vty_out(vty, "%5u %3s %s%s", lac, ran_str, sccp_addr_str, + VTY_NEWLINE); + } + + return CMD_SUCCESS; +} + static void vty_trans_hdr(struct vty *vty) { vty_out(vty, "------------Subscriber --ConnId -P TI -CallRef Proto%s", @@ -1451,6 +1491,7 @@ void msc_vty_init(struct gsm_network *msc_network) install_element_ve(&show_subscr_cmd); install_element_ve(&show_subscr_cache_cmd); install_element_ve(&show_msc_conn_cmd); + install_element_ve(&show_lac_cmd); install_element_ve(&show_msc_transaction_cmd); install_element_ve(&sms_send_pend_cmd); diff --git a/src/libmsc/osmo_msc.c b/src/libmsc/osmo_msc.c index a6618c093..6353661c0 100644 --- a/src/libmsc/osmo_msc.c +++ b/src/libmsc/osmo_msc.c @@ -72,6 +72,7 @@ struct gsm_network *gsm_network_init(void *ctx, mncc_recv_cb_t mncc_recv) net->mncc_recv = mncc_recv; INIT_LLIST_HEAD(&net->a.bscs); + INIT_LLIST_HEAD(&net->lac_contexts); return net; } |