layer23: Integreate mobile further into l23_app

Several functions and data structures in mobile app are refactored to
follow more closely the l23_app API and structures. These movements
allow starting to use already some shared infrastructure defined under
layer23/common.
This is not a full migration to l23_app, since mobile still keeps a
separate main() with a few extra code. This commit is rather a step
towards an eventual merge of mobile's main.cpp into
layer23/common/main.c

This is a preparation commit to later one adding gsmtap VTY configuration
to all l23 apps.

Change-Id: I3141b6cb4a0482970f434180ef8dda3af1d4aa0c
This commit is contained in:
Pau Espin 2023-01-30 17:30:02 +01:00
parent 60716bcfe6
commit 738b65d240
4 changed files with 165 additions and 91 deletions

View File

@ -8,9 +8,6 @@ extern char *config_dir;
struct osmocom_ms;
struct vty;
int l23_app_init(const char *config_file);
int l23_app_exit(void);
int l23_app_work(int *quit);
int mobile_delete(struct osmocom_ms *ms, int force);
struct osmocom_ms *mobile_new(char *name);
int mobile_work(struct osmocom_ms *ms);

View File

@ -29,6 +29,7 @@
#include <osmocom/bb/common/gps.h>
#include <osmocom/bb/common/sap_interface.h>
#include <osmocom/bb/common/sim.h>
#include <osmocom/bb/common/l23_app.h>
#include <osmocom/bb/mobile/gsm48_rr.h>
#include <osmocom/bb/mobile/gsm480_ss.h>
@ -43,8 +44,7 @@
#include <osmocom/bb/mobile/gapk_io.h>
#include <osmocom/bb/mobile/primitives.h>
#include <osmocom/vty/ports.h>
#include <osmocom/vty/logging.h>
#include <osmocom/vty/vty.h>
#include <osmocom/vty/telnet_interface.h>
#include <osmocom/core/msgb.h>
@ -58,12 +58,12 @@
extern void *l23_ctx;
extern struct llist_head ms_list;
extern int vty_reading;
int mncc_recv_internal(struct osmocom_ms *ms, int msg_type, void *arg);
int mncc_recv_external(struct osmocom_ms *ms, int msg_type, void *arg);
int mncc_recv_dummy(struct osmocom_ms *ms, int msg_type, void *arg);
static int quit;
static int _quit;
extern int quit; /* l23 main */
/* handle ms instance */
int mobile_work(struct osmocom_ms *ms)
@ -381,20 +381,20 @@ int global_signal_cb(unsigned int subsys, unsigned int signal,
case S_GLOBAL_SHUTDOWN:
/* force to exit, if signalled */
if (signal_data && *((uint8_t *)signal_data))
quit = 1;
_quit = 1;
llist_for_each_entry_safe(ms, ms2, &ms_list, entity)
mobile_delete(ms, quit);
mobile_delete(ms, _quit);
/* quit, after all MS processes are gone */
quit = 1;
_quit = 1;
break;
}
return 0;
}
/* global work handler */
int l23_app_work(int *_quit)
int _mobile_app_work(void)
{
struct osmocom_ms *ms, *ms2;
int work = 0;
@ -424,12 +424,12 @@ int l23_app_work(int *_quit)
}
/* return, if a shutdown was scheduled (quit = 1) */
*_quit = quit;
quit = _quit;
return work;
}
/* global exit */
int l23_app_exit(void)
int _mobile_app_exit(void)
{
osmo_signal_unregister_handler(SS_L1CTL, &gsm322_l1_signal, NULL);
osmo_signal_unregister_handler(SS_L1CTL, &mobile_signal_cb, NULL);
@ -442,53 +442,10 @@ int l23_app_exit(void)
return 0;
}
static struct vty_app_info vty_info = {
.name = "OsmocomBB",
.version = PACKAGE_VERSION,
};
/* global init */
int l23_app_init(const char *config_file)
int _mobile_app_start(void)
{
struct telnet_connection dummy_conn;
int rc = 0;
osmo_gps_init();
#ifdef WITH_GAPK_IO
/* Init GAPK audio I/O */
gapk_io_init();
#endif
vty_info.tall_ctx = l23_ctx;
vty_init(&vty_info);
logging_vty_add_cmds();
ms_vty_init();
dummy_conn.priv = NULL;
vty_reading = 1;
if (config_file != NULL) {
rc = vty_read_config_file(config_file, &dummy_conn);
if (rc < 0) {
LOGP(DMOB, LOGL_FATAL, "Failed to parse the configuration "
"file '%s'\n", config_file);
LOGP(DMOB, LOGL_FATAL, "Please make sure the file "
"'%s' exists, or use an example from "
"'doc/examples/mobile/'\n", config_file);
return rc;
}
LOGP(DMOB, LOGL_INFO, "Using configuration from '%s'\n", config_file);
}
vty_reading = 0;
rc = telnet_init_default(l23_ctx, NULL, OSMO_VTY_PORT_BB);
if (rc < 0) {
LOGP(DMOB, LOGL_FATAL, "Cannot init VTY on %s port %u: %s\n",
vty_get_bind_addr(), OSMO_VTY_PORT_BB, strerror(errno));
return rc;
}
osmo_signal_register_handler(SS_GLOBAL, &global_signal_cb, NULL);
osmo_signal_register_handler(SS_L1CTL, &mobile_signal_cb, NULL);
osmo_signal_register_handler(SS_L1CTL, &gsm322_l1_signal, NULL);
int rc;
if (llist_empty(&ms_list)) {
struct osmocom_ms *ms;
@ -503,16 +460,60 @@ int l23_app_init(const char *config_file)
return rc;
}
quit = 0;
_quit = 0;
return 0;
}
/* global init */
int l23_app_init(void)
{
l23_app_start = _mobile_app_start;
l23_app_work = _mobile_app_work;
l23_app_exit = _mobile_app_exit;
osmo_gps_init();
#ifdef WITH_GAPK_IO
/* Init GAPK audio I/O */
gapk_io_init();
#endif
osmo_signal_register_handler(SS_GLOBAL, &global_signal_cb, NULL);
osmo_signal_register_handler(SS_L1CTL, &mobile_signal_cb, NULL);
osmo_signal_register_handler(SS_L1CTL, &gsm322_l1_signal, NULL);
return 0;
}
static int _mobile_vty_init(void)
{
return ms_vty_init();
}
static int l23_cfg_supported(void)
{
return L23_OPT_TAP | L23_OPT_VTY | L23_OPT_DBG;
}
static struct vty_app_info _mobile_vty_info = {
.name = "mobile",
.version = PACKAGE_VERSION,
};
static struct l23_app_info info = {
.copyright = "Copyright (C) 2010-2015 Andreas Eversberg, Sylvain Munaut, Holger Freyther, Harald Welte\n",
.contribution = "Contributions by Alex Badea, Pablo Neira, Steve Markgraf and others\n",
.cfg_supported = &l23_cfg_supported,
.vty_info = &_mobile_vty_info,
.vty_init = _mobile_vty_init,
};
struct l23_app_info *l23_app_info(void)
{
return NULL; /* TODO: implement mobile as a full l23_app. */
return &info;
}
void mobile_set_started(struct osmocom_ms *ms, bool state)
{
ms->started = state;

View File

@ -19,6 +19,8 @@
#include <osmocom/bb/common/osmocom_data.h>
#include <osmocom/bb/common/logging.h>
#include <osmocom/bb/common/l23_app.h>
#include <osmocom/bb/common/vty.h>
#include <osmocom/bb/mobile/app_mobile.h>
#include <osmocom/core/talloc.h>
@ -27,6 +29,10 @@
#include <osmocom/core/gsmtap.h>
#include <osmocom/core/signal.h>
#include <osmocom/core/application.h>
#include <osmocom/vty/vty.h>
#include <osmocom/vty/logging.h>
#include <osmocom/vty/telnet_interface.h>
#include <osmocom/vty/ports.h>
#include <arpa/inet.h>
@ -42,13 +48,21 @@
#include <time.h>
#include <libgen.h>
#include "config.h"
void *l23_ctx = NULL;
struct llist_head ms_list;
static char *gsmtap_ip = 0;
static const char *custom_cfg_file = NULL;
struct gsmtap_inst *gsmtap_inst = NULL;
static char *config_file = NULL;
char *config_dir = NULL;
int daemonize = 0;
int quit = 0;
int (*l23_app_start)(void) = NULL;
int (*l23_app_work)(void) = NULL;
int (*l23_app_exit)(void) = NULL;
int mobile_delete(struct osmocom_ms *ms, int force);
int mobile_signal_cb(unsigned int subsys, unsigned int signal,
@ -61,12 +75,12 @@ const char *debug_default =
"DCS:DNB:DPLMN:DRR:DMM:DSIM:DCC:DMNCC:DSS:DLSMS:DPAG:DSUM:DSAP:DGPS:DMOB:DPRIM:DLUA:DGAPK";
const char *openbsc_copyright =
"Copyright (C) 2010-2015 Andreas Eversberg, Sylvain Munaut, Holger Freyther, Harald Welte\n"
"Contributions by Alex Badea, Pablo Neira, Steve Markgraf and others\n\n"
"%s"
"%s\n"
"License GPLv2+: GNU GPL version 2 or later "
"<http://gnu.org/licenses/gpl.html>\n"
"This is free software: you are free to change and redistribute it.\n"
"There is NO WARRANTY, to the extent permitted by law.\n";
"There is NO WARRANTY, to the extent permitted by law.\n\n";
static void print_usage(const char *app)
{
@ -198,13 +212,56 @@ void sighandler(int sigset)
}
}
int main(int argc, char **argv)
static void print_copyright(void)
{
char *config_file;
int quit = 0;
struct l23_app_info *app;
app = l23_app_info();
printf(openbsc_copyright,
app && app->copyright ? app->copyright : "",
app && app->contribution ? app->contribution : "");
}
static int _vty_init(struct l23_app_info *app)
{
static struct vty_app_info l23_vty_info = {
.name = "OsmocomBB",
.version = PACKAGE_VERSION,
};
int rc;
printf("%s\n", openbsc_copyright);
OSMO_ASSERT(app->vty_info);
app->vty_info->tall_ctx = l23_ctx;
vty_init(app->vty_info ? : &l23_vty_info);
logging_vty_add_cmds();
if (app->vty_init)
app->vty_init();
if (config_file) {
LOGP(DLGLOBAL, LOGL_INFO, "Using configuration from '%s'\n", config_file);
l23_vty_reading = true;
rc = vty_read_config_file(config_file, NULL);
l23_vty_reading = false;
if (rc < 0) {
LOGP(DLGLOBAL, LOGL_FATAL,
"Failed to parse the configuration file '%s'\n", config_file);
return rc;
}
}
rc = telnet_init_default(l23_ctx, NULL, OSMO_VTY_PORT_BB);
if (rc < 0) {
LOGP(DMOB, LOGL_FATAL, "Cannot init VTY on %s port %u: %s\n",
vty_get_bind_addr(), OSMO_VTY_PORT_BB, strerror(errno));
return rc;
}
return rc;
}
int main(int argc, char **argv)
{
int rc;
struct l23_app_info *app;
unsigned int app_supp_opt = 0x00;
print_copyright();
srand(time(NULL));
@ -217,21 +274,23 @@ int main(int argc, char **argv)
/* Init default stderr logging */
osmo_init_logging2(l23_ctx, &log_info);
rc = l23_app_init();
if (rc < 0) {
fprintf(stderr, "Failed during l23_app_init()\n");
exit(1);
}
app = l23_app_info();
if (app && app->cfg_supported != NULL)
app_supp_opt = app->cfg_supported();
rc = handle_options(argc, argv);
if (rc) { /* Abort in case of parsing errors */
fprintf(stderr, "Error in command line options. Exiting.\n");
return 1;
}
if (gsmtap_ip) {
gsmtap_inst = gsmtap_source_init(gsmtap_ip, GSMTAP_UDP_PORT, 1);
if (!gsmtap_inst) {
fprintf(stderr, "Failed during gsmtap_init()\n");
exit(1);
}
gsmtap_source_add_sink(gsmtap_inst);
}
if (custom_cfg_file) {
/* Use full path provided by user */
config_file = talloc_strdup(l23_ctx, custom_cfg_file);
@ -250,9 +309,27 @@ int main(int argc, char **argv)
config_dir = talloc_strdup(l23_ctx, config_file);
config_dir = dirname(config_dir);
rc = l23_app_init(config_file);
if (rc)
exit(rc);
if (app_supp_opt & L23_OPT_VTY) {
if (_vty_init(app) < 0)
exit(1);
}
if (gsmtap_ip) {
gsmtap_inst = gsmtap_source_init(gsmtap_ip, GSMTAP_UDP_PORT, 1);
if (!gsmtap_inst) {
fprintf(stderr, "Failed during gsmtap_init()\n");
exit(1);
}
gsmtap_source_add_sink(gsmtap_inst);
}
if (l23_app_start) {
rc = l23_app_start();
if (rc < 0) {
fprintf(stderr, "Failed during l23_app_start()\n");
exit(1);
}
}
signal(SIGINT, sighandler);
signal(SIGTSTP, sighandler);
@ -271,7 +348,7 @@ int main(int argc, char **argv)
}
while (1) {
l23_app_work(&quit);
l23_app_work();
if (quit && llist_empty(&ms_list))
break;
osmo_select_main(0);

View File

@ -106,12 +106,11 @@ int vty_check_number(struct vty *vty, const char *number)
return 0;
}
int vty_reading = 0;
static int hide_default = 0;
static void vty_restart(struct vty *vty, struct osmocom_ms *ms)
{
if (vty_reading)
if (l23_vty_reading)
return;
if (ms->shutdown != MS_SHUTDOWN_NONE)
return;
@ -1183,7 +1182,7 @@ DEFUN(cfg_ms, cfg_ms_cmd, "ms MS_NAME",
}
if (!found) {
if (!vty_reading) {
if (!l23_vty_reading) {
vty_out(vty, "MS name '%s' does not exits, try "
"'ms %s create'%s", argv[0], argv[0],
VTY_NEWLINE);
@ -2270,7 +2269,7 @@ DEFUN(cfg, cfg_cmd, cmd, "Enable " desc "support") \
struct gsm_support *sup = &ms->support; \
if (!sup->item) { \
vty_out(vty, desc " not supported%s", VTY_NEWLINE); \
if (vty_reading) \
if (l23_vty_reading) \
return CMD_SUCCESS; \
return CMD_WARNING; \
} \
@ -2288,7 +2287,7 @@ DEFUN(cfg, cfg_cmd, "no " cmd, NO_STR "Disable " desc " support") \
struct gsm_support *sup = &ms->support; \
if (!sup->item) { \
vty_out(vty, desc " not supported%s", VTY_NEWLINE); \
if (vty_reading) \
if (l23_vty_reading) \
return CMD_SUCCESS; \
return CMD_WARNING; \
} \
@ -2381,7 +2380,7 @@ DEFUN(cfg_ms_sup_class_900, cfg_ms_sup_class_900_cmd, "class-900 (1|2|3|4|5)",
set->class_900 = atoi(argv[0]);
if (set->class_900 < sup->class_900 && !vty_reading)
if (set->class_900 < sup->class_900 && !l23_vty_reading)
vty_out(vty, "Note: You selected a higher class than supported "
" by hardware!%s", VTY_NEWLINE);
@ -2402,7 +2401,7 @@ DEFUN(cfg_ms_sup_class_850, cfg_ms_sup_class_850_cmd, "class-850 (1|2|3|4|5)",
set->class_850 = atoi(argv[0]);
if (set->class_850 < sup->class_850 && !vty_reading)
if (set->class_850 < sup->class_850 && !l23_vty_reading)
vty_out(vty, "Note: You selected a higher class than supported "
" by hardware!%s", VTY_NEWLINE);
@ -2423,7 +2422,7 @@ DEFUN(cfg_ms_sup_class_400, cfg_ms_sup_class_400_cmd, "class-400 (1|2|3|4|5)",
set->class_400 = atoi(argv[0]);
if (set->class_400 < sup->class_400 && !vty_reading)
if (set->class_400 < sup->class_400 && !l23_vty_reading)
vty_out(vty, "Note: You selected a higher class than supported "
" by hardware!%s", VTY_NEWLINE);
@ -2443,7 +2442,7 @@ DEFUN(cfg_ms_sup_class_dcs, cfg_ms_sup_class_dcs_cmd, "class-dcs (1|2|3)",
set->class_dcs = atoi(argv[0]);
if (((set->class_dcs + 1) & 3) < ((sup->class_dcs + 1) & 3)
&& !vty_reading)
&& !l23_vty_reading)
vty_out(vty, "Note: You selected a higher class than supported "
" by hardware!%s", VTY_NEWLINE);
@ -2463,7 +2462,7 @@ DEFUN(cfg_ms_sup_class_pcs, cfg_ms_sup_class_pcs_cmd, "class-pcs (1|2|3)",
set->class_pcs = atoi(argv[0]);
if (((set->class_pcs + 1) & 3) < ((sup->class_pcs + 1) & 3)
&& !vty_reading)
&& !l23_vty_reading)
vty_out(vty, "Note: You selected a higher class than supported "
" by hardware!%s", VTY_NEWLINE);
@ -2489,7 +2488,7 @@ DEFUN(cfg_ms_sup_ch_cap, cfg_ms_sup_ch_cap_cmd,
else
ch_cap = GSM_CAP_SDCCH;
if (ch_cap > sup->ch_cap && !vty_reading) {
if (ch_cap > sup->ch_cap && !l23_vty_reading) {
vty_out(vty, "You selected an higher capability than supported "
" by hardware!%s", VTY_NEWLINE);
return CMD_WARNING;