aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc
diff options
context:
space:
mode:
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);
}