sms: Encapsulate SMS queue related config parameters

Introduce a 'struct sms_queue_config' that holds all config parameters
related to the SMS queue.

Change-Id: I559ab7a6e0502a1a12a662ebd5591875d47ec7b2
This commit is contained in:
Harald Welte 2022-05-17 13:31:14 +02:00
parent 1d72e301cb
commit d302bb11fa
6 changed files with 53 additions and 38 deletions

View File

@ -19,6 +19,7 @@
#include <osmocom/msc/msc_common.h> #include <osmocom/msc/msc_common.h>
#include <osmocom/msc/neighbor_ident.h> #include <osmocom/msc/neighbor_ident.h>
#include <osmocom/msc/sms_queue.h>
#include "gsm_data_shared.h" #include "gsm_data_shared.h"
#include "osmux.h" #include "osmux.h"
@ -263,7 +264,8 @@ struct gsm_network {
/* Whether to use lcls on the network */ /* Whether to use lcls on the network */
bool lcls_permitted; bool lcls_permitted;
char *sms_db_file_path; /* SMS queue config parameters */
struct sms_queue_config *sms_queue_cfg;
}; };
struct osmo_esme; struct osmo_esme;

View File

@ -5,10 +5,18 @@ struct gsm_network;
struct gsm_sms_queue; struct gsm_sms_queue;
struct vty; 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 VSUB_USE_SMS_PENDING "SMS-pending"
#define MSC_A_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 *); int sms_queue_trigger(struct gsm_sms_queue *);
/* vty helper functions */ /* vty helper functions */

View File

@ -62,8 +62,6 @@ struct gsm_network *gsm_network_init(void *ctx, mncc_recv_cb_t mncc_recv)
if (!net) if (!net)
return NULL; 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 }; net->plmn = (struct osmo_plmn_id){ .mcc=1, .mnc=1 };
/* Permit a compile-time default of A5/3 and A5/1 */ /* Permit a compile-time default of A5/3 and A5/1 */

View File

@ -415,7 +415,7 @@ DEFUN(cfg_sms_database, cfg_sms_database_cmd,
"Set the path to the MSC-SMS database file\n" "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") "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; return CMD_SUCCESS;
} }
@ -754,8 +754,8 @@ DEFUN(show_nri, show_nri_cmd,
static int config_write_msc(struct vty *vty) static int config_write_msc(struct vty *vty)
{ {
vty_out(vty, "msc%s", VTY_NEWLINE); vty_out(vty, "msc%s", VTY_NEWLINE);
if (gsmnet->sms_db_file_path && strcmp(gsmnet->sms_db_file_path, SMS_DEFAULT_DB_FILE_PATH)) 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_db_file_path, VTY_NEWLINE); vty_out(vty, " sms-database %s%s", gsmnet->sms_queue_cfg->db_file_path, VTY_NEWLINE);
if (gsmnet->mncc_sock_path) if (gsmnet->mncc_sock_path)
vty_out(vty, " mncc external %s%s", gsmnet->mncc_sock_path, VTY_NEWLINE); vty_out(vty, " mncc external %s%s", gsmnet->mncc_sock_path, VTY_NEWLINE);
vty_out(vty, " mncc guard-timeout %i%s", vty_out(vty, " mncc guard-timeout %i%s",

View File

@ -124,11 +124,9 @@ struct gsm_sms_queue {
struct osmo_timer_list resend_pending; /* timer triggering sms_resend_pending() */ struct osmo_timer_list resend_pending; /* timer triggering sms_resend_pending() */
struct osmo_timer_list push_queue; /* timer triggering sms_submit_pending() */ struct osmo_timer_list push_queue; /* timer triggering sms_submit_pending() */
struct gsm_network *network; 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 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 */ /* last MSISDN for which we read SMS from the database and created gsm_sms_pending records */
char last_msisdn[GSM23003_MSISDN_MAX_DIGITS+1]; 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); pending->sms_id, pending->failed_attempts);
smsq = net->sms_queue; smsq = net->sms_queue;
if (pending->failed_attempts < smsq->max_fail) if (pending->failed_attempts < smsq->cfg->max_fail)
return sms_pending_resend(pending); return sms_pending_resend(pending);
sms_pending_free(smsq, 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) static void sms_submit_pending(void *_data)
{ {
struct gsm_sms_queue *smsq = _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; int initialized = 0;
unsigned long long first_sub = 0; unsigned long long first_sub = 0;
int attempted = 0, rounds = 0; int attempted = 0, rounds = 0;
@ -466,9 +464,22 @@ int sms_queue_trigger(struct gsm_sms_queue *smsq)
return 0; 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 /* initialize the sms_queue subsystem and read the first batch of SMS from
* the database for delivery */ * 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); struct gsm_sms_queue *sms = talloc_zero(network, struct gsm_sms_queue);
if (!sms) { if (!sms) {
@ -476,6 +487,7 @@ int sms_queue_start(struct gsm_network *network, int max_pending)
return -1; return -1;
} }
sms->cfg = network->sms_queue_cfg;
sms->statg = osmo_stat_item_group_alloc(sms, &smsq_statg_desc, 0); sms->statg = osmo_stat_item_group_alloc(sms, &smsq_statg_desc, 0);
if (!sms->statg) if (!sms->statg)
goto err_free; goto err_free;
@ -486,15 +498,24 @@ int sms_queue_start(struct gsm_network *network, int max_pending)
network->sms_queue = sms; network->sms_queue = sms;
INIT_LLIST_HEAD(&sms->pending_sms); INIT_LLIST_HEAD(&sms->pending_sms);
sms->max_fail = 1;
sms->network = network; sms->network = network;
sms->max_pending = max_pending;
osmo_timer_setup(&sms->push_queue, sms_submit_pending, sms); osmo_timer_setup(&sms->push_queue, sms_submit_pending, sms);
osmo_timer_setup(&sms->resend_pending, sms_resend_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_SUBSCR, sms_subscr_cb, network);
osmo_signal_register_handler(SS_SMS, sms_sms_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); sms_submit_pending(sms);
return 0; return 0;
@ -642,7 +663,7 @@ int sms_queue_stats(struct gsm_sms_queue *smsq, struct vty *vty)
struct gsm_sms_pending *pending; struct gsm_sms_pending *pending;
vty_out(vty, "SMSqueue with max_pending: %d pending: %d%s", 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) llist_for_each_entry(pending, &smsq->pending_sms, entry)
vty_out(vty, " SMS Pending for Subscriber: %llu SMS: %llu Failed: %d.%s", 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) 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", LOGP(DLSMS, LOGL_NOTICE, "SMSqueue old max: %d new: %d\n",
smsq->max_pending, max_pending); smsq->cfg->max_pending, max_pending);
smsq->max_pending = max_pending; smsq->cfg->max_pending = max_pending;
return 0; return 0;
} }
int sms_queue_set_max_failure(struct gsm_sms_queue *smsq, int max_fail) 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", LOGP(DLSMS, LOGL_NOTICE, "SMSqueue max failure old: %d new: %d\n",
smsq->max_fail, max_fail); smsq->cfg->max_fail, max_fail);
smsq->max_fail = max_fail; smsq->cfg->max_fail = max_fail;
return 0; return 0;
} }

View File

@ -100,12 +100,10 @@ void *tall_map_ctx = NULL;
/* end deps from libbsc legacy. */ /* end deps from libbsc legacy. */
static struct { static struct {
const char *database_name;
const char *config_file; const char *config_file;
int daemonize; int daemonize;
const char *mncc_sock_path; const char *mncc_sock_path;
} msc_cmdline_config = { } msc_cmdline_config = {
.database_name = NULL,
.config_file = "osmo-msc.cfg", .config_file = "osmo-msc.cfg",
}; };
@ -206,9 +204,9 @@ static void handle_options(int argc, char **argv)
msc_cmdline_config.daemonize = 1; msc_cmdline_config.daemonize = 1;
break; break;
case 'l': case 'l':
msc_cmdline_config.database_name = optarg;
fprintf(stderr, "Command line argument '-%c' is deprecated, use VTY " fprintf(stderr, "Command line argument '-%c' is deprecated, use VTY "
"parameter 'msc' / 'sms-database %s' instead.\n", c, optarg); "parameter 'msc' / 'sms-database %s' instead.\n", c, optarg);
exit(2);
break; break;
case 'c': case 'c':
msc_cmdline_config.config_file = optarg; msc_cmdline_config.config_file = optarg;
@ -264,6 +262,7 @@ struct gsm_network *msc_network_alloc(void *ctx,
net->mgw.tdefs = g_mgw_tdefs; net->mgw.tdefs = g_mgw_tdefs;
osmo_tdefs_reset(net->mgw.tdefs); osmo_tdefs_reset(net->mgw.tdefs);
net->sms_queue_cfg = sms_queue_cfg_alloc(ctx);
return net; 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 /* TODO: is this used for crypto?? Improve randomness, at least we
* should try to use the nanoseconds part of the current time. */ * 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)) { if (msc_gsup_client_start(msc_network)) {
fprintf(stderr, "Failed to start GSUP client\n"); fprintf(stderr, "Failed to start GSUP client\n");
exit(1); exit(1);
@ -703,11 +694,6 @@ TODO: we probably want some of the _net_ ctrl commands from bsc_base_ctrl_cmds_i
exit(1); exit(1);
} }
if (db_prepare()) {
fprintf(stderr, "DB: Failed to prepare database.\n");
return 5;
}
signal(SIGINT, &signal_handler); signal(SIGINT, &signal_handler);
signal(SIGTERM, &signal_handler); signal(SIGTERM, &signal_handler);
signal(SIGABRT, &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(); osmo_init_ignore_signals();
/* start the SMS queue */ /* start the SMS queue */
if (sms_queue_start(msc_network, 20) != 0) if (sms_queue_start(msc_network) != 0)
return -1; return -1;
msc_network->mgw.client = mgcp_client_init( msc_network->mgw.client = mgcp_client_init(