blob: 2036023dceee9995edc60c76b048567405c6cc59 [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
Pau Espin Pedrol474dc772019-09-09 14:09:48 +020064 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckac89a552015-06-29 14:18:46 +020065
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
Pau Espin Pedrol474dc772019-09-09 14:09:48 +020069 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckac89a552015-06-29 14:18:46 +020070}
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
Pau Espin Pedrol474dc772019-09-09 14:09:48 +020077 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +010078
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
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200137 fprintf(stderr, "=== 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;
Pau Espin Pedrol63700ea2019-09-09 13:19:06 +0200158 osmo_tdef_set(bts->T_defs_pcu, -2030, 0, OSMO_TDEF_S);
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200159 osmo_tdef_set(bts->T_defs_pcu, -2031, 0, OSMO_TDEF_S);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100160 trx = &bts->trx[0];
161
162 trx->pdch[ts_no].enable();
Philippd935d882016-11-07 13:07:36 +0100163 the_bts->set_current_frame_number(DUMMY_FN);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100164}
165
166static gprs_rlcmac_dl_tbf *create_dl_tbf(BTS *the_bts, uint8_t ms_class,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +0100167 uint8_t egprs_ms_class, uint8_t *trx_no_)
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100168{
169 gprs_rlcmac_bts *bts;
170 int tfi;
171 uint8_t trx_no;
172
173 gprs_rlcmac_dl_tbf *dl_tbf;
174
175 bts = the_bts->bts_data();
176
177 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_DL_TBF, &trx_no, -1);
178 OSMO_ASSERT(tfi >= 0);
Max92b7a502018-01-26 11:01:35 +0100179 dl_tbf = tbf_alloc_dl_tbf(bts, NULL, trx_no, ms_class, egprs_ms_class,
180 true);
Max9bbe1602016-07-18 12:50:18 +0200181 dl_tbf->set_ta(0);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100182 check_tbf(dl_tbf);
183
184 /* "Establish" the DL TBF */
Max0e599802018-01-23 20:09:06 +0100185 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_SEND_ASS);
Max2399b1d2018-01-12 15:48:12 +0100186 TBF_SET_STATE(dl_tbf, GPRS_RLCMAC_FLOW);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100187 dl_tbf->m_wait_confirm = 0;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100188 check_tbf(dl_tbf);
189
190 *trx_no_ = trx_no;
191
192 return dl_tbf;
193}
194
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200195static unsigned fn2bn(unsigned fn)
196{
197 return (fn % 52) / 4;
198}
199
200static unsigned fn_add_blocks(unsigned fn, unsigned blocks)
201{
202 unsigned bn = fn2bn(fn) + blocks;
203 fn = fn - (fn % 52);
204 fn += bn * 4 + bn / 3;
Max9dabfa22017-05-16 16:10:45 +0200205 return fn % GSM_MAX_FN;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200206}
207
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200208static void request_dl_rlc_block(struct gprs_rlcmac_bts *bts,
Max878bd1f2016-07-20 13:05:05 +0200209 uint8_t trx_no, uint8_t ts_no,
Jacob Erlbeckee310902015-08-24 11:55:17 +0200210 uint32_t *fn, uint8_t *block_nr = NULL)
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100211{
Jacob Erlbeckee310902015-08-24 11:55:17 +0200212 uint8_t bn = fn2bn(*fn);
Max878bd1f2016-07-20 13:05:05 +0200213 gprs_rlcmac_rcv_rts_block(bts, trx_no, ts_no, *fn, bn);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200214 *fn = fn_add_blocks(*fn, 1);
Jacob Erlbeckee310902015-08-24 11:55:17 +0200215 bn += 1;
216 if (block_nr)
217 *block_nr = bn;
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100218}
219
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200220static void request_dl_rlc_block(struct gprs_rlcmac_tbf *tbf,
Jacob Erlbeckee310902015-08-24 11:55:17 +0200221 uint32_t *fn, uint8_t *block_nr = NULL)
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200222{
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200223 request_dl_rlc_block(tbf->bts->bts_data(), tbf->trx->trx_no,
Max878bd1f2016-07-20 13:05:05 +0200224 tbf->control_ts, fn, block_nr);
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200225}
226
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100227enum test_tbf_final_ack_mode {
228 TEST_MODE_STANDARD,
229 TEST_MODE_REVERSE_FREE
230};
231
232static void test_tbf_final_ack(enum test_tbf_final_ack_mode test_mode)
Daniel Willmann510d7d32014-08-15 18:19:41 +0200233{
234 BTS the_bts;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100235 uint8_t ts_no = 4;
236 unsigned i;
Daniel Willmann510d7d32014-08-15 18:19:41 +0200237 uint8_t ms_class = 45;
238 uint32_t fn;
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100239 uint8_t block_nr;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100240 uint8_t trx_no;
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200241 GprsMs *ms;
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200242 uint32_t tlli = 0xffeeddcc;
Daniel Willmann510d7d32014-08-15 18:19:41 +0200243
244 uint8_t rbb[64/8];
245
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200246 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100247
Daniel Willmann510d7d32014-08-15 18:19:41 +0200248 gprs_rlcmac_dl_tbf *dl_tbf;
249 gprs_rlcmac_tbf *new_tbf;
250
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100251 setup_bts(&the_bts, ts_no);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +0100252 dl_tbf = create_dl_tbf(&the_bts, ms_class, 0, &trx_no);
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200253 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200254 ms = dl_tbf->ms();
Daniel Willmann510d7d32014-08-15 18:19:41 +0200255
256 for (i = 0; i < sizeof(llc_data); i++)
257 llc_data[i] = i%256;
258
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100259 /* Schedule two LLC frames */
Daniel Willmann0f58af62014-09-19 11:57:21 +0200260 dl_tbf->append_data(ms_class, 1000, llc_data, sizeof(llc_data));
261 dl_tbf->append_data(ms_class, 1000, llc_data, sizeof(llc_data));
Daniel Willmann510d7d32014-08-15 18:19:41 +0200262
263
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100264 /* Send only a few RLC/MAC blocks */
Daniel Willmann510d7d32014-08-15 18:19:41 +0200265 fn = 0;
Jacob Erlbeckee310902015-08-24 11:55:17 +0200266 do {
Daniel Willmann510d7d32014-08-15 18:19:41 +0200267 /* Request to send one block */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200268 request_dl_rlc_block(dl_tbf, &fn, &block_nr);
Jacob Erlbeckee310902015-08-24 11:55:17 +0200269 } while (block_nr < 3);
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200270
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100271 OSMO_ASSERT(dl_tbf->have_data());
272 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
Daniel Willmann510d7d32014-08-15 18:19:41 +0200273
274 /* Queue a final ACK */
275 memset(rbb, 0, sizeof(rbb));
276 /* Receive a final ACK */
Max7df82d42017-12-15 11:14:30 +0100277 dl_tbf->rcvd_dl_ack(true, 1, rbb);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200278
279 /* Clean up and ensure tbfs are in the correct state */
280 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200281 new_tbf = ms->dl_tbf();
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100282 check_tbf(new_tbf);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200283 OSMO_ASSERT(new_tbf != dl_tbf);
284 OSMO_ASSERT(new_tbf->tfi() == 1);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100285 check_tbf(dl_tbf);
Max0e599802018-01-23 20:09:06 +0100286 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_NONE);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100287 if (test_mode == TEST_MODE_REVERSE_FREE) {
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200288 GprsMs::Guard guard(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100289 tbf_free(new_tbf);
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200290 OSMO_ASSERT(ms->dl_tbf() == NULL);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100291 check_tbf(dl_tbf);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100292 tbf_free(dl_tbf);
293 } else {
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200294 GprsMs::Guard guard(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100295 tbf_free(dl_tbf);
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200296 OSMO_ASSERT(ms->dl_tbf() == new_tbf);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100297 check_tbf(new_tbf);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100298 tbf_free(new_tbf);
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200299 OSMO_ASSERT(ms->dl_tbf() == NULL);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100300 }
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100301
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200302 fprintf(stderr, "=== end %s ===\n", __func__);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200303}
304
Max7d32f552017-12-15 11:25:14 +0100305/* Receive an ACK */
306#define RCV_ACK(fin, tbf, rbb) do { \
Maxea98b7d2018-01-04 15:13:27 +0100307 tbf->rcvd_dl_ack(fin, tbf->window()->v_s(), rbb); \
Max7d32f552017-12-15 11:25:14 +0100308 if (!fin) \
Maxea98b7d2018-01-04 15:13:27 +0100309 OSMO_ASSERT(tbf->window()->window_empty()); \
Max7d32f552017-12-15 11:25:14 +0100310 } while(0)
311
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100312static void test_tbf_delayed_release()
313{
314 BTS the_bts;
315 gprs_rlcmac_bts *bts;
316 uint8_t ts_no = 4;
317 unsigned i;
318 uint8_t ms_class = 45;
319 uint32_t fn = 0;
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100320 uint8_t trx_no;
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200321 uint32_t tlli = 0xffeeddcc;
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200322 unsigned long dl_tbf_idle_msec;
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100323
324 uint8_t rbb[64/8];
325
326 gprs_rlcmac_dl_tbf *dl_tbf;
327
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200328 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100329
330 bts = the_bts.bts_data();
331
332 setup_bts(&the_bts, ts_no);
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200333 OSMO_ASSERT(osmo_tdef_set(bts->T_defs_pcu, -2031, 200, OSMO_TDEF_MS) == 0);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100334
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +0100335 dl_tbf = create_dl_tbf(&the_bts, ms_class, 0, &trx_no);
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200336 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100337
338 for (i = 0; i < sizeof(llc_data); i++)
339 llc_data[i] = i%256;
340
341 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
342
343 /* Schedule two LLC frames */
344 dl_tbf->append_data(ms_class, 1000, llc_data, sizeof(llc_data));
345 dl_tbf->append_data(ms_class, 1000, llc_data, sizeof(llc_data));
346
347 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
348
349 /* Drain the queue */
350 while (dl_tbf->have_data())
351 /* Request to send one RLC/MAC block */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200352 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100353
354 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
355
356 /* ACK all blocks */
357 memset(rbb, 0xff, sizeof(rbb));
Max7d32f552017-12-15 11:25:14 +0100358
359 RCV_ACK(false, dl_tbf, rbb); /* Receive an ACK */
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100360
361 /* Force sending of a single block containing an LLC dummy command */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200362 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100363
Max7d32f552017-12-15 11:25:14 +0100364 RCV_ACK(false, dl_tbf, rbb); /* Receive an ACK */
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100365
366 /* Timeout (make sure fn % 52 remains valid) */
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200367 dl_tbf_idle_msec = osmo_tdef_get(bts->T_defs_pcu, -2031, OSMO_TDEF_MS, -1);
368 fn += 52 * ((msecs_to_frames(dl_tbf_idle_msec + 100) + 51)/ 52);
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200369 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100370
371 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FINISHED));
372
Max7d32f552017-12-15 11:25:14 +0100373 RCV_ACK(true, dl_tbf, rbb); /* Receive a final ACK */
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100374
375 /* Clean up and ensure tbfs are in the correct state */
376 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
Max0e599802018-01-23 20:09:06 +0100377 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_NONE);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100378 check_tbf(dl_tbf);
379 tbf_free(dl_tbf);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200380 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100381}
382
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200383static void test_tbf_imsi()
384{
385 BTS the_bts;
386 uint8_t ts_no = 4;
387 uint8_t ms_class = 45;
388 uint8_t trx_no;
389 GprsMs *ms1, *ms2;
390
391 gprs_rlcmac_dl_tbf *dl_tbf[2];
392
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200393 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200394
395 setup_bts(&the_bts, ts_no);
396
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +0100397 dl_tbf[0] = create_dl_tbf(&the_bts, ms_class, 0, &trx_no);
398 dl_tbf[1] = create_dl_tbf(&the_bts, ms_class, 0, &trx_no);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200399
400 dl_tbf[0]->update_ms(0xf1000001, GPRS_RLCMAC_DL_TBF);
401 dl_tbf[1]->update_ms(0xf1000002, GPRS_RLCMAC_DL_TBF);
402
403 dl_tbf[0]->assign_imsi("001001000000001");
404 ms1 = the_bts.ms_store().get_ms(0, 0, "001001000000001");
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200405 OSMO_ASSERT(ms1 != NULL);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200406 ms2 = the_bts.ms_store().get_ms(0xf1000001);
407 OSMO_ASSERT(ms2 != NULL);
408 OSMO_ASSERT(strcmp(ms2->imsi(), "001001000000001") == 0);
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200409 OSMO_ASSERT(ms1 == ms2);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200410
411 /* change the IMSI on TBF 0 */
412 dl_tbf[0]->assign_imsi("001001000000002");
413 ms1 = the_bts.ms_store().get_ms(0, 0, "001001000000001");
414 OSMO_ASSERT(ms1 == NULL);
415 ms1 = the_bts.ms_store().get_ms(0, 0, "001001000000002");
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200416 OSMO_ASSERT(ms1 != NULL);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200417 OSMO_ASSERT(strcmp(ms2->imsi(), "001001000000002") == 0);
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200418 OSMO_ASSERT(ms1 == ms2);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200419
420 /* use the same IMSI on TBF 2 */
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200421 {
422 GprsMs::Guard guard(ms2);
423 dl_tbf[1]->assign_imsi("001001000000002");
424 ms1 = the_bts.ms_store().get_ms(0, 0, "001001000000002");
425 OSMO_ASSERT(ms1 != NULL);
426 OSMO_ASSERT(ms1 != ms2);
427 OSMO_ASSERT(strcmp(ms1->imsi(), "001001000000002") == 0);
428 OSMO_ASSERT(strcmp(ms2->imsi(), "") == 0);
429 }
430
431 ms2 = the_bts.ms_store().get_ms(0xf1000001);
432 OSMO_ASSERT(ms2 == NULL);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200433
434 tbf_free(dl_tbf[1]);
435 ms1 = the_bts.ms_store().get_ms(0, 0, "001001000000002");
436 OSMO_ASSERT(ms1 == NULL);
437
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200438 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200439}
440
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200441static void test_tbf_exhaustion()
442{
443 BTS the_bts;
444 gprs_rlcmac_bts *bts;
445 unsigned i;
446 uint8_t ts_no = 4;
447 uint8_t ms_class = 45;
448 int rc = 0;
449
450 uint8_t buf[256] = {0};
451
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200452 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200453
Alexander Couzens5c3783b2019-05-25 05:41:18 +0200454 bssgp_nsi = gprs_ns_instantiate(&gprs_bssgp_ns_cb, tall_pcu_ctx);
455 if (!bssgp_nsi) {
456 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
457 abort();
458 }
459
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200460 bts = the_bts.bts_data();
461 setup_bts(&the_bts, ts_no);
Maxa3ff3162019-03-11 14:40:21 +0100462 gprs_bssgp_create_and_connect(bts, 33001, 0, 33001, 1234, 1234, 1234, 1, 1, false, 0, 0, 0);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200463
464 for (i = 0; i < 1024; i++) {
465 uint32_t tlli = 0xc0000000 + i;
466 char imsi[16] = {0};
467 unsigned delay_csec = 1000;
468
Jacob Erlbeck9a2845d2015-05-21 12:06:58 +0200469 snprintf(imsi, sizeof(imsi), "001001%09d", i);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200470
Jacob Erlbeck14e00f82015-11-27 18:10:39 +0100471 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200472 delay_csec, buf, sizeof(buf));
473
474 if (rc < 0)
475 break;
476 }
477
478 OSMO_ASSERT(rc == -EBUSY);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200479 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200480
481 gprs_bssgp_destroy();
482}
483
Jacob Erlbeck41168642015-06-12 13:41:00 +0200484static void test_tbf_dl_llc_loss()
485{
486 BTS the_bts;
487 gprs_rlcmac_bts *bts;
488 uint8_t ts_no = 4;
489 uint8_t ms_class = 45;
490 int rc = 0;
491 uint32_t tlli = 0xc0123456;
492 const char *imsi = "001001000123456";
493 unsigned delay_csec = 1000;
494 GprsMs *ms;
495
496 uint8_t buf[19];
497
Alexander Couzens5c3783b2019-05-25 05:41:18 +0200498 bssgp_nsi = gprs_ns_instantiate(&gprs_bssgp_ns_cb, tall_pcu_ctx);
499 if (!bssgp_nsi) {
500 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
501 abort();
502 }
503
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200504 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200505
506 bts = the_bts.bts_data();
507 setup_bts(&the_bts, ts_no);
Pau Espin Pedrol63700ea2019-09-09 13:19:06 +0200508 /* keep the MS object 10 seconds */
509 OSMO_ASSERT(osmo_tdef_set(bts->T_defs_pcu, -2030, 10, OSMO_TDEF_S) == 0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200510
Maxa3ff3162019-03-11 14:40:21 +0100511 gprs_bssgp_create_and_connect(bts, 33001, 0, 33001, 2234, 2234, 2234, 1, 1, false, 0, 0, 0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200512
513 /* Handle LLC frame 1 */
514 memset(buf, 1, sizeof(buf));
Jacob Erlbeck14e00f82015-11-27 18:10:39 +0100515 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200516 delay_csec, buf, sizeof(buf));
517 OSMO_ASSERT(rc >= 0);
518
519 ms = the_bts.ms_store().get_ms(0, 0, imsi);
520 OSMO_ASSERT(ms != NULL);
521 OSMO_ASSERT(ms->dl_tbf() != NULL);
Max9bbe1602016-07-18 12:50:18 +0200522 ms->dl_tbf()->set_ta(0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200523
524 /* Handle LLC frame 2 */
525 memset(buf, 2, sizeof(buf));
Jacob Erlbeck14e00f82015-11-27 18:10:39 +0100526 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200527 delay_csec, buf, sizeof(buf));
528 OSMO_ASSERT(rc >= 0);
529
530 /* TBF establishment fails (timeout) */
531 tbf_free(ms->dl_tbf());
532
533 /* Handle LLC frame 3 */
534 memset(buf, 3, sizeof(buf));
Jacob Erlbeck14e00f82015-11-27 18:10:39 +0100535 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200536 delay_csec, buf, sizeof(buf));
537 OSMO_ASSERT(rc >= 0);
538
539 OSMO_ASSERT(ms->dl_tbf() != NULL);
540
541 /* Get first BSN */
542 struct msgb *msg;
543 int fn = 0;
544 uint8_t expected_data = 1;
Maxd3a0d912019-03-05 16:15:01 +0100545 static uint8_t exp[][GSM_MACBLOCK_LEN] = {
546 { 0x07, 0x00, 0x00, 0x4d, 0x01, 0x01, 0x01,
547 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
548 { 0x07, 0x00, 0x02, 0x4d, 0x02, 0x02, 0x02,
549 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 },
550 { 0x07, 0x01, 0x04, 0x4d, 0x03, 0x03, 0x03,
551 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 },
552 };
Jacob Erlbeck41168642015-06-12 13:41:00 +0200553
554 while (ms->dl_tbf()->have_data()) {
555 msg = ms->dl_tbf()->create_dl_acked_block(fn += 4, 7);
556 fprintf(stderr, "MSG = %s\n", msgb_hexdump(msg));
Maxd3a0d912019-03-05 16:15:01 +0100557 if (!msgb_eq_data_print(msg, exp[expected_data - 1], GSM_MACBLOCK_LEN))
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200558 fprintf(stderr, "%s failed at %u\n", __func__, expected_data);
Maxd3a0d912019-03-05 16:15:01 +0100559
Jacob Erlbeck41168642015-06-12 13:41:00 +0200560 expected_data += 1;
561 }
Jacob Erlbeck409efa12015-06-12 14:06:09 +0200562 OSMO_ASSERT(expected_data-1 == 3);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200563
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200564 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200565
566 gprs_bssgp_destroy();
567}
568
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200569static gprs_rlcmac_ul_tbf *establish_ul_tbf_single_phase(BTS *the_bts,
570 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta)
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200571{
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200572 GprsMs *ms;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200573 int tfi = 0;
574 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200575 uint8_t trx_no = 0;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200576 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeck20f6fd12015-06-08 11:05:45 +0200577 struct pcu_l1_meas meas;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200578
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200579 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200580
bhargava959d1de2016-08-17 15:17:21 +0530581 the_bts->rcv_rach(0x03, *fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200582
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200583 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200584 OSMO_ASSERT(ul_tbf != NULL);
585
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200586 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200587
588 uint8_t data_msg[23] = {
589 0x00, /* GPRS_RLCMAC_DATA_BLOCK << 6 */
590 uint8_t(1 | (tfi << 2)),
591 uint8_t(1), /* BSN:7, E:1 */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200592 uint8_t(tlli >> 24), uint8_t(tlli >> 16),
593 uint8_t(tlli >> 8), uint8_t(tlli), /* TLLI */
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200594 };
595
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200596 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
597 pdch->rcv_block(&data_msg[0], sizeof(data_msg), *fn, &meas);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200598
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200599 ms = the_bts->ms_by_tlli(tlli);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200600 OSMO_ASSERT(ms != NULL);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200601
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200602 return ul_tbf;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200603}
604
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200605static void send_ul_mac_block(BTS *the_bts, unsigned trx_no, unsigned ts_no,
606 RlcMacUplink_t *ulreq, unsigned fn)
607{
608 bitvec *rlc_block;
609 uint8_t buf[64];
610 int num_bytes;
611 struct gprs_rlcmac_pdch *pdch;
612 struct pcu_l1_meas meas;
613
614 meas.set_rssi(31);
615
Alexander Couzensccde5c92017-02-04 03:10:08 +0100616 rlc_block = bitvec_alloc(23, tall_pcu_ctx);
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200617
618 encode_gsm_rlcmac_uplink(rlc_block, ulreq);
619 num_bytes = bitvec_pack(rlc_block, &buf[0]);
620 OSMO_ASSERT(size_t(num_bytes) < sizeof(buf));
621 bitvec_free(rlc_block);
622
Jacob Erlbeckaf75ce82015-08-26 13:22:28 +0200623 the_bts->set_current_block_frame_number(fn, 0);
624
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200625 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
626 pdch->rcv_block(&buf[0], num_bytes, fn, &meas);
627}
628
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200629static void send_control_ack(gprs_rlcmac_tbf *tbf)
630{
631 RlcMacUplink_t ulreq = {0};
632
633 OSMO_ASSERT(tbf->poll_fn != 0);
Jacob Erlbeck8eb17142016-01-22 17:58:17 +0100634 OSMO_ASSERT(tbf->is_control_ts(tbf->poll_ts));
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200635
636 ulreq.u.MESSAGE_TYPE = MT_PACKET_CONTROL_ACK;
637 Packet_Control_Acknowledgement_t *ctrl_ack =
638 &ulreq.u.Packet_Control_Acknowledgement;
639
640 ctrl_ack->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
641 ctrl_ack->TLLI = tbf->tlli();
Jacob Erlbeck8eb17142016-01-22 17:58:17 +0100642 send_ul_mac_block(tbf->bts, tbf->trx->trx_no, tbf->poll_ts,
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200643 &ulreq, tbf->poll_fn);
644}
645
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530646static gprs_rlcmac_ul_tbf *puan_urbb_len_issue(BTS *the_bts,
647 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
648 uint8_t ms_class, uint8_t egprs_ms_class)
649{
650 GprsMs *ms;
651 uint32_t rach_fn = *fn - 51;
652 uint32_t sba_fn = *fn + 52;
653 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +0100654 int tfi = 0;
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530655 gprs_rlcmac_ul_tbf *ul_tbf;
656 struct gprs_rlcmac_pdch *pdch;
657 gprs_rlcmac_bts *bts;
658 RlcMacUplink_t ulreq = {0};
659 struct pcu_l1_meas meas;
660 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
661 GprsCodingScheme cs;
662
663 meas.set_rssi(31);
664 bts = the_bts->bts_data();
665
666 /* needed to set last_rts_fn in the PDCH object */
667 request_dl_rlc_block(bts, trx_no, ts_no, fn);
668
669 /*
670 * simulate RACH, this sends an Immediate
671 * Assignment Uplink on the AGCH
672 */
Aravind Sirsikarfd713842016-08-28 17:55:05 +0530673 the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530674
675 /* get next free TFI */
676 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
677
678 /* fake a resource request */
679 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
680 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
681 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
682 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
683 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability = 1;
684 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
685 Count_MS_RA_capability_value = 1;
686 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
687 MS_RA_capability_value[0].u.Content.
688 Exist_Multislot_capability = 1;
689 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
690 MS_RA_capability_value[0].u.Content.Multislot_capability.
691 Exist_GPRS_multislot_class = 1;
692 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
693 MS_RA_capability_value[0].u.Content.Multislot_capability.
694 GPRS_multislot_class = ms_class;
695 if (egprs_ms_class) {
696 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
697 MS_RA_capability_value[0].u.Content.
698 Multislot_capability.Exist_EGPRS_multislot_class = 1;
699 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
700 MS_RA_capability_value[0].u.Content.
701 Multislot_capability.EGPRS_multislot_class = ms_class;
702 }
703
704 send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
705
706 /* check the TBF */
707 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
708 OSMO_ASSERT(ul_tbf);
709 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
710
711 /* send packet uplink assignment */
712 *fn = sba_fn;
713 request_dl_rlc_block(ul_tbf, fn);
714
715 /* send real acknowledgement */
716 send_control_ack(ul_tbf);
717
718 check_tbf(ul_tbf);
719 /* send fake data */
720 uint8_t data_msg[42] = {
721 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
Neels Hofmeyrd34646a2017-02-08 17:07:40 +0100722 (uint8_t)(tfi << 1),
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530723 1, /* BSN:7, E:1 */
724 };
725
726 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
727 pdch->rcv_block(&data_msg[0], 23, *fn, &meas);
728
729 ms = the_bts->ms_by_tlli(tlli);
730 OSMO_ASSERT(ms != NULL);
731 OSMO_ASSERT(ms->ta() == qta/4);
732 OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
733
734 /*
735 * TS 44.060, B.8.1
736 * first seg received first, later second seg
737 */
Maxbea2edb2019-03-06 17:04:59 +0100738 cs = MCS3;
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530739 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
740 egprs3->si = 0;
741 egprs3->r = 1;
742 egprs3->cv = 7;
743 egprs3->tfi_hi = tfi & 0x03;
744 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
745 egprs3->bsn1_hi = 1;
746 egprs3->bsn1_lo = 0;
747 egprs3->cps_hi = 1;
748 data_msg[3] = 0xff;
749 egprs3->pi = 0;
750 egprs3->cps_lo = 1;
751 egprs3->rsb = 0;
752 egprs3->spb = 0;
753 egprs3->pi = 0;
754
755 pdch->rcv_block(data_msg, 42, *fn, &meas);
756
757 struct msgb *msg1 = ul_tbf->create_ul_ack(*fn, ts_no);
758
Max6e96dd42019-03-06 18:17:32 +0100759 static uint8_t exp1[] = { 0x40, 0x24, 0x01, 0x03, 0x3e, 0x24, 0x46, 0x68, 0x90, 0x87, 0xb0, 0x06,
Maxd3a0d912019-03-05 16:15:01 +0100760 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b
761 };
762
763 if (!msgb_eq_data_print(msg1, exp1, GSM_MACBLOCK_LEN)) {
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200764 fprintf(stderr, "%s test failed on 1st segment!\n", __func__);
Maxd3a0d912019-03-05 16:15:01 +0100765 return NULL;
766 }
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530767
768 egprs3->si = 0;
769 egprs3->r = 1;
770 egprs3->cv = 7;
771 egprs3->tfi_hi = tfi & 0x03;
772 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
773 egprs3->bsn1_hi = 4;
774 egprs3->bsn1_lo = 0;
775 egprs3->cps_hi = 1;
776 data_msg[3] = 0xff;
777 egprs3->pi = 0;
778 egprs3->cps_lo = 1;
779 egprs3->rsb = 0;
780 egprs3->spb = 0;
781
782 pdch->rcv_block(data_msg, 42, *fn, &meas);
783
784 msg1 = ul_tbf->create_ul_ack(*fn, ts_no);
785
Max6e96dd42019-03-06 18:17:32 +0100786 static uint8_t exp2[] = { 0x40, 0x24, 0x01, 0x03, 0x3e, 0x24, 0x46, 0x68, 0x90, 0x88, 0xb0, 0x06, 0x8b,
Maxd3a0d912019-03-05 16:15:01 +0100787 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b
788 };
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530789
Maxd3a0d912019-03-05 16:15:01 +0100790 if (!msgb_eq_data_print(msg1, exp2, GSM_MACBLOCK_LEN)) {
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200791 fprintf(stderr, "%s test failed on 2nd segment!\n", __func__);
Maxd3a0d912019-03-05 16:15:01 +0100792 return NULL;
793 }
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530794 return ul_tbf;
795}
796
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530797static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(BTS *the_bts,
798 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
799 uint8_t ms_class, uint8_t egprs_ms_class)
800{
801 GprsMs *ms;
802 uint32_t rach_fn = *fn - 51;
803 uint32_t sba_fn = *fn + 52;
804 uint8_t trx_no = 0;
805 int tfi = 0, i = 0;
806 gprs_rlcmac_ul_tbf *ul_tbf;
807 struct gprs_rlcmac_pdch *pdch;
808 gprs_rlcmac_bts *bts;
809 RlcMacUplink_t ulreq = {0};
810 struct pcu_l1_meas meas;
811 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
812 GprsCodingScheme cs;
813
814 meas.set_rssi(31);
815 bts = the_bts->bts_data();
816
817 /* needed to set last_rts_fn in the PDCH object */
818 request_dl_rlc_block(bts, trx_no, ts_no, fn);
819
820 /*
821 * simulate RACH, this sends an Immediate
822 * Assignment Uplink on the AGCH
823 */
bhargava959d1de2016-08-17 15:17:21 +0530824 the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530825
826 /* get next free TFI */
827 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
828
829 /* fake a resource request */
830 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
831 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
832 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
833 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
834 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability = 1;
835 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
836 Count_MS_RA_capability_value = 1;
837 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
838 MS_RA_capability_value[0].u.Content.
839 Exist_Multislot_capability = 1;
840 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
841 MS_RA_capability_value[0].u.Content.Multislot_capability.
842 Exist_GPRS_multislot_class = 1;
843 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
844 MS_RA_capability_value[0].u.Content.Multislot_capability.
845 GPRS_multislot_class = ms_class;
846 if (egprs_ms_class) {
847 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
848 MS_RA_capability_value[0].u.Content.
849 Multislot_capability.Exist_EGPRS_multislot_class = 1;
850 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
851 MS_RA_capability_value[0].u.Content.
852 Multislot_capability.EGPRS_multislot_class = ms_class;
853 }
854
855 send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
856
857 /* check the TBF */
858 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
859 OSMO_ASSERT(ul_tbf != NULL);
860 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
861
862 /* send packet uplink assignment */
863 *fn = sba_fn;
864 request_dl_rlc_block(ul_tbf, fn);
865
866 /* send real acknowledgement */
867 send_control_ack(ul_tbf);
868
869 check_tbf(ul_tbf);
870
871 /* send fake data */
872 uint8_t data_msg[42] = {
873 0x00 | 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
874 uint8_t(0 | (tfi << 1)),
875 uint8_t(1), /* BSN:7, E:1 */
876 };
877
878 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
879 pdch->rcv_block(&data_msg[0], 23, *fn, &meas);
880
881 ms = the_bts->ms_by_tlli(tlli);
882 OSMO_ASSERT(ms != NULL);
883 OSMO_ASSERT(ms->ta() == qta/4);
884 OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
885
886 /*
887 * TS 44.060, B.8.1
888 * first seg received first, later second seg
889 */
Maxbea2edb2019-03-06 17:04:59 +0100890 cs = MCS3;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530891 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
892 egprs3->si = 1;
893 egprs3->r = 1;
894 egprs3->cv = 7;
895 egprs3->tfi_hi = tfi & 0x03;
896 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
897 egprs3->bsn1_hi = 1;
898 egprs3->bsn1_lo = 0;
899 egprs3->cps_hi = 1;
900 data_msg[3] = 0xff;
901 egprs3->pi = 0;
902 egprs3->cps_lo = 1;
903 egprs3->rsb = 0;
904 egprs3->spb = 2;
905 egprs3->pi = 0;
906
907 pdch->rcv_block(data_msg, 42, *fn, &meas);
908
909 struct gprs_rlc_data *block = ul_tbf->m_rlc.block(1);
910
911 /* check the status of the block */
912 OSMO_ASSERT(block->spb_status.block_status_ul ==
913 EGPRS_RESEG_FIRST_SEG_RXD);
914
915 egprs3->si = 1;
916 egprs3->r = 1;
917 egprs3->cv = 7;
918 egprs3->tfi_hi = tfi & 0x03;
919 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
920 egprs3->bsn1_hi = 1;
921 egprs3->bsn1_lo = 0;
922 egprs3->cps_hi = 1;
923 data_msg[3] = 0xff;
924 egprs3->pi = 0;
925 egprs3->cps_lo = 1;
926 egprs3->rsb = 0;
927 egprs3->spb = 3;
928
929 pdch->rcv_block(data_msg, 42, *fn, &meas);
930
931 /* check the status of the block */
932 OSMO_ASSERT(block->spb_status.block_status_ul ==
933 EGPRS_RESEG_DEFAULT);
934 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +0100935 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530936 /* Assembled MCS is MCS6. so the size is 74 */
937 OSMO_ASSERT(block->len == 74);
938
939 /*
940 * TS 44.060, B.8.1
941 * second seg first, later first seg
942 */
943 memset(data_msg, 0, sizeof(data_msg));
944
Maxbea2edb2019-03-06 17:04:59 +0100945 cs = MCS3;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530946 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
947 egprs3->si = 1;
948 egprs3->r = 1;
949 egprs3->cv = 7;
950 egprs3->tfi_hi = tfi & 0x03;
951 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
952 egprs3->bsn1_hi = 2;
953 egprs3->bsn1_lo = 0;
954 egprs3->cps_hi = 1;
955 data_msg[3] = 0xff;
956 egprs3->pi = 0;
957 egprs3->cps_lo = 1;
958 egprs3->rsb = 0;
959 egprs3->spb = 3;
960 egprs3->pi = 0;
961
962 pdch->rcv_block(data_msg, 42, *fn, &meas);
963
964 block = ul_tbf->m_rlc.block(2);
965 /* check the status of the block */
966 OSMO_ASSERT(block->spb_status.block_status_ul ==
967 EGPRS_RESEG_SECOND_SEG_RXD);
968
969 egprs3->si = 1;
970 egprs3->r = 1;
971 egprs3->cv = 7;
972 egprs3->tfi_hi = tfi & 0x03;
973 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
974 egprs3->bsn1_hi = 2;
975 egprs3->bsn1_lo = 0;
976 egprs3->cps_hi = 1;
977 data_msg[3] = 0xff;
978 egprs3->pi = 0;
979 egprs3->cps_lo = 1;
980 egprs3->rsb = 0;
981 egprs3->spb = 2;
982 egprs3->pi = 0;
983
984 pdch->rcv_block(data_msg, 42, *fn, &meas);
985
986 /* check the status of the block */
987 OSMO_ASSERT(block->spb_status.block_status_ul ==
988 EGPRS_RESEG_DEFAULT);
989 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +0100990 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530991 /* Assembled MCS is MCS6. so the size is 74 */
992 OSMO_ASSERT(block->len == 74);
993
994 /*
995 * TS 44.060, B.8.1
996 * Error scenario with spb as 1
997 */
Maxbea2edb2019-03-06 17:04:59 +0100998 cs = MCS3;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530999 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1000 egprs3->si = 1;
1001 egprs3->r = 1;
1002 egprs3->cv = 7;
1003 egprs3->tfi_hi = tfi & 0x03;
1004 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1005 egprs3->bsn1_hi = 3;
1006 egprs3->bsn1_lo = 0;
1007 egprs3->cps_hi = 1;
1008 data_msg[3] = 0xff;
1009 egprs3->pi = 0;
1010 egprs3->cps_lo = 1;
1011 egprs3->rsb = 0;
1012 egprs3->spb = 1;
1013 egprs3->pi = 0;
1014
1015 pdch->rcv_block(data_msg, 42, *fn, &meas);
1016
1017 block = ul_tbf->m_rlc.block(3);
1018 /* check the status of the block */
1019 OSMO_ASSERT(block->spb_status.block_status_ul ==
1020 EGPRS_RESEG_DEFAULT);
1021 /*
1022 * TS 44.060, B.8.1
1023 * comparison of rlc_data for multiple scenarios
1024 * Receive First, the second(BSN 3)
1025 * Receive First, First then Second(BSN 4)
1026 * Receive Second then First(BSN 5)
1027 * after above 3 scenarios are triggered,
1028 * rlc_data of all 3 BSN are compared
1029 */
1030
1031 /* Initialize the data_msg */
1032 for (i = 0; i < 42; i++)
1033 data_msg[i] = i;
1034
Maxbea2edb2019-03-06 17:04:59 +01001035 cs = MCS3;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301036 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1037 egprs3->si = 1;
1038 egprs3->r = 1;
1039 egprs3->cv = 7;
1040 egprs3->tfi_hi = tfi & 0x03;
1041 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1042 egprs3->bsn1_hi = 3;
1043 egprs3->bsn1_lo = 0;
1044 egprs3->cps_hi = 1;
1045 data_msg[3] = 0xff;
1046 egprs3->pi = 0;
1047 egprs3->cps_lo = 1;
1048 egprs3->rsb = 0;
1049 egprs3->spb = 2;
1050 egprs3->pi = 0;
1051
1052 pdch->rcv_block(data_msg, 42, *fn, &meas);
1053
1054 block = ul_tbf->m_rlc.block(3);
1055 /* check the status of the block */
1056 OSMO_ASSERT(block->spb_status.block_status_ul ==
1057 EGPRS_RESEG_FIRST_SEG_RXD);
1058
Maxbea2edb2019-03-06 17:04:59 +01001059 cs = MCS3;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301060 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1061 egprs3->si = 1;
1062 egprs3->r = 1;
1063 egprs3->cv = 7;
1064 egprs3->tfi_hi = tfi & 0x03;
1065 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1066 egprs3->bsn1_hi = 3;
1067 egprs3->bsn1_lo = 0;
1068 egprs3->cps_hi = 1;
1069 data_msg[3] = 0xff;
1070 egprs3->pi = 0;
1071 egprs3->cps_lo = 1;
1072 egprs3->rsb = 0;
1073 egprs3->spb = 3;
1074 egprs3->pi = 0;
1075
1076 pdch->rcv_block(data_msg, 42, *fn, &meas);
1077
1078 block = ul_tbf->m_rlc.block(3);
1079 /* check the status of the block */
1080 OSMO_ASSERT(block->spb_status.block_status_ul ==
1081 EGPRS_RESEG_DEFAULT);
1082 /* Assembled MCS is MCS6. so the size is 74 */
1083 OSMO_ASSERT(block->len == 74);
1084 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001085 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301086
Maxbea2edb2019-03-06 17:04:59 +01001087 cs = MCS3;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301088 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1089 egprs3->si = 1;
1090 egprs3->r = 1;
1091 egprs3->cv = 7;
1092 egprs3->tfi_hi = tfi & 0x03;
1093 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1094 egprs3->bsn1_hi = 4;
1095 egprs3->bsn1_lo = 0;
1096 egprs3->cps_hi = 1;
1097 data_msg[3] = 0xff;
1098 egprs3->pi = 0;
1099 egprs3->cps_lo = 1;
1100 egprs3->rsb = 0;
1101 egprs3->spb = 2;
1102 egprs3->pi = 0;
1103
1104 pdch->rcv_block(data_msg, 42, *fn, &meas);
1105
1106 block = ul_tbf->m_rlc.block(4);
1107 /* check the status of the block */
1108 OSMO_ASSERT(block->spb_status.block_status_ul ==
1109 EGPRS_RESEG_FIRST_SEG_RXD);
1110
Maxbea2edb2019-03-06 17:04:59 +01001111 cs = MCS3;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301112 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1113 egprs3->si = 1;
1114 egprs3->r = 1;
1115 egprs3->cv = 7;
1116 egprs3->tfi_hi = tfi & 0x03;
1117 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1118 egprs3->bsn1_hi = 4;
1119 egprs3->bsn1_lo = 0;
1120 egprs3->cps_hi = 1;
1121 data_msg[3] = 0xff;
1122 egprs3->pi = 0;
1123 egprs3->cps_lo = 1;
1124 egprs3->rsb = 0;
1125 egprs3->spb = 2;
1126 egprs3->pi = 0;
1127
1128 pdch->rcv_block(data_msg, 42, *fn, &meas);
1129
1130 block = ul_tbf->m_rlc.block(4);
1131 /* check the status of the block */
1132 OSMO_ASSERT(block->spb_status.block_status_ul ==
1133 EGPRS_RESEG_FIRST_SEG_RXD);
1134
Maxbea2edb2019-03-06 17:04:59 +01001135 cs = MCS3;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301136 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1137 egprs3->si = 1;
1138 egprs3->r = 1;
1139 egprs3->cv = 7;
1140 egprs3->tfi_hi = tfi & 0x03;
1141 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1142 egprs3->bsn1_hi = 4;
1143 egprs3->bsn1_lo = 0;
1144 egprs3->cps_hi = 1;
1145 data_msg[3] = 0xff;
1146 egprs3->pi = 0;
1147 egprs3->cps_lo = 1;
1148 egprs3->rsb = 0;
1149 egprs3->spb = 3;
1150 egprs3->pi = 0;
1151
1152 pdch->rcv_block(data_msg, 42, *fn, &meas);
1153
1154 block = ul_tbf->m_rlc.block(4);
1155 /* check the status of the block */
1156 OSMO_ASSERT(block->spb_status.block_status_ul ==
1157 EGPRS_RESEG_DEFAULT);
1158 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001159 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301160 /* Assembled MCS is MCS6. so the size is 74 */
1161 OSMO_ASSERT(block->len == 74);
1162
Maxbea2edb2019-03-06 17:04:59 +01001163 cs = MCS3;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301164 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1165 egprs3->si = 1;
1166 egprs3->r = 1;
1167 egprs3->cv = 7;
1168 egprs3->tfi_hi = tfi & 0x03;
1169 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1170 egprs3->bsn1_hi = 5;
1171 egprs3->bsn1_lo = 0;
1172 egprs3->cps_hi = 1;
1173 data_msg[3] = 0xff;
1174 egprs3->pi = 0;
1175 egprs3->cps_lo = 1;
1176 egprs3->rsb = 0;
1177 egprs3->spb = 3;
1178 egprs3->pi = 0;
1179
1180 pdch->rcv_block(data_msg, 42, *fn, &meas);
1181
1182 block = ul_tbf->m_rlc.block(5);
1183 /* check the status of the block */
1184 OSMO_ASSERT(block->spb_status.block_status_ul ==
1185 EGPRS_RESEG_SECOND_SEG_RXD);
1186
Maxbea2edb2019-03-06 17:04:59 +01001187 cs = MCS3;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301188 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1189 egprs3->si = 1;
1190 egprs3->r = 1;
1191 egprs3->cv = 7;
1192 egprs3->tfi_hi = tfi & 0x03;
1193 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1194 egprs3->bsn1_hi = 5;
1195 egprs3->bsn1_lo = 0;
1196 egprs3->cps_hi = 1;
1197 data_msg[3] = 0xff;
1198 egprs3->pi = 0;
1199 egprs3->cps_lo = 1;
1200 egprs3->rsb = 0;
1201 egprs3->spb = 2;
1202 egprs3->pi = 0;
1203
1204 pdch->rcv_block(data_msg, 42, *fn, &meas);
1205
1206 block = ul_tbf->m_rlc.block(5);
1207
1208 /* check the status of the block */
1209 OSMO_ASSERT(block->spb_status.block_status_ul ==
1210 EGPRS_RESEG_DEFAULT);
1211 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001212 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301213 /* Assembled MCS is MCS6. so the size is 74 */
1214 OSMO_ASSERT(block->len == 74);
1215
1216 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->len ==
1217 ul_tbf->m_rlc.block(4)->len);
1218 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->len ==
1219 ul_tbf->m_rlc.block(3)->len);
1220
1221 /* Compare the spb status of each BSNs(3,4,5). should be same */
1222 OSMO_ASSERT(
1223 ul_tbf->m_rlc.block(5)->spb_status.block_status_ul ==
1224 ul_tbf->m_rlc.block(4)->spb_status.block_status_ul);
1225 OSMO_ASSERT(
1226 ul_tbf->m_rlc.block(5)->spb_status.block_status_ul ==
1227 ul_tbf->m_rlc.block(3)->spb_status.block_status_ul);
1228
1229 /* Compare the Assembled MCS of each BSNs(3,4,5). should be same */
1230 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->cs_last ==
1231 ul_tbf->m_rlc.block(4)->cs_last);
1232 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->cs_last ==
1233 ul_tbf->m_rlc.block(3)->cs_last);
1234
1235 /* Compare the data of each BSNs(3,4,5). should be same */
1236 OSMO_ASSERT(
1237 !memcmp(ul_tbf->m_rlc.block(5)->block,
1238 ul_tbf->m_rlc.block(4)->block, ul_tbf->m_rlc.block(5)->len
1239 ));
1240 OSMO_ASSERT(
1241 !memcmp(ul_tbf->m_rlc.block(5)->block,
1242 ul_tbf->m_rlc.block(3)->block, ul_tbf->m_rlc.block(5)->len
1243 ));
1244
1245 return ul_tbf;
1246}
1247
sivasankari1d8744c2017-01-24 15:53:35 +05301248static gprs_rlcmac_ul_tbf *establish_ul_tbf(BTS *the_bts,
1249 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1250 uint8_t ms_class, uint8_t egprs_ms_class)
1251{
sivasankari1d8744c2017-01-24 15:53:35 +05301252 uint32_t rach_fn = *fn - 51;
1253 uint32_t sba_fn = *fn + 52;
1254 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001255 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301256 gprs_rlcmac_ul_tbf *ul_tbf;
sivasankari1d8744c2017-01-24 15:53:35 +05301257 gprs_rlcmac_bts *bts;
1258 RlcMacUplink_t ulreq = {0};
1259 struct pcu_l1_meas meas;
sivasankari1d8744c2017-01-24 15:53:35 +05301260 GprsCodingScheme cs;
1261
1262 meas.set_rssi(31);
1263 bts = the_bts->bts_data();
1264
1265 /* needed to set last_rts_fn in the PDCH object */
1266 request_dl_rlc_block(bts, trx_no, ts_no, fn);
1267
1268 /*
1269 * simulate RACH, this sends an Immediate
1270 * Assignment Uplink on the AGCH
1271 */
1272 the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0);
1273
1274 /* get next free TFI */
1275 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
1276
1277 /* fake a resource request */
1278 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
1279 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
1280 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
1281 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
1282 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability = 1;
1283 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1284 Count_MS_RA_capability_value = 1;
1285 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1286 MS_RA_capability_value[0].u.Content.
1287 Exist_Multislot_capability = 1;
1288 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1289 MS_RA_capability_value[0].u.Content.Multislot_capability.
1290 Exist_GPRS_multislot_class = 1;
1291 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1292 MS_RA_capability_value[0].u.Content.Multislot_capability.
1293 GPRS_multislot_class = ms_class;
1294 if (egprs_ms_class) {
1295 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1296 MS_RA_capability_value[0].u.Content.
1297 Multislot_capability.Exist_EGPRS_multislot_class = 1;
1298 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1299 MS_RA_capability_value[0].u.Content.
1300 Multislot_capability.EGPRS_multislot_class = ms_class;
1301 }
1302 send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
1303
1304 /* check the TBF */
1305 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
1306 /* send packet uplink assignment */
1307 *fn = sba_fn;
1308 request_dl_rlc_block(ul_tbf, fn);
1309
1310 /* send real acknowledgement */
1311 send_control_ack(ul_tbf);
1312
1313 check_tbf(ul_tbf);
1314
1315 return ul_tbf;
1316}
1317
1318static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_no_length(BTS *the_bts,
1319 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1320 uint8_t ms_class, uint8_t egprs_ms_class, gprs_rlcmac_ul_tbf *ul_tbf)
1321{
1322 OSMO_ASSERT(ul_tbf);
1323 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1324 GprsMs *ms;
sivasankari1d8744c2017-01-24 15:53:35 +05301325 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001326 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301327 struct gprs_rlcmac_pdch *pdch;
sivasankari1d8744c2017-01-24 15:53:35 +05301328 struct pcu_l1_meas meas;
sivasankari1d8744c2017-01-24 15:53:35 +05301329 GprsCodingScheme cs;
1330
1331
1332 /* send fake data with cv=0*/
1333 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1334 uint8_t data[49] = {0};
1335
1336 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1337
1338 /*header_construction */
1339 memset(data, 0x2b, sizeof(data));
1340 /* Message with CRBB */
1341 for (int i = 0 ; i < 80; i++) {
1342 hdr3->r = 0;
1343 hdr3->si = 0;
1344 hdr3->cv = 10;
1345 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1346 hdr3->tfi_lo = tfi & 0x7;
1347 hdr3->bsn1_hi = ((i * 2)&0x1f);
1348 hdr3->bsn1_lo = ((i * 2)/32);
1349 hdr3->cps_hi = 0;
1350 hdr3->cps_lo = 0;
1351 hdr3->spb = 0;
1352 hdr3->rsb = 0;
1353 hdr3->pi = 0;
1354 hdr3->spare = 0;
1355 hdr3->dummy = 1;
1356 data[4] = 0x0;
1357 data[5] = 0x0;
1358 data[6] = 0x2b;
1359 data[7] = 0x2b;
1360 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
1361 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1362 }
1363 ul_tbf->create_ul_ack(*fn, ts_no);
1364 memset(data, 0x2b, sizeof(data));
1365 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1366 hdr3->r = 0;
1367 hdr3->si = 0;
1368 hdr3->cv = 0;
1369 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1370 hdr3->tfi_lo = tfi & 0x7;
1371 hdr3->bsn1_hi = 0;
1372 hdr3->bsn1_lo = 2;
1373 hdr3->cps_hi = 0;
1374 hdr3->cps_lo = 0;
1375 hdr3->spb = 0;
1376 hdr3->rsb = 0;
1377 hdr3->pi = 0;
1378 hdr3->spare = 0;
1379 hdr3->dummy = 1;
1380 data[4] = 0x0;
1381 data[5] = 0x2b;
1382 data[6] = 0x2b;
1383 data[7] = 0x2b;
1384
1385 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
1386 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1387
1388 request_dl_rlc_block(ul_tbf, fn);
1389
1390 check_tbf(ul_tbf);
Max088c7df2018-01-23 20:16:23 +01001391 OSMO_ASSERT(ul_tbf->ul_ack_state_is(GPRS_RLCMAC_UL_ACK_NONE));
sivasankari1d8744c2017-01-24 15:53:35 +05301392
1393 ms = the_bts->ms_by_tlli(tlli);
1394 OSMO_ASSERT(ms != NULL);
1395 OSMO_ASSERT(ms->ta() == qta/4);
1396 OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
1397
1398 return ul_tbf;
1399}
1400
1401static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_with_length(BTS *the_bts,
1402 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1403 uint8_t ms_class, uint8_t egprs_ms_class, gprs_rlcmac_ul_tbf *ul_tbf)
1404{
1405 OSMO_ASSERT(ul_tbf);
1406 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1407 GprsMs *ms;
sivasankari1d8744c2017-01-24 15:53:35 +05301408 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001409 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301410 struct gprs_rlcmac_pdch *pdch;
sivasankari1d8744c2017-01-24 15:53:35 +05301411 struct pcu_l1_meas meas;
sivasankari1d8744c2017-01-24 15:53:35 +05301412 GprsCodingScheme cs;
1413
1414 check_tbf(ul_tbf);
1415 /* send fake data with cv=0*/
1416 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1417 uint8_t data[49] = {0};
1418
1419 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1420
1421 /*header_construction */
1422 memset(data, 0x2b, sizeof(data));
1423
1424 /* Message with URBB & URBB length */
1425 for (int i = 0 ; i < 20; i++) {
1426 hdr3->r = 0;
1427 hdr3->si = 0;
1428 hdr3->cv = 10;
1429 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1430 hdr3->tfi_lo = tfi & 0x7;
1431 hdr3->bsn1_hi = ((i * 2)&0x1f);
1432 hdr3->bsn1_lo = ((i * 2)/32);
1433 hdr3->cps_hi = 0;
1434 hdr3->cps_lo = 0;
1435 hdr3->spb = 0;
1436 hdr3->rsb = 0;
1437 hdr3->pi = 0;
1438 hdr3->spare = 0;
1439 hdr3->dummy = 1;
1440 data[4] = 0x0;
1441 data[5] = 0x0;
1442 data[6] = 0x2b;
1443 data[7] = 0x2b;
1444 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
1445 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1446 }
1447 ul_tbf->create_ul_ack(*fn, ts_no);
1448 memset(data, 0x2b, sizeof(data));
1449 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1450 hdr3->r = 0;
1451 hdr3->si = 0;
1452 hdr3->cv = 0;
1453 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1454 hdr3->tfi_lo = tfi & 0x7;
1455 hdr3->bsn1_hi = 0;
1456 hdr3->bsn1_lo = 2;
1457 hdr3->cps_hi = 0;
1458 hdr3->cps_lo = 0;
1459 hdr3->spb = 0;
1460 hdr3->rsb = 0;
1461 hdr3->pi = 0;
1462 hdr3->spare = 0;
1463 hdr3->dummy = 1;
1464 data[4] = 0x0;
1465 data[5] = 0x2b;
1466 data[6] = 0x2b;
1467 data[7] = 0x2b;
1468
1469 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
1470 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1471
1472 request_dl_rlc_block(ul_tbf, fn);
1473
1474 check_tbf(ul_tbf);
Max088c7df2018-01-23 20:16:23 +01001475 OSMO_ASSERT(ul_tbf->ul_ack_state_is(GPRS_RLCMAC_UL_ACK_NONE));
sivasankari1d8744c2017-01-24 15:53:35 +05301476
1477 ms = the_bts->ms_by_tlli(tlli);
1478 OSMO_ASSERT(ms != NULL);
1479 OSMO_ASSERT(ms->ta() == qta/4);
1480 OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
1481
1482 return ul_tbf;
1483}
1484
1485static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_CRBB(BTS *the_bts,
1486 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1487 uint8_t ms_class, uint8_t egprs_ms_class)
1488{
1489 GprsMs *ms;
sivasankari1d8744c2017-01-24 15:53:35 +05301490 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001491 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301492 gprs_rlcmac_ul_tbf *ul_tbf;
1493 struct gprs_rlcmac_pdch *pdch;
sivasankari1d8744c2017-01-24 15:53:35 +05301494 struct pcu_l1_meas meas;
sivasankari1d8744c2017-01-24 15:53:35 +05301495 GprsCodingScheme cs;
1496
1497
1498 /* check the TBF */
1499 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
1500 OSMO_ASSERT(ul_tbf);
1501 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1502
1503 /* send fake data with cv=0*/
1504 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1505 uint8_t data[49] = {0};
1506
1507 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1508
1509 /*header_construction */
1510 memset(data, 0x2b, sizeof(data));
1511
1512 /* Message with CRBB */
1513 for (int i = 80 ; i < 160; i++) {
1514 hdr3->r = 0;
1515 hdr3->si = 0;
1516 hdr3->cv = 10;
1517 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1518 hdr3->tfi_lo = tfi & 0x7;
1519 hdr3->bsn1_hi = ((i)&0x1f);
1520 hdr3->bsn1_lo = ((i)/32);
1521 hdr3->cps_hi = 0;
1522 hdr3->cps_lo = 0;
1523 hdr3->spb = 0;
1524 hdr3->rsb = 0;
1525 hdr3->pi = 0;
1526 hdr3->spare = 0;
1527 hdr3->dummy = 1;
1528 data[4] = 0x0;
1529 data[5] = 0x0;
1530 data[6] = 0x2b;
1531 data[7] = 0x2b;
1532 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
1533 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1534 }
1535 ul_tbf->create_ul_ack(*fn, ts_no);
1536 memset(data, 0x2b, sizeof(data));
1537 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1538 hdr3->r = 0;
1539 hdr3->si = 0;
1540 hdr3->cv = 0;
1541 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1542 hdr3->tfi_lo = tfi & 0x7;
1543 hdr3->bsn1_hi = 0;
1544 hdr3->bsn1_lo = 2;
1545 hdr3->cps_hi = 0;
1546 hdr3->cps_lo = 0;
1547 hdr3->spb = 0;
1548 hdr3->rsb = 0;
1549 hdr3->pi = 0;
1550 hdr3->spare = 0;
1551 hdr3->dummy = 1;
1552 data[4] = 0x0;
1553 data[5] = 0x2b;
1554 data[6] = 0x2b;
1555 data[7] = 0x2b;
1556
1557 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
1558 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1559
1560 request_dl_rlc_block(ul_tbf, fn);
1561
1562 check_tbf(ul_tbf);
Max088c7df2018-01-23 20:16:23 +01001563 OSMO_ASSERT(ul_tbf->ul_ack_state_is(GPRS_RLCMAC_UL_ACK_NONE));
sivasankari1d8744c2017-01-24 15:53:35 +05301564
1565 ms = the_bts->ms_by_tlli(tlli);
1566 OSMO_ASSERT(ms != NULL);
1567 OSMO_ASSERT(ms->ta() == qta/4);
1568 OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
1569
1570 return ul_tbf;
1571}
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001572static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase(BTS *the_bts,
1573 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001574 uint8_t ms_class, uint8_t egprs_ms_class)
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001575{
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001576 GprsMs *ms;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001577 uint32_t rach_fn = *fn - 51;
1578 uint32_t sba_fn = *fn + 52;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001579 uint8_t trx_no = 0;
1580 int tfi = 0;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001581 gprs_rlcmac_ul_tbf *ul_tbf;
1582 struct gprs_rlcmac_pdch *pdch;
1583 gprs_rlcmac_bts *bts;
1584 RlcMacUplink_t ulreq = {0};
Jacob Erlbeck20f6fd12015-06-08 11:05:45 +02001585 struct pcu_l1_meas meas;
1586 meas.set_rssi(31);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001587
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001588 bts = the_bts->bts_data();
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001589
1590 /* needed to set last_rts_fn in the PDCH object */
Max878bd1f2016-07-20 13:05:05 +02001591 request_dl_rlc_block(bts, trx_no, ts_no, fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001592
bhargava959d1de2016-08-17 15:17:21 +05301593 /* simulate RACH, sends an Immediate Assignment Uplink on the AGCH */
1594 the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001595
1596 /* get next free TFI */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001597 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001598
1599 /* fake a resource request */
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001600 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
1601 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
1602 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
1603 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001604 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability = 1;
1605 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1606 Count_MS_RA_capability_value = 1;
1607 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1608 MS_RA_capability_value[0].u.Content.Exist_Multislot_capability = 1;
1609 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1610 MS_RA_capability_value[0].u.Content.Multislot_capability.
1611 Exist_GPRS_multislot_class = 1;
1612 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1613 MS_RA_capability_value[0].u.Content.Multislot_capability.
1614 GPRS_multislot_class = ms_class;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001615 if (egprs_ms_class) {
1616 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1617 MS_RA_capability_value[0].u.Content.Multislot_capability.
1618 Exist_EGPRS_multislot_class = 1;
1619 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
1620 MS_RA_capability_value[0].u.Content.Multislot_capability.
1621 EGPRS_multislot_class = ms_class;
1622 }
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001623
Jacob Erlbeck56f99d12015-08-20 15:55:56 +02001624 send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001625
1626 /* check the TBF */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001627 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001628 OSMO_ASSERT(ul_tbf != NULL);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +02001629 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001630
1631 /* send packet uplink assignment */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001632 *fn = sba_fn;
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +02001633 request_dl_rlc_block(ul_tbf, fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001634
Jacob Erlbeckaf454732015-08-21 15:03:23 +02001635 /* send real acknowledgement */
1636 send_control_ack(ul_tbf);
1637
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001638 check_tbf(ul_tbf);
1639
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001640 /* send fake data */
1641 uint8_t data_msg[23] = {
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001642 0x00 | 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
1643 uint8_t(0 | (tfi << 1)),
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001644 uint8_t(1), /* BSN:7, E:1 */
1645 };
1646
Jacob Erlbeck56f99d12015-08-20 15:55:56 +02001647 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001648 pdch->rcv_block(&data_msg[0], sizeof(data_msg), *fn, &meas);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001649
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001650 ms = the_bts->ms_by_tlli(tlli);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001651 OSMO_ASSERT(ms != NULL);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +02001652 OSMO_ASSERT(ms->ta() == qta/4);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001653 OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
1654
1655 return ul_tbf;
1656}
1657
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001658static void send_dl_data(BTS *the_bts, uint32_t tlli, const char *imsi,
1659 const uint8_t *data, unsigned data_size)
1660{
1661 GprsMs *ms, *ms2;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001662
1663 ms = the_bts->ms_store().get_ms(tlli, 0, imsi);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001664
Jacob Erlbeck14e00f82015-11-27 18:10:39 +01001665 gprs_rlcmac_dl_tbf::handle(the_bts->bts_data(), tlli, 0, imsi, 0, 0,
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001666 1000, data, data_size);
1667
1668 ms = the_bts->ms_by_imsi(imsi);
1669 OSMO_ASSERT(ms != NULL);
1670 OSMO_ASSERT(ms->dl_tbf() != NULL);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001671
1672 if (imsi[0] && strcmp(imsi, "000") != 0) {
1673 ms2 = the_bts->ms_by_tlli(tlli);
1674 OSMO_ASSERT(ms == ms2);
1675 }
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001676}
1677
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001678static void transmit_dl_data(BTS *the_bts, uint32_t tlli, uint32_t *fn,
1679 uint8_t slots = 0xff)
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001680{
1681 gprs_rlcmac_dl_tbf *dl_tbf;
1682 GprsMs *ms;
1683 unsigned ts_no;
1684
1685 ms = the_bts->ms_by_tlli(tlli);
1686 OSMO_ASSERT(ms);
1687 dl_tbf = ms->dl_tbf();
1688 OSMO_ASSERT(dl_tbf);
1689
1690 while (dl_tbf->have_data()) {
1691 uint8_t bn = fn2bn(*fn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001692 for (ts_no = 0 ; ts_no < 8; ts_no += 1) {
1693 if (!(slots & (1 << ts_no)))
1694 continue;
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001695 gprs_rlcmac_rcv_rts_block(the_bts->bts_data(),
Max878bd1f2016-07-20 13:05:05 +02001696 dl_tbf->trx->trx_no, ts_no,
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001697 *fn, bn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001698 }
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001699 *fn = fn_add_blocks(*fn, 1);
1700 }
1701}
1702
Max4c112dc2018-02-01 16:49:23 +01001703static inline void print_ta_tlli(const gprs_rlcmac_ul_tbf *ul_tbf, bool print_ms)
1704{
1705 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
1706 if (print_ms)
1707 fprintf(stderr, "Got MS: TLLI = 0x%08x, TA = %d\n", ul_tbf->ms()->tlli(), ul_tbf->ms()->ta());
1708}
1709
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001710static void test_tbf_single_phase()
1711{
1712 BTS the_bts;
1713 int ts_no = 7;
Philippd935d882016-11-07 13:07:36 +01001714 uint32_t fn = DUMMY_FN; /* 17,25,9 */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001715 uint32_t tlli = 0xf1223344;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001716 const char *imsi = "0011223344";
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001717 uint16_t qta = 31;
1718 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001719
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001720 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001721
1722 setup_bts(&the_bts, ts_no);
1723
1724 ul_tbf = establish_ul_tbf_single_phase(&the_bts, ts_no, tlli, &fn, qta);
1725
Max4c112dc2018-02-01 16:49:23 +01001726 print_ta_tlli(ul_tbf, true);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001727 send_dl_data(&the_bts, tlli, imsi, (const uint8_t *)"TEST", 4);
1728
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001729 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001730}
1731
sivasankari1d8744c2017-01-24 15:53:35 +05301732static void test_tbf_egprs_two_phase_puan(void)
1733{
1734 BTS the_bts;
1735 int ts_no = 7;
1736 uint32_t fn = 2654218;
1737 uint16_t qta = 31;
1738 uint32_t tlli = 0xf1223344;
1739 const char *imsi = "0011223344";
1740 uint8_t ms_class = 1;
1741 gprs_rlcmac_bts *bts;
1742 uint8_t egprs_ms_class = 1;
1743 gprs_rlcmac_ul_tbf *ul_tbf;
sivasankari1d8744c2017-01-24 15:53:35 +05301744 uint8_t test_data[256];
1745
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001746 fprintf(stderr, "=== start %s ===\n", __func__);
sivasankari1d8744c2017-01-24 15:53:35 +05301747
1748 memset(test_data, 1, sizeof(test_data));
1749
1750 setup_bts(&the_bts, ts_no, 4);
1751 the_bts.bts_data()->initial_mcs_dl = 9;
1752 the_bts.bts_data()->egprs_enabled = 1;
1753 bts = the_bts.bts_data();
1754 bts->ws_base = 128;
1755 bts->ws_pdch = 64;
1756
1757 ul_tbf = establish_ul_tbf(&the_bts, ts_no, tlli, &fn, qta, ms_class, egprs_ms_class);
1758 /* Function to generate URBB with no length */
1759 ul_tbf = establish_ul_tbf_two_phase_puan_URBB_no_length(&the_bts, ts_no, tlli, &fn,
1760 qta, ms_class, egprs_ms_class, ul_tbf);
1761
Max4c112dc2018-02-01 16:49:23 +01001762 print_ta_tlli(ul_tbf, true);
sivasankari1d8744c2017-01-24 15:53:35 +05301763 send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data));
1764
Maxea98b7d2018-01-04 15:13:27 +01001765 ul_tbf->window()->reset_state();
sivasankari1d8744c2017-01-24 15:53:35 +05301766 /* Function to generate URBB with length */
1767 ul_tbf = establish_ul_tbf_two_phase_puan_URBB_with_length(&the_bts, ts_no, tlli, &fn,
1768 qta, ms_class, egprs_ms_class, ul_tbf);
1769
Max4c112dc2018-02-01 16:49:23 +01001770 print_ta_tlli(ul_tbf, true);
sivasankari1d8744c2017-01-24 15:53:35 +05301771 send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data));
1772
Maxea98b7d2018-01-04 15:13:27 +01001773 ul_tbf->window()->reset_state();
sivasankari1d8744c2017-01-24 15:53:35 +05301774 /* Function to generate CRBB */
1775 bts->ws_base = 128;
1776 bts->ws_pdch = 64;
1777 ul_tbf = establish_ul_tbf_two_phase_puan_CRBB(&the_bts, ts_no, tlli, &fn,
1778 qta, ms_class, egprs_ms_class);
1779
Max4c112dc2018-02-01 16:49:23 +01001780 print_ta_tlli(ul_tbf, true);
sivasankari1d8744c2017-01-24 15:53:35 +05301781 send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data));
1782
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001783 fprintf(stderr, "=== end %s ===\n", __func__);
sivasankari1d8744c2017-01-24 15:53:35 +05301784}
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301785/*
1786 * Trigger rach for single block
1787 */
1788static void test_immediate_assign_rej_single_block()
1789{
1790 BTS the_bts;
1791 uint32_t fn = 2654218;
1792 uint16_t qta = 31;
1793 int ts_no = 7;
1794
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001795 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301796
1797 setup_bts(&the_bts, ts_no, 4);
1798
1799 the_bts.bts_data()->trx[0].pdch[ts_no].disable();
1800
1801 uint32_t rach_fn = fn - 51;
1802
1803 int rc = 0;
1804
1805 /*
1806 * simulate RACH, sends an Immediate Assignment
1807 * Uplink reject on the AGCH
1808 */
1809 rc = the_bts.rcv_rach(0x70, rach_fn, qta, 0,
1810 GSM_L1_BURST_TYPE_ACCESS_0);
1811
1812 OSMO_ASSERT(rc == -EINVAL);
1813
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001814 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301815}
1816
1817/*
1818 * Trigger rach till resources(USF) exhaust
1819 */
1820static void test_immediate_assign_rej_multi_block()
1821{
1822 BTS the_bts;
1823 uint32_t fn = 2654218;
1824 uint16_t qta = 31;
1825 int ts_no = 7;
1826
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001827 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301828
1829 setup_bts(&the_bts, ts_no, 4);
1830
1831 uint32_t rach_fn = fn - 51;
1832
1833 int rc = 0;
1834
1835 /*
1836 * simulate RACH, sends an Immediate Assignment Uplink
1837 * reject on the AGCH
1838 */
1839 rc = the_bts.rcv_rach(0x78, rach_fn, qta, 0,
1840 GSM_L1_BURST_TYPE_ACCESS_0);
1841 rc = the_bts.rcv_rach(0x79, rach_fn, qta, 0,
1842 GSM_L1_BURST_TYPE_ACCESS_0);
1843 rc = the_bts.rcv_rach(0x7a, rach_fn, qta, 0,
1844 GSM_L1_BURST_TYPE_ACCESS_0);
1845 rc = the_bts.rcv_rach(0x7b, rach_fn, qta, 0,
1846 GSM_L1_BURST_TYPE_ACCESS_0);
1847 rc = the_bts.rcv_rach(0x7c, rach_fn, qta, 0,
1848 GSM_L1_BURST_TYPE_ACCESS_0);
1849 rc = the_bts.rcv_rach(0x7d, rach_fn, qta, 0,
1850 GSM_L1_BURST_TYPE_ACCESS_0);
1851 rc = the_bts.rcv_rach(0x7e, rach_fn, qta, 0,
1852 GSM_L1_BURST_TYPE_ACCESS_0);
1853 rc = the_bts.rcv_rach(0x7f, rach_fn, qta, 0,
1854 GSM_L1_BURST_TYPE_ACCESS_0);
1855
1856 OSMO_ASSERT(rc == -EBUSY);
1857
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001858 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301859}
1860
1861static void test_immediate_assign_rej()
1862{
1863 test_immediate_assign_rej_multi_block();
1864 test_immediate_assign_rej_single_block();
1865}
1866
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001867static void test_tbf_two_phase()
1868{
1869 BTS the_bts;
1870 int ts_no = 7;
1871 uint32_t fn = 2654218;
1872 uint16_t qta = 31;
1873 uint32_t tlli = 0xf1223344;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001874 const char *imsi = "0011223344";
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001875 uint8_t ms_class = 1;
1876 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001877
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001878 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001879
1880 setup_bts(&the_bts, ts_no, 4);
1881
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001882 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli, &fn, qta,
1883 ms_class, 0);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001884
Max4c112dc2018-02-01 16:49:23 +01001885 print_ta_tlli(ul_tbf, true);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001886 send_dl_data(&the_bts, tlli, imsi, (const uint8_t *)"TEST", 4);
1887
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001888 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001889}
1890
Max4c112dc2018-02-01 16:49:23 +01001891static inline void print_ms(const GprsMs *ms, bool old)
1892{
1893 fprintf(stderr, "%s MS: TLLI = 0x%08x, TA = %d, IMSI = %s, LLC = %zu\n",
1894 old ? "Old" : "New", ms->tlli(), ms->ta(), ms->imsi(), ms->llc_queue()->size());
1895}
1896
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001897static void test_tbf_ra_update_rach()
1898{
1899 BTS the_bts;
1900 int ts_no = 7;
1901 uint32_t fn = 2654218;
1902 uint16_t qta = 31;
1903 uint32_t tlli1 = 0xf1223344;
1904 uint32_t tlli2 = 0xf5667788;
1905 const char *imsi = "0011223344";
1906 uint8_t ms_class = 1;
1907 gprs_rlcmac_ul_tbf *ul_tbf;
1908 GprsMs *ms, *ms1, *ms2;
1909
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001910 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001911
1912 setup_bts(&the_bts, ts_no, 4);
1913
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001914 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli1, &fn, qta,
1915 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001916
1917 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01001918 print_ta_tlli(ul_tbf, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001919
1920 send_dl_data(&the_bts, tlli1, imsi, (const uint8_t *)"RAU_ACCEPT", 10);
Max4c112dc2018-02-01 16:49:23 +01001921 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001922
Jacob Erlbeckaf454732015-08-21 15:03:23 +02001923 /* Send Packet Downlink Assignment to MS */
1924 request_dl_rlc_block(ul_tbf, &fn);
1925
1926 /* Ack it */
1927 send_control_ack(ul_tbf);
1928
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001929 /* Make sure the RAU Accept gets sent to the MS */
1930 OSMO_ASSERT(ms1->llc_queue()->size() == 1);
1931 transmit_dl_data(&the_bts, tlli1, &fn);
1932 OSMO_ASSERT(ms1->llc_queue()->size() == 0);
1933
1934 /* Now establish a new TBF for the RA UPDATE COMPLETE (new TLLI) */
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001935 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli2, &fn, qta,
1936 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001937
1938 ms2 = ul_tbf->ms();
1939
1940 /* The PCU cannot know yet, that both TBF belong to the same MS */
1941 OSMO_ASSERT(ms1 != ms2);
Max4c112dc2018-02-01 16:49:23 +01001942 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001943
1944 /* Send some downlink data along with the new TLLI and the IMSI so that
1945 * the PCU can see, that both MS objects belong to same MS */
1946 send_dl_data(&the_bts, tlli2, imsi, (const uint8_t *)"DATA", 4);
1947
1948 ms = the_bts.ms_by_imsi(imsi);
1949 OSMO_ASSERT(ms == ms2);
1950
Max4c112dc2018-02-01 16:49:23 +01001951 print_ms(ms2, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001952
1953 ms = the_bts.ms_by_tlli(tlli1);
1954 OSMO_ASSERT(ms == NULL);
1955 ms = the_bts.ms_by_tlli(tlli2);
1956 OSMO_ASSERT(ms == ms2);
1957
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001958 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001959}
1960
1961static void test_tbf_dl_flow_and_rach_two_phase()
1962{
1963 BTS the_bts;
1964 int ts_no = 7;
1965 uint32_t fn = 2654218;
1966 uint16_t qta = 31;
1967 uint32_t tlli1 = 0xf1223344;
1968 const char *imsi = "0011223344";
1969 uint8_t ms_class = 1;
1970 gprs_rlcmac_ul_tbf *ul_tbf;
1971 gprs_rlcmac_dl_tbf *dl_tbf;
1972 GprsMs *ms, *ms1, *ms2;
1973
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001974 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001975
1976 setup_bts(&the_bts, ts_no, 1);
1977
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001978 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli1, &fn, qta,
1979 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001980
1981 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01001982 print_ta_tlli(ul_tbf, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001983
1984 send_dl_data(&the_bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);
1985 send_dl_data(&the_bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);
Max4c112dc2018-02-01 16:49:23 +01001986 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001987
1988 OSMO_ASSERT(ms1->llc_queue()->size() == 2);
1989 dl_tbf = ms1->dl_tbf();
1990 OSMO_ASSERT(dl_tbf != NULL);
1991
1992 /* Get rid of old UL TBF */
1993 tbf_free(ul_tbf);
1994 ms = the_bts.ms_by_tlli(tlli1);
1995 OSMO_ASSERT(ms1 == ms);
1996
1997 /* Now establish a new UL TBF, this will consume one LLC packet */
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001998 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli1, &fn, qta,
1999 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002000
2001 ms2 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002002 print_ms(ms2, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002003
2004 /* This should be the same MS object */
2005 OSMO_ASSERT(ms2 == ms1);
2006
2007 ms = the_bts.ms_by_tlli(tlli1);
2008 OSMO_ASSERT(ms2 == ms);
2009
Jacob Erlbeckc8cbfc22015-09-01 11:38:40 +02002010 /* A DL TBF should still exist */
2011 OSMO_ASSERT(ms->dl_tbf());
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002012
2013 /* No queued packets should be lost */
Jacob Erlbeck9659d592015-09-01 11:06:14 +02002014 OSMO_ASSERT(ms->llc_queue()->size() == 2);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002015
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002016 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002017}
2018
2019
2020static void test_tbf_dl_flow_and_rach_single_phase()
2021{
2022 BTS the_bts;
2023 int ts_no = 7;
2024 uint32_t fn = 2654218;
2025 uint16_t qta = 31;
2026 uint32_t tlli1 = 0xf1223344;
2027 const char *imsi = "0011223344";
2028 uint8_t ms_class = 1;
2029 gprs_rlcmac_ul_tbf *ul_tbf;
2030 gprs_rlcmac_dl_tbf *dl_tbf;
2031 GprsMs *ms, *ms1, *ms2;
2032
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002033 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002034
2035 setup_bts(&the_bts, ts_no, 1);
2036
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002037 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli1, &fn, qta,
2038 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002039
2040 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002041 print_ta_tlli(ul_tbf, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002042
2043 send_dl_data(&the_bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);
2044 send_dl_data(&the_bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);
Max4c112dc2018-02-01 16:49:23 +01002045 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002046
2047 OSMO_ASSERT(ms1->llc_queue()->size() == 2);
2048 dl_tbf = ms1->dl_tbf();
2049 OSMO_ASSERT(dl_tbf != NULL);
2050
2051 /* Get rid of old UL TBF */
2052 tbf_free(ul_tbf);
2053 ms = the_bts.ms_by_tlli(tlli1);
2054 OSMO_ASSERT(ms1 == ms);
2055
2056 /* Now establish a new UL TBF */
2057 ul_tbf = establish_ul_tbf_single_phase(&the_bts, ts_no, tlli1, &fn, qta);
2058
2059 ms2 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002060 print_ms(ms2, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002061
2062 /* There should be a different MS object */
2063 OSMO_ASSERT(ms2 != ms1);
2064
2065 ms = the_bts.ms_by_tlli(tlli1);
2066 OSMO_ASSERT(ms2 == ms);
2067 OSMO_ASSERT(ms1 != ms);
2068
Jacob Erlbeck5f93f852016-01-21 20:48:39 +01002069 /* DL TBF should be removed */
2070 OSMO_ASSERT(!ms->dl_tbf());
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002071
2072 /* No queued packets should be lost */
Jacob Erlbeck9659d592015-09-01 11:06:14 +02002073 OSMO_ASSERT(ms->llc_queue()->size() == 2);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002074
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002075 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002076}
2077
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002078static void test_tbf_dl_reuse()
2079{
2080 BTS the_bts;
2081 int ts_no = 7;
2082 uint32_t fn = 2654218;
2083 uint16_t qta = 31;
2084 uint32_t tlli1 = 0xf1223344;
2085 const char *imsi = "0011223344";
2086 uint8_t ms_class = 1;
2087 gprs_rlcmac_ul_tbf *ul_tbf;
2088 gprs_rlcmac_dl_tbf *dl_tbf1, *dl_tbf2;
2089 GprsMs *ms1, *ms2;
2090 unsigned i;
2091 RlcMacUplink_t ulreq = {0};
2092
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002093 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002094
2095 setup_bts(&the_bts, ts_no, 1);
2096
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002097 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli1, &fn, qta,
2098 ms_class, 0);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002099
2100 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002101 print_ta_tlli(ul_tbf, false);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002102
2103 /* Send some LLC frames */
2104 for (i = 0; i < 40; i++) {
2105 char buf[32];
2106 int rc;
2107
2108 rc = snprintf(buf, sizeof(buf), "LLC PACKET %02i", i);
2109 OSMO_ASSERT(rc > 0);
2110
2111 send_dl_data(&the_bts, tlli1, imsi, (const uint8_t *)buf, rc);
2112 }
2113
Max4c112dc2018-02-01 16:49:23 +01002114 print_ms(ms1, true);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002115
2116 /* Send Packet Downlink Assignment to MS */
2117 request_dl_rlc_block(ul_tbf, &fn);
2118
2119 /* Ack it */
2120 send_control_ack(ul_tbf);
2121
2122 /* Transmit all data */
2123 transmit_dl_data(&the_bts, tlli1, &fn);
2124 OSMO_ASSERT(ms1->llc_queue()->size() == 0);
2125 OSMO_ASSERT(ms1->dl_tbf());
2126 OSMO_ASSERT(ms1->dl_tbf()->state_is(GPRS_RLCMAC_FINISHED));
2127
2128 dl_tbf1 = ms1->dl_tbf();
2129
2130 /* Send some LLC frames */
2131 for (i = 0; i < 10; i++) {
2132 char buf[32];
2133 int rc;
2134
2135 rc = snprintf(buf, sizeof(buf), "LLC PACKET %02i (TBF 2)", i);
2136 OSMO_ASSERT(rc > 0);
2137
2138 send_dl_data(&the_bts, tlli1, imsi, (const uint8_t *)buf, rc);
2139 }
2140
2141 /* Fake Final DL Ack/Nack */
2142 ulreq.u.MESSAGE_TYPE = MT_PACKET_DOWNLINK_ACK_NACK;
2143 Packet_Downlink_Ack_Nack_t *ack = &ulreq.u.Packet_Downlink_Ack_Nack;
2144
2145 ack->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
2146 ack->DOWNLINK_TFI = dl_tbf1->tfi();
2147 ack->Ack_Nack_Description.FINAL_ACK_INDICATION = 1;
2148
Jacob Erlbeck8eb17142016-01-22 17:58:17 +01002149 send_ul_mac_block(&the_bts, 0, dl_tbf1->poll_ts, &ulreq, dl_tbf1->poll_fn);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002150
2151 OSMO_ASSERT(dl_tbf1->state_is(GPRS_RLCMAC_WAIT_RELEASE));
2152
2153 request_dl_rlc_block(dl_tbf1, &fn);
2154
2155 ms2 = the_bts.ms_by_tlli(tlli1);
2156 OSMO_ASSERT(ms2 == ms1);
2157 OSMO_ASSERT(ms2->dl_tbf());
Neels Hofmeyr4ea45262016-06-08 15:27:40 +02002158 OSMO_ASSERT(ms2->dl_tbf()->state_is(GPRS_RLCMAC_ASSIGN));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002159
2160 dl_tbf2 = ms2->dl_tbf();
2161
2162 OSMO_ASSERT(dl_tbf1 != dl_tbf2);
2163
2164 send_control_ack(dl_tbf1);
Jacob Erlbeck6835cea2015-08-21 15:24:02 +02002165 OSMO_ASSERT(dl_tbf2->state_is(GPRS_RLCMAC_FLOW));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002166
2167 /* Transmit all data */
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002168 transmit_dl_data(&the_bts, tlli1, &fn);
2169 OSMO_ASSERT(ms2->llc_queue()->size() == 0);
2170 OSMO_ASSERT(ms2->dl_tbf());
2171 OSMO_ASSERT(ms2->dl_tbf()->state_is(GPRS_RLCMAC_FINISHED));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002172
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002173 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002174}
2175
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002176static void test_tbf_gprs_egprs()
2177{
2178 BTS the_bts;
2179 gprs_rlcmac_bts *bts;
2180 uint8_t ts_no = 4;
2181 uint8_t ms_class = 45;
2182 int rc = 0;
2183 uint32_t tlli = 0xc0006789;
2184 const char *imsi = "001001123456789";
2185 unsigned delay_csec = 1000;
2186
2187 uint8_t buf[256] = {0};
2188
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002189 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002190
Alexander Couzens5c3783b2019-05-25 05:41:18 +02002191 bssgp_nsi = gprs_ns_instantiate(&gprs_bssgp_ns_cb, tall_pcu_ctx);
2192 if (!bssgp_nsi) {
2193 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
2194 abort();
2195 }
2196
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002197 bts = the_bts.bts_data();
2198 setup_bts(&the_bts, ts_no);
2199
2200 /* EGPRS-only */
2201 bts->egprs_enabled = 1;
2202
Maxa3ff3162019-03-11 14:40:21 +01002203 gprs_bssgp_create_and_connect(bts, 33001, 0, 33001, 3234, 3234, 3234, 1, 1, false, 0, 0, 0);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002204
2205 /* Does not support EGPRS */
2206 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
2207 delay_csec, buf, sizeof(buf));
2208
2209 OSMO_ASSERT(rc == -EBUSY);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002210 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002211
2212 gprs_bssgp_destroy();
2213}
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02002214
Max4c112dc2018-02-01 16:49:23 +01002215static inline void ws_check(gprs_rlcmac_dl_tbf *dl_tbf, const char *test, uint8_t exp_slots, uint16_t exp_ws,
2216 bool free, bool end)
2217{
2218 if (!dl_tbf) {
2219 fprintf(stderr, "%s(): FAILED (NULL TBF)\n", test);
2220 return;
2221 }
2222
2223 fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d",
2224 dl_tbf->dl_slots(),
2225 pcu_bitcount(dl_tbf->dl_slots()),
2226 dl_tbf->window_size());
2227
2228 if (pcu_bitcount(dl_tbf->dl_slots()) != exp_slots || dl_tbf->window_size() != exp_ws)
2229 fprintf(stderr, "%s(): DL TBF FAILED: dl_slots = %u (exp. %u), WS = %u (exp. %u)",
2230 test, pcu_bitcount(dl_tbf->dl_slots()), 4, dl_tbf->window_size(), 128 + 4 * 64);
2231
2232 fprintf(stderr, "\n");
2233
2234 if (free)
2235 tbf_free(dl_tbf);
2236
2237 if (end) {
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002238 fprintf(stderr, "=== end %s ===\n", test);
Max4c112dc2018-02-01 16:49:23 +01002239 gprs_bssgp_destroy();
2240 }
2241}
2242
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002243static void test_tbf_ws()
2244{
2245 BTS the_bts;
2246 gprs_rlcmac_bts *bts;
2247 uint8_t ts_no = 4;
2248 uint8_t ms_class = 12;
2249 gprs_rlcmac_dl_tbf *dl_tbf;
2250
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002251 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002252
Alexander Couzens5c3783b2019-05-25 05:41:18 +02002253 bssgp_nsi = gprs_ns_instantiate(&gprs_bssgp_ns_cb, tall_pcu_ctx);
2254 if (!bssgp_nsi) {
2255 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
2256 abort();
2257 }
2258
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002259 bts = the_bts.bts_data();
2260 setup_bts(&the_bts, ts_no);
2261
2262 bts->ws_base = 128;
2263 bts->ws_pdch = 64;
2264 bts->alloc_algorithm = alloc_algorithm_b;
2265 bts->trx[0].pdch[2].enable();
2266 bts->trx[0].pdch[3].enable();
2267 bts->trx[0].pdch[4].enable();
2268 bts->trx[0].pdch[5].enable();
2269
Maxa3ff3162019-03-11 14:40:21 +01002270 gprs_bssgp_create_and_connect(bts, 33001, 0, 33001, 4234, 4234, 4234, 1, 1, false, 0, 0, 0);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002271
2272 /* Does no support EGPRS */
Max92b7a502018-01-26 11:01:35 +01002273 dl_tbf = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, 0, false);
Max4c112dc2018-02-01 16:49:23 +01002274
2275 ws_check(dl_tbf, __func__, 4, 64, true, false);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002276
2277 /* EGPRS-only */
2278 bts->egprs_enabled = 1;
2279
2280 /* Does support EGPRS */
Max92b7a502018-01-26 11:01:35 +01002281 dl_tbf = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, ms_class, false);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002282
Max4c112dc2018-02-01 16:49:23 +01002283 ws_check(dl_tbf, __func__, 4, 128 + 4 * 64, true, true);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002284}
2285
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302286static void test_tbf_update_ws(void)
2287{
2288 BTS the_bts;
2289 gprs_rlcmac_bts *bts;
2290 uint8_t ts_no = 4;
2291 uint8_t ms_class = 11;
2292 gprs_rlcmac_dl_tbf *dl_tbf;
2293
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002294 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302295
Alexander Couzens5c3783b2019-05-25 05:41:18 +02002296 bssgp_nsi = gprs_ns_instantiate(&gprs_bssgp_ns_cb, tall_pcu_ctx);
2297 if (!bssgp_nsi) {
2298 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
2299 abort();
2300 }
2301
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302302 bts = the_bts.bts_data();
2303 setup_bts(&the_bts, ts_no);
2304
2305 bts->ws_base = 128;
2306 bts->ws_pdch = 64;
2307 bts->alloc_algorithm = alloc_algorithm_b;
2308 bts->trx[0].pdch[2].enable();
2309 bts->trx[0].pdch[3].enable();
2310 bts->trx[0].pdch[4].enable();
2311 bts->trx[0].pdch[5].enable();
2312
Maxa3ff3162019-03-11 14:40:21 +01002313 gprs_bssgp_create_and_connect(bts, 33001, 0, 33001, 5234, 5234, 5234, 1, 1, false, 0, 0, 0);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302314
2315 /* EGPRS-only */
2316 bts->egprs_enabled = 1;
2317
2318 /* Does support EGPRS */
Max92b7a502018-01-26 11:01:35 +01002319 dl_tbf = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, ms_class, true);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302320
Max4c112dc2018-02-01 16:49:23 +01002321 ws_check(dl_tbf, __func__, 1, 128 + 1 * 64, false, false);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302322
2323 dl_tbf->update();
2324
Aravind Sirsikar0ee31cf2016-09-15 17:54:46 +05302325 /* window size should be 384 */
Max4c112dc2018-02-01 16:49:23 +01002326 ws_check(dl_tbf, __func__, 4, 128 + 4 * 64, true, true);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302327}
2328
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302329static void test_tbf_puan_urbb_len(void)
2330{
2331 BTS the_bts;
2332 int ts_no = 7;
2333 uint32_t fn = 2654218;
2334 uint16_t qta = 31;
2335 uint32_t tlli = 0xf1223344;
2336 const char *imsi = "0011223344";
2337 uint8_t ms_class = 1;
2338 uint8_t egprs_ms_class = 1;
2339 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302340 uint8_t test_data[256];
2341
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002342 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302343
2344 memset(test_data, 1, sizeof(test_data));
2345
2346 setup_bts(&the_bts, ts_no, 4);
2347 the_bts.bts_data()->initial_mcs_dl = 9;
2348 the_bts.bts_data()->egprs_enabled = 1;
2349
2350 ul_tbf = puan_urbb_len_issue(&the_bts, ts_no, tlli, &fn, qta,
2351 ms_class, egprs_ms_class);
2352
Max4c112dc2018-02-01 16:49:23 +01002353 print_ta_tlli(ul_tbf, true);
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302354 send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data));
2355
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002356 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302357}
2358
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302359static gprs_rlcmac_ul_tbf *tbf_li_decoding(BTS *the_bts,
2360 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
2361 uint8_t ms_class, uint8_t egprs_ms_class)
2362{
2363 GprsMs *ms;
2364 uint32_t rach_fn = *fn - 51;
2365 uint32_t sba_fn = *fn + 52;
2366 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002367 int tfi = 0;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302368 gprs_rlcmac_ul_tbf *ul_tbf;
2369 struct gprs_rlcmac_pdch *pdch;
2370 gprs_rlcmac_bts *bts;
2371 RlcMacUplink_t ulreq = {0};
2372 struct pcu_l1_meas meas;
2373 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
2374 GprsCodingScheme cs;
2375 Packet_Resource_Request_t *presreq = NULL;
2376 MS_Radio_Access_capability_t *pmsradiocap = NULL;
2377 Multislot_capability_t *pmultislotcap = NULL;
2378
2379 meas.set_rssi(31);
2380 bts = the_bts->bts_data();
2381
2382 /* needed to set last_rts_fn in the PDCH object */
2383 request_dl_rlc_block(bts, trx_no, ts_no, fn);
2384
2385 /*
2386 * simulate RACH, this sends an Immediate
2387 * Assignment Uplink on the AGCH
2388 */
2389 the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0);
2390
2391 /* get next free TFI */
2392 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
2393
2394 /* fake a resource request */
2395 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
2396 presreq = &ulreq.u.Packet_Resource_Request;
2397 presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
2398 presreq->ID.UnionType = 1; /* != 0 */
2399 presreq->ID.u.TLLI = tlli;
2400 presreq->Exist_MS_Radio_Access_capability = 1;
2401 pmsradiocap = &presreq->MS_Radio_Access_capability;
2402 pmsradiocap->Count_MS_RA_capability_value = 1;
2403 pmsradiocap->MS_RA_capability_value[0].u.Content.
2404 Exist_Multislot_capability = 1;
2405 pmultislotcap = &pmsradiocap->MS_RA_capability_value[0].
2406 u.Content.Multislot_capability;
2407
2408 pmultislotcap->Exist_GPRS_multislot_class = 1;
2409 pmultislotcap->GPRS_multislot_class = ms_class;
2410 if (egprs_ms_class) {
2411 pmultislotcap->Exist_EGPRS_multislot_class = 1;
2412 pmultislotcap->EGPRS_multislot_class = ms_class;
2413 }
2414
2415 send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
2416
2417 /* check the TBF */
2418 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
2419 OSMO_ASSERT(ul_tbf);
2420 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
2421
2422 /* send packet uplink assignment */
2423 *fn = sba_fn;
2424 request_dl_rlc_block(ul_tbf, fn);
2425
2426 /* send real acknowledgement */
2427 send_control_ack(ul_tbf);
2428
2429 check_tbf(ul_tbf);
2430
2431 uint8_t data_msg[49] = {0};
2432
2433 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
2434
2435 ms = the_bts->ms_by_tlli(tlli);
2436 OSMO_ASSERT(ms != NULL);
2437 OSMO_ASSERT(ms->ta() == qta/4);
2438 OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
2439
Maxbea2edb2019-03-06 17:04:59 +01002440 cs = MCS4;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302441 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
2442 egprs3->si = 0;
2443 egprs3->r = 1;
2444 egprs3->cv = 7;
2445 egprs3->tfi_hi = tfi & 0x03;
2446 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
2447 egprs3->bsn1_hi = 0;
2448 egprs3->bsn1_lo = 0;
2449 egprs3->cps_hi = 1;
2450 data_msg[3] = 0xff;
2451 egprs3->pi = 0;
2452 egprs3->cps_lo = 1;
2453 egprs3->rsb = 0;
2454 egprs3->spb = 0;
2455 egprs3->pi = 0;
2456 pdch->rcv_block(data_msg, 49, *fn, &meas);
2457
2458 egprs3->bsn1_hi = 1;
2459 egprs3->bsn1_lo = 0;
2460 data_msg[3] = 0x7f;
2461 egprs3->cps_lo = 1;
2462 egprs3->rsb = 0;
2463 egprs3->spb = 0;
2464 egprs3->pi = 0;
2465 data_msg[4] = 0x2;
2466 data_msg[5] = 0x0;
2467 pdch->rcv_block(data_msg, 49, *fn, &meas);
2468
Aravind Sirsikar22a90192016-09-15 17:24:49 +05302469 OSMO_ASSERT(ul_tbf->m_llc.m_index == 43);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302470
2471 return ul_tbf;
2472}
2473
2474static void test_tbf_li_decoding(void)
2475{
2476 BTS the_bts;
2477 int ts_no = 7;
2478 uint32_t fn = 2654218;
2479 uint16_t qta = 31;
2480 uint32_t tlli = 0xf1223344;
2481 const char *imsi = "0011223344";
2482 uint8_t ms_class = 1;
2483 uint8_t egprs_ms_class = 1;
2484 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302485 uint8_t test_data[256];
2486
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002487 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302488
2489 memset(test_data, 1, sizeof(test_data));
2490
2491 setup_bts(&the_bts, ts_no, 4);
2492 the_bts.bts_data()->initial_mcs_dl = 9;
2493 the_bts.bts_data()->egprs_enabled = 1;
2494
2495 ul_tbf = tbf_li_decoding(&the_bts, ts_no, tlli, &fn, qta,
2496 ms_class, egprs_ms_class);
2497
Max4c112dc2018-02-01 16:49:23 +01002498 print_ta_tlli(ul_tbf, true);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302499 send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data));
2500
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002501 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302502}
2503
aravind sirsikarf2761382016-10-25 12:45:24 +05302504/*
2505 * Test that a bit within the uncompressed bitmap whose BSN is not within
2506 * the transmit window shall be ignored. See section 9.1.8.2.4 of 44.060
2507 * version 7.27.0 Release 7.
2508 */
2509static void test_tbf_epdan_out_of_rx_window(void)
2510{
2511 BTS the_bts;
2512 gprs_rlcmac_bts *bts;
2513 uint8_t ms_class = 11;
2514 uint8_t egprs_ms_class = 11;
2515 uint8_t trx_no;
2516 uint32_t tlli = 0xffeeddcc;
2517 gprs_rlcmac_dl_tbf *dl_tbf;
2518 int ts_no = 4;
2519 bitvec *block;
2520 uint8_t bits_data[RLC_EGPRS_MAX_WS/8];
2521 bitvec bits;
2522 int bsn_begin, bsn_end;
2523 EGPRS_PD_AckNack_t *ack_nack;
2524 RlcMacUplink_t ul_control_block;
2525 gprs_rlc_v_b *prlcmvb;
2526 gprs_rlc_dl_window *prlcdlwindow;
2527
aravind sirsikarcc4214a2016-12-09 16:12:42 +05302528 memset(&ul_control_block, 0, sizeof(RlcMacUplink_t));
2529
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002530 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikarf2761382016-10-25 12:45:24 +05302531
2532 bts = the_bts.bts_data();
2533
2534 setup_bts(&the_bts, ts_no);
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +02002535 OSMO_ASSERT(osmo_tdef_set(bts->T_defs_pcu, -2031, 200, OSMO_TDEF_MS) == 0);
aravind sirsikarf2761382016-10-25 12:45:24 +05302536 bts->egprs_enabled = 1;
2537 /* ARQ II */
2538 bts->dl_arq_type = EGPRS_ARQ2;
2539
2540 /*
2541 * Simulate a message captured during over-the-air testing,
2542 * where the following values were observed:
2543 * v_a = 1176, vs = 1288, max sns = 2048, window size = 480.
2544 */
2545 uint8_t data_msg[23] = {0x40, 0x20, 0x0b, 0xff, 0xd1,
2546 0x61, 0x00, 0x3e, 0x0e, 0x51, 0x9f,
2547 0xff, 0xff, 0xfb, 0x80, 0x00, 0x00,
2548 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
2549
2550 dl_tbf = create_dl_tbf(&the_bts, ms_class, egprs_ms_class, &trx_no);
2551 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
Maxea98b7d2018-01-04 15:13:27 +01002552 prlcdlwindow = dl_tbf->window();
aravind sirsikarf2761382016-10-25 12:45:24 +05302553 prlcmvb = &prlcdlwindow->m_v_b;
2554 prlcdlwindow->m_v_s = 1288;
2555 prlcdlwindow->m_v_a = 1176;
2556 prlcdlwindow->set_sns(2048);
2557 prlcdlwindow->set_ws(480);
2558 prlcmvb->mark_unacked(1176);
2559 prlcmvb->mark_unacked(1177);
2560 prlcmvb->mark_unacked(1286);
2561 prlcmvb->mark_unacked(1287);
2562
2563 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2564
Alexander Couzensccde5c92017-02-04 03:10:08 +01002565 block = bitvec_alloc(23, tall_pcu_ctx);
aravind sirsikarf2761382016-10-25 12:45:24 +05302566
2567 bitvec_unpack(block, data_msg);
2568
2569 bits.data = bits_data;
2570 bits.data_len = sizeof(bits_data);
2571 bits.cur_bit = 0;
2572
2573 decode_gsm_rlcmac_uplink(block, &ul_control_block);
2574
2575 ack_nack = &ul_control_block.u.Egprs_Packet_Downlink_Ack_Nack;
2576
2577 OSMO_ASSERT(prlcmvb->is_unacked(1176));
2578 OSMO_ASSERT(prlcmvb->is_unacked(1177));
2579 OSMO_ASSERT(prlcmvb->is_unacked(1286));
2580 OSMO_ASSERT(prlcmvb->is_unacked(1287));
2581
2582 Decoding::decode_egprs_acknack_bits(
2583 &ack_nack->EGPRS_AckNack.Desc, &bits,
Maxea98b7d2018-01-04 15:13:27 +01002584 &bsn_begin, &bsn_end, dl_tbf->window());
aravind sirsikarf2761382016-10-25 12:45:24 +05302585
2586 dl_tbf->rcvd_dl_ack(
2587 ack_nack->EGPRS_AckNack.Desc.FINAL_ACK_INDICATION,
2588 bsn_begin, &bits);
aravind sirsikarf2761382016-10-25 12:45:24 +05302589
aravind sirsikarfb41afa2016-11-02 15:48:00 +05302590 OSMO_ASSERT(prlcmvb->is_invalid(1176));
2591 OSMO_ASSERT(prlcmvb->is_invalid(1177));
2592 OSMO_ASSERT(prlcmvb->is_acked(1286));
2593 OSMO_ASSERT(prlcmvb->is_acked(1287));
aravind sirsikarf2761382016-10-25 12:45:24 +05302594
2595 bitvec_free(block);
2596 tbf_free(dl_tbf);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002597 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikarf2761382016-10-25 12:45:24 +05302598}
2599
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302600static void test_tbf_egprs_two_phase_spb(void)
2601{
2602 BTS the_bts;
2603 int ts_no = 7;
2604 uint32_t fn = 2654218;
2605 uint16_t qta = 31;
2606 uint32_t tlli = 0xf1223344;
2607 const char *imsi = "0011223344";
2608 uint8_t ms_class = 1;
2609 uint8_t egprs_ms_class = 1;
2610 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302611 uint8_t test_data[256];
2612
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002613 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302614
2615 memset(test_data, 1, sizeof(test_data));
2616
2617 setup_bts(&the_bts, ts_no, 4);
2618 the_bts.bts_data()->initial_mcs_dl = 9;
2619 the_bts.bts_data()->egprs_enabled = 1;
2620
2621 ul_tbf = establish_ul_tbf_two_phase_spb(&the_bts, ts_no, tlli, &fn, qta,
2622 ms_class, egprs_ms_class);
2623
Max4c112dc2018-02-01 16:49:23 +01002624 print_ta_tlli(ul_tbf, true);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302625 send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data));
2626
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002627 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302628}
2629
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002630static void test_tbf_egprs_two_phase()
2631{
2632 BTS the_bts;
2633 int ts_no = 7;
2634 uint32_t fn = 2654218;
2635 uint16_t qta = 31;
2636 uint32_t tlli = 0xf1223344;
2637 const char *imsi = "0011223344";
2638 uint8_t ms_class = 1;
2639 uint8_t egprs_ms_class = 1;
2640 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002641 uint8_t test_data[256];
2642
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002643 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002644
2645 memset(test_data, 1, sizeof(test_data));
2646
2647 setup_bts(&the_bts, ts_no, 4);
2648 the_bts.bts_data()->initial_mcs_dl = 9;
2649 the_bts.bts_data()->egprs_enabled = 1;
2650
2651 ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli, &fn, qta,
2652 ms_class, egprs_ms_class);
2653
Max4c112dc2018-02-01 16:49:23 +01002654 print_ta_tlli(ul_tbf, true);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002655 send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data));
2656
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002657 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002658}
2659
2660static void establish_and_use_egprs_dl_tbf(BTS *the_bts, int mcs)
2661{
2662 unsigned i;
2663 uint8_t ms_class = 11;
2664 uint8_t egprs_ms_class = 11;
2665 uint32_t fn = 0;
2666 uint8_t trx_no;
2667 uint32_t tlli = 0xffeeddcc;
2668 uint8_t test_data[512];
2669
2670 uint8_t rbb[64/8];
2671
2672 gprs_rlcmac_dl_tbf *dl_tbf;
2673
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002674 fprintf(stderr, "Testing MCS-%d\n", mcs);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002675
2676 memset(test_data, 1, sizeof(test_data));
2677 the_bts->bts_data()->initial_mcs_dl = mcs;
2678
2679 dl_tbf = create_dl_tbf(the_bts, ms_class, egprs_ms_class, &trx_no);
2680 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
2681
2682 for (i = 0; i < sizeof(llc_data); i++)
2683 llc_data[i] = i%256;
2684
2685 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2686
2687 /* Schedule a small LLC frame */
2688 dl_tbf->append_data(ms_class, 1000, test_data, 10);
2689
2690 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2691
2692 /* Drain the queue */
2693 while (dl_tbf->have_data())
2694 /* Request to send one RLC/MAC block */
2695 request_dl_rlc_block(dl_tbf, &fn);
2696
2697 /* Schedule a large LLC frame */
2698 dl_tbf->append_data(ms_class, 1000, test_data, sizeof(test_data));
2699
2700 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2701
2702 /* Drain the queue */
2703 while (dl_tbf->have_data())
2704 /* Request to send one RLC/MAC block */
2705 request_dl_rlc_block(dl_tbf, &fn);
2706
2707 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2708
Max7d32f552017-12-15 11:25:14 +01002709 RCV_ACK(true, dl_tbf, rbb); /* Receive a final ACK */
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002710
2711 /* Clean up and ensure tbfs are in the correct state */
2712 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
Max0e599802018-01-23 20:09:06 +01002713 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_NONE);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002714 check_tbf(dl_tbf);
2715 tbf_free(dl_tbf);
2716}
2717
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302718static gprs_rlcmac_dl_tbf *tbf_init(BTS *the_bts,
2719 int mcs)
2720{
2721 unsigned i;
2722 uint8_t ms_class = 11;
2723 uint8_t egprs_ms_class = 11;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302724 uint8_t trx_no;
2725 uint32_t tlli = 0xffeeddcc;
2726 uint8_t test_data[512];
2727
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302728 gprs_rlcmac_dl_tbf *dl_tbf;
2729
2730 memset(test_data, 1, sizeof(test_data));
2731 the_bts->bts_data()->initial_mcs_dl = mcs;
2732
2733 dl_tbf = create_dl_tbf(the_bts, ms_class, egprs_ms_class, &trx_no);
2734 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
2735
2736 for (i = 0; i < sizeof(test_data); i++)
2737 test_data[i] = i%256;
2738
2739 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2740
2741 /* Schedule a LLC frame
2742 * passing only 100 bytes, since it is enough to construct
2743 * 2 RLC data blocks. Which are enough to test Header Type 1
2744 * cases
2745 */
2746 dl_tbf->append_data(ms_class, 1000, test_data, 100);
2747
2748 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2749
2750 return dl_tbf;
2751
2752}
2753
2754static void tbf_cleanup(gprs_rlcmac_dl_tbf *dl_tbf)
2755{
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302756 uint8_t rbb[64/8];
2757
Max7d32f552017-12-15 11:25:14 +01002758 RCV_ACK(true, dl_tbf, rbb); /* Receive a final ACK */
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302759
2760 /* Clean up and ensure tbfs are in the correct state */
2761 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
Max0e599802018-01-23 20:09:06 +01002762 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_NONE);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302763 check_tbf(dl_tbf);
2764 tbf_free(dl_tbf);
2765
2766}
2767
Max7d32f552017-12-15 11:25:14 +01002768#define NACK(tbf, x) do { \
Maxea98b7d2018-01-04 15:13:27 +01002769 tbf->window()->m_v_b.mark_nacked(x); \
2770 OSMO_ASSERT(tbf->window()->m_v_b.is_nacked(x)); \
Max7d32f552017-12-15 11:25:14 +01002771 } while(0)
2772
2773#define CHECK_UNACKED(tbf, cs, bsn) do { \
Maxea98b7d2018-01-04 15:13:27 +01002774 OSMO_ASSERT(tbf->window()->m_v_b.is_unacked(bsn)); \
Max898dddb2019-03-12 15:50:57 +01002775 OSMO_ASSERT(mcs_chan_code(tbf->m_rlc.block(bsn)->cs_current_trans) == cs - 1); \
Max7d32f552017-12-15 11:25:14 +01002776 } while(0)
2777
2778#define CHECK_NACKED(tbf, cs, bsn) do { \
Maxea98b7d2018-01-04 15:13:27 +01002779 OSMO_ASSERT(tbf->window()->m_v_b.is_nacked(bsn)); \
Max898dddb2019-03-12 15:50:57 +01002780 OSMO_ASSERT(mcs_chan_code(tbf->m_rlc.block(bsn)->cs_current_trans) == cs - 1); \
Max7d32f552017-12-15 11:25:14 +01002781 } while(0)
2782
2783#define MAKE_ACKED(m, tbf, fn, cs, check_unacked) do { \
2784 m = tbf->create_dl_acked_block(fn, tbf->control_ts); \
2785 OSMO_ASSERT(m); \
2786 if (check_unacked) \
2787 CHECK_UNACKED(tbf, cs, 0); \
2788 else \
2789 CHECK_NACKED(tbf, cs, 0); \
2790 } while(0)
2791
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302792static void egprs_spb_to_normal_validation(BTS *the_bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002793 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302794{
2795 uint32_t fn = 0;
2796 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302797 uint16_t bsn1, bsn2, bsn3;
2798 struct msgb *msg;
2799 struct gprs_rlc_dl_header_egprs_3 *egprs3;
2800 struct gprs_rlc_dl_header_egprs_2 *egprs2;
2801
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002802 fprintf(stderr, "Testing retx for MCS %u to reseg_mcs %u\n", mcs, demanded_mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302803
2804 dl_tbf = tbf_init(the_bts, mcs);
2805
2806 /*
2807 * Table 10.4.8a.3.1 of 44.060.
2808 * (MCS7, MCS9) to (MCS2, MCS3) is not handled since it is same as
2809 * (MCS5, MCS6) to (MCS2, MCS3) transition
2810 */
2811 if (!(mcs == 6 && demanded_mcs == 3))
2812 return;
2813
2814 fn = fn_add_blocks(fn, 1);
2815 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01002816 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302817
2818 egprs2 = (struct gprs_rlc_dl_header_egprs_2 *) msg->data;
Maxb4d368b2017-12-01 17:54:39 +01002819 bsn1 = (egprs2->bsn1_hi << 9) | (egprs2->bsn1_mid << 1) | (egprs2->bsn1_lo);
Max7d32f552017-12-15 11:25:14 +01002820
2821 NACK(dl_tbf, 0);
2822
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302823 OSMO_ASSERT(bsn1 == 0);
2824
2825 dl_tbf->ms()->set_current_cs_dl
Maxbea2edb2019-03-06 17:04:59 +01002826 (static_cast < CodingScheme >
2827 (CS4 + demanded_mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302828
2829 fn = fn_add_blocks(fn, 1);
2830
2831 /* Send first segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002832 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, false);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302833 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2834 == EGPRS_RESEG_FIRST_SEG_SENT);
2835
2836 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2837 OSMO_ASSERT(egprs3->spb == 2);
2838
2839 /* Table 10.4.8a.3.1 of 44.060 */
2840 OSMO_ASSERT(egprs3->cps == 3);
2841
2842 /* Send second segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002843 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302844 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2845 == EGPRS_RESEG_SECOND_SEG_SENT);
2846
2847 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2848 /* Table 10.4.8a.3.1 of 44.060 */
2849 OSMO_ASSERT(egprs3->spb == 3);
Maxb4d368b2017-12-01 17:54:39 +01002850 bsn2 = (egprs3->bsn1_hi << 9) | (egprs3->bsn1_mid << 1) | (egprs3->bsn1_lo);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302851 OSMO_ASSERT(bsn2 == bsn1);
2852
2853 /* Table 10.4.8a.3.1 of 44.060 */
2854 OSMO_ASSERT(egprs3->cps == 3);
2855
2856 /* Handle (MCS3, MCS3) -> MCS6 case */
2857 dl_tbf->ms()->set_current_cs_dl
Maxbea2edb2019-03-06 17:04:59 +01002858 (static_cast < CodingScheme >
2859 (CS4 + mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302860
Max7d32f552017-12-15 11:25:14 +01002861 NACK(dl_tbf, 0);
2862
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302863 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
2864 egprs2 = (struct gprs_rlc_dl_header_egprs_2 *) msg->data;
2865
2866 /* Table 10.4.8a.3.1 of 44.060 */
2867 OSMO_ASSERT(egprs2->cps == 0);
Maxb4d368b2017-12-01 17:54:39 +01002868 bsn3 = (egprs2->bsn1_hi << 9) | (egprs2->bsn1_mid << 1) | (egprs2->bsn1_lo);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302869 OSMO_ASSERT(bsn3 == bsn2);
2870
2871 tbf_cleanup(dl_tbf);
2872}
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002873
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302874static void establish_and_use_egprs_dl_tbf_for_spb(BTS *the_bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002875 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302876{
2877 uint32_t fn = 0;
2878 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302879 struct msgb *msg;
2880 struct gprs_rlc_dl_header_egprs_3 *egprs3;
2881
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002882 fprintf(stderr, "Testing retx for MCS %u to reseg_mcs %u\n", mcs, demanded_mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302883
2884 dl_tbf = tbf_init(the_bts, mcs);
2885
2886 /*
2887 * Table 10.4.8a.3.1 of 44.060.
2888 * (MCS7, MCS9) to (MCS2, MCS3) is not handled since it is same as
2889 * (MCS5, MCS6) to (MCS2, MCS3) transition
2890 */
2891 /* TODO: Need to support of MCS8 -> MCS6 ->MCS3 transistion
2892 * Refer commit be881c028fc4da00c4046ecd9296727975c206a3
2893 * dated 2016-02-07 23:45:40 (UTC)
2894 */
2895 if (!(((mcs == 5) && (demanded_mcs == 2)) ||
2896 ((mcs == 6) && (demanded_mcs == 3)) ||
2897 ((mcs == 4) && (demanded_mcs == 1))))
2898 return;
2899
2900 fn = fn_add_blocks(fn, 1);
2901 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01002902 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302903
Max7d32f552017-12-15 11:25:14 +01002904 NACK(dl_tbf, 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302905
2906 dl_tbf->ms()->set_current_cs_dl
Maxbea2edb2019-03-06 17:04:59 +01002907 (static_cast < CodingScheme >
2908 (CS4 + demanded_mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302909
2910 fn = fn_add_blocks(fn, 1);
2911
2912 /* Send first segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002913 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, false);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302914 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2915 == EGPRS_RESEG_FIRST_SEG_SENT);
2916
2917 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2918 OSMO_ASSERT(egprs3->spb == 2);
2919
2920 /* Table 10.4.8a.3.1 of 44.060 */
2921 switch (demanded_mcs) {
2922 case 3:
2923 OSMO_ASSERT(egprs3->cps == 3);
2924 break;
2925 case 2:
2926 OSMO_ASSERT(egprs3->cps == 9);
2927 break;
2928 case 1:
2929 OSMO_ASSERT(egprs3->cps == 11);
2930 break;
2931 default:
2932 OSMO_ASSERT(false);
2933 break;
2934 }
2935
2936 /* Send second segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002937 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302938 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2939 == EGPRS_RESEG_SECOND_SEG_SENT);
2940
2941 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2942 /* Table 10.4.8a.3.1 of 44.060 */
2943 OSMO_ASSERT(egprs3->spb == 3);
2944
2945 /* Table 10.4.8a.3.1 of 44.060 */
2946 switch (demanded_mcs) {
2947 case 3:
2948 OSMO_ASSERT(egprs3->cps == 3);
2949 break;
2950 case 2:
2951 OSMO_ASSERT(egprs3->cps == 9);
2952 break;
2953 case 1:
2954 OSMO_ASSERT(egprs3->cps == 11);
2955 break;
2956 default:
2957 OSMO_ASSERT(false);
2958 break;
2959 }
2960 tbf_cleanup(dl_tbf);
2961}
2962
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302963static void establish_and_use_egprs_dl_tbf_for_retx(BTS *the_bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002964 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302965{
2966 uint32_t fn = 0;
2967 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302968 struct msgb *msg;
2969
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002970 fprintf(stderr, "Testing retx for MCS %u - %u\n", mcs, demanded_mcs);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302971
2972 dl_tbf = tbf_init(the_bts, mcs);
2973
2974 /* For MCS reduction cases like MCS9->MCS6, MCS7->MCS5
2975 * The MCS transition are referred from table Table 8.1.1.2
2976 * of TS 44.060
2977 */
2978 /* TODO: Need to support of MCS8 -> MCS6 transistion
2979 * Refer commit be881c028fc4da00c4046ecd9296727975c206a3
2980 * dated 2016-02-07 23:45:40 (UTC)
2981 */
2982 if (((mcs == 9) && (demanded_mcs < 9)) ||
2983 ((mcs == 7) && (demanded_mcs < 7))) {
2984 fn = fn_add_blocks(fn, 1);
2985 /* Send 2 RLC data block */
Max7d32f552017-12-15 11:25:14 +01002986 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
2987 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302988
Max7d32f552017-12-15 11:25:14 +01002989 NACK(dl_tbf, 0);
2990 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302991
2992 /* Set the demanded MCS to demanded_mcs */
2993 dl_tbf->ms()->set_current_cs_dl
Maxbea2edb2019-03-06 17:04:59 +01002994 (static_cast < CodingScheme >
2995 (CS4 + demanded_mcs));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302996
2997 fn = fn_add_blocks(fn, 1);
2998 /* Retransmit the first RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002999 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
3000 CHECK_NACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303001
3002 fn = fn_add_blocks(fn, 1);
3003 /* Retransmit the second RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003004 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
3005 CHECK_UNACKED(dl_tbf, demanded_mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303006 } else if (((mcs == 5) && (demanded_mcs > 6)) ||
3007 ((mcs == 6) && (demanded_mcs > 8))) {
3008 fn = fn_add_blocks(fn, 1);
3009 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01003010 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303011
3012 fn = fn_add_blocks(fn, 1);
3013 /* Send second RLC data block BSN 1 */
Max7d32f552017-12-15 11:25:14 +01003014 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3015 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303016
Max7d32f552017-12-15 11:25:14 +01003017 NACK(dl_tbf, 0);
3018 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303019
3020 dl_tbf->ms()->set_current_cs_dl
Maxbea2edb2019-03-06 17:04:59 +01003021 (static_cast < CodingScheme >
3022 (CS4 + demanded_mcs));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303023
3024 fn = fn_add_blocks(fn, 1);
3025 /* Send first, second RLC data blocks with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003026 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
3027 CHECK_UNACKED(dl_tbf, demanded_mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303028 } else if (mcs > 6) {
3029 /* No Mcs change cases are handled here for mcs > MCS6*/
3030 fn = fn_add_blocks(fn, 1);
3031 /* Send first,second RLC data blocks */
Max7d32f552017-12-15 11:25:14 +01003032 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3033 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303034
Max7d32f552017-12-15 11:25:14 +01003035 NACK(dl_tbf, 0);
3036 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303037
3038 fn = fn_add_blocks(fn, 1);
3039 /* Send first,second RLC data blocks with demanded_mcs*/
Max7d32f552017-12-15 11:25:14 +01003040 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3041 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303042 } else {
3043
3044 /* No MCS change cases are handled here for mcs <= MCS6*/
3045 fn = fn_add_blocks(fn, 1);
3046 /* Send first RLC data block */
Max7d32f552017-12-15 11:25:14 +01003047 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303048
Max7d32f552017-12-15 11:25:14 +01003049 NACK(dl_tbf, 0);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303050
3051 fn = fn_add_blocks(fn, 1);
3052 /* Send first RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003053 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303054 }
3055
3056 tbf_cleanup(dl_tbf);
3057}
3058
3059static void test_tbf_egprs_retx_dl(void)
3060{
3061 BTS the_bts;
3062 gprs_rlcmac_bts *bts;
3063 uint8_t ts_no = 4;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303064
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003065 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303066
3067 bts = the_bts.bts_data();
3068 bts->cs_downgrade_threshold = 0;
3069 setup_bts(&the_bts, ts_no);
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +02003070 OSMO_ASSERT(osmo_tdef_set(bts->T_defs_pcu, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303071 bts->egprs_enabled = 1;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303072 /* ARQ II */
3073 bts->dl_arq_type = EGPRS_ARQ2;
3074
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303075
3076 /* First parameter is current MCS, second one is demanded_mcs */
3077 establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 6, 6);
3078 establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 1, 9);
3079 establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 2, 8);
3080 establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 5, 7);
3081 establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 6, 9);
3082 establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 7, 5);
3083 establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 9, 6);
3084
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003085 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303086}
3087
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303088static void test_tbf_egprs_spb_dl(void)
3089{
3090 BTS the_bts;
3091 gprs_rlcmac_bts *bts;
3092 uint8_t ts_no = 4;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303093
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003094 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303095
3096 bts = the_bts.bts_data();
3097 bts->cs_downgrade_threshold = 0;
3098 setup_bts(&the_bts, ts_no);
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +02003099 OSMO_ASSERT(osmo_tdef_set(bts->T_defs_pcu, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303100 bts->egprs_enabled = 1;
3101
3102 /* ARQ I resegmentation support */
3103 bts->dl_arq_type = EGPRS_ARQ1;
3104
3105 /*
3106 * First parameter is current MCS, second one is demanded_mcs
3107 * currently only MCS5->MCS2, MCS6->3, MCS4->MCS1 is tested in UT
3108 * rest scenarios has been integration tested
3109 */
3110 establish_and_use_egprs_dl_tbf_for_spb(&the_bts, 6, 3);
3111 establish_and_use_egprs_dl_tbf_for_spb(&the_bts, 5, 2);
3112 establish_and_use_egprs_dl_tbf_for_spb(&the_bts, 4, 1);
3113 /* check MCS6->(MCS3+MCS3)->MCS6 case */
3114 egprs_spb_to_normal_validation(&the_bts, 6, 3);
3115
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003116 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303117}
3118
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003119static void test_tbf_egprs_dl()
3120{
3121 BTS the_bts;
3122 gprs_rlcmac_bts *bts;
3123 uint8_t ts_no = 4;
3124 int i;
3125
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003126 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003127
3128 bts = the_bts.bts_data();
3129
3130 setup_bts(&the_bts, ts_no);
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +02003131 OSMO_ASSERT(osmo_tdef_set(bts->T_defs_pcu, -2031, 200, OSMO_TDEF_MS) == 0);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003132 bts->egprs_enabled = 1;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303133 /* ARQ II */
3134 bts->dl_arq_type = EGPRS_ARQ2;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003135
3136 for (i = 1; i <= 9; i++)
3137 establish_and_use_egprs_dl_tbf(&the_bts, i);
3138
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003139 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003140}
3141
3142
3143
aravind sirsikare9a138e2017-01-24 12:36:08 +05303144static void test_packet_access_rej_prr_no_other_tbfs()
3145{
3146 BTS the_bts;
3147 uint32_t fn = 2654218;
3148 int ts_no = 7;
3149 uint8_t trx_no = 0;
3150 uint32_t tlli = 0xffeeddcc;
3151 struct gprs_rlcmac_ul_tbf *ul_tbf = NULL;
3152
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003153 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303154
3155 setup_bts(&the_bts, ts_no, 4);
3156
3157 int rc = 0;
3158
3159 ul_tbf = handle_tbf_reject(the_bts.bts_data(), NULL, tlli,
3160 trx_no, ts_no);
3161
3162 OSMO_ASSERT(ul_tbf != 0);
3163
3164 /* trigger packet access reject */
3165 uint8_t bn = fn2bn(fn);
3166
3167 rc = gprs_rlcmac_rcv_rts_block(the_bts.bts_data(),
3168 trx_no, ts_no, fn, bn);
3169
3170 OSMO_ASSERT(rc == 0);
3171
3172 ul_tbf->handle_timeout();
3173
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003174 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303175}
3176
3177static void test_packet_access_rej_prr()
3178{
3179 BTS the_bts;
3180 uint32_t fn = 2654218;
3181 uint16_t qta = 31;
3182 int ts_no = 7;
3183 uint8_t trx_no = 0;
3184 RlcMacUplink_t ulreq = {0};
3185 Packet_Resource_Request_t *presreq = NULL;
3186 uint8_t ms_class = 11;
3187 uint8_t egprs_ms_class = 11;
3188 uint32_t rach_fn = fn - 51;
3189 uint32_t sba_fn = fn + 52;
3190 uint32_t tlli = 0xffeeddcc;
3191 MS_Radio_Access_capability_t *pmsradiocap = NULL;
3192 Multislot_capability_t *pmultislotcap = NULL;
3193
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003194 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303195
3196 setup_bts(&the_bts, ts_no, 4);
3197
3198 int rc = 0;
3199
3200 /*
3201 * Trigger rach till resources(USF) exhaust
3202 */
3203 rc = the_bts.rcv_rach(0x78, rach_fn, qta, 0,
3204 GSM_L1_BURST_TYPE_ACCESS_0);
3205 rc = the_bts.rcv_rach(0x79, rach_fn, qta, 0,
3206 GSM_L1_BURST_TYPE_ACCESS_0);
3207 rc = the_bts.rcv_rach(0x7a, rach_fn, qta, 0,
3208 GSM_L1_BURST_TYPE_ACCESS_0);
3209 rc = the_bts.rcv_rach(0x7b, rach_fn, qta, 0,
3210 GSM_L1_BURST_TYPE_ACCESS_0);
3211 rc = the_bts.rcv_rach(0x7c, rach_fn, qta, 0,
3212 GSM_L1_BURST_TYPE_ACCESS_0);
3213 rc = the_bts.rcv_rach(0x7d, rach_fn, qta, 0,
3214 GSM_L1_BURST_TYPE_ACCESS_0);
3215 rc = the_bts.rcv_rach(0x7e, rach_fn, qta, 0,
3216 GSM_L1_BURST_TYPE_ACCESS_0);
3217
3218 /* fake a resource request */
3219 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
3220 presreq = &ulreq.u.Packet_Resource_Request;
3221 presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
3222 presreq->ID.UnionType = 1; /* != 0 */
3223 presreq->ID.u.TLLI = tlli;
3224 presreq->Exist_MS_Radio_Access_capability = 1;
3225 pmsradiocap = &presreq->MS_Radio_Access_capability;
3226 pmsradiocap->Count_MS_RA_capability_value = 1;
3227 pmsradiocap->MS_RA_capability_value[0].u.Content.
3228 Exist_Multislot_capability = 1;
3229 pmultislotcap = &pmsradiocap->MS_RA_capability_value[0].
3230 u.Content.Multislot_capability;
3231
3232 pmultislotcap->Exist_GPRS_multislot_class = 1;
3233 pmultislotcap->GPRS_multislot_class = ms_class;
3234 if (egprs_ms_class) {
3235 pmultislotcap->Exist_EGPRS_multislot_class = 1;
3236 pmultislotcap->EGPRS_multislot_class = egprs_ms_class;
3237 }
3238
3239 send_ul_mac_block(&the_bts, trx_no, ts_no, &ulreq, sba_fn);
3240
3241 /* trigger packet access reject */
3242 uint8_t bn = fn2bn(fn);
3243
3244 rc = gprs_rlcmac_rcv_rts_block(the_bts.bts_data(),
3245 trx_no, ts_no, fn, bn);
3246
3247 OSMO_ASSERT(rc == 0);
3248
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003249 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303250}
3251
aravind sirsikared3413e2016-11-11 17:15:10 +05303252void test_packet_access_rej_epdan()
3253{
3254 BTS the_bts;
3255 uint32_t tlli = 0xffeeddcc;
Maxd3a0d912019-03-05 16:15:01 +01003256 static uint8_t exp[] = { 0x40, 0x84, 0x7f, 0xf7, 0x6e, 0xe6, 0x41, 0x4b,
3257 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
3258 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b
3259 };
aravind sirsikared3413e2016-11-11 17:15:10 +05303260
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003261 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikared3413e2016-11-11 17:15:10 +05303262 setup_bts(&the_bts, 4);
3263 static gprs_rlcmac_dl_tbf *dl_tbf = tbf_init(&the_bts, 1);
3264
3265 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
3266
3267 struct msgb *msg = dl_tbf->create_packet_access_reject();
3268
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003269 fprintf(stderr, "packet reject: %s\n",
aravind sirsikared3413e2016-11-11 17:15:10 +05303270 osmo_hexdump(msg->data, 23));
3271
Maxd3a0d912019-03-05 16:15:01 +01003272 if (!msgb_eq_data_print(msg, exp, GSM_MACBLOCK_LEN))
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003273 fprintf(stderr, "%s test failed!\n", __func__);
Maxd3a0d912019-03-05 16:15:01 +01003274
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003275 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikared3413e2016-11-11 17:15:10 +05303276
3277}
3278
3279
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003280int main(int argc, char **argv)
3281{
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003282 struct vty_app_info pcu_vty_info = {0};
3283
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003284 tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile TbfTest context");
3285 if (!tall_pcu_ctx)
3286 abort();
3287
Neels Hofmeyr78ce5912017-02-08 17:07:31 +01003288 msgb_talloc_ctx_init(tall_pcu_ctx, 0);
Neels Hofmeyr42f2d612018-04-01 16:54:40 +02003289 osmo_init_logging2(tall_pcu_ctx, &gprs_log_info);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003290 log_set_use_color(osmo_stderr_target, 0);
3291 log_set_print_filename(osmo_stderr_target, 0);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003292 bssgp_set_log_ss(DBSSGP);
Maxfdd79e92018-01-24 11:04:59 +01003293 log_parse_category_mask(osmo_stderr_target, "DRLCMAC,1:DRLCMACDATA,3:DRLCMACDL,3:DRLCMACUL,3:"
3294 "DRLCMACSCHED,1:DRLCMACMEAS,3:DNS,3:DBSSGP,3:DPCU,5:"
Max86e35e42019-03-07 12:20:42 +01003295 "DL1IF,6:DTBF,1:DTBFUL,1:DTBFDL,1:DLGLOBAL,2:");
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003296
3297 vty_init(&pcu_vty_info);
Pau Espin Pedrolcd2ac562019-08-05 14:30:44 +02003298 pcu_vty_init();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003299
Jacob Erlbeckac89a552015-06-29 14:18:46 +02003300 test_tbf_base();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003301 test_tbf_tlli_update();
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +01003302 test_tbf_final_ack(TEST_MODE_STANDARD);
3303 test_tbf_final_ack(TEST_MODE_REVERSE_FREE);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +01003304 test_tbf_delayed_release();
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +02003305 test_tbf_imsi();
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003306 test_tbf_exhaustion();
Jacob Erlbeck41168642015-06-12 13:41:00 +02003307 test_tbf_dl_llc_loss();
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02003308 test_tbf_single_phase();
3309 test_tbf_two_phase();
Jacob Erlbeckb1395982015-08-21 18:15:38 +02003310 test_tbf_ra_update_rach();
3311 test_tbf_dl_flow_and_rach_two_phase();
3312 test_tbf_dl_flow_and_rach_single_phase();
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02003313 test_tbf_dl_reuse();
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01003314 test_tbf_gprs_egprs();
Jacob Erlbeck36df7742016-01-19 15:53:30 +01003315 test_tbf_ws();
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003316 test_tbf_egprs_two_phase();
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05303317 test_tbf_egprs_two_phase_spb();
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003318 test_tbf_egprs_dl();
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303319 test_tbf_egprs_retx_dl();
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303320 test_tbf_egprs_spb_dl();
Aravind Sirsikar02352b42016-08-25 16:37:30 +05303321 test_tbf_puan_urbb_len();
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05303322 test_tbf_update_ws();
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05303323 test_tbf_li_decoding();
aravind sirsikarf2761382016-10-25 12:45:24 +05303324 test_tbf_epdan_out_of_rx_window();
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05303325 test_immediate_assign_rej();
sivasankari1d8744c2017-01-24 15:53:35 +05303326 test_tbf_egprs_two_phase_puan();
aravind sirsikared3413e2016-11-11 17:15:10 +05303327 test_packet_access_rej_epdan();
aravind sirsikare9a138e2017-01-24 12:36:08 +05303328 test_packet_access_rej_prr();
3329 test_packet_access_rej_prr_no_other_tbfs();
Jacob Erlbeck67c38502015-05-11 10:32:40 +02003330
3331 if (getenv("TALLOC_REPORT_FULL"))
3332 talloc_report_full(tall_pcu_ctx, stderr);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003333 return EXIT_SUCCESS;
3334}
3335
3336/*
3337 * stubs that should not be reached
3338 */
3339extern "C" {
3340void l1if_pdch_req() { abort(); }
3341void l1if_connect_pdch() { abort(); }
3342void l1if_close_pdch() { abort(); }
3343void l1if_open_pdch() { abort(); }
3344}