blob: 339390b29c022ddaca74f8d424c17dac543ad649 [file] [log] [blame]
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01001/*
2 * TbfTest.cpp
3 *
4 * Copyright (C) 2013 by Holger Hans Peter Freyther
5 *
6 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Affero General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU Affero General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23#include "bts.h"
24#include "tbf.h"
25#include "gprs_debug.h"
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +010026#include "pcu_utils.h"
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020027#include "gprs_bssgp_pcu.h"
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +020028#include "pcu_l1_if.h"
aravind sirsikarf2761382016-10-25 12:45:24 +053029#include "decoding.h"
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010030
31extern "C" {
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020032#include "pcu_vty.h"
33
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010034#include <osmocom/core/application.h>
35#include <osmocom/core/msgb.h>
36#include <osmocom/core/talloc.h>
37#include <osmocom/core/utils.h>
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020038#include <osmocom/vty/vty.h>
Aravind Sirsikar505a86d2016-07-26 18:26:21 +053039#include <osmocom/gprs/protocol/gsm_04_60.h>
bhargava959d1de2016-08-17 15:17:21 +053040#include <osmocom/gsm/l1sap.h>
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010041}
42
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020043#include <errno.h>
44
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010045void *tall_pcu_ctx;
46int16_t spoof_mnc = 0, spoof_mcc = 0;
47
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +010048static void check_tbf(gprs_rlcmac_tbf *tbf)
49{
50 OSMO_ASSERT(tbf);
Jacob Erlbeck04e72d32015-08-13 18:36:56 +020051 if (tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE))
52 OSMO_ASSERT(tbf->T == 3191 || tbf->T == 3193);
53 if (tbf->state_is(GPRS_RLCMAC_RELEASING))
54 OSMO_ASSERT(tbf->T != 0);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +010055}
56
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +020057/*
58static unsigned inc_fn(fn)
59{
60 unsigned next_fn;
61
62 next_fn = fn + 4;
63 if ((block_nr % 3) == 2)
64 next_fn ++;
65 next_fn = next_fn % 2715648;
66
67 return next_fn;
68}
69*/
70
Jacob Erlbeckac89a552015-06-29 14:18:46 +020071static void test_tbf_base()
72{
73
74 printf("=== start %s ===\n", __func__);
75
76 OSMO_ASSERT(GPRS_RLCMAC_DL_TBF == reverse(GPRS_RLCMAC_UL_TBF));
77 OSMO_ASSERT(GPRS_RLCMAC_UL_TBF == reverse(GPRS_RLCMAC_DL_TBF));
78
79 printf("=== end %s ===\n", __func__);
80}
81
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010082static void test_tbf_tlli_update()
83{
84 BTS the_bts;
Jacob Erlbeck93990462015-05-15 15:50:43 +020085 GprsMs *ms, *ms_new;
86
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +010087 printf("=== start %s ===\n", __func__);
88
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010089 the_bts.bts_data()->alloc_algorithm = alloc_algorithm_a;
90 the_bts.bts_data()->trx[0].pdch[2].enable();
91 the_bts.bts_data()->trx[0].pdch[3].enable();
92
93 /*
94 * Make a uplink and downlink allocation
95 */
Daniel Willmann48aa0b02014-07-16 18:54:10 +020096 gprs_rlcmac_tbf *dl_tbf = tbf_alloc_dl_tbf(the_bts.bts_data(),
Jacob Erlbeck5879c642015-07-10 10:41:36 +020097 NULL,
Jacob Erlbeck86b6f052015-11-27 15:17:34 +010098 0, 0, 0, 0);
Jacob Erlbeckc6d4cee2015-06-29 13:03:46 +020099 OSMO_ASSERT(dl_tbf != NULL);
Jacob Erlbeckbe0cbc12015-05-18 14:35:11 +0200100 dl_tbf->update_ms(0x2342, GPRS_RLCMAC_DL_TBF);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200101 dl_tbf->set_ta(4);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100102
Daniel Willmann48aa0b02014-07-16 18:54:10 +0200103 gprs_rlcmac_tbf *ul_tbf = tbf_alloc_ul_tbf(the_bts.bts_data(),
Jacob Erlbeck5879c642015-07-10 10:41:36 +0200104 dl_tbf->ms(),
Jacob Erlbeck86b6f052015-11-27 15:17:34 +0100105 0, 0, 0, 0);
Jacob Erlbeckc6d4cee2015-06-29 13:03:46 +0200106 OSMO_ASSERT(ul_tbf != NULL);
Jacob Erlbeck0e50ce62015-05-21 16:58:22 +0200107 ul_tbf->update_ms(0x2342, GPRS_RLCMAC_UL_TBF);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100108
Jacob Erlbeck93990462015-05-15 15:50:43 +0200109 ms = the_bts.ms_by_tlli(0x2342);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100110
Jacob Erlbeck93990462015-05-15 15:50:43 +0200111 OSMO_ASSERT(ms != NULL);
112 OSMO_ASSERT(ms->dl_tbf() == dl_tbf);
113 OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100114
115 /*
116 * Now check.. that DL changes and that the timing advance
117 * has changed.
118 */
Jacob Erlbeck0e50ce62015-05-21 16:58:22 +0200119 dl_tbf->update_ms(0x4232, GPRS_RLCMAC_DL_TBF);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100120
Jacob Erlbeck93990462015-05-15 15:50:43 +0200121 /* It is still there, since the new TLLI has not been used for UL yet */
122 ms_new = the_bts.ms_by_tlli(0x2342);
123 OSMO_ASSERT(ms == ms_new);
124
125 ms_new = the_bts.ms_by_tlli(0x4232);
126 OSMO_ASSERT(ms == ms_new);
127 OSMO_ASSERT(ms->dl_tbf() == dl_tbf);
128 OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
129
130 /* Now use the new TLLI for UL */
Jacob Erlbeck0e50ce62015-05-21 16:58:22 +0200131 ul_tbf->update_ms(0x4232, GPRS_RLCMAC_UL_TBF);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200132 ms_new = the_bts.ms_by_tlli(0x2342);
133 OSMO_ASSERT(ms_new == NULL);
Holger Hans Peter Freytherbc1626e2013-10-30 19:50:49 +0100134
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200135 ms_new = the_bts.ms_by_tlli(0x4232);
136 OSMO_ASSERT(ms_new != NULL);
137 OSMO_ASSERT(ms_new->ta() == 4);
138
139 OSMO_ASSERT(ul_tbf->ta() == 4);
140 OSMO_ASSERT(dl_tbf->ta() == 4);
141
142 ul_tbf->set_ta(6);
143
144 OSMO_ASSERT(ul_tbf->ta() == 6);
145 OSMO_ASSERT(dl_tbf->ta() == 6);
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100146
147 printf("=== end %s ===\n", __func__);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100148}
149
Daniel Willmann510d7d32014-08-15 18:19:41 +0200150static uint8_t llc_data[200];
151
152int pcu_sock_send(struct msgb *msg)
153{
154 return 0;
155}
156
Jacob Erlbecka700dd92015-06-02 16:00:41 +0200157static void setup_bts(BTS *the_bts, uint8_t ts_no, uint8_t cs = 1)
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100158{
159 gprs_rlcmac_bts *bts;
160 gprs_rlcmac_trx *trx;
161
162 bts = the_bts->bts_data();
163 bts->alloc_algorithm = alloc_algorithm_a;
Jacob Erlbecka700dd92015-06-02 16:00:41 +0200164 bts->initial_cs_dl = cs;
165 bts->initial_cs_ul = cs;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100166 trx = &bts->trx[0];
167
168 trx->pdch[ts_no].enable();
169}
170
171static gprs_rlcmac_dl_tbf *create_dl_tbf(BTS *the_bts, uint8_t ms_class,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +0100172 uint8_t egprs_ms_class, uint8_t *trx_no_)
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100173{
174 gprs_rlcmac_bts *bts;
175 int tfi;
176 uint8_t trx_no;
177
178 gprs_rlcmac_dl_tbf *dl_tbf;
179
180 bts = the_bts->bts_data();
181
182 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_DL_TBF, &trx_no, -1);
183 OSMO_ASSERT(tfi >= 0);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +0100184 dl_tbf = tbf_alloc_dl_tbf(bts, NULL, trx_no, ms_class, egprs_ms_class, 1);
Max9bbe1602016-07-18 12:50:18 +0200185 dl_tbf->set_ta(0);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100186 check_tbf(dl_tbf);
187
188 /* "Establish" the DL TBF */
189 dl_tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_SEND_ASS;
190 dl_tbf->set_state(GPRS_RLCMAC_FLOW);
191 dl_tbf->m_wait_confirm = 0;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100192 check_tbf(dl_tbf);
193
194 *trx_no_ = trx_no;
195
196 return dl_tbf;
197}
198
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200199static unsigned fn2bn(unsigned fn)
200{
201 return (fn % 52) / 4;
202}
203
204static unsigned fn_add_blocks(unsigned fn, unsigned blocks)
205{
206 unsigned bn = fn2bn(fn) + blocks;
207 fn = fn - (fn % 52);
208 fn += bn * 4 + bn / 3;
209 return fn % 2715648;
210}
211
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200212static void request_dl_rlc_block(struct gprs_rlcmac_bts *bts,
Max878bd1f2016-07-20 13:05:05 +0200213 uint8_t trx_no, uint8_t ts_no,
Jacob Erlbeckee310902015-08-24 11:55:17 +0200214 uint32_t *fn, uint8_t *block_nr = NULL)
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100215{
Jacob Erlbeckee310902015-08-24 11:55:17 +0200216 uint8_t bn = fn2bn(*fn);
Max878bd1f2016-07-20 13:05:05 +0200217 gprs_rlcmac_rcv_rts_block(bts, trx_no, ts_no, *fn, bn);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200218 *fn = fn_add_blocks(*fn, 1);
Jacob Erlbeckee310902015-08-24 11:55:17 +0200219 bn += 1;
220 if (block_nr)
221 *block_nr = bn;
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100222}
223
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200224static void request_dl_rlc_block(struct gprs_rlcmac_tbf *tbf,
Jacob Erlbeckee310902015-08-24 11:55:17 +0200225 uint32_t *fn, uint8_t *block_nr = NULL)
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200226{
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200227 request_dl_rlc_block(tbf->bts->bts_data(), tbf->trx->trx_no,
Max878bd1f2016-07-20 13:05:05 +0200228 tbf->control_ts, fn, block_nr);
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200229}
230
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100231enum test_tbf_final_ack_mode {
232 TEST_MODE_STANDARD,
233 TEST_MODE_REVERSE_FREE
234};
235
236static void test_tbf_final_ack(enum test_tbf_final_ack_mode test_mode)
Daniel Willmann510d7d32014-08-15 18:19:41 +0200237{
238 BTS the_bts;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100239 uint8_t ts_no = 4;
240 unsigned i;
Daniel Willmann510d7d32014-08-15 18:19:41 +0200241 uint8_t ms_class = 45;
242 uint32_t fn;
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100243 uint8_t block_nr;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100244 uint8_t trx_no;
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200245 GprsMs *ms;
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200246 uint32_t tlli = 0xffeeddcc;
Daniel Willmann510d7d32014-08-15 18:19:41 +0200247
248 uint8_t rbb[64/8];
249
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100250 printf("=== start %s ===\n", __func__);
251
Daniel Willmann510d7d32014-08-15 18:19:41 +0200252 gprs_rlcmac_dl_tbf *dl_tbf;
253 gprs_rlcmac_tbf *new_tbf;
254
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100255 setup_bts(&the_bts, ts_no);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +0100256 dl_tbf = create_dl_tbf(&the_bts, ms_class, 0, &trx_no);
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200257 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200258 ms = dl_tbf->ms();
Daniel Willmann510d7d32014-08-15 18:19:41 +0200259
260 for (i = 0; i < sizeof(llc_data); i++)
261 llc_data[i] = i%256;
262
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100263 /* Schedule two LLC frames */
Daniel Willmann0f58af62014-09-19 11:57:21 +0200264 dl_tbf->append_data(ms_class, 1000, llc_data, sizeof(llc_data));
265 dl_tbf->append_data(ms_class, 1000, llc_data, sizeof(llc_data));
Daniel Willmann510d7d32014-08-15 18:19:41 +0200266
267
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100268 /* Send only a few RLC/MAC blocks */
Daniel Willmann510d7d32014-08-15 18:19:41 +0200269 fn = 0;
Jacob Erlbeckee310902015-08-24 11:55:17 +0200270 do {
Daniel Willmann510d7d32014-08-15 18:19:41 +0200271 /* Request to send one block */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200272 request_dl_rlc_block(dl_tbf, &fn, &block_nr);
Jacob Erlbeckee310902015-08-24 11:55:17 +0200273 } while (block_nr < 3);
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200274
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100275 OSMO_ASSERT(dl_tbf->have_data());
276 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
Daniel Willmann510d7d32014-08-15 18:19:41 +0200277
278 /* Queue a final ACK */
279 memset(rbb, 0, sizeof(rbb));
280 /* Receive a final ACK */
281 dl_tbf->rcvd_dl_ack(1, 1, rbb);
282
283 /* Clean up and ensure tbfs are in the correct state */
284 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200285 new_tbf = ms->dl_tbf();
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100286 check_tbf(new_tbf);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200287 OSMO_ASSERT(new_tbf != dl_tbf);
288 OSMO_ASSERT(new_tbf->tfi() == 1);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100289 check_tbf(dl_tbf);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200290 dl_tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE;
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100291 if (test_mode == TEST_MODE_REVERSE_FREE) {
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200292 GprsMs::Guard guard(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100293 tbf_free(new_tbf);
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200294 OSMO_ASSERT(ms->dl_tbf() == NULL);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100295 check_tbf(dl_tbf);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100296 tbf_free(dl_tbf);
297 } else {
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200298 GprsMs::Guard guard(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100299 tbf_free(dl_tbf);
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200300 OSMO_ASSERT(ms->dl_tbf() == new_tbf);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100301 check_tbf(new_tbf);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100302 tbf_free(new_tbf);
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200303 OSMO_ASSERT(ms->dl_tbf() == NULL);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100304 }
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100305
306 printf("=== end %s ===\n", __func__);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200307}
308
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100309static void test_tbf_delayed_release()
310{
311 BTS the_bts;
312 gprs_rlcmac_bts *bts;
313 uint8_t ts_no = 4;
314 unsigned i;
315 uint8_t ms_class = 45;
316 uint32_t fn = 0;
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100317 uint8_t trx_no;
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200318 uint32_t tlli = 0xffeeddcc;
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100319
320 uint8_t rbb[64/8];
321
322 gprs_rlcmac_dl_tbf *dl_tbf;
323
324 printf("=== start %s ===\n", __func__);
325
326 bts = the_bts.bts_data();
327
328 setup_bts(&the_bts, ts_no);
329 bts->dl_tbf_idle_msec = 200;
330
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +0100331 dl_tbf = create_dl_tbf(&the_bts, ms_class, 0, &trx_no);
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200332 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100333
334 for (i = 0; i < sizeof(llc_data); i++)
335 llc_data[i] = i%256;
336
337 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
338
339 /* Schedule two LLC frames */
340 dl_tbf->append_data(ms_class, 1000, llc_data, sizeof(llc_data));
341 dl_tbf->append_data(ms_class, 1000, llc_data, sizeof(llc_data));
342
343 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
344
345 /* Drain the queue */
346 while (dl_tbf->have_data())
347 /* Request to send one RLC/MAC block */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200348 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100349
350 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
351
352 /* ACK all blocks */
353 memset(rbb, 0xff, sizeof(rbb));
354 /* Receive an ACK */
355 dl_tbf->rcvd_dl_ack(0, dl_tbf->m_window.v_s(), rbb);
356 OSMO_ASSERT(dl_tbf->m_window.window_empty());
357
358 /* Force sending of a single block containing an LLC dummy command */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200359 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100360
361 /* Receive an ACK */
362 dl_tbf->rcvd_dl_ack(0, dl_tbf->m_window.v_s(), rbb);
363 OSMO_ASSERT(dl_tbf->m_window.window_empty());
364
365 /* Timeout (make sure fn % 52 remains valid) */
366 fn += 52 * ((msecs_to_frames(bts->dl_tbf_idle_msec + 100) + 51)/ 52);
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200367 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100368
369 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FINISHED));
370
371 /* Receive a final ACK */
372 dl_tbf->rcvd_dl_ack(1, dl_tbf->m_window.v_s(), rbb);
373
374 /* Clean up and ensure tbfs are in the correct state */
375 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100376 dl_tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE;
377 check_tbf(dl_tbf);
378 tbf_free(dl_tbf);
379 printf("=== end %s ===\n", __func__);
380}
381
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200382static void test_tbf_imsi()
383{
384 BTS the_bts;
385 uint8_t ts_no = 4;
386 uint8_t ms_class = 45;
387 uint8_t trx_no;
388 GprsMs *ms1, *ms2;
389
390 gprs_rlcmac_dl_tbf *dl_tbf[2];
391
392 printf("=== start %s ===\n", __func__);
393
394 setup_bts(&the_bts, ts_no);
395
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +0100396 dl_tbf[0] = create_dl_tbf(&the_bts, ms_class, 0, &trx_no);
397 dl_tbf[1] = create_dl_tbf(&the_bts, ms_class, 0, &trx_no);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200398
399 dl_tbf[0]->update_ms(0xf1000001, GPRS_RLCMAC_DL_TBF);
400 dl_tbf[1]->update_ms(0xf1000002, GPRS_RLCMAC_DL_TBF);
401
402 dl_tbf[0]->assign_imsi("001001000000001");
403 ms1 = the_bts.ms_store().get_ms(0, 0, "001001000000001");
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200404 OSMO_ASSERT(ms1 != NULL);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200405 ms2 = the_bts.ms_store().get_ms(0xf1000001);
406 OSMO_ASSERT(ms2 != NULL);
407 OSMO_ASSERT(strcmp(ms2->imsi(), "001001000000001") == 0);
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200408 OSMO_ASSERT(ms1 == ms2);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200409
410 /* change the IMSI on TBF 0 */
411 dl_tbf[0]->assign_imsi("001001000000002");
412 ms1 = the_bts.ms_store().get_ms(0, 0, "001001000000001");
413 OSMO_ASSERT(ms1 == NULL);
414 ms1 = the_bts.ms_store().get_ms(0, 0, "001001000000002");
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200415 OSMO_ASSERT(ms1 != NULL);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200416 OSMO_ASSERT(strcmp(ms2->imsi(), "001001000000002") == 0);
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200417 OSMO_ASSERT(ms1 == ms2);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200418
419 /* use the same IMSI on TBF 2 */
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200420 {
421 GprsMs::Guard guard(ms2);
422 dl_tbf[1]->assign_imsi("001001000000002");
423 ms1 = the_bts.ms_store().get_ms(0, 0, "001001000000002");
424 OSMO_ASSERT(ms1 != NULL);
425 OSMO_ASSERT(ms1 != ms2);
426 OSMO_ASSERT(strcmp(ms1->imsi(), "001001000000002") == 0);
427 OSMO_ASSERT(strcmp(ms2->imsi(), "") == 0);
428 }
429
430 ms2 = the_bts.ms_store().get_ms(0xf1000001);
431 OSMO_ASSERT(ms2 == NULL);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200432
433 tbf_free(dl_tbf[1]);
434 ms1 = the_bts.ms_store().get_ms(0, 0, "001001000000002");
435 OSMO_ASSERT(ms1 == NULL);
436
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200437 printf("=== end %s ===\n", __func__);
438}
439
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200440static void test_tbf_exhaustion()
441{
442 BTS the_bts;
443 gprs_rlcmac_bts *bts;
444 unsigned i;
445 uint8_t ts_no = 4;
446 uint8_t ms_class = 45;
447 int rc = 0;
448
449 uint8_t buf[256] = {0};
450
451 printf("=== start %s ===\n", __func__);
452
453 bts = the_bts.bts_data();
454 setup_bts(&the_bts, ts_no);
455 gprs_bssgp_create_and_connect(bts, 33001, 0, 33001,
456 1234, 1234, 1234, 1, 1, 0, 0, 0);
457
458 for (i = 0; i < 1024; i++) {
459 uint32_t tlli = 0xc0000000 + i;
460 char imsi[16] = {0};
461 unsigned delay_csec = 1000;
462
Jacob Erlbeck9a2845d2015-05-21 12:06:58 +0200463 snprintf(imsi, sizeof(imsi), "001001%09d", i);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200464
Jacob Erlbeck14e00f82015-11-27 18:10:39 +0100465 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200466 delay_csec, buf, sizeof(buf));
467
468 if (rc < 0)
469 break;
470 }
471
472 OSMO_ASSERT(rc == -EBUSY);
473 printf("=== end %s ===\n", __func__);
474
475 gprs_bssgp_destroy();
476}
477
Jacob Erlbeck41168642015-06-12 13:41:00 +0200478static void test_tbf_dl_llc_loss()
479{
480 BTS the_bts;
481 gprs_rlcmac_bts *bts;
482 uint8_t ts_no = 4;
483 uint8_t ms_class = 45;
484 int rc = 0;
485 uint32_t tlli = 0xc0123456;
486 const char *imsi = "001001000123456";
487 unsigned delay_csec = 1000;
488 GprsMs *ms;
489
490 uint8_t buf[19];
491
492 printf("=== start %s ===\n", __func__);
493
494 bts = the_bts.bts_data();
495 setup_bts(&the_bts, ts_no);
496 bts->ms_idle_sec = 10; /* keep the MS object */
497
498 gprs_bssgp_create_and_connect(bts, 33001, 0, 33001,
499 1234, 1234, 1234, 1, 1, 0, 0, 0);
500
501 /* Handle LLC frame 1 */
502 memset(buf, 1, sizeof(buf));
Jacob Erlbeck14e00f82015-11-27 18:10:39 +0100503 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200504 delay_csec, buf, sizeof(buf));
505 OSMO_ASSERT(rc >= 0);
506
507 ms = the_bts.ms_store().get_ms(0, 0, imsi);
508 OSMO_ASSERT(ms != NULL);
509 OSMO_ASSERT(ms->dl_tbf() != NULL);
Max9bbe1602016-07-18 12:50:18 +0200510 ms->dl_tbf()->set_ta(0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200511
512 /* Handle LLC frame 2 */
513 memset(buf, 2, sizeof(buf));
Jacob Erlbeck14e00f82015-11-27 18:10:39 +0100514 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200515 delay_csec, buf, sizeof(buf));
516 OSMO_ASSERT(rc >= 0);
517
518 /* TBF establishment fails (timeout) */
519 tbf_free(ms->dl_tbf());
520
521 /* Handle LLC frame 3 */
522 memset(buf, 3, sizeof(buf));
Jacob Erlbeck14e00f82015-11-27 18:10:39 +0100523 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200524 delay_csec, buf, sizeof(buf));
525 OSMO_ASSERT(rc >= 0);
526
527 OSMO_ASSERT(ms->dl_tbf() != NULL);
528
529 /* Get first BSN */
530 struct msgb *msg;
531 int fn = 0;
532 uint8_t expected_data = 1;
533
534 while (ms->dl_tbf()->have_data()) {
535 msg = ms->dl_tbf()->create_dl_acked_block(fn += 4, 7);
536 fprintf(stderr, "MSG = %s\n", msgb_hexdump(msg));
537 OSMO_ASSERT(msgb_length(msg) == 23);
Jacob Erlbeck409efa12015-06-12 14:06:09 +0200538 OSMO_ASSERT(msgb_data(msg)[10] == expected_data);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200539 expected_data += 1;
540 }
Jacob Erlbeck409efa12015-06-12 14:06:09 +0200541 OSMO_ASSERT(expected_data-1 == 3);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200542
543 printf("=== end %s ===\n", __func__);
544
545 gprs_bssgp_destroy();
546}
547
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200548static gprs_rlcmac_ul_tbf *establish_ul_tbf_single_phase(BTS *the_bts,
549 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta)
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200550{
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200551 GprsMs *ms;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200552 int tfi = 0;
553 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200554 uint8_t trx_no = 0;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200555 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeck20f6fd12015-06-08 11:05:45 +0200556 struct pcu_l1_meas meas;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200557
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200558 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200559
bhargava959d1de2016-08-17 15:17:21 +0530560 the_bts->rcv_rach(0x03, *fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200561
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200562 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200563 OSMO_ASSERT(ul_tbf != NULL);
564
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200565 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200566
567 uint8_t data_msg[23] = {
568 0x00, /* GPRS_RLCMAC_DATA_BLOCK << 6 */
569 uint8_t(1 | (tfi << 2)),
570 uint8_t(1), /* BSN:7, E:1 */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200571 uint8_t(tlli >> 24), uint8_t(tlli >> 16),
572 uint8_t(tlli >> 8), uint8_t(tlli), /* TLLI */
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200573 };
574
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200575 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
576 pdch->rcv_block(&data_msg[0], sizeof(data_msg), *fn, &meas);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200577
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200578 ms = the_bts->ms_by_tlli(tlli);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200579 OSMO_ASSERT(ms != NULL);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200580
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200581 return ul_tbf;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200582}
583
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200584static void send_ul_mac_block(BTS *the_bts, unsigned trx_no, unsigned ts_no,
585 RlcMacUplink_t *ulreq, unsigned fn)
586{
587 bitvec *rlc_block;
588 uint8_t buf[64];
589 int num_bytes;
590 struct gprs_rlcmac_pdch *pdch;
591 struct pcu_l1_meas meas;
592
593 meas.set_rssi(31);
594
595 rlc_block = bitvec_alloc(23);
596
597 encode_gsm_rlcmac_uplink(rlc_block, ulreq);
598 num_bytes = bitvec_pack(rlc_block, &buf[0]);
599 OSMO_ASSERT(size_t(num_bytes) < sizeof(buf));
600 bitvec_free(rlc_block);
601
Jacob Erlbeckaf75ce82015-08-26 13:22:28 +0200602 the_bts->set_current_block_frame_number(fn, 0);
603
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200604 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
605 pdch->rcv_block(&buf[0], num_bytes, fn, &meas);
606}
607
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200608static void send_control_ack(gprs_rlcmac_tbf *tbf)
609{
610 RlcMacUplink_t ulreq = {0};
611
612 OSMO_ASSERT(tbf->poll_fn != 0);
Jacob Erlbeck8eb17142016-01-22 17:58:17 +0100613 OSMO_ASSERT(tbf->is_control_ts(tbf->poll_ts));
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200614
615 ulreq.u.MESSAGE_TYPE = MT_PACKET_CONTROL_ACK;
616 Packet_Control_Acknowledgement_t *ctrl_ack =
617 &ulreq.u.Packet_Control_Acknowledgement;
618
619 ctrl_ack->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
620 ctrl_ack->TLLI = tbf->tlli();
Jacob Erlbeck8eb17142016-01-22 17:58:17 +0100621 send_ul_mac_block(tbf->bts, tbf->trx->trx_no, tbf->poll_ts,
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200622 &ulreq, tbf->poll_fn);
623}
624
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530625static gprs_rlcmac_ul_tbf *puan_urbb_len_issue(BTS *the_bts,
626 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
627 uint8_t ms_class, uint8_t egprs_ms_class)
628{
629 GprsMs *ms;
630 uint32_t rach_fn = *fn - 51;
631 uint32_t sba_fn = *fn + 52;
632 uint8_t trx_no = 0;
633 int tfi = 0, i = 0;
634 gprs_rlcmac_ul_tbf *ul_tbf;
635 struct gprs_rlcmac_pdch *pdch;
636 gprs_rlcmac_bts *bts;
637 RlcMacUplink_t ulreq = {0};
638 struct pcu_l1_meas meas;
639 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
640 GprsCodingScheme cs;
641
642 meas.set_rssi(31);
643 bts = the_bts->bts_data();
644
645 /* needed to set last_rts_fn in the PDCH object */
646 request_dl_rlc_block(bts, trx_no, ts_no, fn);
647
648 /*
649 * simulate RACH, this sends an Immediate
650 * Assignment Uplink on the AGCH
651 */
Aravind Sirsikarfd713842016-08-28 17:55:05 +0530652 the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530653
654 /* get next free TFI */
655 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
656
657 /* fake a resource request */
658 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
659 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
660 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
661 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
662 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability = 1;
663 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
664 Count_MS_RA_capability_value = 1;
665 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
666 MS_RA_capability_value[0].u.Content.
667 Exist_Multislot_capability = 1;
668 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
669 MS_RA_capability_value[0].u.Content.Multislot_capability.
670 Exist_GPRS_multislot_class = 1;
671 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
672 MS_RA_capability_value[0].u.Content.Multislot_capability.
673 GPRS_multislot_class = ms_class;
674 if (egprs_ms_class) {
675 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
676 MS_RA_capability_value[0].u.Content.
677 Multislot_capability.Exist_EGPRS_multislot_class = 1;
678 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
679 MS_RA_capability_value[0].u.Content.
680 Multislot_capability.EGPRS_multislot_class = ms_class;
681 }
682
683 send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
684
685 /* check the TBF */
686 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
687 OSMO_ASSERT(ul_tbf);
688 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
689
690 /* send packet uplink assignment */
691 *fn = sba_fn;
692 request_dl_rlc_block(ul_tbf, fn);
693
694 /* send real acknowledgement */
695 send_control_ack(ul_tbf);
696
697 check_tbf(ul_tbf);
698 /* send fake data */
699 uint8_t data_msg[42] = {
700 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
701 tfi << 1,
702 1, /* BSN:7, E:1 */
703 };
704
705 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
706 pdch->rcv_block(&data_msg[0], 23, *fn, &meas);
707
708 ms = the_bts->ms_by_tlli(tlli);
709 OSMO_ASSERT(ms != NULL);
710 OSMO_ASSERT(ms->ta() == qta/4);
711 OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
712
713 /*
714 * TS 44.060, B.8.1
715 * first seg received first, later second seg
716 */
717 cs = GprsCodingScheme::MCS3;
718 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
719 egprs3->si = 0;
720 egprs3->r = 1;
721 egprs3->cv = 7;
722 egprs3->tfi_hi = tfi & 0x03;
723 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
724 egprs3->bsn1_hi = 1;
725 egprs3->bsn1_lo = 0;
726 egprs3->cps_hi = 1;
727 data_msg[3] = 0xff;
728 egprs3->pi = 0;
729 egprs3->cps_lo = 1;
730 egprs3->rsb = 0;
731 egprs3->spb = 0;
732 egprs3->pi = 0;
733
734 pdch->rcv_block(data_msg, 42, *fn, &meas);
735
736 struct msgb *msg1 = ul_tbf->create_ul_ack(*fn, ts_no);
737
738 OSMO_ASSERT(!strcmp(osmo_hexdump(msg1->data, msg1->data_len),
739 "40 24 01 3f 3e 24 46 68 90 87 b0 06 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b "
740 ));
741
742 egprs3->si = 0;
743 egprs3->r = 1;
744 egprs3->cv = 7;
745 egprs3->tfi_hi = tfi & 0x03;
746 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
747 egprs3->bsn1_hi = 4;
748 egprs3->bsn1_lo = 0;
749 egprs3->cps_hi = 1;
750 data_msg[3] = 0xff;
751 egprs3->pi = 0;
752 egprs3->cps_lo = 1;
753 egprs3->rsb = 0;
754 egprs3->spb = 0;
755
756 pdch->rcv_block(data_msg, 42, *fn, &meas);
757
758 msg1 = ul_tbf->create_ul_ack(*fn, ts_no);
759
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530760 OSMO_ASSERT(!strcmp(osmo_hexdump(msg1->data, msg1->data_len),
Aravind Sirsikareebcb1e2016-08-25 16:40:23 +0530761 "40 24 01 3f 3e 24 46 68 90 88 b0 06 8b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b "
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530762 ));
763
764 return ul_tbf;
765}
766
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530767static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(BTS *the_bts,
768 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
769 uint8_t ms_class, uint8_t egprs_ms_class)
770{
771 GprsMs *ms;
772 uint32_t rach_fn = *fn - 51;
773 uint32_t sba_fn = *fn + 52;
774 uint8_t trx_no = 0;
775 int tfi = 0, i = 0;
776 gprs_rlcmac_ul_tbf *ul_tbf;
777 struct gprs_rlcmac_pdch *pdch;
778 gprs_rlcmac_bts *bts;
779 RlcMacUplink_t ulreq = {0};
780 struct pcu_l1_meas meas;
781 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
782 GprsCodingScheme cs;
783
784 meas.set_rssi(31);
785 bts = the_bts->bts_data();
786
787 /* needed to set last_rts_fn in the PDCH object */
788 request_dl_rlc_block(bts, trx_no, ts_no, fn);
789
790 /*
791 * simulate RACH, this sends an Immediate
792 * Assignment Uplink on the AGCH
793 */
bhargava959d1de2016-08-17 15:17:21 +0530794 the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530795
796 /* get next free TFI */
797 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
798
799 /* fake a resource request */
800 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
801 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
802 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
803 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
804 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability = 1;
805 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
806 Count_MS_RA_capability_value = 1;
807 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
808 MS_RA_capability_value[0].u.Content.
809 Exist_Multislot_capability = 1;
810 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
811 MS_RA_capability_value[0].u.Content.Multislot_capability.
812 Exist_GPRS_multislot_class = 1;
813 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
814 MS_RA_capability_value[0].u.Content.Multislot_capability.
815 GPRS_multislot_class = ms_class;
816 if (egprs_ms_class) {
817 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
818 MS_RA_capability_value[0].u.Content.
819 Multislot_capability.Exist_EGPRS_multislot_class = 1;
820 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
821 MS_RA_capability_value[0].u.Content.
822 Multislot_capability.EGPRS_multislot_class = ms_class;
823 }
824
825 send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
826
827 /* check the TBF */
828 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
829 OSMO_ASSERT(ul_tbf != NULL);
830 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
831
832 /* send packet uplink assignment */
833 *fn = sba_fn;
834 request_dl_rlc_block(ul_tbf, fn);
835
836 /* send real acknowledgement */
837 send_control_ack(ul_tbf);
838
839 check_tbf(ul_tbf);
840
841 /* send fake data */
842 uint8_t data_msg[42] = {
843 0x00 | 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
844 uint8_t(0 | (tfi << 1)),
845 uint8_t(1), /* BSN:7, E:1 */
846 };
847
848 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
849 pdch->rcv_block(&data_msg[0], 23, *fn, &meas);
850
851 ms = the_bts->ms_by_tlli(tlli);
852 OSMO_ASSERT(ms != NULL);
853 OSMO_ASSERT(ms->ta() == qta/4);
854 OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
855
856 /*
857 * TS 44.060, B.8.1
858 * first seg received first, later second seg
859 */
860 cs = GprsCodingScheme::MCS3;
861 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
862 egprs3->si = 1;
863 egprs3->r = 1;
864 egprs3->cv = 7;
865 egprs3->tfi_hi = tfi & 0x03;
866 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
867 egprs3->bsn1_hi = 1;
868 egprs3->bsn1_lo = 0;
869 egprs3->cps_hi = 1;
870 data_msg[3] = 0xff;
871 egprs3->pi = 0;
872 egprs3->cps_lo = 1;
873 egprs3->rsb = 0;
874 egprs3->spb = 2;
875 egprs3->pi = 0;
876
877 pdch->rcv_block(data_msg, 42, *fn, &meas);
878
879 struct gprs_rlc_data *block = ul_tbf->m_rlc.block(1);
880
881 /* check the status of the block */
882 OSMO_ASSERT(block->spb_status.block_status_ul ==
883 EGPRS_RESEG_FIRST_SEG_RXD);
884
885 egprs3->si = 1;
886 egprs3->r = 1;
887 egprs3->cv = 7;
888 egprs3->tfi_hi = tfi & 0x03;
889 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
890 egprs3->bsn1_hi = 1;
891 egprs3->bsn1_lo = 0;
892 egprs3->cps_hi = 1;
893 data_msg[3] = 0xff;
894 egprs3->pi = 0;
895 egprs3->cps_lo = 1;
896 egprs3->rsb = 0;
897 egprs3->spb = 3;
898
899 pdch->rcv_block(data_msg, 42, *fn, &meas);
900
901 /* check the status of the block */
902 OSMO_ASSERT(block->spb_status.block_status_ul ==
903 EGPRS_RESEG_DEFAULT);
904 OSMO_ASSERT(block->cs_last ==
905 GprsCodingScheme::MCS6);
906 /* Assembled MCS is MCS6. so the size is 74 */
907 OSMO_ASSERT(block->len == 74);
908
909 /*
910 * TS 44.060, B.8.1
911 * second seg first, later first seg
912 */
913 memset(data_msg, 0, sizeof(data_msg));
914
915 cs = GprsCodingScheme::MCS3;
916 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
917 egprs3->si = 1;
918 egprs3->r = 1;
919 egprs3->cv = 7;
920 egprs3->tfi_hi = tfi & 0x03;
921 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
922 egprs3->bsn1_hi = 2;
923 egprs3->bsn1_lo = 0;
924 egprs3->cps_hi = 1;
925 data_msg[3] = 0xff;
926 egprs3->pi = 0;
927 egprs3->cps_lo = 1;
928 egprs3->rsb = 0;
929 egprs3->spb = 3;
930 egprs3->pi = 0;
931
932 pdch->rcv_block(data_msg, 42, *fn, &meas);
933
934 block = ul_tbf->m_rlc.block(2);
935 /* check the status of the block */
936 OSMO_ASSERT(block->spb_status.block_status_ul ==
937 EGPRS_RESEG_SECOND_SEG_RXD);
938
939 egprs3->si = 1;
940 egprs3->r = 1;
941 egprs3->cv = 7;
942 egprs3->tfi_hi = tfi & 0x03;
943 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
944 egprs3->bsn1_hi = 2;
945 egprs3->bsn1_lo = 0;
946 egprs3->cps_hi = 1;
947 data_msg[3] = 0xff;
948 egprs3->pi = 0;
949 egprs3->cps_lo = 1;
950 egprs3->rsb = 0;
951 egprs3->spb = 2;
952 egprs3->pi = 0;
953
954 pdch->rcv_block(data_msg, 42, *fn, &meas);
955
956 /* check the status of the block */
957 OSMO_ASSERT(block->spb_status.block_status_ul ==
958 EGPRS_RESEG_DEFAULT);
959 OSMO_ASSERT(block->cs_last ==
960 GprsCodingScheme::MCS6);
961 /* Assembled MCS is MCS6. so the size is 74 */
962 OSMO_ASSERT(block->len == 74);
963
964 /*
965 * TS 44.060, B.8.1
966 * Error scenario with spb as 1
967 */
968 cs = GprsCodingScheme::MCS3;
969 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
970 egprs3->si = 1;
971 egprs3->r = 1;
972 egprs3->cv = 7;
973 egprs3->tfi_hi = tfi & 0x03;
974 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
975 egprs3->bsn1_hi = 3;
976 egprs3->bsn1_lo = 0;
977 egprs3->cps_hi = 1;
978 data_msg[3] = 0xff;
979 egprs3->pi = 0;
980 egprs3->cps_lo = 1;
981 egprs3->rsb = 0;
982 egprs3->spb = 1;
983 egprs3->pi = 0;
984
985 pdch->rcv_block(data_msg, 42, *fn, &meas);
986
987 block = ul_tbf->m_rlc.block(3);
988 /* check the status of the block */
989 OSMO_ASSERT(block->spb_status.block_status_ul ==
990 EGPRS_RESEG_DEFAULT);
991 /*
992 * TS 44.060, B.8.1
993 * comparison of rlc_data for multiple scenarios
994 * Receive First, the second(BSN 3)
995 * Receive First, First then Second(BSN 4)
996 * Receive Second then First(BSN 5)
997 * after above 3 scenarios are triggered,
998 * rlc_data of all 3 BSN are compared
999 */
1000
1001 /* Initialize the data_msg */
1002 for (i = 0; i < 42; i++)
1003 data_msg[i] = i;
1004
1005 cs = GprsCodingScheme::MCS3;
1006 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1007 egprs3->si = 1;
1008 egprs3->r = 1;
1009 egprs3->cv = 7;
1010 egprs3->tfi_hi = tfi & 0x03;
1011 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1012 egprs3->bsn1_hi = 3;
1013 egprs3->bsn1_lo = 0;
1014 egprs3->cps_hi = 1;
1015 data_msg[3] = 0xff;
1016 egprs3->pi = 0;
1017 egprs3->cps_lo = 1;
1018 egprs3->rsb = 0;
1019 egprs3->spb = 2;
1020 egprs3->pi = 0;
1021
1022 pdch->rcv_block(data_msg, 42, *fn, &meas);
1023
1024 block = ul_tbf->m_rlc.block(3);
1025 /* check the status of the block */
1026 OSMO_ASSERT(block->spb_status.block_status_ul ==
1027 EGPRS_RESEG_FIRST_SEG_RXD);
1028
1029 cs = GprsCodingScheme::MCS3;
1030 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1031 egprs3->si = 1;
1032 egprs3->r = 1;
1033 egprs3->cv = 7;
1034 egprs3->tfi_hi = tfi & 0x03;
1035 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1036 egprs3->bsn1_hi = 3;
1037 egprs3->bsn1_lo = 0;
1038 egprs3->cps_hi = 1;
1039 data_msg[3] = 0xff;
1040 egprs3->pi = 0;
1041 egprs3->cps_lo = 1;
1042 egprs3->rsb = 0;
1043 egprs3->spb = 3;
1044 egprs3->pi = 0;
1045
1046 pdch->rcv_block(data_msg, 42, *fn, &meas);
1047
1048 block = ul_tbf->m_rlc.block(3);
1049 /* check the status of the block */
1050 OSMO_ASSERT(block->spb_status.block_status_ul ==
1051 EGPRS_RESEG_DEFAULT);
1052 /* Assembled MCS is MCS6. so the size is 74 */
1053 OSMO_ASSERT(block->len == 74);
1054 OSMO_ASSERT(block->cs_last ==
1055 GprsCodingScheme::MCS6);
1056
1057 cs = GprsCodingScheme::MCS3;
1058 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1059 egprs3->si = 1;
1060 egprs3->r = 1;
1061 egprs3->cv = 7;
1062 egprs3->tfi_hi = tfi & 0x03;
1063 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1064 egprs3->bsn1_hi = 4;
1065 egprs3->bsn1_lo = 0;
1066 egprs3->cps_hi = 1;
1067 data_msg[3] = 0xff;
1068 egprs3->pi = 0;
1069 egprs3->cps_lo = 1;
1070 egprs3->rsb = 0;
1071 egprs3->spb = 2;
1072 egprs3->pi = 0;
1073
1074 pdch->rcv_block(data_msg, 42, *fn, &meas);
1075
1076 block = ul_tbf->m_rlc.block(4);
1077 /* check the status of the block */
1078 OSMO_ASSERT(block->spb_status.block_status_ul ==
1079 EGPRS_RESEG_FIRST_SEG_RXD);
1080
1081 cs = GprsCodingScheme::MCS3;
1082 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1083 egprs3->si = 1;
1084 egprs3->r = 1;
1085 egprs3->cv = 7;
1086 egprs3->tfi_hi = tfi & 0x03;
1087 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1088 egprs3->bsn1_hi = 4;
1089 egprs3->bsn1_lo = 0;
1090 egprs3->cps_hi = 1;
1091 data_msg[3] = 0xff;
1092 egprs3->pi = 0;
1093 egprs3->cps_lo = 1;
1094 egprs3->rsb = 0;
1095 egprs3->spb = 2;
1096 egprs3->pi = 0;
1097
1098 pdch->rcv_block(data_msg, 42, *fn, &meas);
1099
1100 block = ul_tbf->m_rlc.block(4);
1101 /* check the status of the block */
1102 OSMO_ASSERT(block->spb_status.block_status_ul ==
1103 EGPRS_RESEG_FIRST_SEG_RXD);
1104
1105 cs = GprsCodingScheme::MCS3;
1106 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1107 egprs3->si = 1;
1108 egprs3->r = 1;
1109 egprs3->cv = 7;
1110 egprs3->tfi_hi = tfi & 0x03;
1111 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1112 egprs3->bsn1_hi = 4;
1113 egprs3->bsn1_lo = 0;
1114 egprs3->cps_hi = 1;
1115 data_msg[3] = 0xff;
1116 egprs3->pi = 0;
1117 egprs3->cps_lo = 1;
1118 egprs3->rsb = 0;
1119 egprs3->spb = 3;
1120 egprs3->pi = 0;
1121
1122 pdch->rcv_block(data_msg, 42, *fn, &meas);
1123
1124 block = ul_tbf->m_rlc.block(4);
1125 /* check the status of the block */
1126 OSMO_ASSERT(block->spb_status.block_status_ul ==
1127 EGPRS_RESEG_DEFAULT);
1128 OSMO_ASSERT(block->cs_last ==
1129 GprsCodingScheme::MCS6);
1130 /* Assembled MCS is MCS6. so the size is 74 */
1131 OSMO_ASSERT(block->len == 74);
1132
1133 cs = GprsCodingScheme::MCS3;
1134 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1135 egprs3->si = 1;
1136 egprs3->r = 1;
1137 egprs3->cv = 7;
1138 egprs3->tfi_hi = tfi & 0x03;
1139 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1140 egprs3->bsn1_hi = 5;
1141 egprs3->bsn1_lo = 0;
1142 egprs3->cps_hi = 1;
1143 data_msg[3] = 0xff;
1144 egprs3->pi = 0;
1145 egprs3->cps_lo = 1;
1146 egprs3->rsb = 0;
1147 egprs3->spb = 3;
1148 egprs3->pi = 0;
1149
1150 pdch->rcv_block(data_msg, 42, *fn, &meas);
1151
1152 block = ul_tbf->m_rlc.block(5);
1153 /* check the status of the block */
1154 OSMO_ASSERT(block->spb_status.block_status_ul ==
1155 EGPRS_RESEG_SECOND_SEG_RXD);
1156
1157 cs = GprsCodingScheme::MCS3;
1158 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1159 egprs3->si = 1;
1160 egprs3->r = 1;
1161 egprs3->cv = 7;
1162 egprs3->tfi_hi = tfi & 0x03;
1163 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1164 egprs3->bsn1_hi = 5;
1165 egprs3->bsn1_lo = 0;
1166 egprs3->cps_hi = 1;
1167 data_msg[3] = 0xff;
1168 egprs3->pi = 0;
1169 egprs3->cps_lo = 1;
1170 egprs3->rsb = 0;
1171 egprs3->spb = 2;
1172 egprs3->pi = 0;
1173
1174 pdch->rcv_block(data_msg, 42, *fn, &meas);
1175
1176 block = ul_tbf->m_rlc.block(5);
1177
1178 /* check the status of the block */
1179 OSMO_ASSERT(block->spb_status.block_status_ul ==
1180 EGPRS_RESEG_DEFAULT);
1181 OSMO_ASSERT(block->cs_last ==
1182 GprsCodingScheme::MCS6);
1183 /* Assembled MCS is MCS6. so the size is 74 */
1184 OSMO_ASSERT(block->len == 74);
1185
1186 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->len ==
1187 ul_tbf->m_rlc.block(4)->len);
1188 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->len ==
1189 ul_tbf->m_rlc.block(3)->len);
1190
1191 /* Compare the spb status of each BSNs(3,4,5). should be same */
1192 OSMO_ASSERT(
1193 ul_tbf->m_rlc.block(5)->spb_status.block_status_ul ==
1194 ul_tbf->m_rlc.block(4)->spb_status.block_status_ul);
1195 OSMO_ASSERT(
1196 ul_tbf->m_rlc.block(5)->spb_status.block_status_ul ==
1197 ul_tbf->m_rlc.block(3)->spb_status.block_status_ul);
1198
1199 /* Compare the Assembled MCS of each BSNs(3,4,5). should be same */
1200 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->cs_last ==
1201 ul_tbf->m_rlc.block(4)->cs_last);
1202 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->cs_last ==
1203 ul_tbf->m_rlc.block(3)->cs_last);
1204
1205 /* Compare the data of each BSNs(3,4,5). should be same */
1206 OSMO_ASSERT(
1207 !memcmp(ul_tbf->m_rlc.block(5)->block,
1208 ul_tbf->m_rlc.block(4)->block, ul_tbf->m_rlc.block(5)->len
1209 ));
1210 OSMO_ASSERT(
1211 !memcmp(ul_tbf->m_rlc.block(5)->block,
1212 ul_tbf->m_rlc.block(3)->block, ul_tbf->m_rlc.block(5)->len
1213 ));
1214
1215 return ul_tbf;
1216}
1217
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001218static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase(BTS *the_bts,
1219 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001220 uint8_t ms_class, uint8_t egprs_ms_class)
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001221{
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001222 GprsMs *ms;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001223 uint32_t rach_fn = *fn - 51;
1224 uint32_t sba_fn = *fn + 52;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001225 uint8_t trx_no = 0;
1226 int tfi = 0;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001227 gprs_rlcmac_ul_tbf *ul_tbf;
1228 struct gprs_rlcmac_pdch *pdch;
1229 gprs_rlcmac_bts *bts;
1230 RlcMacUplink_t ulreq = {0};
Jacob Erlbeck20f6fd12015-06-08 11:05:45 +02001231 struct pcu_l1_meas meas;
1232 meas.set_rssi(31);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001233
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001234 bts = the_bts->bts_data();
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001235
1236 /* needed to set last_rts_fn in the PDCH object */
Max878bd1f2016-07-20 13:05:05 +02001237 request_dl_rlc_block(bts, trx_no, ts_no, fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001238
bhargava959d1de2016-08-17 15:17:21 +05301239 /* simulate RACH, sends an Immediate Assignment Uplink on the AGCH */
1240 the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001241
1242 /* get next free TFI */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001243 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001244
1245 /* fake a resource request */
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001246 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
1247 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
1248 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
1249 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001250 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability = 1;
1251 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1252 Count_MS_RA_capability_value = 1;
1253 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1254 MS_RA_capability_value[0].u.Content.Exist_Multislot_capability = 1;
1255 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1256 MS_RA_capability_value[0].u.Content.Multislot_capability.
1257 Exist_GPRS_multislot_class = 1;
1258 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1259 MS_RA_capability_value[0].u.Content.Multislot_capability.
1260 GPRS_multislot_class = ms_class;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001261 if (egprs_ms_class) {
1262 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1263 MS_RA_capability_value[0].u.Content.Multislot_capability.
1264 Exist_EGPRS_multislot_class = 1;
1265 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1266 MS_RA_capability_value[0].u.Content.Multislot_capability.
1267 EGPRS_multislot_class = ms_class;
1268 }
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001269
Jacob Erlbeck56f99d12015-08-20 15:55:56 +02001270 send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001271
1272 /* check the TBF */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001273 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001274 OSMO_ASSERT(ul_tbf != NULL);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +02001275 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001276
1277 /* send packet uplink assignment */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001278 *fn = sba_fn;
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +02001279 request_dl_rlc_block(ul_tbf, fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001280
Jacob Erlbeckaf454732015-08-21 15:03:23 +02001281 /* send real acknowledgement */
1282 send_control_ack(ul_tbf);
1283
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001284 check_tbf(ul_tbf);
1285
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001286 /* send fake data */
1287 uint8_t data_msg[23] = {
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001288 0x00 | 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
1289 uint8_t(0 | (tfi << 1)),
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001290 uint8_t(1), /* BSN:7, E:1 */
1291 };
1292
Jacob Erlbeck56f99d12015-08-20 15:55:56 +02001293 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001294 pdch->rcv_block(&data_msg[0], sizeof(data_msg), *fn, &meas);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001295
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001296 ms = the_bts->ms_by_tlli(tlli);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001297 OSMO_ASSERT(ms != NULL);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +02001298 OSMO_ASSERT(ms->ta() == qta/4);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001299 OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
1300
1301 return ul_tbf;
1302}
1303
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001304static void send_dl_data(BTS *the_bts, uint32_t tlli, const char *imsi,
1305 const uint8_t *data, unsigned data_size)
1306{
1307 GprsMs *ms, *ms2;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001308
1309 ms = the_bts->ms_store().get_ms(tlli, 0, imsi);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001310
Jacob Erlbeck14e00f82015-11-27 18:10:39 +01001311 gprs_rlcmac_dl_tbf::handle(the_bts->bts_data(), tlli, 0, imsi, 0, 0,
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001312 1000, data, data_size);
1313
1314 ms = the_bts->ms_by_imsi(imsi);
1315 OSMO_ASSERT(ms != NULL);
1316 OSMO_ASSERT(ms->dl_tbf() != NULL);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001317
1318 if (imsi[0] && strcmp(imsi, "000") != 0) {
1319 ms2 = the_bts->ms_by_tlli(tlli);
1320 OSMO_ASSERT(ms == ms2);
1321 }
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001322}
1323
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001324static void transmit_dl_data(BTS *the_bts, uint32_t tlli, uint32_t *fn,
1325 uint8_t slots = 0xff)
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001326{
1327 gprs_rlcmac_dl_tbf *dl_tbf;
1328 GprsMs *ms;
1329 unsigned ts_no;
1330
1331 ms = the_bts->ms_by_tlli(tlli);
1332 OSMO_ASSERT(ms);
1333 dl_tbf = ms->dl_tbf();
1334 OSMO_ASSERT(dl_tbf);
1335
1336 while (dl_tbf->have_data()) {
1337 uint8_t bn = fn2bn(*fn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001338 for (ts_no = 0 ; ts_no < 8; ts_no += 1) {
1339 if (!(slots & (1 << ts_no)))
1340 continue;
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001341 gprs_rlcmac_rcv_rts_block(the_bts->bts_data(),
Max878bd1f2016-07-20 13:05:05 +02001342 dl_tbf->trx->trx_no, ts_no,
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001343 *fn, bn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001344 }
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001345 *fn = fn_add_blocks(*fn, 1);
1346 }
1347}
1348
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001349static void test_tbf_single_phase()
1350{
1351 BTS the_bts;
1352 int ts_no = 7;
1353 uint32_t fn = 2654167; /* 17,25,9 */
1354 uint32_t tlli = 0xf1223344;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001355 const char *imsi = "0011223344";
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001356 uint16_t qta = 31;
1357 gprs_rlcmac_ul_tbf *ul_tbf;
1358 GprsMs *ms;
1359
1360 printf("=== start %s ===\n", __func__);
1361
1362 setup_bts(&the_bts, ts_no);
1363
1364 ul_tbf = establish_ul_tbf_single_phase(&the_bts, ts_no, tlli, &fn, qta);
1365
1366 ms = ul_tbf->ms();
1367 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
1368 fprintf(stderr, "Got MS: TLLI = 0x%08x, TA = %d\n", ms->tlli(), ms->ta());
1369
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001370 send_dl_data(&the_bts, tlli, imsi, (const uint8_t *)"TEST", 4);
1371
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001372 printf("=== end %s ===\n", __func__);
1373}
1374
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301375/*
1376 * Trigger rach for single block
1377 */
1378static void test_immediate_assign_rej_single_block()
1379{
1380 BTS the_bts;
1381 uint32_t fn = 2654218;
1382 uint16_t qta = 31;
1383 int ts_no = 7;
1384
1385 printf("=== start %s ===\n", __func__);
1386
1387 setup_bts(&the_bts, ts_no, 4);
1388
1389 the_bts.bts_data()->trx[0].pdch[ts_no].disable();
1390
1391 uint32_t rach_fn = fn - 51;
1392
1393 int rc = 0;
1394
1395 /*
1396 * simulate RACH, sends an Immediate Assignment
1397 * Uplink reject on the AGCH
1398 */
1399 rc = the_bts.rcv_rach(0x70, rach_fn, qta, 0,
1400 GSM_L1_BURST_TYPE_ACCESS_0);
1401
1402 OSMO_ASSERT(rc == -EINVAL);
1403
1404 printf("=== end %s ===\n", __func__);
1405}
1406
1407/*
1408 * Trigger rach till resources(USF) exhaust
1409 */
1410static void test_immediate_assign_rej_multi_block()
1411{
1412 BTS the_bts;
1413 uint32_t fn = 2654218;
1414 uint16_t qta = 31;
1415 int ts_no = 7;
1416
1417 printf("=== start %s ===\n", __func__);
1418
1419 setup_bts(&the_bts, ts_no, 4);
1420
1421 uint32_t rach_fn = fn - 51;
1422
1423 int rc = 0;
1424
1425 /*
1426 * simulate RACH, sends an Immediate Assignment Uplink
1427 * reject on the AGCH
1428 */
1429 rc = the_bts.rcv_rach(0x78, rach_fn, qta, 0,
1430 GSM_L1_BURST_TYPE_ACCESS_0);
1431 rc = the_bts.rcv_rach(0x79, rach_fn, qta, 0,
1432 GSM_L1_BURST_TYPE_ACCESS_0);
1433 rc = the_bts.rcv_rach(0x7a, rach_fn, qta, 0,
1434 GSM_L1_BURST_TYPE_ACCESS_0);
1435 rc = the_bts.rcv_rach(0x7b, rach_fn, qta, 0,
1436 GSM_L1_BURST_TYPE_ACCESS_0);
1437 rc = the_bts.rcv_rach(0x7c, rach_fn, qta, 0,
1438 GSM_L1_BURST_TYPE_ACCESS_0);
1439 rc = the_bts.rcv_rach(0x7d, rach_fn, qta, 0,
1440 GSM_L1_BURST_TYPE_ACCESS_0);
1441 rc = the_bts.rcv_rach(0x7e, rach_fn, qta, 0,
1442 GSM_L1_BURST_TYPE_ACCESS_0);
1443 rc = the_bts.rcv_rach(0x7f, rach_fn, qta, 0,
1444 GSM_L1_BURST_TYPE_ACCESS_0);
1445
1446 OSMO_ASSERT(rc == -EBUSY);
1447
1448 printf("=== end %s ===\n", __func__);
1449}
1450
1451static void test_immediate_assign_rej()
1452{
1453 test_immediate_assign_rej_multi_block();
1454 test_immediate_assign_rej_single_block();
1455}
1456
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001457static void test_tbf_two_phase()
1458{
1459 BTS the_bts;
1460 int ts_no = 7;
1461 uint32_t fn = 2654218;
1462 uint16_t qta = 31;
1463 uint32_t tlli = 0xf1223344;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001464 const char *imsi = "0011223344";
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001465 uint8_t ms_class = 1;
1466 gprs_rlcmac_ul_tbf *ul_tbf;
1467 GprsMs *ms;
1468
1469 printf("=== start %s ===\n", __func__);
1470
1471 setup_bts(&the_bts, ts_no, 4);
1472
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001473 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli, &fn, qta,
1474 ms_class, 0);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001475
1476 ms = ul_tbf->ms();
1477 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
1478 fprintf(stderr, "Got MS: TLLI = 0x%08x, TA = %d\n", ms->tlli(), ms->ta());
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001479
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001480 send_dl_data(&the_bts, tlli, imsi, (const uint8_t *)"TEST", 4);
1481
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001482 printf("=== end %s ===\n", __func__);
1483}
1484
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001485static void test_tbf_ra_update_rach()
1486{
1487 BTS the_bts;
1488 int ts_no = 7;
1489 uint32_t fn = 2654218;
1490 uint16_t qta = 31;
1491 uint32_t tlli1 = 0xf1223344;
1492 uint32_t tlli2 = 0xf5667788;
1493 const char *imsi = "0011223344";
1494 uint8_t ms_class = 1;
1495 gprs_rlcmac_ul_tbf *ul_tbf;
1496 GprsMs *ms, *ms1, *ms2;
1497
1498 printf("=== start %s ===\n", __func__);
1499
1500 setup_bts(&the_bts, ts_no, 4);
1501
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001502 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli1, &fn, qta,
1503 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001504
1505 ms1 = ul_tbf->ms();
1506 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
1507
1508 send_dl_data(&the_bts, tlli1, imsi, (const uint8_t *)"RAU_ACCEPT", 10);
1509 fprintf(stderr, "Old MS: TLLI = 0x%08x, TA = %d, IMSI = %s, LLC = %d\n",
1510 ms1->tlli(), ms1->ta(), ms1->imsi(), ms1->llc_queue()->size());
1511
Jacob Erlbeckaf454732015-08-21 15:03:23 +02001512 /* Send Packet Downlink Assignment to MS */
1513 request_dl_rlc_block(ul_tbf, &fn);
1514
1515 /* Ack it */
1516 send_control_ack(ul_tbf);
1517
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001518 /* Make sure the RAU Accept gets sent to the MS */
1519 OSMO_ASSERT(ms1->llc_queue()->size() == 1);
1520 transmit_dl_data(&the_bts, tlli1, &fn);
1521 OSMO_ASSERT(ms1->llc_queue()->size() == 0);
1522
1523 /* Now establish a new TBF for the RA UPDATE COMPLETE (new TLLI) */
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001524 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli2, &fn, qta,
1525 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001526
1527 ms2 = ul_tbf->ms();
1528
1529 /* The PCU cannot know yet, that both TBF belong to the same MS */
1530 OSMO_ASSERT(ms1 != ms2);
1531
1532 fprintf(stderr, "Old MS: TLLI = 0x%08x, TA = %d, IMSI = %s, LLC = %d\n",
1533 ms1->tlli(), ms1->ta(), ms1->imsi(), ms1->llc_queue()->size());
1534
1535 /* Send some downlink data along with the new TLLI and the IMSI so that
1536 * the PCU can see, that both MS objects belong to same MS */
1537 send_dl_data(&the_bts, tlli2, imsi, (const uint8_t *)"DATA", 4);
1538
1539 ms = the_bts.ms_by_imsi(imsi);
1540 OSMO_ASSERT(ms == ms2);
1541
1542 fprintf(stderr, "New MS: TLLI = 0x%08x, TA = %d, IMSI = %s, LLC = %d\n",
1543 ms2->tlli(), ms2->ta(), ms2->imsi(), ms2->llc_queue()->size());
1544
1545 ms = the_bts.ms_by_tlli(tlli1);
1546 OSMO_ASSERT(ms == NULL);
1547 ms = the_bts.ms_by_tlli(tlli2);
1548 OSMO_ASSERT(ms == ms2);
1549
1550 printf("=== end %s ===\n", __func__);
1551}
1552
1553static void test_tbf_dl_flow_and_rach_two_phase()
1554{
1555 BTS the_bts;
1556 int ts_no = 7;
1557 uint32_t fn = 2654218;
1558 uint16_t qta = 31;
1559 uint32_t tlli1 = 0xf1223344;
1560 const char *imsi = "0011223344";
1561 uint8_t ms_class = 1;
1562 gprs_rlcmac_ul_tbf *ul_tbf;
1563 gprs_rlcmac_dl_tbf *dl_tbf;
1564 GprsMs *ms, *ms1, *ms2;
1565
1566 printf("=== start %s ===\n", __func__);
1567
1568 setup_bts(&the_bts, ts_no, 1);
1569
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001570 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli1, &fn, qta,
1571 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001572
1573 ms1 = ul_tbf->ms();
1574 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
1575
1576 send_dl_data(&the_bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);
1577 send_dl_data(&the_bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);
1578 fprintf(stderr, "Old MS: TLLI = 0x%08x, TA = %d, IMSI = %s, LLC = %d\n",
1579 ms1->tlli(), ms1->ta(), ms1->imsi(), ms1->llc_queue()->size());
1580
1581 OSMO_ASSERT(ms1->llc_queue()->size() == 2);
1582 dl_tbf = ms1->dl_tbf();
1583 OSMO_ASSERT(dl_tbf != NULL);
1584
1585 /* Get rid of old UL TBF */
1586 tbf_free(ul_tbf);
1587 ms = the_bts.ms_by_tlli(tlli1);
1588 OSMO_ASSERT(ms1 == ms);
1589
1590 /* Now establish a new UL TBF, this will consume one LLC packet */
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001591 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli1, &fn, qta,
1592 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001593
1594 ms2 = ul_tbf->ms();
1595 fprintf(stderr, "New MS: TLLI = 0x%08x, TA = %d, IMSI = %s, LLC = %d\n",
1596 ms2->tlli(), ms2->ta(), ms2->imsi(), ms2->llc_queue()->size());
1597
1598 /* This should be the same MS object */
1599 OSMO_ASSERT(ms2 == ms1);
1600
1601 ms = the_bts.ms_by_tlli(tlli1);
1602 OSMO_ASSERT(ms2 == ms);
1603
Jacob Erlbeckc8cbfc22015-09-01 11:38:40 +02001604 /* A DL TBF should still exist */
1605 OSMO_ASSERT(ms->dl_tbf());
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001606
1607 /* No queued packets should be lost */
Jacob Erlbeck9659d592015-09-01 11:06:14 +02001608 OSMO_ASSERT(ms->llc_queue()->size() == 2);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001609
1610 printf("=== end %s ===\n", __func__);
1611}
1612
1613
1614static void test_tbf_dl_flow_and_rach_single_phase()
1615{
1616 BTS the_bts;
1617 int ts_no = 7;
1618 uint32_t fn = 2654218;
1619 uint16_t qta = 31;
1620 uint32_t tlli1 = 0xf1223344;
1621 const char *imsi = "0011223344";
1622 uint8_t ms_class = 1;
1623 gprs_rlcmac_ul_tbf *ul_tbf;
1624 gprs_rlcmac_dl_tbf *dl_tbf;
1625 GprsMs *ms, *ms1, *ms2;
1626
1627 printf("=== start %s ===\n", __func__);
1628
1629 setup_bts(&the_bts, ts_no, 1);
1630
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001631 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli1, &fn, qta,
1632 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001633
1634 ms1 = ul_tbf->ms();
1635 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
1636
1637 send_dl_data(&the_bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);
1638 send_dl_data(&the_bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);
1639 fprintf(stderr, "Old MS: TLLI = 0x%08x, TA = %d, IMSI = %s, LLC = %d\n",
1640 ms1->tlli(), ms1->ta(), ms1->imsi(), ms1->llc_queue()->size());
1641
1642 OSMO_ASSERT(ms1->llc_queue()->size() == 2);
1643 dl_tbf = ms1->dl_tbf();
1644 OSMO_ASSERT(dl_tbf != NULL);
1645
1646 /* Get rid of old UL TBF */
1647 tbf_free(ul_tbf);
1648 ms = the_bts.ms_by_tlli(tlli1);
1649 OSMO_ASSERT(ms1 == ms);
1650
1651 /* Now establish a new UL TBF */
1652 ul_tbf = establish_ul_tbf_single_phase(&the_bts, ts_no, tlli1, &fn, qta);
1653
1654 ms2 = ul_tbf->ms();
1655 fprintf(stderr, "New MS: TLLI = 0x%08x, TA = %d, IMSI = %s, LLC = %d\n",
1656 ms2->tlli(), ms2->ta(), ms2->imsi(), ms2->llc_queue()->size());
1657
1658 /* There should be a different MS object */
1659 OSMO_ASSERT(ms2 != ms1);
1660
1661 ms = the_bts.ms_by_tlli(tlli1);
1662 OSMO_ASSERT(ms2 == ms);
1663 OSMO_ASSERT(ms1 != ms);
1664
Jacob Erlbeck5f93f852016-01-21 20:48:39 +01001665 /* DL TBF should be removed */
1666 OSMO_ASSERT(!ms->dl_tbf());
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001667
1668 /* No queued packets should be lost */
Jacob Erlbeck9659d592015-09-01 11:06:14 +02001669 OSMO_ASSERT(ms->llc_queue()->size() == 2);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001670
1671 printf("=== end %s ===\n", __func__);
1672}
1673
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02001674static void test_tbf_dl_reuse()
1675{
1676 BTS the_bts;
1677 int ts_no = 7;
1678 uint32_t fn = 2654218;
1679 uint16_t qta = 31;
1680 uint32_t tlli1 = 0xf1223344;
1681 const char *imsi = "0011223344";
1682 uint8_t ms_class = 1;
1683 gprs_rlcmac_ul_tbf *ul_tbf;
1684 gprs_rlcmac_dl_tbf *dl_tbf1, *dl_tbf2;
1685 GprsMs *ms1, *ms2;
1686 unsigned i;
1687 RlcMacUplink_t ulreq = {0};
1688
1689 printf("=== start %s ===\n", __func__);
1690
1691 setup_bts(&the_bts, ts_no, 1);
1692
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001693 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli1, &fn, qta,
1694 ms_class, 0);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02001695
1696 ms1 = ul_tbf->ms();
1697 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
1698
1699 /* Send some LLC frames */
1700 for (i = 0; i < 40; i++) {
1701 char buf[32];
1702 int rc;
1703
1704 rc = snprintf(buf, sizeof(buf), "LLC PACKET %02i", i);
1705 OSMO_ASSERT(rc > 0);
1706
1707 send_dl_data(&the_bts, tlli1, imsi, (const uint8_t *)buf, rc);
1708 }
1709
1710 fprintf(stderr, "Old MS: TLLI = 0x%08x, TA = %d, IMSI = %s, LLC = %d\n",
1711 ms1->tlli(), ms1->ta(), ms1->imsi(), ms1->llc_queue()->size());
1712
1713 /* Send Packet Downlink Assignment to MS */
1714 request_dl_rlc_block(ul_tbf, &fn);
1715
1716 /* Ack it */
1717 send_control_ack(ul_tbf);
1718
1719 /* Transmit all data */
1720 transmit_dl_data(&the_bts, tlli1, &fn);
1721 OSMO_ASSERT(ms1->llc_queue()->size() == 0);
1722 OSMO_ASSERT(ms1->dl_tbf());
1723 OSMO_ASSERT(ms1->dl_tbf()->state_is(GPRS_RLCMAC_FINISHED));
1724
1725 dl_tbf1 = ms1->dl_tbf();
1726
1727 /* Send some LLC frames */
1728 for (i = 0; i < 10; i++) {
1729 char buf[32];
1730 int rc;
1731
1732 rc = snprintf(buf, sizeof(buf), "LLC PACKET %02i (TBF 2)", i);
1733 OSMO_ASSERT(rc > 0);
1734
1735 send_dl_data(&the_bts, tlli1, imsi, (const uint8_t *)buf, rc);
1736 }
1737
1738 /* Fake Final DL Ack/Nack */
1739 ulreq.u.MESSAGE_TYPE = MT_PACKET_DOWNLINK_ACK_NACK;
1740 Packet_Downlink_Ack_Nack_t *ack = &ulreq.u.Packet_Downlink_Ack_Nack;
1741
1742 ack->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
1743 ack->DOWNLINK_TFI = dl_tbf1->tfi();
1744 ack->Ack_Nack_Description.FINAL_ACK_INDICATION = 1;
1745
Jacob Erlbeck8eb17142016-01-22 17:58:17 +01001746 send_ul_mac_block(&the_bts, 0, dl_tbf1->poll_ts, &ulreq, dl_tbf1->poll_fn);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02001747
1748 OSMO_ASSERT(dl_tbf1->state_is(GPRS_RLCMAC_WAIT_RELEASE));
1749
1750 request_dl_rlc_block(dl_tbf1, &fn);
1751
1752 ms2 = the_bts.ms_by_tlli(tlli1);
1753 OSMO_ASSERT(ms2 == ms1);
1754 OSMO_ASSERT(ms2->dl_tbf());
Neels Hofmeyr4ea45262016-06-08 15:27:40 +02001755 OSMO_ASSERT(ms2->dl_tbf()->state_is(GPRS_RLCMAC_ASSIGN));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02001756
1757 dl_tbf2 = ms2->dl_tbf();
1758
1759 OSMO_ASSERT(dl_tbf1 != dl_tbf2);
1760
1761 send_control_ack(dl_tbf1);
Jacob Erlbeck6835cea2015-08-21 15:24:02 +02001762 OSMO_ASSERT(dl_tbf2->state_is(GPRS_RLCMAC_FLOW));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02001763
1764 /* Transmit all data */
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02001765 transmit_dl_data(&the_bts, tlli1, &fn);
1766 OSMO_ASSERT(ms2->llc_queue()->size() == 0);
1767 OSMO_ASSERT(ms2->dl_tbf());
1768 OSMO_ASSERT(ms2->dl_tbf()->state_is(GPRS_RLCMAC_FINISHED));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02001769
1770 printf("=== end %s ===\n", __func__);
1771}
1772
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01001773static void test_tbf_gprs_egprs()
1774{
1775 BTS the_bts;
1776 gprs_rlcmac_bts *bts;
1777 uint8_t ts_no = 4;
1778 uint8_t ms_class = 45;
1779 int rc = 0;
1780 uint32_t tlli = 0xc0006789;
1781 const char *imsi = "001001123456789";
1782 unsigned delay_csec = 1000;
1783
1784 uint8_t buf[256] = {0};
1785
1786 printf("=== start %s ===\n", __func__);
1787
1788 bts = the_bts.bts_data();
1789 setup_bts(&the_bts, ts_no);
1790
1791 /* EGPRS-only */
1792 bts->egprs_enabled = 1;
1793
1794 gprs_bssgp_create_and_connect(bts, 33001, 0, 33001,
1795 1234, 1234, 1234, 1, 1, 0, 0, 0);
1796
1797 /* Does not support EGPRS */
1798 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
1799 delay_csec, buf, sizeof(buf));
1800
1801 OSMO_ASSERT(rc == -EBUSY);
1802 printf("=== end %s ===\n", __func__);
1803
1804 gprs_bssgp_destroy();
1805}
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001806
Jacob Erlbeck36df7742016-01-19 15:53:30 +01001807static void test_tbf_ws()
1808{
1809 BTS the_bts;
1810 gprs_rlcmac_bts *bts;
1811 uint8_t ts_no = 4;
1812 uint8_t ms_class = 12;
1813 gprs_rlcmac_dl_tbf *dl_tbf;
1814
1815 printf("=== start %s ===\n", __func__);
1816
1817 bts = the_bts.bts_data();
1818 setup_bts(&the_bts, ts_no);
1819
1820 bts->ws_base = 128;
1821 bts->ws_pdch = 64;
1822 bts->alloc_algorithm = alloc_algorithm_b;
1823 bts->trx[0].pdch[2].enable();
1824 bts->trx[0].pdch[3].enable();
1825 bts->trx[0].pdch[4].enable();
1826 bts->trx[0].pdch[5].enable();
1827
1828 gprs_bssgp_create_and_connect(bts, 33001, 0, 33001,
1829 1234, 1234, 1234, 1, 1, 0, 0, 0);
1830
1831 /* Does no support EGPRS */
1832 dl_tbf = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, 0, 0);
1833 OSMO_ASSERT(dl_tbf != NULL);
1834 fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d\n",
1835 dl_tbf->dl_slots(),
1836 pcu_bitcount(dl_tbf->dl_slots()),
1837 dl_tbf->window()->ws());
1838 OSMO_ASSERT(pcu_bitcount(dl_tbf->dl_slots()) == 4);
1839 OSMO_ASSERT(dl_tbf->window()->ws() == 64);
1840 tbf_free(dl_tbf);
1841
1842 /* EGPRS-only */
1843 bts->egprs_enabled = 1;
1844
1845 /* Does support EGPRS */
1846 dl_tbf = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, ms_class, 0);
1847
1848 OSMO_ASSERT(dl_tbf != NULL);
1849 fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d\n",
1850 dl_tbf->dl_slots(),
1851 pcu_bitcount(dl_tbf->dl_slots()),
1852 dl_tbf->window()->ws());
1853 OSMO_ASSERT(pcu_bitcount(dl_tbf->dl_slots()) == 4);
1854 OSMO_ASSERT(dl_tbf->window()->ws() == 128 + 4 * 64);
1855 tbf_free(dl_tbf);
1856
1857 printf("=== end %s ===\n", __func__);
1858
1859 gprs_bssgp_destroy();
1860}
1861
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05301862static void test_tbf_update_ws(void)
1863{
1864 BTS the_bts;
1865 gprs_rlcmac_bts *bts;
1866 uint8_t ts_no = 4;
1867 uint8_t ms_class = 11;
1868 gprs_rlcmac_dl_tbf *dl_tbf;
1869
1870 printf("=== start %s ===\n", __func__);
1871
1872 bts = the_bts.bts_data();
1873 setup_bts(&the_bts, ts_no);
1874
1875 bts->ws_base = 128;
1876 bts->ws_pdch = 64;
1877 bts->alloc_algorithm = alloc_algorithm_b;
1878 bts->trx[0].pdch[2].enable();
1879 bts->trx[0].pdch[3].enable();
1880 bts->trx[0].pdch[4].enable();
1881 bts->trx[0].pdch[5].enable();
1882
1883 gprs_bssgp_create_and_connect(bts, 33001, 0, 33001,
1884 1234, 1234, 1234, 1, 1, 0, 0, 0);
1885
1886 /* EGPRS-only */
1887 bts->egprs_enabled = 1;
1888
1889 /* Does support EGPRS */
1890 dl_tbf = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, ms_class, 1);
1891
1892 OSMO_ASSERT(dl_tbf != NULL);
1893 fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d\n",
1894 dl_tbf->dl_slots(),
1895 pcu_bitcount(dl_tbf->dl_slots()),
1896 dl_tbf->window()->ws());
1897 OSMO_ASSERT(pcu_bitcount(dl_tbf->dl_slots()) == 1);
1898 OSMO_ASSERT(dl_tbf->window()->ws() == 128 + 1 * 64);
1899
1900 dl_tbf->update();
1901
Aravind Sirsikar0ee31cf2016-09-15 17:54:46 +05301902 /* window size should be 384 */
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05301903 OSMO_ASSERT(dl_tbf != NULL);
1904 fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d\n",
1905 dl_tbf->dl_slots(),
1906 pcu_bitcount(dl_tbf->dl_slots()),
1907 dl_tbf->window()->ws());
1908 OSMO_ASSERT(pcu_bitcount(dl_tbf->dl_slots()) == 4);
Aravind Sirsikar0ee31cf2016-09-15 17:54:46 +05301909 OSMO_ASSERT(dl_tbf->window()->ws() == 128 + 4 * 64);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05301910
1911 tbf_free(dl_tbf);
1912
1913 printf("=== end %s ===\n", __func__);
1914
1915 gprs_bssgp_destroy();
1916}
1917
Aravind Sirsikar02352b42016-08-25 16:37:30 +05301918static void test_tbf_puan_urbb_len(void)
1919{
1920 BTS the_bts;
1921 int ts_no = 7;
1922 uint32_t fn = 2654218;
1923 uint16_t qta = 31;
1924 uint32_t tlli = 0xf1223344;
1925 const char *imsi = "0011223344";
1926 uint8_t ms_class = 1;
1927 uint8_t egprs_ms_class = 1;
1928 gprs_rlcmac_ul_tbf *ul_tbf;
1929 GprsMs *ms;
1930 uint8_t test_data[256];
1931
1932 printf("=== start %s ===\n", __func__);
1933
1934 memset(test_data, 1, sizeof(test_data));
1935
1936 setup_bts(&the_bts, ts_no, 4);
1937 the_bts.bts_data()->initial_mcs_dl = 9;
1938 the_bts.bts_data()->egprs_enabled = 1;
1939
1940 ul_tbf = puan_urbb_len_issue(&the_bts, ts_no, tlli, &fn, qta,
1941 ms_class, egprs_ms_class);
1942
1943 ms = ul_tbf->ms();
1944 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
1945 fprintf(stderr,
1946 "Got MS: TLLI = 0x%08x, TA = %d\n", ms->tlli(), ms->ta());
1947
1948 send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data));
1949
1950 printf("=== end %s ===\n", __func__);
1951}
1952
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05301953static gprs_rlcmac_ul_tbf *tbf_li_decoding(BTS *the_bts,
1954 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1955 uint8_t ms_class, uint8_t egprs_ms_class)
1956{
1957 GprsMs *ms;
1958 uint32_t rach_fn = *fn - 51;
1959 uint32_t sba_fn = *fn + 52;
1960 uint8_t trx_no = 0;
1961 int tfi = 0, i = 0;
1962 gprs_rlcmac_ul_tbf *ul_tbf;
1963 struct gprs_rlcmac_pdch *pdch;
1964 gprs_rlcmac_bts *bts;
1965 RlcMacUplink_t ulreq = {0};
1966 struct pcu_l1_meas meas;
1967 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
1968 GprsCodingScheme cs;
1969 Packet_Resource_Request_t *presreq = NULL;
1970 MS_Radio_Access_capability_t *pmsradiocap = NULL;
1971 Multislot_capability_t *pmultislotcap = NULL;
1972
1973 meas.set_rssi(31);
1974 bts = the_bts->bts_data();
1975
1976 /* needed to set last_rts_fn in the PDCH object */
1977 request_dl_rlc_block(bts, trx_no, ts_no, fn);
1978
1979 /*
1980 * simulate RACH, this sends an Immediate
1981 * Assignment Uplink on the AGCH
1982 */
1983 the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0);
1984
1985 /* get next free TFI */
1986 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
1987
1988 /* fake a resource request */
1989 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
1990 presreq = &ulreq.u.Packet_Resource_Request;
1991 presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
1992 presreq->ID.UnionType = 1; /* != 0 */
1993 presreq->ID.u.TLLI = tlli;
1994 presreq->Exist_MS_Radio_Access_capability = 1;
1995 pmsradiocap = &presreq->MS_Radio_Access_capability;
1996 pmsradiocap->Count_MS_RA_capability_value = 1;
1997 pmsradiocap->MS_RA_capability_value[0].u.Content.
1998 Exist_Multislot_capability = 1;
1999 pmultislotcap = &pmsradiocap->MS_RA_capability_value[0].
2000 u.Content.Multislot_capability;
2001
2002 pmultislotcap->Exist_GPRS_multislot_class = 1;
2003 pmultislotcap->GPRS_multislot_class = ms_class;
2004 if (egprs_ms_class) {
2005 pmultislotcap->Exist_EGPRS_multislot_class = 1;
2006 pmultislotcap->EGPRS_multislot_class = ms_class;
2007 }
2008
2009 send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
2010
2011 /* check the TBF */
2012 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
2013 OSMO_ASSERT(ul_tbf);
2014 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
2015
2016 /* send packet uplink assignment */
2017 *fn = sba_fn;
2018 request_dl_rlc_block(ul_tbf, fn);
2019
2020 /* send real acknowledgement */
2021 send_control_ack(ul_tbf);
2022
2023 check_tbf(ul_tbf);
2024
2025 uint8_t data_msg[49] = {0};
2026
2027 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
2028
2029 ms = the_bts->ms_by_tlli(tlli);
2030 OSMO_ASSERT(ms != NULL);
2031 OSMO_ASSERT(ms->ta() == qta/4);
2032 OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
2033
2034 cs = GprsCodingScheme::MCS4;
2035 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
2036 egprs3->si = 0;
2037 egprs3->r = 1;
2038 egprs3->cv = 7;
2039 egprs3->tfi_hi = tfi & 0x03;
2040 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
2041 egprs3->bsn1_hi = 0;
2042 egprs3->bsn1_lo = 0;
2043 egprs3->cps_hi = 1;
2044 data_msg[3] = 0xff;
2045 egprs3->pi = 0;
2046 egprs3->cps_lo = 1;
2047 egprs3->rsb = 0;
2048 egprs3->spb = 0;
2049 egprs3->pi = 0;
2050 pdch->rcv_block(data_msg, 49, *fn, &meas);
2051
2052 egprs3->bsn1_hi = 1;
2053 egprs3->bsn1_lo = 0;
2054 data_msg[3] = 0x7f;
2055 egprs3->cps_lo = 1;
2056 egprs3->rsb = 0;
2057 egprs3->spb = 0;
2058 egprs3->pi = 0;
2059 data_msg[4] = 0x2;
2060 data_msg[5] = 0x0;
2061 pdch->rcv_block(data_msg, 49, *fn, &meas);
2062
Aravind Sirsikar22a90192016-09-15 17:24:49 +05302063 OSMO_ASSERT(ul_tbf->m_llc.m_index == 43);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302064
2065 return ul_tbf;
2066}
2067
2068static void test_tbf_li_decoding(void)
2069{
2070 BTS the_bts;
2071 int ts_no = 7;
2072 uint32_t fn = 2654218;
2073 uint16_t qta = 31;
2074 uint32_t tlli = 0xf1223344;
2075 const char *imsi = "0011223344";
2076 uint8_t ms_class = 1;
2077 uint8_t egprs_ms_class = 1;
2078 gprs_rlcmac_ul_tbf *ul_tbf;
2079 GprsMs *ms;
2080 uint8_t test_data[256];
2081
2082 printf("=== start %s ===\n", __func__);
2083
2084 memset(test_data, 1, sizeof(test_data));
2085
2086 setup_bts(&the_bts, ts_no, 4);
2087 the_bts.bts_data()->initial_mcs_dl = 9;
2088 the_bts.bts_data()->egprs_enabled = 1;
2089
2090 ul_tbf = tbf_li_decoding(&the_bts, ts_no, tlli, &fn, qta,
2091 ms_class, egprs_ms_class);
2092
2093 ms = ul_tbf->ms();
2094 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
2095 fprintf(stderr,
2096 "Got MS: TLLI = 0x%08x, TA = %d\n", ms->tlli(), ms->ta());
2097
2098 send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data));
2099
2100 printf("=== end %s ===\n", __func__);
2101}
2102
aravind sirsikarf2761382016-10-25 12:45:24 +05302103/*
2104 * Test that a bit within the uncompressed bitmap whose BSN is not within
2105 * the transmit window shall be ignored. See section 9.1.8.2.4 of 44.060
2106 * version 7.27.0 Release 7.
2107 */
2108static void test_tbf_epdan_out_of_rx_window(void)
2109{
2110 BTS the_bts;
2111 gprs_rlcmac_bts *bts;
2112 uint8_t ms_class = 11;
2113 uint8_t egprs_ms_class = 11;
2114 uint8_t trx_no;
2115 uint32_t tlli = 0xffeeddcc;
2116 gprs_rlcmac_dl_tbf *dl_tbf;
2117 int ts_no = 4;
2118 bitvec *block;
2119 uint8_t bits_data[RLC_EGPRS_MAX_WS/8];
2120 bitvec bits;
2121 int bsn_begin, bsn_end;
2122 EGPRS_PD_AckNack_t *ack_nack;
2123 RlcMacUplink_t ul_control_block;
2124 gprs_rlc_v_b *prlcmvb;
2125 gprs_rlc_dl_window *prlcdlwindow;
2126
2127 printf("=== start %s ===\n", __func__);
2128
2129 bts = the_bts.bts_data();
2130
2131 setup_bts(&the_bts, ts_no);
2132 bts->dl_tbf_idle_msec = 200;
2133 bts->egprs_enabled = 1;
2134 /* ARQ II */
2135 bts->dl_arq_type = EGPRS_ARQ2;
2136
2137 /*
2138 * Simulate a message captured during over-the-air testing,
2139 * where the following values were observed:
2140 * v_a = 1176, vs = 1288, max sns = 2048, window size = 480.
2141 */
2142 uint8_t data_msg[23] = {0x40, 0x20, 0x0b, 0xff, 0xd1,
2143 0x61, 0x00, 0x3e, 0x0e, 0x51, 0x9f,
2144 0xff, 0xff, 0xfb, 0x80, 0x00, 0x00,
2145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
2146
2147 dl_tbf = create_dl_tbf(&the_bts, ms_class, egprs_ms_class, &trx_no);
2148 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
2149 prlcdlwindow = &dl_tbf->m_window;
2150 prlcmvb = &prlcdlwindow->m_v_b;
2151 prlcdlwindow->m_v_s = 1288;
2152 prlcdlwindow->m_v_a = 1176;
2153 prlcdlwindow->set_sns(2048);
2154 prlcdlwindow->set_ws(480);
2155 prlcmvb->mark_unacked(1176);
2156 prlcmvb->mark_unacked(1177);
2157 prlcmvb->mark_unacked(1286);
2158 prlcmvb->mark_unacked(1287);
2159
2160 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2161
2162 block = bitvec_alloc(23);
2163
2164 bitvec_unpack(block, data_msg);
2165
2166 bits.data = bits_data;
2167 bits.data_len = sizeof(bits_data);
2168 bits.cur_bit = 0;
2169
2170 decode_gsm_rlcmac_uplink(block, &ul_control_block);
2171
2172 ack_nack = &ul_control_block.u.Egprs_Packet_Downlink_Ack_Nack;
2173
2174 OSMO_ASSERT(prlcmvb->is_unacked(1176));
2175 OSMO_ASSERT(prlcmvb->is_unacked(1177));
2176 OSMO_ASSERT(prlcmvb->is_unacked(1286));
2177 OSMO_ASSERT(prlcmvb->is_unacked(1287));
2178
2179 Decoding::decode_egprs_acknack_bits(
2180 &ack_nack->EGPRS_AckNack.Desc, &bits,
2181 &bsn_begin, &bsn_end, &dl_tbf->m_window);
2182
2183 dl_tbf->rcvd_dl_ack(
2184 ack_nack->EGPRS_AckNack.Desc.FINAL_ACK_INDICATION,
2185 bsn_begin, &bits);
aravind sirsikarf2761382016-10-25 12:45:24 +05302186
aravind sirsikarfb41afa2016-11-02 15:48:00 +05302187 OSMO_ASSERT(prlcmvb->is_invalid(1176));
2188 OSMO_ASSERT(prlcmvb->is_invalid(1177));
2189 OSMO_ASSERT(prlcmvb->is_acked(1286));
2190 OSMO_ASSERT(prlcmvb->is_acked(1287));
aravind sirsikarf2761382016-10-25 12:45:24 +05302191
2192 bitvec_free(block);
2193 tbf_free(dl_tbf);
2194 printf("=== end %s ===\n", __func__);
2195}
2196
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302197static void test_tbf_egprs_two_phase_spb(void)
2198{
2199 BTS the_bts;
2200 int ts_no = 7;
2201 uint32_t fn = 2654218;
2202 uint16_t qta = 31;
2203 uint32_t tlli = 0xf1223344;
2204 const char *imsi = "0011223344";
2205 uint8_t ms_class = 1;
2206 uint8_t egprs_ms_class = 1;
2207 gprs_rlcmac_ul_tbf *ul_tbf;
2208 GprsMs *ms;
2209 uint8_t test_data[256];
2210
2211 printf("=== start %s ===\n", __func__);
2212
2213 memset(test_data, 1, sizeof(test_data));
2214
2215 setup_bts(&the_bts, ts_no, 4);
2216 the_bts.bts_data()->initial_mcs_dl = 9;
2217 the_bts.bts_data()->egprs_enabled = 1;
2218
2219 ul_tbf = establish_ul_tbf_two_phase_spb(&the_bts, ts_no, tlli, &fn, qta,
2220 ms_class, egprs_ms_class);
2221
2222 ms = ul_tbf->ms();
2223 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
2224 fprintf(stderr,
2225 "Got MS: TLLI = 0x%08x, TA = %d\n", ms->tlli(), ms->ta());
2226
2227 send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data));
2228
2229 printf("=== end %s ===\n", __func__);
2230}
2231
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002232static void test_tbf_egprs_two_phase()
2233{
2234 BTS the_bts;
2235 int ts_no = 7;
2236 uint32_t fn = 2654218;
2237 uint16_t qta = 31;
2238 uint32_t tlli = 0xf1223344;
2239 const char *imsi = "0011223344";
2240 uint8_t ms_class = 1;
2241 uint8_t egprs_ms_class = 1;
2242 gprs_rlcmac_ul_tbf *ul_tbf;
2243 GprsMs *ms;
2244 uint8_t test_data[256];
2245
2246 printf("=== start %s ===\n", __func__);
2247
2248 memset(test_data, 1, sizeof(test_data));
2249
2250 setup_bts(&the_bts, ts_no, 4);
2251 the_bts.bts_data()->initial_mcs_dl = 9;
2252 the_bts.bts_data()->egprs_enabled = 1;
2253
2254 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli, &fn, qta,
2255 ms_class, egprs_ms_class);
2256
2257 ms = ul_tbf->ms();
2258 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
2259 fprintf(stderr, "Got MS: TLLI = 0x%08x, TA = %d\n", ms->tlli(), ms->ta());
2260
2261 send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data));
2262
2263 printf("=== end %s ===\n", __func__);
2264}
2265
2266static void establish_and_use_egprs_dl_tbf(BTS *the_bts, int mcs)
2267{
2268 unsigned i;
2269 uint8_t ms_class = 11;
2270 uint8_t egprs_ms_class = 11;
2271 uint32_t fn = 0;
2272 uint8_t trx_no;
2273 uint32_t tlli = 0xffeeddcc;
2274 uint8_t test_data[512];
2275
2276 uint8_t rbb[64/8];
2277
2278 gprs_rlcmac_dl_tbf *dl_tbf;
2279
2280 printf("Testing MCS-%d\n", mcs);
2281
2282 memset(test_data, 1, sizeof(test_data));
2283 the_bts->bts_data()->initial_mcs_dl = mcs;
2284
2285 dl_tbf = create_dl_tbf(the_bts, ms_class, egprs_ms_class, &trx_no);
2286 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
2287
2288 for (i = 0; i < sizeof(llc_data); i++)
2289 llc_data[i] = i%256;
2290
2291 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2292
2293 /* Schedule a small LLC frame */
2294 dl_tbf->append_data(ms_class, 1000, test_data, 10);
2295
2296 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2297
2298 /* Drain the queue */
2299 while (dl_tbf->have_data())
2300 /* Request to send one RLC/MAC block */
2301 request_dl_rlc_block(dl_tbf, &fn);
2302
2303 /* Schedule a large LLC frame */
2304 dl_tbf->append_data(ms_class, 1000, test_data, sizeof(test_data));
2305
2306 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2307
2308 /* Drain the queue */
2309 while (dl_tbf->have_data())
2310 /* Request to send one RLC/MAC block */
2311 request_dl_rlc_block(dl_tbf, &fn);
2312
2313 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2314
2315 /* Receive a final ACK */
2316 dl_tbf->rcvd_dl_ack(1, dl_tbf->m_window.v_s(), rbb);
2317
2318 /* Clean up and ensure tbfs are in the correct state */
2319 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
2320 dl_tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE;
2321 check_tbf(dl_tbf);
2322 tbf_free(dl_tbf);
2323}
2324
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302325static gprs_rlcmac_dl_tbf *tbf_init(BTS *the_bts,
2326 int mcs)
2327{
2328 unsigned i;
2329 uint8_t ms_class = 11;
2330 uint8_t egprs_ms_class = 11;
2331 uint32_t fn = 0;
2332 uint8_t trx_no;
2333 uint32_t tlli = 0xffeeddcc;
2334 uint8_t test_data[512];
2335
2336 uint8_t rbb[64/8];
2337
2338 gprs_rlcmac_dl_tbf *dl_tbf;
2339
2340 memset(test_data, 1, sizeof(test_data));
2341 the_bts->bts_data()->initial_mcs_dl = mcs;
2342
2343 dl_tbf = create_dl_tbf(the_bts, ms_class, egprs_ms_class, &trx_no);
2344 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
2345
2346 for (i = 0; i < sizeof(test_data); i++)
2347 test_data[i] = i%256;
2348
2349 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2350
2351 /* Schedule a LLC frame
2352 * passing only 100 bytes, since it is enough to construct
2353 * 2 RLC data blocks. Which are enough to test Header Type 1
2354 * cases
2355 */
2356 dl_tbf->append_data(ms_class, 1000, test_data, 100);
2357
2358 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2359
2360 return dl_tbf;
2361
2362}
2363
2364static void tbf_cleanup(gprs_rlcmac_dl_tbf *dl_tbf)
2365{
2366 uint32_t fn = 0;
2367 uint8_t rbb[64/8];
2368
2369 /* Receive a final ACK */
2370 dl_tbf->rcvd_dl_ack(1, dl_tbf->m_window.v_s(), rbb);
2371
2372 /* Clean up and ensure tbfs are in the correct state */
2373 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
2374 dl_tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE;
2375 check_tbf(dl_tbf);
2376 tbf_free(dl_tbf);
2377
2378}
2379
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302380static void egprs_spb_to_normal_validation(BTS *the_bts,
2381 int mcs, int demanded_mcs)
2382{
2383 uint32_t fn = 0;
2384 gprs_rlcmac_dl_tbf *dl_tbf;
2385 uint8_t block_nr = 0;
2386 int index1 = 0;
2387 uint8_t bn;
2388 uint16_t bsn1, bsn2, bsn3;
2389 struct msgb *msg;
2390 struct gprs_rlc_dl_header_egprs_3 *egprs3;
2391 struct gprs_rlc_dl_header_egprs_2 *egprs2;
2392
2393 printf("Testing retx for MCS %d to reseg_mcs %d\n", mcs, demanded_mcs);
2394
2395 dl_tbf = tbf_init(the_bts, mcs);
2396
2397 /*
2398 * Table 10.4.8a.3.1 of 44.060.
2399 * (MCS7, MCS9) to (MCS2, MCS3) is not handled since it is same as
2400 * (MCS5, MCS6) to (MCS2, MCS3) transition
2401 */
2402 if (!(mcs == 6 && demanded_mcs == 3))
2403 return;
2404
2405 fn = fn_add_blocks(fn, 1);
2406 /* Send first RLC data block BSN 0 */
2407 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
2408 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0));
2409 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num()
2410 == mcs);
2411
2412 egprs2 = (struct gprs_rlc_dl_header_egprs_2 *) msg->data;
2413 bsn1 = (egprs2->bsn1_hi << 9) || (egprs2->bsn1_mid << 1)
2414 || (egprs2->bsn1_lo);
2415 dl_tbf->m_window.m_v_b.mark_nacked(0);
2416 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(0));
2417 OSMO_ASSERT(bsn1 == 0);
2418
2419 dl_tbf->ms()->set_current_cs_dl
2420 (static_cast < GprsCodingScheme::Scheme >
2421 (GprsCodingScheme::CS4 + demanded_mcs));
2422
2423 fn = fn_add_blocks(fn, 1);
2424
2425 /* Send first segment with demanded_mcs */
2426 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
2427 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(0));
2428 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num()
2429 == demanded_mcs);
2430 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2431 == EGPRS_RESEG_FIRST_SEG_SENT);
2432
2433 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2434 OSMO_ASSERT(egprs3->spb == 2);
2435
2436 /* Table 10.4.8a.3.1 of 44.060 */
2437 OSMO_ASSERT(egprs3->cps == 3);
2438
2439 /* Send second segment with demanded_mcs */
2440 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
2441 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0));
2442 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num()
2443 == demanded_mcs);
2444 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2445 == EGPRS_RESEG_SECOND_SEG_SENT);
2446
2447 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2448 /* Table 10.4.8a.3.1 of 44.060 */
2449 OSMO_ASSERT(egprs3->spb == 3);
2450 bsn2 = (egprs3->bsn1_hi << 9) || (egprs3->bsn1_mid << 1) ||
2451 (egprs3->bsn1_lo);
2452 OSMO_ASSERT(bsn2 == bsn1);
2453
2454 /* Table 10.4.8a.3.1 of 44.060 */
2455 OSMO_ASSERT(egprs3->cps == 3);
2456
2457 /* Handle (MCS3, MCS3) -> MCS6 case */
2458 dl_tbf->ms()->set_current_cs_dl
2459 (static_cast < GprsCodingScheme::Scheme >
2460 (GprsCodingScheme::CS4 + mcs));
2461
2462 dl_tbf->m_window.m_v_b.mark_nacked(0);
2463 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(0));
2464 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
2465 egprs2 = (struct gprs_rlc_dl_header_egprs_2 *) msg->data;
2466
2467 /* Table 10.4.8a.3.1 of 44.060 */
2468 OSMO_ASSERT(egprs2->cps == 0);
2469 bsn3 = (egprs2->bsn1_hi << 9) || (egprs2->bsn1_mid << 1) ||
2470 (egprs2->bsn1_lo);
2471 OSMO_ASSERT(bsn3 == bsn2);
2472
2473 tbf_cleanup(dl_tbf);
2474}
2475static void establish_and_use_egprs_dl_tbf_for_spb(BTS *the_bts,
2476 int mcs, int demanded_mcs)
2477{
2478 uint32_t fn = 0;
2479 gprs_rlcmac_dl_tbf *dl_tbf;
2480 uint8_t block_nr = 0;
2481 int index1 = 0;
2482 uint8_t bn;
2483 struct msgb *msg;
2484 struct gprs_rlc_dl_header_egprs_3 *egprs3;
2485
2486 printf("Testing retx for MCS %d to reseg_mcs %d\n", mcs, demanded_mcs);
2487
2488 dl_tbf = tbf_init(the_bts, mcs);
2489
2490 /*
2491 * Table 10.4.8a.3.1 of 44.060.
2492 * (MCS7, MCS9) to (MCS2, MCS3) is not handled since it is same as
2493 * (MCS5, MCS6) to (MCS2, MCS3) transition
2494 */
2495 /* TODO: Need to support of MCS8 -> MCS6 ->MCS3 transistion
2496 * Refer commit be881c028fc4da00c4046ecd9296727975c206a3
2497 * dated 2016-02-07 23:45:40 (UTC)
2498 */
2499 if (!(((mcs == 5) && (demanded_mcs == 2)) ||
2500 ((mcs == 6) && (demanded_mcs == 3)) ||
2501 ((mcs == 4) && (demanded_mcs == 1))))
2502 return;
2503
2504 fn = fn_add_blocks(fn, 1);
2505 /* Send first RLC data block BSN 0 */
2506 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
2507 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0));
2508 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num()
2509 == mcs);
2510
2511 dl_tbf->m_window.m_v_b.mark_nacked(0);
2512 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(0));
2513
2514 dl_tbf->ms()->set_current_cs_dl
2515 (static_cast < GprsCodingScheme::Scheme >
2516 (GprsCodingScheme::CS4 + demanded_mcs));
2517
2518 fn = fn_add_blocks(fn, 1);
2519
2520 /* Send first segment with demanded_mcs */
2521 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
2522 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(0));
2523 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num()
2524 == demanded_mcs);
2525 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2526 == EGPRS_RESEG_FIRST_SEG_SENT);
2527
2528 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2529 OSMO_ASSERT(egprs3->spb == 2);
2530
2531 /* Table 10.4.8a.3.1 of 44.060 */
2532 switch (demanded_mcs) {
2533 case 3:
2534 OSMO_ASSERT(egprs3->cps == 3);
2535 break;
2536 case 2:
2537 OSMO_ASSERT(egprs3->cps == 9);
2538 break;
2539 case 1:
2540 OSMO_ASSERT(egprs3->cps == 11);
2541 break;
2542 default:
2543 OSMO_ASSERT(false);
2544 break;
2545 }
2546
2547 /* Send second segment with demanded_mcs */
2548 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
2549 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0));
2550 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num()
2551 == demanded_mcs);
2552 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2553 == EGPRS_RESEG_SECOND_SEG_SENT);
2554
2555 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2556 /* Table 10.4.8a.3.1 of 44.060 */
2557 OSMO_ASSERT(egprs3->spb == 3);
2558
2559 /* Table 10.4.8a.3.1 of 44.060 */
2560 switch (demanded_mcs) {
2561 case 3:
2562 OSMO_ASSERT(egprs3->cps == 3);
2563 break;
2564 case 2:
2565 OSMO_ASSERT(egprs3->cps == 9);
2566 break;
2567 case 1:
2568 OSMO_ASSERT(egprs3->cps == 11);
2569 break;
2570 default:
2571 OSMO_ASSERT(false);
2572 break;
2573 }
2574 tbf_cleanup(dl_tbf);
2575}
2576
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302577static void establish_and_use_egprs_dl_tbf_for_retx(BTS *the_bts,
2578 int mcs, int demanded_mcs)
2579{
2580 uint32_t fn = 0;
2581 gprs_rlcmac_dl_tbf *dl_tbf;
2582 uint8_t block_nr = 0;
2583 int index1 = 0;
2584 uint8_t bn;
2585 struct msgb *msg;
2586
2587 printf("Testing retx for MCS %d - %d\n", mcs, demanded_mcs);
2588
2589 dl_tbf = tbf_init(the_bts, mcs);
2590
2591 /* For MCS reduction cases like MCS9->MCS6, MCS7->MCS5
2592 * The MCS transition are referred from table Table 8.1.1.2
2593 * of TS 44.060
2594 */
2595 /* TODO: Need to support of MCS8 -> MCS6 transistion
2596 * Refer commit be881c028fc4da00c4046ecd9296727975c206a3
2597 * dated 2016-02-07 23:45:40 (UTC)
2598 */
2599 if (((mcs == 9) && (demanded_mcs < 9)) ||
2600 ((mcs == 7) && (demanded_mcs < 7))) {
2601 fn = fn_add_blocks(fn, 1);
2602 /* Send 2 RLC data block */
2603 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
2604
2605 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0));
2606 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1));
2607 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num()
2608 == mcs);
2609 OSMO_ASSERT(dl_tbf->m_rlc.block(1)->cs_current_trans.to_num()
2610 == mcs);
2611
2612 dl_tbf->m_window.m_v_b.mark_nacked(0);
2613 dl_tbf->m_window.m_v_b.mark_nacked(1);
2614 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(0));
2615 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(1));
2616
2617 /* Set the demanded MCS to demanded_mcs */
2618 dl_tbf->ms()->set_current_cs_dl
2619 (static_cast < GprsCodingScheme::Scheme >
2620 (GprsCodingScheme::CS4 + demanded_mcs));
2621
2622 fn = fn_add_blocks(fn, 1);
2623 /* Retransmit the first RLC data block with demanded_mcs */
2624 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
2625 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0));
2626 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(1));
2627 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num()
2628 == demanded_mcs);
2629
2630 fn = fn_add_blocks(fn, 1);
2631 /* Retransmit the second RLC data block with demanded_mcs */
2632 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
2633 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0));
2634 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1));
2635 OSMO_ASSERT(dl_tbf->m_rlc.block(1)->cs_current_trans.to_num()
2636 == demanded_mcs);
2637 } else if (((mcs == 5) && (demanded_mcs > 6)) ||
2638 ((mcs == 6) && (demanded_mcs > 8))) {
2639 fn = fn_add_blocks(fn, 1);
2640 /* Send first RLC data block BSN 0 */
2641 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
2642 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0));
2643 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num()
2644 == mcs);
2645
2646 fn = fn_add_blocks(fn, 1);
2647 /* Send second RLC data block BSN 1 */
2648 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
2649 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1));
2650 OSMO_ASSERT(dl_tbf->m_rlc.block(1)->cs_current_trans.to_num()
2651 == mcs);
2652
2653 dl_tbf->m_window.m_v_b.mark_nacked(0);
2654 dl_tbf->m_window.m_v_b.mark_nacked(1);
2655 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(0));
2656 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(1));
2657
2658 dl_tbf->ms()->set_current_cs_dl
2659 (static_cast < GprsCodingScheme::Scheme >
2660 (GprsCodingScheme::CS4 + demanded_mcs));
2661
2662 fn = fn_add_blocks(fn, 1);
2663 /* Send first, second RLC data blocks with demanded_mcs */
2664 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
2665 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0));
2666 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1));
2667 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num()
2668 == demanded_mcs);
2669 OSMO_ASSERT(dl_tbf->m_rlc.block(1)->cs_current_trans.to_num()
2670 == demanded_mcs);
2671 } else if (mcs > 6) {
2672 /* No Mcs change cases are handled here for mcs > MCS6*/
2673 fn = fn_add_blocks(fn, 1);
2674 /* Send first,second RLC data blocks */
2675 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
2676 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0));
2677 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1));
2678 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num()
2679 == mcs);
2680 OSMO_ASSERT(dl_tbf->m_rlc.block(1)->cs_current_trans.to_num()
2681 == mcs);
2682
2683 dl_tbf->m_window.m_v_b.mark_nacked(0);
2684 dl_tbf->m_window.m_v_b.mark_nacked(1);
2685 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(0));
2686 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(1));
2687
2688 fn = fn_add_blocks(fn, 1);
2689 /* Send first,second RLC data blocks with demanded_mcs*/
2690 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
2691 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0));
2692 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1));
2693 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num()
2694 == mcs);
2695 OSMO_ASSERT(dl_tbf->m_rlc.block(1)->cs_current_trans.to_num()
2696 == mcs);
2697 } else {
2698
2699 /* No MCS change cases are handled here for mcs <= MCS6*/
2700 fn = fn_add_blocks(fn, 1);
2701 /* Send first RLC data block */
2702 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
2703 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0));
2704 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num()
2705 == mcs);
2706
2707 dl_tbf->m_window.m_v_b.mark_nacked(0);
2708 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(0));
2709
2710 fn = fn_add_blocks(fn, 1);
2711 /* Send first RLC data block with demanded_mcs */
2712 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
2713 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0));
2714 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num()
2715 == mcs);
2716 }
2717
2718 tbf_cleanup(dl_tbf);
2719}
2720
2721static void test_tbf_egprs_retx_dl(void)
2722{
2723 BTS the_bts;
2724 gprs_rlcmac_bts *bts;
2725 uint8_t ts_no = 4;
2726 int i, j;
2727
2728 printf("=== start %s ===\n", __func__);
2729
2730 bts = the_bts.bts_data();
2731 bts->cs_downgrade_threshold = 0;
2732 setup_bts(&the_bts, ts_no);
2733 bts->dl_tbf_idle_msec = 200;
2734 bts->egprs_enabled = 1;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302735 /* ARQ II */
2736 bts->dl_arq_type = EGPRS_ARQ2;
2737
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302738
2739 /* First parameter is current MCS, second one is demanded_mcs */
2740 establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 6, 6);
2741 establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 1, 9);
2742 establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 2, 8);
2743 establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 5, 7);
2744 establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 6, 9);
2745 establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 7, 5);
2746 establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 9, 6);
2747
2748 printf("=== end %s ===\n", __func__);
2749}
2750
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302751static void test_tbf_egprs_spb_dl(void)
2752{
2753 BTS the_bts;
2754 gprs_rlcmac_bts *bts;
2755 uint8_t ts_no = 4;
2756 int i, j;
2757
2758 printf("=== start %s ===\n", __func__);
2759
2760 bts = the_bts.bts_data();
2761 bts->cs_downgrade_threshold = 0;
2762 setup_bts(&the_bts, ts_no);
2763 bts->dl_tbf_idle_msec = 200;
2764 bts->egprs_enabled = 1;
2765
2766 /* ARQ I resegmentation support */
2767 bts->dl_arq_type = EGPRS_ARQ1;
2768
2769 /*
2770 * First parameter is current MCS, second one is demanded_mcs
2771 * currently only MCS5->MCS2, MCS6->3, MCS4->MCS1 is tested in UT
2772 * rest scenarios has been integration tested
2773 */
2774 establish_and_use_egprs_dl_tbf_for_spb(&the_bts, 6, 3);
2775 establish_and_use_egprs_dl_tbf_for_spb(&the_bts, 5, 2);
2776 establish_and_use_egprs_dl_tbf_for_spb(&the_bts, 4, 1);
2777 /* check MCS6->(MCS3+MCS3)->MCS6 case */
2778 egprs_spb_to_normal_validation(&the_bts, 6, 3);
2779
2780 printf("=== end %s ===\n", __func__);
2781}
2782
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002783static void test_tbf_egprs_dl()
2784{
2785 BTS the_bts;
2786 gprs_rlcmac_bts *bts;
2787 uint8_t ts_no = 4;
2788 int i;
2789
2790 printf("=== start %s ===\n", __func__);
2791
2792 bts = the_bts.bts_data();
2793
2794 setup_bts(&the_bts, ts_no);
2795 bts->dl_tbf_idle_msec = 200;
2796 bts->egprs_enabled = 1;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302797 /* ARQ II */
2798 bts->dl_arq_type = EGPRS_ARQ2;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002799
2800 for (i = 1; i <= 9; i++)
2801 establish_and_use_egprs_dl_tbf(&the_bts, i);
2802
2803 printf("=== end %s ===\n", __func__);
2804}
2805
2806
2807
Daniel Willmann341689d2014-06-11 18:33:14 +02002808static const struct log_info_cat default_categories[] = {
2809 {"DCSN1", "\033[1;31m", "Concrete Syntax Notation One (CSN1)", LOGL_INFO, 0},
2810 {"DL1IF", "\033[1;32m", "GPRS PCU L1 interface (L1IF)", LOGL_DEBUG, 1},
2811 {"DRLCMAC", "\033[0;33m", "GPRS RLC/MAC layer (RLCMAC)", LOGL_DEBUG, 1},
2812 {"DRLCMACDATA", "\033[0;33m", "GPRS RLC/MAC layer Data (RLCMAC)", LOGL_DEBUG, 1},
2813 {"DRLCMACDL", "\033[1;33m", "GPRS RLC/MAC layer Downlink (RLCMAC)", LOGL_DEBUG, 1},
2814 {"DRLCMACUL", "\033[1;36m", "GPRS RLC/MAC layer Uplink (RLCMAC)", LOGL_DEBUG, 1},
2815 {"DRLCMACSCHED", "\033[0;36m", "GPRS RLC/MAC layer Scheduling (RLCMAC)", LOGL_DEBUG, 1},
2816 {"DRLCMACMEAS", "\033[1;31m", "GPRS RLC/MAC layer Measurements (RLCMAC)", LOGL_INFO, 1},
Jacob Erlbeck56af6d52015-08-17 14:06:21 +02002817 {"DNS","\033[1;34m", "GPRS Network Service Protocol (NS)", LOGL_INFO , 1},
Daniel Willmann341689d2014-06-11 18:33:14 +02002818 {"DBSSGP","\033[1;34m", "GPRS BSS Gateway Protocol (BSSGP)", LOGL_INFO , 1},
2819 {"DPCU", "\033[1;35m", "GPRS Packet Control Unit (PCU)", LOGL_NOTICE, 1},
2820};
2821
2822static int filter_fn(const struct log_context *ctx,
2823 struct log_target *tar)
2824{
2825 return 1;
2826}
2827
2828const struct log_info debug_log_info = {
2829 filter_fn,
2830 (struct log_info_cat*)default_categories,
2831 ARRAY_SIZE(default_categories),
2832};
2833
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01002834int main(int argc, char **argv)
2835{
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02002836 struct vty_app_info pcu_vty_info = {0};
2837
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01002838 tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile TbfTest context");
2839 if (!tall_pcu_ctx)
2840 abort();
2841
2842 msgb_set_talloc_ctx(tall_pcu_ctx);
Daniel Willmann341689d2014-06-11 18:33:14 +02002843 osmo_init_logging(&debug_log_info);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01002844 log_set_use_color(osmo_stderr_target, 0);
2845 log_set_print_filename(osmo_stderr_target, 0);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02002846 bssgp_set_log_ss(DBSSGP);
2847
2848 vty_init(&pcu_vty_info);
2849 pcu_vty_init(&debug_log_info);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01002850
Jacob Erlbeckac89a552015-06-29 14:18:46 +02002851 test_tbf_base();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01002852 test_tbf_tlli_update();
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +01002853 test_tbf_final_ack(TEST_MODE_STANDARD);
2854 test_tbf_final_ack(TEST_MODE_REVERSE_FREE);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +01002855 test_tbf_delayed_release();
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +02002856 test_tbf_imsi();
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02002857 test_tbf_exhaustion();
Jacob Erlbeck41168642015-06-12 13:41:00 +02002858 test_tbf_dl_llc_loss();
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02002859 test_tbf_single_phase();
2860 test_tbf_two_phase();
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002861 test_tbf_ra_update_rach();
2862 test_tbf_dl_flow_and_rach_two_phase();
2863 test_tbf_dl_flow_and_rach_single_phase();
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002864 test_tbf_dl_reuse();
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002865 test_tbf_gprs_egprs();
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002866 test_tbf_ws();
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002867 test_tbf_egprs_two_phase();
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302868 test_tbf_egprs_two_phase_spb();
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002869 test_tbf_egprs_dl();
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302870 test_tbf_egprs_retx_dl();
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302871 test_tbf_egprs_spb_dl();
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302872 test_tbf_puan_urbb_len();
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302873 test_tbf_update_ws();
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302874 test_tbf_li_decoding();
aravind sirsikarf2761382016-10-25 12:45:24 +05302875 test_tbf_epdan_out_of_rx_window();
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05302876 test_immediate_assign_rej();
Jacob Erlbeck67c38502015-05-11 10:32:40 +02002877
2878 if (getenv("TALLOC_REPORT_FULL"))
2879 talloc_report_full(tall_pcu_ctx, stderr);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01002880 return EXIT_SUCCESS;
2881}
2882
2883/*
2884 * stubs that should not be reached
2885 */
2886extern "C" {
2887void l1if_pdch_req() { abort(); }
2888void l1if_connect_pdch() { abort(); }
2889void l1if_close_pdch() { abort(); }
2890void l1if_open_pdch() { abort(); }
2891}