Compare commits

..

4 Commits

Author SHA1 Message Date
Holger Hans Peter Freyther
ec59bb04df Versioning for the bsc_msc_ip 2010-04-20 18:10:27 +08:00
Holger Hans Peter Freyther
4417f7f477 [vty] Allow to set the RACH NM attributes on a per BTS basis
Be able to tune the RACH settings of the BTS via the vty interface,
by default they are initialized to -1 which means we will use the
content of the static array (BTS default) and can be changed via
the VTY interface. I have verified the setting on the nanoBTS with
wireshark and I have tested writing the config file.
2010-04-20 18:02:25 +08:00
Holger Hans Peter Freyther
39563af27c [paging] Implement the counting for TCH/H and TCH/F
Add some code to count TCH/H and TCH/F and also handle
the neci bit of the network. Our channel allocator will
allocate a TCH/F if we request a TCH/H but can not allocate it.
2010-04-20 17:15:21 +08:00
Holger Hans Peter Freyther
242faaafd1 [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.
2010-04-20 17:10:43 +08:00
6 changed files with 126 additions and 1 deletions

View File

@@ -1,7 +1,7 @@
dnl Process this file with autoconf to produce a configure script
AC_INIT
AM_INIT_AUTOMAKE(openbsc, 0.3.98.2onwaves)
AM_INIT_AUTOMAKE(openbsc, 0.3.99onwaves)
dnl kernel style compile messages
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])

View File

@@ -407,6 +407,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;
};
@@ -522,6 +525,10 @@ struct gsm_bts {
struct gsm_bts_gprs_nsvc nsvc[2];
u_int8_t rac;
} gprs;
/* RACH NM values */
int rach_b_thresh;
int rach_ldavg_slots;
/* transceivers */
int num_trx;

View File

@@ -855,6 +855,22 @@ static void patch_nm_tables(struct gsm_bts *bts)
bs11_attr_radio[2] |= arfcn_high;
bs11_attr_radio[3] = arfcn_low;
/* patch the RACH attributes */
if (bts->rach_b_thresh != -1) {
nanobts_attr_bts[33] = bts->rach_b_thresh & 0xff;
bs11_attr_bts[33] = bts->rach_b_thresh & 0xff;
}
if (bts->rach_ldavg_slots != -1) {
u_int8_t avg_high = bts->rach_ldavg_slots & 0xff;
u_int8_t avg_low = (bts->rach_ldavg_slots >> 8) & 0x0f;
nanobts_attr_bts[35] = avg_high;
nanobts_attr_bts[36] = avg_low;
bs11_attr_bts[35] = avg_high;
bs11_attr_bts[36] = avg_low;
}
/* patch BSIC */
bs11_attr_bts[1] = bts->bsic;
nanobts_attr_bts[sizeof(nanobts_attr_bts)-11] = bts->bsic;

View File

@@ -222,6 +222,10 @@ struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, enum gsm_bts_type type,
}
bts->c0->ts[0].pchan = GSM_PCHAN_CCCH_SDCCH4;
bts->paging.free_chans_need = -1;
bts->rach_b_thresh = -1;
bts->rach_ldavg_slots = -1;
llist_add_tail(&bts->list, &net->bts_list);
return bts;

View File

@@ -118,6 +118,52 @@ 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:
case RSL_CHANNEED_TCH_ForH:
goto count_tch;
break;
case RSL_CHANNEED_SDCCH:
goto count_sdcch;
break;
case RSL_CHANNEED_ANY:
default:
if (bts->network->pag_any_tch)
goto count_tch;
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;
count_tch:
count = 0;
count += pl.pchan[GSM_PCHAN_TCH_F].total
- pl.pchan[GSM_PCHAN_TCH_F].used;
if (bts->network->neci)
count += pl.pchan[GSM_PCHAN_TCH_H].total
- pl.pchan[GSM_PCHAN_TCH_H].used;
return bts->paging.free_chans_need > count;
}
/*
* This is kicked by the periodic PAGING LOAD Indicator
* coming from abis_rsl.c
@@ -154,6 +200,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 +214,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);
}

View File

@@ -350,6 +350,13 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
vty_out(vty, " rach max transmission %u%s",
rach_max_trans_raw2val(bts->si_common.rach_control.max_trans),
VTY_NEWLINE);
if (bts->rach_b_thresh != -1)
vty_out(vty, " rach nm busy threshold %u%s",
bts->rach_b_thresh, VTY_NEWLINE);
if (bts->rach_ldavg_slots != -1)
vty_out(vty, " rach nm load average %u%s",
bts->rach_ldavg_slots, VTY_NEWLINE);
if (bts->si_common.rach_control.cell_bar)
vty_out(vty, " cell barred 1%s", VTY_NEWLINE);
if (is_ipaccess_bts(bts)) {
@@ -360,6 +367,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);
vty_out(vty, " gprs mode %s%s", bts_gprs_mode_name(bts->gprs.mode),
VTY_NEWLINE);
if (bts->gprs.mode != BTS_GPRS_NONE) {
@@ -1599,6 +1611,26 @@ DEFUN(cfg_bts_rach_max_trans,
return CMD_SUCCESS;
}
DEFUN(cfg_bts_rach_nm_b_thresh,
cfg_bts_rach_nm_b_thresh_cmd,
"rach nm busy threshold <0-255>",
"Set the NM Busy Threshold in DB")
{
struct gsm_bts *bts = vty->index;
bts->rach_b_thresh = atoi(argv[0]);
return CMD_SUCCESS;
}
DEFUN(cfg_bts_rach_nm_ldavg,
cfg_bts_rach_nm_ldavg_cmd,
"rach nm load average <0-65535>",
"Set the NM Loadaver Slots value")
{
struct gsm_bts *bts = vty->index;
bts->rach_ldavg_slots = atoi(argv[0]);
return CMD_SUCCESS;
}
DEFUN(cfg_bts_cell_barred, cfg_bts_cell_barred_cmd,
"cell barred (0|1)",
"Should this cell be barred from access?")
@@ -1757,6 +1789,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_rac, cfg_bts_gprs_rac_cmd,
"gprs routing area <0-255>",
"GPRS Routing Area Code")
@@ -2045,6 +2087,8 @@ int bsc_vty_init(struct gsm_network *net)
install_element(BTS_NODE, &cfg_bts_challoc_cmd);
install_element(BTS_NODE, &cfg_bts_rach_tx_integer_cmd);
install_element(BTS_NODE, &cfg_bts_rach_max_trans_cmd);
install_element(BTS_NODE, &cfg_bts_rach_nm_b_thresh_cmd);
install_element(BTS_NODE, &cfg_bts_rach_nm_ldavg_cmd);
install_element(BTS_NODE, &cfg_bts_cell_barred_cmd);
install_element(BTS_NODE, &cfg_bts_ms_max_power_cmd);
install_element(BTS_NODE, &cfg_bts_per_loc_upd_cmd);
@@ -2058,6 +2102,7 @@ int bsc_vty_init(struct gsm_network *net)
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_trx_cmd);
install_node(&trx_node, dummy_config_write);