diff options
-rw-r--r-- | include/osmo-bts/gsm_data.h | 1 | ||||
-rw-r--r-- | src/common/bts.c | 39 |
2 files changed, 39 insertions, 1 deletions
diff --git a/include/osmo-bts/gsm_data.h b/include/osmo-bts/gsm_data.h index a5ac9e2c..5ca1fe33 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 08a5e24e..3d7cd3f2 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++; |