diff --git a/include/osmocom/msc/gsm_data.h b/include/osmocom/msc/gsm_data.h index 34d42db2b..78b9c9a5b 100644 --- a/include/osmocom/msc/gsm_data.h +++ b/include/osmocom/msc/gsm_data.h @@ -19,6 +19,7 @@ #include #include +#include #include "gsm_data_shared.h" #include "osmux.h" @@ -263,7 +264,8 @@ struct gsm_network { /* Whether to use lcls on the network */ bool lcls_permitted; - char *sms_db_file_path; + /* SMS queue config parameters */ + struct sms_queue_config *sms_queue_cfg; }; struct osmo_esme; diff --git a/include/osmocom/msc/sms_queue.h b/include/osmocom/msc/sms_queue.h index ef73baf04..492ae724a 100644 --- a/include/osmocom/msc/sms_queue.h +++ b/include/osmocom/msc/sms_queue.h @@ -5,10 +5,18 @@ struct gsm_network; struct gsm_sms_queue; struct vty; +struct sms_queue_config { + char *db_file_path; /* SMS database file path */ + int max_fail; /* maximum number of delivery failures */ + int max_pending; /* maximum number of gsm_sms_pending in RAM */ +}; + +struct sms_queue_config *sms_queue_cfg_alloc(void *ctx); + #define VSUB_USE_SMS_PENDING "SMS-pending" #define MSC_A_USE_SMS_PENDING "SMS-pending" -int sms_queue_start(struct gsm_network *, int in_flight); +int sms_queue_start(struct gsm_network *net); int sms_queue_trigger(struct gsm_sms_queue *); /* vty helper functions */ diff --git a/src/libmsc/msc_net_init.c b/src/libmsc/msc_net_init.c index af23fe50d..45500b2f7 100644 --- a/src/libmsc/msc_net_init.c +++ b/src/libmsc/msc_net_init.c @@ -62,8 +62,6 @@ struct gsm_network *gsm_network_init(void *ctx, mncc_recv_cb_t mncc_recv) if (!net) return NULL; - net->sms_db_file_path = talloc_strdup(net, SMS_DEFAULT_DB_FILE_PATH); - net->plmn = (struct osmo_plmn_id){ .mcc=1, .mnc=1 }; /* Permit a compile-time default of A5/3 and A5/1 */ diff --git a/src/libmsc/msc_vty.c b/src/libmsc/msc_vty.c index 4dd834b36..5ceb6c4d5 100644 --- a/src/libmsc/msc_vty.c +++ b/src/libmsc/msc_vty.c @@ -415,7 +415,7 @@ DEFUN(cfg_sms_database, cfg_sms_database_cmd, "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(gsmnet, &gsmnet->sms_db_file_path, argv[0]); + osmo_talloc_replace_string(gsmnet, &gsmnet->sms_queue_cfg->db_file_path, argv[0]); return CMD_SUCCESS; } @@ -754,8 +754,8 @@ DEFUN(show_nri, show_nri_cmd, static int config_write_msc(struct vty *vty) { vty_out(vty, "msc%s", VTY_NEWLINE); - if (gsmnet->sms_db_file_path && strcmp(gsmnet->sms_db_file_path, SMS_DEFAULT_DB_FILE_PATH)) - vty_out(vty, " sms-database %s%s", gsmnet->sms_db_file_path, 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", diff --git a/src/libmsc/sms_queue.c b/src/libmsc/sms_queue.c index cc44f580a..e0433ee22 100644 --- a/src/libmsc/sms_queue.c +++ b/src/libmsc/sms_queue.c @@ -124,11 +124,9 @@ struct gsm_sms_queue { struct osmo_timer_list resend_pending; /* timer triggering sms_resend_pending() */ struct osmo_timer_list push_queue; /* timer triggering sms_submit_pending() */ struct gsm_network *network; - int max_fail; /* maximum number of delivery failures */ - int max_pending; /* maximum number of gsm_sms_pending in RAM */ - int pending; /* current number of gsm_sms_pending in RAM */ - struct llist_head pending_sms; /* list of gsm_sms_pending */ + struct sms_queue_config *cfg; + int pending; /* current number of gsm_sms_pending in RAM */ /* last MSISDN for which we read SMS from the database and created gsm_sms_pending records */ char last_msisdn[GSM23003_MSISDN_MAX_DIGITS+1]; @@ -251,7 +249,7 @@ static void sms_pending_failed(struct gsm_sms_pending *pending, int paging_error pending->sms_id, pending->failed_attempts); smsq = net->sms_queue; - if (pending->failed_attempts < smsq->max_fail) + if (pending->failed_attempts < smsq->cfg->max_fail) return sms_pending_resend(pending); sms_pending_free(smsq, pending); @@ -342,7 +340,7 @@ struct gsm_sms *smsq_take_next_sms(struct gsm_network *net, static void sms_submit_pending(void *_data) { struct gsm_sms_queue *smsq = _data; - int attempts = smsq->max_pending - smsq->pending; + int attempts = smsq->cfg->max_pending - smsq->pending; int initialized = 0; unsigned long long first_sub = 0; int attempted = 0, rounds = 0; @@ -466,9 +464,22 @@ int sms_queue_trigger(struct gsm_sms_queue *smsq) return 0; } +/* allocate + initialize SMS queue configuration with some default values */ +struct sms_queue_config *sms_queue_cfg_alloc(void *ctx) +{ + struct sms_queue_config *sqcfg = talloc_zero(ctx, struct sms_queue_config); + OSMO_ASSERT(sqcfg); + + sqcfg->max_pending = 20; + sqcfg->max_fail = 1; + sqcfg->db_file_path = talloc_strdup(ctx, SMS_DEFAULT_DB_FILE_PATH); + + return sqcfg; +} + /* initialize the sms_queue subsystem and read the first batch of SMS from * the database for delivery */ -int sms_queue_start(struct gsm_network *network, int max_pending) +int sms_queue_start(struct gsm_network *network) { struct gsm_sms_queue *sms = talloc_zero(network, struct gsm_sms_queue); if (!sms) { @@ -476,6 +487,7 @@ int sms_queue_start(struct gsm_network *network, int max_pending) return -1; } + sms->cfg = network->sms_queue_cfg; sms->statg = osmo_stat_item_group_alloc(sms, &smsq_statg_desc, 0); if (!sms->statg) goto err_free; @@ -486,15 +498,24 @@ int sms_queue_start(struct gsm_network *network, int max_pending) network->sms_queue = sms; INIT_LLIST_HEAD(&sms->pending_sms); - sms->max_fail = 1; sms->network = network; - sms->max_pending = max_pending; osmo_timer_setup(&sms->push_queue, sms_submit_pending, sms); osmo_timer_setup(&sms->resend_pending, sms_resend_pending, sms); osmo_signal_register_handler(SS_SUBSCR, sms_subscr_cb, network); osmo_signal_register_handler(SS_SMS, sms_sms_cb, network); + if (db_init(sms, sms->cfg->db_file_path, true)) { + LOGP(DMSC, LOGL_FATAL, "DB: Failed to init database: %s\n", + osmo_quote_str(sms->cfg->db_file_path, -1)); + return -1; + } + + if (db_prepare()) { + LOGP(DMSC, LOGL_FATAL, "DB: Failed to prepare database.\n"); + return -1; + } + sms_submit_pending(sms); return 0; @@ -642,7 +663,7 @@ int sms_queue_stats(struct gsm_sms_queue *smsq, struct vty *vty) struct gsm_sms_pending *pending; vty_out(vty, "SMSqueue with max_pending: %d pending: %d%s", - smsq->max_pending, smsq->pending, VTY_NEWLINE); + smsq->cfg->max_pending, smsq->pending, VTY_NEWLINE); llist_for_each_entry(pending, &smsq->pending_sms, entry) vty_out(vty, " SMS Pending for Subscriber: %llu SMS: %llu Failed: %d.%s", @@ -654,16 +675,16 @@ int sms_queue_stats(struct gsm_sms_queue *smsq, struct vty *vty) 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->max_pending, max_pending); - smsq->max_pending = max_pending; + 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->max_fail, max_fail); - smsq->max_fail = max_fail; + smsq->cfg->max_fail, max_fail); + smsq->cfg->max_fail = max_fail; return 0; } diff --git a/src/osmo-msc/msc_main.c b/src/osmo-msc/msc_main.c index e3ac100d5..9329de5e9 100644 --- a/src/osmo-msc/msc_main.c +++ b/src/osmo-msc/msc_main.c @@ -100,12 +100,10 @@ void *tall_map_ctx = NULL; /* end deps from libbsc legacy. */ static struct { - const char *database_name; const char *config_file; int daemonize; const char *mncc_sock_path; } msc_cmdline_config = { - .database_name = NULL, .config_file = "osmo-msc.cfg", }; @@ -206,9 +204,9 @@ static void handle_options(int argc, char **argv) msc_cmdline_config.daemonize = 1; break; case 'l': - msc_cmdline_config.database_name = optarg; fprintf(stderr, "Command line argument '-%c' is deprecated, use VTY " "parameter 'msc' / 'sms-database %s' instead.\n", c, optarg); + exit(2); break; case 'c': msc_cmdline_config.config_file = optarg; @@ -264,6 +262,7 @@ struct gsm_network *msc_network_alloc(void *ctx, net->mgw.tdefs = g_mgw_tdefs; osmo_tdefs_reset(net->mgw.tdefs); + net->sms_queue_cfg = sms_queue_cfg_alloc(ctx); return net; } @@ -683,14 +682,6 @@ TODO: we probably want some of the _net_ ctrl commands from bsc_base_ctrl_cmds_i /* TODO: is this used for crypto?? Improve randomness, at least we * should try to use the nanoseconds part of the current time. */ - if (msc_cmdline_config.database_name) - osmo_talloc_replace_string(msc_network, &msc_network->sms_db_file_path, msc_cmdline_config.database_name); - if (db_init(tall_msc_ctx, msc_network->sms_db_file_path, true)) { - fprintf(stderr, "DB: Failed to init database: %s\n", - osmo_quote_str((char*)msc_network->sms_db_file_path, -1)); - return 4; - } - if (msc_gsup_client_start(msc_network)) { fprintf(stderr, "Failed to start GSUP client\n"); exit(1); @@ -703,11 +694,6 @@ TODO: we probably want some of the _net_ ctrl commands from bsc_base_ctrl_cmds_i exit(1); } - if (db_prepare()) { - fprintf(stderr, "DB: Failed to prepare database.\n"); - return 5; - } - signal(SIGINT, &signal_handler); signal(SIGTERM, &signal_handler); signal(SIGABRT, &signal_handler); @@ -716,7 +702,7 @@ TODO: we probably want some of the _net_ ctrl commands from bsc_base_ctrl_cmds_i osmo_init_ignore_signals(); /* start the SMS queue */ - if (sms_queue_start(msc_network, 20) != 0) + if (sms_queue_start(msc_network) != 0) return -1; msc_network->mgw.client = mgcp_client_init(