aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2010-09-06 10:11:25 +0800
committerHolger Hans Peter Freyther <zecke@selfish.org>2010-09-06 10:13:23 +0800
commite66bf1fd465cc5d364d36ee1ea78419e29b2c4f7 (patch)
tree845b65a3653cbcf2e90238462b7c6aa601fa74bf /openbsc
parenteb241aa1d5720a36cf97f29390c2890cf3aecba7 (diff)
[paging] Only page if we have some free channels right now
Only page if we have a load that is acceptable for paging. This option is off by default, and can be enabled per bts. The idea is that when we have no resources right now we will not page as it will only create more RACHs and increase the load. By default we are keeping the old behavior to always page and only by changing a setting one is using the new behavior.
Diffstat (limited to 'openbsc')
-rw-r--r--openbsc/include/openbsc/gsm_data.h3
-rw-r--r--openbsc/src/bsc_vty.c16
-rw-r--r--openbsc/src/gsm_data.c1
-rw-r--r--openbsc/src/paging.c46
4 files changed, 66 insertions, 0 deletions
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index c87a2c116..31e115281 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -455,6 +455,9 @@ struct gsm_bts_paging_state {
struct timer_list work_timer;
struct timer_list credit_timer;
+ /* free chans needed */
+ int free_chans_need;
+
/* load */
u_int16_t available_slots;
};
diff --git a/openbsc/src/bsc_vty.c b/openbsc/src/bsc_vty.c
index 3eb91d8cf..99b050bc6 100644
--- a/openbsc/src/bsc_vty.c
+++ b/openbsc/src/bsc_vty.c
@@ -449,6 +449,11 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
config_write_e1_link(vty, &bts->oml_e1_link, " oml ");
vty_out(vty, " oml e1 tei %u%s", bts->oml_tei, VTY_NEWLINE);
}
+
+ /* if we have a limit, write it */
+ if (bts->paging.free_chans_need >= 0)
+ vty_out(vty, " paging free %d%s", bts->paging.free_chans_need, VTY_NEWLINE);
+
config_write_bts_gprs(vty, bts);
llist_for_each_entry(trx, &bts->trx_list, list)
@@ -1773,6 +1778,16 @@ DEFUN(cfg_bts_gprs_nsvc_rip, cfg_bts_gprs_nsvc_rip_cmd,
return CMD_SUCCESS;
}
+DEFUN(cfg_bts_pag_free, cfg_bts_pag_free_cmd,
+ "paging free FREE_NR",
+ "Only page when having a certain amount of free slots. -1 to disable")
+{
+ struct gsm_bts *bts = vty->index;
+
+ bts->paging.free_chans_need = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
DEFUN(cfg_bts_gprs_ns_timer, cfg_bts_gprs_ns_timer_cmd,
"gprs ns timer " NS_TIMERS " <0-255>",
GPRS_TEXT "Network Service\n"
@@ -2352,6 +2367,7 @@ int bsc_vty_init(void)
install_element(BTS_NODE, &cfg_bts_gprs_nsvc_lport_cmd);
install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rport_cmd);
install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rip_cmd);
+ install_element(BTS_NODE, &cfg_bts_pag_free_cmd);
install_element(BTS_NODE, &cfg_bts_si_mode_cmd);
install_element(BTS_NODE, &cfg_bts_si_static_cmd);
diff --git a/openbsc/src/gsm_data.c b/openbsc/src/gsm_data.c
index 29b6d0722..526b1777f 100644
--- a/openbsc/src/gsm_data.c
+++ b/openbsc/src/gsm_data.c
@@ -239,6 +239,7 @@ struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, enum gsm_bts_type type,
bts->rach_b_thresh = -1;
bts->rach_ldavg_slots = -1;
+ bts->paging.free_chans_need = -1;
llist_add_tail(&bts->list, &net->bts_list);
return bts;
diff --git a/openbsc/src/paging.c b/openbsc/src/paging.c
index a6bc56d2a..bca97cf87 100644
--- a/openbsc/src/paging.c
+++ b/openbsc/src/paging.c
@@ -118,6 +118,45 @@ static void paging_give_credit(void *data)
paging_handle_pending_requests(paging_bts);
}
+static int can_send_pag_req(struct gsm_bts *bts, int rsl_type)
+{
+ struct pchan_load pl;
+ int count;
+
+ memset(&pl, 0, sizeof(pl));
+ bts_chan_load(&pl, bts);
+
+ switch (rsl_type) {
+ case RSL_CHANNEED_TCH_F:
+ LOGP(DPAG, LOGL_ERROR, "Not implemented.\n");
+ break;
+ case RSL_CHANNEED_TCH_ForH:
+ LOGP(DPAG, LOGL_ERROR, "Not implemented.\n");
+ break;
+ case RSL_CHANNEED_SDCCH:
+ goto count_sdcch;
+ break;
+ case RSL_CHANNEED_ANY:
+ default:
+ if (bts->network->pag_any_tch)
+ LOGP(DPAG, LOGL_ERROR, "Not implemented.\n");
+ else
+ goto count_sdcch;
+ break;
+ }
+
+ return 0;
+
+ /* could available SDCCH */
+count_sdcch:
+ count = 0;
+ count += pl.pchan[GSM_PCHAN_SDCCH8_SACCH8C].total
+ - pl.pchan[GSM_PCHAN_SDCCH8_SACCH8C].used;
+ count += pl.pchan[GSM_PCHAN_CCCH_SDCCH4].total
+ - pl.pchan[GSM_PCHAN_CCCH_SDCCH4].used;
+ return bts->paging.free_chans_need > count;
+}
+
/*
* This is kicked by the periodic PAGING LOAD Indicator
* coming from abis_rsl.c
@@ -154,6 +193,12 @@ static void paging_handle_pending_requests(struct gsm_bts_paging_state *paging_b
request = llist_entry(paging_bts->pending_requests.next,
struct gsm_paging_request, entry);
+ /* we need to determine the number of free channels */
+ if (paging_bts->free_chans_need != -1) {
+ if (can_send_pag_req(request->bts, request->chan_type) != 0)
+ goto skip_paging;
+ }
+
/* handle the paging request now */
page_ms(request);
paging_bts->available_slots--;
@@ -162,6 +207,7 @@ static void paging_handle_pending_requests(struct gsm_bts_paging_state *paging_b
llist_del(&request->entry);
llist_add_tail(&request->entry, &paging_bts->pending_requests);
+skip_paging:
bsc_schedule_timer(&paging_bts->work_timer, PAGING_TIMER);
}