summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2011-08-16 19:47:39 +0200
committerHolger Hans Peter Freyther <zecke@selfish.org>2013-01-15 13:52:00 +0100
commit2a896070a744327968770d3f9c23e6e5410f6f57 (patch)
treea36002e6b255b3dd5e0cc3cc3b6937abd57e2736
parent036b25fb7fccd6bb99f0f539bb42ef6e2155bed2 (diff)
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.
-rw-r--r--openbsc/include/openbsc/osmo_bsc_rf.h3
-rw-r--r--openbsc/include/openbsc/osmo_msc_data.h1
-rw-r--r--openbsc/src/libbsc/bsc_rf_ctrl.c53
-rw-r--r--openbsc/src/libcommon/gsm_data.c1
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_vty.c28
5 files changed, 84 insertions, 2 deletions
diff --git a/openbsc/include/openbsc/osmo_bsc_rf.h b/openbsc/include/openbsc/osmo_bsc_rf.h
index c0ab6b2..a67e1bd 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 8e255a0..ba93a08 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/libbsc/bsc_rf_ctrl.c b/openbsc/src/libbsc/bsc_rf_ctrl.c
index 89a0246..87bf39d 100644
--- a/openbsc/src/libbsc/bsc_rf_ctrl.c
+++ b/openbsc/src/libbsc/bsc_rf_ctrl.c
@@ -366,6 +366,53 @@ 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(DLINP, LOGL_NOTICE,
+ "Going to switch off RF due lack of a MSC connection.\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;
@@ -444,6 +491,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/libcommon/gsm_data.c b/openbsc/src/libcommon/gsm_data.c
index 4ccb820..c9f41fc 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_vty.c b/openbsc/src/osmo-bsc/osmo_bsc_vty.c
index f502683..8cd80f9 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",
@@ -498,8 +522,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);