pespin has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/osmo-bsc/+/28256 )


Change subject: Move all SMSCB/CBC vty code to its own file
......................................................................

Move all SMSCB/CBC vty code to its own file

This way we separate all the VTY boilerplate from the actual logic, as
we usually do in all other subsystems.

Change-Id: Ifc7d1693d745dd2a3c31e3ee9610d8c634b50812
---
M include/osmocom/bsc/smscb.h
M src/osmo-bsc/Makefile.am
M src/osmo-bsc/cbsp_link.c
M src/osmo-bsc/smscb.c
A src/osmo-bsc/smscb_vty.c
5 files changed, 426 insertions(+), 395 deletions(-)



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

diff --git a/include/osmocom/bsc/smscb.h b/include/osmocom/bsc/smscb.h
index 0e157c6..03c3bb0 100644
--- a/include/osmocom/bsc/smscb.h
+++ b/include/osmocom/bsc/smscb.h
@@ -18,7 +18,6 @@
 const char *bts_smscb_chan_state_name(const struct bts_smscb_chan_state 
*cstate);
 unsigned int bts_smscb_chan_load_percent(const struct bts_smscb_chan_state 
*cstate);
 unsigned int bts_smscb_chan_page_count(const struct bts_smscb_chan_state 
*cstate);
-void smscb_vty_init(void);

 /* cbch_scheduler.c */
 int bts_smscb_gen_sched_arr(struct bts_smscb_chan_state *cstate, struct 
bts_smscb_page ***arr_out);
@@ -61,9 +60,12 @@
                struct msgb *msg;
        } client;
 };
-void cbc_vty_init(void);
 int bsc_cbc_link_restart(void);
 int cbsp_tx_decoded(struct bsc_cbc_link *cbc, struct osmo_cbsp_decoded 
*decoded);

 void bts_etws_init(struct gsm_bts *bts);
 void bts_etws_bootstrap(struct gsm_bts *bts);
+
+/* smscb_vty.c: */
+void smscb_vty_init(void);
+void cbc_vty_init(void);
diff --git a/src/osmo-bsc/Makefile.am b/src/osmo-bsc/Makefile.am
index 583fb79..557178e 100644
--- a/src/osmo-bsc/Makefile.am
+++ b/src/osmo-bsc/Makefile.am
@@ -106,6 +106,7 @@
        system_information.c \
        timeslot_fsm.c \
        smscb.c \
+       smscb_vty.c \
        cbch_scheduler.c \
        cbsp_link.c \
        power_control.c \
diff --git a/src/osmo-bsc/cbsp_link.c b/src/osmo-bsc/cbsp_link.c
index 4926799..39798df 100644
--- a/src/osmo-bsc/cbsp_link.c
+++ b/src/osmo-bsc/cbsp_link.c
@@ -21,7 +21,6 @@


 #include <osmocom/bsc/gsm_data.h>
-#include <osmocom/bsc/vty.h>
 #include <osmocom/bsc/debug.h>
 #include <osmocom/bsc/smscb.h>
 #include <osmocom/bsc/bsc_msc_data.h>
@@ -320,341 +319,3 @@
        talloc_free(cbsp);
        return 0;
 }
-
-static struct bsc_cbc_link *vty_cbc_data(struct vty *vty)
-{
-       return bsc_gsmnet->cbc;
-}
-
-/*********************************************************************************
- * VTY Interface (Configuration + Introspection)
- 
*********************************************************************************/
-
-DEFUN(cfg_cbc, cfg_cbc_cmd,
-       "cbc", "Configure CBSP Link to Cell Broadcast Centre\n")
-{
-       vty->node = CBC_NODE;
-       return CMD_SUCCESS;
-}
-
-DEFUN(cfg_cbc_mode, cfg_cbc_mode_cmd,
-       "mode (server|client|disabled)",
-       "Set OsmoBSC as CBSP server or client\n"
-       "CBSP Server: listen for inbound TCP connections from a remote Cell 
Broadcast Centre\n"
-       "CBSP Client: establish outbound TCP connection to a remote Cell 
Broadcast Centre\n"
-       "Disable CBSP link\n")
-{
-       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
-       cbc->mode = get_string_value(bsc_cbc_link_mode_names, argv[0]);
-       OSMO_ASSERT(cbc->mode >= 0);
-
-       /* Immediately restart/stop CBSP only when coming from a telnet 
session. The settings from the config file take
-        * effect in osmo_bsc_main.c's invocation of bsc_cbc_link_restart(). */
-       if (vty->type != VTY_FILE)
-               bsc_cbc_link_restart();
-
-       return CMD_SUCCESS;
-}
-
-DEFUN(cfg_cbc_server, cfg_cbc_server_cmd,
-       "server", "Configure OsmoBSC's CBSP server role\n")
-{
-       vty->node = CBC_SERVER_NODE;
-       return CMD_SUCCESS;
-}
-
-DEFUN(cfg_cbc_server_local_ip, cfg_cbc_server_local_ip_cmd,
-       "local-ip " VTY_IPV46_CMD,
-       "Set IP Address to listen on for inbound CBSP from a Cell Broadcast 
Centre\n"
-       "IPv4 address\n" "IPv6 address\n")
-{
-       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
-       osmo_sockaddr_str_from_str(&cbc->server.local_addr, argv[0], 
cbc->server.local_addr.port);
-       return CMD_SUCCESS;
-}
-
-DEFUN(cfg_cbc_server_local_port, cfg_cbc_server_local_port_cmd,
-       "local-port <1-65535>",
-       "Set TCP port to listen on for inbound CBSP from a Cell Broadcast 
Centre\n"
-       "CBSP port number (Default: " OSMO_STRINGIFY_VAL(CBSP_TCP_PORT) ")\n")
-{
-       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
-       cbc->server.local_addr.port = atoi(argv[0]);
-       return CMD_SUCCESS;
-}
-
-DEFUN(cfg_cbc_client, cfg_cbc_client_cmd,
-       "client", "Configure OsmoBSC's CBSP client role\n")
-{
-       vty->node = CBC_CLIENT_NODE;
-       return CMD_SUCCESS;
-}
-
-DEFUN(cfg_cbc_client_remote_ip, cfg_cbc_client_remote_ip_cmd,
-       "remote-ip " VTY_IPV46_CMD,
-       "Set IP Address of the Cell Broadcast Centre, to establish CBSP link 
to\n"
-       "IPv4 address\n" "IPv6 address\n")
-{
-       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
-       osmo_sockaddr_str_from_str(&cbc->client.remote_addr, argv[0], 
cbc->client.remote_addr.port);
-       return CMD_SUCCESS;
-}
-
-DEFUN(cfg_cbc_client_remote_port, cfg_cbc_client_remote_port_cmd,
-       "remote-port <1-65535>",
-       "Set TCP port of the Cell Broadcast Centre, to establish CBSP link to\n"
-       "CBSP port number (Default: " OSMO_STRINGIFY_VAL(CBSP_TCP_PORT) ")\n")
-{
-       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
-       cbc->client.remote_addr.port = atoi(argv[0]);
-       return CMD_SUCCESS;
-}
-
-DEFUN(cfg_cbc_client_local_ip, cfg_cbc_client_local_ip_cmd,
-       "local-ip " VTY_IPV46_CMD,
-       "Set local bind address for the outbound CBSP link to the Cell 
Broadcast Centre\n"
-       "IPv4 address\n" "IPv6 address\n")
-{
-       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
-       osmo_sockaddr_str_from_str(&cbc->client.local_addr, argv[0], 
cbc->client.local_addr.port);
-       return CMD_SUCCESS;
-}
-
-DEFUN(cfg_cbc_client_local_port, cfg_cbc_client_local_port_cmd,
-       "local-port <1-65535>",
-       "Set local bind port for the outbound CBSP link to the Cell Broadcast 
Centre\n"
-       "port number\n")
-{
-       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
-       cbc->client.local_addr.port = atoi(argv[0]);
-       return CMD_SUCCESS;
-}
-
-DEFUN(cfg_cbc_client_no_local_ip, cfg_cbc_client_no_local_ip_cmd,
-       "no local-ip",
-       NO_STR "Remove local IP address bind config for the CBSP client mode\n")
-{
-       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
-       cbc->client.local_addr = (struct osmo_sockaddr_str){ .port = 
cbc->client.local_addr.port };
-       return CMD_SUCCESS;
-}
-
-DEFUN(cfg_cbc_client_no_local_port, cfg_cbc_client_no_local_port_cmd,
-       "no local-port",
-       NO_STR "Remove local TCP port bind config for the CBSP client mode\n")
-{
-       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
-       cbc->client.local_addr.port = 0;
-       return CMD_SUCCESS;
-}
-
-static struct cmd_node cbc_node = {
-       CBC_NODE,
-       "%s(config-cbc)# ",
-       1,
-};
-
-static struct cmd_node cbc_server_node = {
-       CBC_SERVER_NODE,
-       "%s(config-cbc-server)# ",
-       1,
-};
-
-static struct cmd_node cbc_client_node = {
-       CBC_CLIENT_NODE,
-       "%s(config-cbc-client)# ",
-       1,
-};
-
-static int config_write_cbc(struct vty *vty)
-{
-       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
-
-       bool default_server_local;
-       bool default_client_remote;
-       bool default_client_local;
-
-       default_server_local = !osmo_sockaddr_str_cmp(&cbc->server.local_addr,
-                                                     
&bsc_cbc_default_server_local_addr);
-       default_client_remote = 
!osmo_sockaddr_str_is_set(&cbc->client.remote_addr);
-       default_client_local = 
!osmo_sockaddr_str_is_set(&cbc->client.local_addr);
-
-       /* If all reflects default values, skip the 'cbc' section */
-       if (cbc->mode == BSC_CBC_LINK_MODE_DISABLED
-           && default_server_local
-           && default_client_remote && default_client_local)
-               return 0;
-
-       vty_out(vty, "cbc%s", VTY_NEWLINE);
-       vty_out(vty, " mode %s%s", bsc_cbc_link_mode_name(cbc->mode), 
VTY_NEWLINE);
-
-       if (!default_server_local) {
-               vty_out(vty, " server%s", VTY_NEWLINE);
-
-               if (strcmp(cbc->server.local_addr.ip, 
bsc_cbc_default_server_local_addr.ip))
-                       vty_out(vty, "  local-ip %s%s", 
cbc->server.local_addr.ip, VTY_NEWLINE);
-               if (cbc->server.local_addr.port != 
bsc_cbc_default_server_local_addr.port)
-                       vty_out(vty, "  local-port %u%s", 
cbc->server.local_addr.port, VTY_NEWLINE);
-       }
-
-       if (!(default_client_remote && default_client_local)) {
-               vty_out(vty, " client%s", VTY_NEWLINE);
-
-               if (osmo_sockaddr_str_is_set(&cbc->client.remote_addr)) {
-                       vty_out(vty, "  remote-ip %s%s", 
cbc->client.remote_addr.ip, VTY_NEWLINE);
-                       if (cbc->client.remote_addr.port != CBSP_TCP_PORT)
-                               vty_out(vty, "  remote-port %u%s", 
cbc->client.remote_addr.port, VTY_NEWLINE);
-               }
-
-               if (cbc->client.local_addr.ip[0])
-                       vty_out(vty, "  local-ip %s%s", 
cbc->client.local_addr.ip, VTY_NEWLINE);
-               if (cbc->client.local_addr.port)
-                       vty_out(vty, "  local-port %u%s", 
cbc->client.local_addr.port, VTY_NEWLINE);
-       }
-
-       return 0;
-}
-
-DEFUN(show_cbc, show_cbc_cmd,
-       "show cbc",
-       SHOW_STR "Display state of CBC / CBSP\n")
-{
-       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
-
-       switch (cbc->mode) {
-       case BSC_CBC_LINK_MODE_DISABLED:
-               vty_out(vty, "CBSP link is disabled%s", VTY_NEWLINE);
-               break;
-
-       case BSC_CBC_LINK_MODE_SERVER:
-               vty_out(vty, "OsmoBSC is configured as CBSP Server on " 
OSMO_SOCKADDR_STR_FMT "%s",
-                       OSMO_SOCKADDR_STR_FMT_ARGS(&cbc->server.local_addr), 
VTY_NEWLINE);
-               vty_out(vty, "CBSP Server Connection: %s%s",
-                       cbc->server.sock_name ? cbc->server.sock_name : 
"Disconnected", VTY_NEWLINE);
-               break;
-
-       case BSC_CBC_LINK_MODE_CLIENT:
-               vty_out(vty, "OsmoBSC is configured as CBSP Client to remote 
CBC at " OSMO_SOCKADDR_STR_FMT "%s",
-                       OSMO_SOCKADDR_STR_FMT_ARGS(&cbc->client.remote_addr), 
VTY_NEWLINE);
-               vty_out(vty, "CBSP Client Connection: %s%s",
-                       cbc->client.sock_name ? cbc->client.sock_name : 
"Disconnected", VTY_NEWLINE);
-               break;
-       }
-       return CMD_SUCCESS;
-}
-
-/* --- Deprecated 'cbc' commands for backwards compat --- */
-
-DEFUN_DEPRECATED(cfg_cbc_remote_ip, cfg_cbc_remote_ip_cmd,
-       "remote-ip A.B.C.D",
-       "IP Address of the Cell Broadcast Centre\n"
-       "IP Address of the Cell Broadcast Centre\n")
-{
-       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
-       vty_out(vty, "%% cbc/remote-ip config is deprecated, instead use 
cbc/client/remote-ip and cbc/ mode%s",
-               VTY_NEWLINE);
-       osmo_sockaddr_str_from_str(&cbc->client.remote_addr, argv[0], 
cbc->client.remote_addr.port);
-       cbc->mode = BSC_CBC_LINK_MODE_CLIENT;
-       if (vty->type != VTY_FILE)
-               bsc_cbc_link_restart();
-       return CMD_SUCCESS;
-}
-DEFUN_DEPRECATED(cfg_cbc_no_remote_ip, cfg_cbc_no_remote_ip_cmd,
-       "no remote-ip",
-       NO_STR "Remove IP address of CBC; disables outbound CBSP connections\n")
-{
-       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
-       vty_out(vty, "%% cbc/remote-ip config is deprecated, instead use 
cbc/client/remote-ip and cbc/mode%s",
-               VTY_NEWLINE);
-       if (cbc->mode == BSC_CBC_LINK_MODE_CLIENT) {
-               cbc->mode = BSC_CBC_LINK_MODE_DISABLED;
-               if (vty->type != VTY_FILE)
-                       bsc_cbc_link_restart();
-       }
-       return CMD_SUCCESS;
-}
-
-DEFUN_DEPRECATED(cfg_cbc_remote_port, cfg_cbc_remote_port_cmd,
-       "remote-port <1-65535>",
-       "TCP Port number of the Cell Broadcast Centre (Default: 48049)\n"
-       "TCP Port number of the Cell Broadcast Centre (Default: 48049)\n")
-{
-       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
-       vty_out(vty, "%% cbc/remote-port config is deprecated, instead use 
cbc/client/remote-port%s",
-               VTY_NEWLINE);
-       cbc->client.remote_addr.port = atoi(argv[0]);
-       return CMD_SUCCESS;
-}
-
-DEFUN_DEPRECATED(cfg_cbc_listen_port, cfg_cbc_listen_port_cmd,
-       "listen-port <1-65535>",
-       "Local TCP port at which BSC listens for incoming CBSP connections from 
CBC\n"
-       "Local TCP port at which BSC listens for incoming CBSP connections from 
CBC\n")
-{
-       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
-       vty_out(vty, "%% cbc/listen-port config is deprecated, instead use 
cbc/server/local-port and cbc/mode%s",
-               VTY_NEWLINE);
-       cbc->mode = BSC_CBC_LINK_MODE_SERVER;
-       cbc->server.local_addr.port = atoi(argv[0]);
-       if (vty->type != VTY_FILE)
-               bsc_cbc_link_restart();
-       return CMD_SUCCESS;
-}
-
-DEFUN_DEPRECATED(cfg_cbc_no_listen_port, cfg_cbc_no_listen_port_cmd,
-       "no listen-port",
-       NO_STR "Remove CBSP Listen Port; disables inbound CBSP connections\n")
-{
-       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
-       vty_out(vty, "%% cbc/listen-port config is deprecated, instead use 
cbc/server/local-port and cbc/mode%s",
-               VTY_NEWLINE);
-       if (cbc->mode == BSC_CBC_LINK_MODE_SERVER) {
-               cbc->mode = BSC_CBC_LINK_MODE_DISABLED;
-               if (vty->type != VTY_FILE)
-                       bsc_cbc_link_restart();
-       }
-       return CMD_SUCCESS;
-}
-
-DEFUN_DEPRECATED(cfg_cbc_listen_ip, cfg_cbc_listen_ip_cmd,
-       "listen-ip A.B.C.D",
-       "Local IP Address where BSC listens for incoming CBC connections 
(Default: 127.0.0.1)\n"
-       "Local IP Address where BSC listens for incoming CBC connections\n")
-{
-       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
-       vty_out(vty, "%% cbc/listen-ip config is deprecated, instead use 
cbc/server/local-ip%s",
-               VTY_NEWLINE);
-       osmo_sockaddr_str_from_str(&cbc->server.local_addr, argv[0], 
cbc->server.local_addr.port);
-       return CMD_SUCCESS;
-}
-
-void cbc_vty_init(void)
-{
-       install_element_ve(&show_cbc_cmd);
-
-       install_element(CONFIG_NODE, &cfg_cbc_cmd);
-       install_node(&cbc_node, config_write_cbc);
-       install_element(CBC_NODE, &cfg_cbc_mode_cmd);
-
-       install_element(CBC_NODE, &cfg_cbc_server_cmd);
-       install_node(&cbc_server_node, NULL);
-       install_element(CBC_SERVER_NODE, &cfg_cbc_server_local_ip_cmd);
-       install_element(CBC_SERVER_NODE, &cfg_cbc_server_local_port_cmd);
-
-       install_element(CBC_NODE, &cfg_cbc_client_cmd);
-       install_node(&cbc_client_node, NULL);
-       install_element(CBC_CLIENT_NODE, &cfg_cbc_client_remote_ip_cmd);
-       install_element(CBC_CLIENT_NODE, &cfg_cbc_client_remote_port_cmd);
-       install_element(CBC_CLIENT_NODE, &cfg_cbc_client_local_ip_cmd);
-       install_element(CBC_CLIENT_NODE, &cfg_cbc_client_local_port_cmd);
-       install_element(CBC_CLIENT_NODE, &cfg_cbc_client_no_local_ip_cmd);
-       install_element(CBC_CLIENT_NODE, &cfg_cbc_client_no_local_port_cmd);
-
-       /* Deprecated, for backwards compat */
-       install_element(CBC_NODE, &cfg_cbc_remote_ip_cmd);
-       install_element(CBC_NODE, &cfg_cbc_no_remote_ip_cmd);
-       install_element(CBC_NODE, &cfg_cbc_remote_port_cmd);
-       install_element(CBC_NODE, &cfg_cbc_listen_port_cmd);
-       install_element(CBC_NODE, &cfg_cbc_no_listen_port_cmd);
-       install_element(CBC_NODE, &cfg_cbc_listen_ip_cmd);
-}
diff --git a/src/osmo-bsc/smscb.c b/src/osmo-bsc/smscb.c
index 8e2eb0c..193dc4e 100644
--- a/src/osmo-bsc/smscb.c
+++ b/src/osmo-bsc/smscb.c
@@ -38,7 +38,6 @@
 #include <osmocom/bsc/debug.h>
 #include <osmocom/bsc/gsm_data.h>
 #include <osmocom/bsc/smscb.h>
-#include <osmocom/bsc/vty.h>
 #include <osmocom/bsc/gsm_04_08_rr.h>
 #include <osmocom/bsc/lchan_fsm.h>
 #include <osmocom/bsc/abis_rsl.h>
@@ -1026,59 +1025,6 @@
        return rc;
 }

-/*********************************************************************************
- * VTY Interface (Introspection)
- 
*********************************************************************************/
-
-static void vty_dump_smscb_chan_state(struct vty *vty, const struct 
bts_smscb_chan_state *cs)
-{
-       const struct bts_smscb_message *sm;
-
-       vty_out(vty, "%s CBCH:%s", cs == &cs->bts->cbch_basic ? "BASIC" : 
"EXTENDED", VTY_NEWLINE);
-
-       vty_out(vty, " MsgId | SerNo | Pg |      Category | Perd | #Tx  | #Req 
| DCS%s", VTY_NEWLINE);
-       vty_out(vty, 
"-------|-------|----|---------------|------|------|------|----%s", 
VTY_NEWLINE);
-       llist_for_each_entry(sm, &cs->messages, list) {
-               vty_out(vty, "  %04x |  %04x | %2u | %13s | %4u | %4u | %4u | 
%02x%s",
-                       sm->input.msg_id, sm->input.serial_nr, sm->num_pages,
-                       get_value_string(cbsp_category_names, 
sm->input.category),
-                       sm->input.rep_period, sm->bcast_count, 
sm->input.num_bcast_req,
-                       sm->input.dcs, VTY_NEWLINE);
-       }
-       vty_out(vty, "%s", VTY_NEWLINE);
-}
-
-DEFUN(bts_show_cbs, bts_show_cbs_cmd,
-       "show bts <0-255> smscb [(basic|extended)]",
-       SHOW_STR "Display information about a BTS\n" "BTS number\n"
-       "SMS Cell Broadcast State\n"
-       "Show only information related to CBCH BASIC\n"
-       "Show only information related to CBCH EXTENDED\n")
-{
-       struct gsm_network *net = gsmnet_from_vty(vty);
-       int bts_nr = atoi(argv[0]);
-       struct gsm_bts *bts;
-
-       if (bts_nr >= net->num_bts) {
-               vty_out(vty, "%% can't find BTS '%s'%s", argv[0], VTY_NEWLINE);
-               return CMD_WARNING;
-       }
-       bts = gsm_bts_num(net, bts_nr);
-
-       if (argc < 2 || !strcmp(argv[1], "basic"))
-               vty_dump_smscb_chan_state(vty, &bts->cbch_basic);
-       if (argc < 2 || !strcmp(argv[1], "extended"))
-               vty_dump_smscb_chan_state(vty, &bts->cbch_extended);
-
-       return CMD_SUCCESS;
-}
-
-void smscb_vty_init(void)
-{
-       install_element_ve(&bts_show_cbs_cmd);
-}
-
-
 /* initialize the ETWS state of a BTS */
 void bts_etws_init(struct gsm_bts *bts)
 {
diff --git a/src/osmo-bsc/smscb_vty.c b/src/osmo-bsc/smscb_vty.c
new file mode 100644
index 0000000..b13d2db
--- /dev/null
+++ b/src/osmo-bsc/smscb_vty.c
@@ -0,0 +1,421 @@
+/* CBSP (Cell Broadcast Service Protocol) Handling for OsmoBSC */
+/*
+ * (C) 2019 by Harald Welte <[email protected]>
+ *
+ * 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/gsm_data.h>
+#include <osmocom/bsc/vty.h>
+#include <osmocom/bsc/debug.h>
+#include <osmocom/bsc/smscb.h>
+#include <osmocom/bsc/bsc_msc_data.h>
+#include <osmocom/bsc/bts.h>
+
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/socket.h>
+#include <osmocom/gsm/cbsp.h>
+
+/*********************************************************************************
+ * cbc
+ 
*********************************************************************************/
+static struct bsc_cbc_link *vty_cbc_data(struct vty *vty)
+{
+       return bsc_gsmnet->cbc;
+}
+
+DEFUN(cfg_cbc, cfg_cbc_cmd,
+       "cbc", "Configure CBSP Link to Cell Broadcast Centre\n")
+{
+       vty->node = CBC_NODE;
+       return CMD_SUCCESS;
+}
+
+DEFUN(cfg_cbc_mode, cfg_cbc_mode_cmd,
+       "mode (server|client|disabled)",
+       "Set OsmoBSC as CBSP server or client\n"
+       "CBSP Server: listen for inbound TCP connections from a remote Cell 
Broadcast Centre\n"
+       "CBSP Client: establish outbound TCP connection to a remote Cell 
Broadcast Centre\n"
+       "Disable CBSP link\n")
+{
+       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
+       cbc->mode = get_string_value(bsc_cbc_link_mode_names, argv[0]);
+       OSMO_ASSERT(cbc->mode >= 0);
+
+       /* Immediately restart/stop CBSP only when coming from a telnet 
session. The settings from the config file take
+        * effect in osmo_bsc_main.c's invocation of bsc_cbc_link_restart(). */
+       if (vty->type != VTY_FILE)
+               bsc_cbc_link_restart();
+
+       return CMD_SUCCESS;
+}
+
+DEFUN(cfg_cbc_server, cfg_cbc_server_cmd,
+       "server", "Configure OsmoBSC's CBSP server role\n")
+{
+       vty->node = CBC_SERVER_NODE;
+       return CMD_SUCCESS;
+}
+
+DEFUN(cfg_cbc_server_local_ip, cfg_cbc_server_local_ip_cmd,
+       "local-ip " VTY_IPV46_CMD,
+       "Set IP Address to listen on for inbound CBSP from a Cell Broadcast 
Centre\n"
+       "IPv4 address\n" "IPv6 address\n")
+{
+       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
+       osmo_sockaddr_str_from_str(&cbc->server.local_addr, argv[0], 
cbc->server.local_addr.port);
+       return CMD_SUCCESS;
+}
+
+DEFUN(cfg_cbc_server_local_port, cfg_cbc_server_local_port_cmd,
+       "local-port <1-65535>",
+       "Set TCP port to listen on for inbound CBSP from a Cell Broadcast 
Centre\n"
+       "CBSP port number (Default: " OSMO_STRINGIFY_VAL(CBSP_TCP_PORT) ")\n")
+{
+       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
+       cbc->server.local_addr.port = atoi(argv[0]);
+       return CMD_SUCCESS;
+}
+
+DEFUN(cfg_cbc_client, cfg_cbc_client_cmd,
+       "client", "Configure OsmoBSC's CBSP client role\n")
+{
+       vty->node = CBC_CLIENT_NODE;
+       return CMD_SUCCESS;
+}
+
+DEFUN(cfg_cbc_client_remote_ip, cfg_cbc_client_remote_ip_cmd,
+       "remote-ip " VTY_IPV46_CMD,
+       "Set IP Address of the Cell Broadcast Centre, to establish CBSP link 
to\n"
+       "IPv4 address\n" "IPv6 address\n")
+{
+       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
+       osmo_sockaddr_str_from_str(&cbc->client.remote_addr, argv[0], 
cbc->client.remote_addr.port);
+       return CMD_SUCCESS;
+}
+
+DEFUN(cfg_cbc_client_remote_port, cfg_cbc_client_remote_port_cmd,
+       "remote-port <1-65535>",
+       "Set TCP port of the Cell Broadcast Centre, to establish CBSP link to\n"
+       "CBSP port number (Default: " OSMO_STRINGIFY_VAL(CBSP_TCP_PORT) ")\n")
+{
+       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
+       cbc->client.remote_addr.port = atoi(argv[0]);
+       return CMD_SUCCESS;
+}
+
+DEFUN(cfg_cbc_client_local_ip, cfg_cbc_client_local_ip_cmd,
+       "local-ip " VTY_IPV46_CMD,
+       "Set local bind address for the outbound CBSP link to the Cell 
Broadcast Centre\n"
+       "IPv4 address\n" "IPv6 address\n")
+{
+       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
+       osmo_sockaddr_str_from_str(&cbc->client.local_addr, argv[0], 
cbc->client.local_addr.port);
+       return CMD_SUCCESS;
+}
+
+DEFUN(cfg_cbc_client_local_port, cfg_cbc_client_local_port_cmd,
+       "local-port <1-65535>",
+       "Set local bind port for the outbound CBSP link to the Cell Broadcast 
Centre\n"
+       "port number\n")
+{
+       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
+       cbc->client.local_addr.port = atoi(argv[0]);
+       return CMD_SUCCESS;
+}
+
+DEFUN(cfg_cbc_client_no_local_ip, cfg_cbc_client_no_local_ip_cmd,
+       "no local-ip",
+       NO_STR "Remove local IP address bind config for the CBSP client mode\n")
+{
+       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
+       cbc->client.local_addr = (struct osmo_sockaddr_str){ .port = 
cbc->client.local_addr.port };
+       return CMD_SUCCESS;
+}
+
+DEFUN(cfg_cbc_client_no_local_port, cfg_cbc_client_no_local_port_cmd,
+       "no local-port",
+       NO_STR "Remove local TCP port bind config for the CBSP client mode\n")
+{
+       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
+       cbc->client.local_addr.port = 0;
+       return CMD_SUCCESS;
+}
+
+static struct cmd_node cbc_node = {
+       CBC_NODE,
+       "%s(config-cbc)# ",
+       1,
+};
+
+static struct cmd_node cbc_server_node = {
+       CBC_SERVER_NODE,
+       "%s(config-cbc-server)# ",
+       1,
+};
+
+static struct cmd_node cbc_client_node = {
+       CBC_CLIENT_NODE,
+       "%s(config-cbc-client)# ",
+       1,
+};
+
+static int config_write_cbc(struct vty *vty)
+{
+       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
+
+       bool default_server_local;
+       bool default_client_remote;
+       bool default_client_local;
+
+       default_server_local = !osmo_sockaddr_str_cmp(&cbc->server.local_addr,
+                                                     
&bsc_cbc_default_server_local_addr);
+       default_client_remote = 
!osmo_sockaddr_str_is_set(&cbc->client.remote_addr);
+       default_client_local = 
!osmo_sockaddr_str_is_set(&cbc->client.local_addr);
+
+       /* If all reflects default values, skip the 'cbc' section */
+       if (cbc->mode == BSC_CBC_LINK_MODE_DISABLED
+           && default_server_local
+           && default_client_remote && default_client_local)
+               return 0;
+
+       vty_out(vty, "cbc%s", VTY_NEWLINE);
+       vty_out(vty, " mode %s%s", bsc_cbc_link_mode_name(cbc->mode), 
VTY_NEWLINE);
+
+       if (!default_server_local) {
+               vty_out(vty, " server%s", VTY_NEWLINE);
+
+               if (strcmp(cbc->server.local_addr.ip, 
bsc_cbc_default_server_local_addr.ip))
+                       vty_out(vty, "  local-ip %s%s", 
cbc->server.local_addr.ip, VTY_NEWLINE);
+               if (cbc->server.local_addr.port != 
bsc_cbc_default_server_local_addr.port)
+                       vty_out(vty, "  local-port %u%s", 
cbc->server.local_addr.port, VTY_NEWLINE);
+       }
+
+       if (!(default_client_remote && default_client_local)) {
+               vty_out(vty, " client%s", VTY_NEWLINE);
+
+               if (osmo_sockaddr_str_is_set(&cbc->client.remote_addr)) {
+                       vty_out(vty, "  remote-ip %s%s", 
cbc->client.remote_addr.ip, VTY_NEWLINE);
+                       if (cbc->client.remote_addr.port != CBSP_TCP_PORT)
+                               vty_out(vty, "  remote-port %u%s", 
cbc->client.remote_addr.port, VTY_NEWLINE);
+               }
+
+               if (cbc->client.local_addr.ip[0])
+                       vty_out(vty, "  local-ip %s%s", 
cbc->client.local_addr.ip, VTY_NEWLINE);
+               if (cbc->client.local_addr.port)
+                       vty_out(vty, "  local-port %u%s", 
cbc->client.local_addr.port, VTY_NEWLINE);
+       }
+
+       return 0;
+}
+
+DEFUN(show_cbc, show_cbc_cmd,
+       "show cbc",
+       SHOW_STR "Display state of CBC / CBSP\n")
+{
+       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
+
+       switch (cbc->mode) {
+       case BSC_CBC_LINK_MODE_DISABLED:
+               vty_out(vty, "CBSP link is disabled%s", VTY_NEWLINE);
+               break;
+
+       case BSC_CBC_LINK_MODE_SERVER:
+               vty_out(vty, "OsmoBSC is configured as CBSP Server on " 
OSMO_SOCKADDR_STR_FMT "%s",
+                       OSMO_SOCKADDR_STR_FMT_ARGS(&cbc->server.local_addr), 
VTY_NEWLINE);
+               vty_out(vty, "CBSP Server Connection: %s%s",
+                       cbc->server.sock_name ? cbc->server.sock_name : 
"Disconnected", VTY_NEWLINE);
+               break;
+
+       case BSC_CBC_LINK_MODE_CLIENT:
+               vty_out(vty, "OsmoBSC is configured as CBSP Client to remote 
CBC at " OSMO_SOCKADDR_STR_FMT "%s",
+                       OSMO_SOCKADDR_STR_FMT_ARGS(&cbc->client.remote_addr), 
VTY_NEWLINE);
+               vty_out(vty, "CBSP Client Connection: %s%s",
+                       cbc->client.sock_name ? cbc->client.sock_name : 
"Disconnected", VTY_NEWLINE);
+               break;
+       }
+       return CMD_SUCCESS;
+}
+
+/* --- Deprecated 'cbc' commands for backwards compat --- */
+
+DEFUN_DEPRECATED(cfg_cbc_remote_ip, cfg_cbc_remote_ip_cmd,
+       "remote-ip A.B.C.D",
+       "IP Address of the Cell Broadcast Centre\n"
+       "IP Address of the Cell Broadcast Centre\n")
+{
+       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
+       vty_out(vty, "%% cbc/remote-ip config is deprecated, instead use 
cbc/client/remote-ip and cbc/ mode%s",
+               VTY_NEWLINE);
+       osmo_sockaddr_str_from_str(&cbc->client.remote_addr, argv[0], 
cbc->client.remote_addr.port);
+       cbc->mode = BSC_CBC_LINK_MODE_CLIENT;
+       if (vty->type != VTY_FILE)
+               bsc_cbc_link_restart();
+       return CMD_SUCCESS;
+}
+DEFUN_DEPRECATED(cfg_cbc_no_remote_ip, cfg_cbc_no_remote_ip_cmd,
+       "no remote-ip",
+       NO_STR "Remove IP address of CBC; disables outbound CBSP connections\n")
+{
+       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
+       vty_out(vty, "%% cbc/remote-ip config is deprecated, instead use 
cbc/client/remote-ip and cbc/mode%s",
+               VTY_NEWLINE);
+       if (cbc->mode == BSC_CBC_LINK_MODE_CLIENT) {
+               cbc->mode = BSC_CBC_LINK_MODE_DISABLED;
+               if (vty->type != VTY_FILE)
+                       bsc_cbc_link_restart();
+       }
+       return CMD_SUCCESS;
+}
+
+DEFUN_DEPRECATED(cfg_cbc_remote_port, cfg_cbc_remote_port_cmd,
+       "remote-port <1-65535>",
+       "TCP Port number of the Cell Broadcast Centre (Default: 48049)\n"
+       "TCP Port number of the Cell Broadcast Centre (Default: 48049)\n")
+{
+       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
+       vty_out(vty, "%% cbc/remote-port config is deprecated, instead use 
cbc/client/remote-port%s",
+               VTY_NEWLINE);
+       cbc->client.remote_addr.port = atoi(argv[0]);
+       return CMD_SUCCESS;
+}
+
+DEFUN_DEPRECATED(cfg_cbc_listen_port, cfg_cbc_listen_port_cmd,
+       "listen-port <1-65535>",
+       "Local TCP port at which BSC listens for incoming CBSP connections from 
CBC\n"
+       "Local TCP port at which BSC listens for incoming CBSP connections from 
CBC\n")
+{
+       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
+       vty_out(vty, "%% cbc/listen-port config is deprecated, instead use 
cbc/server/local-port and cbc/mode%s",
+               VTY_NEWLINE);
+       cbc->mode = BSC_CBC_LINK_MODE_SERVER;
+       cbc->server.local_addr.port = atoi(argv[0]);
+       if (vty->type != VTY_FILE)
+               bsc_cbc_link_restart();
+       return CMD_SUCCESS;
+}
+
+DEFUN_DEPRECATED(cfg_cbc_no_listen_port, cfg_cbc_no_listen_port_cmd,
+       "no listen-port",
+       NO_STR "Remove CBSP Listen Port; disables inbound CBSP connections\n")
+{
+       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
+       vty_out(vty, "%% cbc/listen-port config is deprecated, instead use 
cbc/server/local-port and cbc/mode%s",
+               VTY_NEWLINE);
+       if (cbc->mode == BSC_CBC_LINK_MODE_SERVER) {
+               cbc->mode = BSC_CBC_LINK_MODE_DISABLED;
+               if (vty->type != VTY_FILE)
+                       bsc_cbc_link_restart();
+       }
+       return CMD_SUCCESS;
+}
+
+DEFUN_DEPRECATED(cfg_cbc_listen_ip, cfg_cbc_listen_ip_cmd,
+       "listen-ip A.B.C.D",
+       "Local IP Address where BSC listens for incoming CBC connections 
(Default: 127.0.0.1)\n"
+       "Local IP Address where BSC listens for incoming CBC connections\n")
+{
+       struct bsc_cbc_link *cbc = vty_cbc_data(vty);
+       vty_out(vty, "%% cbc/listen-ip config is deprecated, instead use 
cbc/server/local-ip%s",
+               VTY_NEWLINE);
+       osmo_sockaddr_str_from_str(&cbc->server.local_addr, argv[0], 
cbc->server.local_addr.port);
+       return CMD_SUCCESS;
+}
+
+void cbc_vty_init(void)
+{
+       install_element_ve(&show_cbc_cmd);
+
+       install_element(CONFIG_NODE, &cfg_cbc_cmd);
+       install_node(&cbc_node, config_write_cbc);
+       install_element(CBC_NODE, &cfg_cbc_mode_cmd);
+
+       install_element(CBC_NODE, &cfg_cbc_server_cmd);
+       install_node(&cbc_server_node, NULL);
+       install_element(CBC_SERVER_NODE, &cfg_cbc_server_local_ip_cmd);
+       install_element(CBC_SERVER_NODE, &cfg_cbc_server_local_port_cmd);
+
+       install_element(CBC_NODE, &cfg_cbc_client_cmd);
+       install_node(&cbc_client_node, NULL);
+       install_element(CBC_CLIENT_NODE, &cfg_cbc_client_remote_ip_cmd);
+       install_element(CBC_CLIENT_NODE, &cfg_cbc_client_remote_port_cmd);
+       install_element(CBC_CLIENT_NODE, &cfg_cbc_client_local_ip_cmd);
+       install_element(CBC_CLIENT_NODE, &cfg_cbc_client_local_port_cmd);
+       install_element(CBC_CLIENT_NODE, &cfg_cbc_client_no_local_ip_cmd);
+       install_element(CBC_CLIENT_NODE, &cfg_cbc_client_no_local_port_cmd);
+
+       /* Deprecated, for backwards compat */
+       install_element(CBC_NODE, &cfg_cbc_remote_ip_cmd);
+       install_element(CBC_NODE, &cfg_cbc_no_remote_ip_cmd);
+       install_element(CBC_NODE, &cfg_cbc_remote_port_cmd);
+       install_element(CBC_NODE, &cfg_cbc_listen_port_cmd);
+       install_element(CBC_NODE, &cfg_cbc_no_listen_port_cmd);
+       install_element(CBC_NODE, &cfg_cbc_listen_ip_cmd);
+}
+
+
+/*********************************************************************************
+ * smscb
+ 
*********************************************************************************/
+static void vty_dump_smscb_chan_state(struct vty *vty, const struct 
bts_smscb_chan_state *cs)
+{
+       const struct bts_smscb_message *sm;
+
+       vty_out(vty, "%s CBCH:%s", cs == &cs->bts->cbch_basic ? "BASIC" : 
"EXTENDED", VTY_NEWLINE);
+
+       vty_out(vty, " MsgId | SerNo | Pg |      Category | Perd | #Tx  | #Req 
| DCS%s", VTY_NEWLINE);
+       vty_out(vty, 
"-------|-------|----|---------------|------|------|------|----%s", 
VTY_NEWLINE);
+       llist_for_each_entry(sm, &cs->messages, list) {
+               vty_out(vty, "  %04x |  %04x | %2u | %13s | %4u | %4u | %4u | 
%02x%s",
+                       sm->input.msg_id, sm->input.serial_nr, sm->num_pages,
+                       get_value_string(cbsp_category_names, 
sm->input.category),
+                       sm->input.rep_period, sm->bcast_count, 
sm->input.num_bcast_req,
+                       sm->input.dcs, VTY_NEWLINE);
+       }
+       vty_out(vty, "%s", VTY_NEWLINE);
+}
+
+DEFUN(bts_show_cbs, bts_show_cbs_cmd,
+       "show bts <0-255> smscb [(basic|extended)]",
+       SHOW_STR "Display information about a BTS\n" "BTS number\n"
+       "SMS Cell Broadcast State\n"
+       "Show only information related to CBCH BASIC\n"
+       "Show only information related to CBCH EXTENDED\n")
+{
+       struct gsm_network *net = gsmnet_from_vty(vty);
+       int bts_nr = atoi(argv[0]);
+       struct gsm_bts *bts;
+
+       if (bts_nr >= net->num_bts) {
+               vty_out(vty, "%% can't find BTS '%s'%s", argv[0], VTY_NEWLINE);
+               return CMD_WARNING;
+       }
+       bts = gsm_bts_num(net, bts_nr);
+
+       if (argc < 2 || !strcmp(argv[1], "basic"))
+               vty_dump_smscb_chan_state(vty, &bts->cbch_basic);
+       if (argc < 2 || !strcmp(argv[1], "extended"))
+               vty_dump_smscb_chan_state(vty, &bts->cbch_extended);
+
+       return CMD_SUCCESS;
+}
+
+void smscb_vty_init(void)
+{
+       install_element_ve(&bts_show_cbs_cmd);
+}

--
To view, visit https://gerrit.osmocom.org/c/osmo-bsc/+/28256
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: Ifc7d1693d745dd2a3c31e3ee9610d8c634b50812
Gerrit-Change-Number: 28256
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <[email protected]>
Gerrit-MessageType: newchange

Reply via email to