From 63c2c828c0c7e60e835abd298f92ae0fcfd1988e Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Tue, 16 Aug 2011 19:47:39 +0200 Subject: bsc: Auto RF Off in case of missing MSC connection For short IP failures we want the RF to stay up and wait for the re-connect but in case the A-link is gone too long it is good to switch off the RF and wait for commands to enable it again. --- openbsc/include/openbsc/osmo_bsc_rf.h | 3 ++ openbsc/include/openbsc/osmo_msc_data.h | 1 + openbsc/src/libcommon/gsm_data.c | 1 + openbsc/src/osmo-bsc/osmo_bsc_rf.c | 52 +++++++++++++++++++++++++++++++++ openbsc/src/osmo-bsc/osmo_bsc_vty.c | 28 ++++++++++++++++-- 5 files changed, 83 insertions(+), 2 deletions(-) diff --git a/openbsc/include/openbsc/osmo_bsc_rf.h b/openbsc/include/openbsc/osmo_bsc_rf.h index 6aa5ad40b..d4da7b101 100644 --- a/openbsc/include/openbsc/osmo_bsc_rf.h +++ b/openbsc/include/openbsc/osmo_bsc_rf.h @@ -42,6 +42,9 @@ struct osmo_bsc_rf { /* some handling for the automatic grace switch */ struct osmo_timer_list grace_timeout; + + /* auto RF switch-off due lack of MSC connection */ + struct osmo_timer_list auto_off_timer; }; struct osmo_bsc_rf_conn { diff --git a/openbsc/include/openbsc/osmo_msc_data.h b/openbsc/include/openbsc/osmo_msc_data.h index 8e255a0fd..ba93a089d 100644 --- a/openbsc/include/openbsc/osmo_msc_data.h +++ b/openbsc/include/openbsc/osmo_msc_data.h @@ -99,6 +99,7 @@ struct osmo_bsc_data { int mid_call_timeout; char *rf_ctrl_name; struct osmo_bsc_rf *rf_ctrl; + int auto_off_timeout; }; diff --git a/openbsc/src/libcommon/gsm_data.c b/openbsc/src/libcommon/gsm_data.c index 0dfad6c29..48fc96d4d 100644 --- a/openbsc/src/libcommon/gsm_data.c +++ b/openbsc/src/libcommon/gsm_data.c @@ -86,6 +86,7 @@ struct gsm_network *gsm_network_init(uint16_t country_code, uint16_t network_cod } /* Init back pointer */ + net->bsc_data->auto_off_timeout = -1; net->bsc_data->network = net; INIT_LLIST_HEAD(&net->bsc_data->mscs); diff --git a/openbsc/src/osmo-bsc/osmo_bsc_rf.c b/openbsc/src/osmo-bsc/osmo_bsc_rf.c index 052409acd..c64bbe575 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_rf.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_rf.c @@ -325,6 +325,52 @@ static int rf_ctrl_accept(struct osmo_fd *bfd, unsigned int what) return 0; } +static void rf_auto_off_cb(void *_timer) +{ + struct osmo_bsc_rf *rf = _timer; + + LOGP(DINP, LOGL_NOTICE, "Going to switch off RF due lack of MSC.\n"); + osmo_bsc_rf_schedule_lock(rf, RF_CMD_D_OFF); +} + +static int msc_signal_handler(unsigned int subsys, unsigned int signal, + void *handler_data, void *signal_data) +{ + struct gsm_network *net; + struct msc_signal_data *msc; + struct osmo_bsc_rf *rf; + + /* check if we want to handle this signal */ + if (subsys != SS_MSC) + return 0; + + net = handler_data; + msc = signal_data; + + /* check if we have the needed information */ + if (!net->bsc_data || !net->bsc_data->rf_ctrl) + return 0; + if (msc->data->type != MSC_CON_TYPE_NORMAL) + return 0; + + rf = net->bsc_data->rf_ctrl; + switch (signal) { + case S_MSC_LOST: + if (net->bsc_data->auto_off_timeout < 0) + return 0; + if (osmo_timer_pending(&rf->auto_off_timer)) + return 0; + osmo_timer_schedule(&rf->auto_off_timer, + net->bsc_data->auto_off_timeout, 0); + break; + case S_MSC_CONNECTED: + osmo_timer_del(&rf->auto_off_timer); + break; + } + + return 0; +} + struct osmo_bsc_rf *osmo_bsc_rf_create(const char *path, struct gsm_network *net) { unsigned int namelen; @@ -403,6 +449,12 @@ struct osmo_bsc_rf *osmo_bsc_rf_create(const char *path, struct gsm_network *net rf->delay_cmd.data = rf; rf->delay_cmd.cb = rf_delay_cmd_cb; + rf->auto_off_timer.data = rf; + rf->auto_off_timer.cb = rf_auto_off_cb; + + /* listen to RF signals */ + osmo_signal_register_handler(SS_MSC, msc_signal_handler, net); + return rf; } diff --git a/openbsc/src/osmo-bsc/osmo_bsc_vty.c b/openbsc/src/osmo-bsc/osmo_bsc_vty.c index a82a53868..f4c462efb 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_vty.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_vty.c @@ -168,6 +168,10 @@ static int config_write_bsc(struct vty *vty) vty_out(vty, " bsc-rf-socket %s%s", bsc->rf_ctrl_name, VTY_NEWLINE); + if (bsc->auto_off_timeout != -1) + vty_out(vty, " bsc-auto-rf-off %d%s", + bsc->auto_off_timeout, VTY_NEWLINE); + return CMD_SUCCESS; } @@ -462,6 +466,26 @@ DEFUN(cfg_net_rf_socket, return CMD_SUCCESS; } +DEFUN(cfg_net_rf_off_time, + cfg_net_rf_off_time_cmd, + "bsc-auto-rf-off <1-65000>", + "Disable RF on MSC Connection\n" "Timeout\n") +{ + struct osmo_bsc_data *data = osmo_bsc_data(vty); + data->auto_off_timeout = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(cfg_net_no_rf_off_time, + cfg_net_no_rf_off_time_cmd, + "no bsc-auto-rf-off", + NO_STR "Disable RF on MSC Connection\n") +{ + struct osmo_bsc_data *data = osmo_bsc_data(vty); + data->auto_off_timeout = -1; + return CMD_SUCCESS; +} + DEFUN(show_statistics, show_statistics_cmd, "show statistics", @@ -481,8 +505,8 @@ int bsc_vty_init_extra(void) install_element(BSC_NODE, &cfg_net_bsc_mid_call_text_cmd); install_element(BSC_NODE, &cfg_net_bsc_mid_call_timeout_cmd); install_element(BSC_NODE, &cfg_net_rf_socket_cmd); - - + install_element(BSC_NODE, &cfg_net_rf_off_time_cmd); + install_element(BSC_NODE, &cfg_net_no_rf_off_time_cmd); install_node(&msc_node, config_write_msc); install_default(MSC_NODE); -- cgit v1.2.3