diff options
author | Andreas.Eversberg <jolly@eversberg.eu> | 2010-11-14 11:52:57 +0000 |
---|---|---|
committer | Andreas.Eversberg <jolly@eversberg.eu> | 2010-11-14 11:52:57 +0000 |
commit | f8903f06d19f67d7dde85004e5e306cef7d199b6 (patch) | |
tree | 3968e5c5a68b211960b3d432022d14c232228872 /src/host | |
parent | 2d8b427ef862b04dbf87ded883a4ee656ec38c34 (diff) |
[layer23] Cleanup of mobile application
All functions for handling mobile instances and mobile relevant parts are
moved to mobile/app_mobile.c, the mobile/main.c and mobile/mncc.c become a
simple out-of-the-box mobile application. (making calls)
The mobile/main.c can be replaced easily by a different application now.
this application may have it's own call control implementation (layer 4).
Full configurations via VTY is still possible and required in this case.
Diffstat (limited to 'src/host')
-rw-r--r-- | src/host/layer23/include/osmocom/bb/common/osmocom_data.h | 2 | ||||
-rw-r--r-- | src/host/layer23/include/osmocom/bb/mobile/app_mobile.h | 15 | ||||
-rw-r--r-- | src/host/layer23/include/osmocom/bb/mobile/mncc.h | 3 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/app_mobile.c | 212 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/gsm322.c | 4 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/gsm48_mm.c | 6 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/main.c | 154 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/vty_interface.c | 11 |
8 files changed, 245 insertions, 162 deletions
diff --git a/src/host/layer23/include/osmocom/bb/common/osmocom_data.h b/src/host/layer23/include/osmocom/bb/common/osmocom_data.h index da35cdb0..749c144c 100644 --- a/src/host/layer23/include/osmocom/bb/common/osmocom_data.h +++ b/src/host/layer23/include/osmocom/bb/common/osmocom_data.h @@ -53,7 +53,7 @@ struct osmocom_ms { struct write_queue l2_wq, sap_wq; uint16_t test_arfcn; - uint8_t delete, shutdown, started; + uint8_t deleting, shutdown, started; struct gsm_support support; struct gsm_settings settings; struct gsm_subscriber subscr; diff --git a/src/host/layer23/include/osmocom/bb/mobile/app_mobile.h b/src/host/layer23/include/osmocom/bb/mobile/app_mobile.h new file mode 100644 index 00000000..138fbe04 --- /dev/null +++ b/src/host/layer23/include/osmocom/bb/mobile/app_mobile.h @@ -0,0 +1,15 @@ +#ifndef APP_MOBILE_H +#define APP_MOBILE_H + +int l23_app_init(int (*mncc_recv)(struct osmocom_ms *ms, int, void *), + const char *config_file, uint16_t vty_port); +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_init(struct osmocom_ms *ms); +int mobile_exit(struct osmocom_ms *ms, int force); +int mobile_work(struct osmocom_ms *ms); + +#endif + diff --git a/src/host/layer23/include/osmocom/bb/mobile/mncc.h b/src/host/layer23/include/osmocom/bb/mobile/mncc.h index 1f8e9099..151f0b4b 100644 --- a/src/host/layer23/include/osmocom/bb/mobile/mncc.h +++ b/src/host/layer23/include/osmocom/bb/mobile/mncc.h @@ -109,6 +109,9 @@ struct gsm_call { #define GSM_TCHF_FRAME 0x0300 #define GSM_TCHF_FRAME_EFR 0x0301 +#define MS_NEW 0x0400 +#define MS_DELETE 0x0401 + #define GSM_MAX_FACILITY 128 #define GSM_MAX_SSVERSION 128 #define GSM_MAX_USERUSER 128 diff --git a/src/host/layer23/src/mobile/app_mobile.c b/src/host/layer23/src/mobile/app_mobile.c index 293d1355..1461e3bb 100644 --- a/src/host/layer23/src/mobile/app_mobile.c +++ b/src/host/layer23/src/mobile/app_mobile.c @@ -30,18 +30,28 @@ #include <osmocom/bb/common/l1ctl.h> #include <osmocom/bb/common/lapdm.h> #include <osmocom/bb/common/logging.h> +#include <osmocom/bb/common/gps.h> #include <osmocom/bb/mobile/gsm48_rr.h> #include <osmocom/bb/mobile/vty.h> +#include <osmocom/bb/mobile/app_mobile.h> +#include <osmocom/bb/mobile/mncc.h> #include <osmocom/vty/telnet_interface.h> #include <osmocore/msgb.h> #include <osmocore/talloc.h> #include <osmocore/select.h> +#include <osmocore/signal.h> + +extern void *l23_ctx; +extern struct llist_head ms_list; +extern int vty_reading; int mncc_recv_mobile(struct osmocom_ms *ms, int msg_type, void *arg); int mncc_recv_dummy(struct osmocom_ms *ms, int msg_type, void *arg); -extern int (*l23_app_exit) (struct osmocom_ms *ms, int force); +int (*mncc_recv_app)(struct osmocom_ms *ms, int, void *); +static int quit; +/* handle ms instance */ int mobile_work(struct osmocom_ms *ms) { int work = 0, w; @@ -63,6 +73,7 @@ int mobile_work(struct osmocom_ms *ms) return work; } +/* run ms instance, if layer1 is available */ int mobile_signal_cb(unsigned int subsys, unsigned int signal, void *handler_data, void *signal_data) { @@ -108,6 +119,7 @@ int mobile_signal_cb(unsigned int subsys, unsigned int signal, return 0; } +/* power-off ms instance */ int mobile_exit(struct osmocom_ms *ms, int force) { struct gsm48_mmlayer *mm = &ms->mmlayer; @@ -141,7 +153,8 @@ int mobile_exit(struct osmocom_ms *ms, int force) return 0; } -int l23_app_init(struct osmocom_ms *ms) +/* power-on ms instance */ +int mobile_init(struct osmocom_ms *ms) { int rc; @@ -159,7 +172,7 @@ int l23_app_init(struct osmocom_ms *ms) if (rc < 0) { fprintf(stderr, "Failed during layer2_open()\n"); ms->l2_wq.bfd.fd = -1; - l23_app_exit(ms, 1); + mobile_exit(ms, 1); return rc; } @@ -168,12 +181,14 @@ int l23_app_init(struct osmocom_ms *ms) if (rc < 0) { fprintf(stderr, "Failed during sap_open(), no SIM reader\n"); ms->sap_wq.bfd.fd = -1; - l23_app_exit(ms, 1); + mobile_exit(ms, 1); return rc; } #endif - if (ms->settings.ch_cap == GSM_CAP_SDCCH) + if (mncc_recv_app) + ms->cclayer.mncc_recv = mncc_recv_app; + else if (ms->settings.ch_cap == GSM_CAP_SDCCH) ms->cclayer.mncc_recv = mncc_recv_dummy; else ms->cclayer.mncc_recv = mncc_recv_mobile; @@ -188,3 +203,190 @@ int l23_app_init(struct osmocom_ms *ms) return 0; } +/* create ms instance */ +struct osmocom_ms *mobile_new(char *name) +{ + static struct osmocom_ms *ms; + + ms = talloc_zero(l23_ctx, struct osmocom_ms); + if (!ms) { + fprintf(stderr, "Failed to allocate MS\n"); + exit(1); + } + llist_add_tail(&ms->entity, &ms_list); + + strcpy(ms->name, name); + + ms->l2_wq.bfd.fd = -1; + ms->sap_wq.bfd.fd = -1; + + gsm_support_init(ms); + gsm_settings_init(ms); + + ms->shutdown = 2; /* being down */ + + if (mncc_recv_app) { + struct msgb *msg; + + msg = msgb_alloc(sizeof(struct gsm_mncc), "MNCC"); + if (msg) { + struct gsm_mncc *mncc = (struct gsm_mncc *)msg->data; + + mncc->msg_type = MS_NEW; + mncc_recv_app(ms, mncc->msg_type, mncc); + } + ms->cclayer.mncc_recv = mncc_recv_app; + } else + ms->cclayer.mncc_recv = mncc_recv_dummy; + + return ms; +} + +/* destroy ms instance */ +int mobile_delete(struct osmocom_ms *ms, int force) +{ + int rc; + + ms->deleting = 1; + + if (ms->shutdown == 0 || (ms->shutdown == 1 && force)) { + rc = mobile_exit(ms, force); + if (rc < 0) + return rc; + } + + if (mncc_recv_app) { + struct msgb *msg; + + msg = msgb_alloc(sizeof(struct gsm_mncc), "MNCC"); + if (msg) { + struct gsm_mncc *mncc = (struct gsm_mncc *)msg->data; + + mncc->msg_type = MS_DELETE; + mncc_recv_app(ms, mncc->msg_type, mncc); + } + } + + return 0; +} + +/* handle global shutdown */ +int global_signal_cb(unsigned int subsys, unsigned int signal, + void *handler_data, void *signal_data) +{ + struct osmocom_ms *ms, *ms2; + + if (subsys != SS_GLOBAL) + return 0; + + switch (signal) { + case S_GLOBAL_SHUTDOWN: + llist_for_each_entry_safe(ms, ms2, &ms_list, entity) + mobile_delete(ms, quit); + + /* if second signal is received, force to exit */ + quit = 1; + break; + } + return 0; +} + +/* global work handler */ +int l23_app_work(int *_quit) +{ + struct osmocom_ms *ms, *ms2; + int work = 0; + + llist_for_each_entry_safe(ms, ms2, &ms_list, entity) { + if (ms->shutdown != 2) + work |= mobile_work(ms); + if (ms->shutdown == 2) { + if (ms->l2_wq.bfd.fd > -1) { + layer2_close(ms); + ms->l2_wq.bfd.fd = -1; + } + + if (ms->sap_wq.bfd.fd > -1) { + sap_close(ms); + ms->sap_wq.bfd.fd = -1; + } + + if (ms->deleting) { + gsm_settings_exit(ms); + llist_del(&ms->entity); + talloc_free(ms); + work = 1; + } + } + } + + /* return, if a shutdown was scheduled (quit = 1) */ + *_quit = quit; + return work; +} + +/* global exit */ +int l23_app_exit(void) +{ + unregister_signal_handler(SS_L1CTL, &gsm322_l1_signal, NULL); + unregister_signal_handler(SS_L1CTL, &mobile_signal_cb, NULL); + unregister_signal_handler(SS_GLOBAL, &global_signal_cb, NULL); + + gps_close(); + + return 0; +} + +static struct vty_app_info vty_info = { + .name = "OsmocomBB", + .version = PACKAGE_VERSION, + .go_parent_cb = ms_vty_go_parent, +}; + +/* global init */ +int l23_app_init(int (*mncc_recv)(struct osmocom_ms *ms, int, void *), + const char *config_file, uint16_t vty_port) +{ + struct telnet_connection dummy_conn; + int rc; + + mncc_recv_app = mncc_recv; + + gps_init(); + + vty_init(&vty_info); + ms_vty_init(); + dummy_conn.priv = NULL; + vty_reading = 1; + rc = vty_read_config_file(config_file, &dummy_conn); + if (rc < 0) { + fprintf(stderr, "Failed to parse the config file: '%s'\n", + config_file); + fprintf(stderr, "Please check or create config file using: " + "'touch %s'\n", config_file); + return rc; + } + vty_reading = 0; + telnet_init(l23_ctx, NULL, vty_port); + if (rc < 0) + return rc; + printf("VTY available on port %u.\n", vty_port); + + register_signal_handler(SS_GLOBAL, &global_signal_cb, NULL); + register_signal_handler(SS_L1CTL, &mobile_signal_cb, NULL); + register_signal_handler(SS_L1CTL, &gsm322_l1_signal, NULL); + + if (llist_empty(&ms_list)) { + struct osmocom_ms *ms; + + printf("No Mobile Station defined, creating: MS '1'\n"); + ms = mobile_new("1"); + if (ms) + mobile_init(ms); + } + + quit = 0; + + return 0; +} + diff --git a/src/host/layer23/src/mobile/gsm322.c b/src/host/layer23/src/mobile/gsm322.c index 751b8b4b..3c920e4e 100644 --- a/src/host/layer23/src/mobile/gsm322.c +++ b/src/host/layer23/src/mobile/gsm322.c @@ -36,9 +36,9 @@ #include <osmocom/bb/common/osmocom_data.h> #include <osmocom/bb/common/networks.h> #include <osmocom/bb/mobile/vty.h> +#include <osmocom/bb/mobile/app_mobile.h> extern void *l23_ctx; -extern int (*l23_app_exit) (struct osmocom_ms *ms, int force); static void gsm322_cs_timeout(void *arg); static void gsm322_cs_loss(void *arg); @@ -2489,7 +2489,7 @@ int gsm322_l1_signal(unsigned int subsys, unsigned int signal, case S_L1CTL_RESET: ms = signal_data; if (ms->mmlayer.power_off_idle) { - l23_app_exit(ms, 1); + mobile_exit(ms, 1); return 0; } break; diff --git a/src/host/layer23/src/mobile/gsm48_mm.c b/src/host/layer23/src/mobile/gsm48_mm.c index d4444cf2..1751230f 100644 --- a/src/host/layer23/src/mobile/gsm48_mm.c +++ b/src/host/layer23/src/mobile/gsm48_mm.c @@ -36,9 +36,9 @@ #include <osmocom/bb/common/networks.h> #include <osmocom/bb/common/l1ctl.h> #include <osmocom/bb/mobile/gsm48_cc.h> +#include <osmocom/bb/mobile/app_mobile.h> extern void *l23_ctx; -extern int (*l23_app_exit) (struct osmocom_ms *ms, int force); void mm_conn_free(struct gsm48_mm_conn *conn); static int gsm48_rcv_rr(struct osmocom_ms *ms, struct msgb *msg); @@ -1743,7 +1743,7 @@ static int gsm48_mm_imsi_detach_end(struct osmocom_ms *ms, struct msgb *msg) /* wait for RR idle and then power off when IMSI is detached */ if (ms->shutdown) { if (mm->state == GSM48_MM_ST_MM_IDLE) { - l23_app_exit(ms, 1); + mobile_exit(ms, 1); return 0; } /* power off when MM idle */ @@ -1818,7 +1818,7 @@ static int gsm48_mm_imsi_detach_release(struct osmocom_ms *ms, struct msgb *msg) /* power off */ if (ms->shutdown) { - l23_app_exit(ms, 1); + mobile_exit(ms, 1); return 0; } diff --git a/src/host/layer23/src/mobile/main.c b/src/host/layer23/src/mobile/main.c index 9fd4ff78..2f25a978 100644 --- a/src/host/layer23/src/mobile/main.c +++ b/src/host/layer23/src/mobile/main.c @@ -22,19 +22,10 @@ */ #include <osmocom/bb/common/osmocom_data.h> -#include <osmocom/bb/common/l1l2_interface.h> -#include <osmocom/bb/common/l1ctl.h> -#include <osmocom/bb/common/sap_interface.h> -#include <osmocom/bb/misc/layer3.h> -#include <osmocom/bb/common/lapdm.h> #include <osmocom/bb/common/logging.h> -#include <osmocom/bb/common/gps.h> -#include <osmocom/bb/mobile/vty.h> -#include <osmocom/vty/telnet_interface.h> +#include <osmocom/bb/mobile/app_mobile.h> -#include <osmocore/msgb.h> #include <osmocore/talloc.h> -#include <osmocore/select.h> #include <osmocore/linuxlist.h> #include <osmocore/gsmtap_util.h> #include <osmocore/signal.h> @@ -57,16 +48,13 @@ static const char *config_file = "/etc/osmocom/osmocom.cfg"; struct llist_head ms_list; static uint32_t gsmtap_ip = 0; unsigned short vty_port = 4247; -int (*l23_app_work) (struct osmocom_ms *ms) = NULL; -int (*l23_app_exit) (struct osmocom_ms *ms, int force) = NULL; -int quit = 0; +int debug_set = 0; int mobile_delete(struct osmocom_ms *ms, int force); int mobile_signal_cb(unsigned int subsys, unsigned int signal, void *handler_data, void *signal_data); int mobile_work(struct osmocom_ms *ms); int mobile_exit(struct osmocom_ms *ms, int force); -extern int vty_reading; const char *openbsc_copyright = @@ -128,6 +116,7 @@ static void handle_options(int argc, char **argv) break; case 'd': log_parse_category_mask(stderr_target, optarg); + debug_set = 1; break; default: break; @@ -151,75 +140,9 @@ void sighandler(int sigset) dispatch_signal(SS_GLOBAL, S_GLOBAL_SHUTDOWN, NULL); } -int global_signal_cb(unsigned int subsys, unsigned int signal, - void *handler_data, void *signal_data) -{ - struct osmocom_ms *ms, *ms2; - - if (subsys != SS_GLOBAL) - return 0; - - switch (signal) { - case S_GLOBAL_SHUTDOWN: - llist_for_each_entry_safe(ms, ms2, &ms_list, entity) - mobile_delete(ms, quit); - - /* if second signal is received, force to exit */ - quit = 1; - break; - } - return 0; -} - -struct osmocom_ms *mobile_new(char *name) -{ - static struct osmocom_ms *ms; - - ms = talloc_zero(l23_ctx, struct osmocom_ms); - if (!ms) { - fprintf(stderr, "Failed to allocate MS\n"); - exit(1); - } - llist_add_tail(&ms->entity, &ms_list); - - strcpy(ms->name, name); - - ms->l2_wq.bfd.fd = -1; - ms->sap_wq.bfd.fd = -1; - - gsm_support_init(ms); - gsm_settings_init(ms); - - ms->shutdown = 2; /* being down */ - - return ms; -} - -int mobile_delete(struct osmocom_ms *ms, int force) -{ - int rc; - - ms->delete = 1; - - if (ms->shutdown == 0 || (ms->shutdown == 1 && force)) { - rc = l23_app_exit(ms, force); - if (rc < 0) - return rc; - } - - return 0; -} - -static struct vty_app_info vty_info = { - .name = "OsmocomBB", - .version = PACKAGE_VERSION, - .go_parent_cb = ms_vty_go_parent, -}; - int main(int argc, char **argv) { - struct osmocom_ms *ms, *ms2; - struct telnet_connection dummy_conn; + int quit = 0; int rc; printf("%s\n", openbsc_copyright); @@ -236,45 +159,10 @@ int main(int argc, char **argv) handle_options(argc, argv); -// log_parse_category_mask(stderr_target, "DL1C:DRSL:DLAPDM:DCS:DPLMN:DRR:DMM:DSIM:DCC:DMNCC:DPAG:DSUM"); - log_parse_category_mask(stderr_target, "DCS:DPLMN:DRR:DMM:DSIM:DCC:DMNCC:DPAG:DSUM"); + if (!debug_set) + log_parse_category_mask(stderr_target, "DCS:DPLMN:DRR:DMM:DSIM:DCC:DMNCC:DPAG:DSUM"); log_set_log_level(stderr_target, LOGL_INFO); - gps_init(); - - l23_app_work = mobile_work; - register_signal_handler(SS_GLOBAL, &global_signal_cb, NULL); - register_signal_handler(SS_L1CTL, &mobile_signal_cb, NULL); - register_signal_handler(SS_L1CTL, &gsm322_l1_signal, NULL); - l23_app_exit = mobile_exit; - - vty_init(&vty_info); - ms_vty_init(); - dummy_conn.priv = NULL; - vty_reading = 1; - rc = vty_read_config_file(config_file, &dummy_conn); - if (rc < 0) { - fprintf(stderr, "Failed to parse the config file: '%s'\n", - config_file); - fprintf(stderr, "Please check or create config file using: " - "'touch %s'\n", config_file); - return rc; - } - vty_reading = 0; - telnet_init(l23_ctx, NULL, vty_port); - if (rc < 0) - return rc; - printf("VTY available on port %u.\n", vty_port); - - if (llist_empty(&ms_list)) { - struct osmocom_ms *ms; - - printf("No Mobile Station defined, creating: MS '1'\n"); - ms = mobile_new("1"); - if (ms) - l23_app_init(ms); - } - if (gsmtap_ip) { rc = gsmtap_init(gsmtap_ip); if (rc < 0) { @@ -283,43 +171,21 @@ int main(int argc, char **argv) } } + l23_app_init(NULL, config_file, vty_port); + signal(SIGINT, sighandler); signal(SIGHUP, sighandler); signal(SIGTERM, sighandler); signal(SIGPIPE, sighandler); while (1) { - llist_for_each_entry_safe(ms, ms2, &ms_list, entity) { - if (ms->shutdown != 2) - l23_app_work(ms); - if (ms->shutdown == 2) { - if (ms->l2_wq.bfd.fd > -1) { - layer2_close(ms); - ms->l2_wq.bfd.fd = -1; - } - - if (ms->sap_wq.bfd.fd > -1) { - sap_close(ms); - ms->sap_wq.bfd.fd = -1; - } - - if (ms->delete) { - gsm_settings_exit(ms); - llist_del(&ms->entity); - talloc_free(ms); - } - } - } + l23_app_work(&quit); if (quit && llist_empty(&ms_list)) break; bsc_select_main(0); } - unregister_signal_handler(SS_L1CTL, &gsm322_l1_signal, NULL); - unregister_signal_handler(SS_L1CTL, &mobile_signal_cb, NULL); - unregister_signal_handler(SS_GLOBAL, &global_signal_cb, NULL); - - gps_close(); + l23_app_exit(); return 0; } diff --git a/src/host/layer23/src/mobile/vty_interface.c b/src/host/layer23/src/mobile/vty_interface.c index 8a13a5dc..bb998a1e 100644 --- a/src/host/layer23/src/mobile/vty_interface.c +++ b/src/host/layer23/src/mobile/vty_interface.c @@ -36,13 +36,10 @@ #include <osmocom/bb/mobile/mncc.h> #include <osmocom/bb/mobile/transaction.h> #include <osmocom/bb/mobile/vty.h> +#include <osmocom/bb/mobile/app_mobile.h> #include <osmocom/vty/telnet_interface.h> void *l23_ctx; -extern int l23_app_init(struct osmocom_ms *ms); -extern int (*l23_app_exit) (struct osmocom_ms *ms, int force); -extern struct osmocom_ms *mobile_new(char *name); -extern int mobile_delete(struct osmocom_ms *ms, int force); int mncc_call(struct osmocom_ms *ms, char *number); int mncc_hangup(struct osmocom_ms *ms); @@ -2078,7 +2075,7 @@ DEFUN(cfg_no_shutdown, cfg_ms_no_shutdown_cmd, "no shutdown", } } - rc = l23_app_init(ms); + rc = mobile_init(ms); if (rc < 0) { vty_out(vty, "Connection to layer 1 failed!%s", VTY_NEWLINE); @@ -2094,7 +2091,7 @@ DEFUN(cfg_shutdown, cfg_ms_shutdown_cmd, "shutdown", struct osmocom_ms *ms = vty->index; if (ms->shutdown == 0) - l23_app_exit(ms, 0); + mobile_exit(ms, 0); return CMD_SUCCESS; } @@ -2105,7 +2102,7 @@ DEFUN(cfg_shutdown_force, cfg_ms_shutdown_force_cmd, "shutdown force", struct osmocom_ms *ms = vty->index; if (ms->shutdown <= 1) - l23_app_exit(ms, 1); + mobile_exit(ms, 1); return CMD_SUCCESS; } |