blob: 7d786b42be307d280629459546391c51ede929c9 [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
Philippd935d882016-11-07 13:07:36 +010045#define DUMMY_FN 2654167
46
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010047void *tall_pcu_ctx;
48int16_t spoof_mnc = 0, spoof_mcc = 0;
49
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +010050static void check_tbf(gprs_rlcmac_tbf *tbf)
51{
52 OSMO_ASSERT(tbf);
Jacob Erlbeck04e72d32015-08-13 18:36:56 +020053 if (tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE))
54 OSMO_ASSERT(tbf->T == 3191 || tbf->T == 3193);
55 if (tbf->state_is(GPRS_RLCMAC_RELEASING))
56 OSMO_ASSERT(tbf->T != 0);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +010057}
58
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +020059/*
60static unsigned inc_fn(fn)
61{
62 unsigned next_fn;
63
64 next_fn = fn + 4;
65 if ((block_nr % 3) == 2)
66 next_fn ++;
67 next_fn = next_fn % 2715648;
68
69 return next_fn;
70}
71*/
72
Jacob Erlbeckac89a552015-06-29 14:18:46 +020073static void test_tbf_base()
74{
75
76 printf("=== start %s ===\n", __func__);
77
78 OSMO_ASSERT(GPRS_RLCMAC_DL_TBF == reverse(GPRS_RLCMAC_UL_TBF));
79 OSMO_ASSERT(GPRS_RLCMAC_UL_TBF == reverse(GPRS_RLCMAC_DL_TBF));
80
81 printf("=== end %s ===\n", __func__);
82}
83
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010084static void test_tbf_tlli_update()
85{
86 BTS the_bts;
Jacob Erlbeck93990462015-05-15 15:50:43 +020087 GprsMs *ms, *ms_new;
88
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +010089 printf("=== start %s ===\n", __func__);
90
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010091 the_bts.bts_data()->alloc_algorithm = alloc_algorithm_a;
92 the_bts.bts_data()->trx[0].pdch[2].enable();
93 the_bts.bts_data()->trx[0].pdch[3].enable();
94
95 /*
96 * Make a uplink and downlink allocation
97 */
Daniel Willmann48aa0b02014-07-16 18:54:10 +020098 gprs_rlcmac_tbf *dl_tbf = tbf_alloc_dl_tbf(the_bts.bts_data(),
Jacob Erlbeck5879c642015-07-10 10:41:36 +020099 NULL,
Jacob Erlbeck86b6f052015-11-27 15:17:34 +0100100 0, 0, 0, 0);
Jacob Erlbeckc6d4cee2015-06-29 13:03:46 +0200101 OSMO_ASSERT(dl_tbf != NULL);
Jacob Erlbeckbe0cbc12015-05-18 14:35:11 +0200102 dl_tbf->update_ms(0x2342, GPRS_RLCMAC_DL_TBF);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200103 dl_tbf->set_ta(4);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100104
Daniel Willmann48aa0b02014-07-16 18:54:10 +0200105 gprs_rlcmac_tbf *ul_tbf = tbf_alloc_ul_tbf(the_bts.bts_data(),
Jacob Erlbeck5879c642015-07-10 10:41:36 +0200106 dl_tbf->ms(),
Jacob Erlbeck86b6f052015-11-27 15:17:34 +0100107 0, 0, 0, 0);
Jacob Erlbeckc6d4cee2015-06-29 13:03:46 +0200108 OSMO_ASSERT(ul_tbf != NULL);
Jacob Erlbeck0e50ce62015-05-21 16:58:22 +0200109 ul_tbf->update_ms(0x2342, GPRS_RLCMAC_UL_TBF);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100110
Jacob Erlbeck93990462015-05-15 15:50:43 +0200111 ms = the_bts.ms_by_tlli(0x2342);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100112
Jacob Erlbeck93990462015-05-15 15:50:43 +0200113 OSMO_ASSERT(ms != NULL);
114 OSMO_ASSERT(ms->dl_tbf() == dl_tbf);
115 OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100116
117 /*
118 * Now check.. that DL changes and that the timing advance
119 * has changed.
120 */
Jacob Erlbeck0e50ce62015-05-21 16:58:22 +0200121 dl_tbf->update_ms(0x4232, GPRS_RLCMAC_DL_TBF);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100122
Jacob Erlbeck93990462015-05-15 15:50:43 +0200123 /* It is still there, since the new TLLI has not been used for UL yet */
124 ms_new = the_bts.ms_by_tlli(0x2342);
125 OSMO_ASSERT(ms == ms_new);
126
127 ms_new = the_bts.ms_by_tlli(0x4232);
128 OSMO_ASSERT(ms == ms_new);
129 OSMO_ASSERT(ms->dl_tbf() == dl_tbf);
130 OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
131
132 /* Now use the new TLLI for UL */
Jacob Erlbeck0e50ce62015-05-21 16:58:22 +0200133 ul_tbf->update_ms(0x4232, GPRS_RLCMAC_UL_TBF);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200134 ms_new = the_bts.ms_by_tlli(0x2342);
135 OSMO_ASSERT(ms_new == NULL);
Holger Hans Peter Freytherbc1626e2013-10-30 19:50:49 +0100136
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200137 ms_new = the_bts.ms_by_tlli(0x4232);
138 OSMO_ASSERT(ms_new != NULL);
139 OSMO_ASSERT(ms_new->ta() == 4);
140
141 OSMO_ASSERT(ul_tbf->ta() == 4);
142 OSMO_ASSERT(dl_tbf->ta() == 4);
143
144 ul_tbf->set_ta(6);
145
146 OSMO_ASSERT(ul_tbf->ta() == 6);
147 OSMO_ASSERT(dl_tbf->ta() == 6);
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100148
149 printf("=== end %s ===\n", __func__);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100150}
151
Daniel Willmann510d7d32014-08-15 18:19:41 +0200152static uint8_t llc_data[200];
153
154int pcu_sock_send(struct msgb *msg)
155{
156 return 0;
157}
158
Jacob Erlbecka700dd92015-06-02 16:00:41 +0200159static void setup_bts(BTS *the_bts, uint8_t ts_no, uint8_t cs = 1)
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100160{
161 gprs_rlcmac_bts *bts;
162 gprs_rlcmac_trx *trx;
163
164 bts = the_bts->bts_data();
165 bts->alloc_algorithm = alloc_algorithm_a;
Jacob Erlbecka700dd92015-06-02 16:00:41 +0200166 bts->initial_cs_dl = cs;
167 bts->initial_cs_ul = cs;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100168 trx = &bts->trx[0];
169
170 trx->pdch[ts_no].enable();
Philippd935d882016-11-07 13:07:36 +0100171 the_bts->set_current_frame_number(DUMMY_FN);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100172}
173
174static gprs_rlcmac_dl_tbf *create_dl_tbf(BTS *the_bts, uint8_t ms_class,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +0100175 uint8_t egprs_ms_class, uint8_t *trx_no_)
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100176{
177 gprs_rlcmac_bts *bts;
178 int tfi;
179 uint8_t trx_no;
180
181 gprs_rlcmac_dl_tbf *dl_tbf;
182
183 bts = the_bts->bts_data();
184
185 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_DL_TBF, &trx_no, -1);
186 OSMO_ASSERT(tfi >= 0);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +0100187 dl_tbf = tbf_alloc_dl_tbf(bts, NULL, trx_no, ms_class, egprs_ms_class, 1);
Max9bbe1602016-07-18 12:50:18 +0200188 dl_tbf->set_ta(0);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100189 check_tbf(dl_tbf);
190
191 /* "Establish" the DL TBF */
192 dl_tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_SEND_ASS;
193 dl_tbf->set_state(GPRS_RLCMAC_FLOW);
194 dl_tbf->m_wait_confirm = 0;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100195 check_tbf(dl_tbf);
196
197 *trx_no_ = trx_no;
198
199 return dl_tbf;
200}
201
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200202static unsigned fn2bn(unsigned fn)
203{
204 return (fn % 52) / 4;
205}
206
207static unsigned fn_add_blocks(unsigned fn, unsigned blocks)
208{
209 unsigned bn = fn2bn(fn) + blocks;
210 fn = fn - (fn % 52);
211 fn += bn * 4 + bn / 3;
212 return fn % 2715648;
213}
214
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200215static void request_dl_rlc_block(struct gprs_rlcmac_bts *bts,
Max878bd1f2016-07-20 13:05:05 +0200216 uint8_t trx_no, uint8_t ts_no,
Jacob Erlbeckee310902015-08-24 11:55:17 +0200217 uint32_t *fn, uint8_t *block_nr = NULL)
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100218{
Jacob Erlbeckee310902015-08-24 11:55:17 +0200219 uint8_t bn = fn2bn(*fn);
Max878bd1f2016-07-20 13:05:05 +0200220 gprs_rlcmac_rcv_rts_block(bts, trx_no, ts_no, *fn, bn);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200221 *fn = fn_add_blocks(*fn, 1);
Jacob Erlbeckee310902015-08-24 11:55:17 +0200222 bn += 1;
223 if (block_nr)
224 *block_nr = bn;
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100225}
226
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200227static void request_dl_rlc_block(struct gprs_rlcmac_tbf *tbf,
Jacob Erlbeckee310902015-08-24 11:55:17 +0200228 uint32_t *fn, uint8_t *block_nr = NULL)
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200229{
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200230 request_dl_rlc_block(tbf->bts->bts_data(), tbf->trx->trx_no,
Max878bd1f2016-07-20 13:05:05 +0200231 tbf->control_ts, fn, block_nr);
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200232}
233
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100234enum test_tbf_final_ack_mode {
235 TEST_MODE_STANDARD,
236 TEST_MODE_REVERSE_FREE
237};
238
239static void test_tbf_final_ack(enum test_tbf_final_ack_mode test_mode)
Daniel Willmann510d7d32014-08-15 18:19:41 +0200240{
241 BTS the_bts;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100242 uint8_t ts_no = 4;
243 unsigned i;
Daniel Willmann510d7d32014-08-15 18:19:41 +0200244 uint8_t ms_class = 45;
245 uint32_t fn;
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100246 uint8_t block_nr;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100247 uint8_t trx_no;
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200248 GprsMs *ms;
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200249 uint32_t tlli = 0xffeeddcc;
Daniel Willmann510d7d32014-08-15 18:19:41 +0200250
251 uint8_t rbb[64/8];
252
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100253 printf("=== start %s ===\n", __func__);
254
Daniel Willmann510d7d32014-08-15 18:19:41 +0200255 gprs_rlcmac_dl_tbf *dl_tbf;
256 gprs_rlcmac_tbf *new_tbf;
257
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100258 setup_bts(&the_bts, ts_no);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +0100259 dl_tbf = create_dl_tbf(&the_bts, ms_class, 0, &trx_no);
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200260 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200261 ms = dl_tbf->ms();
Daniel Willmann510d7d32014-08-15 18:19:41 +0200262
263 for (i = 0; i < sizeof(llc_data); i++)
264 llc_data[i] = i%256;
265
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100266 /* Schedule two LLC frames */
Daniel Willmann0f58af62014-09-19 11:57:21 +0200267 dl_tbf->append_data(ms_class, 1000, llc_data, sizeof(llc_data));
268 dl_tbf->append_data(ms_class, 1000, llc_data, sizeof(llc_data));
Daniel Willmann510d7d32014-08-15 18:19:41 +0200269
270
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100271 /* Send only a few RLC/MAC blocks */
Daniel Willmann510d7d32014-08-15 18:19:41 +0200272 fn = 0;
Jacob Erlbeckee310902015-08-24 11:55:17 +0200273 do {
Daniel Willmann510d7d32014-08-15 18:19:41 +0200274 /* Request to send one block */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200275 request_dl_rlc_block(dl_tbf, &fn, &block_nr);
Jacob Erlbeckee310902015-08-24 11:55:17 +0200276 } while (block_nr < 3);
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200277
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100278 OSMO_ASSERT(dl_tbf->have_data());
279 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
Daniel Willmann510d7d32014-08-15 18:19:41 +0200280
281 /* Queue a final ACK */
282 memset(rbb, 0, sizeof(rbb));
283 /* Receive a final ACK */
284 dl_tbf->rcvd_dl_ack(1, 1, rbb);
285
286 /* Clean up and ensure tbfs are in the correct state */
287 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200288 new_tbf = ms->dl_tbf();
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100289 check_tbf(new_tbf);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200290 OSMO_ASSERT(new_tbf != dl_tbf);
291 OSMO_ASSERT(new_tbf->tfi() == 1);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100292 check_tbf(dl_tbf);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200293 dl_tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE;
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100294 if (test_mode == TEST_MODE_REVERSE_FREE) {
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200295 GprsMs::Guard guard(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100296 tbf_free(new_tbf);
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200297 OSMO_ASSERT(ms->dl_tbf() == NULL);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100298 check_tbf(dl_tbf);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100299 tbf_free(dl_tbf);
300 } else {
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200301 GprsMs::Guard guard(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100302 tbf_free(dl_tbf);
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200303 OSMO_ASSERT(ms->dl_tbf() == new_tbf);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100304 check_tbf(new_tbf);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100305 tbf_free(new_tbf);
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200306 OSMO_ASSERT(ms->dl_tbf() == NULL);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100307 }
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100308
309 printf("=== end %s ===\n", __func__);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200310}
311
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100312static void test_tbf_delayed_release()
313{
314 BTS the_bts;
315 gprs_rlcmac_bts *bts;
316 uint8_t ts_no = 4;
317 unsigned i;
318 uint8_t ms_class = 45;
319 uint32_t fn = 0;
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100320 uint8_t trx_no;
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200321 uint32_t tlli = 0xffeeddcc;
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100322
323 uint8_t rbb[64/8];
324
325 gprs_rlcmac_dl_tbf *dl_tbf;
326
327 printf("=== start %s ===\n", __func__);
328
329 bts = the_bts.bts_data();
330
331 setup_bts(&the_bts, ts_no);
332 bts->dl_tbf_idle_msec = 200;
333
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +0100334 dl_tbf = create_dl_tbf(&the_bts, ms_class, 0, &trx_no);
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200335 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100336
337 for (i = 0; i < sizeof(llc_data); i++)
338 llc_data[i] = i%256;
339
340 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
341
342 /* Schedule two LLC frames */
343 dl_tbf->append_data(ms_class, 1000, llc_data, sizeof(llc_data));
344 dl_tbf->append_data(ms_class, 1000, llc_data, sizeof(llc_data));
345
346 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
347
348 /* Drain the queue */
349 while (dl_tbf->have_data())
350 /* Request to send one RLC/MAC block */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200351 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100352
353 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
354
355 /* ACK all blocks */
356 memset(rbb, 0xff, sizeof(rbb));
357 /* Receive an ACK */
358 dl_tbf->rcvd_dl_ack(0, dl_tbf->m_window.v_s(), rbb);
359 OSMO_ASSERT(dl_tbf->m_window.window_empty());
360
361 /* Force sending of a single block containing an LLC dummy command */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200362 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100363
364 /* Receive an ACK */
365 dl_tbf->rcvd_dl_ack(0, dl_tbf->m_window.v_s(), rbb);
366 OSMO_ASSERT(dl_tbf->m_window.window_empty());
367
368 /* Timeout (make sure fn % 52 remains valid) */
369 fn += 52 * ((msecs_to_frames(bts->dl_tbf_idle_msec + 100) + 51)/ 52);
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200370 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100371
372 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FINISHED));
373
374 /* Receive a final ACK */
375 dl_tbf->rcvd_dl_ack(1, dl_tbf->m_window.v_s(), rbb);
376
377 /* Clean up and ensure tbfs are in the correct state */
378 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100379 dl_tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE;
380 check_tbf(dl_tbf);
381 tbf_free(dl_tbf);
382 printf("=== end %s ===\n", __func__);
383}
384
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200385static void test_tbf_imsi()
386{
387 BTS the_bts;
388 uint8_t ts_no = 4;
389 uint8_t ms_class = 45;
390 uint8_t trx_no;
391 GprsMs *ms1, *ms2;
392
393 gprs_rlcmac_dl_tbf *dl_tbf[2];
394
395 printf("=== start %s ===\n", __func__);
396
397 setup_bts(&the_bts, ts_no);
398
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +0100399 dl_tbf[0] = create_dl_tbf(&the_bts, ms_class, 0, &trx_no);
400 dl_tbf[1] = create_dl_tbf(&the_bts, ms_class, 0, &trx_no);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200401
402 dl_tbf[0]->update_ms(0xf1000001, GPRS_RLCMAC_DL_TBF);
403 dl_tbf[1]->update_ms(0xf1000002, GPRS_RLCMAC_DL_TBF);
404
405 dl_tbf[0]->assign_imsi("001001000000001");
406 ms1 = the_bts.ms_store().get_ms(0, 0, "001001000000001");
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200407 OSMO_ASSERT(ms1 != NULL);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200408 ms2 = the_bts.ms_store().get_ms(0xf1000001);
409 OSMO_ASSERT(ms2 != NULL);
410 OSMO_ASSERT(strcmp(ms2->imsi(), "001001000000001") == 0);
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200411 OSMO_ASSERT(ms1 == ms2);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200412
413 /* change the IMSI on TBF 0 */
414 dl_tbf[0]->assign_imsi("001001000000002");
415 ms1 = the_bts.ms_store().get_ms(0, 0, "001001000000001");
416 OSMO_ASSERT(ms1 == NULL);
417 ms1 = the_bts.ms_store().get_ms(0, 0, "001001000000002");
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200418 OSMO_ASSERT(ms1 != NULL);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200419 OSMO_ASSERT(strcmp(ms2->imsi(), "001001000000002") == 0);
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200420 OSMO_ASSERT(ms1 == ms2);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200421
422 /* use the same IMSI on TBF 2 */
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200423 {
424 GprsMs::Guard guard(ms2);
425 dl_tbf[1]->assign_imsi("001001000000002");
426 ms1 = the_bts.ms_store().get_ms(0, 0, "001001000000002");
427 OSMO_ASSERT(ms1 != NULL);
428 OSMO_ASSERT(ms1 != ms2);
429 OSMO_ASSERT(strcmp(ms1->imsi(), "001001000000002") == 0);
430 OSMO_ASSERT(strcmp(ms2->imsi(), "") == 0);
431 }
432
433 ms2 = the_bts.ms_store().get_ms(0xf1000001);
434 OSMO_ASSERT(ms2 == NULL);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200435
436 tbf_free(dl_tbf[1]);
437 ms1 = the_bts.ms_store().get_ms(0, 0, "001001000000002");
438 OSMO_ASSERT(ms1 == NULL);
439
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200440 printf("=== end %s ===\n", __func__);
441}
442
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200443static void test_tbf_exhaustion()
444{
445 BTS the_bts;
446 gprs_rlcmac_bts *bts;
447 unsigned i;
448 uint8_t ts_no = 4;
449 uint8_t ms_class = 45;
450 int rc = 0;
451
452 uint8_t buf[256] = {0};
453
454 printf("=== start %s ===\n", __func__);
455
456 bts = the_bts.bts_data();
457 setup_bts(&the_bts, ts_no);
458 gprs_bssgp_create_and_connect(bts, 33001, 0, 33001,
459 1234, 1234, 1234, 1, 1, 0, 0, 0);
460
461 for (i = 0; i < 1024; i++) {
462 uint32_t tlli = 0xc0000000 + i;
463 char imsi[16] = {0};
464 unsigned delay_csec = 1000;
465
Jacob Erlbeck9a2845d2015-05-21 12:06:58 +0200466 snprintf(imsi, sizeof(imsi), "001001%09d", i);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200467
Jacob Erlbeck14e00f82015-11-27 18:10:39 +0100468 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200469 delay_csec, buf, sizeof(buf));
470
471 if (rc < 0)
472 break;
473 }
474
475 OSMO_ASSERT(rc == -EBUSY);
476 printf("=== end %s ===\n", __func__);
477
478 gprs_bssgp_destroy();
479}
480
Jacob Erlbeck41168642015-06-12 13:41:00 +0200481static void test_tbf_dl_llc_loss()
482{
483 BTS the_bts;
484 gprs_rlcmac_bts *bts;
485 uint8_t ts_no = 4;
486 uint8_t ms_class = 45;
487 int rc = 0;
488 uint32_t tlli = 0xc0123456;
489 const char *imsi = "001001000123456";
490 unsigned delay_csec = 1000;
491 GprsMs *ms;
492
493 uint8_t buf[19];
494
495 printf("=== start %s ===\n", __func__);
496
497 bts = the_bts.bts_data();
498 setup_bts(&the_bts, ts_no);
499 bts->ms_idle_sec = 10; /* keep the MS object */
500
501 gprs_bssgp_create_and_connect(bts, 33001, 0, 33001,
502 1234, 1234, 1234, 1, 1, 0, 0, 0);
503
504 /* Handle LLC frame 1 */
505 memset(buf, 1, sizeof(buf));
Jacob Erlbeck14e00f82015-11-27 18:10:39 +0100506 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200507 delay_csec, buf, sizeof(buf));
508 OSMO_ASSERT(rc >= 0);
509
510 ms = the_bts.ms_store().get_ms(0, 0, imsi);
511 OSMO_ASSERT(ms != NULL);
512 OSMO_ASSERT(ms->dl_tbf() != NULL);
Max9bbe1602016-07-18 12:50:18 +0200513 ms->dl_tbf()->set_ta(0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200514
515 /* Handle LLC frame 2 */
516 memset(buf, 2, sizeof(buf));
Jacob Erlbeck14e00f82015-11-27 18:10:39 +0100517 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200518 delay_csec, buf, sizeof(buf));
519 OSMO_ASSERT(rc >= 0);
520
521 /* TBF establishment fails (timeout) */
522 tbf_free(ms->dl_tbf());
523
524 /* Handle LLC frame 3 */
525 memset(buf, 3, sizeof(buf));
Jacob Erlbeck14e00f82015-11-27 18:10:39 +0100526 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200527 delay_csec, buf, sizeof(buf));
528 OSMO_ASSERT(rc >= 0);
529
530 OSMO_ASSERT(ms->dl_tbf() != NULL);
531
532 /* Get first BSN */
533 struct msgb *msg;
534 int fn = 0;
535 uint8_t expected_data = 1;
536
537 while (ms->dl_tbf()->have_data()) {
538 msg = ms->dl_tbf()->create_dl_acked_block(fn += 4, 7);
539 fprintf(stderr, "MSG = %s\n", msgb_hexdump(msg));
540 OSMO_ASSERT(msgb_length(msg) == 23);
Jacob Erlbeck409efa12015-06-12 14:06:09 +0200541 OSMO_ASSERT(msgb_data(msg)[10] == expected_data);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200542 expected_data += 1;
543 }
Jacob Erlbeck409efa12015-06-12 14:06:09 +0200544 OSMO_ASSERT(expected_data-1 == 3);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200545
546 printf("=== end %s ===\n", __func__);
547
548 gprs_bssgp_destroy();
549}
550
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200551static gprs_rlcmac_ul_tbf *establish_ul_tbf_single_phase(BTS *the_bts,
552 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta)
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200553{
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200554 GprsMs *ms;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200555 int tfi = 0;
556 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200557 uint8_t trx_no = 0;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200558 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeck20f6fd12015-06-08 11:05:45 +0200559 struct pcu_l1_meas meas;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200560
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200561 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200562
bhargava959d1de2016-08-17 15:17:21 +0530563 the_bts->rcv_rach(0x03, *fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200564
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200565 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200566 OSMO_ASSERT(ul_tbf != NULL);
567
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200568 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200569
570 uint8_t data_msg[23] = {
571 0x00, /* GPRS_RLCMAC_DATA_BLOCK << 6 */
572 uint8_t(1 | (tfi << 2)),
573 uint8_t(1), /* BSN:7, E:1 */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200574 uint8_t(tlli >> 24), uint8_t(tlli >> 16),
575 uint8_t(tlli >> 8), uint8_t(tlli), /* TLLI */
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200576 };
577
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200578 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
579 pdch->rcv_block(&data_msg[0], sizeof(data_msg), *fn, &meas);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200580
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200581 ms = the_bts->ms_by_tlli(tlli);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200582 OSMO_ASSERT(ms != NULL);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200583
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200584 return ul_tbf;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200585}
586
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200587static void send_ul_mac_block(BTS *the_bts, unsigned trx_no, unsigned ts_no,
588 RlcMacUplink_t *ulreq, unsigned fn)
589{
590 bitvec *rlc_block;
591 uint8_t buf[64];
592 int num_bytes;
593 struct gprs_rlcmac_pdch *pdch;
594 struct pcu_l1_meas meas;
595
596 meas.set_rssi(31);
597
598 rlc_block = bitvec_alloc(23);
599
600 encode_gsm_rlcmac_uplink(rlc_block, ulreq);
601 num_bytes = bitvec_pack(rlc_block, &buf[0]);
602 OSMO_ASSERT(size_t(num_bytes) < sizeof(buf));
603 bitvec_free(rlc_block);
604
Jacob Erlbeckaf75ce82015-08-26 13:22:28 +0200605 the_bts->set_current_block_frame_number(fn, 0);
606
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200607 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
608 pdch->rcv_block(&buf[0], num_bytes, fn, &meas);
609}
610
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200611static void send_control_ack(gprs_rlcmac_tbf *tbf)
612{
613 RlcMacUplink_t ulreq = {0};
614
615 OSMO_ASSERT(tbf->poll_fn != 0);
Jacob Erlbeck8eb17142016-01-22 17:58:17 +0100616 OSMO_ASSERT(tbf->is_control_ts(tbf->poll_ts));
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200617
618 ulreq.u.MESSAGE_TYPE = MT_PACKET_CONTROL_ACK;
619 Packet_Control_Acknowledgement_t *ctrl_ack =
620 &ulreq.u.Packet_Control_Acknowledgement;
621
622 ctrl_ack->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
623 ctrl_ack->TLLI = tbf->tlli();
Jacob Erlbeck8eb17142016-01-22 17:58:17 +0100624 send_ul_mac_block(tbf->bts, tbf->trx->trx_no, tbf->poll_ts,
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200625 &ulreq, tbf->poll_fn);
626}
627
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530628static gprs_rlcmac_ul_tbf *puan_urbb_len_issue(BTS *the_bts,
629 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
630 uint8_t ms_class, uint8_t egprs_ms_class)
631{
632 GprsMs *ms;
633 uint32_t rach_fn = *fn - 51;
634 uint32_t sba_fn = *fn + 52;
635 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +0100636 int tfi = 0;
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530637 gprs_rlcmac_ul_tbf *ul_tbf;
638 struct gprs_rlcmac_pdch *pdch;
639 gprs_rlcmac_bts *bts;
640 RlcMacUplink_t ulreq = {0};
641 struct pcu_l1_meas meas;
642 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
643 GprsCodingScheme cs;
644
645 meas.set_rssi(31);
646 bts = the_bts->bts_data();
647
648 /* needed to set last_rts_fn in the PDCH object */
649 request_dl_rlc_block(bts, trx_no, ts_no, fn);
650
651 /*
652 * simulate RACH, this sends an Immediate
653 * Assignment Uplink on the AGCH
654 */
Aravind Sirsikarfd713842016-08-28 17:55:05 +0530655 the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530656
657 /* get next free TFI */
658 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
659
660 /* fake a resource request */
661 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
662 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
663 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
664 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
665 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability = 1;
666 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
667 Count_MS_RA_capability_value = 1;
668 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
669 MS_RA_capability_value[0].u.Content.
670 Exist_Multislot_capability = 1;
671 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
672 MS_RA_capability_value[0].u.Content.Multislot_capability.
673 Exist_GPRS_multislot_class = 1;
674 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
675 MS_RA_capability_value[0].u.Content.Multislot_capability.
676 GPRS_multislot_class = ms_class;
677 if (egprs_ms_class) {
678 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
679 MS_RA_capability_value[0].u.Content.
680 Multislot_capability.Exist_EGPRS_multislot_class = 1;
681 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
682 MS_RA_capability_value[0].u.Content.
683 Multislot_capability.EGPRS_multislot_class = ms_class;
684 }
685
686 send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
687
688 /* check the TBF */
689 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
690 OSMO_ASSERT(ul_tbf);
691 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
692
693 /* send packet uplink assignment */
694 *fn = sba_fn;
695 request_dl_rlc_block(ul_tbf, fn);
696
697 /* send real acknowledgement */
698 send_control_ack(ul_tbf);
699
700 check_tbf(ul_tbf);
701 /* send fake data */
702 uint8_t data_msg[42] = {
703 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
Neels Hofmeyrd34646a2017-02-08 17:07:40 +0100704 (uint8_t)(tfi << 1),
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530705 1, /* BSN:7, E:1 */
706 };
707
708 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
709 pdch->rcv_block(&data_msg[0], 23, *fn, &meas);
710
711 ms = the_bts->ms_by_tlli(tlli);
712 OSMO_ASSERT(ms != NULL);
713 OSMO_ASSERT(ms->ta() == qta/4);
714 OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
715
716 /*
717 * TS 44.060, B.8.1
718 * first seg received first, later second seg
719 */
720 cs = GprsCodingScheme::MCS3;
721 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
722 egprs3->si = 0;
723 egprs3->r = 1;
724 egprs3->cv = 7;
725 egprs3->tfi_hi = tfi & 0x03;
726 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
727 egprs3->bsn1_hi = 1;
728 egprs3->bsn1_lo = 0;
729 egprs3->cps_hi = 1;
730 data_msg[3] = 0xff;
731 egprs3->pi = 0;
732 egprs3->cps_lo = 1;
733 egprs3->rsb = 0;
734 egprs3->spb = 0;
735 egprs3->pi = 0;
736
737 pdch->rcv_block(data_msg, 42, *fn, &meas);
738
739 struct msgb *msg1 = ul_tbf->create_ul_ack(*fn, ts_no);
740
741 OSMO_ASSERT(!strcmp(osmo_hexdump(msg1->data, msg1->data_len),
742 "40 24 01 3f 3e 24 46 68 90 87 b0 06 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b "
743 ));
744
745 egprs3->si = 0;
746 egprs3->r = 1;
747 egprs3->cv = 7;
748 egprs3->tfi_hi = tfi & 0x03;
749 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
750 egprs3->bsn1_hi = 4;
751 egprs3->bsn1_lo = 0;
752 egprs3->cps_hi = 1;
753 data_msg[3] = 0xff;
754 egprs3->pi = 0;
755 egprs3->cps_lo = 1;
756 egprs3->rsb = 0;
757 egprs3->spb = 0;
758
759 pdch->rcv_block(data_msg, 42, *fn, &meas);
760
761 msg1 = ul_tbf->create_ul_ack(*fn, ts_no);
762
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530763 OSMO_ASSERT(!strcmp(osmo_hexdump(msg1->data, msg1->data_len),
Aravind Sirsikareebcb1e2016-08-25 16:40:23 +0530764 "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 +0530765 ));
766
767 return ul_tbf;
768}
769
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530770static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(BTS *the_bts,
771 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
772 uint8_t ms_class, uint8_t egprs_ms_class)
773{
774 GprsMs *ms;
775 uint32_t rach_fn = *fn - 51;
776 uint32_t sba_fn = *fn + 52;
777 uint8_t trx_no = 0;
778 int tfi = 0, i = 0;
779 gprs_rlcmac_ul_tbf *ul_tbf;
780 struct gprs_rlcmac_pdch *pdch;
781 gprs_rlcmac_bts *bts;
782 RlcMacUplink_t ulreq = {0};
783 struct pcu_l1_meas meas;
784 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
785 GprsCodingScheme cs;
786
787 meas.set_rssi(31);
788 bts = the_bts->bts_data();
789
790 /* needed to set last_rts_fn in the PDCH object */
791 request_dl_rlc_block(bts, trx_no, ts_no, fn);
792
793 /*
794 * simulate RACH, this sends an Immediate
795 * Assignment Uplink on the AGCH
796 */
bhargava959d1de2016-08-17 15:17:21 +0530797 the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530798
799 /* get next free TFI */
800 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
801
802 /* fake a resource request */
803 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
804 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
805 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
806 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
807 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability = 1;
808 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
809 Count_MS_RA_capability_value = 1;
810 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
811 MS_RA_capability_value[0].u.Content.
812 Exist_Multislot_capability = 1;
813 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
814 MS_RA_capability_value[0].u.Content.Multislot_capability.
815 Exist_GPRS_multislot_class = 1;
816 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
817 MS_RA_capability_value[0].u.Content.Multislot_capability.
818 GPRS_multislot_class = ms_class;
819 if (egprs_ms_class) {
820 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
821 MS_RA_capability_value[0].u.Content.
822 Multislot_capability.Exist_EGPRS_multislot_class = 1;
823 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
824 MS_RA_capability_value[0].u.Content.
825 Multislot_capability.EGPRS_multislot_class = ms_class;
826 }
827
828 send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
829
830 /* check the TBF */
831 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
832 OSMO_ASSERT(ul_tbf != NULL);
833 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
834
835 /* send packet uplink assignment */
836 *fn = sba_fn;
837 request_dl_rlc_block(ul_tbf, fn);
838
839 /* send real acknowledgement */
840 send_control_ack(ul_tbf);
841
842 check_tbf(ul_tbf);
843
844 /* send fake data */
845 uint8_t data_msg[42] = {
846 0x00 | 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
847 uint8_t(0 | (tfi << 1)),
848 uint8_t(1), /* BSN:7, E:1 */
849 };
850
851 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
852 pdch->rcv_block(&data_msg[0], 23, *fn, &meas);
853
854 ms = the_bts->ms_by_tlli(tlli);
855 OSMO_ASSERT(ms != NULL);
856 OSMO_ASSERT(ms->ta() == qta/4);
857 OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
858
859 /*
860 * TS 44.060, B.8.1
861 * first seg received first, later second seg
862 */
863 cs = GprsCodingScheme::MCS3;
864 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
865 egprs3->si = 1;
866 egprs3->r = 1;
867 egprs3->cv = 7;
868 egprs3->tfi_hi = tfi & 0x03;
869 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
870 egprs3->bsn1_hi = 1;
871 egprs3->bsn1_lo = 0;
872 egprs3->cps_hi = 1;
873 data_msg[3] = 0xff;
874 egprs3->pi = 0;
875 egprs3->cps_lo = 1;
876 egprs3->rsb = 0;
877 egprs3->spb = 2;
878 egprs3->pi = 0;
879
880 pdch->rcv_block(data_msg, 42, *fn, &meas);
881
882 struct gprs_rlc_data *block = ul_tbf->m_rlc.block(1);
883
884 /* check the status of the block */
885 OSMO_ASSERT(block->spb_status.block_status_ul ==
886 EGPRS_RESEG_FIRST_SEG_RXD);
887
888 egprs3->si = 1;
889 egprs3->r = 1;
890 egprs3->cv = 7;
891 egprs3->tfi_hi = tfi & 0x03;
892 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
893 egprs3->bsn1_hi = 1;
894 egprs3->bsn1_lo = 0;
895 egprs3->cps_hi = 1;
896 data_msg[3] = 0xff;
897 egprs3->pi = 0;
898 egprs3->cps_lo = 1;
899 egprs3->rsb = 0;
900 egprs3->spb = 3;
901
902 pdch->rcv_block(data_msg, 42, *fn, &meas);
903
904 /* check the status of the block */
905 OSMO_ASSERT(block->spb_status.block_status_ul ==
906 EGPRS_RESEG_DEFAULT);
907 OSMO_ASSERT(block->cs_last ==
908 GprsCodingScheme::MCS6);
909 /* Assembled MCS is MCS6. so the size is 74 */
910 OSMO_ASSERT(block->len == 74);
911
912 /*
913 * TS 44.060, B.8.1
914 * second seg first, later first seg
915 */
916 memset(data_msg, 0, sizeof(data_msg));
917
918 cs = GprsCodingScheme::MCS3;
919 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
920 egprs3->si = 1;
921 egprs3->r = 1;
922 egprs3->cv = 7;
923 egprs3->tfi_hi = tfi & 0x03;
924 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
925 egprs3->bsn1_hi = 2;
926 egprs3->bsn1_lo = 0;
927 egprs3->cps_hi = 1;
928 data_msg[3] = 0xff;
929 egprs3->pi = 0;
930 egprs3->cps_lo = 1;
931 egprs3->rsb = 0;
932 egprs3->spb = 3;
933 egprs3->pi = 0;
934
935 pdch->rcv_block(data_msg, 42, *fn, &meas);
936
937 block = ul_tbf->m_rlc.block(2);
938 /* check the status of the block */
939 OSMO_ASSERT(block->spb_status.block_status_ul ==
940 EGPRS_RESEG_SECOND_SEG_RXD);
941
942 egprs3->si = 1;
943 egprs3->r = 1;
944 egprs3->cv = 7;
945 egprs3->tfi_hi = tfi & 0x03;
946 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
947 egprs3->bsn1_hi = 2;
948 egprs3->bsn1_lo = 0;
949 egprs3->cps_hi = 1;
950 data_msg[3] = 0xff;
951 egprs3->pi = 0;
952 egprs3->cps_lo = 1;
953 egprs3->rsb = 0;
954 egprs3->spb = 2;
955 egprs3->pi = 0;
956
957 pdch->rcv_block(data_msg, 42, *fn, &meas);
958
959 /* check the status of the block */
960 OSMO_ASSERT(block->spb_status.block_status_ul ==
961 EGPRS_RESEG_DEFAULT);
962 OSMO_ASSERT(block->cs_last ==
963 GprsCodingScheme::MCS6);
964 /* Assembled MCS is MCS6. so the size is 74 */
965 OSMO_ASSERT(block->len == 74);
966
967 /*
968 * TS 44.060, B.8.1
969 * Error scenario with spb as 1
970 */
971 cs = GprsCodingScheme::MCS3;
972 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
973 egprs3->si = 1;
974 egprs3->r = 1;
975 egprs3->cv = 7;
976 egprs3->tfi_hi = tfi & 0x03;
977 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
978 egprs3->bsn1_hi = 3;
979 egprs3->bsn1_lo = 0;
980 egprs3->cps_hi = 1;
981 data_msg[3] = 0xff;
982 egprs3->pi = 0;
983 egprs3->cps_lo = 1;
984 egprs3->rsb = 0;
985 egprs3->spb = 1;
986 egprs3->pi = 0;
987
988 pdch->rcv_block(data_msg, 42, *fn, &meas);
989
990 block = ul_tbf->m_rlc.block(3);
991 /* check the status of the block */
992 OSMO_ASSERT(block->spb_status.block_status_ul ==
993 EGPRS_RESEG_DEFAULT);
994 /*
995 * TS 44.060, B.8.1
996 * comparison of rlc_data for multiple scenarios
997 * Receive First, the second(BSN 3)
998 * Receive First, First then Second(BSN 4)
999 * Receive Second then First(BSN 5)
1000 * after above 3 scenarios are triggered,
1001 * rlc_data of all 3 BSN are compared
1002 */
1003
1004 /* Initialize the data_msg */
1005 for (i = 0; i < 42; i++)
1006 data_msg[i] = i;
1007
1008 cs = GprsCodingScheme::MCS3;
1009 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1010 egprs3->si = 1;
1011 egprs3->r = 1;
1012 egprs3->cv = 7;
1013 egprs3->tfi_hi = tfi & 0x03;
1014 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1015 egprs3->bsn1_hi = 3;
1016 egprs3->bsn1_lo = 0;
1017 egprs3->cps_hi = 1;
1018 data_msg[3] = 0xff;
1019 egprs3->pi = 0;
1020 egprs3->cps_lo = 1;
1021 egprs3->rsb = 0;
1022 egprs3->spb = 2;
1023 egprs3->pi = 0;
1024
1025 pdch->rcv_block(data_msg, 42, *fn, &meas);
1026
1027 block = ul_tbf->m_rlc.block(3);
1028 /* check the status of the block */
1029 OSMO_ASSERT(block->spb_status.block_status_ul ==
1030 EGPRS_RESEG_FIRST_SEG_RXD);
1031
1032 cs = GprsCodingScheme::MCS3;
1033 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1034 egprs3->si = 1;
1035 egprs3->r = 1;
1036 egprs3->cv = 7;
1037 egprs3->tfi_hi = tfi & 0x03;
1038 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1039 egprs3->bsn1_hi = 3;
1040 egprs3->bsn1_lo = 0;
1041 egprs3->cps_hi = 1;
1042 data_msg[3] = 0xff;
1043 egprs3->pi = 0;
1044 egprs3->cps_lo = 1;
1045 egprs3->rsb = 0;
1046 egprs3->spb = 3;
1047 egprs3->pi = 0;
1048
1049 pdch->rcv_block(data_msg, 42, *fn, &meas);
1050
1051 block = ul_tbf->m_rlc.block(3);
1052 /* check the status of the block */
1053 OSMO_ASSERT(block->spb_status.block_status_ul ==
1054 EGPRS_RESEG_DEFAULT);
1055 /* Assembled MCS is MCS6. so the size is 74 */
1056 OSMO_ASSERT(block->len == 74);
1057 OSMO_ASSERT(block->cs_last ==
1058 GprsCodingScheme::MCS6);
1059
1060 cs = GprsCodingScheme::MCS3;
1061 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1062 egprs3->si = 1;
1063 egprs3->r = 1;
1064 egprs3->cv = 7;
1065 egprs3->tfi_hi = tfi & 0x03;
1066 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1067 egprs3->bsn1_hi = 4;
1068 egprs3->bsn1_lo = 0;
1069 egprs3->cps_hi = 1;
1070 data_msg[3] = 0xff;
1071 egprs3->pi = 0;
1072 egprs3->cps_lo = 1;
1073 egprs3->rsb = 0;
1074 egprs3->spb = 2;
1075 egprs3->pi = 0;
1076
1077 pdch->rcv_block(data_msg, 42, *fn, &meas);
1078
1079 block = ul_tbf->m_rlc.block(4);
1080 /* check the status of the block */
1081 OSMO_ASSERT(block->spb_status.block_status_ul ==
1082 EGPRS_RESEG_FIRST_SEG_RXD);
1083
1084 cs = GprsCodingScheme::MCS3;
1085 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1086 egprs3->si = 1;
1087 egprs3->r = 1;
1088 egprs3->cv = 7;
1089 egprs3->tfi_hi = tfi & 0x03;
1090 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1091 egprs3->bsn1_hi = 4;
1092 egprs3->bsn1_lo = 0;
1093 egprs3->cps_hi = 1;
1094 data_msg[3] = 0xff;
1095 egprs3->pi = 0;
1096 egprs3->cps_lo = 1;
1097 egprs3->rsb = 0;
1098 egprs3->spb = 2;
1099 egprs3->pi = 0;
1100
1101 pdch->rcv_block(data_msg, 42, *fn, &meas);
1102
1103 block = ul_tbf->m_rlc.block(4);
1104 /* check the status of the block */
1105 OSMO_ASSERT(block->spb_status.block_status_ul ==
1106 EGPRS_RESEG_FIRST_SEG_RXD);
1107
1108 cs = GprsCodingScheme::MCS3;
1109 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1110 egprs3->si = 1;
1111 egprs3->r = 1;
1112 egprs3->cv = 7;
1113 egprs3->tfi_hi = tfi & 0x03;
1114 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1115 egprs3->bsn1_hi = 4;
1116 egprs3->bsn1_lo = 0;
1117 egprs3->cps_hi = 1;
1118 data_msg[3] = 0xff;
1119 egprs3->pi = 0;
1120 egprs3->cps_lo = 1;
1121 egprs3->rsb = 0;
1122 egprs3->spb = 3;
1123 egprs3->pi = 0;
1124
1125 pdch->rcv_block(data_msg, 42, *fn, &meas);
1126
1127 block = ul_tbf->m_rlc.block(4);
1128 /* check the status of the block */
1129 OSMO_ASSERT(block->spb_status.block_status_ul ==
1130 EGPRS_RESEG_DEFAULT);
1131 OSMO_ASSERT(block->cs_last ==
1132 GprsCodingScheme::MCS6);
1133 /* Assembled MCS is MCS6. so the size is 74 */
1134 OSMO_ASSERT(block->len == 74);
1135
1136 cs = GprsCodingScheme::MCS3;
1137 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1138 egprs3->si = 1;
1139 egprs3->r = 1;
1140 egprs3->cv = 7;
1141 egprs3->tfi_hi = tfi & 0x03;
1142 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1143 egprs3->bsn1_hi = 5;
1144 egprs3->bsn1_lo = 0;
1145 egprs3->cps_hi = 1;
1146 data_msg[3] = 0xff;
1147 egprs3->pi = 0;
1148 egprs3->cps_lo = 1;
1149 egprs3->rsb = 0;
1150 egprs3->spb = 3;
1151 egprs3->pi = 0;
1152
1153 pdch->rcv_block(data_msg, 42, *fn, &meas);
1154
1155 block = ul_tbf->m_rlc.block(5);
1156 /* check the status of the block */
1157 OSMO_ASSERT(block->spb_status.block_status_ul ==
1158 EGPRS_RESEG_SECOND_SEG_RXD);
1159
1160 cs = GprsCodingScheme::MCS3;
1161 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1162 egprs3->si = 1;
1163 egprs3->r = 1;
1164 egprs3->cv = 7;
1165 egprs3->tfi_hi = tfi & 0x03;
1166 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1167 egprs3->bsn1_hi = 5;
1168 egprs3->bsn1_lo = 0;
1169 egprs3->cps_hi = 1;
1170 data_msg[3] = 0xff;
1171 egprs3->pi = 0;
1172 egprs3->cps_lo = 1;
1173 egprs3->rsb = 0;
1174 egprs3->spb = 2;
1175 egprs3->pi = 0;
1176
1177 pdch->rcv_block(data_msg, 42, *fn, &meas);
1178
1179 block = ul_tbf->m_rlc.block(5);
1180
1181 /* check the status of the block */
1182 OSMO_ASSERT(block->spb_status.block_status_ul ==
1183 EGPRS_RESEG_DEFAULT);
1184 OSMO_ASSERT(block->cs_last ==
1185 GprsCodingScheme::MCS6);
1186 /* Assembled MCS is MCS6. so the size is 74 */
1187 OSMO_ASSERT(block->len == 74);
1188
1189 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->len ==
1190 ul_tbf->m_rlc.block(4)->len);
1191 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->len ==
1192 ul_tbf->m_rlc.block(3)->len);
1193
1194 /* Compare the spb status of each BSNs(3,4,5). should be same */
1195 OSMO_ASSERT(
1196 ul_tbf->m_rlc.block(5)->spb_status.block_status_ul ==
1197 ul_tbf->m_rlc.block(4)->spb_status.block_status_ul);
1198 OSMO_ASSERT(
1199 ul_tbf->m_rlc.block(5)->spb_status.block_status_ul ==
1200 ul_tbf->m_rlc.block(3)->spb_status.block_status_ul);
1201
1202 /* Compare the Assembled MCS of each BSNs(3,4,5). should be same */
1203 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->cs_last ==
1204 ul_tbf->m_rlc.block(4)->cs_last);
1205 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->cs_last ==
1206 ul_tbf->m_rlc.block(3)->cs_last);
1207
1208 /* Compare the data of each BSNs(3,4,5). should be same */
1209 OSMO_ASSERT(
1210 !memcmp(ul_tbf->m_rlc.block(5)->block,
1211 ul_tbf->m_rlc.block(4)->block, ul_tbf->m_rlc.block(5)->len
1212 ));
1213 OSMO_ASSERT(
1214 !memcmp(ul_tbf->m_rlc.block(5)->block,
1215 ul_tbf->m_rlc.block(3)->block, ul_tbf->m_rlc.block(5)->len
1216 ));
1217
1218 return ul_tbf;
1219}
1220
sivasankari1d8744c2017-01-24 15:53:35 +05301221static gprs_rlcmac_ul_tbf *establish_ul_tbf(BTS *the_bts,
1222 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1223 uint8_t ms_class, uint8_t egprs_ms_class)
1224{
sivasankari1d8744c2017-01-24 15:53:35 +05301225 uint32_t rach_fn = *fn - 51;
1226 uint32_t sba_fn = *fn + 52;
1227 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001228 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301229 gprs_rlcmac_ul_tbf *ul_tbf;
sivasankari1d8744c2017-01-24 15:53:35 +05301230 gprs_rlcmac_bts *bts;
1231 RlcMacUplink_t ulreq = {0};
1232 struct pcu_l1_meas meas;
sivasankari1d8744c2017-01-24 15:53:35 +05301233 GprsCodingScheme cs;
1234
1235 meas.set_rssi(31);
1236 bts = the_bts->bts_data();
1237
1238 /* needed to set last_rts_fn in the PDCH object */
1239 request_dl_rlc_block(bts, trx_no, ts_no, fn);
1240
1241 /*
1242 * simulate RACH, this sends an Immediate
1243 * Assignment Uplink on the AGCH
1244 */
1245 the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0);
1246
1247 /* get next free TFI */
1248 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
1249
1250 /* fake a resource request */
1251 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
1252 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
1253 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
1254 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
1255 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability = 1;
1256 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1257 Count_MS_RA_capability_value = 1;
1258 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1259 MS_RA_capability_value[0].u.Content.
1260 Exist_Multislot_capability = 1;
1261 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1262 MS_RA_capability_value[0].u.Content.Multislot_capability.
1263 Exist_GPRS_multislot_class = 1;
1264 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1265 MS_RA_capability_value[0].u.Content.Multislot_capability.
1266 GPRS_multislot_class = ms_class;
1267 if (egprs_ms_class) {
1268 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1269 MS_RA_capability_value[0].u.Content.
1270 Multislot_capability.Exist_EGPRS_multislot_class = 1;
1271 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1272 MS_RA_capability_value[0].u.Content.
1273 Multislot_capability.EGPRS_multislot_class = ms_class;
1274 }
1275 send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
1276
1277 /* check the TBF */
1278 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
1279 /* send packet uplink assignment */
1280 *fn = sba_fn;
1281 request_dl_rlc_block(ul_tbf, fn);
1282
1283 /* send real acknowledgement */
1284 send_control_ack(ul_tbf);
1285
1286 check_tbf(ul_tbf);
1287
1288 return ul_tbf;
1289}
1290
1291static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_no_length(BTS *the_bts,
1292 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1293 uint8_t ms_class, uint8_t egprs_ms_class, gprs_rlcmac_ul_tbf *ul_tbf)
1294{
1295 OSMO_ASSERT(ul_tbf);
1296 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1297 GprsMs *ms;
sivasankari1d8744c2017-01-24 15:53:35 +05301298 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001299 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301300 struct gprs_rlcmac_pdch *pdch;
sivasankari1d8744c2017-01-24 15:53:35 +05301301 struct pcu_l1_meas meas;
sivasankari1d8744c2017-01-24 15:53:35 +05301302 GprsCodingScheme cs;
1303
1304
1305 /* send fake data with cv=0*/
1306 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1307 uint8_t data[49] = {0};
1308
1309 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1310
1311 /*header_construction */
1312 memset(data, 0x2b, sizeof(data));
1313 /* Message with CRBB */
1314 for (int i = 0 ; i < 80; i++) {
1315 hdr3->r = 0;
1316 hdr3->si = 0;
1317 hdr3->cv = 10;
1318 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1319 hdr3->tfi_lo = tfi & 0x7;
1320 hdr3->bsn1_hi = ((i * 2)&0x1f);
1321 hdr3->bsn1_lo = ((i * 2)/32);
1322 hdr3->cps_hi = 0;
1323 hdr3->cps_lo = 0;
1324 hdr3->spb = 0;
1325 hdr3->rsb = 0;
1326 hdr3->pi = 0;
1327 hdr3->spare = 0;
1328 hdr3->dummy = 1;
1329 data[4] = 0x0;
1330 data[5] = 0x0;
1331 data[6] = 0x2b;
1332 data[7] = 0x2b;
1333 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
1334 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1335 }
1336 ul_tbf->create_ul_ack(*fn, ts_no);
1337 memset(data, 0x2b, sizeof(data));
1338 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1339 hdr3->r = 0;
1340 hdr3->si = 0;
1341 hdr3->cv = 0;
1342 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1343 hdr3->tfi_lo = tfi & 0x7;
1344 hdr3->bsn1_hi = 0;
1345 hdr3->bsn1_lo = 2;
1346 hdr3->cps_hi = 0;
1347 hdr3->cps_lo = 0;
1348 hdr3->spb = 0;
1349 hdr3->rsb = 0;
1350 hdr3->pi = 0;
1351 hdr3->spare = 0;
1352 hdr3->dummy = 1;
1353 data[4] = 0x0;
1354 data[5] = 0x2b;
1355 data[6] = 0x2b;
1356 data[7] = 0x2b;
1357
1358 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
1359 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1360
1361 request_dl_rlc_block(ul_tbf, fn);
1362
1363 check_tbf(ul_tbf);
1364 OSMO_ASSERT(ul_tbf->ul_ack_state == GPRS_RLCMAC_UL_ACK_NONE);
1365
1366 ms = the_bts->ms_by_tlli(tlli);
1367 OSMO_ASSERT(ms != NULL);
1368 OSMO_ASSERT(ms->ta() == qta/4);
1369 OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
1370
1371 return ul_tbf;
1372}
1373
1374static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_with_length(BTS *the_bts,
1375 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1376 uint8_t ms_class, uint8_t egprs_ms_class, gprs_rlcmac_ul_tbf *ul_tbf)
1377{
1378 OSMO_ASSERT(ul_tbf);
1379 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1380 GprsMs *ms;
sivasankari1d8744c2017-01-24 15:53:35 +05301381 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001382 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301383 struct gprs_rlcmac_pdch *pdch;
sivasankari1d8744c2017-01-24 15:53:35 +05301384 struct pcu_l1_meas meas;
sivasankari1d8744c2017-01-24 15:53:35 +05301385 GprsCodingScheme cs;
1386
1387 check_tbf(ul_tbf);
1388 /* send fake data with cv=0*/
1389 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1390 uint8_t data[49] = {0};
1391
1392 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1393
1394 /*header_construction */
1395 memset(data, 0x2b, sizeof(data));
1396
1397 /* Message with URBB & URBB length */
1398 for (int i = 0 ; i < 20; i++) {
1399 hdr3->r = 0;
1400 hdr3->si = 0;
1401 hdr3->cv = 10;
1402 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1403 hdr3->tfi_lo = tfi & 0x7;
1404 hdr3->bsn1_hi = ((i * 2)&0x1f);
1405 hdr3->bsn1_lo = ((i * 2)/32);
1406 hdr3->cps_hi = 0;
1407 hdr3->cps_lo = 0;
1408 hdr3->spb = 0;
1409 hdr3->rsb = 0;
1410 hdr3->pi = 0;
1411 hdr3->spare = 0;
1412 hdr3->dummy = 1;
1413 data[4] = 0x0;
1414 data[5] = 0x0;
1415 data[6] = 0x2b;
1416 data[7] = 0x2b;
1417 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
1418 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1419 }
1420 ul_tbf->create_ul_ack(*fn, ts_no);
1421 memset(data, 0x2b, sizeof(data));
1422 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1423 hdr3->r = 0;
1424 hdr3->si = 0;
1425 hdr3->cv = 0;
1426 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1427 hdr3->tfi_lo = tfi & 0x7;
1428 hdr3->bsn1_hi = 0;
1429 hdr3->bsn1_lo = 2;
1430 hdr3->cps_hi = 0;
1431 hdr3->cps_lo = 0;
1432 hdr3->spb = 0;
1433 hdr3->rsb = 0;
1434 hdr3->pi = 0;
1435 hdr3->spare = 0;
1436 hdr3->dummy = 1;
1437 data[4] = 0x0;
1438 data[5] = 0x2b;
1439 data[6] = 0x2b;
1440 data[7] = 0x2b;
1441
1442 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
1443 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1444
1445 request_dl_rlc_block(ul_tbf, fn);
1446
1447 check_tbf(ul_tbf);
1448 OSMO_ASSERT(ul_tbf->ul_ack_state == GPRS_RLCMAC_UL_ACK_NONE);
1449
1450 ms = the_bts->ms_by_tlli(tlli);
1451 OSMO_ASSERT(ms != NULL);
1452 OSMO_ASSERT(ms->ta() == qta/4);
1453 OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
1454
1455 return ul_tbf;
1456}
1457
1458static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_CRBB(BTS *the_bts,
1459 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1460 uint8_t ms_class, uint8_t egprs_ms_class)
1461{
1462 GprsMs *ms;
sivasankari1d8744c2017-01-24 15:53:35 +05301463 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001464 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301465 gprs_rlcmac_ul_tbf *ul_tbf;
1466 struct gprs_rlcmac_pdch *pdch;
sivasankari1d8744c2017-01-24 15:53:35 +05301467 struct pcu_l1_meas meas;
sivasankari1d8744c2017-01-24 15:53:35 +05301468 GprsCodingScheme cs;
1469
1470
1471 /* check the TBF */
1472 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
1473 OSMO_ASSERT(ul_tbf);
1474 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1475
1476 /* send fake data with cv=0*/
1477 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1478 uint8_t data[49] = {0};
1479
1480 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1481
1482 /*header_construction */
1483 memset(data, 0x2b, sizeof(data));
1484
1485 /* Message with CRBB */
1486 for (int i = 80 ; i < 160; i++) {
1487 hdr3->r = 0;
1488 hdr3->si = 0;
1489 hdr3->cv = 10;
1490 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1491 hdr3->tfi_lo = tfi & 0x7;
1492 hdr3->bsn1_hi = ((i)&0x1f);
1493 hdr3->bsn1_lo = ((i)/32);
1494 hdr3->cps_hi = 0;
1495 hdr3->cps_lo = 0;
1496 hdr3->spb = 0;
1497 hdr3->rsb = 0;
1498 hdr3->pi = 0;
1499 hdr3->spare = 0;
1500 hdr3->dummy = 1;
1501 data[4] = 0x0;
1502 data[5] = 0x0;
1503 data[6] = 0x2b;
1504 data[7] = 0x2b;
1505 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
1506 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1507 }
1508 ul_tbf->create_ul_ack(*fn, ts_no);
1509 memset(data, 0x2b, sizeof(data));
1510 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1511 hdr3->r = 0;
1512 hdr3->si = 0;
1513 hdr3->cv = 0;
1514 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1515 hdr3->tfi_lo = tfi & 0x7;
1516 hdr3->bsn1_hi = 0;
1517 hdr3->bsn1_lo = 2;
1518 hdr3->cps_hi = 0;
1519 hdr3->cps_lo = 0;
1520 hdr3->spb = 0;
1521 hdr3->rsb = 0;
1522 hdr3->pi = 0;
1523 hdr3->spare = 0;
1524 hdr3->dummy = 1;
1525 data[4] = 0x0;
1526 data[5] = 0x2b;
1527 data[6] = 0x2b;
1528 data[7] = 0x2b;
1529
1530 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
1531 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1532
1533 request_dl_rlc_block(ul_tbf, fn);
1534
1535 check_tbf(ul_tbf);
1536 OSMO_ASSERT(ul_tbf->ul_ack_state == GPRS_RLCMAC_UL_ACK_NONE);
1537
1538 ms = the_bts->ms_by_tlli(tlli);
1539 OSMO_ASSERT(ms != NULL);
1540 OSMO_ASSERT(ms->ta() == qta/4);
1541 OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
1542
1543 return ul_tbf;
1544}
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001545static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase(BTS *the_bts,
1546 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001547 uint8_t ms_class, uint8_t egprs_ms_class)
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001548{
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001549 GprsMs *ms;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001550 uint32_t rach_fn = *fn - 51;
1551 uint32_t sba_fn = *fn + 52;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001552 uint8_t trx_no = 0;
1553 int tfi = 0;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001554 gprs_rlcmac_ul_tbf *ul_tbf;
1555 struct gprs_rlcmac_pdch *pdch;
1556 gprs_rlcmac_bts *bts;
1557 RlcMacUplink_t ulreq = {0};
Jacob Erlbeck20f6fd12015-06-08 11:05:45 +02001558 struct pcu_l1_meas meas;
1559 meas.set_rssi(31);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001560
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001561 bts = the_bts->bts_data();
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001562
1563 /* needed to set last_rts_fn in the PDCH object */
Max878bd1f2016-07-20 13:05:05 +02001564 request_dl_rlc_block(bts, trx_no, ts_no, fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001565
bhargava959d1de2016-08-17 15:17:21 +05301566 /* simulate RACH, sends an Immediate Assignment Uplink on the AGCH */
1567 the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001568
1569 /* get next free TFI */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001570 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001571
1572 /* fake a resource request */
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001573 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
1574 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
1575 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
1576 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001577 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability = 1;
1578 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1579 Count_MS_RA_capability_value = 1;
1580 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1581 MS_RA_capability_value[0].u.Content.Exist_Multislot_capability = 1;
1582 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1583 MS_RA_capability_value[0].u.Content.Multislot_capability.
1584 Exist_GPRS_multislot_class = 1;
1585 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1586 MS_RA_capability_value[0].u.Content.Multislot_capability.
1587 GPRS_multislot_class = ms_class;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001588 if (egprs_ms_class) {
1589 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1590 MS_RA_capability_value[0].u.Content.Multislot_capability.
1591 Exist_EGPRS_multislot_class = 1;
1592 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1593 MS_RA_capability_value[0].u.Content.Multislot_capability.
1594 EGPRS_multislot_class = ms_class;
1595 }
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001596
Jacob Erlbeck56f99d12015-08-20 15:55:56 +02001597 send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001598
1599 /* check the TBF */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001600 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001601 OSMO_ASSERT(ul_tbf != NULL);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +02001602 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001603
1604 /* send packet uplink assignment */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001605 *fn = sba_fn;
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +02001606 request_dl_rlc_block(ul_tbf, fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001607
Jacob Erlbeckaf454732015-08-21 15:03:23 +02001608 /* send real acknowledgement */
1609 send_control_ack(ul_tbf);
1610
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001611 check_tbf(ul_tbf);
1612
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001613 /* send fake data */
1614 uint8_t data_msg[23] = {
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001615 0x00 | 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
1616 uint8_t(0 | (tfi << 1)),
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001617 uint8_t(1), /* BSN:7, E:1 */
1618 };
1619
Jacob Erlbeck56f99d12015-08-20 15:55:56 +02001620 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001621 pdch->rcv_block(&data_msg[0], sizeof(data_msg), *fn, &meas);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001622
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001623 ms = the_bts->ms_by_tlli(tlli);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001624 OSMO_ASSERT(ms != NULL);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +02001625 OSMO_ASSERT(ms->ta() == qta/4);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001626 OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
1627
1628 return ul_tbf;
1629}
1630
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001631static void send_dl_data(BTS *the_bts, uint32_t tlli, const char *imsi,
1632 const uint8_t *data, unsigned data_size)
1633{
1634 GprsMs *ms, *ms2;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001635
1636 ms = the_bts->ms_store().get_ms(tlli, 0, imsi);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001637
Jacob Erlbeck14e00f82015-11-27 18:10:39 +01001638 gprs_rlcmac_dl_tbf::handle(the_bts->bts_data(), tlli, 0, imsi, 0, 0,
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001639 1000, data, data_size);
1640
1641 ms = the_bts->ms_by_imsi(imsi);
1642 OSMO_ASSERT(ms != NULL);
1643 OSMO_ASSERT(ms->dl_tbf() != NULL);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001644
1645 if (imsi[0] && strcmp(imsi, "000") != 0) {
1646 ms2 = the_bts->ms_by_tlli(tlli);
1647 OSMO_ASSERT(ms == ms2);
1648 }
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001649}
1650
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001651static void transmit_dl_data(BTS *the_bts, uint32_t tlli, uint32_t *fn,
1652 uint8_t slots = 0xff)
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001653{
1654 gprs_rlcmac_dl_tbf *dl_tbf;
1655 GprsMs *ms;
1656 unsigned ts_no;
1657
1658 ms = the_bts->ms_by_tlli(tlli);
1659 OSMO_ASSERT(ms);
1660 dl_tbf = ms->dl_tbf();
1661 OSMO_ASSERT(dl_tbf);
1662
1663 while (dl_tbf->have_data()) {
1664 uint8_t bn = fn2bn(*fn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001665 for (ts_no = 0 ; ts_no < 8; ts_no += 1) {
1666 if (!(slots & (1 << ts_no)))
1667 continue;
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001668 gprs_rlcmac_rcv_rts_block(the_bts->bts_data(),
Max878bd1f2016-07-20 13:05:05 +02001669 dl_tbf->trx->trx_no, ts_no,
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001670 *fn, bn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001671 }
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001672 *fn = fn_add_blocks(*fn, 1);
1673 }
1674}
1675
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001676static void test_tbf_single_phase()
1677{
1678 BTS the_bts;
1679 int ts_no = 7;
Philippd935d882016-11-07 13:07:36 +01001680 uint32_t fn = DUMMY_FN; /* 17,25,9 */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001681 uint32_t tlli = 0xf1223344;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001682 const char *imsi = "0011223344";
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001683 uint16_t qta = 31;
1684 gprs_rlcmac_ul_tbf *ul_tbf;
1685 GprsMs *ms;
1686
1687 printf("=== start %s ===\n", __func__);
1688
1689 setup_bts(&the_bts, ts_no);
1690
1691 ul_tbf = establish_ul_tbf_single_phase(&the_bts, ts_no, tlli, &fn, qta);
1692
1693 ms = ul_tbf->ms();
1694 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
1695 fprintf(stderr, "Got MS: TLLI = 0x%08x, TA = %d\n", ms->tlli(), ms->ta());
1696
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001697 send_dl_data(&the_bts, tlli, imsi, (const uint8_t *)"TEST", 4);
1698
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001699 printf("=== end %s ===\n", __func__);
1700}
1701
sivasankari1d8744c2017-01-24 15:53:35 +05301702static void test_tbf_egprs_two_phase_puan(void)
1703{
1704 BTS the_bts;
1705 int ts_no = 7;
1706 uint32_t fn = 2654218;
1707 uint16_t qta = 31;
1708 uint32_t tlli = 0xf1223344;
1709 const char *imsi = "0011223344";
1710 uint8_t ms_class = 1;
1711 gprs_rlcmac_bts *bts;
1712 uint8_t egprs_ms_class = 1;
1713 gprs_rlcmac_ul_tbf *ul_tbf;
1714 GprsMs *ms;
1715 uint8_t test_data[256];
1716
1717 printf("=== start %s ===\n", __func__);
1718
1719 memset(test_data, 1, sizeof(test_data));
1720
1721 setup_bts(&the_bts, ts_no, 4);
1722 the_bts.bts_data()->initial_mcs_dl = 9;
1723 the_bts.bts_data()->egprs_enabled = 1;
1724 bts = the_bts.bts_data();
1725 bts->ws_base = 128;
1726 bts->ws_pdch = 64;
1727
1728 ul_tbf = establish_ul_tbf(&the_bts, ts_no, tlli, &fn, qta, ms_class, egprs_ms_class);
1729 /* Function to generate URBB with no length */
1730 ul_tbf = establish_ul_tbf_two_phase_puan_URBB_no_length(&the_bts, ts_no, tlli, &fn,
1731 qta, ms_class, egprs_ms_class, ul_tbf);
1732
1733 ms = ul_tbf->ms();
1734 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
1735 fprintf(stderr,
1736 "Got MS: TLLI = 0x%08x, TA = %d\n", ms->tlli(), ms->ta());
1737 send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data));
1738
1739 ul_tbf->m_window.set_v_r(0);
1740 ul_tbf->m_window.set_v_q(0);
1741 /* Function to generate URBB with length */
1742 ul_tbf = establish_ul_tbf_two_phase_puan_URBB_with_length(&the_bts, ts_no, tlli, &fn,
1743 qta, ms_class, egprs_ms_class, ul_tbf);
1744
1745 ms = ul_tbf->ms();
1746 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
1747 fprintf(stderr,
1748 "Got MS: TLLI = 0x%08x, TA = %d\n", ms->tlli(), ms->ta());
1749
1750 send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data));
1751
1752 ul_tbf->m_window.set_v_r(0);
1753 ul_tbf->m_window.set_v_q(0);
1754 /* Function to generate CRBB */
1755 bts->ws_base = 128;
1756 bts->ws_pdch = 64;
1757 ul_tbf = establish_ul_tbf_two_phase_puan_CRBB(&the_bts, ts_no, tlli, &fn,
1758 qta, ms_class, egprs_ms_class);
1759
1760 ms = ul_tbf->ms();
1761 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
1762 fprintf(stderr,
1763 "Got MS: TLLI = 0x%08x, TA = %d\n", ms->tlli(), ms->ta());
1764
1765 send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data));
1766
1767 printf("=== end %s ===\n", __func__);
1768}
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301769/*
1770 * Trigger rach for single block
1771 */
1772static void test_immediate_assign_rej_single_block()
1773{
1774 BTS the_bts;
1775 uint32_t fn = 2654218;
1776 uint16_t qta = 31;
1777 int ts_no = 7;
1778
1779 printf("=== start %s ===\n", __func__);
1780
1781 setup_bts(&the_bts, ts_no, 4);
1782
1783 the_bts.bts_data()->trx[0].pdch[ts_no].disable();
1784
1785 uint32_t rach_fn = fn - 51;
1786
1787 int rc = 0;
1788
1789 /*
1790 * simulate RACH, sends an Immediate Assignment
1791 * Uplink reject on the AGCH
1792 */
1793 rc = the_bts.rcv_rach(0x70, rach_fn, qta, 0,
1794 GSM_L1_BURST_TYPE_ACCESS_0);
1795
1796 OSMO_ASSERT(rc == -EINVAL);
1797
1798 printf("=== end %s ===\n", __func__);
1799}
1800
1801/*
1802 * Trigger rach till resources(USF) exhaust
1803 */
1804static void test_immediate_assign_rej_multi_block()
1805{
1806 BTS the_bts;
1807 uint32_t fn = 2654218;
1808 uint16_t qta = 31;
1809 int ts_no = 7;
1810
1811 printf("=== start %s ===\n", __func__);
1812
1813 setup_bts(&the_bts, ts_no, 4);
1814
1815 uint32_t rach_fn = fn - 51;
1816
1817 int rc = 0;
1818
1819 /*
1820 * simulate RACH, sends an Immediate Assignment Uplink
1821 * reject on the AGCH
1822 */
1823 rc = the_bts.rcv_rach(0x78, rach_fn, qta, 0,
1824 GSM_L1_BURST_TYPE_ACCESS_0);
1825 rc = the_bts.rcv_rach(0x79, rach_fn, qta, 0,
1826 GSM_L1_BURST_TYPE_ACCESS_0);
1827 rc = the_bts.rcv_rach(0x7a, rach_fn, qta, 0,
1828 GSM_L1_BURST_TYPE_ACCESS_0);
1829 rc = the_bts.rcv_rach(0x7b, rach_fn, qta, 0,
1830 GSM_L1_BURST_TYPE_ACCESS_0);
1831 rc = the_bts.rcv_rach(0x7c, rach_fn, qta, 0,
1832 GSM_L1_BURST_TYPE_ACCESS_0);
1833 rc = the_bts.rcv_rach(0x7d, rach_fn, qta, 0,
1834 GSM_L1_BURST_TYPE_ACCESS_0);
1835 rc = the_bts.rcv_rach(0x7e, rach_fn, qta, 0,
1836 GSM_L1_BURST_TYPE_ACCESS_0);
1837 rc = the_bts.rcv_rach(0x7f, rach_fn, qta, 0,
1838 GSM_L1_BURST_TYPE_ACCESS_0);
1839
1840 OSMO_ASSERT(rc == -EBUSY);
1841
1842 printf("=== end %s ===\n", __func__);
1843}
1844
1845static void test_immediate_assign_rej()
1846{
1847 test_immediate_assign_rej_multi_block();
1848 test_immediate_assign_rej_single_block();
1849}
1850
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001851static void test_tbf_two_phase()
1852{
1853 BTS the_bts;
1854 int ts_no = 7;
1855 uint32_t fn = 2654218;
1856 uint16_t qta = 31;
1857 uint32_t tlli = 0xf1223344;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001858 const char *imsi = "0011223344";
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001859 uint8_t ms_class = 1;
1860 gprs_rlcmac_ul_tbf *ul_tbf;
1861 GprsMs *ms;
1862
1863 printf("=== start %s ===\n", __func__);
1864
1865 setup_bts(&the_bts, ts_no, 4);
1866
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001867 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli, &fn, qta,
1868 ms_class, 0);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001869
1870 ms = ul_tbf->ms();
1871 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
1872 fprintf(stderr, "Got MS: TLLI = 0x%08x, TA = %d\n", ms->tlli(), ms->ta());
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001873
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001874 send_dl_data(&the_bts, tlli, imsi, (const uint8_t *)"TEST", 4);
1875
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001876 printf("=== end %s ===\n", __func__);
1877}
1878
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001879static void test_tbf_ra_update_rach()
1880{
1881 BTS the_bts;
1882 int ts_no = 7;
1883 uint32_t fn = 2654218;
1884 uint16_t qta = 31;
1885 uint32_t tlli1 = 0xf1223344;
1886 uint32_t tlli2 = 0xf5667788;
1887 const char *imsi = "0011223344";
1888 uint8_t ms_class = 1;
1889 gprs_rlcmac_ul_tbf *ul_tbf;
1890 GprsMs *ms, *ms1, *ms2;
1891
1892 printf("=== start %s ===\n", __func__);
1893
1894 setup_bts(&the_bts, ts_no, 4);
1895
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001896 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli1, &fn, qta,
1897 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001898
1899 ms1 = ul_tbf->ms();
1900 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
1901
1902 send_dl_data(&the_bts, tlli1, imsi, (const uint8_t *)"RAU_ACCEPT", 10);
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001903 fprintf(stderr, "Old MS: TLLI = 0x%08x, TA = %d, IMSI = %s, LLC = %zu\n",
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001904 ms1->tlli(), ms1->ta(), ms1->imsi(), ms1->llc_queue()->size());
1905
Jacob Erlbeckaf454732015-08-21 15:03:23 +02001906 /* Send Packet Downlink Assignment to MS */
1907 request_dl_rlc_block(ul_tbf, &fn);
1908
1909 /* Ack it */
1910 send_control_ack(ul_tbf);
1911
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001912 /* Make sure the RAU Accept gets sent to the MS */
1913 OSMO_ASSERT(ms1->llc_queue()->size() == 1);
1914 transmit_dl_data(&the_bts, tlli1, &fn);
1915 OSMO_ASSERT(ms1->llc_queue()->size() == 0);
1916
1917 /* Now establish a new TBF for the RA UPDATE COMPLETE (new TLLI) */
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001918 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli2, &fn, qta,
1919 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001920
1921 ms2 = ul_tbf->ms();
1922
1923 /* The PCU cannot know yet, that both TBF belong to the same MS */
1924 OSMO_ASSERT(ms1 != ms2);
1925
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001926 fprintf(stderr, "Old MS: TLLI = 0x%08x, TA = %d, IMSI = %s, LLC = %zu\n",
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001927 ms1->tlli(), ms1->ta(), ms1->imsi(), ms1->llc_queue()->size());
1928
1929 /* Send some downlink data along with the new TLLI and the IMSI so that
1930 * the PCU can see, that both MS objects belong to same MS */
1931 send_dl_data(&the_bts, tlli2, imsi, (const uint8_t *)"DATA", 4);
1932
1933 ms = the_bts.ms_by_imsi(imsi);
1934 OSMO_ASSERT(ms == ms2);
1935
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001936 fprintf(stderr, "New MS: TLLI = 0x%08x, TA = %d, IMSI = %s, LLC = %zu\n",
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001937 ms2->tlli(), ms2->ta(), ms2->imsi(), ms2->llc_queue()->size());
1938
1939 ms = the_bts.ms_by_tlli(tlli1);
1940 OSMO_ASSERT(ms == NULL);
1941 ms = the_bts.ms_by_tlli(tlli2);
1942 OSMO_ASSERT(ms == ms2);
1943
1944 printf("=== end %s ===\n", __func__);
1945}
1946
1947static void test_tbf_dl_flow_and_rach_two_phase()
1948{
1949 BTS the_bts;
1950 int ts_no = 7;
1951 uint32_t fn = 2654218;
1952 uint16_t qta = 31;
1953 uint32_t tlli1 = 0xf1223344;
1954 const char *imsi = "0011223344";
1955 uint8_t ms_class = 1;
1956 gprs_rlcmac_ul_tbf *ul_tbf;
1957 gprs_rlcmac_dl_tbf *dl_tbf;
1958 GprsMs *ms, *ms1, *ms2;
1959
1960 printf("=== start %s ===\n", __func__);
1961
1962 setup_bts(&the_bts, ts_no, 1);
1963
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001964 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli1, &fn, qta,
1965 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001966
1967 ms1 = ul_tbf->ms();
1968 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
1969
1970 send_dl_data(&the_bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);
1971 send_dl_data(&the_bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001972 fprintf(stderr, "Old MS: TLLI = 0x%08x, TA = %d, IMSI = %s, LLC = %zu\n",
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001973 ms1->tlli(), ms1->ta(), ms1->imsi(), ms1->llc_queue()->size());
1974
1975 OSMO_ASSERT(ms1->llc_queue()->size() == 2);
1976 dl_tbf = ms1->dl_tbf();
1977 OSMO_ASSERT(dl_tbf != NULL);
1978
1979 /* Get rid of old UL TBF */
1980 tbf_free(ul_tbf);
1981 ms = the_bts.ms_by_tlli(tlli1);
1982 OSMO_ASSERT(ms1 == ms);
1983
1984 /* Now establish a new UL TBF, this will consume one LLC packet */
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001985 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli1, &fn, qta,
1986 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001987
1988 ms2 = ul_tbf->ms();
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001989 fprintf(stderr, "New MS: TLLI = 0x%08x, TA = %d, IMSI = %s, LLC = %zu\n",
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001990 ms2->tlli(), ms2->ta(), ms2->imsi(), ms2->llc_queue()->size());
1991
1992 /* This should be the same MS object */
1993 OSMO_ASSERT(ms2 == ms1);
1994
1995 ms = the_bts.ms_by_tlli(tlli1);
1996 OSMO_ASSERT(ms2 == ms);
1997
Jacob Erlbeckc8cbfc22015-09-01 11:38:40 +02001998 /* A DL TBF should still exist */
1999 OSMO_ASSERT(ms->dl_tbf());
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002000
2001 /* No queued packets should be lost */
Jacob Erlbeck9659d592015-09-01 11:06:14 +02002002 OSMO_ASSERT(ms->llc_queue()->size() == 2);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002003
2004 printf("=== end %s ===\n", __func__);
2005}
2006
2007
2008static void test_tbf_dl_flow_and_rach_single_phase()
2009{
2010 BTS the_bts;
2011 int ts_no = 7;
2012 uint32_t fn = 2654218;
2013 uint16_t qta = 31;
2014 uint32_t tlli1 = 0xf1223344;
2015 const char *imsi = "0011223344";
2016 uint8_t ms_class = 1;
2017 gprs_rlcmac_ul_tbf *ul_tbf;
2018 gprs_rlcmac_dl_tbf *dl_tbf;
2019 GprsMs *ms, *ms1, *ms2;
2020
2021 printf("=== start %s ===\n", __func__);
2022
2023 setup_bts(&the_bts, ts_no, 1);
2024
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002025 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli1, &fn, qta,
2026 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002027
2028 ms1 = ul_tbf->ms();
2029 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
2030
2031 send_dl_data(&the_bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);
2032 send_dl_data(&the_bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002033 fprintf(stderr, "Old MS: TLLI = 0x%08x, TA = %d, IMSI = %s, LLC = %zu\n",
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002034 ms1->tlli(), ms1->ta(), ms1->imsi(), ms1->llc_queue()->size());
2035
2036 OSMO_ASSERT(ms1->llc_queue()->size() == 2);
2037 dl_tbf = ms1->dl_tbf();
2038 OSMO_ASSERT(dl_tbf != NULL);
2039
2040 /* Get rid of old UL TBF */
2041 tbf_free(ul_tbf);
2042 ms = the_bts.ms_by_tlli(tlli1);
2043 OSMO_ASSERT(ms1 == ms);
2044
2045 /* Now establish a new UL TBF */
2046 ul_tbf = establish_ul_tbf_single_phase(&the_bts, ts_no, tlli1, &fn, qta);
2047
2048 ms2 = ul_tbf->ms();
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002049 fprintf(stderr, "New MS: TLLI = 0x%08x, TA = %d, IMSI = %s, LLC = %zu\n",
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002050 ms2->tlli(), ms2->ta(), ms2->imsi(), ms2->llc_queue()->size());
2051
2052 /* There should be a different MS object */
2053 OSMO_ASSERT(ms2 != ms1);
2054
2055 ms = the_bts.ms_by_tlli(tlli1);
2056 OSMO_ASSERT(ms2 == ms);
2057 OSMO_ASSERT(ms1 != ms);
2058
Jacob Erlbeck5f93f852016-01-21 20:48:39 +01002059 /* DL TBF should be removed */
2060 OSMO_ASSERT(!ms->dl_tbf());
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002061
2062 /* No queued packets should be lost */
Jacob Erlbeck9659d592015-09-01 11:06:14 +02002063 OSMO_ASSERT(ms->llc_queue()->size() == 2);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002064
2065 printf("=== end %s ===\n", __func__);
2066}
2067
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002068static void test_tbf_dl_reuse()
2069{
2070 BTS the_bts;
2071 int ts_no = 7;
2072 uint32_t fn = 2654218;
2073 uint16_t qta = 31;
2074 uint32_t tlli1 = 0xf1223344;
2075 const char *imsi = "0011223344";
2076 uint8_t ms_class = 1;
2077 gprs_rlcmac_ul_tbf *ul_tbf;
2078 gprs_rlcmac_dl_tbf *dl_tbf1, *dl_tbf2;
2079 GprsMs *ms1, *ms2;
2080 unsigned i;
2081 RlcMacUplink_t ulreq = {0};
2082
2083 printf("=== start %s ===\n", __func__);
2084
2085 setup_bts(&the_bts, ts_no, 1);
2086
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002087 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli1, &fn, qta,
2088 ms_class, 0);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002089
2090 ms1 = ul_tbf->ms();
2091 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
2092
2093 /* Send some LLC frames */
2094 for (i = 0; i < 40; i++) {
2095 char buf[32];
2096 int rc;
2097
2098 rc = snprintf(buf, sizeof(buf), "LLC PACKET %02i", i);
2099 OSMO_ASSERT(rc > 0);
2100
2101 send_dl_data(&the_bts, tlli1, imsi, (const uint8_t *)buf, rc);
2102 }
2103
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002104 fprintf(stderr, "Old MS: TLLI = 0x%08x, TA = %d, IMSI = %s, LLC = %zu\n",
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002105 ms1->tlli(), ms1->ta(), ms1->imsi(), ms1->llc_queue()->size());
2106
2107 /* Send Packet Downlink Assignment to MS */
2108 request_dl_rlc_block(ul_tbf, &fn);
2109
2110 /* Ack it */
2111 send_control_ack(ul_tbf);
2112
2113 /* Transmit all data */
2114 transmit_dl_data(&the_bts, tlli1, &fn);
2115 OSMO_ASSERT(ms1->llc_queue()->size() == 0);
2116 OSMO_ASSERT(ms1->dl_tbf());
2117 OSMO_ASSERT(ms1->dl_tbf()->state_is(GPRS_RLCMAC_FINISHED));
2118
2119 dl_tbf1 = ms1->dl_tbf();
2120
2121 /* Send some LLC frames */
2122 for (i = 0; i < 10; i++) {
2123 char buf[32];
2124 int rc;
2125
2126 rc = snprintf(buf, sizeof(buf), "LLC PACKET %02i (TBF 2)", i);
2127 OSMO_ASSERT(rc > 0);
2128
2129 send_dl_data(&the_bts, tlli1, imsi, (const uint8_t *)buf, rc);
2130 }
2131
2132 /* Fake Final DL Ack/Nack */
2133 ulreq.u.MESSAGE_TYPE = MT_PACKET_DOWNLINK_ACK_NACK;
2134 Packet_Downlink_Ack_Nack_t *ack = &ulreq.u.Packet_Downlink_Ack_Nack;
2135
2136 ack->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
2137 ack->DOWNLINK_TFI = dl_tbf1->tfi();
2138 ack->Ack_Nack_Description.FINAL_ACK_INDICATION = 1;
2139
Jacob Erlbeck8eb17142016-01-22 17:58:17 +01002140 send_ul_mac_block(&the_bts, 0, dl_tbf1->poll_ts, &ulreq, dl_tbf1->poll_fn);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002141
2142 OSMO_ASSERT(dl_tbf1->state_is(GPRS_RLCMAC_WAIT_RELEASE));
2143
2144 request_dl_rlc_block(dl_tbf1, &fn);
2145
2146 ms2 = the_bts.ms_by_tlli(tlli1);
2147 OSMO_ASSERT(ms2 == ms1);
2148 OSMO_ASSERT(ms2->dl_tbf());
Neels Hofmeyr4ea45262016-06-08 15:27:40 +02002149 OSMO_ASSERT(ms2->dl_tbf()->state_is(GPRS_RLCMAC_ASSIGN));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002150
2151 dl_tbf2 = ms2->dl_tbf();
2152
2153 OSMO_ASSERT(dl_tbf1 != dl_tbf2);
2154
2155 send_control_ack(dl_tbf1);
Jacob Erlbeck6835cea2015-08-21 15:24:02 +02002156 OSMO_ASSERT(dl_tbf2->state_is(GPRS_RLCMAC_FLOW));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002157
2158 /* Transmit all data */
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002159 transmit_dl_data(&the_bts, tlli1, &fn);
2160 OSMO_ASSERT(ms2->llc_queue()->size() == 0);
2161 OSMO_ASSERT(ms2->dl_tbf());
2162 OSMO_ASSERT(ms2->dl_tbf()->state_is(GPRS_RLCMAC_FINISHED));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002163
2164 printf("=== end %s ===\n", __func__);
2165}
2166
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002167static void test_tbf_gprs_egprs()
2168{
2169 BTS the_bts;
2170 gprs_rlcmac_bts *bts;
2171 uint8_t ts_no = 4;
2172 uint8_t ms_class = 45;
2173 int rc = 0;
2174 uint32_t tlli = 0xc0006789;
2175 const char *imsi = "001001123456789";
2176 unsigned delay_csec = 1000;
2177
2178 uint8_t buf[256] = {0};
2179
2180 printf("=== start %s ===\n", __func__);
2181
2182 bts = the_bts.bts_data();
2183 setup_bts(&the_bts, ts_no);
2184
2185 /* EGPRS-only */
2186 bts->egprs_enabled = 1;
2187
2188 gprs_bssgp_create_and_connect(bts, 33001, 0, 33001,
2189 1234, 1234, 1234, 1, 1, 0, 0, 0);
2190
2191 /* Does not support EGPRS */
2192 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
2193 delay_csec, buf, sizeof(buf));
2194
2195 OSMO_ASSERT(rc == -EBUSY);
2196 printf("=== end %s ===\n", __func__);
2197
2198 gprs_bssgp_destroy();
2199}
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02002200
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002201static void test_tbf_ws()
2202{
2203 BTS the_bts;
2204 gprs_rlcmac_bts *bts;
2205 uint8_t ts_no = 4;
2206 uint8_t ms_class = 12;
2207 gprs_rlcmac_dl_tbf *dl_tbf;
2208
2209 printf("=== start %s ===\n", __func__);
2210
2211 bts = the_bts.bts_data();
2212 setup_bts(&the_bts, ts_no);
2213
2214 bts->ws_base = 128;
2215 bts->ws_pdch = 64;
2216 bts->alloc_algorithm = alloc_algorithm_b;
2217 bts->trx[0].pdch[2].enable();
2218 bts->trx[0].pdch[3].enable();
2219 bts->trx[0].pdch[4].enable();
2220 bts->trx[0].pdch[5].enable();
2221
2222 gprs_bssgp_create_and_connect(bts, 33001, 0, 33001,
2223 1234, 1234, 1234, 1, 1, 0, 0, 0);
2224
2225 /* Does no support EGPRS */
2226 dl_tbf = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, 0, 0);
2227 OSMO_ASSERT(dl_tbf != NULL);
2228 fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d\n",
2229 dl_tbf->dl_slots(),
2230 pcu_bitcount(dl_tbf->dl_slots()),
2231 dl_tbf->window()->ws());
2232 OSMO_ASSERT(pcu_bitcount(dl_tbf->dl_slots()) == 4);
2233 OSMO_ASSERT(dl_tbf->window()->ws() == 64);
2234 tbf_free(dl_tbf);
2235
2236 /* EGPRS-only */
2237 bts->egprs_enabled = 1;
2238
2239 /* Does support EGPRS */
2240 dl_tbf = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, ms_class, 0);
2241
2242 OSMO_ASSERT(dl_tbf != NULL);
2243 fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d\n",
2244 dl_tbf->dl_slots(),
2245 pcu_bitcount(dl_tbf->dl_slots()),
2246 dl_tbf->window()->ws());
2247 OSMO_ASSERT(pcu_bitcount(dl_tbf->dl_slots()) == 4);
2248 OSMO_ASSERT(dl_tbf->window()->ws() == 128 + 4 * 64);
2249 tbf_free(dl_tbf);
2250
2251 printf("=== end %s ===\n", __func__);
2252
2253 gprs_bssgp_destroy();
2254}
2255
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302256static void test_tbf_update_ws(void)
2257{
2258 BTS the_bts;
2259 gprs_rlcmac_bts *bts;
2260 uint8_t ts_no = 4;
2261 uint8_t ms_class = 11;
2262 gprs_rlcmac_dl_tbf *dl_tbf;
2263
2264 printf("=== start %s ===\n", __func__);
2265
2266 bts = the_bts.bts_data();
2267 setup_bts(&the_bts, ts_no);
2268
2269 bts->ws_base = 128;
2270 bts->ws_pdch = 64;
2271 bts->alloc_algorithm = alloc_algorithm_b;
2272 bts->trx[0].pdch[2].enable();
2273 bts->trx[0].pdch[3].enable();
2274 bts->trx[0].pdch[4].enable();
2275 bts->trx[0].pdch[5].enable();
2276
2277 gprs_bssgp_create_and_connect(bts, 33001, 0, 33001,
2278 1234, 1234, 1234, 1, 1, 0, 0, 0);
2279
2280 /* EGPRS-only */
2281 bts->egprs_enabled = 1;
2282
2283 /* Does support EGPRS */
2284 dl_tbf = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, ms_class, 1);
2285
2286 OSMO_ASSERT(dl_tbf != NULL);
2287 fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d\n",
2288 dl_tbf->dl_slots(),
2289 pcu_bitcount(dl_tbf->dl_slots()),
2290 dl_tbf->window()->ws());
2291 OSMO_ASSERT(pcu_bitcount(dl_tbf->dl_slots()) == 1);
2292 OSMO_ASSERT(dl_tbf->window()->ws() == 128 + 1 * 64);
2293
2294 dl_tbf->update();
2295
Aravind Sirsikar0ee31cf2016-09-15 17:54:46 +05302296 /* window size should be 384 */
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302297 OSMO_ASSERT(dl_tbf != NULL);
2298 fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d\n",
2299 dl_tbf->dl_slots(),
2300 pcu_bitcount(dl_tbf->dl_slots()),
2301 dl_tbf->window()->ws());
2302 OSMO_ASSERT(pcu_bitcount(dl_tbf->dl_slots()) == 4);
Aravind Sirsikar0ee31cf2016-09-15 17:54:46 +05302303 OSMO_ASSERT(dl_tbf->window()->ws() == 128 + 4 * 64);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302304
2305 tbf_free(dl_tbf);
2306
2307 printf("=== end %s ===\n", __func__);
2308
2309 gprs_bssgp_destroy();
2310}
2311
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302312static void test_tbf_puan_urbb_len(void)
2313{
2314 BTS the_bts;
2315 int ts_no = 7;
2316 uint32_t fn = 2654218;
2317 uint16_t qta = 31;
2318 uint32_t tlli = 0xf1223344;
2319 const char *imsi = "0011223344";
2320 uint8_t ms_class = 1;
2321 uint8_t egprs_ms_class = 1;
2322 gprs_rlcmac_ul_tbf *ul_tbf;
2323 GprsMs *ms;
2324 uint8_t test_data[256];
2325
2326 printf("=== start %s ===\n", __func__);
2327
2328 memset(test_data, 1, sizeof(test_data));
2329
2330 setup_bts(&the_bts, ts_no, 4);
2331 the_bts.bts_data()->initial_mcs_dl = 9;
2332 the_bts.bts_data()->egprs_enabled = 1;
2333
2334 ul_tbf = puan_urbb_len_issue(&the_bts, ts_no, tlli, &fn, qta,
2335 ms_class, egprs_ms_class);
2336
2337 ms = ul_tbf->ms();
2338 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
2339 fprintf(stderr,
2340 "Got MS: TLLI = 0x%08x, TA = %d\n", ms->tlli(), ms->ta());
2341
2342 send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data));
2343
2344 printf("=== end %s ===\n", __func__);
2345}
2346
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302347static gprs_rlcmac_ul_tbf *tbf_li_decoding(BTS *the_bts,
2348 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
2349 uint8_t ms_class, uint8_t egprs_ms_class)
2350{
2351 GprsMs *ms;
2352 uint32_t rach_fn = *fn - 51;
2353 uint32_t sba_fn = *fn + 52;
2354 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002355 int tfi = 0;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302356 gprs_rlcmac_ul_tbf *ul_tbf;
2357 struct gprs_rlcmac_pdch *pdch;
2358 gprs_rlcmac_bts *bts;
2359 RlcMacUplink_t ulreq = {0};
2360 struct pcu_l1_meas meas;
2361 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
2362 GprsCodingScheme cs;
2363 Packet_Resource_Request_t *presreq = NULL;
2364 MS_Radio_Access_capability_t *pmsradiocap = NULL;
2365 Multislot_capability_t *pmultislotcap = NULL;
2366
2367 meas.set_rssi(31);
2368 bts = the_bts->bts_data();
2369
2370 /* needed to set last_rts_fn in the PDCH object */
2371 request_dl_rlc_block(bts, trx_no, ts_no, fn);
2372
2373 /*
2374 * simulate RACH, this sends an Immediate
2375 * Assignment Uplink on the AGCH
2376 */
2377 the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0);
2378
2379 /* get next free TFI */
2380 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
2381
2382 /* fake a resource request */
2383 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
2384 presreq = &ulreq.u.Packet_Resource_Request;
2385 presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
2386 presreq->ID.UnionType = 1; /* != 0 */
2387 presreq->ID.u.TLLI = tlli;
2388 presreq->Exist_MS_Radio_Access_capability = 1;
2389 pmsradiocap = &presreq->MS_Radio_Access_capability;
2390 pmsradiocap->Count_MS_RA_capability_value = 1;
2391 pmsradiocap->MS_RA_capability_value[0].u.Content.
2392 Exist_Multislot_capability = 1;
2393 pmultislotcap = &pmsradiocap->MS_RA_capability_value[0].
2394 u.Content.Multislot_capability;
2395
2396 pmultislotcap->Exist_GPRS_multislot_class = 1;
2397 pmultislotcap->GPRS_multislot_class = ms_class;
2398 if (egprs_ms_class) {
2399 pmultislotcap->Exist_EGPRS_multislot_class = 1;
2400 pmultislotcap->EGPRS_multislot_class = ms_class;
2401 }
2402
2403 send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
2404
2405 /* check the TBF */
2406 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
2407 OSMO_ASSERT(ul_tbf);
2408 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
2409
2410 /* send packet uplink assignment */
2411 *fn = sba_fn;
2412 request_dl_rlc_block(ul_tbf, fn);
2413
2414 /* send real acknowledgement */
2415 send_control_ack(ul_tbf);
2416
2417 check_tbf(ul_tbf);
2418
2419 uint8_t data_msg[49] = {0};
2420
2421 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
2422
2423 ms = the_bts->ms_by_tlli(tlli);
2424 OSMO_ASSERT(ms != NULL);
2425 OSMO_ASSERT(ms->ta() == qta/4);
2426 OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
2427
2428 cs = GprsCodingScheme::MCS4;
2429 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
2430 egprs3->si = 0;
2431 egprs3->r = 1;
2432 egprs3->cv = 7;
2433 egprs3->tfi_hi = tfi & 0x03;
2434 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
2435 egprs3->bsn1_hi = 0;
2436 egprs3->bsn1_lo = 0;
2437 egprs3->cps_hi = 1;
2438 data_msg[3] = 0xff;
2439 egprs3->pi = 0;
2440 egprs3->cps_lo = 1;
2441 egprs3->rsb = 0;
2442 egprs3->spb = 0;
2443 egprs3->pi = 0;
2444 pdch->rcv_block(data_msg, 49, *fn, &meas);
2445
2446 egprs3->bsn1_hi = 1;
2447 egprs3->bsn1_lo = 0;
2448 data_msg[3] = 0x7f;
2449 egprs3->cps_lo = 1;
2450 egprs3->rsb = 0;
2451 egprs3->spb = 0;
2452 egprs3->pi = 0;
2453 data_msg[4] = 0x2;
2454 data_msg[5] = 0x0;
2455 pdch->rcv_block(data_msg, 49, *fn, &meas);
2456
Aravind Sirsikar22a90192016-09-15 17:24:49 +05302457 OSMO_ASSERT(ul_tbf->m_llc.m_index == 43);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302458
2459 return ul_tbf;
2460}
2461
2462static void test_tbf_li_decoding(void)
2463{
2464 BTS the_bts;
2465 int ts_no = 7;
2466 uint32_t fn = 2654218;
2467 uint16_t qta = 31;
2468 uint32_t tlli = 0xf1223344;
2469 const char *imsi = "0011223344";
2470 uint8_t ms_class = 1;
2471 uint8_t egprs_ms_class = 1;
2472 gprs_rlcmac_ul_tbf *ul_tbf;
2473 GprsMs *ms;
2474 uint8_t test_data[256];
2475
2476 printf("=== start %s ===\n", __func__);
2477
2478 memset(test_data, 1, sizeof(test_data));
2479
2480 setup_bts(&the_bts, ts_no, 4);
2481 the_bts.bts_data()->initial_mcs_dl = 9;
2482 the_bts.bts_data()->egprs_enabled = 1;
2483
2484 ul_tbf = tbf_li_decoding(&the_bts, ts_no, tlli, &fn, qta,
2485 ms_class, egprs_ms_class);
2486
2487 ms = ul_tbf->ms();
2488 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
2489 fprintf(stderr,
2490 "Got MS: TLLI = 0x%08x, TA = %d\n", ms->tlli(), ms->ta());
2491
2492 send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data));
2493
2494 printf("=== end %s ===\n", __func__);
2495}
2496
aravind sirsikarf2761382016-10-25 12:45:24 +05302497/*
2498 * Test that a bit within the uncompressed bitmap whose BSN is not within
2499 * the transmit window shall be ignored. See section 9.1.8.2.4 of 44.060
2500 * version 7.27.0 Release 7.
2501 */
2502static void test_tbf_epdan_out_of_rx_window(void)
2503{
2504 BTS the_bts;
2505 gprs_rlcmac_bts *bts;
2506 uint8_t ms_class = 11;
2507 uint8_t egprs_ms_class = 11;
2508 uint8_t trx_no;
2509 uint32_t tlli = 0xffeeddcc;
2510 gprs_rlcmac_dl_tbf *dl_tbf;
2511 int ts_no = 4;
2512 bitvec *block;
2513 uint8_t bits_data[RLC_EGPRS_MAX_WS/8];
2514 bitvec bits;
2515 int bsn_begin, bsn_end;
2516 EGPRS_PD_AckNack_t *ack_nack;
2517 RlcMacUplink_t ul_control_block;
2518 gprs_rlc_v_b *prlcmvb;
2519 gprs_rlc_dl_window *prlcdlwindow;
2520
aravind sirsikarcc4214a2016-12-09 16:12:42 +05302521 memset(&ul_control_block, 0, sizeof(RlcMacUplink_t));
2522
aravind sirsikarf2761382016-10-25 12:45:24 +05302523 printf("=== start %s ===\n", __func__);
2524
2525 bts = the_bts.bts_data();
2526
2527 setup_bts(&the_bts, ts_no);
2528 bts->dl_tbf_idle_msec = 200;
2529 bts->egprs_enabled = 1;
2530 /* ARQ II */
2531 bts->dl_arq_type = EGPRS_ARQ2;
2532
2533 /*
2534 * Simulate a message captured during over-the-air testing,
2535 * where the following values were observed:
2536 * v_a = 1176, vs = 1288, max sns = 2048, window size = 480.
2537 */
2538 uint8_t data_msg[23] = {0x40, 0x20, 0x0b, 0xff, 0xd1,
2539 0x61, 0x00, 0x3e, 0x0e, 0x51, 0x9f,
2540 0xff, 0xff, 0xfb, 0x80, 0x00, 0x00,
2541 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
2542
2543 dl_tbf = create_dl_tbf(&the_bts, ms_class, egprs_ms_class, &trx_no);
2544 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
2545 prlcdlwindow = &dl_tbf->m_window;
2546 prlcmvb = &prlcdlwindow->m_v_b;
2547 prlcdlwindow->m_v_s = 1288;
2548 prlcdlwindow->m_v_a = 1176;
2549 prlcdlwindow->set_sns(2048);
2550 prlcdlwindow->set_ws(480);
2551 prlcmvb->mark_unacked(1176);
2552 prlcmvb->mark_unacked(1177);
2553 prlcmvb->mark_unacked(1286);
2554 prlcmvb->mark_unacked(1287);
2555
2556 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2557
2558 block = bitvec_alloc(23);
2559
2560 bitvec_unpack(block, data_msg);
2561
2562 bits.data = bits_data;
2563 bits.data_len = sizeof(bits_data);
2564 bits.cur_bit = 0;
2565
2566 decode_gsm_rlcmac_uplink(block, &ul_control_block);
2567
2568 ack_nack = &ul_control_block.u.Egprs_Packet_Downlink_Ack_Nack;
2569
2570 OSMO_ASSERT(prlcmvb->is_unacked(1176));
2571 OSMO_ASSERT(prlcmvb->is_unacked(1177));
2572 OSMO_ASSERT(prlcmvb->is_unacked(1286));
2573 OSMO_ASSERT(prlcmvb->is_unacked(1287));
2574
2575 Decoding::decode_egprs_acknack_bits(
2576 &ack_nack->EGPRS_AckNack.Desc, &bits,
2577 &bsn_begin, &bsn_end, &dl_tbf->m_window);
2578
2579 dl_tbf->rcvd_dl_ack(
2580 ack_nack->EGPRS_AckNack.Desc.FINAL_ACK_INDICATION,
2581 bsn_begin, &bits);
aravind sirsikarf2761382016-10-25 12:45:24 +05302582
aravind sirsikarfb41afa2016-11-02 15:48:00 +05302583 OSMO_ASSERT(prlcmvb->is_invalid(1176));
2584 OSMO_ASSERT(prlcmvb->is_invalid(1177));
2585 OSMO_ASSERT(prlcmvb->is_acked(1286));
2586 OSMO_ASSERT(prlcmvb->is_acked(1287));
aravind sirsikarf2761382016-10-25 12:45:24 +05302587
2588 bitvec_free(block);
2589 tbf_free(dl_tbf);
2590 printf("=== end %s ===\n", __func__);
2591}
2592
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302593static void test_tbf_egprs_two_phase_spb(void)
2594{
2595 BTS the_bts;
2596 int ts_no = 7;
2597 uint32_t fn = 2654218;
2598 uint16_t qta = 31;
2599 uint32_t tlli = 0xf1223344;
2600 const char *imsi = "0011223344";
2601 uint8_t ms_class = 1;
2602 uint8_t egprs_ms_class = 1;
2603 gprs_rlcmac_ul_tbf *ul_tbf;
2604 GprsMs *ms;
2605 uint8_t test_data[256];
2606
2607 printf("=== start %s ===\n", __func__);
2608
2609 memset(test_data, 1, sizeof(test_data));
2610
2611 setup_bts(&the_bts, ts_no, 4);
2612 the_bts.bts_data()->initial_mcs_dl = 9;
2613 the_bts.bts_data()->egprs_enabled = 1;
2614
2615 ul_tbf = establish_ul_tbf_two_phase_spb(&the_bts, ts_no, tlli, &fn, qta,
2616 ms_class, egprs_ms_class);
2617
2618 ms = ul_tbf->ms();
2619 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
2620 fprintf(stderr,
2621 "Got MS: TLLI = 0x%08x, TA = %d\n", ms->tlli(), ms->ta());
2622
2623 send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data));
2624
2625 printf("=== end %s ===\n", __func__);
2626}
2627
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002628static void test_tbf_egprs_two_phase()
2629{
2630 BTS the_bts;
2631 int ts_no = 7;
2632 uint32_t fn = 2654218;
2633 uint16_t qta = 31;
2634 uint32_t tlli = 0xf1223344;
2635 const char *imsi = "0011223344";
2636 uint8_t ms_class = 1;
2637 uint8_t egprs_ms_class = 1;
2638 gprs_rlcmac_ul_tbf *ul_tbf;
2639 GprsMs *ms;
2640 uint8_t test_data[256];
2641
2642 printf("=== start %s ===\n", __func__);
2643
2644 memset(test_data, 1, sizeof(test_data));
2645
2646 setup_bts(&the_bts, ts_no, 4);
2647 the_bts.bts_data()->initial_mcs_dl = 9;
2648 the_bts.bts_data()->egprs_enabled = 1;
2649
2650 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli, &fn, qta,
2651 ms_class, egprs_ms_class);
2652
2653 ms = ul_tbf->ms();
2654 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
2655 fprintf(stderr, "Got MS: TLLI = 0x%08x, TA = %d\n", ms->tlli(), ms->ta());
2656
2657 send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data));
2658
2659 printf("=== end %s ===\n", __func__);
2660}
2661
2662static void establish_and_use_egprs_dl_tbf(BTS *the_bts, int mcs)
2663{
2664 unsigned i;
2665 uint8_t ms_class = 11;
2666 uint8_t egprs_ms_class = 11;
2667 uint32_t fn = 0;
2668 uint8_t trx_no;
2669 uint32_t tlli = 0xffeeddcc;
2670 uint8_t test_data[512];
2671
2672 uint8_t rbb[64/8];
2673
2674 gprs_rlcmac_dl_tbf *dl_tbf;
2675
2676 printf("Testing MCS-%d\n", mcs);
2677
2678 memset(test_data, 1, sizeof(test_data));
2679 the_bts->bts_data()->initial_mcs_dl = mcs;
2680
2681 dl_tbf = create_dl_tbf(the_bts, ms_class, egprs_ms_class, &trx_no);
2682 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
2683
2684 for (i = 0; i < sizeof(llc_data); i++)
2685 llc_data[i] = i%256;
2686
2687 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2688
2689 /* Schedule a small LLC frame */
2690 dl_tbf->append_data(ms_class, 1000, test_data, 10);
2691
2692 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2693
2694 /* Drain the queue */
2695 while (dl_tbf->have_data())
2696 /* Request to send one RLC/MAC block */
2697 request_dl_rlc_block(dl_tbf, &fn);
2698
2699 /* Schedule a large LLC frame */
2700 dl_tbf->append_data(ms_class, 1000, test_data, sizeof(test_data));
2701
2702 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2703
2704 /* Drain the queue */
2705 while (dl_tbf->have_data())
2706 /* Request to send one RLC/MAC block */
2707 request_dl_rlc_block(dl_tbf, &fn);
2708
2709 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2710
2711 /* Receive a final ACK */
2712 dl_tbf->rcvd_dl_ack(1, dl_tbf->m_window.v_s(), rbb);
2713
2714 /* Clean up and ensure tbfs are in the correct state */
2715 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
2716 dl_tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE;
2717 check_tbf(dl_tbf);
2718 tbf_free(dl_tbf);
2719}
2720
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302721static gprs_rlcmac_dl_tbf *tbf_init(BTS *the_bts,
2722 int mcs)
2723{
2724 unsigned i;
2725 uint8_t ms_class = 11;
2726 uint8_t egprs_ms_class = 11;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302727 uint8_t trx_no;
2728 uint32_t tlli = 0xffeeddcc;
2729 uint8_t test_data[512];
2730
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302731 gprs_rlcmac_dl_tbf *dl_tbf;
2732
2733 memset(test_data, 1, sizeof(test_data));
2734 the_bts->bts_data()->initial_mcs_dl = mcs;
2735
2736 dl_tbf = create_dl_tbf(the_bts, ms_class, egprs_ms_class, &trx_no);
2737 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
2738
2739 for (i = 0; i < sizeof(test_data); i++)
2740 test_data[i] = i%256;
2741
2742 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2743
2744 /* Schedule a LLC frame
2745 * passing only 100 bytes, since it is enough to construct
2746 * 2 RLC data blocks. Which are enough to test Header Type 1
2747 * cases
2748 */
2749 dl_tbf->append_data(ms_class, 1000, test_data, 100);
2750
2751 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2752
2753 return dl_tbf;
2754
2755}
2756
2757static void tbf_cleanup(gprs_rlcmac_dl_tbf *dl_tbf)
2758{
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302759 uint8_t rbb[64/8];
2760
2761 /* Receive a final ACK */
2762 dl_tbf->rcvd_dl_ack(1, dl_tbf->m_window.v_s(), rbb);
2763
2764 /* Clean up and ensure tbfs are in the correct state */
2765 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
2766 dl_tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE;
2767 check_tbf(dl_tbf);
2768 tbf_free(dl_tbf);
2769
2770}
2771
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302772static void egprs_spb_to_normal_validation(BTS *the_bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002773 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302774{
2775 uint32_t fn = 0;
2776 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302777 uint16_t bsn1, bsn2, bsn3;
2778 struct msgb *msg;
2779 struct gprs_rlc_dl_header_egprs_3 *egprs3;
2780 struct gprs_rlc_dl_header_egprs_2 *egprs2;
2781
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002782 printf("Testing retx for MCS %u to reseg_mcs %u\n", mcs, demanded_mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302783
2784 dl_tbf = tbf_init(the_bts, mcs);
2785
2786 /*
2787 * Table 10.4.8a.3.1 of 44.060.
2788 * (MCS7, MCS9) to (MCS2, MCS3) is not handled since it is same as
2789 * (MCS5, MCS6) to (MCS2, MCS3) transition
2790 */
2791 if (!(mcs == 6 && demanded_mcs == 3))
2792 return;
2793
2794 fn = fn_add_blocks(fn, 1);
2795 /* Send first RLC data block BSN 0 */
2796 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
2797 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0));
2798 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num()
2799 == mcs);
2800
2801 egprs2 = (struct gprs_rlc_dl_header_egprs_2 *) msg->data;
2802 bsn1 = (egprs2->bsn1_hi << 9) || (egprs2->bsn1_mid << 1)
2803 || (egprs2->bsn1_lo);
2804 dl_tbf->m_window.m_v_b.mark_nacked(0);
2805 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(0));
2806 OSMO_ASSERT(bsn1 == 0);
2807
2808 dl_tbf->ms()->set_current_cs_dl
2809 (static_cast < GprsCodingScheme::Scheme >
2810 (GprsCodingScheme::CS4 + demanded_mcs));
2811
2812 fn = fn_add_blocks(fn, 1);
2813
2814 /* Send first segment with demanded_mcs */
2815 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
2816 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(0));
2817 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num()
2818 == demanded_mcs);
2819 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2820 == EGPRS_RESEG_FIRST_SEG_SENT);
2821
2822 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2823 OSMO_ASSERT(egprs3->spb == 2);
2824
2825 /* Table 10.4.8a.3.1 of 44.060 */
2826 OSMO_ASSERT(egprs3->cps == 3);
2827
2828 /* Send second segment with demanded_mcs */
2829 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
2830 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0));
2831 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num()
2832 == demanded_mcs);
2833 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2834 == EGPRS_RESEG_SECOND_SEG_SENT);
2835
2836 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2837 /* Table 10.4.8a.3.1 of 44.060 */
2838 OSMO_ASSERT(egprs3->spb == 3);
2839 bsn2 = (egprs3->bsn1_hi << 9) || (egprs3->bsn1_mid << 1) ||
2840 (egprs3->bsn1_lo);
2841 OSMO_ASSERT(bsn2 == bsn1);
2842
2843 /* Table 10.4.8a.3.1 of 44.060 */
2844 OSMO_ASSERT(egprs3->cps == 3);
2845
2846 /* Handle (MCS3, MCS3) -> MCS6 case */
2847 dl_tbf->ms()->set_current_cs_dl
2848 (static_cast < GprsCodingScheme::Scheme >
2849 (GprsCodingScheme::CS4 + mcs));
2850
2851 dl_tbf->m_window.m_v_b.mark_nacked(0);
2852 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(0));
2853 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
2854 egprs2 = (struct gprs_rlc_dl_header_egprs_2 *) msg->data;
2855
2856 /* Table 10.4.8a.3.1 of 44.060 */
2857 OSMO_ASSERT(egprs2->cps == 0);
2858 bsn3 = (egprs2->bsn1_hi << 9) || (egprs2->bsn1_mid << 1) ||
2859 (egprs2->bsn1_lo);
2860 OSMO_ASSERT(bsn3 == bsn2);
2861
2862 tbf_cleanup(dl_tbf);
2863}
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002864
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302865static void establish_and_use_egprs_dl_tbf_for_spb(BTS *the_bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002866 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302867{
2868 uint32_t fn = 0;
2869 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302870 struct msgb *msg;
2871 struct gprs_rlc_dl_header_egprs_3 *egprs3;
2872
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002873 printf("Testing retx for MCS %u to reseg_mcs %u\n", mcs, demanded_mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302874
2875 dl_tbf = tbf_init(the_bts, mcs);
2876
2877 /*
2878 * Table 10.4.8a.3.1 of 44.060.
2879 * (MCS7, MCS9) to (MCS2, MCS3) is not handled since it is same as
2880 * (MCS5, MCS6) to (MCS2, MCS3) transition
2881 */
2882 /* TODO: Need to support of MCS8 -> MCS6 ->MCS3 transistion
2883 * Refer commit be881c028fc4da00c4046ecd9296727975c206a3
2884 * dated 2016-02-07 23:45:40 (UTC)
2885 */
2886 if (!(((mcs == 5) && (demanded_mcs == 2)) ||
2887 ((mcs == 6) && (demanded_mcs == 3)) ||
2888 ((mcs == 4) && (demanded_mcs == 1))))
2889 return;
2890
2891 fn = fn_add_blocks(fn, 1);
2892 /* Send first RLC data block BSN 0 */
2893 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
2894 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0));
2895 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num()
2896 == mcs);
2897
2898 dl_tbf->m_window.m_v_b.mark_nacked(0);
2899 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(0));
2900
2901 dl_tbf->ms()->set_current_cs_dl
2902 (static_cast < GprsCodingScheme::Scheme >
2903 (GprsCodingScheme::CS4 + demanded_mcs));
2904
2905 fn = fn_add_blocks(fn, 1);
2906
2907 /* Send first segment with demanded_mcs */
2908 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
2909 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(0));
2910 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num()
2911 == demanded_mcs);
2912 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2913 == EGPRS_RESEG_FIRST_SEG_SENT);
2914
2915 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2916 OSMO_ASSERT(egprs3->spb == 2);
2917
2918 /* Table 10.4.8a.3.1 of 44.060 */
2919 switch (demanded_mcs) {
2920 case 3:
2921 OSMO_ASSERT(egprs3->cps == 3);
2922 break;
2923 case 2:
2924 OSMO_ASSERT(egprs3->cps == 9);
2925 break;
2926 case 1:
2927 OSMO_ASSERT(egprs3->cps == 11);
2928 break;
2929 default:
2930 OSMO_ASSERT(false);
2931 break;
2932 }
2933
2934 /* Send second segment with demanded_mcs */
2935 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
2936 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0));
2937 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num()
2938 == demanded_mcs);
2939 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2940 == EGPRS_RESEG_SECOND_SEG_SENT);
2941
2942 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2943 /* Table 10.4.8a.3.1 of 44.060 */
2944 OSMO_ASSERT(egprs3->spb == 3);
2945
2946 /* Table 10.4.8a.3.1 of 44.060 */
2947 switch (demanded_mcs) {
2948 case 3:
2949 OSMO_ASSERT(egprs3->cps == 3);
2950 break;
2951 case 2:
2952 OSMO_ASSERT(egprs3->cps == 9);
2953 break;
2954 case 1:
2955 OSMO_ASSERT(egprs3->cps == 11);
2956 break;
2957 default:
2958 OSMO_ASSERT(false);
2959 break;
2960 }
2961 tbf_cleanup(dl_tbf);
2962}
2963
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302964static void establish_and_use_egprs_dl_tbf_for_retx(BTS *the_bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002965 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302966{
2967 uint32_t fn = 0;
2968 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302969 struct msgb *msg;
2970
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002971 printf("Testing retx for MCS %u - %u\n", mcs, demanded_mcs);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302972
2973 dl_tbf = tbf_init(the_bts, mcs);
2974
2975 /* For MCS reduction cases like MCS9->MCS6, MCS7->MCS5
2976 * The MCS transition are referred from table Table 8.1.1.2
2977 * of TS 44.060
2978 */
2979 /* TODO: Need to support of MCS8 -> MCS6 transistion
2980 * Refer commit be881c028fc4da00c4046ecd9296727975c206a3
2981 * dated 2016-02-07 23:45:40 (UTC)
2982 */
2983 if (((mcs == 9) && (demanded_mcs < 9)) ||
2984 ((mcs == 7) && (demanded_mcs < 7))) {
2985 fn = fn_add_blocks(fn, 1);
2986 /* Send 2 RLC data block */
2987 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
Neels Hofmeyrde9da392017-02-08 17:34:56 +01002988 OSMO_ASSERT(msg);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302989 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0));
2990 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1));
2991 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num()
2992 == mcs);
2993 OSMO_ASSERT(dl_tbf->m_rlc.block(1)->cs_current_trans.to_num()
2994 == mcs);
2995
2996 dl_tbf->m_window.m_v_b.mark_nacked(0);
2997 dl_tbf->m_window.m_v_b.mark_nacked(1);
2998 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(0));
2999 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(1));
3000
3001 /* Set the demanded MCS to demanded_mcs */
3002 dl_tbf->ms()->set_current_cs_dl
3003 (static_cast < GprsCodingScheme::Scheme >
3004 (GprsCodingScheme::CS4 + demanded_mcs));
3005
3006 fn = fn_add_blocks(fn, 1);
3007 /* Retransmit the first RLC data block with demanded_mcs */
3008 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
Neels Hofmeyrde9da392017-02-08 17:34:56 +01003009 OSMO_ASSERT(msg);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303010 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0));
3011 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(1));
3012 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num()
3013 == demanded_mcs);
3014
3015 fn = fn_add_blocks(fn, 1);
3016 /* Retransmit the second RLC data block with demanded_mcs */
3017 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
Neels Hofmeyrde9da392017-02-08 17:34:56 +01003018 OSMO_ASSERT(msg);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303019 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0));
3020 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1));
3021 OSMO_ASSERT(dl_tbf->m_rlc.block(1)->cs_current_trans.to_num()
3022 == demanded_mcs);
3023 } else if (((mcs == 5) && (demanded_mcs > 6)) ||
3024 ((mcs == 6) && (demanded_mcs > 8))) {
3025 fn = fn_add_blocks(fn, 1);
3026 /* Send first RLC data block BSN 0 */
3027 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
Neels Hofmeyrde9da392017-02-08 17:34:56 +01003028 OSMO_ASSERT(msg);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303029 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0));
3030 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num()
3031 == mcs);
3032
3033 fn = fn_add_blocks(fn, 1);
3034 /* Send second RLC data block BSN 1 */
3035 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
Neels Hofmeyrde9da392017-02-08 17:34:56 +01003036 OSMO_ASSERT(msg);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303037 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1));
3038 OSMO_ASSERT(dl_tbf->m_rlc.block(1)->cs_current_trans.to_num()
3039 == mcs);
3040
3041 dl_tbf->m_window.m_v_b.mark_nacked(0);
3042 dl_tbf->m_window.m_v_b.mark_nacked(1);
3043 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(0));
3044 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(1));
3045
3046 dl_tbf->ms()->set_current_cs_dl
3047 (static_cast < GprsCodingScheme::Scheme >
3048 (GprsCodingScheme::CS4 + demanded_mcs));
3049
3050 fn = fn_add_blocks(fn, 1);
3051 /* Send first, second RLC data blocks with demanded_mcs */
3052 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
Neels Hofmeyrde9da392017-02-08 17:34:56 +01003053 OSMO_ASSERT(msg);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303054 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0));
3055 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1));
3056 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num()
3057 == demanded_mcs);
3058 OSMO_ASSERT(dl_tbf->m_rlc.block(1)->cs_current_trans.to_num()
3059 == demanded_mcs);
3060 } else if (mcs > 6) {
3061 /* No Mcs change cases are handled here for mcs > MCS6*/
3062 fn = fn_add_blocks(fn, 1);
3063 /* Send first,second RLC data blocks */
3064 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
Neels Hofmeyrde9da392017-02-08 17:34:56 +01003065 OSMO_ASSERT(msg);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303066 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0));
3067 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1));
3068 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num()
3069 == mcs);
3070 OSMO_ASSERT(dl_tbf->m_rlc.block(1)->cs_current_trans.to_num()
3071 == mcs);
3072
3073 dl_tbf->m_window.m_v_b.mark_nacked(0);
3074 dl_tbf->m_window.m_v_b.mark_nacked(1);
3075 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(0));
3076 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(1));
3077
3078 fn = fn_add_blocks(fn, 1);
3079 /* Send first,second RLC data blocks with demanded_mcs*/
3080 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
Neels Hofmeyrde9da392017-02-08 17:34:56 +01003081 OSMO_ASSERT(msg);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303082 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0));
3083 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1));
3084 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num()
3085 == mcs);
3086 OSMO_ASSERT(dl_tbf->m_rlc.block(1)->cs_current_trans.to_num()
3087 == mcs);
3088 } else {
3089
3090 /* No MCS change cases are handled here for mcs <= MCS6*/
3091 fn = fn_add_blocks(fn, 1);
3092 /* Send first RLC data block */
3093 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
Neels Hofmeyrde9da392017-02-08 17:34:56 +01003094 OSMO_ASSERT(msg);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303095 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0));
3096 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num()
3097 == mcs);
3098
3099 dl_tbf->m_window.m_v_b.mark_nacked(0);
3100 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(0));
3101
3102 fn = fn_add_blocks(fn, 1);
3103 /* Send first RLC data block with demanded_mcs */
3104 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
Neels Hofmeyrde9da392017-02-08 17:34:56 +01003105 OSMO_ASSERT(msg);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303106 OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0));
3107 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num()
3108 == mcs);
3109 }
3110
3111 tbf_cleanup(dl_tbf);
3112}
3113
3114static void test_tbf_egprs_retx_dl(void)
3115{
3116 BTS the_bts;
3117 gprs_rlcmac_bts *bts;
3118 uint8_t ts_no = 4;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303119
3120 printf("=== start %s ===\n", __func__);
3121
3122 bts = the_bts.bts_data();
3123 bts->cs_downgrade_threshold = 0;
3124 setup_bts(&the_bts, ts_no);
3125 bts->dl_tbf_idle_msec = 200;
3126 bts->egprs_enabled = 1;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303127 /* ARQ II */
3128 bts->dl_arq_type = EGPRS_ARQ2;
3129
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303130
3131 /* First parameter is current MCS, second one is demanded_mcs */
3132 establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 6, 6);
3133 establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 1, 9);
3134 establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 2, 8);
3135 establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 5, 7);
3136 establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 6, 9);
3137 establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 7, 5);
3138 establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 9, 6);
3139
3140 printf("=== end %s ===\n", __func__);
3141}
3142
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303143static void test_tbf_egprs_spb_dl(void)
3144{
3145 BTS the_bts;
3146 gprs_rlcmac_bts *bts;
3147 uint8_t ts_no = 4;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303148
3149 printf("=== start %s ===\n", __func__);
3150
3151 bts = the_bts.bts_data();
3152 bts->cs_downgrade_threshold = 0;
3153 setup_bts(&the_bts, ts_no);
3154 bts->dl_tbf_idle_msec = 200;
3155 bts->egprs_enabled = 1;
3156
3157 /* ARQ I resegmentation support */
3158 bts->dl_arq_type = EGPRS_ARQ1;
3159
3160 /*
3161 * First parameter is current MCS, second one is demanded_mcs
3162 * currently only MCS5->MCS2, MCS6->3, MCS4->MCS1 is tested in UT
3163 * rest scenarios has been integration tested
3164 */
3165 establish_and_use_egprs_dl_tbf_for_spb(&the_bts, 6, 3);
3166 establish_and_use_egprs_dl_tbf_for_spb(&the_bts, 5, 2);
3167 establish_and_use_egprs_dl_tbf_for_spb(&the_bts, 4, 1);
3168 /* check MCS6->(MCS3+MCS3)->MCS6 case */
3169 egprs_spb_to_normal_validation(&the_bts, 6, 3);
3170
3171 printf("=== end %s ===\n", __func__);
3172}
3173
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003174static void test_tbf_egprs_dl()
3175{
3176 BTS the_bts;
3177 gprs_rlcmac_bts *bts;
3178 uint8_t ts_no = 4;
3179 int i;
3180
3181 printf("=== start %s ===\n", __func__);
3182
3183 bts = the_bts.bts_data();
3184
3185 setup_bts(&the_bts, ts_no);
3186 bts->dl_tbf_idle_msec = 200;
3187 bts->egprs_enabled = 1;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303188 /* ARQ II */
3189 bts->dl_arq_type = EGPRS_ARQ2;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003190
3191 for (i = 1; i <= 9; i++)
3192 establish_and_use_egprs_dl_tbf(&the_bts, i);
3193
3194 printf("=== end %s ===\n", __func__);
3195}
3196
3197
3198
Daniel Willmann341689d2014-06-11 18:33:14 +02003199static const struct log_info_cat default_categories[] = {
3200 {"DCSN1", "\033[1;31m", "Concrete Syntax Notation One (CSN1)", LOGL_INFO, 0},
3201 {"DL1IF", "\033[1;32m", "GPRS PCU L1 interface (L1IF)", LOGL_DEBUG, 1},
3202 {"DRLCMAC", "\033[0;33m", "GPRS RLC/MAC layer (RLCMAC)", LOGL_DEBUG, 1},
3203 {"DRLCMACDATA", "\033[0;33m", "GPRS RLC/MAC layer Data (RLCMAC)", LOGL_DEBUG, 1},
3204 {"DRLCMACDL", "\033[1;33m", "GPRS RLC/MAC layer Downlink (RLCMAC)", LOGL_DEBUG, 1},
3205 {"DRLCMACUL", "\033[1;36m", "GPRS RLC/MAC layer Uplink (RLCMAC)", LOGL_DEBUG, 1},
3206 {"DRLCMACSCHED", "\033[0;36m", "GPRS RLC/MAC layer Scheduling (RLCMAC)", LOGL_DEBUG, 1},
3207 {"DRLCMACMEAS", "\033[1;31m", "GPRS RLC/MAC layer Measurements (RLCMAC)", LOGL_INFO, 1},
Jacob Erlbeck56af6d52015-08-17 14:06:21 +02003208 {"DNS","\033[1;34m", "GPRS Network Service Protocol (NS)", LOGL_INFO , 1},
Daniel Willmann341689d2014-06-11 18:33:14 +02003209 {"DBSSGP","\033[1;34m", "GPRS BSS Gateway Protocol (BSSGP)", LOGL_INFO , 1},
3210 {"DPCU", "\033[1;35m", "GPRS Packet Control Unit (PCU)", LOGL_NOTICE, 1},
3211};
3212
3213static int filter_fn(const struct log_context *ctx,
3214 struct log_target *tar)
3215{
3216 return 1;
3217}
3218
3219const struct log_info debug_log_info = {
3220 filter_fn,
3221 (struct log_info_cat*)default_categories,
3222 ARRAY_SIZE(default_categories),
3223};
3224
aravind sirsikare9a138e2017-01-24 12:36:08 +05303225static void test_packet_access_rej_prr_no_other_tbfs()
3226{
3227 BTS the_bts;
3228 uint32_t fn = 2654218;
3229 int ts_no = 7;
3230 uint8_t trx_no = 0;
3231 uint32_t tlli = 0xffeeddcc;
3232 struct gprs_rlcmac_ul_tbf *ul_tbf = NULL;
3233
3234 printf("=== start %s ===\n", __func__);
3235
3236 setup_bts(&the_bts, ts_no, 4);
3237
3238 int rc = 0;
3239
3240 ul_tbf = handle_tbf_reject(the_bts.bts_data(), NULL, tlli,
3241 trx_no, ts_no);
3242
3243 OSMO_ASSERT(ul_tbf != 0);
3244
3245 /* trigger packet access reject */
3246 uint8_t bn = fn2bn(fn);
3247
3248 rc = gprs_rlcmac_rcv_rts_block(the_bts.bts_data(),
3249 trx_no, ts_no, fn, bn);
3250
3251 OSMO_ASSERT(rc == 0);
3252
3253 ul_tbf->handle_timeout();
3254
3255 printf("=== end %s ===\n", __func__);
3256}
3257
3258static void test_packet_access_rej_prr()
3259{
3260 BTS the_bts;
3261 uint32_t fn = 2654218;
3262 uint16_t qta = 31;
3263 int ts_no = 7;
3264 uint8_t trx_no = 0;
3265 RlcMacUplink_t ulreq = {0};
3266 Packet_Resource_Request_t *presreq = NULL;
3267 uint8_t ms_class = 11;
3268 uint8_t egprs_ms_class = 11;
3269 uint32_t rach_fn = fn - 51;
3270 uint32_t sba_fn = fn + 52;
3271 uint32_t tlli = 0xffeeddcc;
3272 MS_Radio_Access_capability_t *pmsradiocap = NULL;
3273 Multislot_capability_t *pmultislotcap = NULL;
3274
3275 printf("=== start %s ===\n", __func__);
3276
3277 setup_bts(&the_bts, ts_no, 4);
3278
3279 int rc = 0;
3280
3281 /*
3282 * Trigger rach till resources(USF) exhaust
3283 */
3284 rc = the_bts.rcv_rach(0x78, rach_fn, qta, 0,
3285 GSM_L1_BURST_TYPE_ACCESS_0);
3286 rc = the_bts.rcv_rach(0x79, rach_fn, qta, 0,
3287 GSM_L1_BURST_TYPE_ACCESS_0);
3288 rc = the_bts.rcv_rach(0x7a, rach_fn, qta, 0,
3289 GSM_L1_BURST_TYPE_ACCESS_0);
3290 rc = the_bts.rcv_rach(0x7b, rach_fn, qta, 0,
3291 GSM_L1_BURST_TYPE_ACCESS_0);
3292 rc = the_bts.rcv_rach(0x7c, rach_fn, qta, 0,
3293 GSM_L1_BURST_TYPE_ACCESS_0);
3294 rc = the_bts.rcv_rach(0x7d, rach_fn, qta, 0,
3295 GSM_L1_BURST_TYPE_ACCESS_0);
3296 rc = the_bts.rcv_rach(0x7e, rach_fn, qta, 0,
3297 GSM_L1_BURST_TYPE_ACCESS_0);
3298
3299 /* fake a resource request */
3300 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
3301 presreq = &ulreq.u.Packet_Resource_Request;
3302 presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
3303 presreq->ID.UnionType = 1; /* != 0 */
3304 presreq->ID.u.TLLI = tlli;
3305 presreq->Exist_MS_Radio_Access_capability = 1;
3306 pmsradiocap = &presreq->MS_Radio_Access_capability;
3307 pmsradiocap->Count_MS_RA_capability_value = 1;
3308 pmsradiocap->MS_RA_capability_value[0].u.Content.
3309 Exist_Multislot_capability = 1;
3310 pmultislotcap = &pmsradiocap->MS_RA_capability_value[0].
3311 u.Content.Multislot_capability;
3312
3313 pmultislotcap->Exist_GPRS_multislot_class = 1;
3314 pmultislotcap->GPRS_multislot_class = ms_class;
3315 if (egprs_ms_class) {
3316 pmultislotcap->Exist_EGPRS_multislot_class = 1;
3317 pmultislotcap->EGPRS_multislot_class = egprs_ms_class;
3318 }
3319
3320 send_ul_mac_block(&the_bts, trx_no, ts_no, &ulreq, sba_fn);
3321
3322 /* trigger packet access reject */
3323 uint8_t bn = fn2bn(fn);
3324
3325 rc = gprs_rlcmac_rcv_rts_block(the_bts.bts_data(),
3326 trx_no, ts_no, fn, bn);
3327
3328 OSMO_ASSERT(rc == 0);
3329
3330 printf("=== end %s ===\n", __func__);
3331}
3332
aravind sirsikared3413e2016-11-11 17:15:10 +05303333void test_packet_access_rej_epdan()
3334{
3335 BTS the_bts;
3336 uint32_t tlli = 0xffeeddcc;
3337
3338 printf("=== start %s ===\n", __func__);
3339 setup_bts(&the_bts, 4);
3340 static gprs_rlcmac_dl_tbf *dl_tbf = tbf_init(&the_bts, 1);
3341
3342 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
3343
3344 struct msgb *msg = dl_tbf->create_packet_access_reject();
3345
3346 printf("packet reject: %s\n",
3347 osmo_hexdump(msg->data, 23));
3348
3349 OSMO_ASSERT(!strcmp(osmo_hexdump(msg->data, 23),
3350 "40 84 7f f7 6e e6 41 4b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b "));
3351 printf("=== end %s ===\n", __func__);
3352
3353}
3354
3355
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003356int main(int argc, char **argv)
3357{
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003358 struct vty_app_info pcu_vty_info = {0};
3359
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003360 tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile TbfTest context");
3361 if (!tall_pcu_ctx)
3362 abort();
3363
3364 msgb_set_talloc_ctx(tall_pcu_ctx);
Daniel Willmann341689d2014-06-11 18:33:14 +02003365 osmo_init_logging(&debug_log_info);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003366 log_set_use_color(osmo_stderr_target, 0);
3367 log_set_print_filename(osmo_stderr_target, 0);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003368 bssgp_set_log_ss(DBSSGP);
3369
3370 vty_init(&pcu_vty_info);
3371 pcu_vty_init(&debug_log_info);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003372
Jacob Erlbeckac89a552015-06-29 14:18:46 +02003373 test_tbf_base();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003374 test_tbf_tlli_update();
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +01003375 test_tbf_final_ack(TEST_MODE_STANDARD);
3376 test_tbf_final_ack(TEST_MODE_REVERSE_FREE);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +01003377 test_tbf_delayed_release();
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +02003378 test_tbf_imsi();
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003379 test_tbf_exhaustion();
Jacob Erlbeck41168642015-06-12 13:41:00 +02003380 test_tbf_dl_llc_loss();
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02003381 test_tbf_single_phase();
3382 test_tbf_two_phase();
Jacob Erlbeckb1395982015-08-21 18:15:38 +02003383 test_tbf_ra_update_rach();
3384 test_tbf_dl_flow_and_rach_two_phase();
3385 test_tbf_dl_flow_and_rach_single_phase();
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02003386 test_tbf_dl_reuse();
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01003387 test_tbf_gprs_egprs();
Jacob Erlbeck36df7742016-01-19 15:53:30 +01003388 test_tbf_ws();
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003389 test_tbf_egprs_two_phase();
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05303390 test_tbf_egprs_two_phase_spb();
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003391 test_tbf_egprs_dl();
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303392 test_tbf_egprs_retx_dl();
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303393 test_tbf_egprs_spb_dl();
Aravind Sirsikar02352b42016-08-25 16:37:30 +05303394 test_tbf_puan_urbb_len();
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05303395 test_tbf_update_ws();
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05303396 test_tbf_li_decoding();
aravind sirsikarf2761382016-10-25 12:45:24 +05303397 test_tbf_epdan_out_of_rx_window();
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05303398 test_immediate_assign_rej();
sivasankari1d8744c2017-01-24 15:53:35 +05303399 test_tbf_egprs_two_phase_puan();
aravind sirsikared3413e2016-11-11 17:15:10 +05303400 test_packet_access_rej_epdan();
aravind sirsikare9a138e2017-01-24 12:36:08 +05303401 test_packet_access_rej_prr();
3402 test_packet_access_rej_prr_no_other_tbfs();
Jacob Erlbeck67c38502015-05-11 10:32:40 +02003403
3404 if (getenv("TALLOC_REPORT_FULL"))
3405 talloc_report_full(tall_pcu_ctx, stderr);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003406 return EXIT_SUCCESS;
3407}
3408
3409/*
3410 * stubs that should not be reached
3411 */
3412extern "C" {
3413void l1if_pdch_req() { abort(); }
3414void l1if_connect_pdch() { abort(); }
3415void l1if_close_pdch() { abort(); }
3416void l1if_open_pdch() { abort(); }
3417}