aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvan Kluchnikov <kluchnikovi@gmail.com>2014-02-11 02:36:58 +0400
committerIvan Kluchnikov <kluchnikovi@gmail.com>2014-02-11 02:40:01 +0400
commit2c1c652915c06ab53c43bed9eb0644868421297d (patch)
tree7f1f123433e0fa56e08ac363f306e921eb36e58f
parent1e0fca4969a423a6234f6c117bba64d210d5d35f (diff)
bts: Calculate length of agch queuekluchnikov/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.
-rw-r--r--include/osmo-bts/gsm_data.h1
-rw-r--r--src/common/bts.c39
2 files changed, 39 insertions, 1 deletions
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++;