aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2013-01-28 16:00:46 +0100
committerHolger Hans Peter Freyther <zecke@selfish.org>2013-01-28 16:00:46 +0100
commit883fbc9d044318791239d79f86fc1aa235cb32e6 (patch)
treef9d4d99821a356169af7d2b8674cabcfd384dc56
parente7ea08379e1b8aa13e6db52558fbdd17002d0e3e (diff)
parentdc030960fc729c3124c40838a733eab1bc9394b0 (diff)
Merge branch 'zecke/feature/rf-lock-exclude'
Exclude a BTS from the RF Lock and allow MO and MT operations on this BTS. The paging modification has been verified using the FakeBTS and the handover test. Paging continues to work for the normal case.
-rw-r--r--openbsc/include/openbsc/gsm_data_shared.h3
-rw-r--r--openbsc/include/openbsc/osmo_bsc_grace.h9
-rw-r--r--openbsc/include/openbsc/paging.h2
-rw-r--r--openbsc/src/libbsc/bsc_rf_ctrl.c28
-rw-r--r--openbsc/src/libbsc/bsc_vty.c27
-rw-r--r--openbsc/src/libbsc/paging.c35
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_bssap.c5
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_grace.c50
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_sccp.c5
9 files changed, 136 insertions, 28 deletions
diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h
index 56d62e54c..4f9f21f01 100644
--- a/openbsc/include/openbsc/gsm_data_shared.h
+++ b/openbsc/include/openbsc/gsm_data_shared.h
@@ -699,6 +699,9 @@ struct gsm_bts {
/* do we use static (user-defined) system information messages? (bitmask) */
uint32_t si_mode_static;
+
+ /* exclude the BTS from the global RF Lock handling */
+ int excl_from_rf_lock;
#endif /* ROLE_BSC */
void *role;
};
diff --git a/openbsc/include/openbsc/osmo_bsc_grace.h b/openbsc/include/openbsc/osmo_bsc_grace.h
index 45d4db8ec..e9c1a0a07 100644
--- a/openbsc/include/openbsc/osmo_bsc_grace.h
+++ b/openbsc/include/openbsc/osmo_bsc_grace.h
@@ -1,6 +1,6 @@
/*
- * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2010 by On-Waves
+ * (C) 2010-2013 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2010-2013 by On-Waves
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@@ -23,6 +23,9 @@
#include "gsm_data.h"
-int bsc_grace_allow_new_connection(struct gsm_network *network);
+struct osmo_msc_data;
+
+int bsc_grace_allow_new_connection(struct gsm_network *net, struct gsm_bts *bts);
+int bsc_grace_paging_request(struct gsm_subscriber *sub, int type, struct osmo_msc_data *msc);
#endif
diff --git a/openbsc/include/openbsc/paging.h b/openbsc/include/openbsc/paging.h
index e1438ba4c..2a10f4ef1 100644
--- a/openbsc/include/openbsc/paging.h
+++ b/openbsc/include/openbsc/paging.h
@@ -56,6 +56,8 @@ struct gsm_paging_request {
/* schedule paging request */
int paging_request(struct gsm_network *network, struct gsm_subscriber *subscr,
int type, gsm_cbfn *cbfn, void *data);
+int paging_request_bts(struct gsm_bts *bts, struct gsm_subscriber *subscr,
+ int type, gsm_cbfn *cbfn, void *data);
/* stop paging requests */
void paging_request_stop(struct gsm_bts *bts, struct gsm_subscriber *subscr,
diff --git a/openbsc/src/libbsc/bsc_rf_ctrl.c b/openbsc/src/libbsc/bsc_rf_ctrl.c
index 87bf39de5..bd36e1884 100644
--- a/openbsc/src/libbsc/bsc_rf_ctrl.c
+++ b/openbsc/src/libbsc/bsc_rf_ctrl.c
@@ -1,8 +1,8 @@
/* RF Ctl handling socket */
/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
- * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2010 by On-Waves
+ * (C) 2010-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2010-2012 by On-Waves
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@@ -129,6 +129,14 @@ static int lock_each_trx(struct gsm_network *net, int lock)
llist_for_each_entry(bts, &net->bts_list, list) {
struct gsm_bts_trx *trx;
+
+ /* Exclude the BTS from the global lock */
+ if (bts->excl_from_rf_lock) {
+ LOGP(DLINP, LOGL_DEBUG,
+ "Excluding BTS(%d) from trx lock.\n", bts->nr);
+ continue;
+ }
+
llist_for_each_entry(trx, &bts->trx_list, list) {
gsm_trx_lock_rf(trx, lock);
}
@@ -176,6 +184,13 @@ static void handle_query(struct osmo_bsc_rf_conn *conn)
llist_for_each_entry(bts, &conn->rf->gsm_network->bts_list, list) {
struct gsm_bts_trx *trx;
+
+ /* Exclude the BTS from the global lock */
+ if (bts->excl_from_rf_lock) {
+ LOGP(DLINP, LOGL_DEBUG,
+ "Excluding BTS(%d) from query.\n", bts->nr);
+ continue;
+ }
llist_for_each_entry(trx, &bts->trx_list, list) {
if (trx->mo.nm_state.availability == NM_AVSTATE_OK &&
trx->mo.nm_state.operational != NM_OPSTATE_DISABLED) {
@@ -200,6 +215,13 @@ static void rf_check_cb(void *_data)
if (!bts->oml_link || !is_ipaccess_bts(bts))
continue;
+ /* Exclude the BTS from the global lock */
+ if (bts->excl_from_rf_lock) {
+ LOGP(DLINP, LOGL_DEBUG,
+ "Excluding BTS(%d) from query.\n", bts->nr);
+ continue;
+ }
+
llist_for_each_entry(trx, &bts->trx_list, list) {
if (trx->mo.nm_state.availability != NM_AVSTATE_OK ||
trx->mo.nm_state.operational != NM_OPSTATE_ENABLED ||
@@ -233,7 +255,7 @@ static void grace_timeout(void *_data)
{
struct osmo_bsc_rf *rf = (struct osmo_bsc_rf *) _data;
- LOGP(DLINP, LOGL_NOTICE, "Grace timeout. Disabling the TRX.\n");
+ LOGP(DLINP, LOGL_NOTICE, "Grace timeout. Going to disable all BTS/TRX.\n");
switch_rf_off(rf);
}
diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c
index e89317ddd..ec92c1875 100644
--- a/openbsc/src/libbsc/bsc_vty.c
+++ b/openbsc/src/libbsc/bsc_vty.c
@@ -580,6 +580,9 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
config_write_bts_gprs(vty, bts);
+ if (bts->excl_from_rf_lock)
+ vty_out(vty, " rf-lock-exclude%s", VTY_NEWLINE);
+
if (bts->model->config_write_bts)
bts->model->config_write_bts(vty, bts);
@@ -2443,6 +2446,28 @@ DEFUN(cfg_bts_si5_neigh, cfg_bts_si5_neigh_cmd,
return CMD_SUCCESS;
}
+#define EXCL_RFLOCK_STR "Exclude this BTS from the global RF Lock\n"
+
+DEFUN(cfg_bts_excl_rf_lock,
+ cfg_bts_excl_rf_lock_cmd,
+ "rf-lock-exclude",
+ EXCL_RFLOCK_STR)
+{
+ struct gsm_bts *bts = vty->index;
+ bts->excl_from_rf_lock = 1;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_bts_no_excl_rf_lock,
+ cfg_bts_no_excl_rf_lock_cmd,
+ "no rf-lock-exclude",
+ NO_STR EXCL_RFLOCK_STR)
+{
+ struct gsm_bts *bts = vty->index;
+ bts->excl_from_rf_lock = 0;
+ return CMD_SUCCESS;
+}
+
#define TRX_TEXT "Radio Transceiver\n"
/* per TRX configuration */
@@ -3037,6 +3062,8 @@ int bsc_vty_init(const struct log_info *cat)
install_element(BTS_NODE, &cfg_bts_neigh_mode_cmd);
install_element(BTS_NODE, &cfg_bts_neigh_cmd);
install_element(BTS_NODE, &cfg_bts_si5_neigh_cmd);
+ install_element(BTS_NODE, &cfg_bts_excl_rf_lock_cmd);
+ install_element(BTS_NODE, &cfg_bts_no_excl_rf_lock_cmd);
install_element(BTS_NODE, &cfg_trx_cmd);
install_node(&trx_node, dummy_config_write);
diff --git a/openbsc/src/libbsc/paging.c b/openbsc/src/libbsc/paging.c
index b731dbcfa..286c57ba9 100644
--- a/openbsc/src/libbsc/paging.c
+++ b/openbsc/src/libbsc/paging.c
@@ -1,5 +1,5 @@
/* Paging helper and manager.... */
-/* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
+/* (C) 2009,2013 by Holger Hans Peter Freyther <zecke@selfish.org>
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@@ -298,6 +298,26 @@ static int _paging_request(struct gsm_bts *bts, struct gsm_subscriber *subscr,
return 0;
}
+int paging_request_bts(struct gsm_bts *bts, struct gsm_subscriber *subscr,
+ int type, gsm_cbfn *cbfn, void *data)
+{
+ int rc;
+
+ /* skip all currently inactive TRX */
+ if (!trx_is_usable(bts->c0))
+ return 0;
+
+ /* maybe it is the first time we use it */
+ paging_init_if_needed(bts);
+
+
+ /* Trigger paging, pass any error to the caller */
+ rc = _paging_request(bts, subscr, type, cbfn, data);
+ if (rc < 0)
+ return rc;
+ return 1;
+}
+
int paging_request(struct gsm_network *network, struct gsm_subscriber *subscr,
int type, gsm_cbfn *cbfn, void *data)
{
@@ -314,19 +334,10 @@ int paging_request(struct gsm_network *network, struct gsm_subscriber *subscr,
if (!bts)
break;
- /* skip all currently inactive TRX */
- if (!trx_is_usable(bts->c0))
- continue;
-
- /* maybe it is the first time we use it */
- paging_init_if_needed(bts);
-
- num_pages++;
-
- /* Trigger paging, pass any error to caller */
- rc = _paging_request(bts, subscr, type, cbfn, data);
+ rc = paging_request_bts(bts, subscr, type, cbfn, data);
if (rc < 0)
return rc;
+ num_pages += rc;
} while (1);
if (num_pages == 0)
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_bssap.c b/openbsc/src/osmo-bsc/osmo_bsc_bssap.c
index 6b8504d21..c2c241732 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_bssap.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_bssap.c
@@ -177,7 +177,7 @@ static int bssmap_handle_paging(struct osmo_msc_data *msc,
subscr->tmsi = tmsi;
LOGP(DMSC, LOGL_INFO, "Paging request from MSC IMSI: '%s' TMSI: '0x%x/%u' LAC: 0x%x\n", mi_string, tmsi, tmsi, lac);
- paging_request(msc->network, subscr, chan_needed, NULL, msc);
+ bsc_grace_paging_request(subscr, chan_needed, msc);
return 0;
}
@@ -413,8 +413,7 @@ static int bssmap_rcvmsg_udt(struct osmo_msc_data *msc,
ret = bssmap_handle_reset_ack(msc, msg, length);
break;
case BSS_MAP_MSG_PAGING:
- if (bsc_grace_allow_new_connection(msc->network))
- ret = bssmap_handle_paging(msc, msg, length);
+ ret = bssmap_handle_paging(msc, msg, length);
break;
}
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_grace.c b/openbsc/src/osmo-bsc/osmo_bsc_grace.c
index 3f73b5018..341971ef2 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_grace.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_grace.c
@@ -1,6 +1,6 @@
/*
- * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2010 by On-Waves
+ * (C) 2010-2013 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2010-2013 by On-Waves
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@@ -22,15 +22,59 @@
#include <openbsc/osmo_bsc_rf.h>
#include <openbsc/osmo_msc_data.h>
#include <openbsc/gsm_04_80.h>
+#include <openbsc/gsm_subscriber.h>
+#include <openbsc/paging.h>
#include <openbsc/signal.h>
-int bsc_grace_allow_new_connection(struct gsm_network *network)
+int bsc_grace_allow_new_connection(struct gsm_network *network, struct gsm_bts *bts)
{
if (!network->bsc_data->rf_ctrl)
return 1;
+ if (bts->excl_from_rf_lock)
+ return 1;
return network->bsc_data->rf_ctrl->policy == S_RF_ON;
}
+/**
+ * Try to not page if everything the cell is not on.
+ */
+int bsc_grace_paging_request(struct gsm_subscriber *subscr, int chan_needed,
+ struct osmo_msc_data *msc)
+{
+ struct gsm_bts *bts = NULL;
+
+ if (!subscr->net->bsc_data->rf_ctrl)
+ goto page;
+ if (subscr->net->bsc_data->rf_ctrl->policy == S_RF_ON)
+ goto page;
+
+ /*
+ * Check if there is any BTS that is on for the given lac. Start
+ * with NULL and iterate through all bts.
+ */
+ do {
+ bts = gsm_bts_by_lac(subscr->net, subscr->lac, bts);
+ if (!bts)
+ break;
+
+ /*
+ * continue if the BTS is not excluded from the lock
+ */
+ if (!bts->excl_from_rf_lock)
+ continue;
+
+ /*
+ * now page on this bts
+ */
+ paging_request_bts(bts, subscr, chan_needed, NULL, msc);
+ } while (1);
+
+ /* All bts are either off or in the grace period */
+ return 0;
+page:
+ return paging_request(subscr->net, subscr, chan_needed, NULL, msc);
+}
+
static int handle_sub(struct gsm_lchan *lchan, const char *text)
{
struct gsm_subscriber_connection *conn;
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_sccp.c b/openbsc/src/osmo-bsc/osmo_bsc_sccp.c
index 37eb1b799..3533d6df0 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_sccp.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_sccp.c
@@ -190,12 +190,9 @@ int bsc_queue_for_msc(struct osmo_bsc_sccp_con *conn, struct msgb *msg)
int bsc_create_new_connection(struct gsm_subscriber_connection *conn,
struct osmo_msc_data *msc)
{
- struct gsm_network *net;
struct osmo_bsc_sccp_con *bsc_con;
struct sccp_connection *sccp;
- net = conn->bts->network;
-
/* This should not trigger */
if (!msc->msc_con->is_authenticated) {
LOGP(DMSC, LOGL_ERROR,
@@ -203,7 +200,7 @@ int bsc_create_new_connection(struct gsm_subscriber_connection *conn,
return -1;
}
- if (!bsc_grace_allow_new_connection(net)) {
+ if (!bsc_grace_allow_new_connection(conn->bts->network, conn->bts)) {
LOGP(DMSC, LOGL_NOTICE, "BSC in grace period. No new connections.\n");
return -1;
}