aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/osmo-bsc/osmo_bsc_rf.c
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>2011-08-25 23:19:45 +0200
commit63c2c828c0c7e60e835abd298f92ae0fcfd1988e (patch)
treedb75261eaeae930992c2fff457429e1b6f6e5319 /openbsc/src/osmo-bsc/osmo_bsc_rf.c
parent1979e7227f45db9e734a31225fc31e361d2ba16b (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.
Diffstat (limited to 'openbsc/src/osmo-bsc/osmo_bsc_rf.c')
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_rf.c52
1 files changed, 52 insertions, 0 deletions
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;
}