Hi all, The attached patches for openbsc and osmo-bts finally fix issues which were discussed above.
There are two parts: 1. Implementation of sending rsl Delete_Ind message (on bts side) and handling it (on bsc side). Bts should send rsl Delete Ind message to bsc, if there is no space in agch queue and bts can not send current imm assign message. When bsc receives Delete_Ind message from bts, bsc should release allocated channel, which was specified in dropped imm_assign message. 2. Implemented calculation of agch queue length. Bts should calculate allowed length of agch queue, because bts should send imm assign message before immediate assignment procedure will be aborted by MS. Imm assign message can be queued no longer than T3126, so agch queue length should be equal (T3126 / 51 ) * bs_ag_blks_res. These patches fix critical issues and prevent network failures under heavy load, so it makes sense to merge them asap. 2013-09-10 16:50 GMT+04:00 Holger Hans Peter Freyther <[email protected]>: > On Tue, Sep 10, 2013 at 02:24:38PM +0400, Alexander Chemeris wrote: >> >> If Andreas don't implement the calculation, we'll go with a manually >> configured limit. Should be fine for most use cases. > > come on, please don't be so lazy. > -- Regards, Ivan Kluchnikov. http://fairwaves.ru
From a0c73d17a396bad27744dc24f95a9c40f03c3d16 Mon Sep 17 00:00:00 2001 From: Ivan Kluchnikov <[email protected]> Date: Tue, 11 Feb 2014 00:21:36 +0400 Subject: [PATCH 1/1] rsl: Implement handling of rsl Delete Ind message If bsc receives Delete_Ind message from bts, bsc should release allocated channel, which was specified in dropped imm_assign message. --- openbsc/src/libbsc/abis_rsl.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/openbsc/src/libbsc/abis_rsl.c b/openbsc/src/libbsc/abis_rsl.c index f53ba84..ae8e0d4 100644 --- a/openbsc/src/libbsc/abis_rsl.c +++ b/openbsc/src/libbsc/abis_rsl.c @@ -1539,6 +1539,25 @@ static int rsl_rx_ccch_load(struct msgb *msg) return 0; } +/* CCCH overloaded, IMM_ASSIGN was dropped */ +static int rsl_rx_delete_ind(struct gsm_bts_trx *trx, struct msgb *msg) +{ + struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg); + struct gsm48_imm_ass *ia; + struct gsm_lchan *lchan; + uint8_t chan_nr; + + /* bts didn't send IMM_ASSIGN, so we should release allocated channel */ + ia = (struct gsm48_imm_ass *) (rqd_hdr->data + 2); + if (ia->msg_type == GSM48_MT_RR_IMM_ASS) { + chan_nr = ia->chan_desc.chan_nr; + lchan = lchan_lookup(trx, chan_nr); + rsl_rf_chan_release(lchan, 1, SACCH_DEACTIVATE); + } + + return 0; +} + static int abis_rsl_rx_cchan(struct msgb *msg) { struct e1inp_sign_link *sign_link = msg->dst; @@ -1558,6 +1577,8 @@ static int abis_rsl_rx_cchan(struct msgb *msg) break; case RSL_MT_DELETE_IND: /* CCCH overloaded, IMM_ASSIGN was dropped */ + rc = rsl_rx_delete_ind(sign_link->trx, msg); + break; case RSL_MT_CBCH_LOAD_IND: /* current load on the CBCH */ LOGP(DRSL, LOGL_NOTICE, "Unimplemented Abis RSL TRX message " -- 1.7.9.5
From 1e0fca4969a423a6234f6c117bba64d210d5d35f Mon Sep 17 00:00:00 2001 From: Ivan Kluchnikov <[email protected]> Date: Tue, 11 Feb 2014 02:13:08 +0400 Subject: [PATCH 1/2] rsl: Send rsl Delete Ind message to bsc, if there is no space in agch queue --- src/common/rsl.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/common/rsl.c b/src/common/rsl.c index ca323c5..8b128ce 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -380,6 +380,21 @@ int rsl_tx_ccch_load_ind_rach(struct gsm_bts *bts, uint16_t total, return abis_bts_rsl_sendmsg(msg); } +/* 8.5.4 DELETE INDICATION */ +int rsl_tx_delete_ind(struct gsm_bts *bts, uint8_t len, uint8_t *val) +{ + struct msgb *msg; + + msg = rsl_msgb_alloc(sizeof(struct abis_rsl_cchan_hdr)); + if (!msg) + return -ENOMEM; + rsl_cch_push_hdr(msg, RSL_MT_DELETE_IND, RSL_CHAN_PCH_AGCH); + msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, len, val); + msg->trx = bts->c0; + + return abis_rsl_sendmsg(msg); +} + /* 8.5.5 PAGING COMMAND */ static int rsl_rx_paging_cmd(struct gsm_bts_trx *trx, struct msgb *msg) { @@ -476,7 +491,8 @@ static int rsl_rx_imm_ass(struct gsm_bts_trx *trx, struct msgb *msg) /* put into the AGCH queue of the BTS */ if (bts_agch_enqueue(trx->bts, msg) < 0) { /* if there is no space in the queue: send DELETE IND */ - msgb_free(msg); + rsl_tx_delete_ind(trx->bts, msg->len, msg->data); + return -ENOMEM; } /* return 1 means: don't msgb_free() the msg */ -- 1.7.9.5
From 2c1c652915c06ab53c43bed9eb0644868421297d Mon Sep 17 00:00:00 2001 From: Ivan Kluchnikov <[email protected]> Date: Tue, 11 Feb 2014 02:36:58 +0400 Subject: [PATCH 2/2] bts: Calculate length of agch queue We should calculate allowed length of agch queue, because bts should send imm assign message before immediate assignment procedure will be aborted by MS. Imm assign message can be queued no longer than T3126, so agch queue length should be equal (T3126 / 51 ) * bs_ag_blks_res. --- include/osmo-bts/gsm_data.h | 1 + src/common/bts.c | 39 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/include/osmo-bts/gsm_data.h b/include/osmo-bts/gsm_data.h index a5ac9e2..5ca1fe3 100644 --- a/include/osmo-bts/gsm_data.h +++ b/include/osmo-bts/gsm_data.h @@ -50,6 +50,7 @@ struct gsm_bts_role_bts { uint8_t max_ta; struct llist_head agch_queue; int agch_queue_count; + uint8_t agch_queue_len; struct paging_state *paging_state; char *bsc_oml_host; unsigned int rtp_jitter_buf_ms; diff --git a/src/common/bts.c b/src/common/bts.c index 08a5e24..3d7cd3f 100644 --- a/src/common/bts.c +++ b/src/common/bts.c @@ -49,6 +49,15 @@ struct gsm_network bts_gsmnet = { .num_bts = 0, }; +/* Table 3.1 TS 04.08: Values of parameter S */ +static const uint8_t tx_integer[] = { + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 20, 25, 32, 50, +}; + +static const uint8_t s_values[][2] = { + { 55, 41 }, { 76, 52 }, { 109, 58 }, { 163, 86 }, { 217, 115 }, +}; + void *tall_bts_ctx; int bts_init(struct gsm_bts *bts) @@ -215,9 +224,37 @@ int lchan_init_lapdm(struct gsm_lchan *lchan) int bts_agch_enqueue(struct gsm_bts *bts, struct msgb *msg) { struct gsm_bts_role_bts *btsb = bts_role_bts(bts); + struct gsm48_system_information_type_3 *si3; + uint8_t T, S, agch_num, i; + uint8_t T_group = 0; + uint8_t ccch_comb = 0; + + /* calculate length of agch queue + agch_queue_len = ( min( T3126 ) / 51 ) * bs_ag_blks_res + min(T3126) = T + 2*S defined in 04.08 11.1.1 + S and T are defined in 04.08 3.3.1.1.2 */ + + si3 = GSM_BTS_SI(bts, SYSINFO_TYPE_3); + T = si3->rach_control.tx_integer; + for (i = 0; i < 15; i++) { + if (tx_integer[i] == T) { + T_group = i % 5; + break; + } + } + if (si3->control_channel_desc.ccch_conf == 1) { + ccch_comb = 1; + } + S = s_values[T_group][ccch_comb]; + agch_num = si3->control_channel_desc.bs_ag_blks_res; - if (btsb->agch_queue_count >= 30) + btsb->agch_queue_len = ((T + 2 * S) / 51) * agch_num; + + if (btsb->agch_queue_count >= btsb->agch_queue_len) { + LOGP(DRSL, LOGL_NOTICE, "AGCH enqueue count = %d >= %d (drop message)\n", + btsb->agch_queue_count, btsb->agch_queue_len); return -ENOMEM; + } msgb_enqueue(&btsb->agch_queue, msg); btsb->agch_queue_count++; -- 1.7.9.5
