From: Sylvain Munaut tnt@246tNt.com
If a RF channel is assigned but no response is ever heard from the phone, we will receive a CONNECTION FAIL from the BTS, triggering a RF release freeing the channel. Then sometime later, T3101 will expire as well and free the channel again ...
Signed-off-by: Sylvain Munaut tnt@246tNt.com --- openbsc/src/chan_alloc.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/openbsc/src/chan_alloc.c b/openbsc/src/chan_alloc.c index 786e8b1..a23192a 100644 --- a/openbsc/src/chan_alloc.c +++ b/openbsc/src/chan_alloc.c @@ -251,6 +251,7 @@ void lchan_free(struct gsm_lchan *lchan)
/* stop the timer */ bsc_del_timer(&lchan->release_timer); + bsc_del_timer(&lchan->T3101);
/* clear cached measuement reports */ lchan->meas_rep_idx = 0;
From: Sylvain Munaut tnt@246tNt.com
Tweaking theses can be useful especially tx-integer that influence both the spread of rach attemps and the delay between two attemps.
Looking up GSM 04.08 3.3.1.1.2 & 10.5.2.29 can help determine good values. The default are choosed with a wide spacing between attemps (tx integer = 9 -> T=12 & S=217 (non-combined CCCH/SDCCH) or 115 (for combined CCCH/SDCCH)). This alleviates the problem of responding to several RACH attempts by a same MS, allocating several RF channels when only 1 is needed.
Signed-off-by: Sylvain Munaut tnt@246tNt.com --- openbsc/include/openbsc/gsm_data.h | 4 ++++ openbsc/include/openbsc/gsm_utils.h | 7 +++++++ openbsc/src/bsc_init.c | 4 ++-- openbsc/src/gsm_data.c | 2 ++ openbsc/src/vty_interface.c | 24 ++++++++++++++++++++++++ 5 files changed, 39 insertions(+), 2 deletions(-)
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index f4e4d21..bc1dbe6 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -451,6 +451,10 @@ struct gsm_network { enum gsm48_reject_value reject_cause; int a5_encryption; int neci; + struct { + int tx_integer; + int max_retrans; + } rach; int send_mm_info; struct { int active; diff --git a/openbsc/include/openbsc/gsm_utils.h b/openbsc/include/openbsc/gsm_utils.h index 5809221..80fe12f 100644 --- a/openbsc/include/openbsc/gsm_utils.h +++ b/openbsc/include/openbsc/gsm_utils.h @@ -37,5 +37,12 @@ int ms_pwr_dbm(enum gsm_band band, u_int8_t lvl); int rxlev2dbm(u_int8_t rxlev); u_int8_t dbm2rxlev(int dbm);
+/* According to GSM 04.08 Chapter 10.5.2.29 */ +static inline int rach_max_retrans_val2raw(int val) { return (val >> 1) & 3; } +static inline int rach_max_retrans_raw2val(int raw) { + const int tbl[4] = { 1, 2, 4, 7 }; + return tbl[raw & 3]; +} + void generate_backtrace(); #endif diff --git a/openbsc/src/bsc_init.c b/openbsc/src/bsc_init.c index ae6f163..0e6e3dc 100644 --- a/openbsc/src/bsc_init.c +++ b/openbsc/src/bsc_init.c @@ -823,8 +823,8 @@ static int bootstrap_bts(struct gsm_bts *bts)
/* some defaults for our system information */ bts->si_common.rach_control.re = 1; /* no re-establishment */ - bts->si_common.rach_control.tx_integer = 5; /* 8 slots spread */ - bts->si_common.rach_control.max_trans = 3; /* 7 retransmissions */ + bts->si_common.rach_control.tx_integer = bts->network->rach.tx_integer; + bts->si_common.rach_control.max_trans = bts->network->rach.max_retrans; bts->si_common.rach_control.t2 = 4; /* no emergency calls */
bts->si_common.cell_options.radio_link_timeout = 2; /* 12 */ diff --git a/openbsc/src/gsm_data.c b/openbsc/src/gsm_data.c index 94ed91b..a4a4fb7 100644 --- a/openbsc/src/gsm_data.c +++ b/openbsc/src/gsm_data.c @@ -206,6 +206,8 @@ struct gsm_network *gsm_network_init(u_int16_t country_code, u_int16_t network_c net->country_code = country_code; net->network_code = network_code; net->num_bts = 0; + net->rach.max_retrans = 3; /* 7 retransmissions */ + net->rach.tx_integer = 9; /* 12 slots spread - 217/115 slots delay */ net->T3101 = GSM_T3101_DEFAULT; net->T3113 = GSM_T3113_DEFAULT; /* FIXME: initialize all other timers! */ diff --git a/openbsc/src/vty_interface.c b/openbsc/src/vty_interface.c index 20df909..9dc7253 100644 --- a/openbsc/src/vty_interface.c +++ b/openbsc/src/vty_interface.c @@ -91,6 +91,10 @@ static void net_dump_vty(struct vty *vty, struct gsm_network *net) VTY_NEWLINE); vty_out(vty, " NECI (TCH/H): %u%s", net->neci, VTY_NEWLINE); + vty_out(vty, " RACH TX-Integer: %u%s", net->rach.tx_integer, + VTY_NEWLINE); + vty_out(vty, " RACH Max retransmissions: %u%s", rach_max_retrans_raw2val(net->rach.max_retrans), + VTY_NEWLINE); vty_out(vty, " RRLP Mode: %s%s", rrlp_mode_name(net->rrlp.mode), VTY_NEWLINE); vty_out(vty, " MM Info: %s%s", net->send_mm_info ? "On" : "Off", @@ -295,6 +299,8 @@ static int config_write_net(struct vty *vty) gsmnet->reject_cause, VTY_NEWLINE); vty_out(vty, " encryption a5 %u%s", gsmnet->a5_encryption, VTY_NEWLINE); vty_out(vty, " neci %u%s", gsmnet->neci, VTY_NEWLINE); + vty_out(vty, " rach tx integer %u%s", gsmnet->rach.tx_integer, VTY_NEWLINE); + vty_out(vty, " rach max retransmission %u%s", rach_max_retrans_raw2val(gsmnet->rach.max_retrans), VTY_NEWLINE); vty_out(vty, " rrlp mode %s%s", rrlp_mode_name(gsmnet->rrlp.mode), VTY_NEWLINE); vty_out(vty, " mm info %u%s", gsmnet->send_mm_info, VTY_NEWLINE); @@ -848,6 +854,24 @@ DEFUN(cfg_net_neci, return CMD_SUCCESS; }
+DEFUN(cfg_net_rach_tx_integer, + cfg_net_rach_tx_integer_cmd, + "rach tx integer <0-15>", + "Set the raw tx integer value in RACH Control parameters IE") +{ + gsmnet->rach.tx_integer = atoi(argv[0]) & 0xf; + return CMD_SUCCESS; +} + +DEFUN(cfg_net_rach_max_retransmission, + cfg_net_rach_max_retransmission_cmd, + "rach max retransmission (1|2|4|7)", + "Set the maximum number of RACH burst retransmissions") +{ + gsmnet->rach.max_retrans = rach_max_retrans_val2raw(atoi(argv[0])); + return CMD_SUCCESS; +} + DEFUN(cfg_net_rrlp_mode, cfg_net_rrlp_mode_cmd, "rrlp mode (none|ms-based|ms-preferred|ass-preferred)", "Set the Radio Resource Location Protocol Mode")
From: Sylvain Munaut tnt@246tNt.com
The previous implementation had some shortcomings: - If the MIN ID given was not the exact id of the first unsent SMS, it would try to submit the same sms several time until id++ finally made id go to the next one. - If a subscriber had several SMS pending it would try to submit them individually (only to get rejected because a paging for that subscriber was already in progress)
Signed-off-by: Sylvain Munaut tnt@246tNt.com --- openbsc/src/db.c | 27 +++++++++++++++++++++++++++ openbsc/src/vty_interface_layer3.c | 17 +++++++---------- 2 files changed, 34 insertions(+), 10 deletions(-)
diff --git a/openbsc/src/db.c b/openbsc/src/db.c index ebfe923..b796350 100644 --- a/openbsc/src/db.c +++ b/openbsc/src/db.c @@ -788,6 +788,33 @@ struct gsm_sms *db_sms_get_unsent(struct gsm_network *net, int min_id) return sms; }
+struct gsm_sms *db_sms_get_unsent_by_subscr(struct gsm_network *net, int min_subscr_id) +{ + dbi_result result; + struct gsm_sms *sms; + + result = dbi_conn_queryf(conn, + "SELECT * FROM SMS,Subscriber " + "WHERE sms.receiver_id >= %llu AND sms.sent is NULL " + "AND sms.receiver_id = subscriber.id " + "AND subscriber.lac > 0 " + "ORDER BY sms.receiver_id, id LIMIT 1", + min_subscr_id); + if (!result) + return NULL; + + if (!dbi_result_next_row(result)) { + dbi_result_free(result); + return NULL; + } + + sms = sms_from_result(net, result); + + dbi_result_free(result); + + return sms; +} + /* retrieve the next unsent SMS for a given subscriber */ struct gsm_sms *db_sms_get_unsent_for_subscr(struct gsm_subscriber *subscr) { diff --git a/openbsc/src/vty_interface_layer3.c b/openbsc/src/vty_interface_layer3.c index 4cc08c2..70e8445 100644 --- a/openbsc/src/vty_interface_layer3.c +++ b/openbsc/src/vty_interface_layer3.c @@ -143,23 +143,20 @@ DEFUN(show_subscr_cache,
DEFUN(sms_send_pend, sms_send_pend_cmd, - "sms send pending MIN_ID", - "Send all pending SMS starting from MIN_ID") + "sms send pending", + "Send all pending SMS") { struct gsm_sms *sms; - int id = atoi(argv[0]); + int id = 0;
while (1) { - sms = db_sms_get_unsent(gsmnet, id++); + sms = db_sms_get_unsent_by_subscr(gsmnet, id); if (!sms) - return CMD_WARNING; - - if (!sms->receiver) { - sms_free(sms); - continue; - } + break;
gsm411_send_sms_subscr(sms->receiver, sms); + + id = sms->receiver->id + 1; }
return CMD_SUCCESS;
thanks, applied.
Hi Sylvain,
Tweaking theses can be useful especially tx-integer that influence both the spread of rach attemps and the delay between two attemps.
I like the idea of making this configurable, and yes our defaults are probably not all that great.
However, I think those parameters are inherently an attribute of the BTS, not the network.
So if you don't mind, please re-submit with adding the same data to the struct gsm_bts rather the struct gsm_network (and of course also move the vty parameters to the bts section).
On Sun, Dec 20, 2009 at 06:16:44PM +0100, Sylvain Munaut wrote:
If a RF channel is assigned but no response is ever heard from the phone, we will receive a CONNECTION FAIL from the BTS, triggering a RF release freeing the channel. Then sometime later, T3101 will expire as well and free the channel again ...
Thanks, applied.