From 52c0ef934cee215a0b4199e8a21a79d93705ff24 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 17 May 2022 12:06:58 +0200 Subject: sms: Give smsc its own VTY The pre-historic sms_queue code used to have very strange aspects, such as having some parameters (max-failure, max-pending) which could only be sent from the 'enable' node, but not from a config file. Before adding more configuration parameters, let's clean this up by introducing a proper VTY config node for the 'smsc'; move the existing config commands there and add new ones for max-failure and max-pending. As the sms_queue data structure is only allocated after the config file parsing happens, we are introducing a new 'sms_queue_config' data structure. This encapsulates the public readable/writable config parameters. Change-Id: Ie8e0ab1a9f979337ff06544b9ab3820954d9804a --- include/osmocom/msc/sms_queue.h | 2 - include/osmocom/msc/vty.h | 2 + src/libmsc/Makefile.am | 1 + src/libmsc/msc_vty.c | 55 +------------ src/libmsc/sms_queue.c | 16 ---- src/libmsc/smsc_vty.c | 168 ++++++++++++++++++++++++++++++++++++++++ src/osmo-msc/msc_main.c | 2 +- tests/test_nodes.vty | 5 +- 8 files changed, 178 insertions(+), 73 deletions(-) create mode 100644 src/libmsc/smsc_vty.c diff --git a/include/osmocom/msc/sms_queue.h b/include/osmocom/msc/sms_queue.h index 492ae724a..76f885bf6 100644 --- a/include/osmocom/msc/sms_queue.h +++ b/include/osmocom/msc/sms_queue.h @@ -21,8 +21,6 @@ int sms_queue_trigger(struct gsm_sms_queue *); /* vty helper functions */ int sms_queue_stats(struct gsm_sms_queue *, struct vty* vty); -int sms_queue_set_max_pending(struct gsm_sms_queue *, int max); -int sms_queue_set_max_failure(struct gsm_sms_queue *, int fail); int sms_queue_clear(struct gsm_sms_queue *); int sms_queue_sms_is_pending(struct gsm_sms_queue *smsq, unsigned long long sms_id); diff --git a/include/osmocom/msc/vty.h b/include/osmocom/msc/vty.h index 2a3b18bdf..1e13846ed 100644 --- a/include/osmocom/msc/vty.h +++ b/include/osmocom/msc/vty.h @@ -24,11 +24,13 @@ enum bsc_vty_node { SMPP_ESME_NODE, HLR_NODE, CFG_SGS_NODE, + SMSC_NODE, }; int bsc_vty_init_extra(void); void msc_vty_init(struct gsm_network *msc_network); +void smsc_vty_init(struct gsm_network *msc_network); struct gsm_network *gsmnet_from_vty(struct vty *vty); diff --git a/src/libmsc/Makefile.am b/src/libmsc/Makefile.am index e6a2dc164..d3b6035e2 100644 --- a/src/libmsc/Makefile.am +++ b/src/libmsc/Makefile.am @@ -67,6 +67,7 @@ libmsc_a_SOURCES = \ sdp_msg.c \ silent_call.c \ sms_queue.c \ + smsc_vty.c \ transaction.c \ msc_net_init.c \ ctrl_commands.c \ diff --git a/src/libmsc/msc_vty.c b/src/libmsc/msc_vty.c index 5ceb6c4d5..be05a95aa 100644 --- a/src/libmsc/msc_vty.c +++ b/src/libmsc/msc_vty.c @@ -410,7 +410,7 @@ DEFUN(cfg_msc, cfg_msc_cmd, #define MNCC_GUARD_TIMEOUT_STR "Set global guard timer for mncc interface activity\n" #define MNCC_GUARD_TIMEOUT_VALUE_STR "guard timer value (sec.)\n" -DEFUN(cfg_sms_database, cfg_sms_database_cmd, +DEFUN_DEPRECATED(cfg_sms_database, cfg_sms_database_cmd, "sms-database PATH", "Set the path to the MSC-SMS database file\n" "Relative or absolute file system path to the database file (default is '" SMS_DEFAULT_DB_FILE_PATH "')\n") @@ -754,8 +754,6 @@ DEFUN(show_nri, show_nri_cmd, static int config_write_msc(struct vty *vty) { vty_out(vty, "msc%s", VTY_NEWLINE); - if (gsmnet->sms_queue_cfg->db_file_path && strcmp(gsmnet->sms_queue_cfg->db_file_path, SMS_DEFAULT_DB_FILE_PATH)) - vty_out(vty, " sms-database %s%s", gsmnet->sms_queue_cfg->db_file_path, VTY_NEWLINE); if (gsmnet->mncc_sock_path) vty_out(vty, " mncc external %s%s", gsmnet->mncc_sock_path, VTY_NEWLINE); vty_out(vty, " mncc guard-timeout %i%s", @@ -1860,51 +1858,6 @@ DEFUN(show_stats, return CMD_SUCCESS; } -DEFUN(show_smsqueue, - show_smsqueue_cmd, - "show sms-queue", - SHOW_STR "Display SMSqueue statistics\n") -{ - sms_queue_stats(gsmnet->sms_queue, vty); - return CMD_SUCCESS; -} - -DEFUN(smsqueue_trigger, - smsqueue_trigger_cmd, - "sms-queue trigger", - "SMS Queue\n" "Trigger sending messages\n") -{ - sms_queue_trigger(gsmnet->sms_queue); - return CMD_SUCCESS; -} - -DEFUN(smsqueue_max, - smsqueue_max_cmd, - "sms-queue max-pending <1-500>", - "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n") -{ - sms_queue_set_max_pending(gsmnet->sms_queue, atoi(argv[0])); - return CMD_SUCCESS; -} - -DEFUN(smsqueue_clear, - smsqueue_clear_cmd, - "sms-queue clear", - "SMS Queue\n" "Clear the queue of pending SMS\n") -{ - sms_queue_clear(gsmnet->sms_queue); - return CMD_SUCCESS; -} - -DEFUN(smsqueue_fail, - smsqueue_fail_cmd, - "sms-queue max-failure <1-500>", - "SMS Queue\n" "Maximum amount of delivery failures\n" "Amount\n") -{ - sms_queue_set_max_failure(gsmnet->sms_queue, atoi(argv[0])); - return CMD_SUCCESS; -} - DEFUN(cfg_mncc_int, cfg_mncc_int_cmd, "mncc-int", "Configure internal MNCC handler") @@ -2118,6 +2071,7 @@ void msc_vty_init(struct gsm_network *msc_network) ranap_iu_vty_init(MSC_NODE, (enum ranap_nsap_addr_enc*)&msc_network->iu.rab_assign_addr_enc); #endif sgs_vty_init(); + smsc_vty_init(msc_network); osmo_fsm_vty_add_cmds(); @@ -2143,14 +2097,9 @@ void msc_vty_init(struct gsm_network *msc_network) install_element_ve(&subscriber_mstest_open_cmd); install_element_ve(&subscriber_paging_cmd); install_element_ve(&show_stats_cmd); - install_element_ve(&show_smsqueue_cmd); install_element_ve(&logging_fltr_imsi_cmd); install_element(ENABLE_NODE, &ena_subscr_expire_cmd); - install_element(ENABLE_NODE, &smsqueue_trigger_cmd); - install_element(ENABLE_NODE, &smsqueue_max_cmd); - install_element(ENABLE_NODE, &smsqueue_clear_cmd); - install_element(ENABLE_NODE, &smsqueue_fail_cmd); install_element(ENABLE_NODE, &subscriber_send_pending_sms_cmd); install_element(ENABLE_NODE, &subscriber_sms_delete_all_cmd); diff --git a/src/libmsc/sms_queue.c b/src/libmsc/sms_queue.c index e0433ee22..a47f8e0c7 100644 --- a/src/libmsc/sms_queue.c +++ b/src/libmsc/sms_queue.c @@ -672,22 +672,6 @@ int sms_queue_stats(struct gsm_sms_queue *smsq, struct vty *vty) return 0; } -int sms_queue_set_max_pending(struct gsm_sms_queue *smsq, int max_pending) -{ - LOGP(DLSMS, LOGL_NOTICE, "SMSqueue old max: %d new: %d\n", - smsq->cfg->max_pending, max_pending); - smsq->cfg->max_pending = max_pending; - return 0; -} - -int sms_queue_set_max_failure(struct gsm_sms_queue *smsq, int max_fail) -{ - LOGP(DLSMS, LOGL_NOTICE, "SMSqueue max failure old: %d new: %d\n", - smsq->cfg->max_fail, max_fail); - smsq->cfg->max_fail = max_fail; - return 0; -} - int sms_queue_clear(struct gsm_sms_queue *smsq) { struct gsm_sms_pending *pending, *tmp; diff --git a/src/libmsc/smsc_vty.c b/src/libmsc/smsc_vty.c new file mode 100644 index 000000000..cdb81c60f --- /dev/null +++ b/src/libmsc/smsc_vty.c @@ -0,0 +1,168 @@ +/* SMSC interface to VTY */ +/* (C) 2016-2018 by sysmocom s.m.f.c. GmbH + * Based on OpenBSC interface to quagga VTY (libmsc/vty_interface_layer3.c) + * (C) 2009-2022 by Harald Welte + * (C) 2009-2011 by Holger Hans Peter Freyther + * 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 "config.h" + +#include +#include +#include + +#include +#include +#include + + +static struct gsm_network *gsmnet; +static struct sms_queue_config *smqcfg; + +/*********************************************************************** + * SMSC Config Node + ***********************************************************************/ + +static struct cmd_node smsc_node = { + SMSC_NODE, + "%s(config-smsc)# ", + 1, +}; + +DEFUN(cfg_smsc, cfg_smsc_cmd, + "smsc", "Configure SMSC options") +{ + vty->node = SMSC_NODE; + return CMD_SUCCESS; +} + +DEFUN(cfg_sms_database, cfg_sms_database_cmd, + "database PATH", + "Set the path to the MSC-SMS database file\n" + "Relative or absolute file system path to the database file (default is '" SMS_DEFAULT_DB_FILE_PATH "')\n") +{ + osmo_talloc_replace_string(smqcfg, &smqcfg->db_file_path, argv[0]); + return CMD_SUCCESS; +} + +DEFUN(cfg_sms_queue_max, cfg_sms_queue_max_cmd, + "queue max-pending <1-500>", + "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n") +{ + smqcfg->max_pending = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(cfg_sms_queue_fail, cfg_sms_queue_fail_cmd, + "queue max-failure <1-500>", + "SMS Queue\n" "Maximum number of delivery failures before giving up\n" "Amount\n") +{ + smqcfg->max_fail = atoi(argv[0]); + return CMD_SUCCESS; +} + +/*********************************************************************** + * View / Enable Node + ***********************************************************************/ + +DEFUN(show_smsqueue, + show_smsqueue_cmd, + "show sms-queue", + SHOW_STR "Display SMSqueue statistics\n") +{ + sms_queue_stats(gsmnet->sms_queue, vty); + return CMD_SUCCESS; +} + +DEFUN(smsqueue_trigger, + smsqueue_trigger_cmd, + "sms-queue trigger", + "SMS Queue\n" "Trigger sending messages\n") +{ + sms_queue_trigger(gsmnet->sms_queue); + return CMD_SUCCESS; +} + +DEFUN(smsqueue_max, + smsqueue_max_cmd, + "sms-queue max-pending <1-500>", + "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n") +{ + int max_pending = atoi(argv[0]); + vty_out(vty, "%% SMSqueue old max: %d new: %d%s", + smqcfg->max_pending, max_pending, VTY_NEWLINE); + smqcfg->max_pending = max_pending; + return CMD_SUCCESS; +} + +DEFUN(smsqueue_clear, + smsqueue_clear_cmd, + "sms-queue clear", + "SMS Queue\n" "Clear the queue of pending SMS\n") +{ + sms_queue_clear(gsmnet->sms_queue); + return CMD_SUCCESS; +} + +DEFUN(smsqueue_fail, + smsqueue_fail_cmd, + "sms-queue max-failure <1-500>", + "SMS Queue\n" "Maximum amount of delivery failures\n" "Amount\n") +{ + int max_fail = atoi(argv[0]); + vty_out(vty, "%% SMSqueue max failure old: %d new: %d%s", + smqcfg->max_fail, max_fail, VTY_NEWLINE); + smqcfg->max_fail = max_fail; + return CMD_SUCCESS; +} + +static int config_write_smsc(struct vty *vty) +{ + vty_out(vty, "smsc%s", VTY_NEWLINE); + + if (smqcfg->db_file_path && strcmp(smqcfg->db_file_path, SMS_DEFAULT_DB_FILE_PATH)) + vty_out(vty, " database %s%s", smqcfg->db_file_path, VTY_NEWLINE); + + vty_out(vty, " queue max-pending %u%s", smqcfg->max_pending, VTY_NEWLINE); + vty_out(vty, " queue max-failure %u%s", smqcfg->max_fail, VTY_NEWLINE); + + return 0; +} + +void smsc_vty_init(struct gsm_network *msc_network) +{ + OSMO_ASSERT(gsmnet == NULL); + gsmnet = msc_network; + smqcfg = msc_network->sms_queue_cfg; + + /* config node */ + install_element(CONFIG_NODE, &cfg_smsc_cmd); + install_node(&smsc_node, config_write_smsc); + install_element(SMSC_NODE, &cfg_sms_database_cmd); + install_element(SMSC_NODE, &cfg_sms_queue_max_cmd); + install_element(SMSC_NODE, &cfg_sms_queue_fail_cmd); + + /* enable node */ + install_element(ENABLE_NODE, &smsqueue_trigger_cmd); + install_element(ENABLE_NODE, &smsqueue_max_cmd); + install_element(ENABLE_NODE, &smsqueue_clear_cmd); + install_element(ENABLE_NODE, &smsqueue_fail_cmd); + + /* view / enable node */ + install_element_ve(&show_smsqueue_cmd); +} diff --git a/src/osmo-msc/msc_main.c b/src/osmo-msc/msc_main.c index 9329de5e9..bdffb4104 100644 --- a/src/osmo-msc/msc_main.c +++ b/src/osmo-msc/msc_main.c @@ -205,7 +205,7 @@ static void handle_options(int argc, char **argv) break; case 'l': fprintf(stderr, "Command line argument '-%c' is deprecated, use VTY " - "parameter 'msc' / 'sms-database %s' instead.\n", c, optarg); + "parameter 'smsc' / 'database %s' instead.\n", c, optarg); exit(2); break; case 'c': diff --git a/tests/test_nodes.vty b/tests/test_nodes.vty index 14f15a200..a67f20268 100644 --- a/tests/test_nodes.vty +++ b/tests/test_nodes.vty @@ -5,6 +5,7 @@ OsmoMSC(config)# list network msc sgs + smsc mncc-int hlr ... @@ -46,7 +47,6 @@ OsmoMSC(config-net)# exit OsmoMSC(config)# msc OsmoMSC(config-msc)# list ... - sms-database PATH assign-tmsi lcls-permitted no lcls-permitted @@ -178,6 +178,9 @@ sgs local-port 29118 local-ip 0.0.0.0 vlr-name vlr.example.net +smsc + queue max-pending 20 + queue max-failure 1 end OsmoMSC# configure terminal -- cgit v1.2.3