blob: dfed79eccbbac5d899a764cfa20854003e963206 [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"
Max1187a772018-01-26 13:31:42 +010030#include <gprs_rlcmac.h>
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010031
32extern "C" {
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020033#include "pcu_vty.h"
34
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010035#include <osmocom/core/application.h>
36#include <osmocom/core/msgb.h>
37#include <osmocom/core/talloc.h>
38#include <osmocom/core/utils.h>
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020039#include <osmocom/vty/vty.h>
Aravind Sirsikar505a86d2016-07-26 18:26:21 +053040#include <osmocom/gprs/protocol/gsm_04_60.h>
bhargava959d1de2016-08-17 15:17:21 +053041#include <osmocom/gsm/l1sap.h>
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010042}
43
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020044#include <errno.h>
45
Philippd935d882016-11-07 13:07:36 +010046#define DUMMY_FN 2654167
47
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010048void *tall_pcu_ctx;
49int16_t spoof_mnc = 0, spoof_mcc = 0;
Neels Hofmeyrbdc55fa2018-02-21 00:39:07 +010050bool spoof_mnc_3_digits = false;
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010051
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +010052static void check_tbf(gprs_rlcmac_tbf *tbf)
53{
54 OSMO_ASSERT(tbf);
Jacob Erlbeck04e72d32015-08-13 18:36:56 +020055 if (tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE))
Maxee5be3a2017-12-20 17:31:13 +010056 OSMO_ASSERT(tbf->timers_pending(T3191) || tbf->timers_pending(T3193));
Jacob Erlbeck04e72d32015-08-13 18:36:56 +020057 if (tbf->state_is(GPRS_RLCMAC_RELEASING))
Maxee5be3a2017-12-20 17:31:13 +010058 OSMO_ASSERT(tbf->timers_pending(T_MAX));
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +010059}
60
Jacob Erlbeckac89a552015-06-29 14:18:46 +020061static void test_tbf_base()
62{
63
64 printf("=== start %s ===\n", __func__);
65
66 OSMO_ASSERT(GPRS_RLCMAC_DL_TBF == reverse(GPRS_RLCMAC_UL_TBF));
67 OSMO_ASSERT(GPRS_RLCMAC_UL_TBF == reverse(GPRS_RLCMAC_DL_TBF));
68
69 printf("=== end %s ===\n", __func__);
70}
71
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010072static void test_tbf_tlli_update()
73{
74 BTS the_bts;
Jacob Erlbeck93990462015-05-15 15:50:43 +020075 GprsMs *ms, *ms_new;
76
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +010077 printf("=== start %s ===\n", __func__);
78
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010079 the_bts.bts_data()->alloc_algorithm = alloc_algorithm_a;
80 the_bts.bts_data()->trx[0].pdch[2].enable();
81 the_bts.bts_data()->trx[0].pdch[3].enable();
82
83 /*
84 * Make a uplink and downlink allocation
85 */
Daniel Willmann48aa0b02014-07-16 18:54:10 +020086 gprs_rlcmac_tbf *dl_tbf = tbf_alloc_dl_tbf(the_bts.bts_data(),
Jacob Erlbeck5879c642015-07-10 10:41:36 +020087 NULL,
Max92b7a502018-01-26 11:01:35 +010088 0, 0, 0, false);
Jacob Erlbeckc6d4cee2015-06-29 13:03:46 +020089 OSMO_ASSERT(dl_tbf != NULL);
Jacob Erlbeckbe0cbc12015-05-18 14:35:11 +020090 dl_tbf->update_ms(0x2342, GPRS_RLCMAC_DL_TBF);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +020091 dl_tbf->set_ta(4);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010092
Daniel Willmann48aa0b02014-07-16 18:54:10 +020093 gprs_rlcmac_tbf *ul_tbf = tbf_alloc_ul_tbf(the_bts.bts_data(),
Jacob Erlbeck5879c642015-07-10 10:41:36 +020094 dl_tbf->ms(),
Max92b7a502018-01-26 11:01:35 +010095 0, 0, 0, false);
Jacob Erlbeckc6d4cee2015-06-29 13:03:46 +020096 OSMO_ASSERT(ul_tbf != NULL);
Jacob Erlbeck0e50ce62015-05-21 16:58:22 +020097 ul_tbf->update_ms(0x2342, GPRS_RLCMAC_UL_TBF);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010098
Jacob Erlbeck93990462015-05-15 15:50:43 +020099 ms = the_bts.ms_by_tlli(0x2342);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100100
Jacob Erlbeck93990462015-05-15 15:50:43 +0200101 OSMO_ASSERT(ms != NULL);
102 OSMO_ASSERT(ms->dl_tbf() == dl_tbf);
103 OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100104
105 /*
106 * Now check.. that DL changes and that the timing advance
107 * has changed.
108 */
Jacob Erlbeck0e50ce62015-05-21 16:58:22 +0200109 dl_tbf->update_ms(0x4232, GPRS_RLCMAC_DL_TBF);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100110
Jacob Erlbeck93990462015-05-15 15:50:43 +0200111 /* It is still there, since the new TLLI has not been used for UL yet */
112 ms_new = the_bts.ms_by_tlli(0x2342);
113 OSMO_ASSERT(ms == ms_new);
114
115 ms_new = the_bts.ms_by_tlli(0x4232);
116 OSMO_ASSERT(ms == ms_new);
117 OSMO_ASSERT(ms->dl_tbf() == dl_tbf);
118 OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
119
120 /* Now use the new TLLI for UL */
Jacob Erlbeck0e50ce62015-05-21 16:58:22 +0200121 ul_tbf->update_ms(0x4232, GPRS_RLCMAC_UL_TBF);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200122 ms_new = the_bts.ms_by_tlli(0x2342);
123 OSMO_ASSERT(ms_new == NULL);
Holger Hans Peter Freytherbc1626e2013-10-30 19:50:49 +0100124
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200125 ms_new = the_bts.ms_by_tlli(0x4232);
126 OSMO_ASSERT(ms_new != NULL);
127 OSMO_ASSERT(ms_new->ta() == 4);
128
129 OSMO_ASSERT(ul_tbf->ta() == 4);
130 OSMO_ASSERT(dl_tbf->ta() == 4);
131
132 ul_tbf->set_ta(6);
133
134 OSMO_ASSERT(ul_tbf->ta() == 6);
135 OSMO_ASSERT(dl_tbf->ta() == 6);
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100136
137 printf("=== end %s ===\n", __func__);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100138}
139
Daniel Willmann510d7d32014-08-15 18:19:41 +0200140static uint8_t llc_data[200];
141
Maxa2961182018-01-25 19:47:28 +0100142/* override, requires '-Wl,--wrap=pcu_sock_send' */
143int __real_pcu_sock_send(struct msgb *msg);
144int __wrap_pcu_sock_send(struct msgb *msg)
Daniel Willmann510d7d32014-08-15 18:19:41 +0200145{
146 return 0;
147}
148
Jacob Erlbecka700dd92015-06-02 16:00:41 +0200149static void setup_bts(BTS *the_bts, uint8_t ts_no, uint8_t cs = 1)
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100150{
151 gprs_rlcmac_bts *bts;
152 gprs_rlcmac_trx *trx;
153
154 bts = the_bts->bts_data();
155 bts->alloc_algorithm = alloc_algorithm_a;
Jacob Erlbecka700dd92015-06-02 16:00:41 +0200156 bts->initial_cs_dl = cs;
157 bts->initial_cs_ul = cs;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100158 trx = &bts->trx[0];
159
160 trx->pdch[ts_no].enable();
Philippd935d882016-11-07 13:07:36 +0100161 the_bts->set_current_frame_number(DUMMY_FN);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100162}
163
164static gprs_rlcmac_dl_tbf *create_dl_tbf(BTS *the_bts, uint8_t ms_class,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +0100165 uint8_t egprs_ms_class, uint8_t *trx_no_)
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100166{
167 gprs_rlcmac_bts *bts;
168 int tfi;
169 uint8_t trx_no;
170
171 gprs_rlcmac_dl_tbf *dl_tbf;
172
173 bts = the_bts->bts_data();
174
175 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_DL_TBF, &trx_no, -1);
176 OSMO_ASSERT(tfi >= 0);
Max92b7a502018-01-26 11:01:35 +0100177 dl_tbf = tbf_alloc_dl_tbf(bts, NULL, trx_no, ms_class, egprs_ms_class,
178 true);
Max9bbe1602016-07-18 12:50:18 +0200179 dl_tbf->set_ta(0);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100180 check_tbf(dl_tbf);
181
182 /* "Establish" the DL TBF */
Max0e599802018-01-23 20:09:06 +0100183 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_SEND_ASS);
Max2399b1d2018-01-12 15:48:12 +0100184 TBF_SET_STATE(dl_tbf, GPRS_RLCMAC_FLOW);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100185 dl_tbf->m_wait_confirm = 0;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100186 check_tbf(dl_tbf);
187
188 *trx_no_ = trx_no;
189
190 return dl_tbf;
191}
192
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200193static unsigned fn2bn(unsigned fn)
194{
195 return (fn % 52) / 4;
196}
197
198static unsigned fn_add_blocks(unsigned fn, unsigned blocks)
199{
200 unsigned bn = fn2bn(fn) + blocks;
201 fn = fn - (fn % 52);
202 fn += bn * 4 + bn / 3;
Max9dabfa22017-05-16 16:10:45 +0200203 return fn % GSM_MAX_FN;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200204}
205
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200206static void request_dl_rlc_block(struct gprs_rlcmac_bts *bts,
Max878bd1f2016-07-20 13:05:05 +0200207 uint8_t trx_no, uint8_t ts_no,
Jacob Erlbeckee310902015-08-24 11:55:17 +0200208 uint32_t *fn, uint8_t *block_nr = NULL)
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100209{
Jacob Erlbeckee310902015-08-24 11:55:17 +0200210 uint8_t bn = fn2bn(*fn);
Max878bd1f2016-07-20 13:05:05 +0200211 gprs_rlcmac_rcv_rts_block(bts, trx_no, ts_no, *fn, bn);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200212 *fn = fn_add_blocks(*fn, 1);
Jacob Erlbeckee310902015-08-24 11:55:17 +0200213 bn += 1;
214 if (block_nr)
215 *block_nr = bn;
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100216}
217
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200218static void request_dl_rlc_block(struct gprs_rlcmac_tbf *tbf,
Jacob Erlbeckee310902015-08-24 11:55:17 +0200219 uint32_t *fn, uint8_t *block_nr = NULL)
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200220{
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200221 request_dl_rlc_block(tbf->bts->bts_data(), tbf->trx->trx_no,
Max878bd1f2016-07-20 13:05:05 +0200222 tbf->control_ts, fn, block_nr);
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200223}
224
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100225enum test_tbf_final_ack_mode {
226 TEST_MODE_STANDARD,
227 TEST_MODE_REVERSE_FREE
228};
229
230static void test_tbf_final_ack(enum test_tbf_final_ack_mode test_mode)
Daniel Willmann510d7d32014-08-15 18:19:41 +0200231{
232 BTS the_bts;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100233 uint8_t ts_no = 4;
234 unsigned i;
Daniel Willmann510d7d32014-08-15 18:19:41 +0200235 uint8_t ms_class = 45;
236 uint32_t fn;
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100237 uint8_t block_nr;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100238 uint8_t trx_no;
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200239 GprsMs *ms;
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200240 uint32_t tlli = 0xffeeddcc;
Daniel Willmann510d7d32014-08-15 18:19:41 +0200241
242 uint8_t rbb[64/8];
243
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100244 printf("=== start %s ===\n", __func__);
245
Daniel Willmann510d7d32014-08-15 18:19:41 +0200246 gprs_rlcmac_dl_tbf *dl_tbf;
247 gprs_rlcmac_tbf *new_tbf;
248
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100249 setup_bts(&the_bts, ts_no);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +0100250 dl_tbf = create_dl_tbf(&the_bts, ms_class, 0, &trx_no);
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200251 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200252 ms = dl_tbf->ms();
Daniel Willmann510d7d32014-08-15 18:19:41 +0200253
254 for (i = 0; i < sizeof(llc_data); i++)
255 llc_data[i] = i%256;
256
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100257 /* Schedule two LLC frames */
Daniel Willmann0f58af62014-09-19 11:57:21 +0200258 dl_tbf->append_data(ms_class, 1000, llc_data, sizeof(llc_data));
259 dl_tbf->append_data(ms_class, 1000, llc_data, sizeof(llc_data));
Daniel Willmann510d7d32014-08-15 18:19:41 +0200260
261
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100262 /* Send only a few RLC/MAC blocks */
Daniel Willmann510d7d32014-08-15 18:19:41 +0200263 fn = 0;
Jacob Erlbeckee310902015-08-24 11:55:17 +0200264 do {
Daniel Willmann510d7d32014-08-15 18:19:41 +0200265 /* Request to send one block */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200266 request_dl_rlc_block(dl_tbf, &fn, &block_nr);
Jacob Erlbeckee310902015-08-24 11:55:17 +0200267 } while (block_nr < 3);
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200268
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100269 OSMO_ASSERT(dl_tbf->have_data());
270 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
Daniel Willmann510d7d32014-08-15 18:19:41 +0200271
272 /* Queue a final ACK */
273 memset(rbb, 0, sizeof(rbb));
274 /* Receive a final ACK */
Max7df82d42017-12-15 11:14:30 +0100275 dl_tbf->rcvd_dl_ack(true, 1, rbb);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200276
277 /* Clean up and ensure tbfs are in the correct state */
278 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200279 new_tbf = ms->dl_tbf();
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100280 check_tbf(new_tbf);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200281 OSMO_ASSERT(new_tbf != dl_tbf);
282 OSMO_ASSERT(new_tbf->tfi() == 1);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100283 check_tbf(dl_tbf);
Max0e599802018-01-23 20:09:06 +0100284 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_NONE);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100285 if (test_mode == TEST_MODE_REVERSE_FREE) {
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200286 GprsMs::Guard guard(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100287 tbf_free(new_tbf);
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200288 OSMO_ASSERT(ms->dl_tbf() == NULL);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100289 check_tbf(dl_tbf);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100290 tbf_free(dl_tbf);
291 } else {
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200292 GprsMs::Guard guard(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100293 tbf_free(dl_tbf);
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200294 OSMO_ASSERT(ms->dl_tbf() == new_tbf);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100295 check_tbf(new_tbf);
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 Erlbeck5e9f40d2015-02-23 14:26:59 +0100298 }
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100299
300 printf("=== end %s ===\n", __func__);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200301}
302
Max7d32f552017-12-15 11:25:14 +0100303/* Receive an ACK */
304#define RCV_ACK(fin, tbf, rbb) do { \
Maxea98b7d2018-01-04 15:13:27 +0100305 tbf->rcvd_dl_ack(fin, tbf->window()->v_s(), rbb); \
Max7d32f552017-12-15 11:25:14 +0100306 if (!fin) \
Maxea98b7d2018-01-04 15:13:27 +0100307 OSMO_ASSERT(tbf->window()->window_empty()); \
Max7d32f552017-12-15 11:25:14 +0100308 } while(0)
309
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100310static void test_tbf_delayed_release()
311{
312 BTS the_bts;
313 gprs_rlcmac_bts *bts;
314 uint8_t ts_no = 4;
315 unsigned i;
316 uint8_t ms_class = 45;
317 uint32_t fn = 0;
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100318 uint8_t trx_no;
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200319 uint32_t tlli = 0xffeeddcc;
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100320
321 uint8_t rbb[64/8];
322
323 gprs_rlcmac_dl_tbf *dl_tbf;
324
325 printf("=== start %s ===\n", __func__);
326
327 bts = the_bts.bts_data();
328
329 setup_bts(&the_bts, ts_no);
330 bts->dl_tbf_idle_msec = 200;
331
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +0100332 dl_tbf = create_dl_tbf(&the_bts, ms_class, 0, &trx_no);
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200333 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100334
335 for (i = 0; i < sizeof(llc_data); i++)
336 llc_data[i] = i%256;
337
338 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
339
340 /* Schedule two LLC frames */
341 dl_tbf->append_data(ms_class, 1000, llc_data, sizeof(llc_data));
342 dl_tbf->append_data(ms_class, 1000, llc_data, sizeof(llc_data));
343
344 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
345
346 /* Drain the queue */
347 while (dl_tbf->have_data())
348 /* Request to send one RLC/MAC block */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200349 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100350
351 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
352
353 /* ACK all blocks */
354 memset(rbb, 0xff, sizeof(rbb));
Max7d32f552017-12-15 11:25:14 +0100355
356 RCV_ACK(false, dl_tbf, rbb); /* Receive an ACK */
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100357
358 /* Force sending of a single block containing an LLC dummy command */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200359 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100360
Max7d32f552017-12-15 11:25:14 +0100361 RCV_ACK(false, dl_tbf, rbb); /* Receive an ACK */
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100362
363 /* Timeout (make sure fn % 52 remains valid) */
364 fn += 52 * ((msecs_to_frames(bts->dl_tbf_idle_msec + 100) + 51)/ 52);
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200365 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100366
367 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FINISHED));
368
Max7d32f552017-12-15 11:25:14 +0100369 RCV_ACK(true, dl_tbf, rbb); /* Receive a final ACK */
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100370
371 /* Clean up and ensure tbfs are in the correct state */
372 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
Max0e599802018-01-23 20:09:06 +0100373 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_NONE);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100374 check_tbf(dl_tbf);
375 tbf_free(dl_tbf);
376 printf("=== end %s ===\n", __func__);
377}
378
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200379static void test_tbf_imsi()
380{
381 BTS the_bts;
382 uint8_t ts_no = 4;
383 uint8_t ms_class = 45;
384 uint8_t trx_no;
385 GprsMs *ms1, *ms2;
386
387 gprs_rlcmac_dl_tbf *dl_tbf[2];
388
389 printf("=== start %s ===\n", __func__);
390
391 setup_bts(&the_bts, ts_no);
392
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +0100393 dl_tbf[0] = create_dl_tbf(&the_bts, ms_class, 0, &trx_no);
394 dl_tbf[1] = create_dl_tbf(&the_bts, ms_class, 0, &trx_no);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200395
396 dl_tbf[0]->update_ms(0xf1000001, GPRS_RLCMAC_DL_TBF);
397 dl_tbf[1]->update_ms(0xf1000002, GPRS_RLCMAC_DL_TBF);
398
399 dl_tbf[0]->assign_imsi("001001000000001");
400 ms1 = the_bts.ms_store().get_ms(0, 0, "001001000000001");
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200401 OSMO_ASSERT(ms1 != NULL);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200402 ms2 = the_bts.ms_store().get_ms(0xf1000001);
403 OSMO_ASSERT(ms2 != NULL);
404 OSMO_ASSERT(strcmp(ms2->imsi(), "001001000000001") == 0);
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200405 OSMO_ASSERT(ms1 == ms2);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200406
407 /* change the IMSI on TBF 0 */
408 dl_tbf[0]->assign_imsi("001001000000002");
409 ms1 = the_bts.ms_store().get_ms(0, 0, "001001000000001");
410 OSMO_ASSERT(ms1 == NULL);
411 ms1 = the_bts.ms_store().get_ms(0, 0, "001001000000002");
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200412 OSMO_ASSERT(ms1 != NULL);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200413 OSMO_ASSERT(strcmp(ms2->imsi(), "001001000000002") == 0);
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200414 OSMO_ASSERT(ms1 == ms2);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200415
416 /* use the same IMSI on TBF 2 */
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200417 {
418 GprsMs::Guard guard(ms2);
419 dl_tbf[1]->assign_imsi("001001000000002");
420 ms1 = the_bts.ms_store().get_ms(0, 0, "001001000000002");
421 OSMO_ASSERT(ms1 != NULL);
422 OSMO_ASSERT(ms1 != ms2);
423 OSMO_ASSERT(strcmp(ms1->imsi(), "001001000000002") == 0);
424 OSMO_ASSERT(strcmp(ms2->imsi(), "") == 0);
425 }
426
427 ms2 = the_bts.ms_store().get_ms(0xf1000001);
428 OSMO_ASSERT(ms2 == NULL);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200429
430 tbf_free(dl_tbf[1]);
431 ms1 = the_bts.ms_store().get_ms(0, 0, "001001000000002");
432 OSMO_ASSERT(ms1 == NULL);
433
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200434 printf("=== end %s ===\n", __func__);
435}
436
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200437static void test_tbf_exhaustion()
438{
439 BTS the_bts;
440 gprs_rlcmac_bts *bts;
441 unsigned i;
442 uint8_t ts_no = 4;
443 uint8_t ms_class = 45;
444 int rc = 0;
445
446 uint8_t buf[256] = {0};
447
448 printf("=== start %s ===\n", __func__);
449
450 bts = the_bts.bts_data();
451 setup_bts(&the_bts, ts_no);
452 gprs_bssgp_create_and_connect(bts, 33001, 0, 33001,
Neels Hofmeyrbdc55fa2018-02-21 00:39:07 +0100453 1234, 1234, 1234, 1, 1, false, 0, 0, 0);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200454
455 for (i = 0; i < 1024; i++) {
456 uint32_t tlli = 0xc0000000 + i;
457 char imsi[16] = {0};
458 unsigned delay_csec = 1000;
459
Jacob Erlbeck9a2845d2015-05-21 12:06:58 +0200460 snprintf(imsi, sizeof(imsi), "001001%09d", i);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200461
Jacob Erlbeck14e00f82015-11-27 18:10:39 +0100462 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200463 delay_csec, buf, sizeof(buf));
464
465 if (rc < 0)
466 break;
467 }
468
469 OSMO_ASSERT(rc == -EBUSY);
470 printf("=== end %s ===\n", __func__);
471
472 gprs_bssgp_destroy();
473}
474
Jacob Erlbeck41168642015-06-12 13:41:00 +0200475static void test_tbf_dl_llc_loss()
476{
477 BTS the_bts;
478 gprs_rlcmac_bts *bts;
479 uint8_t ts_no = 4;
480 uint8_t ms_class = 45;
481 int rc = 0;
482 uint32_t tlli = 0xc0123456;
483 const char *imsi = "001001000123456";
484 unsigned delay_csec = 1000;
485 GprsMs *ms;
486
487 uint8_t buf[19];
488
489 printf("=== start %s ===\n", __func__);
490
491 bts = the_bts.bts_data();
492 setup_bts(&the_bts, ts_no);
493 bts->ms_idle_sec = 10; /* keep the MS object */
494
495 gprs_bssgp_create_and_connect(bts, 33001, 0, 33001,
Neels Hofmeyrbdc55fa2018-02-21 00:39:07 +0100496 1234, 1234, 1234, 1, 1, false, 0, 0, 0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200497
498 /* Handle LLC frame 1 */
499 memset(buf, 1, sizeof(buf));
Jacob Erlbeck14e00f82015-11-27 18:10:39 +0100500 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200501 delay_csec, buf, sizeof(buf));
502 OSMO_ASSERT(rc >= 0);
503
504 ms = the_bts.ms_store().get_ms(0, 0, imsi);
505 OSMO_ASSERT(ms != NULL);
506 OSMO_ASSERT(ms->dl_tbf() != NULL);
Max9bbe1602016-07-18 12:50:18 +0200507 ms->dl_tbf()->set_ta(0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200508
509 /* Handle LLC frame 2 */
510 memset(buf, 2, sizeof(buf));
Jacob Erlbeck14e00f82015-11-27 18:10:39 +0100511 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200512 delay_csec, buf, sizeof(buf));
513 OSMO_ASSERT(rc >= 0);
514
515 /* TBF establishment fails (timeout) */
516 tbf_free(ms->dl_tbf());
517
518 /* Handle LLC frame 3 */
519 memset(buf, 3, sizeof(buf));
Jacob Erlbeck14e00f82015-11-27 18:10:39 +0100520 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200521 delay_csec, buf, sizeof(buf));
522 OSMO_ASSERT(rc >= 0);
523
524 OSMO_ASSERT(ms->dl_tbf() != NULL);
525
526 /* Get first BSN */
527 struct msgb *msg;
528 int fn = 0;
529 uint8_t expected_data = 1;
530
531 while (ms->dl_tbf()->have_data()) {
532 msg = ms->dl_tbf()->create_dl_acked_block(fn += 4, 7);
533 fprintf(stderr, "MSG = %s\n", msgb_hexdump(msg));
534 OSMO_ASSERT(msgb_length(msg) == 23);
Jacob Erlbeck409efa12015-06-12 14:06:09 +0200535 OSMO_ASSERT(msgb_data(msg)[10] == expected_data);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200536 expected_data += 1;
537 }
Jacob Erlbeck409efa12015-06-12 14:06:09 +0200538 OSMO_ASSERT(expected_data-1 == 3);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200539
540 printf("=== end %s ===\n", __func__);
541
542 gprs_bssgp_destroy();
543}
544
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200545static gprs_rlcmac_ul_tbf *establish_ul_tbf_single_phase(BTS *the_bts,
546 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta)
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200547{
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200548 GprsMs *ms;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200549 int tfi = 0;
550 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200551 uint8_t trx_no = 0;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200552 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeck20f6fd12015-06-08 11:05:45 +0200553 struct pcu_l1_meas meas;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200554
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200555 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200556
bhargava959d1de2016-08-17 15:17:21 +0530557 the_bts->rcv_rach(0x03, *fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200558
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200559 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200560 OSMO_ASSERT(ul_tbf != NULL);
561
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200562 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200563
564 uint8_t data_msg[23] = {
565 0x00, /* GPRS_RLCMAC_DATA_BLOCK << 6 */
566 uint8_t(1 | (tfi << 2)),
567 uint8_t(1), /* BSN:7, E:1 */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200568 uint8_t(tlli >> 24), uint8_t(tlli >> 16),
569 uint8_t(tlli >> 8), uint8_t(tlli), /* TLLI */
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200570 };
571
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200572 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
573 pdch->rcv_block(&data_msg[0], sizeof(data_msg), *fn, &meas);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200574
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200575 ms = the_bts->ms_by_tlli(tlli);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200576 OSMO_ASSERT(ms != NULL);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200577
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200578 return ul_tbf;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200579}
580
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200581static void send_ul_mac_block(BTS *the_bts, unsigned trx_no, unsigned ts_no,
582 RlcMacUplink_t *ulreq, unsigned fn)
583{
584 bitvec *rlc_block;
585 uint8_t buf[64];
586 int num_bytes;
587 struct gprs_rlcmac_pdch *pdch;
588 struct pcu_l1_meas meas;
589
590 meas.set_rssi(31);
591
Alexander Couzensccde5c92017-02-04 03:10:08 +0100592 rlc_block = bitvec_alloc(23, tall_pcu_ctx);
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200593
594 encode_gsm_rlcmac_uplink(rlc_block, ulreq);
595 num_bytes = bitvec_pack(rlc_block, &buf[0]);
596 OSMO_ASSERT(size_t(num_bytes) < sizeof(buf));
597 bitvec_free(rlc_block);
598
Jacob Erlbeckaf75ce82015-08-26 13:22:28 +0200599 the_bts->set_current_block_frame_number(fn, 0);
600
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200601 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
602 pdch->rcv_block(&buf[0], num_bytes, fn, &meas);
603}
604
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200605static void send_control_ack(gprs_rlcmac_tbf *tbf)
606{
607 RlcMacUplink_t ulreq = {0};
608
609 OSMO_ASSERT(tbf->poll_fn != 0);
Jacob Erlbeck8eb17142016-01-22 17:58:17 +0100610 OSMO_ASSERT(tbf->is_control_ts(tbf->poll_ts));
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200611
612 ulreq.u.MESSAGE_TYPE = MT_PACKET_CONTROL_ACK;
613 Packet_Control_Acknowledgement_t *ctrl_ack =
614 &ulreq.u.Packet_Control_Acknowledgement;
615
616 ctrl_ack->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
617 ctrl_ack->TLLI = tbf->tlli();
Jacob Erlbeck8eb17142016-01-22 17:58:17 +0100618 send_ul_mac_block(tbf->bts, tbf->trx->trx_no, tbf->poll_ts,
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200619 &ulreq, tbf->poll_fn);
620}
621
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530622static gprs_rlcmac_ul_tbf *puan_urbb_len_issue(BTS *the_bts,
623 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
624 uint8_t ms_class, uint8_t egprs_ms_class)
625{
626 GprsMs *ms;
627 uint32_t rach_fn = *fn - 51;
628 uint32_t sba_fn = *fn + 52;
629 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +0100630 int tfi = 0;
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530631 gprs_rlcmac_ul_tbf *ul_tbf;
632 struct gprs_rlcmac_pdch *pdch;
633 gprs_rlcmac_bts *bts;
634 RlcMacUplink_t ulreq = {0};
635 struct pcu_l1_meas meas;
636 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
637 GprsCodingScheme cs;
638
639 meas.set_rssi(31);
640 bts = the_bts->bts_data();
641
642 /* needed to set last_rts_fn in the PDCH object */
643 request_dl_rlc_block(bts, trx_no, ts_no, fn);
644
645 /*
646 * simulate RACH, this sends an Immediate
647 * Assignment Uplink on the AGCH
648 */
Aravind Sirsikarfd713842016-08-28 17:55:05 +0530649 the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530650
651 /* get next free TFI */
652 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
653
654 /* fake a resource request */
655 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
656 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
657 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
658 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
659 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability = 1;
660 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
661 Count_MS_RA_capability_value = 1;
662 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
663 MS_RA_capability_value[0].u.Content.
664 Exist_Multislot_capability = 1;
665 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
666 MS_RA_capability_value[0].u.Content.Multislot_capability.
667 Exist_GPRS_multislot_class = 1;
668 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
669 MS_RA_capability_value[0].u.Content.Multislot_capability.
670 GPRS_multislot_class = ms_class;
671 if (egprs_ms_class) {
672 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
673 MS_RA_capability_value[0].u.Content.
674 Multislot_capability.Exist_EGPRS_multislot_class = 1;
675 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
676 MS_RA_capability_value[0].u.Content.
677 Multislot_capability.EGPRS_multislot_class = ms_class;
678 }
679
680 send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
681
682 /* check the TBF */
683 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
684 OSMO_ASSERT(ul_tbf);
685 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
686
687 /* send packet uplink assignment */
688 *fn = sba_fn;
689 request_dl_rlc_block(ul_tbf, fn);
690
691 /* send real acknowledgement */
692 send_control_ack(ul_tbf);
693
694 check_tbf(ul_tbf);
695 /* send fake data */
696 uint8_t data_msg[42] = {
697 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
Neels Hofmeyrd34646a2017-02-08 17:07:40 +0100698 (uint8_t)(tfi << 1),
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530699 1, /* BSN:7, E:1 */
700 };
701
702 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
703 pdch->rcv_block(&data_msg[0], 23, *fn, &meas);
704
705 ms = the_bts->ms_by_tlli(tlli);
706 OSMO_ASSERT(ms != NULL);
707 OSMO_ASSERT(ms->ta() == qta/4);
708 OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
709
710 /*
711 * TS 44.060, B.8.1
712 * first seg received first, later second seg
713 */
714 cs = GprsCodingScheme::MCS3;
715 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
716 egprs3->si = 0;
717 egprs3->r = 1;
718 egprs3->cv = 7;
719 egprs3->tfi_hi = tfi & 0x03;
720 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
721 egprs3->bsn1_hi = 1;
722 egprs3->bsn1_lo = 0;
723 egprs3->cps_hi = 1;
724 data_msg[3] = 0xff;
725 egprs3->pi = 0;
726 egprs3->cps_lo = 1;
727 egprs3->rsb = 0;
728 egprs3->spb = 0;
729 egprs3->pi = 0;
730
731 pdch->rcv_block(data_msg, 42, *fn, &meas);
732
733 struct msgb *msg1 = ul_tbf->create_ul_ack(*fn, ts_no);
734
735 OSMO_ASSERT(!strcmp(osmo_hexdump(msg1->data, msg1->data_len),
736 "40 24 01 3f 3e 24 46 68 90 87 b0 06 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b "
737 ));
738
739 egprs3->si = 0;
740 egprs3->r = 1;
741 egprs3->cv = 7;
742 egprs3->tfi_hi = tfi & 0x03;
743 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
744 egprs3->bsn1_hi = 4;
745 egprs3->bsn1_lo = 0;
746 egprs3->cps_hi = 1;
747 data_msg[3] = 0xff;
748 egprs3->pi = 0;
749 egprs3->cps_lo = 1;
750 egprs3->rsb = 0;
751 egprs3->spb = 0;
752
753 pdch->rcv_block(data_msg, 42, *fn, &meas);
754
755 msg1 = ul_tbf->create_ul_ack(*fn, ts_no);
756
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530757 OSMO_ASSERT(!strcmp(osmo_hexdump(msg1->data, msg1->data_len),
Aravind Sirsikareebcb1e2016-08-25 16:40:23 +0530758 "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 +0530759 ));
760
761 return ul_tbf;
762}
763
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530764static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(BTS *the_bts,
765 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
766 uint8_t ms_class, uint8_t egprs_ms_class)
767{
768 GprsMs *ms;
769 uint32_t rach_fn = *fn - 51;
770 uint32_t sba_fn = *fn + 52;
771 uint8_t trx_no = 0;
772 int tfi = 0, i = 0;
773 gprs_rlcmac_ul_tbf *ul_tbf;
774 struct gprs_rlcmac_pdch *pdch;
775 gprs_rlcmac_bts *bts;
776 RlcMacUplink_t ulreq = {0};
777 struct pcu_l1_meas meas;
778 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
779 GprsCodingScheme cs;
780
781 meas.set_rssi(31);
782 bts = the_bts->bts_data();
783
784 /* needed to set last_rts_fn in the PDCH object */
785 request_dl_rlc_block(bts, trx_no, ts_no, fn);
786
787 /*
788 * simulate RACH, this sends an Immediate
789 * Assignment Uplink on the AGCH
790 */
bhargava959d1de2016-08-17 15:17:21 +0530791 the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530792
793 /* get next free TFI */
794 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
795
796 /* fake a resource request */
797 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
798 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
799 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
800 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
801 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability = 1;
802 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
803 Count_MS_RA_capability_value = 1;
804 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
805 MS_RA_capability_value[0].u.Content.
806 Exist_Multislot_capability = 1;
807 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
808 MS_RA_capability_value[0].u.Content.Multislot_capability.
809 Exist_GPRS_multislot_class = 1;
810 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
811 MS_RA_capability_value[0].u.Content.Multislot_capability.
812 GPRS_multislot_class = ms_class;
813 if (egprs_ms_class) {
814 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
815 MS_RA_capability_value[0].u.Content.
816 Multislot_capability.Exist_EGPRS_multislot_class = 1;
817 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
818 MS_RA_capability_value[0].u.Content.
819 Multislot_capability.EGPRS_multislot_class = ms_class;
820 }
821
822 send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
823
824 /* check the TBF */
825 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
826 OSMO_ASSERT(ul_tbf != NULL);
827 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
828
829 /* send packet uplink assignment */
830 *fn = sba_fn;
831 request_dl_rlc_block(ul_tbf, fn);
832
833 /* send real acknowledgement */
834 send_control_ack(ul_tbf);
835
836 check_tbf(ul_tbf);
837
838 /* send fake data */
839 uint8_t data_msg[42] = {
840 0x00 | 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
841 uint8_t(0 | (tfi << 1)),
842 uint8_t(1), /* BSN:7, E:1 */
843 };
844
845 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
846 pdch->rcv_block(&data_msg[0], 23, *fn, &meas);
847
848 ms = the_bts->ms_by_tlli(tlli);
849 OSMO_ASSERT(ms != NULL);
850 OSMO_ASSERT(ms->ta() == qta/4);
851 OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
852
853 /*
854 * TS 44.060, B.8.1
855 * first seg received first, later second seg
856 */
857 cs = GprsCodingScheme::MCS3;
858 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
859 egprs3->si = 1;
860 egprs3->r = 1;
861 egprs3->cv = 7;
862 egprs3->tfi_hi = tfi & 0x03;
863 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
864 egprs3->bsn1_hi = 1;
865 egprs3->bsn1_lo = 0;
866 egprs3->cps_hi = 1;
867 data_msg[3] = 0xff;
868 egprs3->pi = 0;
869 egprs3->cps_lo = 1;
870 egprs3->rsb = 0;
871 egprs3->spb = 2;
872 egprs3->pi = 0;
873
874 pdch->rcv_block(data_msg, 42, *fn, &meas);
875
876 struct gprs_rlc_data *block = ul_tbf->m_rlc.block(1);
877
878 /* check the status of the block */
879 OSMO_ASSERT(block->spb_status.block_status_ul ==
880 EGPRS_RESEG_FIRST_SEG_RXD);
881
882 egprs3->si = 1;
883 egprs3->r = 1;
884 egprs3->cv = 7;
885 egprs3->tfi_hi = tfi & 0x03;
886 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
887 egprs3->bsn1_hi = 1;
888 egprs3->bsn1_lo = 0;
889 egprs3->cps_hi = 1;
890 data_msg[3] = 0xff;
891 egprs3->pi = 0;
892 egprs3->cps_lo = 1;
893 egprs3->rsb = 0;
894 egprs3->spb = 3;
895
896 pdch->rcv_block(data_msg, 42, *fn, &meas);
897
898 /* check the status of the block */
899 OSMO_ASSERT(block->spb_status.block_status_ul ==
900 EGPRS_RESEG_DEFAULT);
901 OSMO_ASSERT(block->cs_last ==
902 GprsCodingScheme::MCS6);
903 /* Assembled MCS is MCS6. so the size is 74 */
904 OSMO_ASSERT(block->len == 74);
905
906 /*
907 * TS 44.060, B.8.1
908 * second seg first, later first seg
909 */
910 memset(data_msg, 0, sizeof(data_msg));
911
912 cs = GprsCodingScheme::MCS3;
913 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
914 egprs3->si = 1;
915 egprs3->r = 1;
916 egprs3->cv = 7;
917 egprs3->tfi_hi = tfi & 0x03;
918 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
919 egprs3->bsn1_hi = 2;
920 egprs3->bsn1_lo = 0;
921 egprs3->cps_hi = 1;
922 data_msg[3] = 0xff;
923 egprs3->pi = 0;
924 egprs3->cps_lo = 1;
925 egprs3->rsb = 0;
926 egprs3->spb = 3;
927 egprs3->pi = 0;
928
929 pdch->rcv_block(data_msg, 42, *fn, &meas);
930
931 block = ul_tbf->m_rlc.block(2);
932 /* check the status of the block */
933 OSMO_ASSERT(block->spb_status.block_status_ul ==
934 EGPRS_RESEG_SECOND_SEG_RXD);
935
936 egprs3->si = 1;
937 egprs3->r = 1;
938 egprs3->cv = 7;
939 egprs3->tfi_hi = tfi & 0x03;
940 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
941 egprs3->bsn1_hi = 2;
942 egprs3->bsn1_lo = 0;
943 egprs3->cps_hi = 1;
944 data_msg[3] = 0xff;
945 egprs3->pi = 0;
946 egprs3->cps_lo = 1;
947 egprs3->rsb = 0;
948 egprs3->spb = 2;
949 egprs3->pi = 0;
950
951 pdch->rcv_block(data_msg, 42, *fn, &meas);
952
953 /* check the status of the block */
954 OSMO_ASSERT(block->spb_status.block_status_ul ==
955 EGPRS_RESEG_DEFAULT);
956 OSMO_ASSERT(block->cs_last ==
957 GprsCodingScheme::MCS6);
958 /* Assembled MCS is MCS6. so the size is 74 */
959 OSMO_ASSERT(block->len == 74);
960
961 /*
962 * TS 44.060, B.8.1
963 * Error scenario with spb as 1
964 */
965 cs = GprsCodingScheme::MCS3;
966 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
967 egprs3->si = 1;
968 egprs3->r = 1;
969 egprs3->cv = 7;
970 egprs3->tfi_hi = tfi & 0x03;
971 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
972 egprs3->bsn1_hi = 3;
973 egprs3->bsn1_lo = 0;
974 egprs3->cps_hi = 1;
975 data_msg[3] = 0xff;
976 egprs3->pi = 0;
977 egprs3->cps_lo = 1;
978 egprs3->rsb = 0;
979 egprs3->spb = 1;
980 egprs3->pi = 0;
981
982 pdch->rcv_block(data_msg, 42, *fn, &meas);
983
984 block = ul_tbf->m_rlc.block(3);
985 /* check the status of the block */
986 OSMO_ASSERT(block->spb_status.block_status_ul ==
987 EGPRS_RESEG_DEFAULT);
988 /*
989 * TS 44.060, B.8.1
990 * comparison of rlc_data for multiple scenarios
991 * Receive First, the second(BSN 3)
992 * Receive First, First then Second(BSN 4)
993 * Receive Second then First(BSN 5)
994 * after above 3 scenarios are triggered,
995 * rlc_data of all 3 BSN are compared
996 */
997
998 /* Initialize the data_msg */
999 for (i = 0; i < 42; i++)
1000 data_msg[i] = i;
1001
1002 cs = GprsCodingScheme::MCS3;
1003 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1004 egprs3->si = 1;
1005 egprs3->r = 1;
1006 egprs3->cv = 7;
1007 egprs3->tfi_hi = tfi & 0x03;
1008 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1009 egprs3->bsn1_hi = 3;
1010 egprs3->bsn1_lo = 0;
1011 egprs3->cps_hi = 1;
1012 data_msg[3] = 0xff;
1013 egprs3->pi = 0;
1014 egprs3->cps_lo = 1;
1015 egprs3->rsb = 0;
1016 egprs3->spb = 2;
1017 egprs3->pi = 0;
1018
1019 pdch->rcv_block(data_msg, 42, *fn, &meas);
1020
1021 block = ul_tbf->m_rlc.block(3);
1022 /* check the status of the block */
1023 OSMO_ASSERT(block->spb_status.block_status_ul ==
1024 EGPRS_RESEG_FIRST_SEG_RXD);
1025
1026 cs = GprsCodingScheme::MCS3;
1027 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1028 egprs3->si = 1;
1029 egprs3->r = 1;
1030 egprs3->cv = 7;
1031 egprs3->tfi_hi = tfi & 0x03;
1032 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1033 egprs3->bsn1_hi = 3;
1034 egprs3->bsn1_lo = 0;
1035 egprs3->cps_hi = 1;
1036 data_msg[3] = 0xff;
1037 egprs3->pi = 0;
1038 egprs3->cps_lo = 1;
1039 egprs3->rsb = 0;
1040 egprs3->spb = 3;
1041 egprs3->pi = 0;
1042
1043 pdch->rcv_block(data_msg, 42, *fn, &meas);
1044
1045 block = ul_tbf->m_rlc.block(3);
1046 /* check the status of the block */
1047 OSMO_ASSERT(block->spb_status.block_status_ul ==
1048 EGPRS_RESEG_DEFAULT);
1049 /* Assembled MCS is MCS6. so the size is 74 */
1050 OSMO_ASSERT(block->len == 74);
1051 OSMO_ASSERT(block->cs_last ==
1052 GprsCodingScheme::MCS6);
1053
1054 cs = GprsCodingScheme::MCS3;
1055 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1056 egprs3->si = 1;
1057 egprs3->r = 1;
1058 egprs3->cv = 7;
1059 egprs3->tfi_hi = tfi & 0x03;
1060 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1061 egprs3->bsn1_hi = 4;
1062 egprs3->bsn1_lo = 0;
1063 egprs3->cps_hi = 1;
1064 data_msg[3] = 0xff;
1065 egprs3->pi = 0;
1066 egprs3->cps_lo = 1;
1067 egprs3->rsb = 0;
1068 egprs3->spb = 2;
1069 egprs3->pi = 0;
1070
1071 pdch->rcv_block(data_msg, 42, *fn, &meas);
1072
1073 block = ul_tbf->m_rlc.block(4);
1074 /* check the status of the block */
1075 OSMO_ASSERT(block->spb_status.block_status_ul ==
1076 EGPRS_RESEG_FIRST_SEG_RXD);
1077
1078 cs = GprsCodingScheme::MCS3;
1079 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1080 egprs3->si = 1;
1081 egprs3->r = 1;
1082 egprs3->cv = 7;
1083 egprs3->tfi_hi = tfi & 0x03;
1084 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1085 egprs3->bsn1_hi = 4;
1086 egprs3->bsn1_lo = 0;
1087 egprs3->cps_hi = 1;
1088 data_msg[3] = 0xff;
1089 egprs3->pi = 0;
1090 egprs3->cps_lo = 1;
1091 egprs3->rsb = 0;
1092 egprs3->spb = 2;
1093 egprs3->pi = 0;
1094
1095 pdch->rcv_block(data_msg, 42, *fn, &meas);
1096
1097 block = ul_tbf->m_rlc.block(4);
1098 /* check the status of the block */
1099 OSMO_ASSERT(block->spb_status.block_status_ul ==
1100 EGPRS_RESEG_FIRST_SEG_RXD);
1101
1102 cs = GprsCodingScheme::MCS3;
1103 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1104 egprs3->si = 1;
1105 egprs3->r = 1;
1106 egprs3->cv = 7;
1107 egprs3->tfi_hi = tfi & 0x03;
1108 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1109 egprs3->bsn1_hi = 4;
1110 egprs3->bsn1_lo = 0;
1111 egprs3->cps_hi = 1;
1112 data_msg[3] = 0xff;
1113 egprs3->pi = 0;
1114 egprs3->cps_lo = 1;
1115 egprs3->rsb = 0;
1116 egprs3->spb = 3;
1117 egprs3->pi = 0;
1118
1119 pdch->rcv_block(data_msg, 42, *fn, &meas);
1120
1121 block = ul_tbf->m_rlc.block(4);
1122 /* check the status of the block */
1123 OSMO_ASSERT(block->spb_status.block_status_ul ==
1124 EGPRS_RESEG_DEFAULT);
1125 OSMO_ASSERT(block->cs_last ==
1126 GprsCodingScheme::MCS6);
1127 /* Assembled MCS is MCS6. so the size is 74 */
1128 OSMO_ASSERT(block->len == 74);
1129
1130 cs = GprsCodingScheme::MCS3;
1131 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1132 egprs3->si = 1;
1133 egprs3->r = 1;
1134 egprs3->cv = 7;
1135 egprs3->tfi_hi = tfi & 0x03;
1136 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1137 egprs3->bsn1_hi = 5;
1138 egprs3->bsn1_lo = 0;
1139 egprs3->cps_hi = 1;
1140 data_msg[3] = 0xff;
1141 egprs3->pi = 0;
1142 egprs3->cps_lo = 1;
1143 egprs3->rsb = 0;
1144 egprs3->spb = 3;
1145 egprs3->pi = 0;
1146
1147 pdch->rcv_block(data_msg, 42, *fn, &meas);
1148
1149 block = ul_tbf->m_rlc.block(5);
1150 /* check the status of the block */
1151 OSMO_ASSERT(block->spb_status.block_status_ul ==
1152 EGPRS_RESEG_SECOND_SEG_RXD);
1153
1154 cs = GprsCodingScheme::MCS3;
1155 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1156 egprs3->si = 1;
1157 egprs3->r = 1;
1158 egprs3->cv = 7;
1159 egprs3->tfi_hi = tfi & 0x03;
1160 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1161 egprs3->bsn1_hi = 5;
1162 egprs3->bsn1_lo = 0;
1163 egprs3->cps_hi = 1;
1164 data_msg[3] = 0xff;
1165 egprs3->pi = 0;
1166 egprs3->cps_lo = 1;
1167 egprs3->rsb = 0;
1168 egprs3->spb = 2;
1169 egprs3->pi = 0;
1170
1171 pdch->rcv_block(data_msg, 42, *fn, &meas);
1172
1173 block = ul_tbf->m_rlc.block(5);
1174
1175 /* check the status of the block */
1176 OSMO_ASSERT(block->spb_status.block_status_ul ==
1177 EGPRS_RESEG_DEFAULT);
1178 OSMO_ASSERT(block->cs_last ==
1179 GprsCodingScheme::MCS6);
1180 /* Assembled MCS is MCS6. so the size is 74 */
1181 OSMO_ASSERT(block->len == 74);
1182
1183 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->len ==
1184 ul_tbf->m_rlc.block(4)->len);
1185 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->len ==
1186 ul_tbf->m_rlc.block(3)->len);
1187
1188 /* Compare the spb status of each BSNs(3,4,5). should be same */
1189 OSMO_ASSERT(
1190 ul_tbf->m_rlc.block(5)->spb_status.block_status_ul ==
1191 ul_tbf->m_rlc.block(4)->spb_status.block_status_ul);
1192 OSMO_ASSERT(
1193 ul_tbf->m_rlc.block(5)->spb_status.block_status_ul ==
1194 ul_tbf->m_rlc.block(3)->spb_status.block_status_ul);
1195
1196 /* Compare the Assembled MCS of each BSNs(3,4,5). should be same */
1197 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->cs_last ==
1198 ul_tbf->m_rlc.block(4)->cs_last);
1199 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->cs_last ==
1200 ul_tbf->m_rlc.block(3)->cs_last);
1201
1202 /* Compare the data of each BSNs(3,4,5). should be same */
1203 OSMO_ASSERT(
1204 !memcmp(ul_tbf->m_rlc.block(5)->block,
1205 ul_tbf->m_rlc.block(4)->block, ul_tbf->m_rlc.block(5)->len
1206 ));
1207 OSMO_ASSERT(
1208 !memcmp(ul_tbf->m_rlc.block(5)->block,
1209 ul_tbf->m_rlc.block(3)->block, ul_tbf->m_rlc.block(5)->len
1210 ));
1211
1212 return ul_tbf;
1213}
1214
sivasankari1d8744c2017-01-24 15:53:35 +05301215static gprs_rlcmac_ul_tbf *establish_ul_tbf(BTS *the_bts,
1216 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1217 uint8_t ms_class, uint8_t egprs_ms_class)
1218{
sivasankari1d8744c2017-01-24 15:53:35 +05301219 uint32_t rach_fn = *fn - 51;
1220 uint32_t sba_fn = *fn + 52;
1221 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001222 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301223 gprs_rlcmac_ul_tbf *ul_tbf;
sivasankari1d8744c2017-01-24 15:53:35 +05301224 gprs_rlcmac_bts *bts;
1225 RlcMacUplink_t ulreq = {0};
1226 struct pcu_l1_meas meas;
sivasankari1d8744c2017-01-24 15:53:35 +05301227 GprsCodingScheme cs;
1228
1229 meas.set_rssi(31);
1230 bts = the_bts->bts_data();
1231
1232 /* needed to set last_rts_fn in the PDCH object */
1233 request_dl_rlc_block(bts, trx_no, ts_no, fn);
1234
1235 /*
1236 * simulate RACH, this sends an Immediate
1237 * Assignment Uplink on the AGCH
1238 */
1239 the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0);
1240
1241 /* get next free TFI */
1242 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
1243
1244 /* fake a resource request */
1245 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
1246 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
1247 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
1248 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
1249 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability = 1;
1250 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1251 Count_MS_RA_capability_value = 1;
1252 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1253 MS_RA_capability_value[0].u.Content.
1254 Exist_Multislot_capability = 1;
1255 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1256 MS_RA_capability_value[0].u.Content.Multislot_capability.
1257 Exist_GPRS_multislot_class = 1;
1258 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1259 MS_RA_capability_value[0].u.Content.Multislot_capability.
1260 GPRS_multislot_class = ms_class;
1261 if (egprs_ms_class) {
1262 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1263 MS_RA_capability_value[0].u.Content.
1264 Multislot_capability.Exist_EGPRS_multislot_class = 1;
1265 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1266 MS_RA_capability_value[0].u.Content.
1267 Multislot_capability.EGPRS_multislot_class = ms_class;
1268 }
1269 send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
1270
1271 /* check the TBF */
1272 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
1273 /* send packet uplink assignment */
1274 *fn = sba_fn;
1275 request_dl_rlc_block(ul_tbf, fn);
1276
1277 /* send real acknowledgement */
1278 send_control_ack(ul_tbf);
1279
1280 check_tbf(ul_tbf);
1281
1282 return ul_tbf;
1283}
1284
1285static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_no_length(BTS *the_bts,
1286 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1287 uint8_t ms_class, uint8_t egprs_ms_class, gprs_rlcmac_ul_tbf *ul_tbf)
1288{
1289 OSMO_ASSERT(ul_tbf);
1290 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1291 GprsMs *ms;
sivasankari1d8744c2017-01-24 15:53:35 +05301292 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001293 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301294 struct gprs_rlcmac_pdch *pdch;
sivasankari1d8744c2017-01-24 15:53:35 +05301295 struct pcu_l1_meas meas;
sivasankari1d8744c2017-01-24 15:53:35 +05301296 GprsCodingScheme cs;
1297
1298
1299 /* send fake data with cv=0*/
1300 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1301 uint8_t data[49] = {0};
1302
1303 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1304
1305 /*header_construction */
1306 memset(data, 0x2b, sizeof(data));
1307 /* Message with CRBB */
1308 for (int i = 0 ; i < 80; i++) {
1309 hdr3->r = 0;
1310 hdr3->si = 0;
1311 hdr3->cv = 10;
1312 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1313 hdr3->tfi_lo = tfi & 0x7;
1314 hdr3->bsn1_hi = ((i * 2)&0x1f);
1315 hdr3->bsn1_lo = ((i * 2)/32);
1316 hdr3->cps_hi = 0;
1317 hdr3->cps_lo = 0;
1318 hdr3->spb = 0;
1319 hdr3->rsb = 0;
1320 hdr3->pi = 0;
1321 hdr3->spare = 0;
1322 hdr3->dummy = 1;
1323 data[4] = 0x0;
1324 data[5] = 0x0;
1325 data[6] = 0x2b;
1326 data[7] = 0x2b;
1327 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
1328 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1329 }
1330 ul_tbf->create_ul_ack(*fn, ts_no);
1331 memset(data, 0x2b, sizeof(data));
1332 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1333 hdr3->r = 0;
1334 hdr3->si = 0;
1335 hdr3->cv = 0;
1336 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1337 hdr3->tfi_lo = tfi & 0x7;
1338 hdr3->bsn1_hi = 0;
1339 hdr3->bsn1_lo = 2;
1340 hdr3->cps_hi = 0;
1341 hdr3->cps_lo = 0;
1342 hdr3->spb = 0;
1343 hdr3->rsb = 0;
1344 hdr3->pi = 0;
1345 hdr3->spare = 0;
1346 hdr3->dummy = 1;
1347 data[4] = 0x0;
1348 data[5] = 0x2b;
1349 data[6] = 0x2b;
1350 data[7] = 0x2b;
1351
1352 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
1353 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1354
1355 request_dl_rlc_block(ul_tbf, fn);
1356
1357 check_tbf(ul_tbf);
Max088c7df2018-01-23 20:16:23 +01001358 OSMO_ASSERT(ul_tbf->ul_ack_state_is(GPRS_RLCMAC_UL_ACK_NONE));
sivasankari1d8744c2017-01-24 15:53:35 +05301359
1360 ms = the_bts->ms_by_tlli(tlli);
1361 OSMO_ASSERT(ms != NULL);
1362 OSMO_ASSERT(ms->ta() == qta/4);
1363 OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
1364
1365 return ul_tbf;
1366}
1367
1368static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_with_length(BTS *the_bts,
1369 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1370 uint8_t ms_class, uint8_t egprs_ms_class, gprs_rlcmac_ul_tbf *ul_tbf)
1371{
1372 OSMO_ASSERT(ul_tbf);
1373 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1374 GprsMs *ms;
sivasankari1d8744c2017-01-24 15:53:35 +05301375 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001376 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301377 struct gprs_rlcmac_pdch *pdch;
sivasankari1d8744c2017-01-24 15:53:35 +05301378 struct pcu_l1_meas meas;
sivasankari1d8744c2017-01-24 15:53:35 +05301379 GprsCodingScheme cs;
1380
1381 check_tbf(ul_tbf);
1382 /* send fake data with cv=0*/
1383 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1384 uint8_t data[49] = {0};
1385
1386 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1387
1388 /*header_construction */
1389 memset(data, 0x2b, sizeof(data));
1390
1391 /* Message with URBB & URBB length */
1392 for (int i = 0 ; i < 20; i++) {
1393 hdr3->r = 0;
1394 hdr3->si = 0;
1395 hdr3->cv = 10;
1396 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1397 hdr3->tfi_lo = tfi & 0x7;
1398 hdr3->bsn1_hi = ((i * 2)&0x1f);
1399 hdr3->bsn1_lo = ((i * 2)/32);
1400 hdr3->cps_hi = 0;
1401 hdr3->cps_lo = 0;
1402 hdr3->spb = 0;
1403 hdr3->rsb = 0;
1404 hdr3->pi = 0;
1405 hdr3->spare = 0;
1406 hdr3->dummy = 1;
1407 data[4] = 0x0;
1408 data[5] = 0x0;
1409 data[6] = 0x2b;
1410 data[7] = 0x2b;
1411 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
1412 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1413 }
1414 ul_tbf->create_ul_ack(*fn, ts_no);
1415 memset(data, 0x2b, sizeof(data));
1416 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1417 hdr3->r = 0;
1418 hdr3->si = 0;
1419 hdr3->cv = 0;
1420 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1421 hdr3->tfi_lo = tfi & 0x7;
1422 hdr3->bsn1_hi = 0;
1423 hdr3->bsn1_lo = 2;
1424 hdr3->cps_hi = 0;
1425 hdr3->cps_lo = 0;
1426 hdr3->spb = 0;
1427 hdr3->rsb = 0;
1428 hdr3->pi = 0;
1429 hdr3->spare = 0;
1430 hdr3->dummy = 1;
1431 data[4] = 0x0;
1432 data[5] = 0x2b;
1433 data[6] = 0x2b;
1434 data[7] = 0x2b;
1435
1436 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
1437 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1438
1439 request_dl_rlc_block(ul_tbf, fn);
1440
1441 check_tbf(ul_tbf);
Max088c7df2018-01-23 20:16:23 +01001442 OSMO_ASSERT(ul_tbf->ul_ack_state_is(GPRS_RLCMAC_UL_ACK_NONE));
sivasankari1d8744c2017-01-24 15:53:35 +05301443
1444 ms = the_bts->ms_by_tlli(tlli);
1445 OSMO_ASSERT(ms != NULL);
1446 OSMO_ASSERT(ms->ta() == qta/4);
1447 OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
1448
1449 return ul_tbf;
1450}
1451
1452static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_CRBB(BTS *the_bts,
1453 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1454 uint8_t ms_class, uint8_t egprs_ms_class)
1455{
1456 GprsMs *ms;
sivasankari1d8744c2017-01-24 15:53:35 +05301457 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001458 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301459 gprs_rlcmac_ul_tbf *ul_tbf;
1460 struct gprs_rlcmac_pdch *pdch;
sivasankari1d8744c2017-01-24 15:53:35 +05301461 struct pcu_l1_meas meas;
sivasankari1d8744c2017-01-24 15:53:35 +05301462 GprsCodingScheme cs;
1463
1464
1465 /* check the TBF */
1466 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
1467 OSMO_ASSERT(ul_tbf);
1468 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1469
1470 /* send fake data with cv=0*/
1471 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1472 uint8_t data[49] = {0};
1473
1474 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1475
1476 /*header_construction */
1477 memset(data, 0x2b, sizeof(data));
1478
1479 /* Message with CRBB */
1480 for (int i = 80 ; i < 160; i++) {
1481 hdr3->r = 0;
1482 hdr3->si = 0;
1483 hdr3->cv = 10;
1484 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1485 hdr3->tfi_lo = tfi & 0x7;
1486 hdr3->bsn1_hi = ((i)&0x1f);
1487 hdr3->bsn1_lo = ((i)/32);
1488 hdr3->cps_hi = 0;
1489 hdr3->cps_lo = 0;
1490 hdr3->spb = 0;
1491 hdr3->rsb = 0;
1492 hdr3->pi = 0;
1493 hdr3->spare = 0;
1494 hdr3->dummy = 1;
1495 data[4] = 0x0;
1496 data[5] = 0x0;
1497 data[6] = 0x2b;
1498 data[7] = 0x2b;
1499 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
1500 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1501 }
1502 ul_tbf->create_ul_ack(*fn, ts_no);
1503 memset(data, 0x2b, sizeof(data));
1504 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1505 hdr3->r = 0;
1506 hdr3->si = 0;
1507 hdr3->cv = 0;
1508 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1509 hdr3->tfi_lo = tfi & 0x7;
1510 hdr3->bsn1_hi = 0;
1511 hdr3->bsn1_lo = 2;
1512 hdr3->cps_hi = 0;
1513 hdr3->cps_lo = 0;
1514 hdr3->spb = 0;
1515 hdr3->rsb = 0;
1516 hdr3->pi = 0;
1517 hdr3->spare = 0;
1518 hdr3->dummy = 1;
1519 data[4] = 0x0;
1520 data[5] = 0x2b;
1521 data[6] = 0x2b;
1522 data[7] = 0x2b;
1523
1524 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
1525 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1526
1527 request_dl_rlc_block(ul_tbf, fn);
1528
1529 check_tbf(ul_tbf);
Max088c7df2018-01-23 20:16:23 +01001530 OSMO_ASSERT(ul_tbf->ul_ack_state_is(GPRS_RLCMAC_UL_ACK_NONE));
sivasankari1d8744c2017-01-24 15:53:35 +05301531
1532 ms = the_bts->ms_by_tlli(tlli);
1533 OSMO_ASSERT(ms != NULL);
1534 OSMO_ASSERT(ms->ta() == qta/4);
1535 OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
1536
1537 return ul_tbf;
1538}
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001539static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase(BTS *the_bts,
1540 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001541 uint8_t ms_class, uint8_t egprs_ms_class)
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001542{
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001543 GprsMs *ms;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001544 uint32_t rach_fn = *fn - 51;
1545 uint32_t sba_fn = *fn + 52;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001546 uint8_t trx_no = 0;
1547 int tfi = 0;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001548 gprs_rlcmac_ul_tbf *ul_tbf;
1549 struct gprs_rlcmac_pdch *pdch;
1550 gprs_rlcmac_bts *bts;
1551 RlcMacUplink_t ulreq = {0};
Jacob Erlbeck20f6fd12015-06-08 11:05:45 +02001552 struct pcu_l1_meas meas;
1553 meas.set_rssi(31);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001554
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001555 bts = the_bts->bts_data();
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001556
1557 /* needed to set last_rts_fn in the PDCH object */
Max878bd1f2016-07-20 13:05:05 +02001558 request_dl_rlc_block(bts, trx_no, ts_no, fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001559
bhargava959d1de2016-08-17 15:17:21 +05301560 /* simulate RACH, sends an Immediate Assignment Uplink on the AGCH */
1561 the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001562
1563 /* get next free TFI */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001564 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001565
1566 /* fake a resource request */
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001567 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
1568 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
1569 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
1570 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001571 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability = 1;
1572 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1573 Count_MS_RA_capability_value = 1;
1574 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1575 MS_RA_capability_value[0].u.Content.Exist_Multislot_capability = 1;
1576 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1577 MS_RA_capability_value[0].u.Content.Multislot_capability.
1578 Exist_GPRS_multislot_class = 1;
1579 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1580 MS_RA_capability_value[0].u.Content.Multislot_capability.
1581 GPRS_multislot_class = ms_class;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001582 if (egprs_ms_class) {
1583 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1584 MS_RA_capability_value[0].u.Content.Multislot_capability.
1585 Exist_EGPRS_multislot_class = 1;
1586 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1587 MS_RA_capability_value[0].u.Content.Multislot_capability.
1588 EGPRS_multislot_class = ms_class;
1589 }
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001590
Jacob Erlbeck56f99d12015-08-20 15:55:56 +02001591 send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001592
1593 /* check the TBF */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001594 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001595 OSMO_ASSERT(ul_tbf != NULL);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +02001596 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001597
1598 /* send packet uplink assignment */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001599 *fn = sba_fn;
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +02001600 request_dl_rlc_block(ul_tbf, fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001601
Jacob Erlbeckaf454732015-08-21 15:03:23 +02001602 /* send real acknowledgement */
1603 send_control_ack(ul_tbf);
1604
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001605 check_tbf(ul_tbf);
1606
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001607 /* send fake data */
1608 uint8_t data_msg[23] = {
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001609 0x00 | 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
1610 uint8_t(0 | (tfi << 1)),
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001611 uint8_t(1), /* BSN:7, E:1 */
1612 };
1613
Jacob Erlbeck56f99d12015-08-20 15:55:56 +02001614 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001615 pdch->rcv_block(&data_msg[0], sizeof(data_msg), *fn, &meas);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001616
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001617 ms = the_bts->ms_by_tlli(tlli);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001618 OSMO_ASSERT(ms != NULL);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +02001619 OSMO_ASSERT(ms->ta() == qta/4);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001620 OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
1621
1622 return ul_tbf;
1623}
1624
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001625static void send_dl_data(BTS *the_bts, uint32_t tlli, const char *imsi,
1626 const uint8_t *data, unsigned data_size)
1627{
1628 GprsMs *ms, *ms2;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001629
1630 ms = the_bts->ms_store().get_ms(tlli, 0, imsi);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001631
Jacob Erlbeck14e00f82015-11-27 18:10:39 +01001632 gprs_rlcmac_dl_tbf::handle(the_bts->bts_data(), tlli, 0, imsi, 0, 0,
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001633 1000, data, data_size);
1634
1635 ms = the_bts->ms_by_imsi(imsi);
1636 OSMO_ASSERT(ms != NULL);
1637 OSMO_ASSERT(ms->dl_tbf() != NULL);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001638
1639 if (imsi[0] && strcmp(imsi, "000") != 0) {
1640 ms2 = the_bts->ms_by_tlli(tlli);
1641 OSMO_ASSERT(ms == ms2);
1642 }
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001643}
1644
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001645static void transmit_dl_data(BTS *the_bts, uint32_t tlli, uint32_t *fn,
1646 uint8_t slots = 0xff)
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001647{
1648 gprs_rlcmac_dl_tbf *dl_tbf;
1649 GprsMs *ms;
1650 unsigned ts_no;
1651
1652 ms = the_bts->ms_by_tlli(tlli);
1653 OSMO_ASSERT(ms);
1654 dl_tbf = ms->dl_tbf();
1655 OSMO_ASSERT(dl_tbf);
1656
1657 while (dl_tbf->have_data()) {
1658 uint8_t bn = fn2bn(*fn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001659 for (ts_no = 0 ; ts_no < 8; ts_no += 1) {
1660 if (!(slots & (1 << ts_no)))
1661 continue;
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001662 gprs_rlcmac_rcv_rts_block(the_bts->bts_data(),
Max878bd1f2016-07-20 13:05:05 +02001663 dl_tbf->trx->trx_no, ts_no,
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001664 *fn, bn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001665 }
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001666 *fn = fn_add_blocks(*fn, 1);
1667 }
1668}
1669
Max4c112dc2018-02-01 16:49:23 +01001670static inline void print_ta_tlli(const gprs_rlcmac_ul_tbf *ul_tbf, bool print_ms)
1671{
1672 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
1673 if (print_ms)
1674 fprintf(stderr, "Got MS: TLLI = 0x%08x, TA = %d\n", ul_tbf->ms()->tlli(), ul_tbf->ms()->ta());
1675}
1676
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001677static void test_tbf_single_phase()
1678{
1679 BTS the_bts;
1680 int ts_no = 7;
Philippd935d882016-11-07 13:07:36 +01001681 uint32_t fn = DUMMY_FN; /* 17,25,9 */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001682 uint32_t tlli = 0xf1223344;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001683 const char *imsi = "0011223344";
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001684 uint16_t qta = 31;
1685 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001686
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
Max4c112dc2018-02-01 16:49:23 +01001693 print_ta_tlli(ul_tbf, true);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001694 send_dl_data(&the_bts, tlli, imsi, (const uint8_t *)"TEST", 4);
1695
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001696 printf("=== end %s ===\n", __func__);
1697}
1698
sivasankari1d8744c2017-01-24 15:53:35 +05301699static void test_tbf_egprs_two_phase_puan(void)
1700{
1701 BTS the_bts;
1702 int ts_no = 7;
1703 uint32_t fn = 2654218;
1704 uint16_t qta = 31;
1705 uint32_t tlli = 0xf1223344;
1706 const char *imsi = "0011223344";
1707 uint8_t ms_class = 1;
1708 gprs_rlcmac_bts *bts;
1709 uint8_t egprs_ms_class = 1;
1710 gprs_rlcmac_ul_tbf *ul_tbf;
sivasankari1d8744c2017-01-24 15:53:35 +05301711 uint8_t test_data[256];
1712
1713 printf("=== start %s ===\n", __func__);
1714
1715 memset(test_data, 1, sizeof(test_data));
1716
1717 setup_bts(&the_bts, ts_no, 4);
1718 the_bts.bts_data()->initial_mcs_dl = 9;
1719 the_bts.bts_data()->egprs_enabled = 1;
1720 bts = the_bts.bts_data();
1721 bts->ws_base = 128;
1722 bts->ws_pdch = 64;
1723
1724 ul_tbf = establish_ul_tbf(&the_bts, ts_no, tlli, &fn, qta, ms_class, egprs_ms_class);
1725 /* Function to generate URBB with no length */
1726 ul_tbf = establish_ul_tbf_two_phase_puan_URBB_no_length(&the_bts, ts_no, tlli, &fn,
1727 qta, ms_class, egprs_ms_class, ul_tbf);
1728
Max4c112dc2018-02-01 16:49:23 +01001729 print_ta_tlli(ul_tbf, true);
sivasankari1d8744c2017-01-24 15:53:35 +05301730 send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data));
1731
Maxea98b7d2018-01-04 15:13:27 +01001732 ul_tbf->window()->reset_state();
sivasankari1d8744c2017-01-24 15:53:35 +05301733 /* Function to generate URBB with length */
1734 ul_tbf = establish_ul_tbf_two_phase_puan_URBB_with_length(&the_bts, ts_no, tlli, &fn,
1735 qta, ms_class, egprs_ms_class, ul_tbf);
1736
Max4c112dc2018-02-01 16:49:23 +01001737 print_ta_tlli(ul_tbf, true);
sivasankari1d8744c2017-01-24 15:53:35 +05301738 send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data));
1739
Maxea98b7d2018-01-04 15:13:27 +01001740 ul_tbf->window()->reset_state();
sivasankari1d8744c2017-01-24 15:53:35 +05301741 /* Function to generate CRBB */
1742 bts->ws_base = 128;
1743 bts->ws_pdch = 64;
1744 ul_tbf = establish_ul_tbf_two_phase_puan_CRBB(&the_bts, ts_no, tlli, &fn,
1745 qta, ms_class, egprs_ms_class);
1746
Max4c112dc2018-02-01 16:49:23 +01001747 print_ta_tlli(ul_tbf, true);
sivasankari1d8744c2017-01-24 15:53:35 +05301748 send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data));
1749
1750 printf("=== end %s ===\n", __func__);
1751}
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301752/*
1753 * Trigger rach for single block
1754 */
1755static void test_immediate_assign_rej_single_block()
1756{
1757 BTS the_bts;
1758 uint32_t fn = 2654218;
1759 uint16_t qta = 31;
1760 int ts_no = 7;
1761
1762 printf("=== start %s ===\n", __func__);
1763
1764 setup_bts(&the_bts, ts_no, 4);
1765
1766 the_bts.bts_data()->trx[0].pdch[ts_no].disable();
1767
1768 uint32_t rach_fn = fn - 51;
1769
1770 int rc = 0;
1771
1772 /*
1773 * simulate RACH, sends an Immediate Assignment
1774 * Uplink reject on the AGCH
1775 */
1776 rc = the_bts.rcv_rach(0x70, rach_fn, qta, 0,
1777 GSM_L1_BURST_TYPE_ACCESS_0);
1778
1779 OSMO_ASSERT(rc == -EINVAL);
1780
1781 printf("=== end %s ===\n", __func__);
1782}
1783
1784/*
1785 * Trigger rach till resources(USF) exhaust
1786 */
1787static void test_immediate_assign_rej_multi_block()
1788{
1789 BTS the_bts;
1790 uint32_t fn = 2654218;
1791 uint16_t qta = 31;
1792 int ts_no = 7;
1793
1794 printf("=== start %s ===\n", __func__);
1795
1796 setup_bts(&the_bts, ts_no, 4);
1797
1798 uint32_t rach_fn = fn - 51;
1799
1800 int rc = 0;
1801
1802 /*
1803 * simulate RACH, sends an Immediate Assignment Uplink
1804 * reject on the AGCH
1805 */
1806 rc = the_bts.rcv_rach(0x78, rach_fn, qta, 0,
1807 GSM_L1_BURST_TYPE_ACCESS_0);
1808 rc = the_bts.rcv_rach(0x79, rach_fn, qta, 0,
1809 GSM_L1_BURST_TYPE_ACCESS_0);
1810 rc = the_bts.rcv_rach(0x7a, rach_fn, qta, 0,
1811 GSM_L1_BURST_TYPE_ACCESS_0);
1812 rc = the_bts.rcv_rach(0x7b, rach_fn, qta, 0,
1813 GSM_L1_BURST_TYPE_ACCESS_0);
1814 rc = the_bts.rcv_rach(0x7c, rach_fn, qta, 0,
1815 GSM_L1_BURST_TYPE_ACCESS_0);
1816 rc = the_bts.rcv_rach(0x7d, rach_fn, qta, 0,
1817 GSM_L1_BURST_TYPE_ACCESS_0);
1818 rc = the_bts.rcv_rach(0x7e, rach_fn, qta, 0,
1819 GSM_L1_BURST_TYPE_ACCESS_0);
1820 rc = the_bts.rcv_rach(0x7f, rach_fn, qta, 0,
1821 GSM_L1_BURST_TYPE_ACCESS_0);
1822
1823 OSMO_ASSERT(rc == -EBUSY);
1824
1825 printf("=== end %s ===\n", __func__);
1826}
1827
1828static void test_immediate_assign_rej()
1829{
1830 test_immediate_assign_rej_multi_block();
1831 test_immediate_assign_rej_single_block();
1832}
1833
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001834static void test_tbf_two_phase()
1835{
1836 BTS the_bts;
1837 int ts_no = 7;
1838 uint32_t fn = 2654218;
1839 uint16_t qta = 31;
1840 uint32_t tlli = 0xf1223344;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001841 const char *imsi = "0011223344";
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001842 uint8_t ms_class = 1;
1843 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001844
1845 printf("=== start %s ===\n", __func__);
1846
1847 setup_bts(&the_bts, ts_no, 4);
1848
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001849 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli, &fn, qta,
1850 ms_class, 0);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001851
Max4c112dc2018-02-01 16:49:23 +01001852 print_ta_tlli(ul_tbf, true);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001853 send_dl_data(&the_bts, tlli, imsi, (const uint8_t *)"TEST", 4);
1854
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001855 printf("=== end %s ===\n", __func__);
1856}
1857
Max4c112dc2018-02-01 16:49:23 +01001858static inline void print_ms(const GprsMs *ms, bool old)
1859{
1860 fprintf(stderr, "%s MS: TLLI = 0x%08x, TA = %d, IMSI = %s, LLC = %zu\n",
1861 old ? "Old" : "New", ms->tlli(), ms->ta(), ms->imsi(), ms->llc_queue()->size());
1862}
1863
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001864static void test_tbf_ra_update_rach()
1865{
1866 BTS the_bts;
1867 int ts_no = 7;
1868 uint32_t fn = 2654218;
1869 uint16_t qta = 31;
1870 uint32_t tlli1 = 0xf1223344;
1871 uint32_t tlli2 = 0xf5667788;
1872 const char *imsi = "0011223344";
1873 uint8_t ms_class = 1;
1874 gprs_rlcmac_ul_tbf *ul_tbf;
1875 GprsMs *ms, *ms1, *ms2;
1876
1877 printf("=== start %s ===\n", __func__);
1878
1879 setup_bts(&the_bts, ts_no, 4);
1880
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001881 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli1, &fn, qta,
1882 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001883
1884 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01001885 print_ta_tlli(ul_tbf, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001886
1887 send_dl_data(&the_bts, tlli1, imsi, (const uint8_t *)"RAU_ACCEPT", 10);
Max4c112dc2018-02-01 16:49:23 +01001888 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001889
Jacob Erlbeckaf454732015-08-21 15:03:23 +02001890 /* Send Packet Downlink Assignment to MS */
1891 request_dl_rlc_block(ul_tbf, &fn);
1892
1893 /* Ack it */
1894 send_control_ack(ul_tbf);
1895
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001896 /* Make sure the RAU Accept gets sent to the MS */
1897 OSMO_ASSERT(ms1->llc_queue()->size() == 1);
1898 transmit_dl_data(&the_bts, tlli1, &fn);
1899 OSMO_ASSERT(ms1->llc_queue()->size() == 0);
1900
1901 /* Now establish a new TBF for the RA UPDATE COMPLETE (new TLLI) */
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001902 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli2, &fn, qta,
1903 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001904
1905 ms2 = ul_tbf->ms();
1906
1907 /* The PCU cannot know yet, that both TBF belong to the same MS */
1908 OSMO_ASSERT(ms1 != ms2);
Max4c112dc2018-02-01 16:49:23 +01001909 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001910
1911 /* Send some downlink data along with the new TLLI and the IMSI so that
1912 * the PCU can see, that both MS objects belong to same MS */
1913 send_dl_data(&the_bts, tlli2, imsi, (const uint8_t *)"DATA", 4);
1914
1915 ms = the_bts.ms_by_imsi(imsi);
1916 OSMO_ASSERT(ms == ms2);
1917
Max4c112dc2018-02-01 16:49:23 +01001918 print_ms(ms2, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001919
1920 ms = the_bts.ms_by_tlli(tlli1);
1921 OSMO_ASSERT(ms == NULL);
1922 ms = the_bts.ms_by_tlli(tlli2);
1923 OSMO_ASSERT(ms == ms2);
1924
1925 printf("=== end %s ===\n", __func__);
1926}
1927
1928static void test_tbf_dl_flow_and_rach_two_phase()
1929{
1930 BTS the_bts;
1931 int ts_no = 7;
1932 uint32_t fn = 2654218;
1933 uint16_t qta = 31;
1934 uint32_t tlli1 = 0xf1223344;
1935 const char *imsi = "0011223344";
1936 uint8_t ms_class = 1;
1937 gprs_rlcmac_ul_tbf *ul_tbf;
1938 gprs_rlcmac_dl_tbf *dl_tbf;
1939 GprsMs *ms, *ms1, *ms2;
1940
1941 printf("=== start %s ===\n", __func__);
1942
1943 setup_bts(&the_bts, ts_no, 1);
1944
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001945 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli1, &fn, qta,
1946 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001947
1948 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01001949 print_ta_tlli(ul_tbf, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001950
1951 send_dl_data(&the_bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);
1952 send_dl_data(&the_bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);
Max4c112dc2018-02-01 16:49:23 +01001953 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001954
1955 OSMO_ASSERT(ms1->llc_queue()->size() == 2);
1956 dl_tbf = ms1->dl_tbf();
1957 OSMO_ASSERT(dl_tbf != NULL);
1958
1959 /* Get rid of old UL TBF */
1960 tbf_free(ul_tbf);
1961 ms = the_bts.ms_by_tlli(tlli1);
1962 OSMO_ASSERT(ms1 == ms);
1963
1964 /* Now establish a new UL TBF, this will consume one LLC packet */
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001965 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli1, &fn, qta,
1966 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001967
1968 ms2 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01001969 print_ms(ms2, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001970
1971 /* This should be the same MS object */
1972 OSMO_ASSERT(ms2 == ms1);
1973
1974 ms = the_bts.ms_by_tlli(tlli1);
1975 OSMO_ASSERT(ms2 == ms);
1976
Jacob Erlbeckc8cbfc22015-09-01 11:38:40 +02001977 /* A DL TBF should still exist */
1978 OSMO_ASSERT(ms->dl_tbf());
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001979
1980 /* No queued packets should be lost */
Jacob Erlbeck9659d592015-09-01 11:06:14 +02001981 OSMO_ASSERT(ms->llc_queue()->size() == 2);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001982
1983 printf("=== end %s ===\n", __func__);
1984}
1985
1986
1987static void test_tbf_dl_flow_and_rach_single_phase()
1988{
1989 BTS the_bts;
1990 int ts_no = 7;
1991 uint32_t fn = 2654218;
1992 uint16_t qta = 31;
1993 uint32_t tlli1 = 0xf1223344;
1994 const char *imsi = "0011223344";
1995 uint8_t ms_class = 1;
1996 gprs_rlcmac_ul_tbf *ul_tbf;
1997 gprs_rlcmac_dl_tbf *dl_tbf;
1998 GprsMs *ms, *ms1, *ms2;
1999
2000 printf("=== start %s ===\n", __func__);
2001
2002 setup_bts(&the_bts, ts_no, 1);
2003
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002004 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli1, &fn, qta,
2005 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002006
2007 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002008 print_ta_tlli(ul_tbf, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002009
2010 send_dl_data(&the_bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);
2011 send_dl_data(&the_bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);
Max4c112dc2018-02-01 16:49:23 +01002012 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002013
2014 OSMO_ASSERT(ms1->llc_queue()->size() == 2);
2015 dl_tbf = ms1->dl_tbf();
2016 OSMO_ASSERT(dl_tbf != NULL);
2017
2018 /* Get rid of old UL TBF */
2019 tbf_free(ul_tbf);
2020 ms = the_bts.ms_by_tlli(tlli1);
2021 OSMO_ASSERT(ms1 == ms);
2022
2023 /* Now establish a new UL TBF */
2024 ul_tbf = establish_ul_tbf_single_phase(&the_bts, ts_no, tlli1, &fn, qta);
2025
2026 ms2 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002027 print_ms(ms2, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002028
2029 /* There should be a different MS object */
2030 OSMO_ASSERT(ms2 != ms1);
2031
2032 ms = the_bts.ms_by_tlli(tlli1);
2033 OSMO_ASSERT(ms2 == ms);
2034 OSMO_ASSERT(ms1 != ms);
2035
Jacob Erlbeck5f93f852016-01-21 20:48:39 +01002036 /* DL TBF should be removed */
2037 OSMO_ASSERT(!ms->dl_tbf());
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002038
2039 /* No queued packets should be lost */
Jacob Erlbeck9659d592015-09-01 11:06:14 +02002040 OSMO_ASSERT(ms->llc_queue()->size() == 2);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002041
2042 printf("=== end %s ===\n", __func__);
2043}
2044
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002045static void test_tbf_dl_reuse()
2046{
2047 BTS the_bts;
2048 int ts_no = 7;
2049 uint32_t fn = 2654218;
2050 uint16_t qta = 31;
2051 uint32_t tlli1 = 0xf1223344;
2052 const char *imsi = "0011223344";
2053 uint8_t ms_class = 1;
2054 gprs_rlcmac_ul_tbf *ul_tbf;
2055 gprs_rlcmac_dl_tbf *dl_tbf1, *dl_tbf2;
2056 GprsMs *ms1, *ms2;
2057 unsigned i;
2058 RlcMacUplink_t ulreq = {0};
2059
2060 printf("=== start %s ===\n", __func__);
2061
2062 setup_bts(&the_bts, ts_no, 1);
2063
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002064 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli1, &fn, qta,
2065 ms_class, 0);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002066
2067 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002068 print_ta_tlli(ul_tbf, false);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002069
2070 /* Send some LLC frames */
2071 for (i = 0; i < 40; i++) {
2072 char buf[32];
2073 int rc;
2074
2075 rc = snprintf(buf, sizeof(buf), "LLC PACKET %02i", i);
2076 OSMO_ASSERT(rc > 0);
2077
2078 send_dl_data(&the_bts, tlli1, imsi, (const uint8_t *)buf, rc);
2079 }
2080
Max4c112dc2018-02-01 16:49:23 +01002081 print_ms(ms1, true);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002082
2083 /* Send Packet Downlink Assignment to MS */
2084 request_dl_rlc_block(ul_tbf, &fn);
2085
2086 /* Ack it */
2087 send_control_ack(ul_tbf);
2088
2089 /* Transmit all data */
2090 transmit_dl_data(&the_bts, tlli1, &fn);
2091 OSMO_ASSERT(ms1->llc_queue()->size() == 0);
2092 OSMO_ASSERT(ms1->dl_tbf());
2093 OSMO_ASSERT(ms1->dl_tbf()->state_is(GPRS_RLCMAC_FINISHED));
2094
2095 dl_tbf1 = ms1->dl_tbf();
2096
2097 /* Send some LLC frames */
2098 for (i = 0; i < 10; i++) {
2099 char buf[32];
2100 int rc;
2101
2102 rc = snprintf(buf, sizeof(buf), "LLC PACKET %02i (TBF 2)", i);
2103 OSMO_ASSERT(rc > 0);
2104
2105 send_dl_data(&the_bts, tlli1, imsi, (const uint8_t *)buf, rc);
2106 }
2107
2108 /* Fake Final DL Ack/Nack */
2109 ulreq.u.MESSAGE_TYPE = MT_PACKET_DOWNLINK_ACK_NACK;
2110 Packet_Downlink_Ack_Nack_t *ack = &ulreq.u.Packet_Downlink_Ack_Nack;
2111
2112 ack->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
2113 ack->DOWNLINK_TFI = dl_tbf1->tfi();
2114 ack->Ack_Nack_Description.FINAL_ACK_INDICATION = 1;
2115
Jacob Erlbeck8eb17142016-01-22 17:58:17 +01002116 send_ul_mac_block(&the_bts, 0, dl_tbf1->poll_ts, &ulreq, dl_tbf1->poll_fn);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002117
2118 OSMO_ASSERT(dl_tbf1->state_is(GPRS_RLCMAC_WAIT_RELEASE));
2119
2120 request_dl_rlc_block(dl_tbf1, &fn);
2121
2122 ms2 = the_bts.ms_by_tlli(tlli1);
2123 OSMO_ASSERT(ms2 == ms1);
2124 OSMO_ASSERT(ms2->dl_tbf());
Neels Hofmeyr4ea45262016-06-08 15:27:40 +02002125 OSMO_ASSERT(ms2->dl_tbf()->state_is(GPRS_RLCMAC_ASSIGN));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002126
2127 dl_tbf2 = ms2->dl_tbf();
2128
2129 OSMO_ASSERT(dl_tbf1 != dl_tbf2);
2130
2131 send_control_ack(dl_tbf1);
Jacob Erlbeck6835cea2015-08-21 15:24:02 +02002132 OSMO_ASSERT(dl_tbf2->state_is(GPRS_RLCMAC_FLOW));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002133
2134 /* Transmit all data */
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002135 transmit_dl_data(&the_bts, tlli1, &fn);
2136 OSMO_ASSERT(ms2->llc_queue()->size() == 0);
2137 OSMO_ASSERT(ms2->dl_tbf());
2138 OSMO_ASSERT(ms2->dl_tbf()->state_is(GPRS_RLCMAC_FINISHED));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002139
2140 printf("=== end %s ===\n", __func__);
2141}
2142
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002143static void test_tbf_gprs_egprs()
2144{
2145 BTS the_bts;
2146 gprs_rlcmac_bts *bts;
2147 uint8_t ts_no = 4;
2148 uint8_t ms_class = 45;
2149 int rc = 0;
2150 uint32_t tlli = 0xc0006789;
2151 const char *imsi = "001001123456789";
2152 unsigned delay_csec = 1000;
2153
2154 uint8_t buf[256] = {0};
2155
2156 printf("=== start %s ===\n", __func__);
2157
2158 bts = the_bts.bts_data();
2159 setup_bts(&the_bts, ts_no);
2160
2161 /* EGPRS-only */
2162 bts->egprs_enabled = 1;
2163
2164 gprs_bssgp_create_and_connect(bts, 33001, 0, 33001,
Neels Hofmeyrbdc55fa2018-02-21 00:39:07 +01002165 1234, 1234, 1234, 1, 1, false, 0, 0, 0);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002166
2167 /* Does not support EGPRS */
2168 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
2169 delay_csec, buf, sizeof(buf));
2170
2171 OSMO_ASSERT(rc == -EBUSY);
2172 printf("=== end %s ===\n", __func__);
2173
2174 gprs_bssgp_destroy();
2175}
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02002176
Max4c112dc2018-02-01 16:49:23 +01002177static inline void ws_check(gprs_rlcmac_dl_tbf *dl_tbf, const char *test, uint8_t exp_slots, uint16_t exp_ws,
2178 bool free, bool end)
2179{
2180 if (!dl_tbf) {
2181 fprintf(stderr, "%s(): FAILED (NULL TBF)\n", test);
2182 return;
2183 }
2184
2185 fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d",
2186 dl_tbf->dl_slots(),
2187 pcu_bitcount(dl_tbf->dl_slots()),
2188 dl_tbf->window_size());
2189
2190 if (pcu_bitcount(dl_tbf->dl_slots()) != exp_slots || dl_tbf->window_size() != exp_ws)
2191 fprintf(stderr, "%s(): DL TBF FAILED: dl_slots = %u (exp. %u), WS = %u (exp. %u)",
2192 test, pcu_bitcount(dl_tbf->dl_slots()), 4, dl_tbf->window_size(), 128 + 4 * 64);
2193
2194 fprintf(stderr, "\n");
2195
2196 if (free)
2197 tbf_free(dl_tbf);
2198
2199 if (end) {
2200 printf("=== end %s ===\n", test);
2201 gprs_bssgp_destroy();
2202 }
2203}
2204
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002205static void test_tbf_ws()
2206{
2207 BTS the_bts;
2208 gprs_rlcmac_bts *bts;
2209 uint8_t ts_no = 4;
2210 uint8_t ms_class = 12;
2211 gprs_rlcmac_dl_tbf *dl_tbf;
2212
2213 printf("=== start %s ===\n", __func__);
2214
2215 bts = the_bts.bts_data();
2216 setup_bts(&the_bts, ts_no);
2217
2218 bts->ws_base = 128;
2219 bts->ws_pdch = 64;
2220 bts->alloc_algorithm = alloc_algorithm_b;
2221 bts->trx[0].pdch[2].enable();
2222 bts->trx[0].pdch[3].enable();
2223 bts->trx[0].pdch[4].enable();
2224 bts->trx[0].pdch[5].enable();
2225
2226 gprs_bssgp_create_and_connect(bts, 33001, 0, 33001,
Neels Hofmeyrbdc55fa2018-02-21 00:39:07 +01002227 1234, 1234, 1234, 1, 1, false, 0, 0, 0);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002228
2229 /* Does no support EGPRS */
Max92b7a502018-01-26 11:01:35 +01002230 dl_tbf = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, 0, false);
Max4c112dc2018-02-01 16:49:23 +01002231
2232 ws_check(dl_tbf, __func__, 4, 64, true, false);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002233
2234 /* EGPRS-only */
2235 bts->egprs_enabled = 1;
2236
2237 /* Does support EGPRS */
Max92b7a502018-01-26 11:01:35 +01002238 dl_tbf = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, ms_class, false);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002239
Max4c112dc2018-02-01 16:49:23 +01002240 ws_check(dl_tbf, __func__, 4, 128 + 4 * 64, true, true);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002241}
2242
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302243static void test_tbf_update_ws(void)
2244{
2245 BTS the_bts;
2246 gprs_rlcmac_bts *bts;
2247 uint8_t ts_no = 4;
2248 uint8_t ms_class = 11;
2249 gprs_rlcmac_dl_tbf *dl_tbf;
2250
2251 printf("=== start %s ===\n", __func__);
2252
2253 bts = the_bts.bts_data();
2254 setup_bts(&the_bts, ts_no);
2255
2256 bts->ws_base = 128;
2257 bts->ws_pdch = 64;
2258 bts->alloc_algorithm = alloc_algorithm_b;
2259 bts->trx[0].pdch[2].enable();
2260 bts->trx[0].pdch[3].enable();
2261 bts->trx[0].pdch[4].enable();
2262 bts->trx[0].pdch[5].enable();
2263
2264 gprs_bssgp_create_and_connect(bts, 33001, 0, 33001,
Neels Hofmeyrbdc55fa2018-02-21 00:39:07 +01002265 1234, 1234, 1234, 1, 1, false, 0, 0, 0);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302266
2267 /* EGPRS-only */
2268 bts->egprs_enabled = 1;
2269
2270 /* Does support EGPRS */
Max92b7a502018-01-26 11:01:35 +01002271 dl_tbf = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, ms_class, true);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302272
Max4c112dc2018-02-01 16:49:23 +01002273 ws_check(dl_tbf, __func__, 1, 128 + 1 * 64, false, false);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302274
2275 dl_tbf->update();
2276
Aravind Sirsikar0ee31cf2016-09-15 17:54:46 +05302277 /* window size should be 384 */
Max4c112dc2018-02-01 16:49:23 +01002278 ws_check(dl_tbf, __func__, 4, 128 + 4 * 64, true, true);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302279}
2280
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302281static void test_tbf_puan_urbb_len(void)
2282{
2283 BTS the_bts;
2284 int ts_no = 7;
2285 uint32_t fn = 2654218;
2286 uint16_t qta = 31;
2287 uint32_t tlli = 0xf1223344;
2288 const char *imsi = "0011223344";
2289 uint8_t ms_class = 1;
2290 uint8_t egprs_ms_class = 1;
2291 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302292 uint8_t test_data[256];
2293
2294 printf("=== start %s ===\n", __func__);
2295
2296 memset(test_data, 1, sizeof(test_data));
2297
2298 setup_bts(&the_bts, ts_no, 4);
2299 the_bts.bts_data()->initial_mcs_dl = 9;
2300 the_bts.bts_data()->egprs_enabled = 1;
2301
2302 ul_tbf = puan_urbb_len_issue(&the_bts, ts_no, tlli, &fn, qta,
2303 ms_class, egprs_ms_class);
2304
Max4c112dc2018-02-01 16:49:23 +01002305 print_ta_tlli(ul_tbf, true);
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302306 send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data));
2307
2308 printf("=== end %s ===\n", __func__);
2309}
2310
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302311static gprs_rlcmac_ul_tbf *tbf_li_decoding(BTS *the_bts,
2312 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
2313 uint8_t ms_class, uint8_t egprs_ms_class)
2314{
2315 GprsMs *ms;
2316 uint32_t rach_fn = *fn - 51;
2317 uint32_t sba_fn = *fn + 52;
2318 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002319 int tfi = 0;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302320 gprs_rlcmac_ul_tbf *ul_tbf;
2321 struct gprs_rlcmac_pdch *pdch;
2322 gprs_rlcmac_bts *bts;
2323 RlcMacUplink_t ulreq = {0};
2324 struct pcu_l1_meas meas;
2325 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
2326 GprsCodingScheme cs;
2327 Packet_Resource_Request_t *presreq = NULL;
2328 MS_Radio_Access_capability_t *pmsradiocap = NULL;
2329 Multislot_capability_t *pmultislotcap = NULL;
2330
2331 meas.set_rssi(31);
2332 bts = the_bts->bts_data();
2333
2334 /* needed to set last_rts_fn in the PDCH object */
2335 request_dl_rlc_block(bts, trx_no, ts_no, fn);
2336
2337 /*
2338 * simulate RACH, this sends an Immediate
2339 * Assignment Uplink on the AGCH
2340 */
2341 the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0);
2342
2343 /* get next free TFI */
2344 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
2345
2346 /* fake a resource request */
2347 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
2348 presreq = &ulreq.u.Packet_Resource_Request;
2349 presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
2350 presreq->ID.UnionType = 1; /* != 0 */
2351 presreq->ID.u.TLLI = tlli;
2352 presreq->Exist_MS_Radio_Access_capability = 1;
2353 pmsradiocap = &presreq->MS_Radio_Access_capability;
2354 pmsradiocap->Count_MS_RA_capability_value = 1;
2355 pmsradiocap->MS_RA_capability_value[0].u.Content.
2356 Exist_Multislot_capability = 1;
2357 pmultislotcap = &pmsradiocap->MS_RA_capability_value[0].
2358 u.Content.Multislot_capability;
2359
2360 pmultislotcap->Exist_GPRS_multislot_class = 1;
2361 pmultislotcap->GPRS_multislot_class = ms_class;
2362 if (egprs_ms_class) {
2363 pmultislotcap->Exist_EGPRS_multislot_class = 1;
2364 pmultislotcap->EGPRS_multislot_class = ms_class;
2365 }
2366
2367 send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
2368
2369 /* check the TBF */
2370 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
2371 OSMO_ASSERT(ul_tbf);
2372 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
2373
2374 /* send packet uplink assignment */
2375 *fn = sba_fn;
2376 request_dl_rlc_block(ul_tbf, fn);
2377
2378 /* send real acknowledgement */
2379 send_control_ack(ul_tbf);
2380
2381 check_tbf(ul_tbf);
2382
2383 uint8_t data_msg[49] = {0};
2384
2385 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
2386
2387 ms = the_bts->ms_by_tlli(tlli);
2388 OSMO_ASSERT(ms != NULL);
2389 OSMO_ASSERT(ms->ta() == qta/4);
2390 OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
2391
2392 cs = GprsCodingScheme::MCS4;
2393 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
2394 egprs3->si = 0;
2395 egprs3->r = 1;
2396 egprs3->cv = 7;
2397 egprs3->tfi_hi = tfi & 0x03;
2398 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
2399 egprs3->bsn1_hi = 0;
2400 egprs3->bsn1_lo = 0;
2401 egprs3->cps_hi = 1;
2402 data_msg[3] = 0xff;
2403 egprs3->pi = 0;
2404 egprs3->cps_lo = 1;
2405 egprs3->rsb = 0;
2406 egprs3->spb = 0;
2407 egprs3->pi = 0;
2408 pdch->rcv_block(data_msg, 49, *fn, &meas);
2409
2410 egprs3->bsn1_hi = 1;
2411 egprs3->bsn1_lo = 0;
2412 data_msg[3] = 0x7f;
2413 egprs3->cps_lo = 1;
2414 egprs3->rsb = 0;
2415 egprs3->spb = 0;
2416 egprs3->pi = 0;
2417 data_msg[4] = 0x2;
2418 data_msg[5] = 0x0;
2419 pdch->rcv_block(data_msg, 49, *fn, &meas);
2420
Aravind Sirsikar22a90192016-09-15 17:24:49 +05302421 OSMO_ASSERT(ul_tbf->m_llc.m_index == 43);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302422
2423 return ul_tbf;
2424}
2425
2426static void test_tbf_li_decoding(void)
2427{
2428 BTS the_bts;
2429 int ts_no = 7;
2430 uint32_t fn = 2654218;
2431 uint16_t qta = 31;
2432 uint32_t tlli = 0xf1223344;
2433 const char *imsi = "0011223344";
2434 uint8_t ms_class = 1;
2435 uint8_t egprs_ms_class = 1;
2436 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302437 uint8_t test_data[256];
2438
2439 printf("=== start %s ===\n", __func__);
2440
2441 memset(test_data, 1, sizeof(test_data));
2442
2443 setup_bts(&the_bts, ts_no, 4);
2444 the_bts.bts_data()->initial_mcs_dl = 9;
2445 the_bts.bts_data()->egprs_enabled = 1;
2446
2447 ul_tbf = tbf_li_decoding(&the_bts, ts_no, tlli, &fn, qta,
2448 ms_class, egprs_ms_class);
2449
Max4c112dc2018-02-01 16:49:23 +01002450 print_ta_tlli(ul_tbf, true);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302451 send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data));
2452
2453 printf("=== end %s ===\n", __func__);
2454}
2455
aravind sirsikarf2761382016-10-25 12:45:24 +05302456/*
2457 * Test that a bit within the uncompressed bitmap whose BSN is not within
2458 * the transmit window shall be ignored. See section 9.1.8.2.4 of 44.060
2459 * version 7.27.0 Release 7.
2460 */
2461static void test_tbf_epdan_out_of_rx_window(void)
2462{
2463 BTS the_bts;
2464 gprs_rlcmac_bts *bts;
2465 uint8_t ms_class = 11;
2466 uint8_t egprs_ms_class = 11;
2467 uint8_t trx_no;
2468 uint32_t tlli = 0xffeeddcc;
2469 gprs_rlcmac_dl_tbf *dl_tbf;
2470 int ts_no = 4;
2471 bitvec *block;
2472 uint8_t bits_data[RLC_EGPRS_MAX_WS/8];
2473 bitvec bits;
2474 int bsn_begin, bsn_end;
2475 EGPRS_PD_AckNack_t *ack_nack;
2476 RlcMacUplink_t ul_control_block;
2477 gprs_rlc_v_b *prlcmvb;
2478 gprs_rlc_dl_window *prlcdlwindow;
2479
aravind sirsikarcc4214a2016-12-09 16:12:42 +05302480 memset(&ul_control_block, 0, sizeof(RlcMacUplink_t));
2481
aravind sirsikarf2761382016-10-25 12:45:24 +05302482 printf("=== start %s ===\n", __func__);
2483
2484 bts = the_bts.bts_data();
2485
2486 setup_bts(&the_bts, ts_no);
2487 bts->dl_tbf_idle_msec = 200;
2488 bts->egprs_enabled = 1;
2489 /* ARQ II */
2490 bts->dl_arq_type = EGPRS_ARQ2;
2491
2492 /*
2493 * Simulate a message captured during over-the-air testing,
2494 * where the following values were observed:
2495 * v_a = 1176, vs = 1288, max sns = 2048, window size = 480.
2496 */
2497 uint8_t data_msg[23] = {0x40, 0x20, 0x0b, 0xff, 0xd1,
2498 0x61, 0x00, 0x3e, 0x0e, 0x51, 0x9f,
2499 0xff, 0xff, 0xfb, 0x80, 0x00, 0x00,
2500 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
2501
2502 dl_tbf = create_dl_tbf(&the_bts, ms_class, egprs_ms_class, &trx_no);
2503 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
Maxea98b7d2018-01-04 15:13:27 +01002504 prlcdlwindow = dl_tbf->window();
aravind sirsikarf2761382016-10-25 12:45:24 +05302505 prlcmvb = &prlcdlwindow->m_v_b;
2506 prlcdlwindow->m_v_s = 1288;
2507 prlcdlwindow->m_v_a = 1176;
2508 prlcdlwindow->set_sns(2048);
2509 prlcdlwindow->set_ws(480);
2510 prlcmvb->mark_unacked(1176);
2511 prlcmvb->mark_unacked(1177);
2512 prlcmvb->mark_unacked(1286);
2513 prlcmvb->mark_unacked(1287);
2514
2515 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2516
Alexander Couzensccde5c92017-02-04 03:10:08 +01002517 block = bitvec_alloc(23, tall_pcu_ctx);
aravind sirsikarf2761382016-10-25 12:45:24 +05302518
2519 bitvec_unpack(block, data_msg);
2520
2521 bits.data = bits_data;
2522 bits.data_len = sizeof(bits_data);
2523 bits.cur_bit = 0;
2524
2525 decode_gsm_rlcmac_uplink(block, &ul_control_block);
2526
2527 ack_nack = &ul_control_block.u.Egprs_Packet_Downlink_Ack_Nack;
2528
2529 OSMO_ASSERT(prlcmvb->is_unacked(1176));
2530 OSMO_ASSERT(prlcmvb->is_unacked(1177));
2531 OSMO_ASSERT(prlcmvb->is_unacked(1286));
2532 OSMO_ASSERT(prlcmvb->is_unacked(1287));
2533
2534 Decoding::decode_egprs_acknack_bits(
2535 &ack_nack->EGPRS_AckNack.Desc, &bits,
Maxea98b7d2018-01-04 15:13:27 +01002536 &bsn_begin, &bsn_end, dl_tbf->window());
aravind sirsikarf2761382016-10-25 12:45:24 +05302537
2538 dl_tbf->rcvd_dl_ack(
2539 ack_nack->EGPRS_AckNack.Desc.FINAL_ACK_INDICATION,
2540 bsn_begin, &bits);
aravind sirsikarf2761382016-10-25 12:45:24 +05302541
aravind sirsikarfb41afa2016-11-02 15:48:00 +05302542 OSMO_ASSERT(prlcmvb->is_invalid(1176));
2543 OSMO_ASSERT(prlcmvb->is_invalid(1177));
2544 OSMO_ASSERT(prlcmvb->is_acked(1286));
2545 OSMO_ASSERT(prlcmvb->is_acked(1287));
aravind sirsikarf2761382016-10-25 12:45:24 +05302546
2547 bitvec_free(block);
2548 tbf_free(dl_tbf);
2549 printf("=== end %s ===\n", __func__);
2550}
2551
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302552static void test_tbf_egprs_two_phase_spb(void)
2553{
2554 BTS the_bts;
2555 int ts_no = 7;
2556 uint32_t fn = 2654218;
2557 uint16_t qta = 31;
2558 uint32_t tlli = 0xf1223344;
2559 const char *imsi = "0011223344";
2560 uint8_t ms_class = 1;
2561 uint8_t egprs_ms_class = 1;
2562 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302563 uint8_t test_data[256];
2564
2565 printf("=== start %s ===\n", __func__);
2566
2567 memset(test_data, 1, sizeof(test_data));
2568
2569 setup_bts(&the_bts, ts_no, 4);
2570 the_bts.bts_data()->initial_mcs_dl = 9;
2571 the_bts.bts_data()->egprs_enabled = 1;
2572
2573 ul_tbf = establish_ul_tbf_two_phase_spb(&the_bts, ts_no, tlli, &fn, qta,
2574 ms_class, egprs_ms_class);
2575
Max4c112dc2018-02-01 16:49:23 +01002576 print_ta_tlli(ul_tbf, true);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302577 send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data));
2578
2579 printf("=== end %s ===\n", __func__);
2580}
2581
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002582static void test_tbf_egprs_two_phase()
2583{
2584 BTS the_bts;
2585 int ts_no = 7;
2586 uint32_t fn = 2654218;
2587 uint16_t qta = 31;
2588 uint32_t tlli = 0xf1223344;
2589 const char *imsi = "0011223344";
2590 uint8_t ms_class = 1;
2591 uint8_t egprs_ms_class = 1;
2592 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002593 uint8_t test_data[256];
2594
2595 printf("=== start %s ===\n", __func__);
2596
2597 memset(test_data, 1, sizeof(test_data));
2598
2599 setup_bts(&the_bts, ts_no, 4);
2600 the_bts.bts_data()->initial_mcs_dl = 9;
2601 the_bts.bts_data()->egprs_enabled = 1;
2602
2603 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli, &fn, qta,
2604 ms_class, egprs_ms_class);
2605
Max4c112dc2018-02-01 16:49:23 +01002606 print_ta_tlli(ul_tbf, true);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002607 send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data));
2608
2609 printf("=== end %s ===\n", __func__);
2610}
2611
2612static void establish_and_use_egprs_dl_tbf(BTS *the_bts, int mcs)
2613{
2614 unsigned i;
2615 uint8_t ms_class = 11;
2616 uint8_t egprs_ms_class = 11;
2617 uint32_t fn = 0;
2618 uint8_t trx_no;
2619 uint32_t tlli = 0xffeeddcc;
2620 uint8_t test_data[512];
2621
2622 uint8_t rbb[64/8];
2623
2624 gprs_rlcmac_dl_tbf *dl_tbf;
2625
2626 printf("Testing MCS-%d\n", mcs);
2627
2628 memset(test_data, 1, sizeof(test_data));
2629 the_bts->bts_data()->initial_mcs_dl = mcs;
2630
2631 dl_tbf = create_dl_tbf(the_bts, ms_class, egprs_ms_class, &trx_no);
2632 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
2633
2634 for (i = 0; i < sizeof(llc_data); i++)
2635 llc_data[i] = i%256;
2636
2637 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2638
2639 /* Schedule a small LLC frame */
2640 dl_tbf->append_data(ms_class, 1000, test_data, 10);
2641
2642 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2643
2644 /* Drain the queue */
2645 while (dl_tbf->have_data())
2646 /* Request to send one RLC/MAC block */
2647 request_dl_rlc_block(dl_tbf, &fn);
2648
2649 /* Schedule a large LLC frame */
2650 dl_tbf->append_data(ms_class, 1000, test_data, sizeof(test_data));
2651
2652 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2653
2654 /* Drain the queue */
2655 while (dl_tbf->have_data())
2656 /* Request to send one RLC/MAC block */
2657 request_dl_rlc_block(dl_tbf, &fn);
2658
2659 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2660
Max7d32f552017-12-15 11:25:14 +01002661 RCV_ACK(true, dl_tbf, rbb); /* Receive a final ACK */
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002662
2663 /* Clean up and ensure tbfs are in the correct state */
2664 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
Max0e599802018-01-23 20:09:06 +01002665 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_NONE);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002666 check_tbf(dl_tbf);
2667 tbf_free(dl_tbf);
2668}
2669
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302670static gprs_rlcmac_dl_tbf *tbf_init(BTS *the_bts,
2671 int mcs)
2672{
2673 unsigned i;
2674 uint8_t ms_class = 11;
2675 uint8_t egprs_ms_class = 11;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302676 uint8_t trx_no;
2677 uint32_t tlli = 0xffeeddcc;
2678 uint8_t test_data[512];
2679
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302680 gprs_rlcmac_dl_tbf *dl_tbf;
2681
2682 memset(test_data, 1, sizeof(test_data));
2683 the_bts->bts_data()->initial_mcs_dl = mcs;
2684
2685 dl_tbf = create_dl_tbf(the_bts, ms_class, egprs_ms_class, &trx_no);
2686 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
2687
2688 for (i = 0; i < sizeof(test_data); i++)
2689 test_data[i] = i%256;
2690
2691 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2692
2693 /* Schedule a LLC frame
2694 * passing only 100 bytes, since it is enough to construct
2695 * 2 RLC data blocks. Which are enough to test Header Type 1
2696 * cases
2697 */
2698 dl_tbf->append_data(ms_class, 1000, test_data, 100);
2699
2700 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2701
2702 return dl_tbf;
2703
2704}
2705
2706static void tbf_cleanup(gprs_rlcmac_dl_tbf *dl_tbf)
2707{
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302708 uint8_t rbb[64/8];
2709
Max7d32f552017-12-15 11:25:14 +01002710 RCV_ACK(true, dl_tbf, rbb); /* Receive a final ACK */
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302711
2712 /* Clean up and ensure tbfs are in the correct state */
2713 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
Max0e599802018-01-23 20:09:06 +01002714 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_NONE);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302715 check_tbf(dl_tbf);
2716 tbf_free(dl_tbf);
2717
2718}
2719
Max7d32f552017-12-15 11:25:14 +01002720#define NACK(tbf, x) do { \
Maxea98b7d2018-01-04 15:13:27 +01002721 tbf->window()->m_v_b.mark_nacked(x); \
2722 OSMO_ASSERT(tbf->window()->m_v_b.is_nacked(x)); \
Max7d32f552017-12-15 11:25:14 +01002723 } while(0)
2724
2725#define CHECK_UNACKED(tbf, cs, bsn) do { \
Maxea98b7d2018-01-04 15:13:27 +01002726 OSMO_ASSERT(tbf->window()->m_v_b.is_unacked(bsn)); \
Max7d32f552017-12-15 11:25:14 +01002727 OSMO_ASSERT(tbf->m_rlc.block(bsn)->cs_current_trans.to_num() == cs); \
2728 } while(0)
2729
2730#define CHECK_NACKED(tbf, cs, bsn) do { \
Maxea98b7d2018-01-04 15:13:27 +01002731 OSMO_ASSERT(tbf->window()->m_v_b.is_nacked(bsn)); \
Max7d32f552017-12-15 11:25:14 +01002732 OSMO_ASSERT(tbf->m_rlc.block(bsn)->cs_current_trans.to_num() == cs); \
2733 } while(0)
2734
2735#define MAKE_ACKED(m, tbf, fn, cs, check_unacked) do { \
2736 m = tbf->create_dl_acked_block(fn, tbf->control_ts); \
2737 OSMO_ASSERT(m); \
2738 if (check_unacked) \
2739 CHECK_UNACKED(tbf, cs, 0); \
2740 else \
2741 CHECK_NACKED(tbf, cs, 0); \
2742 } while(0)
2743
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302744static void egprs_spb_to_normal_validation(BTS *the_bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002745 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302746{
2747 uint32_t fn = 0;
2748 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302749 uint16_t bsn1, bsn2, bsn3;
2750 struct msgb *msg;
2751 struct gprs_rlc_dl_header_egprs_3 *egprs3;
2752 struct gprs_rlc_dl_header_egprs_2 *egprs2;
2753
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002754 printf("Testing retx for MCS %u to reseg_mcs %u\n", mcs, demanded_mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302755
2756 dl_tbf = tbf_init(the_bts, mcs);
2757
2758 /*
2759 * Table 10.4.8a.3.1 of 44.060.
2760 * (MCS7, MCS9) to (MCS2, MCS3) is not handled since it is same as
2761 * (MCS5, MCS6) to (MCS2, MCS3) transition
2762 */
2763 if (!(mcs == 6 && demanded_mcs == 3))
2764 return;
2765
2766 fn = fn_add_blocks(fn, 1);
2767 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01002768 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302769
2770 egprs2 = (struct gprs_rlc_dl_header_egprs_2 *) msg->data;
Maxb4d368b2017-12-01 17:54:39 +01002771 bsn1 = (egprs2->bsn1_hi << 9) | (egprs2->bsn1_mid << 1) | (egprs2->bsn1_lo);
Max7d32f552017-12-15 11:25:14 +01002772
2773 NACK(dl_tbf, 0);
2774
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302775 OSMO_ASSERT(bsn1 == 0);
2776
2777 dl_tbf->ms()->set_current_cs_dl
2778 (static_cast < GprsCodingScheme::Scheme >
2779 (GprsCodingScheme::CS4 + demanded_mcs));
2780
2781 fn = fn_add_blocks(fn, 1);
2782
2783 /* Send first segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002784 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, false);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302785 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2786 == EGPRS_RESEG_FIRST_SEG_SENT);
2787
2788 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2789 OSMO_ASSERT(egprs3->spb == 2);
2790
2791 /* Table 10.4.8a.3.1 of 44.060 */
2792 OSMO_ASSERT(egprs3->cps == 3);
2793
2794 /* Send second segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002795 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302796 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2797 == EGPRS_RESEG_SECOND_SEG_SENT);
2798
2799 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2800 /* Table 10.4.8a.3.1 of 44.060 */
2801 OSMO_ASSERT(egprs3->spb == 3);
Maxb4d368b2017-12-01 17:54:39 +01002802 bsn2 = (egprs3->bsn1_hi << 9) | (egprs3->bsn1_mid << 1) | (egprs3->bsn1_lo);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302803 OSMO_ASSERT(bsn2 == bsn1);
2804
2805 /* Table 10.4.8a.3.1 of 44.060 */
2806 OSMO_ASSERT(egprs3->cps == 3);
2807
2808 /* Handle (MCS3, MCS3) -> MCS6 case */
2809 dl_tbf->ms()->set_current_cs_dl
2810 (static_cast < GprsCodingScheme::Scheme >
2811 (GprsCodingScheme::CS4 + mcs));
2812
Max7d32f552017-12-15 11:25:14 +01002813 NACK(dl_tbf, 0);
2814
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302815 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
2816 egprs2 = (struct gprs_rlc_dl_header_egprs_2 *) msg->data;
2817
2818 /* Table 10.4.8a.3.1 of 44.060 */
2819 OSMO_ASSERT(egprs2->cps == 0);
Maxb4d368b2017-12-01 17:54:39 +01002820 bsn3 = (egprs2->bsn1_hi << 9) | (egprs2->bsn1_mid << 1) | (egprs2->bsn1_lo);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302821 OSMO_ASSERT(bsn3 == bsn2);
2822
2823 tbf_cleanup(dl_tbf);
2824}
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002825
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302826static void establish_and_use_egprs_dl_tbf_for_spb(BTS *the_bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002827 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302828{
2829 uint32_t fn = 0;
2830 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302831 struct msgb *msg;
2832 struct gprs_rlc_dl_header_egprs_3 *egprs3;
2833
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002834 printf("Testing retx for MCS %u to reseg_mcs %u\n", mcs, demanded_mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302835
2836 dl_tbf = tbf_init(the_bts, mcs);
2837
2838 /*
2839 * Table 10.4.8a.3.1 of 44.060.
2840 * (MCS7, MCS9) to (MCS2, MCS3) is not handled since it is same as
2841 * (MCS5, MCS6) to (MCS2, MCS3) transition
2842 */
2843 /* TODO: Need to support of MCS8 -> MCS6 ->MCS3 transistion
2844 * Refer commit be881c028fc4da00c4046ecd9296727975c206a3
2845 * dated 2016-02-07 23:45:40 (UTC)
2846 */
2847 if (!(((mcs == 5) && (demanded_mcs == 2)) ||
2848 ((mcs == 6) && (demanded_mcs == 3)) ||
2849 ((mcs == 4) && (demanded_mcs == 1))))
2850 return;
2851
2852 fn = fn_add_blocks(fn, 1);
2853 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01002854 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302855
Max7d32f552017-12-15 11:25:14 +01002856 NACK(dl_tbf, 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302857
2858 dl_tbf->ms()->set_current_cs_dl
2859 (static_cast < GprsCodingScheme::Scheme >
2860 (GprsCodingScheme::CS4 + demanded_mcs));
2861
2862 fn = fn_add_blocks(fn, 1);
2863
2864 /* Send first segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002865 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, false);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302866 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2867 == EGPRS_RESEG_FIRST_SEG_SENT);
2868
2869 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2870 OSMO_ASSERT(egprs3->spb == 2);
2871
2872 /* Table 10.4.8a.3.1 of 44.060 */
2873 switch (demanded_mcs) {
2874 case 3:
2875 OSMO_ASSERT(egprs3->cps == 3);
2876 break;
2877 case 2:
2878 OSMO_ASSERT(egprs3->cps == 9);
2879 break;
2880 case 1:
2881 OSMO_ASSERT(egprs3->cps == 11);
2882 break;
2883 default:
2884 OSMO_ASSERT(false);
2885 break;
2886 }
2887
2888 /* Send second segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002889 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302890 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2891 == EGPRS_RESEG_SECOND_SEG_SENT);
2892
2893 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2894 /* Table 10.4.8a.3.1 of 44.060 */
2895 OSMO_ASSERT(egprs3->spb == 3);
2896
2897 /* Table 10.4.8a.3.1 of 44.060 */
2898 switch (demanded_mcs) {
2899 case 3:
2900 OSMO_ASSERT(egprs3->cps == 3);
2901 break;
2902 case 2:
2903 OSMO_ASSERT(egprs3->cps == 9);
2904 break;
2905 case 1:
2906 OSMO_ASSERT(egprs3->cps == 11);
2907 break;
2908 default:
2909 OSMO_ASSERT(false);
2910 break;
2911 }
2912 tbf_cleanup(dl_tbf);
2913}
2914
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302915static void establish_and_use_egprs_dl_tbf_for_retx(BTS *the_bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002916 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302917{
2918 uint32_t fn = 0;
2919 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302920 struct msgb *msg;
2921
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002922 printf("Testing retx for MCS %u - %u\n", mcs, demanded_mcs);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302923
2924 dl_tbf = tbf_init(the_bts, mcs);
2925
2926 /* For MCS reduction cases like MCS9->MCS6, MCS7->MCS5
2927 * The MCS transition are referred from table Table 8.1.1.2
2928 * of TS 44.060
2929 */
2930 /* TODO: Need to support of MCS8 -> MCS6 transistion
2931 * Refer commit be881c028fc4da00c4046ecd9296727975c206a3
2932 * dated 2016-02-07 23:45:40 (UTC)
2933 */
2934 if (((mcs == 9) && (demanded_mcs < 9)) ||
2935 ((mcs == 7) && (demanded_mcs < 7))) {
2936 fn = fn_add_blocks(fn, 1);
2937 /* Send 2 RLC data block */
Max7d32f552017-12-15 11:25:14 +01002938 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
2939 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302940
Max7d32f552017-12-15 11:25:14 +01002941 NACK(dl_tbf, 0);
2942 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302943
2944 /* Set the demanded MCS to demanded_mcs */
2945 dl_tbf->ms()->set_current_cs_dl
2946 (static_cast < GprsCodingScheme::Scheme >
2947 (GprsCodingScheme::CS4 + demanded_mcs));
2948
2949 fn = fn_add_blocks(fn, 1);
2950 /* Retransmit the first RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002951 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
2952 CHECK_NACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302953
2954 fn = fn_add_blocks(fn, 1);
2955 /* Retransmit the second RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002956 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
2957 CHECK_UNACKED(dl_tbf, demanded_mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302958 } else if (((mcs == 5) && (demanded_mcs > 6)) ||
2959 ((mcs == 6) && (demanded_mcs > 8))) {
2960 fn = fn_add_blocks(fn, 1);
2961 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01002962 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302963
2964 fn = fn_add_blocks(fn, 1);
2965 /* Send second RLC data block BSN 1 */
Max7d32f552017-12-15 11:25:14 +01002966 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
2967 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302968
Max7d32f552017-12-15 11:25:14 +01002969 NACK(dl_tbf, 0);
2970 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302971
2972 dl_tbf->ms()->set_current_cs_dl
2973 (static_cast < GprsCodingScheme::Scheme >
2974 (GprsCodingScheme::CS4 + demanded_mcs));
2975
2976 fn = fn_add_blocks(fn, 1);
2977 /* Send first, second RLC data blocks with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002978 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
2979 CHECK_UNACKED(dl_tbf, demanded_mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302980 } else if (mcs > 6) {
2981 /* No Mcs change cases are handled here for mcs > MCS6*/
2982 fn = fn_add_blocks(fn, 1);
2983 /* Send first,second RLC data blocks */
Max7d32f552017-12-15 11:25:14 +01002984 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
2985 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302986
Max7d32f552017-12-15 11:25:14 +01002987 NACK(dl_tbf, 0);
2988 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302989
2990 fn = fn_add_blocks(fn, 1);
2991 /* Send first,second RLC data blocks with demanded_mcs*/
Max7d32f552017-12-15 11:25:14 +01002992 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
2993 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302994 } else {
2995
2996 /* No MCS change cases are handled here for mcs <= MCS6*/
2997 fn = fn_add_blocks(fn, 1);
2998 /* Send first RLC data block */
Max7d32f552017-12-15 11:25:14 +01002999 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303000
Max7d32f552017-12-15 11:25:14 +01003001 NACK(dl_tbf, 0);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303002
3003 fn = fn_add_blocks(fn, 1);
3004 /* Send first RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003005 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303006 }
3007
3008 tbf_cleanup(dl_tbf);
3009}
3010
3011static void test_tbf_egprs_retx_dl(void)
3012{
3013 BTS the_bts;
3014 gprs_rlcmac_bts *bts;
3015 uint8_t ts_no = 4;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303016
3017 printf("=== start %s ===\n", __func__);
3018
3019 bts = the_bts.bts_data();
3020 bts->cs_downgrade_threshold = 0;
3021 setup_bts(&the_bts, ts_no);
3022 bts->dl_tbf_idle_msec = 200;
3023 bts->egprs_enabled = 1;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303024 /* ARQ II */
3025 bts->dl_arq_type = EGPRS_ARQ2;
3026
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303027
3028 /* First parameter is current MCS, second one is demanded_mcs */
3029 establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 6, 6);
3030 establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 1, 9);
3031 establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 2, 8);
3032 establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 5, 7);
3033 establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 6, 9);
3034 establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 7, 5);
3035 establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 9, 6);
3036
3037 printf("=== end %s ===\n", __func__);
3038}
3039
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303040static void test_tbf_egprs_spb_dl(void)
3041{
3042 BTS the_bts;
3043 gprs_rlcmac_bts *bts;
3044 uint8_t ts_no = 4;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303045
3046 printf("=== start %s ===\n", __func__);
3047
3048 bts = the_bts.bts_data();
3049 bts->cs_downgrade_threshold = 0;
3050 setup_bts(&the_bts, ts_no);
3051 bts->dl_tbf_idle_msec = 200;
3052 bts->egprs_enabled = 1;
3053
3054 /* ARQ I resegmentation support */
3055 bts->dl_arq_type = EGPRS_ARQ1;
3056
3057 /*
3058 * First parameter is current MCS, second one is demanded_mcs
3059 * currently only MCS5->MCS2, MCS6->3, MCS4->MCS1 is tested in UT
3060 * rest scenarios has been integration tested
3061 */
3062 establish_and_use_egprs_dl_tbf_for_spb(&the_bts, 6, 3);
3063 establish_and_use_egprs_dl_tbf_for_spb(&the_bts, 5, 2);
3064 establish_and_use_egprs_dl_tbf_for_spb(&the_bts, 4, 1);
3065 /* check MCS6->(MCS3+MCS3)->MCS6 case */
3066 egprs_spb_to_normal_validation(&the_bts, 6, 3);
3067
3068 printf("=== end %s ===\n", __func__);
3069}
3070
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003071static void test_tbf_egprs_dl()
3072{
3073 BTS the_bts;
3074 gprs_rlcmac_bts *bts;
3075 uint8_t ts_no = 4;
3076 int i;
3077
3078 printf("=== start %s ===\n", __func__);
3079
3080 bts = the_bts.bts_data();
3081
3082 setup_bts(&the_bts, ts_no);
3083 bts->dl_tbf_idle_msec = 200;
3084 bts->egprs_enabled = 1;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303085 /* ARQ II */
3086 bts->dl_arq_type = EGPRS_ARQ2;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003087
3088 for (i = 1; i <= 9; i++)
3089 establish_and_use_egprs_dl_tbf(&the_bts, i);
3090
3091 printf("=== end %s ===\n", __func__);
3092}
3093
3094
3095
aravind sirsikare9a138e2017-01-24 12:36:08 +05303096static void test_packet_access_rej_prr_no_other_tbfs()
3097{
3098 BTS the_bts;
3099 uint32_t fn = 2654218;
3100 int ts_no = 7;
3101 uint8_t trx_no = 0;
3102 uint32_t tlli = 0xffeeddcc;
3103 struct gprs_rlcmac_ul_tbf *ul_tbf = NULL;
3104
3105 printf("=== start %s ===\n", __func__);
3106
3107 setup_bts(&the_bts, ts_no, 4);
3108
3109 int rc = 0;
3110
3111 ul_tbf = handle_tbf_reject(the_bts.bts_data(), NULL, tlli,
3112 trx_no, ts_no);
3113
3114 OSMO_ASSERT(ul_tbf != 0);
3115
3116 /* trigger packet access reject */
3117 uint8_t bn = fn2bn(fn);
3118
3119 rc = gprs_rlcmac_rcv_rts_block(the_bts.bts_data(),
3120 trx_no, ts_no, fn, bn);
3121
3122 OSMO_ASSERT(rc == 0);
3123
3124 ul_tbf->handle_timeout();
3125
3126 printf("=== end %s ===\n", __func__);
3127}
3128
3129static void test_packet_access_rej_prr()
3130{
3131 BTS the_bts;
3132 uint32_t fn = 2654218;
3133 uint16_t qta = 31;
3134 int ts_no = 7;
3135 uint8_t trx_no = 0;
3136 RlcMacUplink_t ulreq = {0};
3137 Packet_Resource_Request_t *presreq = NULL;
3138 uint8_t ms_class = 11;
3139 uint8_t egprs_ms_class = 11;
3140 uint32_t rach_fn = fn - 51;
3141 uint32_t sba_fn = fn + 52;
3142 uint32_t tlli = 0xffeeddcc;
3143 MS_Radio_Access_capability_t *pmsradiocap = NULL;
3144 Multislot_capability_t *pmultislotcap = NULL;
3145
3146 printf("=== start %s ===\n", __func__);
3147
3148 setup_bts(&the_bts, ts_no, 4);
3149
3150 int rc = 0;
3151
3152 /*
3153 * Trigger rach till resources(USF) exhaust
3154 */
3155 rc = the_bts.rcv_rach(0x78, rach_fn, qta, 0,
3156 GSM_L1_BURST_TYPE_ACCESS_0);
3157 rc = the_bts.rcv_rach(0x79, rach_fn, qta, 0,
3158 GSM_L1_BURST_TYPE_ACCESS_0);
3159 rc = the_bts.rcv_rach(0x7a, rach_fn, qta, 0,
3160 GSM_L1_BURST_TYPE_ACCESS_0);
3161 rc = the_bts.rcv_rach(0x7b, rach_fn, qta, 0,
3162 GSM_L1_BURST_TYPE_ACCESS_0);
3163 rc = the_bts.rcv_rach(0x7c, rach_fn, qta, 0,
3164 GSM_L1_BURST_TYPE_ACCESS_0);
3165 rc = the_bts.rcv_rach(0x7d, rach_fn, qta, 0,
3166 GSM_L1_BURST_TYPE_ACCESS_0);
3167 rc = the_bts.rcv_rach(0x7e, rach_fn, qta, 0,
3168 GSM_L1_BURST_TYPE_ACCESS_0);
3169
3170 /* fake a resource request */
3171 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
3172 presreq = &ulreq.u.Packet_Resource_Request;
3173 presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
3174 presreq->ID.UnionType = 1; /* != 0 */
3175 presreq->ID.u.TLLI = tlli;
3176 presreq->Exist_MS_Radio_Access_capability = 1;
3177 pmsradiocap = &presreq->MS_Radio_Access_capability;
3178 pmsradiocap->Count_MS_RA_capability_value = 1;
3179 pmsradiocap->MS_RA_capability_value[0].u.Content.
3180 Exist_Multislot_capability = 1;
3181 pmultislotcap = &pmsradiocap->MS_RA_capability_value[0].
3182 u.Content.Multislot_capability;
3183
3184 pmultislotcap->Exist_GPRS_multislot_class = 1;
3185 pmultislotcap->GPRS_multislot_class = ms_class;
3186 if (egprs_ms_class) {
3187 pmultislotcap->Exist_EGPRS_multislot_class = 1;
3188 pmultislotcap->EGPRS_multislot_class = egprs_ms_class;
3189 }
3190
3191 send_ul_mac_block(&the_bts, trx_no, ts_no, &ulreq, sba_fn);
3192
3193 /* trigger packet access reject */
3194 uint8_t bn = fn2bn(fn);
3195
3196 rc = gprs_rlcmac_rcv_rts_block(the_bts.bts_data(),
3197 trx_no, ts_no, fn, bn);
3198
3199 OSMO_ASSERT(rc == 0);
3200
3201 printf("=== end %s ===\n", __func__);
3202}
3203
aravind sirsikared3413e2016-11-11 17:15:10 +05303204void test_packet_access_rej_epdan()
3205{
3206 BTS the_bts;
3207 uint32_t tlli = 0xffeeddcc;
3208
3209 printf("=== start %s ===\n", __func__);
3210 setup_bts(&the_bts, 4);
3211 static gprs_rlcmac_dl_tbf *dl_tbf = tbf_init(&the_bts, 1);
3212
3213 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
3214
3215 struct msgb *msg = dl_tbf->create_packet_access_reject();
3216
3217 printf("packet reject: %s\n",
3218 osmo_hexdump(msg->data, 23));
3219
3220 OSMO_ASSERT(!strcmp(osmo_hexdump(msg->data, 23),
3221 "40 84 7f f7 6e e6 41 4b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b "));
3222 printf("=== end %s ===\n", __func__);
3223
3224}
3225
3226
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003227int main(int argc, char **argv)
3228{
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003229 struct vty_app_info pcu_vty_info = {0};
3230
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003231 tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile TbfTest context");
3232 if (!tall_pcu_ctx)
3233 abort();
3234
Neels Hofmeyr78ce5912017-02-08 17:07:31 +01003235 msgb_talloc_ctx_init(tall_pcu_ctx, 0);
Neels Hofmeyr42f2d612018-04-01 16:54:40 +02003236 osmo_init_logging2(tall_pcu_ctx, &gprs_log_info);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003237 log_set_use_color(osmo_stderr_target, 0);
3238 log_set_print_filename(osmo_stderr_target, 0);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003239 bssgp_set_log_ss(DBSSGP);
Maxfdd79e92018-01-24 11:04:59 +01003240 log_parse_category_mask(osmo_stderr_target, "DRLCMAC,1:DRLCMACDATA,3:DRLCMACDL,3:DRLCMACUL,3:"
3241 "DRLCMACSCHED,1:DRLCMACMEAS,3:DNS,3:DBSSGP,3:DPCU,5:"
Max164b59d2018-01-25 19:52:27 +01003242 "DL1IF,6:DTBF,1:DTBFUL,1:DTBFDL,1:");
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003243
3244 vty_init(&pcu_vty_info);
Harald Welteac0490a2017-10-29 10:39:32 +01003245 pcu_vty_init(&gprs_log_info);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003246
Jacob Erlbeckac89a552015-06-29 14:18:46 +02003247 test_tbf_base();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003248 test_tbf_tlli_update();
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +01003249 test_tbf_final_ack(TEST_MODE_STANDARD);
3250 test_tbf_final_ack(TEST_MODE_REVERSE_FREE);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +01003251 test_tbf_delayed_release();
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +02003252 test_tbf_imsi();
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003253 test_tbf_exhaustion();
Jacob Erlbeck41168642015-06-12 13:41:00 +02003254 test_tbf_dl_llc_loss();
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02003255 test_tbf_single_phase();
3256 test_tbf_two_phase();
Jacob Erlbeckb1395982015-08-21 18:15:38 +02003257 test_tbf_ra_update_rach();
3258 test_tbf_dl_flow_and_rach_two_phase();
3259 test_tbf_dl_flow_and_rach_single_phase();
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02003260 test_tbf_dl_reuse();
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01003261 test_tbf_gprs_egprs();
Jacob Erlbeck36df7742016-01-19 15:53:30 +01003262 test_tbf_ws();
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003263 test_tbf_egprs_two_phase();
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05303264 test_tbf_egprs_two_phase_spb();
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003265 test_tbf_egprs_dl();
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303266 test_tbf_egprs_retx_dl();
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303267 test_tbf_egprs_spb_dl();
Aravind Sirsikar02352b42016-08-25 16:37:30 +05303268 test_tbf_puan_urbb_len();
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05303269 test_tbf_update_ws();
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05303270 test_tbf_li_decoding();
aravind sirsikarf2761382016-10-25 12:45:24 +05303271 test_tbf_epdan_out_of_rx_window();
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05303272 test_immediate_assign_rej();
sivasankari1d8744c2017-01-24 15:53:35 +05303273 test_tbf_egprs_two_phase_puan();
aravind sirsikared3413e2016-11-11 17:15:10 +05303274 test_packet_access_rej_epdan();
aravind sirsikare9a138e2017-01-24 12:36:08 +05303275 test_packet_access_rej_prr();
3276 test_packet_access_rej_prr_no_other_tbfs();
Jacob Erlbeck67c38502015-05-11 10:32:40 +02003277
3278 if (getenv("TALLOC_REPORT_FULL"))
3279 talloc_report_full(tall_pcu_ctx, stderr);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003280 return EXIT_SUCCESS;
3281}
3282
3283/*
3284 * stubs that should not be reached
3285 */
3286extern "C" {
3287void l1if_pdch_req() { abort(); }
3288void l1if_connect_pdch() { abort(); }
3289void l1if_close_pdch() { abort(); }
3290void l1if_open_pdch() { abort(); }
3291}