blob: 0b2e8680616992cd01eac87880127c0b270bf00d [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"
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010025#include "tbf_dl.h"
Pau Espin Pedrol9d1cdb12019-09-25 17:47:02 +020026#include "tbf_ul.h"
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010027#include "gprs_ms.h"
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010028#include "gprs_debug.h"
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010029#include "gprs_ms_storage.h"
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +010030#include "pcu_utils.h"
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020031#include "gprs_bssgp_pcu.h"
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +020032#include "pcu_l1_if.h"
aravind sirsikarf2761382016-10-25 12:45:24 +053033#include "decoding.h"
Max1187a772018-01-26 13:31:42 +010034#include <gprs_rlcmac.h>
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010035
36extern "C" {
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020037#include "pcu_vty.h"
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +020038#include "coding_scheme.h"
Pau Espin Pedrolff7c5812022-12-14 18:49:06 +010039#include "alloc_algo.h"
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020040
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010041#include <osmocom/core/application.h>
42#include <osmocom/core/msgb.h>
43#include <osmocom/core/talloc.h>
44#include <osmocom/core/utils.h>
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020045#include <osmocom/vty/vty.h>
Aravind Sirsikar505a86d2016-07-26 18:26:21 +053046#include <osmocom/gprs/protocol/gsm_04_60.h>
bhargava959d1de2016-08-17 15:17:21 +053047#include <osmocom/gsm/l1sap.h>
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +020048#include <osmocom/core/fsm.h>
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010049}
50
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020051#include <errno.h>
52
Philippd935d882016-11-07 13:07:36 +010053#define DUMMY_FN 2654167
54
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010055void *tall_pcu_ctx;
56int16_t spoof_mnc = 0, spoof_mcc = 0;
Neels Hofmeyrbdc55fa2018-02-21 00:39:07 +010057bool spoof_mnc_3_digits = false;
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010058
Vadim Yanitskiy87b6e7d2019-11-08 04:44:04 +070059/* Measurements shared by all unit tests */
60static struct pcu_l1_meas meas;
61
Pau Espin Pedrol945be912021-07-26 14:47:46 +020062int gprs_gp_send_test_cb(void *ctx, struct msgb *msg)
63{
64 return 0;
65}
66
67static gprs_pcu *prepare_pcu(void)
68{
69 struct gprs_pcu *pcu = gprs_pcu_alloc(tall_pcu_ctx);
70 bssgp_set_bssgp_callback(gprs_gp_send_test_cb, NULL);
Pau Espin Pedrol9184e852022-05-09 16:13:52 +020071 osmo_tdef_set(pcu->T_defs, -2030, 0, OSMO_TDEF_S);
72 osmo_tdef_set(pcu->T_defs, -2031, 0, OSMO_TDEF_S);
Pau Espin Pedrol945be912021-07-26 14:47:46 +020073 return pcu;
74}
75
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010076static int bts_handle_rach(struct gprs_rlcmac_bts *bts, uint16_t ra, uint32_t Fn, int16_t qta)
Vadim Yanitskiya0a0b7f2020-05-21 19:55:46 +070077{
78 struct rach_ind_params rip = {
79 .burst_type = GSM_L1_BURST_TYPE_ACCESS_0,
80 .is_11bit = false,
81 .ra = ra,
82 .trx_nr = 0,
83 .ts_nr = 0,
84 .rfn = Fn,
85 .qta = qta,
86 };
87
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010088 return bts_rcv_rach(bts, &rip);
Vadim Yanitskiya0a0b7f2020-05-21 19:55:46 +070089}
90
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +010091static void check_tbf(gprs_rlcmac_tbf *tbf)
92{
93 OSMO_ASSERT(tbf);
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +020094 if (tbf->state_is(TBF_ST_WAIT_RELEASE))
Pau Espin Pedrolf197f152022-11-17 20:18:46 +010095 OSMO_ASSERT(tbf->timers_pending(T3191) || osmo_timer_pending(&tbf->state_fi->timer));
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +020096 if (tbf->state_is(TBF_ST_RELEASING))
Maxee5be3a2017-12-20 17:31:13 +010097 OSMO_ASSERT(tbf->timers_pending(T_MAX));
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +010098}
99
Jacob Erlbeckac89a552015-06-29 14:18:46 +0200100static void test_tbf_base()
101{
102
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200103 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckac89a552015-06-29 14:18:46 +0200104
105 OSMO_ASSERT(GPRS_RLCMAC_DL_TBF == reverse(GPRS_RLCMAC_UL_TBF));
106 OSMO_ASSERT(GPRS_RLCMAC_UL_TBF == reverse(GPRS_RLCMAC_DL_TBF));
107
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200108 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckac89a552015-06-29 14:18:46 +0200109}
110
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100111static void test_tbf_tlli_update()
112{
Pau Espin Pedrol945be912021-07-26 14:47:46 +0200113 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100114 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200115 GprsMs *ms, *ms_new;
116
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200117 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100118
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100119 the_pcu->alloc_algorithm = alloc_algorithm_a;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100120 bts->trx[0].pdch[2].enable();
121 bts->trx[0].pdch[3].enable();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100122
123 /*
124 * Make a uplink and downlink allocation
125 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100126 ms = bts_alloc_ms(bts, 0, 0);
Pau Espin Pedrol87573842022-10-26 20:23:45 +0200127 gprs_rlcmac_tbf *dl_tbf = dl_tbf_alloc(bts,
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200128 ms, 0, false);
Jacob Erlbeckc6d4cee2015-06-29 13:03:46 +0200129 OSMO_ASSERT(dl_tbf != NULL);
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +0200130 ms_confirm_tlli(ms, 0x2342);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200131 dl_tbf->set_ta(4);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100132 OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200133 OSMO_ASSERT(dl_tbf->ms() == ms);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100134
Pau Espin Pedrolbda7bb72022-10-31 14:33:09 +0100135 gprs_rlcmac_tbf *ul_tbf = ul_tbf_alloc(bts,
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200136 ms, 0, false);
Jacob Erlbeckc6d4cee2015-06-29 13:03:46 +0200137 OSMO_ASSERT(ul_tbf != NULL);
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +0200138 ms_update_announced_tlli(ms, 0x2342);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100139 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200140 OSMO_ASSERT(ul_tbf->ms() == ms);
141
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100142 OSMO_ASSERT(bts_ms_by_tlli(bts, 0x2342, GSM_RESERVED_TMSI) == ms);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100143
144 /*
145 * Now check.. that DL changes and that the timing advance
146 * has changed.
147 */
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +0200148 ms_confirm_tlli(dl_tbf->ms(), 0x4232);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100149
Jacob Erlbeck93990462015-05-15 15:50:43 +0200150 /* It is still there, since the new TLLI has not been used for UL yet */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100151 ms_new = bts_ms_by_tlli(bts, 0x2342, GSM_RESERVED_TMSI);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200152 OSMO_ASSERT(ms == ms_new);
153
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100154 ms_new = bts_ms_by_tlli(bts, 0x4232, GSM_RESERVED_TMSI);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200155 OSMO_ASSERT(ms == ms_new);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100156 OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf);
157 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200158
159 /* Now use the new TLLI for UL */
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +0200160 ms_update_announced_tlli(ms, 0x4232);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100161 ms_new = bts_ms_by_tlli(bts, 0x2342, GSM_RESERVED_TMSI);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200162 OSMO_ASSERT(ms_new == NULL);
Holger Hans Peter Freytherbc1626e2013-10-30 19:50:49 +0100163
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100164 ms_new = bts_ms_by_tlli(bts, 0x4232, GSM_RESERVED_TMSI);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200165 OSMO_ASSERT(ms_new != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100166 OSMO_ASSERT(ms_ta(ms_new) == 4);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200167
168 OSMO_ASSERT(ul_tbf->ta() == 4);
169 OSMO_ASSERT(dl_tbf->ta() == 4);
170
171 ul_tbf->set_ta(6);
172
173 OSMO_ASSERT(ul_tbf->ta() == 6);
174 OSMO_ASSERT(dl_tbf->ta() == 6);
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100175
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200176 fprintf(stderr, "=== end %s ===\n", __func__);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100177 TALLOC_FREE(the_pcu);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100178}
179
Daniel Willmann510d7d32014-08-15 18:19:41 +0200180static uint8_t llc_data[200];
181
Maxa2961182018-01-25 19:47:28 +0100182/* override, requires '-Wl,--wrap=pcu_sock_send' */
183int __real_pcu_sock_send(struct msgb *msg);
Pau Espin Pedrole91c4c72021-01-18 17:54:30 +0100184extern "C" int __wrap_pcu_sock_send(struct msgb *msg)
Daniel Willmann510d7d32014-08-15 18:19:41 +0200185{
186 return 0;
187}
188
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100189static void setup_bts(struct gprs_rlcmac_bts *bts, uint8_t ts_no, uint8_t cs = 1)
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100190{
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100191 gprs_rlcmac_trx *trx;
192
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100193 the_pcu->alloc_algorithm = alloc_algorithm_a;
Jacob Erlbecka700dd92015-06-02 16:00:41 +0200194 bts->initial_cs_dl = cs;
195 bts->initial_cs_ul = cs;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100196 trx = &bts->trx[0];
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100197 trx->pdch[ts_no].enable();
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100198 bts_set_current_frame_number(bts, DUMMY_FN);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100199}
200
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100201static gprs_rlcmac_dl_tbf *create_dl_tbf(struct gprs_rlcmac_bts *bts, uint8_t ms_class,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +0100202 uint8_t egprs_ms_class, uint8_t *trx_no_)
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100203{
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100204 int tfi;
205 uint8_t trx_no;
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200206 GprsMs *ms;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100207 gprs_rlcmac_dl_tbf *dl_tbf;
208
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100209 ms = bts_alloc_ms(bts, ms_class, egprs_ms_class);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100210
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100211 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_DL_TBF, &trx_no, -1);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100212 OSMO_ASSERT(tfi >= 0);
Pau Espin Pedrol87573842022-10-26 20:23:45 +0200213 dl_tbf = dl_tbf_alloc(bts, ms, trx_no, true);
Pau Espin Pedrol983bb7e2020-10-26 14:52:06 +0100214 OSMO_ASSERT(dl_tbf);
Max9bbe1602016-07-18 12:50:18 +0200215 dl_tbf->set_ta(0);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100216 check_tbf(dl_tbf);
217
218 /* "Establish" the DL TBF */
Pau Espin Pedrol49a2f402021-07-27 17:33:07 +0200219 osmo_fsm_inst_dispatch(dl_tbf->dl_ass_fsm.fi, TBF_DL_ASS_EV_SCHED_ASS, NULL);
Pau Espin Pedrolf197f152022-11-17 20:18:46 +0100220 osmo_fsm_inst_dispatch(dl_tbf->state_fi, TBF_EV_ASSIGN_ADD_CCCH, NULL);
221 osmo_fsm_inst_dispatch(dl_tbf->state_fi, TBF_EV_ASSIGN_ACK_PACCH, NULL);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100222 check_tbf(dl_tbf);
223
224 *trx_no_ = trx_no;
225
226 return dl_tbf;
227}
228
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200229static unsigned fn_add_blocks(unsigned fn, unsigned blocks)
230{
231 unsigned bn = fn2bn(fn) + blocks;
232 fn = fn - (fn % 52);
233 fn += bn * 4 + bn / 3;
Max9dabfa22017-05-16 16:10:45 +0200234 return fn % GSM_MAX_FN;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200235}
236
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200237static void request_dl_rlc_block(struct gprs_rlcmac_bts *bts,
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100238 struct gprs_rlcmac_pdch *pdch,
Jacob Erlbeckee310902015-08-24 11:55:17 +0200239 uint32_t *fn, uint8_t *block_nr = NULL)
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100240{
Jacob Erlbeckee310902015-08-24 11:55:17 +0200241 uint8_t bn = fn2bn(*fn);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100242 gprs_rlcmac_rcv_rts_block(bts, pdch->trx->trx_no, pdch->ts_no, *fn, bn);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200243 *fn = fn_add_blocks(*fn, 1);
Jacob Erlbeckee310902015-08-24 11:55:17 +0200244 bn += 1;
245 if (block_nr)
246 *block_nr = bn;
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100247}
248
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200249static void request_dl_rlc_block(struct gprs_rlcmac_tbf *tbf,
Jacob Erlbeckee310902015-08-24 11:55:17 +0200250 uint32_t *fn, uint8_t *block_nr = NULL)
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200251{
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100252 request_dl_rlc_block(tbf->bts, tbf->control_ts, fn, block_nr);
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200253}
254
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100255enum test_tbf_final_ack_mode {
256 TEST_MODE_STANDARD,
257 TEST_MODE_REVERSE_FREE
258};
259
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +0200260/* Receive an ACK */
261static void _rcv_ack(bool fin, gprs_rlcmac_dl_tbf *tbf, uint8_t *rbb)
262{
263 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window());
264 uint8_t bits_data[RLC_GPRS_WS/8];
265 bitvec bits;
266 Ack_Nack_Description_t ack_nack;
267 int bsn_begin, bsn_end;
268 uint8_t ssn = w->v_s();
269
270 bits.data = bits_data;
271 bits.data_len = sizeof(bits_data);
272 bits.cur_bit = 0;
273 ack_nack.FINAL_ACK_INDICATION = fin;
274 ack_nack.STARTING_SEQUENCE_NUMBER = ssn;
275 memcpy(ack_nack.RECEIVED_BLOCK_BITMAP, rbb, RLC_GPRS_WS/8);
276
277 Decoding::decode_gprs_acknack_bits(
278 &ack_nack, &bits,
279 &bsn_begin, &bsn_end, w);
280
281 tbf->rcvd_dl_ack(fin, bsn_begin, &bits);
282 if (!fin)
283 OSMO_ASSERT(w->window_empty());
284}
285
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100286static void test_tbf_final_ack(enum test_tbf_final_ack_mode test_mode)
Daniel Willmann510d7d32014-08-15 18:19:41 +0200287{
Pau Espin Pedrol945be912021-07-26 14:47:46 +0200288 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100289 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100290 uint8_t ts_no = 4;
291 unsigned i;
Daniel Willmann510d7d32014-08-15 18:19:41 +0200292 uint8_t ms_class = 45;
293 uint32_t fn;
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100294 uint8_t block_nr;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100295 uint8_t trx_no;
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200296 GprsMs *ms;
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200297 uint32_t tlli = 0xffeeddcc;
Daniel Willmann510d7d32014-08-15 18:19:41 +0200298
299 uint8_t rbb[64/8];
300
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200301 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100302
Daniel Willmann510d7d32014-08-15 18:19:41 +0200303 gprs_rlcmac_dl_tbf *dl_tbf;
304 gprs_rlcmac_tbf *new_tbf;
305
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100306 setup_bts(bts, ts_no);
307 dl_tbf = create_dl_tbf(bts, ms_class, 0, &trx_no);
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +0200308 ms_confirm_tlli(dl_tbf->ms(), tlli);
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200309 ms = dl_tbf->ms();
Daniel Willmann510d7d32014-08-15 18:19:41 +0200310
311 for (i = 0; i < sizeof(llc_data); i++)
312 llc_data[i] = i%256;
313
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100314 /* Schedule two LLC frames */
Pau Espin Pedrol14beef62022-10-26 19:44:07 +0200315 ms_append_llc_dl_data(dl_tbf->ms(), 1000, llc_data, sizeof(llc_data));
316 ms_append_llc_dl_data(dl_tbf->ms(), 1000, llc_data, sizeof(llc_data));
Daniel Willmann510d7d32014-08-15 18:19:41 +0200317
318
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100319 /* Send only a few RLC/MAC blocks */
Daniel Willmann510d7d32014-08-15 18:19:41 +0200320 fn = 0;
Jacob Erlbeckee310902015-08-24 11:55:17 +0200321 do {
Daniel Willmann510d7d32014-08-15 18:19:41 +0200322 /* Request to send one block */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200323 request_dl_rlc_block(dl_tbf, &fn, &block_nr);
Jacob Erlbeckee310902015-08-24 11:55:17 +0200324 } while (block_nr < 3);
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200325
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100326 OSMO_ASSERT(dl_tbf->have_data());
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200327 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Daniel Willmann510d7d32014-08-15 18:19:41 +0200328
329 /* Queue a final ACK */
330 memset(rbb, 0, sizeof(rbb));
331 /* Receive a final ACK */
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +0200332 _rcv_ack(true, dl_tbf, rbb);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200333
334 /* Clean up and ensure tbfs are in the correct state */
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200335 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_WAIT_RELEASE));
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100336 new_tbf = ms_dl_tbf(ms);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100337 check_tbf(new_tbf);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200338 OSMO_ASSERT(new_tbf != dl_tbf);
339 OSMO_ASSERT(new_tbf->tfi() == 1);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100340 check_tbf(dl_tbf);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100341 if (test_mode == TEST_MODE_REVERSE_FREE) {
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100342 ms_ref(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100343 tbf_free(new_tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100344 OSMO_ASSERT(ms_dl_tbf(ms) == NULL);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100345 check_tbf(dl_tbf);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100346 tbf_free(dl_tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100347 ms_unref(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100348 } else {
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100349 ms_ref(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100350 tbf_free(dl_tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100351 OSMO_ASSERT(ms_dl_tbf(ms) == new_tbf);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100352 check_tbf(new_tbf);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100353 tbf_free(new_tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100354 OSMO_ASSERT(ms_dl_tbf(ms) == NULL);
355 ms_unref(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100356 }
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100357
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100358 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200359 fprintf(stderr, "=== end %s ===\n", __func__);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200360}
361
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100362static void test_tbf_delayed_release()
363{
Pau Espin Pedrol945be912021-07-26 14:47:46 +0200364 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100365 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100366 uint8_t ts_no = 4;
367 unsigned i;
368 uint8_t ms_class = 45;
369 uint32_t fn = 0;
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100370 uint8_t trx_no;
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200371 uint32_t tlli = 0xffeeddcc;
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200372 unsigned long dl_tbf_idle_msec;
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100373
374 uint8_t rbb[64/8];
375
376 gprs_rlcmac_dl_tbf *dl_tbf;
377
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200378 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100379
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100380 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +0100381 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100382
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100383 dl_tbf = create_dl_tbf(bts, ms_class, 0, &trx_no);
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +0200384 ms_confirm_tlli(dl_tbf->ms(), tlli);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100385
386 for (i = 0; i < sizeof(llc_data); i++)
387 llc_data[i] = i%256;
388
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200389 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100390
391 /* Schedule two LLC frames */
Pau Espin Pedrol14beef62022-10-26 19:44:07 +0200392 ms_append_llc_dl_data(dl_tbf->ms(), 1000, llc_data, sizeof(llc_data));
393 ms_append_llc_dl_data(dl_tbf->ms(), 1000, llc_data, sizeof(llc_data));
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100394
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200395 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100396
397 /* Drain the queue */
398 while (dl_tbf->have_data())
399 /* Request to send one RLC/MAC block */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200400 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100401
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200402 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100403
404 /* ACK all blocks */
405 memset(rbb, 0xff, sizeof(rbb));
Max7d32f552017-12-15 11:25:14 +0100406
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +0200407 _rcv_ack(false, dl_tbf, rbb); /* Receive an ACK */
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100408
409 /* Force sending of a single block containing an LLC dummy command */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200410 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100411
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +0200412 _rcv_ack(false, dl_tbf, rbb); /* Receive an ACK */
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100413
414 /* Timeout (make sure fn % 52 remains valid) */
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +0100415 dl_tbf_idle_msec = osmo_tdef_get(the_pcu->T_defs, -2031, OSMO_TDEF_MS, -1);
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200416 fn += 52 * ((msecs_to_frames(dl_tbf_idle_msec + 100) + 51)/ 52);
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200417 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100418
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200419 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FINISHED));
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100420
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +0200421 _rcv_ack(true, dl_tbf, rbb); /* Receive a final ACK */
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100422
423 /* Clean up and ensure tbfs are in the correct state */
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200424 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_WAIT_RELEASE));
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100425 check_tbf(dl_tbf);
426 tbf_free(dl_tbf);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100427 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200428 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100429}
430
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200431static void test_tbf_imsi()
432{
Pau Espin Pedrol945be912021-07-26 14:47:46 +0200433 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100434 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200435 uint8_t ts_no = 4;
436 uint8_t ms_class = 45;
437 uint8_t trx_no;
438 GprsMs *ms1, *ms2;
439
440 gprs_rlcmac_dl_tbf *dl_tbf[2];
441
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200442 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200443
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100444 setup_bts(bts, ts_no);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200445
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100446 dl_tbf[0] = create_dl_tbf(bts, ms_class, 0, &trx_no);
447 dl_tbf[1] = create_dl_tbf(bts, ms_class, 0, &trx_no);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200448
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +0200449 ms_confirm_tlli(dl_tbf[0]->ms(), 0xf1000001);
450 ms_confirm_tlli(dl_tbf[1]->ms(), 0xf1000002);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200451
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100452 ms_set_imsi(dl_tbf[0]->ms(), "001001000000001");
Pau Espin Pedrol7f360e72022-10-21 14:30:36 +0200453 ms1 = bts_ms_store(bts)->get_ms(GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, "001001000000001");
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200454 OSMO_ASSERT(ms1 != NULL);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100455 ms2 = bts_ms_store(bts)->get_ms(0xf1000001);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200456 OSMO_ASSERT(ms2 != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100457 OSMO_ASSERT(strcmp(ms_imsi(ms2), "001001000000001") == 0);
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200458 OSMO_ASSERT(ms1 == ms2);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200459
460 /* change the IMSI on TBF 0 */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100461 ms_set_imsi(dl_tbf[0]->ms(), "001001000000002");
Pau Espin Pedrol7f360e72022-10-21 14:30:36 +0200462 ms1 = bts_ms_store(bts)->get_ms(GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, "001001000000001");
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200463 OSMO_ASSERT(ms1 == NULL);
Pau Espin Pedrol7f360e72022-10-21 14:30:36 +0200464 ms1 = bts_ms_store(bts)->get_ms(GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, "001001000000002");
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200465 OSMO_ASSERT(ms1 != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100466 OSMO_ASSERT(strcmp(ms_imsi(ms2), "001001000000002") == 0);
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200467 OSMO_ASSERT(ms1 == ms2);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200468
Pau Espin Pedrol528820d2020-10-26 12:40:11 +0100469 /* use the same IMSI on TBF 1 */
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200470 {
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100471 ms_ref(ms2);
472 ms_set_imsi(dl_tbf[1]->ms(), "001001000000002");
Pau Espin Pedrol7f360e72022-10-21 14:30:36 +0200473 ms1 = bts_ms_store(bts)->get_ms(GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, "001001000000002");
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200474 OSMO_ASSERT(ms1 != NULL);
475 OSMO_ASSERT(ms1 != ms2);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100476 OSMO_ASSERT(strcmp(ms_imsi(ms1), "001001000000002") == 0);
477 OSMO_ASSERT(strcmp(ms_imsi(ms2), "") == 0);
478 ms_unref(ms2);
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200479 }
480
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100481 ms2 = bts_ms_store(bts)->get_ms(0xf1000001);
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200482 OSMO_ASSERT(ms2 == NULL);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200483
484 tbf_free(dl_tbf[1]);
Pau Espin Pedrol7f360e72022-10-21 14:30:36 +0200485 ms1 = bts_ms_store(bts)->get_ms(GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, "001001000000002");
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200486 OSMO_ASSERT(ms1 == NULL);
487
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100488 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200489 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200490}
491
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200492static void test_tbf_exhaustion()
493{
Pau Espin Pedrol945be912021-07-26 14:47:46 +0200494 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100495 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200496 unsigned i;
497 uint8_t ts_no = 4;
498 uint8_t ms_class = 45;
499 int rc = 0;
500
501 uint8_t buf[256] = {0};
502
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200503 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200504
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100505 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
506 if (!bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +0200507 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
508 abort();
509 }
510
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100511 setup_bts(bts, ts_no);
Alexander Couzens290d9032020-09-16 21:52:02 +0200512 gprs_bssgp_init(bts, 1234, 1234, 1, 1, false, 0, 0, 0);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200513
514 for (i = 0; i < 1024; i++) {
515 uint32_t tlli = 0xc0000000 + i;
516 char imsi[16] = {0};
517 unsigned delay_csec = 1000;
518
Jacob Erlbeck9a2845d2015-05-21 12:06:58 +0200519 snprintf(imsi, sizeof(imsi), "001001%09d", i);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200520
Pau Espin Pedrol8a35e642021-01-18 17:14:14 +0100521 rc = dl_tbf_handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200522 delay_csec, buf, sizeof(buf));
523
524 if (rc < 0)
525 break;
526 }
527
528 OSMO_ASSERT(rc == -EBUSY);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200529 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200530
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100531 TALLOC_FREE(the_pcu);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200532}
533
Jacob Erlbeck41168642015-06-12 13:41:00 +0200534static void test_tbf_dl_llc_loss()
535{
Pau Espin Pedrol945be912021-07-26 14:47:46 +0200536 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100537 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrold29a1432022-12-15 18:57:35 +0100538 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeck41168642015-06-12 13:41:00 +0200539 uint8_t ts_no = 4;
540 uint8_t ms_class = 45;
541 int rc = 0;
542 uint32_t tlli = 0xc0123456;
543 const char *imsi = "001001000123456";
544 unsigned delay_csec = 1000;
545 GprsMs *ms;
546
547 uint8_t buf[19];
548
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100549 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
550 if (!bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +0200551 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
552 abort();
553 }
554
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200555 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200556
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100557 setup_bts(bts, ts_no);
Pau Espin Pedrold29a1432022-12-15 18:57:35 +0100558 pdch = &bts->trx[0].pdch[ts_no];
Pau Espin Pedrol63700ea2019-09-09 13:19:06 +0200559 /* keep the MS object 10 seconds */
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +0100560 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2030, 10, OSMO_TDEF_S) == 0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200561
Alexander Couzens290d9032020-09-16 21:52:02 +0200562 gprs_bssgp_init(bts, 2234, 2234, 1, 1, false, 0, 0, 0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200563
564 /* Handle LLC frame 1 */
565 memset(buf, 1, sizeof(buf));
Pau Espin Pedrol8a35e642021-01-18 17:14:14 +0100566 rc = dl_tbf_handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200567 delay_csec, buf, sizeof(buf));
568 OSMO_ASSERT(rc >= 0);
569
Pau Espin Pedrol7f360e72022-10-21 14:30:36 +0200570 ms = bts_ms_store(bts)->get_ms(GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, imsi);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200571 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100572 OSMO_ASSERT(ms_dl_tbf(ms) != NULL);
573 ms_dl_tbf(ms)->set_ta(0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200574
575 /* Handle LLC frame 2 */
576 memset(buf, 2, sizeof(buf));
Pau Espin Pedrol8a35e642021-01-18 17:14:14 +0100577 rc = dl_tbf_handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200578 delay_csec, buf, sizeof(buf));
579 OSMO_ASSERT(rc >= 0);
580
581 /* TBF establishment fails (timeout) */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100582 tbf_free(ms_dl_tbf(ms));
Jacob Erlbeck41168642015-06-12 13:41:00 +0200583
584 /* Handle LLC frame 3 */
585 memset(buf, 3, sizeof(buf));
Pau Espin Pedrol8a35e642021-01-18 17:14:14 +0100586 rc = dl_tbf_handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200587 delay_csec, buf, sizeof(buf));
588 OSMO_ASSERT(rc >= 0);
589
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100590 OSMO_ASSERT(ms_dl_tbf(ms) != NULL);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200591
Pau Espin Pedrolef1b9842022-12-15 18:47:39 +0100592 /* Here BTS would answer with data_cnf and trigger
Pau Espin Pedrol32252902021-07-29 16:44:11 +0200593 * bts_rcv_imm_ass_cnf(), which would trigger TBF_EV_ASSIGN_PCUIF_CNF.
594 * That in turn would set up timer X2002. Finally, X2002 timeout
595 * moves it to FLOW state. We set X2002 timeout to 0 here to get
596 * immediate trigger through osmo_select_main() */
597 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2002, 0, OSMO_TDEF_MS) == 0);
Pau Espin Pedrolf197f152022-11-17 20:18:46 +0100598 osmo_fsm_inst_dispatch(ms_dl_tbf(ms)->state_fi, TBF_EV_ASSIGN_PCUIF_CNF, NULL);
Pau Espin Pedrol32252902021-07-29 16:44:11 +0200599 osmo_select_main(0);
Pau Espin Pedrol65bba932021-07-26 12:06:20 +0200600 OSMO_ASSERT(ms_dl_tbf(ms)->state_is(TBF_ST_FLOW));
601
Jacob Erlbeck41168642015-06-12 13:41:00 +0200602 /* Get first BSN */
603 struct msgb *msg;
604 int fn = 0;
605 uint8_t expected_data = 1;
Maxd3a0d912019-03-05 16:15:01 +0100606 static uint8_t exp[][GSM_MACBLOCK_LEN] = {
607 { 0x07, 0x00, 0x00, 0x4d, 0x01, 0x01, 0x01,
608 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
609 { 0x07, 0x00, 0x02, 0x4d, 0x02, 0x02, 0x02,
610 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 },
Pau Espin Pedrolef1b9842022-12-15 18:47:39 +0100611 /* On last DL block, PCU requests polling (DL ACK/NACK): S/P 1 and RRBP 01, hence 0x07 becomes 0xf1 */
612 { 0x1f, 0x01, 0x04, 0x4d, 0x03, 0x03, 0x03,
Maxd3a0d912019-03-05 16:15:01 +0100613 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 },
614 };
Jacob Erlbeck41168642015-06-12 13:41:00 +0200615
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100616 while (ms_dl_tbf(ms)->have_data()) {
Pau Espin Pedrold29a1432022-12-15 18:57:35 +0100617 msg = ms_dl_tbf(ms)->create_dl_acked_block(fn += 4, pdch);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200618 fprintf(stderr, "MSG = %s\n", msgb_hexdump(msg));
Maxd3a0d912019-03-05 16:15:01 +0100619 if (!msgb_eq_data_print(msg, exp[expected_data - 1], GSM_MACBLOCK_LEN))
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200620 fprintf(stderr, "%s failed at %u\n", __func__, expected_data);
Maxd3a0d912019-03-05 16:15:01 +0100621
Jacob Erlbeck41168642015-06-12 13:41:00 +0200622 expected_data += 1;
623 }
Jacob Erlbeck409efa12015-06-12 14:06:09 +0200624 OSMO_ASSERT(expected_data-1 == 3);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200625
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200626 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200627
Pau Espin Pedrol52e2c082022-05-09 17:12:53 +0200628 /* Restore MS release timeout to 0 to make sure it is freed immediately: */
629 ms_set_timeout(ms, 0);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100630 TALLOC_FREE(the_pcu);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200631}
632
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100633static gprs_rlcmac_ul_tbf *establish_ul_tbf_single_phase(struct gprs_rlcmac_bts *bts,
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100634 struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta)
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200635{
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200636 GprsMs *ms;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200637 int tfi = 0;
638 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200639
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100640 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &pdch->trx->trx_no, -1);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200641
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100642 bts_handle_rach(bts, 0x03, *fn, qta);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200643
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100644 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, pdch->trx->trx_no, pdch->ts_no);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200645 OSMO_ASSERT(ul_tbf != NULL);
646
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200647 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200648
649 uint8_t data_msg[23] = {
650 0x00, /* GPRS_RLCMAC_DATA_BLOCK << 6 */
651 uint8_t(1 | (tfi << 2)),
652 uint8_t(1), /* BSN:7, E:1 */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200653 uint8_t(tlli >> 24), uint8_t(tlli >> 16),
654 uint8_t(tlli >> 8), uint8_t(tlli), /* TLLI */
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200655 };
656
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200657 pdch->rcv_block(&data_msg[0], sizeof(data_msg), *fn, &meas);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200658
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100659 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200660 OSMO_ASSERT(ms != NULL);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200661
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200662 return ul_tbf;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200663}
664
Pau Espin Pedrol99360a32021-03-09 17:18:12 +0100665static void send_ul_mac_block_buf(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_pdch *pdch,
666 unsigned fn, uint8_t *buf, int num_bytes)
667{
Pau Espin Pedrolfecab502021-03-17 15:26:37 +0100668 bts_set_current_block_frame_number(bts, fn);
Pau Espin Pedrol99360a32021-03-09 17:18:12 +0100669 pdch->rcv_block(buf, num_bytes, fn, &meas);
670 pdch_ulc_expire_fn(pdch->ulc, fn);
671}
672
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100673static void send_ul_mac_block(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_pdch *pdch,
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200674 RlcMacUplink_t *ulreq, unsigned fn)
675{
676 bitvec *rlc_block;
677 uint8_t buf[64];
678 int num_bytes;
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200679
Alexander Couzensccde5c92017-02-04 03:10:08 +0100680 rlc_block = bitvec_alloc(23, tall_pcu_ctx);
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200681
Pau Espin Pedrol5e300ce2020-02-03 17:18:03 +0100682 OSMO_ASSERT(encode_gsm_rlcmac_uplink(rlc_block, ulreq) == 0);
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200683 num_bytes = bitvec_pack(rlc_block, &buf[0]);
684 OSMO_ASSERT(size_t(num_bytes) < sizeof(buf));
685 bitvec_free(rlc_block);
686
Pau Espin Pedrol99360a32021-03-09 17:18:12 +0100687 send_ul_mac_block_buf(bts, pdch, fn, &buf[0], num_bytes);
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200688}
689
Pau Espin Pedrol58046e42021-03-29 19:01:13 +0200690
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100691static uint32_t get_poll_fn(struct gprs_rlcmac_tbf *tbf, struct gprs_rlcmac_pdch *pdch)
Pau Espin Pedrol58046e42021-03-29 19:01:13 +0200692{
Pau Espin Pedrol58046e42021-03-29 19:01:13 +0200693 struct pdch_ulc *ulc = pdch->ulc;
694 struct rb_node *node;
695 struct pdch_ulc_node *item;
696
697 for (node = rb_first(&ulc->tree_root); node; node = rb_next(node)) {
698 item = container_of(node, struct pdch_ulc_node, node);
699 if (item->type == PDCH_ULC_NODE_TBF_POLL && item->tbf_poll.poll_tbf == tbf)
700 return item->fn;
701 }
702 OSMO_ASSERT(0);
703}
704
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200705static void send_control_ack(gprs_rlcmac_tbf *tbf)
706{
707 RlcMacUplink_t ulreq = {0};
708
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200709 ulreq.u.MESSAGE_TYPE = MT_PACKET_CONTROL_ACK;
710 Packet_Control_Acknowledgement_t *ctrl_ack =
711 &ulreq.u.Packet_Control_Acknowledgement;
712
713 ctrl_ack->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
714 ctrl_ack->TLLI = tbf->tlli();
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100715 send_ul_mac_block(tbf->bts, tbf->control_ts,
Pau Espin Pedrol16e16782021-03-29 19:10:19 +0200716 &ulreq, get_poll_fn(tbf, tbf->control_ts));
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200717}
718
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100719static void send_empty_block(gprs_rlcmac_tbf *tbf, struct gprs_rlcmac_pdch *pdch, unsigned fn)
Pau Espin Pedrol99360a32021-03-09 17:18:12 +0100720{
Pau Espin Pedrol99360a32021-03-09 17:18:12 +0100721 send_ul_mac_block_buf(tbf->bts, pdch, fn, NULL, 0);
722}
723
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100724static gprs_rlcmac_ul_tbf *puan_urbb_len_issue(struct gprs_rlcmac_bts *bts,
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100725 struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta,
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530726 uint8_t ms_class, uint8_t egprs_ms_class)
727{
728 GprsMs *ms;
729 uint32_t rach_fn = *fn - 51;
730 uint32_t sba_fn = *fn + 52;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +0100731 int tfi = 0;
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530732 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530733 RlcMacUplink_t ulreq = {0};
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530734 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530735
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530736 /* needed to set last_rts_fn in the PDCH object */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100737 request_dl_rlc_block(bts, pdch, fn);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530738
739 /*
740 * simulate RACH, this sends an Immediate
741 * Assignment Uplink on the AGCH
742 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100743 bts_handle_rach(bts, 0x73, rach_fn, qta);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530744
745 /* get next free TFI */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100746 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &pdch->trx->trx_no, -1);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530747
748 /* fake a resource request */
749 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
750 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
751 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
752 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100753 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
754 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530755 Count_MS_RA_capability_value = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100756 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530757 MS_RA_capability_value[0].u.Content.
758 Exist_Multislot_capability = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100759 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530760 MS_RA_capability_value[0].u.Content.Multislot_capability.
761 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100762 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530763 MS_RA_capability_value[0].u.Content.Multislot_capability.
764 GPRS_multislot_class = ms_class;
765 if (egprs_ms_class) {
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100766 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530767 MS_RA_capability_value[0].u.Content.
768 Multislot_capability.Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100769 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530770 MS_RA_capability_value[0].u.Content.
771 Multislot_capability.EGPRS_multislot_class = ms_class;
772 }
773
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100774 send_ul_mac_block(bts, pdch, &ulreq, sba_fn);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530775
776 /* check the TBF */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100777 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, pdch->trx->trx_no, pdch->ts_no);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530778 OSMO_ASSERT(ul_tbf);
779 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
780
781 /* send packet uplink assignment */
782 *fn = sba_fn;
783 request_dl_rlc_block(ul_tbf, fn);
784
785 /* send real acknowledgement */
786 send_control_ack(ul_tbf);
787
788 check_tbf(ul_tbf);
789 /* send fake data */
790 uint8_t data_msg[42] = {
791 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
Neels Hofmeyrd34646a2017-02-08 17:07:40 +0100792 (uint8_t)(tfi << 1),
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530793 1, /* BSN:7, E:1 */
794 };
795
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530796 pdch->rcv_block(&data_msg[0], 23, *fn, &meas);
797
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100798 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530799 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100800 OSMO_ASSERT(ms_ta(ms) == qta/4);
801 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530802
803 /*
804 * TS 44.060, B.8.1
805 * first seg received first, later second seg
806 */
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530807 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
808 egprs3->si = 0;
809 egprs3->r = 1;
810 egprs3->cv = 7;
811 egprs3->tfi_hi = tfi & 0x03;
812 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
813 egprs3->bsn1_hi = 1;
814 egprs3->bsn1_lo = 0;
815 egprs3->cps_hi = 1;
816 data_msg[3] = 0xff;
817 egprs3->pi = 0;
818 egprs3->cps_lo = 1;
819 egprs3->rsb = 0;
820 egprs3->spb = 0;
821 egprs3->pi = 0;
822
823 pdch->rcv_block(data_msg, 42, *fn, &meas);
824
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +0200825 osmo_fsm_inst_dispatch(ul_tbf->ul_ack_fsm.fi, TBF_UL_ACK_EV_SCHED_ACK, NULL);
Pau Espin Pedrol5ba3ef92022-12-12 18:02:25 +0100826 struct msgb *msg1 = tbf_ul_ack_create_rlcmac_msg(ul_tbf, pdch, *fn);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530827
Pau Espin Pedrolc432e062021-05-11 13:17:31 +0200828 static uint8_t exp1[] = { 0x40, 0x24, 0x01, 0x0b, 0x3e, 0x24, 0x46, 0x68, 0x9c, 0x70, 0x87, 0xb0,
829 0x06, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b
Maxd3a0d912019-03-05 16:15:01 +0100830 };
831
832 if (!msgb_eq_data_print(msg1, exp1, GSM_MACBLOCK_LEN)) {
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200833 fprintf(stderr, "%s test failed on 1st segment!\n", __func__);
Maxd3a0d912019-03-05 16:15:01 +0100834 return NULL;
835 }
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530836
837 egprs3->si = 0;
838 egprs3->r = 1;
839 egprs3->cv = 7;
840 egprs3->tfi_hi = tfi & 0x03;
841 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
842 egprs3->bsn1_hi = 4;
843 egprs3->bsn1_lo = 0;
844 egprs3->cps_hi = 1;
845 data_msg[3] = 0xff;
846 egprs3->pi = 0;
847 egprs3->cps_lo = 1;
848 egprs3->rsb = 0;
849 egprs3->spb = 0;
850
851 pdch->rcv_block(data_msg, 42, *fn, &meas);
852
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +0200853 osmo_fsm_inst_dispatch(ul_tbf->ul_ack_fsm.fi, TBF_UL_ACK_EV_SCHED_ACK, NULL);
Pau Espin Pedrol5ba3ef92022-12-12 18:02:25 +0100854 msg1 = tbf_ul_ack_create_rlcmac_msg(ul_tbf, pdch, *fn);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530855
Pau Espin Pedrolc432e062021-05-11 13:17:31 +0200856 static uint8_t exp2[] = { 0x40, 0x24, 0x01, 0x0b, 0x3e, 0x24, 0x46, 0x68, 0x9c, 0x70, 0x88, 0xb0,
857 0x06, 0x8b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b
Maxd3a0d912019-03-05 16:15:01 +0100858 };
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530859
Maxd3a0d912019-03-05 16:15:01 +0100860 if (!msgb_eq_data_print(msg1, exp2, GSM_MACBLOCK_LEN)) {
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200861 fprintf(stderr, "%s test failed on 2nd segment!\n", __func__);
Maxd3a0d912019-03-05 16:15:01 +0100862 return NULL;
863 }
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530864 return ul_tbf;
865}
866
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100867static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(struct gprs_rlcmac_bts *bts,
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100868 struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta,
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530869 uint8_t ms_class, uint8_t egprs_ms_class)
870{
871 GprsMs *ms;
872 uint32_t rach_fn = *fn - 51;
873 uint32_t sba_fn = *fn + 52;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530874 int tfi = 0, i = 0;
875 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530876 RlcMacUplink_t ulreq = {0};
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530877 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530878
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530879 /* needed to set last_rts_fn in the PDCH object */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100880 request_dl_rlc_block(bts, pdch, fn);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530881
882 /*
883 * simulate RACH, this sends an Immediate
884 * Assignment Uplink on the AGCH
885 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100886 bts_handle_rach(bts, 0x73, rach_fn, qta);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530887
888 /* get next free TFI */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100889 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &pdch->trx->trx_no, -1);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530890
891 /* fake a resource request */
892 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
893 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
894 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
895 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100896 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
897 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530898 Count_MS_RA_capability_value = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100899 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530900 MS_RA_capability_value[0].u.Content.
901 Exist_Multislot_capability = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100902 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530903 MS_RA_capability_value[0].u.Content.Multislot_capability.
904 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100905 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530906 MS_RA_capability_value[0].u.Content.Multislot_capability.
907 GPRS_multislot_class = ms_class;
908 if (egprs_ms_class) {
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100909 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530910 MS_RA_capability_value[0].u.Content.
911 Multislot_capability.Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100912 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530913 MS_RA_capability_value[0].u.Content.
914 Multislot_capability.EGPRS_multislot_class = ms_class;
915 }
916
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100917 send_ul_mac_block(bts, pdch, &ulreq, sba_fn);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530918
919 /* check the TBF */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100920 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, pdch->trx->trx_no, pdch->ts_no);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530921 OSMO_ASSERT(ul_tbf != NULL);
922 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
923
924 /* send packet uplink assignment */
925 *fn = sba_fn;
926 request_dl_rlc_block(ul_tbf, fn);
927
928 /* send real acknowledgement */
929 send_control_ack(ul_tbf);
930
931 check_tbf(ul_tbf);
932
933 /* send fake data */
934 uint8_t data_msg[42] = {
935 0x00 | 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
936 uint8_t(0 | (tfi << 1)),
937 uint8_t(1), /* BSN:7, E:1 */
938 };
939
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530940 pdch->rcv_block(&data_msg[0], 23, *fn, &meas);
941
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100942 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530943 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100944 OSMO_ASSERT(ms_ta(ms) == qta/4);
945 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530946
947 /*
948 * TS 44.060, B.8.1
949 * first seg received first, later second seg
950 */
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530951 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
952 egprs3->si = 1;
953 egprs3->r = 1;
954 egprs3->cv = 7;
955 egprs3->tfi_hi = tfi & 0x03;
956 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
957 egprs3->bsn1_hi = 1;
958 egprs3->bsn1_lo = 0;
959 egprs3->cps_hi = 1;
960 data_msg[3] = 0xff;
961 egprs3->pi = 0;
962 egprs3->cps_lo = 1;
963 egprs3->rsb = 0;
964 egprs3->spb = 2;
965 egprs3->pi = 0;
966
967 pdch->rcv_block(data_msg, 42, *fn, &meas);
968
969 struct gprs_rlc_data *block = ul_tbf->m_rlc.block(1);
970
971 /* check the status of the block */
972 OSMO_ASSERT(block->spb_status.block_status_ul ==
973 EGPRS_RESEG_FIRST_SEG_RXD);
974
975 egprs3->si = 1;
976 egprs3->r = 1;
977 egprs3->cv = 7;
978 egprs3->tfi_hi = tfi & 0x03;
979 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
980 egprs3->bsn1_hi = 1;
981 egprs3->bsn1_lo = 0;
982 egprs3->cps_hi = 1;
983 data_msg[3] = 0xff;
984 egprs3->pi = 0;
985 egprs3->cps_lo = 1;
986 egprs3->rsb = 0;
987 egprs3->spb = 3;
988
989 pdch->rcv_block(data_msg, 42, *fn, &meas);
990
991 /* check the status of the block */
992 OSMO_ASSERT(block->spb_status.block_status_ul ==
993 EGPRS_RESEG_DEFAULT);
994 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +0100995 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530996 /* Assembled MCS is MCS6. so the size is 74 */
997 OSMO_ASSERT(block->len == 74);
998
999 /*
1000 * TS 44.060, B.8.1
1001 * second seg first, later first seg
1002 */
1003 memset(data_msg, 0, sizeof(data_msg));
1004
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301005 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1006 egprs3->si = 1;
1007 egprs3->r = 1;
1008 egprs3->cv = 7;
1009 egprs3->tfi_hi = tfi & 0x03;
1010 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1011 egprs3->bsn1_hi = 2;
1012 egprs3->bsn1_lo = 0;
1013 egprs3->cps_hi = 1;
1014 data_msg[3] = 0xff;
1015 egprs3->pi = 0;
1016 egprs3->cps_lo = 1;
1017 egprs3->rsb = 0;
1018 egprs3->spb = 3;
1019 egprs3->pi = 0;
1020
1021 pdch->rcv_block(data_msg, 42, *fn, &meas);
1022
1023 block = ul_tbf->m_rlc.block(2);
1024 /* check the status of the block */
1025 OSMO_ASSERT(block->spb_status.block_status_ul ==
1026 EGPRS_RESEG_SECOND_SEG_RXD);
1027
1028 egprs3->si = 1;
1029 egprs3->r = 1;
1030 egprs3->cv = 7;
1031 egprs3->tfi_hi = tfi & 0x03;
1032 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1033 egprs3->bsn1_hi = 2;
1034 egprs3->bsn1_lo = 0;
1035 egprs3->cps_hi = 1;
1036 data_msg[3] = 0xff;
1037 egprs3->pi = 0;
1038 egprs3->cps_lo = 1;
1039 egprs3->rsb = 0;
1040 egprs3->spb = 2;
1041 egprs3->pi = 0;
1042
1043 pdch->rcv_block(data_msg, 42, *fn, &meas);
1044
1045 /* check the status of the block */
1046 OSMO_ASSERT(block->spb_status.block_status_ul ==
1047 EGPRS_RESEG_DEFAULT);
1048 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001049 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301050 /* Assembled MCS is MCS6. so the size is 74 */
1051 OSMO_ASSERT(block->len == 74);
1052
1053 /*
1054 * TS 44.060, B.8.1
1055 * Error scenario with spb as 1
1056 */
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301057 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1058 egprs3->si = 1;
1059 egprs3->r = 1;
1060 egprs3->cv = 7;
1061 egprs3->tfi_hi = tfi & 0x03;
1062 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1063 egprs3->bsn1_hi = 3;
1064 egprs3->bsn1_lo = 0;
1065 egprs3->cps_hi = 1;
1066 data_msg[3] = 0xff;
1067 egprs3->pi = 0;
1068 egprs3->cps_lo = 1;
1069 egprs3->rsb = 0;
1070 egprs3->spb = 1;
1071 egprs3->pi = 0;
1072
1073 pdch->rcv_block(data_msg, 42, *fn, &meas);
1074
1075 block = ul_tbf->m_rlc.block(3);
1076 /* check the status of the block */
1077 OSMO_ASSERT(block->spb_status.block_status_ul ==
1078 EGPRS_RESEG_DEFAULT);
1079 /*
1080 * TS 44.060, B.8.1
1081 * comparison of rlc_data for multiple scenarios
1082 * Receive First, the second(BSN 3)
1083 * Receive First, First then Second(BSN 4)
1084 * Receive Second then First(BSN 5)
1085 * after above 3 scenarios are triggered,
1086 * rlc_data of all 3 BSN are compared
1087 */
1088
1089 /* Initialize the data_msg */
1090 for (i = 0; i < 42; i++)
1091 data_msg[i] = i;
1092
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301093 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1094 egprs3->si = 1;
1095 egprs3->r = 1;
1096 egprs3->cv = 7;
1097 egprs3->tfi_hi = tfi & 0x03;
1098 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1099 egprs3->bsn1_hi = 3;
1100 egprs3->bsn1_lo = 0;
1101 egprs3->cps_hi = 1;
1102 data_msg[3] = 0xff;
1103 egprs3->pi = 0;
1104 egprs3->cps_lo = 1;
1105 egprs3->rsb = 0;
1106 egprs3->spb = 2;
1107 egprs3->pi = 0;
1108
1109 pdch->rcv_block(data_msg, 42, *fn, &meas);
1110
1111 block = ul_tbf->m_rlc.block(3);
1112 /* check the status of the block */
1113 OSMO_ASSERT(block->spb_status.block_status_ul ==
1114 EGPRS_RESEG_FIRST_SEG_RXD);
1115
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301116 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1117 egprs3->si = 1;
1118 egprs3->r = 1;
1119 egprs3->cv = 7;
1120 egprs3->tfi_hi = tfi & 0x03;
1121 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1122 egprs3->bsn1_hi = 3;
1123 egprs3->bsn1_lo = 0;
1124 egprs3->cps_hi = 1;
1125 data_msg[3] = 0xff;
1126 egprs3->pi = 0;
1127 egprs3->cps_lo = 1;
1128 egprs3->rsb = 0;
1129 egprs3->spb = 3;
1130 egprs3->pi = 0;
1131
1132 pdch->rcv_block(data_msg, 42, *fn, &meas);
1133
1134 block = ul_tbf->m_rlc.block(3);
1135 /* check the status of the block */
1136 OSMO_ASSERT(block->spb_status.block_status_ul ==
1137 EGPRS_RESEG_DEFAULT);
1138 /* Assembled MCS is MCS6. so the size is 74 */
1139 OSMO_ASSERT(block->len == 74);
1140 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001141 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301142
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301143 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1144 egprs3->si = 1;
1145 egprs3->r = 1;
1146 egprs3->cv = 7;
1147 egprs3->tfi_hi = tfi & 0x03;
1148 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1149 egprs3->bsn1_hi = 4;
1150 egprs3->bsn1_lo = 0;
1151 egprs3->cps_hi = 1;
1152 data_msg[3] = 0xff;
1153 egprs3->pi = 0;
1154 egprs3->cps_lo = 1;
1155 egprs3->rsb = 0;
1156 egprs3->spb = 2;
1157 egprs3->pi = 0;
1158
1159 pdch->rcv_block(data_msg, 42, *fn, &meas);
1160
1161 block = ul_tbf->m_rlc.block(4);
1162 /* check the status of the block */
1163 OSMO_ASSERT(block->spb_status.block_status_ul ==
1164 EGPRS_RESEG_FIRST_SEG_RXD);
1165
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301166 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1167 egprs3->si = 1;
1168 egprs3->r = 1;
1169 egprs3->cv = 7;
1170 egprs3->tfi_hi = tfi & 0x03;
1171 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1172 egprs3->bsn1_hi = 4;
1173 egprs3->bsn1_lo = 0;
1174 egprs3->cps_hi = 1;
1175 data_msg[3] = 0xff;
1176 egprs3->pi = 0;
1177 egprs3->cps_lo = 1;
1178 egprs3->rsb = 0;
1179 egprs3->spb = 2;
1180 egprs3->pi = 0;
1181
1182 pdch->rcv_block(data_msg, 42, *fn, &meas);
1183
1184 block = ul_tbf->m_rlc.block(4);
1185 /* check the status of the block */
1186 OSMO_ASSERT(block->spb_status.block_status_ul ==
1187 EGPRS_RESEG_FIRST_SEG_RXD);
1188
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301189 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1190 egprs3->si = 1;
1191 egprs3->r = 1;
1192 egprs3->cv = 7;
1193 egprs3->tfi_hi = tfi & 0x03;
1194 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1195 egprs3->bsn1_hi = 4;
1196 egprs3->bsn1_lo = 0;
1197 egprs3->cps_hi = 1;
1198 data_msg[3] = 0xff;
1199 egprs3->pi = 0;
1200 egprs3->cps_lo = 1;
1201 egprs3->rsb = 0;
1202 egprs3->spb = 3;
1203 egprs3->pi = 0;
1204
1205 pdch->rcv_block(data_msg, 42, *fn, &meas);
1206
1207 block = ul_tbf->m_rlc.block(4);
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
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301216 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1217 egprs3->si = 1;
1218 egprs3->r = 1;
1219 egprs3->cv = 7;
1220 egprs3->tfi_hi = tfi & 0x03;
1221 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1222 egprs3->bsn1_hi = 5;
1223 egprs3->bsn1_lo = 0;
1224 egprs3->cps_hi = 1;
1225 data_msg[3] = 0xff;
1226 egprs3->pi = 0;
1227 egprs3->cps_lo = 1;
1228 egprs3->rsb = 0;
1229 egprs3->spb = 3;
1230 egprs3->pi = 0;
1231
1232 pdch->rcv_block(data_msg, 42, *fn, &meas);
1233
1234 block = ul_tbf->m_rlc.block(5);
1235 /* check the status of the block */
1236 OSMO_ASSERT(block->spb_status.block_status_ul ==
1237 EGPRS_RESEG_SECOND_SEG_RXD);
1238
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301239 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1240 egprs3->si = 1;
1241 egprs3->r = 1;
1242 egprs3->cv = 7;
1243 egprs3->tfi_hi = tfi & 0x03;
1244 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1245 egprs3->bsn1_hi = 5;
1246 egprs3->bsn1_lo = 0;
1247 egprs3->cps_hi = 1;
1248 data_msg[3] = 0xff;
1249 egprs3->pi = 0;
1250 egprs3->cps_lo = 1;
1251 egprs3->rsb = 0;
1252 egprs3->spb = 2;
1253 egprs3->pi = 0;
1254
1255 pdch->rcv_block(data_msg, 42, *fn, &meas);
1256
1257 block = ul_tbf->m_rlc.block(5);
1258
1259 /* check the status of the block */
1260 OSMO_ASSERT(block->spb_status.block_status_ul ==
1261 EGPRS_RESEG_DEFAULT);
1262 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001263 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301264 /* Assembled MCS is MCS6. so the size is 74 */
1265 OSMO_ASSERT(block->len == 74);
1266
1267 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->len ==
1268 ul_tbf->m_rlc.block(4)->len);
1269 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->len ==
1270 ul_tbf->m_rlc.block(3)->len);
1271
1272 /* Compare the spb status of each BSNs(3,4,5). should be same */
1273 OSMO_ASSERT(
1274 ul_tbf->m_rlc.block(5)->spb_status.block_status_ul ==
1275 ul_tbf->m_rlc.block(4)->spb_status.block_status_ul);
1276 OSMO_ASSERT(
1277 ul_tbf->m_rlc.block(5)->spb_status.block_status_ul ==
1278 ul_tbf->m_rlc.block(3)->spb_status.block_status_ul);
1279
1280 /* Compare the Assembled MCS of each BSNs(3,4,5). should be same */
1281 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->cs_last ==
1282 ul_tbf->m_rlc.block(4)->cs_last);
1283 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->cs_last ==
1284 ul_tbf->m_rlc.block(3)->cs_last);
1285
1286 /* Compare the data of each BSNs(3,4,5). should be same */
1287 OSMO_ASSERT(
1288 !memcmp(ul_tbf->m_rlc.block(5)->block,
1289 ul_tbf->m_rlc.block(4)->block, ul_tbf->m_rlc.block(5)->len
1290 ));
1291 OSMO_ASSERT(
1292 !memcmp(ul_tbf->m_rlc.block(5)->block,
1293 ul_tbf->m_rlc.block(3)->block, ul_tbf->m_rlc.block(5)->len
1294 ));
1295
1296 return ul_tbf;
1297}
1298
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001299static gprs_rlcmac_ul_tbf *establish_ul_tbf(struct gprs_rlcmac_bts *bts,
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001300 struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta,
sivasankari1d8744c2017-01-24 15:53:35 +05301301 uint8_t ms_class, uint8_t egprs_ms_class)
1302{
sivasankari1d8744c2017-01-24 15:53:35 +05301303 uint32_t rach_fn = *fn - 51;
1304 uint32_t sba_fn = *fn + 52;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001305 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301306 gprs_rlcmac_ul_tbf *ul_tbf;
sivasankari1d8744c2017-01-24 15:53:35 +05301307 RlcMacUplink_t ulreq = {0};
sivasankari1d8744c2017-01-24 15:53:35 +05301308
sivasankari1d8744c2017-01-24 15:53:35 +05301309 /* needed to set last_rts_fn in the PDCH object */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001310 request_dl_rlc_block(bts, pdch, fn);
sivasankari1d8744c2017-01-24 15:53:35 +05301311
1312 /*
1313 * simulate RACH, this sends an Immediate
1314 * Assignment Uplink on the AGCH
1315 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001316 bts_handle_rach(bts, 0x73, rach_fn, qta);
sivasankari1d8744c2017-01-24 15:53:35 +05301317
1318 /* get next free TFI */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001319 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &pdch->trx->trx_no, -1);
sivasankari1d8744c2017-01-24 15:53:35 +05301320
1321 /* fake a resource request */
1322 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
1323 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
1324 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
1325 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001326 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
1327 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301328 Count_MS_RA_capability_value = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001329 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301330 MS_RA_capability_value[0].u.Content.
1331 Exist_Multislot_capability = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001332 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301333 MS_RA_capability_value[0].u.Content.Multislot_capability.
1334 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001335 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301336 MS_RA_capability_value[0].u.Content.Multislot_capability.
1337 GPRS_multislot_class = ms_class;
1338 if (egprs_ms_class) {
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001339 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301340 MS_RA_capability_value[0].u.Content.
1341 Multislot_capability.Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001342 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301343 MS_RA_capability_value[0].u.Content.
1344 Multislot_capability.EGPRS_multislot_class = ms_class;
1345 }
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001346 send_ul_mac_block(bts, pdch, &ulreq, sba_fn);
sivasankari1d8744c2017-01-24 15:53:35 +05301347
1348 /* check the TBF */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001349 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, pdch->trx->trx_no, pdch->ts_no);
sivasankari1d8744c2017-01-24 15:53:35 +05301350 /* send packet uplink assignment */
1351 *fn = sba_fn;
1352 request_dl_rlc_block(ul_tbf, fn);
1353
1354 /* send real acknowledgement */
1355 send_control_ack(ul_tbf);
1356
1357 check_tbf(ul_tbf);
1358
1359 return ul_tbf;
1360}
1361
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001362static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_no_length(struct gprs_rlcmac_bts *bts,
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001363 struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta,
sivasankari1d8744c2017-01-24 15:53:35 +05301364 uint8_t ms_class, uint8_t egprs_ms_class, gprs_rlcmac_ul_tbf *ul_tbf)
1365{
1366 OSMO_ASSERT(ul_tbf);
1367 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1368 GprsMs *ms;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001369 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301370
1371 /* send fake data with cv=0*/
1372 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1373 uint8_t data[49] = {0};
1374
1375 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1376
1377 /*header_construction */
1378 memset(data, 0x2b, sizeof(data));
1379 /* Message with CRBB */
1380 for (int i = 0 ; i < 80; i++) {
1381 hdr3->r = 0;
1382 hdr3->si = 0;
1383 hdr3->cv = 10;
1384 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1385 hdr3->tfi_lo = tfi & 0x7;
1386 hdr3->bsn1_hi = ((i * 2)&0x1f);
1387 hdr3->bsn1_lo = ((i * 2)/32);
1388 hdr3->cps_hi = 0;
1389 hdr3->cps_lo = 0;
1390 hdr3->spb = 0;
1391 hdr3->rsb = 0;
1392 hdr3->pi = 0;
1393 hdr3->spare = 0;
1394 hdr3->dummy = 1;
1395 data[4] = 0x0;
1396 data[5] = 0x0;
1397 data[6] = 0x2b;
1398 data[7] = 0x2b;
sivasankari1d8744c2017-01-24 15:53:35 +05301399 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1400 }
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +02001401 osmo_fsm_inst_dispatch(ul_tbf->ul_ack_fsm.fi, TBF_UL_ACK_EV_SCHED_ACK, NULL);
Pau Espin Pedrol5ba3ef92022-12-12 18:02:25 +01001402 tbf_ul_ack_create_rlcmac_msg(ul_tbf, pdch, *fn);
sivasankari1d8744c2017-01-24 15:53:35 +05301403 memset(data, 0x2b, sizeof(data));
1404 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1405 hdr3->r = 0;
1406 hdr3->si = 0;
1407 hdr3->cv = 0;
1408 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1409 hdr3->tfi_lo = tfi & 0x7;
1410 hdr3->bsn1_hi = 0;
1411 hdr3->bsn1_lo = 2;
1412 hdr3->cps_hi = 0;
1413 hdr3->cps_lo = 0;
1414 hdr3->spb = 0;
1415 hdr3->rsb = 0;
1416 hdr3->pi = 0;
1417 hdr3->spare = 0;
1418 hdr3->dummy = 1;
1419 data[4] = 0x0;
1420 data[5] = 0x2b;
1421 data[6] = 0x2b;
1422 data[7] = 0x2b;
1423
sivasankari1d8744c2017-01-24 15:53:35 +05301424 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1425
1426 request_dl_rlc_block(ul_tbf, fn);
1427
1428 check_tbf(ul_tbf);
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +02001429 OSMO_ASSERT(tbf_ul_ack_fi(ul_tbf)->state == TBF_UL_ACK_ST_NONE);
sivasankari1d8744c2017-01-24 15:53:35 +05301430
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001431 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
sivasankari1d8744c2017-01-24 15:53:35 +05301432 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001433 OSMO_ASSERT(ms_ta(ms) == qta/4);
1434 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
sivasankari1d8744c2017-01-24 15:53:35 +05301435
1436 return ul_tbf;
1437}
1438
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001439static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_with_length(struct gprs_rlcmac_bts *bts,
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001440 struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta,
sivasankari1d8744c2017-01-24 15:53:35 +05301441 uint8_t ms_class, uint8_t egprs_ms_class, gprs_rlcmac_ul_tbf *ul_tbf)
1442{
1443 OSMO_ASSERT(ul_tbf);
1444 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1445 GprsMs *ms;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001446 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301447
1448 check_tbf(ul_tbf);
1449 /* send fake data with cv=0*/
1450 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1451 uint8_t data[49] = {0};
1452
1453 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1454
1455 /*header_construction */
1456 memset(data, 0x2b, sizeof(data));
1457
1458 /* Message with URBB & URBB length */
1459 for (int i = 0 ; i < 20; i++) {
1460 hdr3->r = 0;
1461 hdr3->si = 0;
1462 hdr3->cv = 10;
1463 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1464 hdr3->tfi_lo = tfi & 0x7;
1465 hdr3->bsn1_hi = ((i * 2)&0x1f);
1466 hdr3->bsn1_lo = ((i * 2)/32);
1467 hdr3->cps_hi = 0;
1468 hdr3->cps_lo = 0;
1469 hdr3->spb = 0;
1470 hdr3->rsb = 0;
1471 hdr3->pi = 0;
1472 hdr3->spare = 0;
1473 hdr3->dummy = 1;
1474 data[4] = 0x0;
1475 data[5] = 0x0;
1476 data[6] = 0x2b;
1477 data[7] = 0x2b;
sivasankari1d8744c2017-01-24 15:53:35 +05301478 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1479 }
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +02001480 osmo_fsm_inst_dispatch(ul_tbf->ul_ack_fsm.fi, TBF_UL_ACK_EV_SCHED_ACK, NULL);
Pau Espin Pedrol5ba3ef92022-12-12 18:02:25 +01001481 tbf_ul_ack_create_rlcmac_msg(ul_tbf, pdch, *fn);
sivasankari1d8744c2017-01-24 15:53:35 +05301482 memset(data, 0x2b, sizeof(data));
1483 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1484 hdr3->r = 0;
1485 hdr3->si = 0;
1486 hdr3->cv = 0;
1487 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1488 hdr3->tfi_lo = tfi & 0x7;
1489 hdr3->bsn1_hi = 0;
1490 hdr3->bsn1_lo = 2;
1491 hdr3->cps_hi = 0;
1492 hdr3->cps_lo = 0;
1493 hdr3->spb = 0;
1494 hdr3->rsb = 0;
1495 hdr3->pi = 0;
1496 hdr3->spare = 0;
1497 hdr3->dummy = 1;
1498 data[4] = 0x0;
1499 data[5] = 0x2b;
1500 data[6] = 0x2b;
1501 data[7] = 0x2b;
1502
sivasankari1d8744c2017-01-24 15:53:35 +05301503 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +02001504 osmo_fsm_inst_dispatch(ul_tbf->ul_ack_fsm.fi, TBF_UL_ACK_EV_SCHED_ACK, NULL);
Pau Espin Pedrol5ba3ef92022-12-12 18:02:25 +01001505 tbf_ul_ack_create_rlcmac_msg(ul_tbf, pdch, *fn);
sivasankari1d8744c2017-01-24 15:53:35 +05301506
1507 request_dl_rlc_block(ul_tbf, fn);
1508
1509 check_tbf(ul_tbf);
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +02001510 OSMO_ASSERT(tbf_ul_ack_fi(ul_tbf)->state == TBF_UL_ACK_ST_NONE);
sivasankari1d8744c2017-01-24 15:53:35 +05301511
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001512 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
sivasankari1d8744c2017-01-24 15:53:35 +05301513 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001514 OSMO_ASSERT(ms_ta(ms) == qta/4);
1515 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
sivasankari1d8744c2017-01-24 15:53:35 +05301516
1517 return ul_tbf;
1518}
1519
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001520static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_CRBB(struct gprs_rlcmac_bts *bts,
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001521 struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta,
sivasankari1d8744c2017-01-24 15:53:35 +05301522 uint8_t ms_class, uint8_t egprs_ms_class)
1523{
1524 GprsMs *ms;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001525 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301526 gprs_rlcmac_ul_tbf *ul_tbf;
sivasankari1d8744c2017-01-24 15:53:35 +05301527
1528 /* check the TBF */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001529 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, pdch->trx->trx_no, pdch->ts_no);
sivasankari1d8744c2017-01-24 15:53:35 +05301530 OSMO_ASSERT(ul_tbf);
1531 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1532
1533 /* send fake data with cv=0*/
1534 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1535 uint8_t data[49] = {0};
1536
1537 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1538
1539 /*header_construction */
1540 memset(data, 0x2b, sizeof(data));
1541
1542 /* Message with CRBB */
1543 for (int i = 80 ; i < 160; i++) {
1544 hdr3->r = 0;
1545 hdr3->si = 0;
1546 hdr3->cv = 10;
1547 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1548 hdr3->tfi_lo = tfi & 0x7;
1549 hdr3->bsn1_hi = ((i)&0x1f);
1550 hdr3->bsn1_lo = ((i)/32);
1551 hdr3->cps_hi = 0;
1552 hdr3->cps_lo = 0;
1553 hdr3->spb = 0;
1554 hdr3->rsb = 0;
1555 hdr3->pi = 0;
1556 hdr3->spare = 0;
1557 hdr3->dummy = 1;
1558 data[4] = 0x0;
1559 data[5] = 0x0;
1560 data[6] = 0x2b;
1561 data[7] = 0x2b;
sivasankari1d8744c2017-01-24 15:53:35 +05301562 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1563 }
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +02001564 osmo_fsm_inst_dispatch(ul_tbf->ul_ack_fsm.fi, TBF_UL_ACK_EV_SCHED_ACK, NULL);
Pau Espin Pedrol5ba3ef92022-12-12 18:02:25 +01001565 tbf_ul_ack_create_rlcmac_msg(ul_tbf, pdch, *fn);
sivasankari1d8744c2017-01-24 15:53:35 +05301566 memset(data, 0x2b, sizeof(data));
1567 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1568 hdr3->r = 0;
1569 hdr3->si = 0;
1570 hdr3->cv = 0;
1571 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1572 hdr3->tfi_lo = tfi & 0x7;
1573 hdr3->bsn1_hi = 0;
1574 hdr3->bsn1_lo = 2;
1575 hdr3->cps_hi = 0;
1576 hdr3->cps_lo = 0;
1577 hdr3->spb = 0;
1578 hdr3->rsb = 0;
1579 hdr3->pi = 0;
1580 hdr3->spare = 0;
1581 hdr3->dummy = 1;
1582 data[4] = 0x0;
1583 data[5] = 0x2b;
1584 data[6] = 0x2b;
1585 data[7] = 0x2b;
1586
sivasankari1d8744c2017-01-24 15:53:35 +05301587 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1588
1589 request_dl_rlc_block(ul_tbf, fn);
1590
1591 check_tbf(ul_tbf);
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +02001592 OSMO_ASSERT(tbf_ul_ack_fi(ul_tbf)->state == TBF_UL_ACK_ST_NONE);
sivasankari1d8744c2017-01-24 15:53:35 +05301593
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001594 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
sivasankari1d8744c2017-01-24 15:53:35 +05301595 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001596 OSMO_ASSERT(ms_ta(ms) == qta/4);
1597 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
sivasankari1d8744c2017-01-24 15:53:35 +05301598
1599 return ul_tbf;
1600}
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001601static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase(struct gprs_rlcmac_bts *bts,
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001602 struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001603 uint8_t ms_class, uint8_t egprs_ms_class)
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001604{
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001605 GprsMs *ms;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001606 uint32_t rach_fn = *fn - 51;
1607 uint32_t sba_fn = *fn + 52;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001608 int tfi = 0;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001609 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001610 RlcMacUplink_t ulreq = {0};
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001611
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001612 /* needed to set last_rts_fn in the PDCH object */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001613 request_dl_rlc_block(bts, pdch, fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001614
bhargava959d1de2016-08-17 15:17:21 +05301615 /* simulate RACH, sends an Immediate Assignment Uplink on the AGCH */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001616 bts_handle_rach(bts, 0x73, rach_fn, qta);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001617
1618 /* get next free TFI */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001619 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &pdch->trx->trx_no, -1);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001620
1621 /* fake a resource request */
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001622 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
1623 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
1624 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
1625 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001626 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
1627 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001628 Count_MS_RA_capability_value = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001629 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001630 MS_RA_capability_value[0].u.Content.Exist_Multislot_capability = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001631 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001632 MS_RA_capability_value[0].u.Content.Multislot_capability.
1633 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001634 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001635 MS_RA_capability_value[0].u.Content.Multislot_capability.
1636 GPRS_multislot_class = ms_class;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001637 if (egprs_ms_class) {
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001638 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001639 MS_RA_capability_value[0].u.Content.Multislot_capability.
1640 Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001641 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001642 MS_RA_capability_value[0].u.Content.Multislot_capability.
1643 EGPRS_multislot_class = ms_class;
1644 }
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001645
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001646 send_ul_mac_block(bts, pdch, &ulreq, sba_fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001647
1648 /* check the TBF */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001649 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, pdch->trx->trx_no, pdch->ts_no);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001650 OSMO_ASSERT(ul_tbf != NULL);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +02001651 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001652
1653 /* send packet uplink assignment */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001654 *fn = sba_fn;
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +02001655 request_dl_rlc_block(ul_tbf, fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001656
Jacob Erlbeckaf454732015-08-21 15:03:23 +02001657 /* send real acknowledgement */
1658 send_control_ack(ul_tbf);
1659
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001660 check_tbf(ul_tbf);
1661
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001662 /* send fake data */
1663 uint8_t data_msg[23] = {
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001664 0x00 | 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
1665 uint8_t(0 | (tfi << 1)),
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001666 uint8_t(1), /* BSN:7, E:1 */
1667 };
1668
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001669 pdch->rcv_block(&data_msg[0], sizeof(data_msg), *fn, &meas);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001670
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001671 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001672 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001673 OSMO_ASSERT(ms_ta(ms) == qta/4);
1674 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001675
1676 return ul_tbf;
1677}
1678
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001679static void send_dl_data(struct gprs_rlcmac_bts *bts, uint32_t tlli, const char *imsi,
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001680 const uint8_t *data, unsigned data_size)
1681{
1682 GprsMs *ms, *ms2;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001683
Pau Espin Pedrol7f360e72022-10-21 14:30:36 +02001684 ms = bts_ms_store(bts)->get_ms(tlli, GSM_RESERVED_TMSI, imsi);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001685
Pau Espin Pedrol8a35e642021-01-18 17:14:14 +01001686 dl_tbf_handle(bts, tlli, 0, imsi, 0, 0,
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001687 1000, data, data_size);
1688
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001689 ms = bts_ms_by_imsi(bts, imsi);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001690 OSMO_ASSERT(ms != NULL);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001691
Pau Espin Pedrol5deac142021-11-12 18:01:50 +01001692 if (imsi[0] != '\0') {
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001693 ms2 = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001694 OSMO_ASSERT(ms == ms2);
1695 }
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001696}
1697
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001698static void transmit_dl_data(struct gprs_rlcmac_bts *bts, uint32_t tlli, uint32_t *fn,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001699 uint8_t slots = 0xff)
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001700{
1701 gprs_rlcmac_dl_tbf *dl_tbf;
1702 GprsMs *ms;
1703 unsigned ts_no;
1704
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001705 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001706 OSMO_ASSERT(ms);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001707 dl_tbf = ms_dl_tbf(ms);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001708 OSMO_ASSERT(dl_tbf);
1709
1710 while (dl_tbf->have_data()) {
1711 uint8_t bn = fn2bn(*fn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001712 for (ts_no = 0 ; ts_no < 8; ts_no += 1) {
1713 if (!(slots & (1 << ts_no)))
1714 continue;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001715 gprs_rlcmac_rcv_rts_block(bts,
Max878bd1f2016-07-20 13:05:05 +02001716 dl_tbf->trx->trx_no, ts_no,
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001717 *fn, bn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001718 }
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001719 *fn = fn_add_blocks(*fn, 1);
1720 }
1721}
1722
Max4c112dc2018-02-01 16:49:23 +01001723static inline void print_ta_tlli(const gprs_rlcmac_ul_tbf *ul_tbf, bool print_ms)
1724{
1725 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
1726 if (print_ms)
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001727 fprintf(stderr, "Got MS: TLLI = 0x%08x, TA = %d\n", ms_tlli(ul_tbf->ms()), ms_ta(ul_tbf->ms()));
Max4c112dc2018-02-01 16:49:23 +01001728}
1729
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001730static void test_tbf_single_phase()
1731{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02001732 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001733 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001734 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001735 int ts_no = 7;
Philippd935d882016-11-07 13:07:36 +01001736 uint32_t fn = DUMMY_FN; /* 17,25,9 */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001737 uint32_t tlli = 0xf1223344;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001738 const char *imsi = "0011223344";
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001739 uint16_t qta = 31;
1740 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001741
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001742 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001743
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001744 setup_bts(bts, ts_no);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001745 pdch = &bts->trx[0].pdch[ts_no];
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001746
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001747 ul_tbf = establish_ul_tbf_single_phase(bts, pdch, tlli, &fn, qta);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001748
Max4c112dc2018-02-01 16:49:23 +01001749 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001750 send_dl_data(bts, tlli, imsi, (const uint8_t *)"TEST", 4);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001751
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001752 fprintf(stderr, "=== end %s ===\n", __func__);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001753 TALLOC_FREE(the_pcu);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001754}
1755
Pau Espin Pedrol22b26d82022-10-26 15:44:14 +02001756static void test_tbf_single_phase2()
1757{
1758 the_pcu = prepare_pcu();
1759 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001760 struct gprs_rlcmac_pdch *pdch;
Pau Espin Pedrol22b26d82022-10-26 15:44:14 +02001761 int ts_no = 7;
1762 uint32_t fn = DUMMY_FN; /* 17,25,9 */
1763 uint32_t tlli = 0xf1223344;
1764 const char *imsi = "0011223344";
1765 uint16_t qta = 31;
1766 gprs_rlcmac_ul_tbf *ul_tbf;
1767
1768 fprintf(stderr, "=== start %s ===\n", __func__);
1769
1770 setup_bts(bts, ts_no);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001771 pdch = &bts->trx[0].pdch[ts_no];
Pau Espin Pedrol22b26d82022-10-26 15:44:14 +02001772
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001773 ul_tbf = establish_ul_tbf_single_phase(bts, pdch, tlli, &fn, qta);
Pau Espin Pedrol22b26d82022-10-26 15:44:14 +02001774
1775 print_ta_tlli(ul_tbf, true);
1776 /* PCU sends CTRL ACK/NCK with FINAL_ACK=1, hence TBF is not in state FINISHED */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001777 request_dl_rlc_block(bts, pdch, &fn);
Pau Espin Pedrol22b26d82022-10-26 15:44:14 +02001778 OSMO_ASSERT(ul_tbf->state_is(TBF_ST_FINISHED));
1779 /* Now data is sent but no DL TBF is created because MS is not reachable for DL Assignment */
1780 send_dl_data(bts, tlli, imsi, (const uint8_t *)"TEST", 4);
1781
1782 /* After MS CTRL ACKs the FINAL_ACK=1 then it releases the TBF and goes
1783 * to packet-idle mode. Hence PCU will trigger ImmAss(PktDlAss) on PCH. */
1784 send_control_ack(ul_tbf);
1785
1786 fprintf(stderr, "=== end %s ===\n", __func__);
1787 TALLOC_FREE(the_pcu);
1788}
1789
sivasankari1d8744c2017-01-24 15:53:35 +05301790static void test_tbf_egprs_two_phase_puan(void)
1791{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02001792 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001793 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
sivasankari1d8744c2017-01-24 15:53:35 +05301794 int ts_no = 7;
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001795 struct gprs_rlcmac_pdch *pdch;
sivasankari1d8744c2017-01-24 15:53:35 +05301796 uint32_t fn = 2654218;
1797 uint16_t qta = 31;
1798 uint32_t tlli = 0xf1223344;
1799 const char *imsi = "0011223344";
1800 uint8_t ms_class = 1;
sivasankari1d8744c2017-01-24 15:53:35 +05301801 uint8_t egprs_ms_class = 1;
1802 gprs_rlcmac_ul_tbf *ul_tbf;
sivasankari1d8744c2017-01-24 15:53:35 +05301803 uint8_t test_data[256];
1804
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001805 fprintf(stderr, "=== start %s ===\n", __func__);
sivasankari1d8744c2017-01-24 15:53:35 +05301806
1807 memset(test_data, 1, sizeof(test_data));
1808
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001809 setup_bts(bts, ts_no, 4);
1810 bts->initial_mcs_dl = 9;
Pau Espin Pedrol519d0712021-01-14 14:30:03 +01001811 the_pcu->vty.ws_base = 128;
1812 the_pcu->vty.ws_pdch = 64;
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001813 pdch = &bts->trx[0].pdch[ts_no];
sivasankari1d8744c2017-01-24 15:53:35 +05301814
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001815 ul_tbf = establish_ul_tbf(bts, pdch, tlli, &fn, qta, ms_class, egprs_ms_class);
sivasankari1d8744c2017-01-24 15:53:35 +05301816 /* Function to generate URBB with no length */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001817 ul_tbf = establish_ul_tbf_two_phase_puan_URBB_no_length(bts, pdch, tlli, &fn,
sivasankari1d8744c2017-01-24 15:53:35 +05301818 qta, ms_class, egprs_ms_class, ul_tbf);
1819
Max4c112dc2018-02-01 16:49:23 +01001820 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001821 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
sivasankari1d8744c2017-01-24 15:53:35 +05301822
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02001823 static_cast<gprs_rlc_ul_window *>(ul_tbf->window())->reset_state();
sivasankari1d8744c2017-01-24 15:53:35 +05301824 /* Function to generate URBB with length */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001825 ul_tbf = establish_ul_tbf_two_phase_puan_URBB_with_length(bts, pdch, tlli, &fn,
sivasankari1d8744c2017-01-24 15:53:35 +05301826 qta, ms_class, egprs_ms_class, ul_tbf);
1827
Max4c112dc2018-02-01 16:49:23 +01001828 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001829 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
sivasankari1d8744c2017-01-24 15:53:35 +05301830
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02001831 static_cast<gprs_rlc_ul_window *>(ul_tbf->window())->reset_state();
sivasankari1d8744c2017-01-24 15:53:35 +05301832 /* Function to generate CRBB */
Pau Espin Pedrol519d0712021-01-14 14:30:03 +01001833 the_pcu->vty.ws_base = 128;
1834 the_pcu->vty.ws_pdch = 64;
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001835 ul_tbf = establish_ul_tbf_two_phase_puan_CRBB(bts, pdch, tlli, &fn,
sivasankari1d8744c2017-01-24 15:53:35 +05301836 qta, ms_class, egprs_ms_class);
1837
Max4c112dc2018-02-01 16:49:23 +01001838 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001839 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
sivasankari1d8744c2017-01-24 15:53:35 +05301840
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001841 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001842 fprintf(stderr, "=== end %s ===\n", __func__);
sivasankari1d8744c2017-01-24 15:53:35 +05301843}
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301844/*
1845 * Trigger rach for single block
1846 */
1847static void test_immediate_assign_rej_single_block()
1848{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02001849 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001850 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301851 uint32_t fn = 2654218;
1852 uint16_t qta = 31;
1853 int ts_no = 7;
1854
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001855 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301856
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001857 setup_bts(bts, ts_no, 4);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301858
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001859 bts->trx[0].pdch[ts_no].disable();
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301860
1861 uint32_t rach_fn = fn - 51;
1862
1863 int rc = 0;
1864
1865 /*
1866 * simulate RACH, sends an Immediate Assignment
1867 * Uplink reject on the AGCH
1868 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001869 rc = bts_handle_rach(bts, 0x70, rach_fn, qta);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301870
Pau Espin Pedrol15c58ac2021-03-08 14:57:58 +01001871 OSMO_ASSERT(rc == -EBUSY);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301872
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001873 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001874 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301875}
1876
1877/*
1878 * Trigger rach till resources(USF) exhaust
1879 */
1880static void test_immediate_assign_rej_multi_block()
1881{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02001882 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001883 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301884 uint32_t fn = 2654218;
1885 uint16_t qta = 31;
1886 int ts_no = 7;
1887
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001888 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301889
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001890 setup_bts(bts, ts_no, 4);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301891
1892 uint32_t rach_fn = fn - 51;
1893
1894 int rc = 0;
1895
1896 /*
1897 * simulate RACH, sends an Immediate Assignment Uplink
1898 * reject on the AGCH
1899 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001900 rc = bts_handle_rach(bts, 0x78, rach_fn, qta);
1901 rc = bts_handle_rach(bts, 0x79, rach_fn, qta);
1902 rc = bts_handle_rach(bts, 0x7a, rach_fn, qta);
1903 rc = bts_handle_rach(bts, 0x7b, rach_fn, qta);
1904 rc = bts_handle_rach(bts, 0x7c, rach_fn, qta);
1905 rc = bts_handle_rach(bts, 0x7d, rach_fn, qta);
1906 rc = bts_handle_rach(bts, 0x7e, rach_fn, qta);
1907 rc = bts_handle_rach(bts, 0x7f, rach_fn, qta);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301908
1909 OSMO_ASSERT(rc == -EBUSY);
1910
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001911 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001912 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301913}
1914
1915static void test_immediate_assign_rej()
1916{
1917 test_immediate_assign_rej_multi_block();
1918 test_immediate_assign_rej_single_block();
1919}
1920
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001921static void test_tbf_two_phase()
1922{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02001923 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001924 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001925 int ts_no = 7;
1926 uint32_t fn = 2654218;
1927 uint16_t qta = 31;
1928 uint32_t tlli = 0xf1223344;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001929 const char *imsi = "0011223344";
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001930 uint8_t ms_class = 1;
1931 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001932
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001933 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001934
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001935 setup_bts(bts, ts_no, 4);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001936
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001937 ul_tbf = establish_ul_tbf_two_phase(bts, &bts->trx[0].pdch[ts_no],
1938 tlli, &fn, qta, ms_class, 0);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001939
Max4c112dc2018-02-01 16:49:23 +01001940 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001941 send_dl_data(bts, tlli, imsi, (const uint8_t *)"TEST", 4);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001942
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001943 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001944 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001945}
1946
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001947static inline void print_ms(GprsMs *ms, bool old)
Max4c112dc2018-02-01 16:49:23 +01001948{
1949 fprintf(stderr, "%s MS: TLLI = 0x%08x, TA = %d, IMSI = %s, LLC = %zu\n",
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001950 old ? "Old" : "New", ms_tlli(ms), ms_ta(ms), ms_imsi(ms), llc_queue_size(ms_llc_queue(ms)));
Max4c112dc2018-02-01 16:49:23 +01001951}
1952
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001953static void test_tbf_ra_update_rach()
1954{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02001955 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001956 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001957 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001958 int ts_no = 7;
1959 uint32_t fn = 2654218;
1960 uint16_t qta = 31;
1961 uint32_t tlli1 = 0xf1223344;
1962 uint32_t tlli2 = 0xf5667788;
1963 const char *imsi = "0011223344";
1964 uint8_t ms_class = 1;
1965 gprs_rlcmac_ul_tbf *ul_tbf;
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01001966 gprs_rlcmac_dl_tbf *dl_tbf;
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001967 GprsMs *ms, *ms1, *ms2;
1968
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001969 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001970
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001971 setup_bts(bts, ts_no, 4);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001972 pdch = &bts->trx[0].pdch[ts_no];
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001973
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001974 ul_tbf = establish_ul_tbf_two_phase(bts, pdch, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001975 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001976
1977 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01001978 print_ta_tlli(ul_tbf, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001979
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001980 send_dl_data(bts, tlli1, imsi, (const uint8_t *)"RAU_ACCEPT", 10);
Max4c112dc2018-02-01 16:49:23 +01001981 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001982
Jacob Erlbeckaf454732015-08-21 15:03:23 +02001983 /* Send Packet Downlink Assignment to MS */
1984 request_dl_rlc_block(ul_tbf, &fn);
1985
1986 /* Ack it */
1987 send_control_ack(ul_tbf);
1988
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001989 /* Make sure the RAU Accept gets sent to the MS */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001990 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 1);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001991 transmit_dl_data(bts, tlli1, &fn);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001992 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001993
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01001994 dl_tbf = ms_dl_tbf(ms1);
1995 OSMO_ASSERT(dl_tbf);
Pau Espin Pedrol16e16782021-03-29 19:10:19 +02001996 fn = get_poll_fn(dl_tbf, dl_tbf->control_ts);
1997 send_empty_block(dl_tbf, dl_tbf->control_ts, fn);
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01001998 fn = fn_add_blocks(fn, 1);
1999
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002000 /* Now establish a new TBF for the RA UPDATE COMPLETE (new TLLI) */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002001 ul_tbf = establish_ul_tbf_two_phase(bts, pdch, tlli2, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002002 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002003
2004 ms2 = ul_tbf->ms();
2005
2006 /* The PCU cannot know yet, that both TBF belong to the same MS */
2007 OSMO_ASSERT(ms1 != ms2);
Max4c112dc2018-02-01 16:49:23 +01002008 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002009
2010 /* Send some downlink data along with the new TLLI and the IMSI so that
2011 * the PCU can see, that both MS objects belong to same MS */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002012 send_dl_data(bts, tlli2, imsi, (const uint8_t *)"DATA", 4);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002013
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002014 ms = bts_ms_by_imsi(bts, imsi);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002015 OSMO_ASSERT(ms == ms2);
2016
Max4c112dc2018-02-01 16:49:23 +01002017 print_ms(ms2, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002018
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002019 ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002020 OSMO_ASSERT(ms == NULL);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002021 ms = bts_ms_by_tlli(bts, tlli2, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002022 OSMO_ASSERT(ms == ms2);
2023
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002024 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002025 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002026}
2027
2028static void test_tbf_dl_flow_and_rach_two_phase()
2029{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002030 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002031 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002032 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002033 int ts_no = 7;
2034 uint32_t fn = 2654218;
2035 uint16_t qta = 31;
2036 uint32_t tlli1 = 0xf1223344;
2037 const char *imsi = "0011223344";
2038 uint8_t ms_class = 1;
2039 gprs_rlcmac_ul_tbf *ul_tbf;
2040 gprs_rlcmac_dl_tbf *dl_tbf;
2041 GprsMs *ms, *ms1, *ms2;
2042
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002043 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002044
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002045 setup_bts(bts, ts_no, 1);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002046 pdch = &bts->trx[0].pdch[ts_no];
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002047
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002048 ul_tbf = establish_ul_tbf_two_phase(bts, pdch, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002049 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002050
2051 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002052 print_ta_tlli(ul_tbf, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002053
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002054 send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);
2055 send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);
Max4c112dc2018-02-01 16:49:23 +01002056 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002057
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002058 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 2);
2059 dl_tbf = ms_dl_tbf(ms1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002060 OSMO_ASSERT(dl_tbf != NULL);
2061
2062 /* Get rid of old UL TBF */
2063 tbf_free(ul_tbf);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002064 ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002065 OSMO_ASSERT(ms1 == ms);
2066
2067 /* Now establish a new UL TBF, this will consume one LLC packet */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002068 ul_tbf = establish_ul_tbf_two_phase(bts, pdch, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002069 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002070
2071 ms2 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002072 print_ms(ms2, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002073
2074 /* This should be the same MS object */
2075 OSMO_ASSERT(ms2 == ms1);
2076
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002077 ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002078 OSMO_ASSERT(ms2 == ms);
2079
Jacob Erlbeckc8cbfc22015-09-01 11:38:40 +02002080 /* A DL TBF should still exist */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002081 OSMO_ASSERT(ms_dl_tbf(ms));
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002082
2083 /* No queued packets should be lost */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002084 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms)) == 2);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002085
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002086 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002087 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002088}
2089
2090
2091static void test_tbf_dl_flow_and_rach_single_phase()
2092{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002093 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002094 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002095 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002096 int ts_no = 7;
2097 uint32_t fn = 2654218;
2098 uint16_t qta = 31;
2099 uint32_t tlli1 = 0xf1223344;
2100 const char *imsi = "0011223344";
2101 uint8_t ms_class = 1;
2102 gprs_rlcmac_ul_tbf *ul_tbf;
2103 gprs_rlcmac_dl_tbf *dl_tbf;
2104 GprsMs *ms, *ms1, *ms2;
2105
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002106 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002107
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002108 setup_bts(bts, ts_no, 1);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002109 pdch = &bts->trx[0].pdch[ts_no];
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002110
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002111 ul_tbf = establish_ul_tbf_two_phase(bts, pdch, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002112 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002113
2114 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002115 print_ta_tlli(ul_tbf, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002116
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002117 send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);
2118 send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);
Max4c112dc2018-02-01 16:49:23 +01002119 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002120
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002121 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 2);
2122 dl_tbf = ms_dl_tbf(ms1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002123 OSMO_ASSERT(dl_tbf != NULL);
2124
2125 /* Get rid of old UL TBF */
2126 tbf_free(ul_tbf);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002127 ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002128 OSMO_ASSERT(ms1 == ms);
2129
2130 /* Now establish a new UL TBF */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002131 ul_tbf = establish_ul_tbf_single_phase(bts, pdch, tlli1, &fn, qta);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002132
2133 ms2 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002134 print_ms(ms2, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002135
2136 /* There should be a different MS object */
2137 OSMO_ASSERT(ms2 != ms1);
2138
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002139 ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002140 OSMO_ASSERT(ms2 == ms);
2141 OSMO_ASSERT(ms1 != ms);
2142
Jacob Erlbeck5f93f852016-01-21 20:48:39 +01002143 /* DL TBF should be removed */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002144 OSMO_ASSERT(!ms_dl_tbf(ms));
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002145
2146 /* No queued packets should be lost */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002147 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms)) == 2);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002148
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002149 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002150 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002151}
2152
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002153static void test_tbf_dl_reuse()
2154{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002155 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002156 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002157 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002158 int ts_no = 7;
2159 uint32_t fn = 2654218;
2160 uint16_t qta = 31;
2161 uint32_t tlli1 = 0xf1223344;
2162 const char *imsi = "0011223344";
2163 uint8_t ms_class = 1;
2164 gprs_rlcmac_ul_tbf *ul_tbf;
2165 gprs_rlcmac_dl_tbf *dl_tbf1, *dl_tbf2;
2166 GprsMs *ms1, *ms2;
2167 unsigned i;
2168 RlcMacUplink_t ulreq = {0};
2169
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002170 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002171
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002172 setup_bts(bts, ts_no, 1);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002173 pdch = &bts->trx[0].pdch[ts_no];
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002174
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002175 ul_tbf = establish_ul_tbf_two_phase(bts, pdch, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002176 ms_class, 0);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002177
2178 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002179 print_ta_tlli(ul_tbf, false);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002180
2181 /* Send some LLC frames */
2182 for (i = 0; i < 40; i++) {
2183 char buf[32];
2184 int rc;
2185
2186 rc = snprintf(buf, sizeof(buf), "LLC PACKET %02i", i);
2187 OSMO_ASSERT(rc > 0);
2188
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002189 send_dl_data(bts, tlli1, imsi, (const uint8_t *)buf, rc);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002190 }
2191
Max4c112dc2018-02-01 16:49:23 +01002192 print_ms(ms1, true);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002193
2194 /* Send Packet Downlink Assignment to MS */
2195 request_dl_rlc_block(ul_tbf, &fn);
2196
2197 /* Ack it */
2198 send_control_ack(ul_tbf);
2199
2200 /* Transmit all data */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002201 transmit_dl_data(bts, tlli1, &fn);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002202 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 0);
2203 OSMO_ASSERT(ms_dl_tbf(ms1));
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002204 OSMO_ASSERT(ms_dl_tbf(ms1)->state_is(TBF_ST_FINISHED));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002205
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002206 dl_tbf1 = ms_dl_tbf(ms1);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002207
2208 /* Send some LLC frames */
2209 for (i = 0; i < 10; i++) {
2210 char buf[32];
2211 int rc;
2212
2213 rc = snprintf(buf, sizeof(buf), "LLC PACKET %02i (TBF 2)", i);
2214 OSMO_ASSERT(rc > 0);
2215
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002216 send_dl_data(bts, tlli1, imsi, (const uint8_t *)buf, rc);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002217 }
2218
Pau Espin Pedrol422636d2021-09-28 15:59:35 +02002219 /* Drop first DL_ACK poll queued */
2220 send_empty_block(dl_tbf1, dl_tbf1->control_ts, get_poll_fn(dl_tbf1, dl_tbf1->control_ts));
2221
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002222 /* Fake Final DL Ack/Nack */
2223 ulreq.u.MESSAGE_TYPE = MT_PACKET_DOWNLINK_ACK_NACK;
2224 Packet_Downlink_Ack_Nack_t *ack = &ulreq.u.Packet_Downlink_Ack_Nack;
2225
2226 ack->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
2227 ack->DOWNLINK_TFI = dl_tbf1->tfi();
2228 ack->Ack_Nack_Description.FINAL_ACK_INDICATION = 1;
2229
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002230 send_ul_mac_block(bts, dl_tbf1->control_ts, &ulreq, get_poll_fn(dl_tbf1, dl_tbf1->control_ts));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002231
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002232 OSMO_ASSERT(dl_tbf1->state_is(TBF_ST_WAIT_RELEASE));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002233
2234 request_dl_rlc_block(dl_tbf1, &fn);
2235
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002236 ms2 = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002237 OSMO_ASSERT(ms2 == ms1);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002238 OSMO_ASSERT(ms_dl_tbf(ms2));
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002239 OSMO_ASSERT(ms_dl_tbf(ms2)->state_is(TBF_ST_ASSIGN));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002240
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002241 dl_tbf2 = ms_dl_tbf(ms2);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002242
2243 OSMO_ASSERT(dl_tbf1 != dl_tbf2);
2244
2245 send_control_ack(dl_tbf1);
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002246 OSMO_ASSERT(dl_tbf2->state_is(TBF_ST_FLOW));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002247
2248 /* Transmit all data */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002249 transmit_dl_data(bts, tlli1, &fn);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002250 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms2)) == 0);
2251 OSMO_ASSERT(ms_dl_tbf(ms2));
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002252 OSMO_ASSERT(ms_dl_tbf(ms2)->state_is(TBF_ST_FINISHED));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002253
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002254 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002255 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002256}
2257
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002258static void test_tbf_gprs_egprs()
2259{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002260 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002261 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002262 uint8_t ts_no = 4;
2263 uint8_t ms_class = 45;
2264 int rc = 0;
2265 uint32_t tlli = 0xc0006789;
2266 const char *imsi = "001001123456789";
2267 unsigned delay_csec = 1000;
2268
2269 uint8_t buf[256] = {0};
2270
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002271 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002272
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002273 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
2274 if (!bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +02002275 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
2276 abort();
2277 }
2278
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002279 setup_bts(bts, ts_no);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002280
2281 /* EGPRS-only */
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002282
Alexander Couzens290d9032020-09-16 21:52:02 +02002283 gprs_bssgp_init(bts, 3234, 3234, 1, 1, false, 0, 0, 0);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002284
2285 /* Does not support EGPRS */
Pau Espin Pedrol8a35e642021-01-18 17:14:14 +01002286 rc = dl_tbf_handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002287 delay_csec, buf, sizeof(buf));
2288
Pau Espin Pedrol569f0d22020-10-27 14:45:20 +01002289 OSMO_ASSERT(rc == 0);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002290 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002291
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002292 TALLOC_FREE(the_pcu);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002293}
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02002294
Max4c112dc2018-02-01 16:49:23 +01002295static inline void ws_check(gprs_rlcmac_dl_tbf *dl_tbf, const char *test, uint8_t exp_slots, uint16_t exp_ws,
Pau Espin Pedrolbf5e3cb2022-05-09 16:31:22 +02002296 bool free)
Max4c112dc2018-02-01 16:49:23 +01002297{
2298 if (!dl_tbf) {
2299 fprintf(stderr, "%s(): FAILED (NULL TBF)\n", test);
2300 return;
2301 }
2302
2303 fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d",
2304 dl_tbf->dl_slots(),
2305 pcu_bitcount(dl_tbf->dl_slots()),
2306 dl_tbf->window_size());
2307
2308 if (pcu_bitcount(dl_tbf->dl_slots()) != exp_slots || dl_tbf->window_size() != exp_ws)
2309 fprintf(stderr, "%s(): DL TBF FAILED: dl_slots = %u (exp. %u), WS = %u (exp. %u)",
2310 test, pcu_bitcount(dl_tbf->dl_slots()), 4, dl_tbf->window_size(), 128 + 4 * 64);
2311
2312 fprintf(stderr, "\n");
2313
2314 if (free)
2315 tbf_free(dl_tbf);
Max4c112dc2018-02-01 16:49:23 +01002316}
2317
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002318static void test_tbf_ws()
2319{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002320 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002321 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +02002322 GprsMs *ms;
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002323 uint8_t ts_no = 4;
2324 uint8_t ms_class = 12;
2325 gprs_rlcmac_dl_tbf *dl_tbf;
2326
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002327 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002328
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002329 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
2330 if (!bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +02002331 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
2332 abort();
2333 }
2334
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002335 setup_bts(bts, ts_no);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002336
Pau Espin Pedrol519d0712021-01-14 14:30:03 +01002337 the_pcu->vty.ws_base = 128;
2338 the_pcu->vty.ws_pdch = 64;
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002339 the_pcu->alloc_algorithm = alloc_algorithm_b;
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002340 bts->trx[0].pdch[2].enable();
2341 bts->trx[0].pdch[3].enable();
Pau Espin Pedrol4f67a9b2021-06-30 16:03:06 +02002342 /* bts->trx[0].pdch[4].enable(); Already enabled during setup_bts() */
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002343 bts->trx[0].pdch[5].enable();
2344
Alexander Couzens290d9032020-09-16 21:52:02 +02002345 gprs_bssgp_init(bts, 4234, 4234, 1, 1, false, 0, 0, 0);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002346
2347 /* Does no support EGPRS */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002348 ms = bts_alloc_ms(bts, ms_class, 0);
Pau Espin Pedrol87573842022-10-26 20:23:45 +02002349 dl_tbf = dl_tbf_alloc(bts, ms, 0, false);
Max4c112dc2018-02-01 16:49:23 +01002350
Pau Espin Pedrolbf5e3cb2022-05-09 16:31:22 +02002351 ws_check(dl_tbf, __func__, 4, 64, true);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002352
2353 /* EGPRS-only */
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002354
2355 /* Does support EGPRS */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002356 ms = bts_alloc_ms(bts, ms_class, ms_class);
Pau Espin Pedrol87573842022-10-26 20:23:45 +02002357 dl_tbf = dl_tbf_alloc(bts, ms, 0, false);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002358
Pau Espin Pedrolbf5e3cb2022-05-09 16:31:22 +02002359 ws_check(dl_tbf, __func__, 4, 128 + 4 * 64, true);
2360 fprintf(stderr, "=== end %s ===\n", __func__);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002361 TALLOC_FREE(the_pcu);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002362}
2363
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302364static void test_tbf_update_ws(void)
2365{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002366 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002367 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +02002368 GprsMs *ms;
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302369 uint8_t ts_no = 4;
2370 uint8_t ms_class = 11;
2371 gprs_rlcmac_dl_tbf *dl_tbf;
2372
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002373 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302374
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002375 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
2376 if (!bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +02002377 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
2378 abort();
2379 }
2380
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002381 setup_bts(bts, ts_no);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302382
Pau Espin Pedrol519d0712021-01-14 14:30:03 +01002383 the_pcu->vty.ws_base = 128;
2384 the_pcu->vty.ws_pdch = 64;
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002385 the_pcu->alloc_algorithm = alloc_algorithm_b;
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302386 bts->trx[0].pdch[2].enable();
2387 bts->trx[0].pdch[3].enable();
Pau Espin Pedrol4f67a9b2021-06-30 16:03:06 +02002388 /* bts->trx[0].pdch[4].enable(); Already enabled during setup_bts()) */
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302389 bts->trx[0].pdch[5].enable();
2390
Alexander Couzens290d9032020-09-16 21:52:02 +02002391 gprs_bssgp_init(bts, 5234, 5234, 1, 1, false, 0, 0, 0);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302392
2393 /* EGPRS-only */
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302394
2395 /* Does support EGPRS */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002396 ms = bts_alloc_ms(bts, ms_class, ms_class);
Pau Espin Pedrol87573842022-10-26 20:23:45 +02002397 dl_tbf = dl_tbf_alloc(bts, ms, 0, true);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302398
Pau Espin Pedrolbf5e3cb2022-05-09 16:31:22 +02002399 ws_check(dl_tbf, __func__, 1, 128 + 1 * 64, false);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302400
Pau Espin Pedrolb7a2b592022-12-13 14:43:59 +01002401 OSMO_ASSERT(dl_tbf_upgrade_to_multislot(dl_tbf) == 0);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302402
Aravind Sirsikar0ee31cf2016-09-15 17:54:46 +05302403 /* window size should be 384 */
Pau Espin Pedrolbf5e3cb2022-05-09 16:31:22 +02002404 ws_check(dl_tbf, __func__, 4, 128 + 4 * 64, true);
2405 fprintf(stderr, "=== end %s ===\n", __func__);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002406 TALLOC_FREE(the_pcu);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302407}
2408
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01002409/* Test DL-TBF first assigned over CCCH ImmAss, then after X2002 timeout, when MS
2410is available to receive from TBF on PACCH, upgrade it to multislot. In the
2411middle the MS would request a new UL-TBF and PCU ends up creating 2 MS objects on
2412different TRX, which are eventually merged.
2413Hence, new multislot DL-TBF allocation (assigned over PACCH) happens on a different TRX
2414than the one which was assigned over CCCH and where the PktDlAss is sent. SYS#6231 */
2415static void test_ms_merge_dl_tbf_different_trx(void)
2416{
2417 the_pcu = prepare_pcu();
2418 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
2419 GprsMs *first_ms, *second_ms;
2420 uint8_t ts_no = 1;
2421 uint8_t ms_class = 11;
2422 struct gprs_rlcmac_trx *trx0 = &bts->trx[0];
2423 struct gprs_rlcmac_trx *trx1 = &bts->trx[1];
2424 uint32_t old_tlli = 0xa3c2f953;
2425 uint32_t new_tlli = 0xecc1f953;
2426 const char *imsi = "001001000000001";
2427 uint8_t llc_buf[19];
2428 int rc;
2429 unsigned delay_csec = 1000;
2430 struct gprs_rlcmac_dl_tbf *dl_tbf;
2431 struct gprs_rlcmac_ul_tbf *ul_tbf;
2432 uint32_t fn = 0;
2433
2434 fprintf(stderr, "=== start %s ===\n", __func__);
2435
2436 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
2437 if (!bts->pcu->nsi) {
2438 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
2439 abort();
2440 }
2441
2442 setup_bts(bts, ts_no);
2443 the_pcu->alloc_algorithm = alloc_algorithm_b;
2444 /* trx0->pdch[ts_no].enable(); Already enabled during setup_bts()) */
2445 trx0->pdch[ts_no].disable();
2446 trx1->pdch[4].enable();
2447 trx1->pdch[5].enable();
2448 trx1->pdch[6].enable();
2449 gprs_bssgp_init(bts, 5234, 5234, 1, 1, false, 0, 0, 0);
2450
2451 /* Handle LLC frame 1. This will create the TBF we want in TRX1 and
Pau Espin Pedrold1058b92022-12-16 18:39:29 +01002452 * we'll have it upgrade to multislot on TRX0 later. This will trigger a
2453 * CCCH Dl ImAss towards BTS PCUIF. The confirmation from BTS is
2454 * injected further below (TBF_EV_ASSIGN_PCUIF_CNF). */
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01002455 memset(llc_buf, 1, sizeof(llc_buf));
2456 rc = dl_tbf_handle(bts, old_tlli, 0, imsi, ms_class, 0,
2457 delay_csec, llc_buf, sizeof(llc_buf));
2458 OSMO_ASSERT(rc >= 0);
2459
2460 first_ms = bts_ms_store(bts)->get_ms(GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, imsi);
2461 OSMO_ASSERT(first_ms);
2462 dl_tbf = ms_dl_tbf(first_ms);
2463 OSMO_ASSERT(dl_tbf);
2464 OSMO_ASSERT(tbf_get_trx(dl_tbf) == trx1);
2465 OSMO_ASSERT(dl_tbf->control_ts->trx == trx1);
2466 struct gprs_rlcmac_pdch *old_dl_control_ts = dl_tbf->control_ts;
2467
2468 /* Enable PDCHs on TRX0 so that second_ms is allocated on TRX0: */
2469 trx0->pdch[1].enable();
2470 trx0->pdch[2].enable();
2471 trx0->pdch[3].enable();
2472
2473 second_ms = bts_alloc_ms(bts, 0, 0);
2474 ms_set_tlli(second_ms, new_tlli);
2475 ul_tbf = ul_tbf_alloc(bts, second_ms, 0, true);
2476 OSMO_ASSERT(ul_tbf != NULL);
2477 ms_update_announced_tlli(second_ms, new_tlli);
2478
2479 /* Here PCU gets to know the MS are the same and they get merged. */
2480 rc = dl_tbf_handle(bts, new_tlli, old_tlli, imsi, ms_class, 0,
2481 delay_csec, llc_buf, sizeof(llc_buf));
2482 OSMO_ASSERT(rc >= 0);
Pau Espin Pedrold1058b92022-12-16 18:39:29 +01002483 /* Here we assert a new DL-TBF is created in the new MS (hence old from TRX1 is deleted and new one is in TRX0): */
2484 dl_tbf = ms_dl_tbf(second_ms);
2485 OSMO_ASSERT(tbf_get_trx(dl_tbf) == trx0);
2486 OSMO_ASSERT(dl_tbf->control_ts != old_dl_control_ts);
2487 OSMO_ASSERT(dl_tbf == llist_first_entry_or_null(&trx0->dl_tbfs, struct llist_item, list)->entry);
2488 OSMO_ASSERT(NULL == llist_first_entry_or_null(&trx1->dl_tbfs, struct llist_item, list));
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01002489
2490 /* Here BTS would answer with data_cnf and trigger
2491 * bts_rcv_imm_ass_cnf(), which would trigger TBF_EV_ASSIGN_PCUIF_CNF.
Pau Espin Pedrold1058b92022-12-16 18:39:29 +01002492 * Since that's for an older DL-TBF assignment which no longer exists, it is ignored. */
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01002493 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2002, 0, OSMO_TDEF_MS) == 0);
2494 osmo_fsm_inst_dispatch(ms_dl_tbf(second_ms)->state_fi, TBF_EV_ASSIGN_PCUIF_CNF, NULL);
2495 osmo_select_main(0);
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01002496
Pau Espin Pedrold1058b92022-12-16 18:39:29 +01002497 /* get the PACCH PktDlAss for the DL-TBF, allocated one the UL-TBF from the new MS obj: */
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01002498 request_dl_rlc_block(dl_tbf->bts, dl_tbf->control_ts, &fn);
2499
2500 fprintf(stderr, "=== end %s ===\n", __func__);
2501 TALLOC_FREE(the_pcu);
2502}
2503
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302504static void test_tbf_puan_urbb_len(void)
2505{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002506 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002507 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002508 struct gprs_rlcmac_pdch *pdch;
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302509 int ts_no = 7;
2510 uint32_t fn = 2654218;
2511 uint16_t qta = 31;
2512 uint32_t tlli = 0xf1223344;
2513 const char *imsi = "0011223344";
2514 uint8_t ms_class = 1;
2515 uint8_t egprs_ms_class = 1;
2516 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302517 uint8_t test_data[256];
2518
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002519 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302520
2521 memset(test_data, 1, sizeof(test_data));
2522
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002523 setup_bts(bts, ts_no, 4);
2524 bts->initial_mcs_dl = 9;
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002525 pdch = &bts->trx[0].pdch[ts_no];
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302526
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002527 ul_tbf = puan_urbb_len_issue(bts, pdch, tlli, &fn, qta,
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302528 ms_class, egprs_ms_class);
2529
Max4c112dc2018-02-01 16:49:23 +01002530 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002531 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302532
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002533 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002534 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302535}
2536
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002537static gprs_rlcmac_ul_tbf *tbf_li_decoding(struct gprs_rlcmac_bts *bts,
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002538 struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta,
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302539 uint8_t ms_class, uint8_t egprs_ms_class)
2540{
2541 GprsMs *ms;
2542 uint32_t rach_fn = *fn - 51;
2543 uint32_t sba_fn = *fn + 52;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002544 int tfi = 0;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302545 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302546 RlcMacUplink_t ulreq = {0};
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302547 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302548 Packet_Resource_Request_t *presreq = NULL;
2549 MS_Radio_Access_capability_t *pmsradiocap = NULL;
2550 Multislot_capability_t *pmultislotcap = NULL;
2551
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302552 /* needed to set last_rts_fn in the PDCH object */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002553 request_dl_rlc_block(bts, pdch, fn);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302554
2555 /*
2556 * simulate RACH, this sends an Immediate
2557 * Assignment Uplink on the AGCH
2558 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002559 bts_handle_rach(bts, 0x73, rach_fn, qta);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302560
2561 /* get next free TFI */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002562 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &pdch->trx->trx_no, -1);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302563
2564 /* fake a resource request */
2565 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
2566 presreq = &ulreq.u.Packet_Resource_Request;
2567 presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
2568 presreq->ID.UnionType = 1; /* != 0 */
2569 presreq->ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01002570 presreq->Exist_MS_Radio_Access_capability2 = 1;
2571 pmsradiocap = &presreq->MS_Radio_Access_capability2;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302572 pmsradiocap->Count_MS_RA_capability_value = 1;
2573 pmsradiocap->MS_RA_capability_value[0].u.Content.
2574 Exist_Multislot_capability = 1;
2575 pmultislotcap = &pmsradiocap->MS_RA_capability_value[0].
2576 u.Content.Multislot_capability;
2577
2578 pmultislotcap->Exist_GPRS_multislot_class = 1;
2579 pmultislotcap->GPRS_multislot_class = ms_class;
2580 if (egprs_ms_class) {
2581 pmultislotcap->Exist_EGPRS_multislot_class = 1;
2582 pmultislotcap->EGPRS_multislot_class = ms_class;
2583 }
2584
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002585 send_ul_mac_block(bts, pdch, &ulreq, sba_fn);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302586
2587 /* check the TBF */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002588 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, pdch->trx->trx_no, pdch->ts_no);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302589 OSMO_ASSERT(ul_tbf);
2590 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
2591
2592 /* send packet uplink assignment */
2593 *fn = sba_fn;
2594 request_dl_rlc_block(ul_tbf, fn);
2595
2596 /* send real acknowledgement */
2597 send_control_ack(ul_tbf);
2598
2599 check_tbf(ul_tbf);
2600
2601 uint8_t data_msg[49] = {0};
2602
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002603 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302604 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002605 OSMO_ASSERT(ms_ta(ms) == qta/4);
2606 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302607
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302608 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
2609 egprs3->si = 0;
2610 egprs3->r = 1;
2611 egprs3->cv = 7;
2612 egprs3->tfi_hi = tfi & 0x03;
2613 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
2614 egprs3->bsn1_hi = 0;
2615 egprs3->bsn1_lo = 0;
2616 egprs3->cps_hi = 1;
2617 data_msg[3] = 0xff;
2618 egprs3->pi = 0;
2619 egprs3->cps_lo = 1;
2620 egprs3->rsb = 0;
2621 egprs3->spb = 0;
2622 egprs3->pi = 0;
2623 pdch->rcv_block(data_msg, 49, *fn, &meas);
2624
2625 egprs3->bsn1_hi = 1;
2626 egprs3->bsn1_lo = 0;
2627 data_msg[3] = 0x7f;
2628 egprs3->cps_lo = 1;
2629 egprs3->rsb = 0;
2630 egprs3->spb = 0;
2631 egprs3->pi = 0;
2632 data_msg[4] = 0x2;
2633 data_msg[5] = 0x0;
2634 pdch->rcv_block(data_msg, 49, *fn, &meas);
2635
Pau Espin Pedrol14633832022-03-31 19:08:07 +02002636 OSMO_ASSERT(ul_tbf->m_llc.index == 43);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302637
2638 return ul_tbf;
2639}
2640
2641static void test_tbf_li_decoding(void)
2642{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002643 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002644 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002645 struct gprs_rlcmac_pdch *pdch;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302646 int ts_no = 7;
2647 uint32_t fn = 2654218;
2648 uint16_t qta = 31;
2649 uint32_t tlli = 0xf1223344;
2650 const char *imsi = "0011223344";
2651 uint8_t ms_class = 1;
2652 uint8_t egprs_ms_class = 1;
2653 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302654 uint8_t test_data[256];
2655
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002656 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302657
2658 memset(test_data, 1, sizeof(test_data));
2659
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002660 setup_bts(bts, ts_no, 4);
2661 bts->initial_mcs_dl = 9;
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002662 pdch = &bts->trx[0].pdch[ts_no];
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302663
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002664 ul_tbf = tbf_li_decoding(bts, pdch, tlli, &fn, qta,
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302665 ms_class, egprs_ms_class);
2666
Max4c112dc2018-02-01 16:49:23 +01002667 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002668 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302669
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002670 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002671 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302672}
2673
aravind sirsikarf2761382016-10-25 12:45:24 +05302674/*
2675 * Test that a bit within the uncompressed bitmap whose BSN is not within
2676 * the transmit window shall be ignored. See section 9.1.8.2.4 of 44.060
2677 * version 7.27.0 Release 7.
2678 */
2679static void test_tbf_epdan_out_of_rx_window(void)
2680{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002681 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002682 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
aravind sirsikarf2761382016-10-25 12:45:24 +05302683 uint8_t ms_class = 11;
2684 uint8_t egprs_ms_class = 11;
2685 uint8_t trx_no;
2686 uint32_t tlli = 0xffeeddcc;
2687 gprs_rlcmac_dl_tbf *dl_tbf;
2688 int ts_no = 4;
2689 bitvec *block;
2690 uint8_t bits_data[RLC_EGPRS_MAX_WS/8];
2691 bitvec bits;
2692 int bsn_begin, bsn_end;
2693 EGPRS_PD_AckNack_t *ack_nack;
2694 RlcMacUplink_t ul_control_block;
2695 gprs_rlc_v_b *prlcmvb;
2696 gprs_rlc_dl_window *prlcdlwindow;
Pau Espin Pedrol5e300ce2020-02-03 17:18:03 +01002697 int rc;
aravind sirsikarf2761382016-10-25 12:45:24 +05302698
aravind sirsikarcc4214a2016-12-09 16:12:42 +05302699 memset(&ul_control_block, 0, sizeof(RlcMacUplink_t));
2700
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002701 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikarf2761382016-10-25 12:45:24 +05302702
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002703 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01002704 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
aravind sirsikarf2761382016-10-25 12:45:24 +05302705 /* ARQ II */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01002706 the_pcu->vty.dl_arq_type = EGPRS_ARQ2;
aravind sirsikarf2761382016-10-25 12:45:24 +05302707
2708 /*
2709 * Simulate a message captured during over-the-air testing,
2710 * where the following values were observed:
2711 * v_a = 1176, vs = 1288, max sns = 2048, window size = 480.
2712 */
2713 uint8_t data_msg[23] = {0x40, 0x20, 0x0b, 0xff, 0xd1,
2714 0x61, 0x00, 0x3e, 0x0e, 0x51, 0x9f,
2715 0xff, 0xff, 0xfb, 0x80, 0x00, 0x00,
2716 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
2717
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002718 dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no);
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +02002719 ms_confirm_tlli(dl_tbf->ms(), tlli);
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002720 prlcdlwindow = static_cast<gprs_rlc_dl_window *>(dl_tbf->window());
aravind sirsikarf2761382016-10-25 12:45:24 +05302721 prlcmvb = &prlcdlwindow->m_v_b;
2722 prlcdlwindow->m_v_s = 1288;
2723 prlcdlwindow->m_v_a = 1176;
2724 prlcdlwindow->set_sns(2048);
2725 prlcdlwindow->set_ws(480);
2726 prlcmvb->mark_unacked(1176);
2727 prlcmvb->mark_unacked(1177);
2728 prlcmvb->mark_unacked(1286);
2729 prlcmvb->mark_unacked(1287);
2730
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002731 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
aravind sirsikarf2761382016-10-25 12:45:24 +05302732
Alexander Couzensccde5c92017-02-04 03:10:08 +01002733 block = bitvec_alloc(23, tall_pcu_ctx);
aravind sirsikarf2761382016-10-25 12:45:24 +05302734
2735 bitvec_unpack(block, data_msg);
2736
2737 bits.data = bits_data;
2738 bits.data_len = sizeof(bits_data);
2739 bits.cur_bit = 0;
2740
Pau Espin Pedrol5e300ce2020-02-03 17:18:03 +01002741 rc = decode_gsm_rlcmac_uplink(block, &ul_control_block);
2742 OSMO_ASSERT(rc == 0);
aravind sirsikarf2761382016-10-25 12:45:24 +05302743
2744 ack_nack = &ul_control_block.u.Egprs_Packet_Downlink_Ack_Nack;
2745
2746 OSMO_ASSERT(prlcmvb->is_unacked(1176));
2747 OSMO_ASSERT(prlcmvb->is_unacked(1177));
2748 OSMO_ASSERT(prlcmvb->is_unacked(1286));
2749 OSMO_ASSERT(prlcmvb->is_unacked(1287));
2750
2751 Decoding::decode_egprs_acknack_bits(
2752 &ack_nack->EGPRS_AckNack.Desc, &bits,
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002753 &bsn_begin, &bsn_end, prlcdlwindow);
aravind sirsikarf2761382016-10-25 12:45:24 +05302754
2755 dl_tbf->rcvd_dl_ack(
2756 ack_nack->EGPRS_AckNack.Desc.FINAL_ACK_INDICATION,
2757 bsn_begin, &bits);
aravind sirsikarf2761382016-10-25 12:45:24 +05302758
aravind sirsikarfb41afa2016-11-02 15:48:00 +05302759 OSMO_ASSERT(prlcmvb->is_invalid(1176));
2760 OSMO_ASSERT(prlcmvb->is_invalid(1177));
2761 OSMO_ASSERT(prlcmvb->is_acked(1286));
2762 OSMO_ASSERT(prlcmvb->is_acked(1287));
aravind sirsikarf2761382016-10-25 12:45:24 +05302763
2764 bitvec_free(block);
2765 tbf_free(dl_tbf);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002766 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002767 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikarf2761382016-10-25 12:45:24 +05302768}
2769
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302770static void test_tbf_egprs_two_phase_spb(void)
2771{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002772 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002773 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002774 struct gprs_rlcmac_pdch *pdch;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302775 int ts_no = 7;
2776 uint32_t fn = 2654218;
2777 uint16_t qta = 31;
2778 uint32_t tlli = 0xf1223344;
2779 const char *imsi = "0011223344";
2780 uint8_t ms_class = 1;
2781 uint8_t egprs_ms_class = 1;
2782 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302783 uint8_t test_data[256];
2784
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002785 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302786
2787 memset(test_data, 1, sizeof(test_data));
2788
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002789 setup_bts(bts, ts_no, 4);
2790 bts->initial_mcs_dl = 9;
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002791 pdch = &bts->trx[0].pdch[ts_no];
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302792
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002793 ul_tbf = establish_ul_tbf_two_phase_spb(bts, pdch, tlli, &fn, qta,
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302794 ms_class, egprs_ms_class);
2795
Max4c112dc2018-02-01 16:49:23 +01002796 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002797 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302798
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002799 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002800 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302801}
2802
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002803static void test_tbf_egprs_two_phase()
2804{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002805 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002806 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002807 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002808 int ts_no = 7;
2809 uint32_t fn = 2654218;
2810 uint16_t qta = 31;
2811 uint32_t tlli = 0xf1223344;
2812 const char *imsi = "0011223344";
2813 uint8_t ms_class = 1;
2814 uint8_t egprs_ms_class = 1;
2815 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002816 uint8_t test_data[256];
2817
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002818 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002819
2820 memset(test_data, 1, sizeof(test_data));
2821
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002822 setup_bts(bts, ts_no, 4);
2823 bts->initial_mcs_dl = 9;
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002824 pdch = &bts->trx[0].pdch[ts_no];
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002825
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002826 ul_tbf = establish_ul_tbf_two_phase(bts, pdch, tlli, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002827 ms_class, egprs_ms_class);
2828
Max4c112dc2018-02-01 16:49:23 +01002829 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002830 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002831
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002832 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002833 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002834}
2835
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002836static void establish_and_use_egprs_dl_tbf(struct gprs_rlcmac_bts *bts, int mcs)
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002837{
2838 unsigned i;
2839 uint8_t ms_class = 11;
2840 uint8_t egprs_ms_class = 11;
2841 uint32_t fn = 0;
2842 uint8_t trx_no;
2843 uint32_t tlli = 0xffeeddcc;
2844 uint8_t test_data[512];
2845
2846 uint8_t rbb[64/8];
2847
2848 gprs_rlcmac_dl_tbf *dl_tbf;
2849
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002850 fprintf(stderr, "Testing MCS-%d\n", mcs);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002851
2852 memset(test_data, 1, sizeof(test_data));
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002853 bts->initial_mcs_dl = mcs;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002854
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002855 dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no);
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +02002856 ms_confirm_tlli(dl_tbf->ms(), tlli);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002857
2858 for (i = 0; i < sizeof(llc_data); i++)
2859 llc_data[i] = i%256;
2860
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002861 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002862
2863 /* Schedule a small LLC frame */
Pau Espin Pedrol14beef62022-10-26 19:44:07 +02002864 ms_append_llc_dl_data(dl_tbf->ms(), 1000, test_data, 10);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002865
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002866 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002867
2868 /* Drain the queue */
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01002869 while (dl_tbf->have_data()) {
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002870 /* Request to send one RLC/MAC block */
2871 request_dl_rlc_block(dl_tbf, &fn);
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01002872 }
Pau Espin Pedrol16e16782021-03-29 19:10:19 +02002873 send_empty_block(dl_tbf, dl_tbf->control_ts, fn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002874
2875 /* Schedule a large LLC frame */
Pau Espin Pedrol14beef62022-10-26 19:44:07 +02002876 ms_append_llc_dl_data(dl_tbf->ms(), 1000, test_data, sizeof(test_data));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002877
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002878 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002879
2880 /* Drain the queue */
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01002881 while (dl_tbf->have_data()) {
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002882 /* Request to send one RLC/MAC block */
2883 request_dl_rlc_block(dl_tbf, &fn);
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01002884 }
Pau Espin Pedrol16e16782021-03-29 19:10:19 +02002885 send_empty_block(dl_tbf, dl_tbf->control_ts, fn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002886
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002887 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002888
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +02002889 _rcv_ack(true, dl_tbf, rbb); /* Receive a final ACK */
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002890
2891 /* Clean up and ensure tbfs are in the correct state */
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002892 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_WAIT_RELEASE));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002893 check_tbf(dl_tbf);
2894 tbf_free(dl_tbf);
2895}
2896
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002897static gprs_rlcmac_dl_tbf *tbf_init(struct gprs_rlcmac_bts *bts,
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302898 int mcs)
2899{
2900 unsigned i;
2901 uint8_t ms_class = 11;
2902 uint8_t egprs_ms_class = 11;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302903 uint8_t trx_no;
2904 uint32_t tlli = 0xffeeddcc;
2905 uint8_t test_data[512];
2906
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302907 gprs_rlcmac_dl_tbf *dl_tbf;
2908
2909 memset(test_data, 1, sizeof(test_data));
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002910 bts->initial_mcs_dl = mcs;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302911
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002912 dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no);
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +02002913 ms_confirm_tlli(dl_tbf->ms(), tlli);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302914
2915 for (i = 0; i < sizeof(test_data); i++)
2916 test_data[i] = i%256;
2917
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002918 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302919
2920 /* Schedule a LLC frame
2921 * passing only 100 bytes, since it is enough to construct
2922 * 2 RLC data blocks. Which are enough to test Header Type 1
2923 * cases
2924 */
Pau Espin Pedrol14beef62022-10-26 19:44:07 +02002925 ms_append_llc_dl_data(dl_tbf->ms(), 1000, test_data, 100);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302926
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002927 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302928
2929 return dl_tbf;
2930
2931}
2932
2933static void tbf_cleanup(gprs_rlcmac_dl_tbf *dl_tbf)
2934{
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302935 uint8_t rbb[64/8];
2936
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +02002937 _rcv_ack(true, dl_tbf, rbb); /* Receive a final ACK */
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302938
2939 /* Clean up and ensure tbfs are in the correct state */
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002940 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_WAIT_RELEASE));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302941 check_tbf(dl_tbf);
2942 tbf_free(dl_tbf);
2943
2944}
2945
Max7d32f552017-12-15 11:25:14 +01002946#define NACK(tbf, x) do { \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002947 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
2948 w->m_v_b.mark_nacked(x); \
2949 OSMO_ASSERT(w->m_v_b.is_nacked(x)); \
Max7d32f552017-12-15 11:25:14 +01002950 } while(0)
2951
2952#define CHECK_UNACKED(tbf, cs, bsn) do { \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002953 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
2954 OSMO_ASSERT(w->m_v_b.is_unacked(bsn)); \
Max898dddb2019-03-12 15:50:57 +01002955 OSMO_ASSERT(mcs_chan_code(tbf->m_rlc.block(bsn)->cs_current_trans) == cs - 1); \
Max7d32f552017-12-15 11:25:14 +01002956 } while(0)
2957
2958#define CHECK_NACKED(tbf, cs, bsn) do { \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002959 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
2960 OSMO_ASSERT(w->m_v_b.is_nacked(bsn)); \
Max898dddb2019-03-12 15:50:57 +01002961 OSMO_ASSERT(mcs_chan_code(tbf->m_rlc.block(bsn)->cs_current_trans) == cs - 1); \
Max7d32f552017-12-15 11:25:14 +01002962 } while(0)
2963
2964#define MAKE_ACKED(m, tbf, fn, cs, check_unacked) do { \
Pau Espin Pedrold29a1432022-12-15 18:57:35 +01002965 m = tbf->create_dl_acked_block(fn, tbf->control_ts); \
Max7d32f552017-12-15 11:25:14 +01002966 OSMO_ASSERT(m); \
2967 if (check_unacked) \
2968 CHECK_UNACKED(tbf, cs, 0); \
2969 else \
2970 CHECK_NACKED(tbf, cs, 0); \
2971 } while(0)
2972
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002973static void egprs_spb_to_normal_validation(struct gprs_rlcmac_bts *bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002974 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302975{
2976 uint32_t fn = 0;
2977 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302978 uint16_t bsn1, bsn2, bsn3;
2979 struct msgb *msg;
2980 struct gprs_rlc_dl_header_egprs_3 *egprs3;
2981 struct gprs_rlc_dl_header_egprs_2 *egprs2;
2982
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002983 fprintf(stderr, "Testing retx for MCS %u to reseg_mcs %u\n", mcs, demanded_mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302984
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002985 dl_tbf = tbf_init(bts, mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302986
2987 /*
2988 * Table 10.4.8a.3.1 of 44.060.
2989 * (MCS7, MCS9) to (MCS2, MCS3) is not handled since it is same as
2990 * (MCS5, MCS6) to (MCS2, MCS3) transition
2991 */
2992 if (!(mcs == 6 && demanded_mcs == 3))
2993 return;
2994
2995 fn = fn_add_blocks(fn, 1);
2996 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01002997 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302998
2999 egprs2 = (struct gprs_rlc_dl_header_egprs_2 *) msg->data;
Maxb4d368b2017-12-01 17:54:39 +01003000 bsn1 = (egprs2->bsn1_hi << 9) | (egprs2->bsn1_mid << 1) | (egprs2->bsn1_lo);
Max7d32f552017-12-15 11:25:14 +01003001
3002 NACK(dl_tbf, 0);
3003
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303004 OSMO_ASSERT(bsn1 == 0);
3005
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003006 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303007
3008 fn = fn_add_blocks(fn, 1);
3009
3010 /* Send first segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003011 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, false);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303012 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
3013 == EGPRS_RESEG_FIRST_SEG_SENT);
3014
3015 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
3016 OSMO_ASSERT(egprs3->spb == 2);
3017
3018 /* Table 10.4.8a.3.1 of 44.060 */
3019 OSMO_ASSERT(egprs3->cps == 3);
3020
3021 /* Send second segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003022 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303023 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
3024 == EGPRS_RESEG_SECOND_SEG_SENT);
3025
3026 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
3027 /* Table 10.4.8a.3.1 of 44.060 */
3028 OSMO_ASSERT(egprs3->spb == 3);
Maxb4d368b2017-12-01 17:54:39 +01003029 bsn2 = (egprs3->bsn1_hi << 9) | (egprs3->bsn1_mid << 1) | (egprs3->bsn1_lo);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303030 OSMO_ASSERT(bsn2 == bsn1);
3031
3032 /* Table 10.4.8a.3.1 of 44.060 */
3033 OSMO_ASSERT(egprs3->cps == 3);
3034
3035 /* Handle (MCS3, MCS3) -> MCS6 case */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003036 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303037
Max7d32f552017-12-15 11:25:14 +01003038 NACK(dl_tbf, 0);
3039
Pau Espin Pedrold29a1432022-12-15 18:57:35 +01003040 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303041 egprs2 = (struct gprs_rlc_dl_header_egprs_2 *) msg->data;
3042
3043 /* Table 10.4.8a.3.1 of 44.060 */
3044 OSMO_ASSERT(egprs2->cps == 0);
Maxb4d368b2017-12-01 17:54:39 +01003045 bsn3 = (egprs2->bsn1_hi << 9) | (egprs2->bsn1_mid << 1) | (egprs2->bsn1_lo);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303046 OSMO_ASSERT(bsn3 == bsn2);
3047
3048 tbf_cleanup(dl_tbf);
3049}
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01003050
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003051static void establish_and_use_egprs_dl_tbf_for_spb(struct gprs_rlcmac_bts *bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01003052 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303053{
3054 uint32_t fn = 0;
3055 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303056 struct msgb *msg;
3057 struct gprs_rlc_dl_header_egprs_3 *egprs3;
3058
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003059 fprintf(stderr, "Testing retx for MCS %u to reseg_mcs %u\n", mcs, demanded_mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303060
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003061 dl_tbf = tbf_init(bts, mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303062
3063 /*
3064 * Table 10.4.8a.3.1 of 44.060.
3065 * (MCS7, MCS9) to (MCS2, MCS3) is not handled since it is same as
3066 * (MCS5, MCS6) to (MCS2, MCS3) transition
3067 */
3068 /* TODO: Need to support of MCS8 -> MCS6 ->MCS3 transistion
3069 * Refer commit be881c028fc4da00c4046ecd9296727975c206a3
3070 * dated 2016-02-07 23:45:40 (UTC)
3071 */
3072 if (!(((mcs == 5) && (demanded_mcs == 2)) ||
3073 ((mcs == 6) && (demanded_mcs == 3)) ||
3074 ((mcs == 4) && (demanded_mcs == 1))))
3075 return;
3076
3077 fn = fn_add_blocks(fn, 1);
3078 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01003079 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303080
Max7d32f552017-12-15 11:25:14 +01003081 NACK(dl_tbf, 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303082
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003083 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303084
3085 fn = fn_add_blocks(fn, 1);
3086
3087 /* Send first segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003088 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, false);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303089 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
3090 == EGPRS_RESEG_FIRST_SEG_SENT);
3091
3092 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
3093 OSMO_ASSERT(egprs3->spb == 2);
3094
3095 /* Table 10.4.8a.3.1 of 44.060 */
3096 switch (demanded_mcs) {
3097 case 3:
3098 OSMO_ASSERT(egprs3->cps == 3);
3099 break;
3100 case 2:
3101 OSMO_ASSERT(egprs3->cps == 9);
3102 break;
3103 case 1:
3104 OSMO_ASSERT(egprs3->cps == 11);
3105 break;
3106 default:
3107 OSMO_ASSERT(false);
3108 break;
3109 }
3110
3111 /* Send second segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003112 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303113 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
3114 == EGPRS_RESEG_SECOND_SEG_SENT);
3115
3116 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
3117 /* Table 10.4.8a.3.1 of 44.060 */
3118 OSMO_ASSERT(egprs3->spb == 3);
3119
3120 /* Table 10.4.8a.3.1 of 44.060 */
3121 switch (demanded_mcs) {
3122 case 3:
3123 OSMO_ASSERT(egprs3->cps == 3);
3124 break;
3125 case 2:
3126 OSMO_ASSERT(egprs3->cps == 9);
3127 break;
3128 case 1:
3129 OSMO_ASSERT(egprs3->cps == 11);
3130 break;
3131 default:
3132 OSMO_ASSERT(false);
3133 break;
3134 }
3135 tbf_cleanup(dl_tbf);
3136}
3137
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003138static void establish_and_use_egprs_dl_tbf_for_retx(struct gprs_rlcmac_bts *bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01003139 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303140{
3141 uint32_t fn = 0;
3142 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303143 struct msgb *msg;
3144
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003145 fprintf(stderr, "Testing retx for MCS %u - %u\n", mcs, demanded_mcs);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303146
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003147 dl_tbf = tbf_init(bts, mcs);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303148
3149 /* For MCS reduction cases like MCS9->MCS6, MCS7->MCS5
3150 * The MCS transition are referred from table Table 8.1.1.2
3151 * of TS 44.060
3152 */
3153 /* TODO: Need to support of MCS8 -> MCS6 transistion
3154 * Refer commit be881c028fc4da00c4046ecd9296727975c206a3
3155 * dated 2016-02-07 23:45:40 (UTC)
3156 */
3157 if (((mcs == 9) && (demanded_mcs < 9)) ||
3158 ((mcs == 7) && (demanded_mcs < 7))) {
3159 fn = fn_add_blocks(fn, 1);
3160 /* Send 2 RLC data block */
Max7d32f552017-12-15 11:25:14 +01003161 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3162 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303163
Max7d32f552017-12-15 11:25:14 +01003164 NACK(dl_tbf, 0);
3165 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303166
3167 /* Set the demanded MCS to demanded_mcs */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003168 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303169
3170 fn = fn_add_blocks(fn, 1);
3171 /* Retransmit the first RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003172 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
3173 CHECK_NACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303174
3175 fn = fn_add_blocks(fn, 1);
3176 /* Retransmit the second RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003177 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
3178 CHECK_UNACKED(dl_tbf, demanded_mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303179 } else if (((mcs == 5) && (demanded_mcs > 6)) ||
3180 ((mcs == 6) && (demanded_mcs > 8))) {
3181 fn = fn_add_blocks(fn, 1);
3182 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01003183 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303184
3185 fn = fn_add_blocks(fn, 1);
3186 /* Send second RLC data block BSN 1 */
Max7d32f552017-12-15 11:25:14 +01003187 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3188 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303189
Max7d32f552017-12-15 11:25:14 +01003190 NACK(dl_tbf, 0);
3191 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303192
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003193 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303194
3195 fn = fn_add_blocks(fn, 1);
3196 /* Send first, second RLC data blocks with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003197 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
3198 CHECK_UNACKED(dl_tbf, demanded_mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303199 } else if (mcs > 6) {
3200 /* No Mcs change cases are handled here for mcs > MCS6*/
3201 fn = fn_add_blocks(fn, 1);
3202 /* Send first,second RLC data blocks */
Max7d32f552017-12-15 11:25:14 +01003203 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3204 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303205
Max7d32f552017-12-15 11:25:14 +01003206 NACK(dl_tbf, 0);
3207 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303208
3209 fn = fn_add_blocks(fn, 1);
3210 /* Send first,second RLC data blocks with demanded_mcs*/
Max7d32f552017-12-15 11:25:14 +01003211 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3212 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303213 } else {
3214
3215 /* No MCS change cases are handled here for mcs <= MCS6*/
3216 fn = fn_add_blocks(fn, 1);
3217 /* Send first RLC data block */
Max7d32f552017-12-15 11:25:14 +01003218 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303219
Max7d32f552017-12-15 11:25:14 +01003220 NACK(dl_tbf, 0);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303221
3222 fn = fn_add_blocks(fn, 1);
3223 /* Send first RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003224 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303225 }
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01003226 /* Clean up pending items in UL controller: */
Pau Espin Pedrol16e16782021-03-29 19:10:19 +02003227 send_empty_block(dl_tbf, dl_tbf->control_ts, fn+50);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303228 tbf_cleanup(dl_tbf);
3229}
3230
3231static void test_tbf_egprs_retx_dl(void)
3232{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003233 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003234 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303235 uint8_t ts_no = 4;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303236
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003237 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303238
Pau Espin Pedrolad79b852021-01-14 13:20:55 +01003239 the_pcu->vty.cs_downgrade_threshold = 0;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003240 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01003241 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303242 /* ARQ II */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01003243 the_pcu->vty.dl_arq_type = EGPRS_ARQ2;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303244
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303245
3246 /* First parameter is current MCS, second one is demanded_mcs */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003247 establish_and_use_egprs_dl_tbf_for_retx(bts, 6, 6);
3248 establish_and_use_egprs_dl_tbf_for_retx(bts, 1, 9);
3249 establish_and_use_egprs_dl_tbf_for_retx(bts, 2, 8);
3250 establish_and_use_egprs_dl_tbf_for_retx(bts, 5, 7);
3251 establish_and_use_egprs_dl_tbf_for_retx(bts, 6, 9);
3252 establish_and_use_egprs_dl_tbf_for_retx(bts, 7, 5);
3253 establish_and_use_egprs_dl_tbf_for_retx(bts, 9, 6);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303254
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003255 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003256 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303257}
3258
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303259static void test_tbf_egprs_spb_dl(void)
3260{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003261 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003262 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303263 uint8_t ts_no = 4;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303264
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003265 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303266
Pau Espin Pedrolad79b852021-01-14 13:20:55 +01003267 the_pcu->vty.cs_downgrade_threshold = 0;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003268 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01003269 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303270
3271 /* ARQ I resegmentation support */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01003272 the_pcu->vty.dl_arq_type = EGPRS_ARQ1;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303273
3274 /*
3275 * First parameter is current MCS, second one is demanded_mcs
3276 * currently only MCS5->MCS2, MCS6->3, MCS4->MCS1 is tested in UT
3277 * rest scenarios has been integration tested
3278 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003279 establish_and_use_egprs_dl_tbf_for_spb(bts, 6, 3);
3280 establish_and_use_egprs_dl_tbf_for_spb(bts, 5, 2);
3281 establish_and_use_egprs_dl_tbf_for_spb(bts, 4, 1);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303282 /* check MCS6->(MCS3+MCS3)->MCS6 case */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003283 egprs_spb_to_normal_validation(bts, 6, 3);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303284
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003285 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003286 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303287}
3288
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003289static void test_tbf_egprs_dl()
3290{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003291 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003292 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003293 uint8_t ts_no = 4;
3294 int i;
3295
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003296 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003297
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003298 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01003299 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303300 /* ARQ II */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01003301 the_pcu->vty.dl_arq_type = EGPRS_ARQ2;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003302
3303 for (i = 1; i <= 9; i++)
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003304 establish_and_use_egprs_dl_tbf(bts, i);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003305
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003306 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003307 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003308}
3309
3310
3311
aravind sirsikare9a138e2017-01-24 12:36:08 +05303312static void test_packet_access_rej_prr_no_other_tbfs()
3313{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003314 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003315 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003316 struct gprs_rlcmac_pdch *pdch;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303317 uint32_t fn = 2654218;
3318 int ts_no = 7;
3319 uint8_t trx_no = 0;
3320 uint32_t tlli = 0xffeeddcc;
Pau Espin Pedrol54742f22021-04-26 16:48:34 +02003321 struct gprs_rlcmac_ul_tbf *ul_tbf;
3322 struct GprsMs *ms;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303323
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003324 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303325
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003326 setup_bts(bts, ts_no, 4);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003327 pdch = &bts->trx[trx_no].pdch[ts_no];
Pau Espin Pedrol9d67e722021-07-28 19:25:38 +02003328 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2000, 0, OSMO_TDEF_MS) == 0);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303329
3330 int rc = 0;
3331
Pau Espin Pedrol54742f22021-04-26 16:48:34 +02003332 ms = bts_alloc_ms(bts, 0, 0);
3333 ms_set_tlli(ms, tlli);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003334 ul_tbf = ms_new_ul_tbf_rejected_pacch(ms, pdch);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303335
3336 OSMO_ASSERT(ul_tbf != 0);
3337
3338 /* trigger packet access reject */
3339 uint8_t bn = fn2bn(fn);
3340
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003341 rc = gprs_rlcmac_rcv_rts_block(bts, pdch->trx->trx_no, pdch->ts_no, fn, bn);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303342
3343 OSMO_ASSERT(rc == 0);
Pau Espin Pedrol9d67e722021-07-28 19:25:38 +02003344 osmo_select_main(0);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303345
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003346 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003347 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303348}
3349
3350static void test_packet_access_rej_prr()
3351{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003352 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003353 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003354 struct gprs_rlcmac_pdch *pdch;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303355 uint32_t fn = 2654218;
3356 uint16_t qta = 31;
3357 int ts_no = 7;
3358 uint8_t trx_no = 0;
3359 RlcMacUplink_t ulreq = {0};
3360 Packet_Resource_Request_t *presreq = NULL;
3361 uint8_t ms_class = 11;
3362 uint8_t egprs_ms_class = 11;
3363 uint32_t rach_fn = fn - 51;
3364 uint32_t sba_fn = fn + 52;
3365 uint32_t tlli = 0xffeeddcc;
3366 MS_Radio_Access_capability_t *pmsradiocap = NULL;
3367 Multislot_capability_t *pmultislotcap = NULL;
3368
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003369 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303370
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003371 setup_bts(bts, ts_no, 4);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003372 pdch = &bts->trx[trx_no].pdch[ts_no];
aravind sirsikare9a138e2017-01-24 12:36:08 +05303373
3374 int rc = 0;
3375
3376 /*
3377 * Trigger rach till resources(USF) exhaust
3378 */
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003379 int i;
3380 for (i = 0; i < 8; i++) {
3381 rc = bts_handle_rach(bts, 0x70 + i, rach_fn, qta);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303382 }
3383
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003384 sba_fn = 52;
3385 for (i = 0; i < 8; i++) {
3386 /* fake a resource request */
3387 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
3388 presreq = &ulreq.u.Packet_Resource_Request;
3389 presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
3390 presreq->ID.UnionType = 1; /* != 0 */
3391 presreq->ID.u.TLLI = tlli + i;
3392 presreq->Exist_MS_Radio_Access_capability2 = 1;
3393 pmsradiocap = &presreq->MS_Radio_Access_capability2;
3394 pmsradiocap->Count_MS_RA_capability_value = 1;
3395 pmsradiocap->MS_RA_capability_value[0].u.Content.
3396 Exist_Multislot_capability = 1;
3397 pmultislotcap = &pmsradiocap->MS_RA_capability_value[0].
3398 u.Content.Multislot_capability;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303399
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003400 pmultislotcap->Exist_GPRS_multislot_class = 1;
3401 pmultislotcap->GPRS_multislot_class = ms_class;
3402 if (egprs_ms_class) {
3403 pmultislotcap->Exist_EGPRS_multislot_class = 1;
3404 pmultislotcap->EGPRS_multislot_class = egprs_ms_class;
3405 }
aravind sirsikare9a138e2017-01-24 12:36:08 +05303406
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003407 send_ul_mac_block(bts, pdch, &ulreq, sba_fn);
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003408 sba_fn = fn_next_block(sba_fn);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303409
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003410 /* trigger packet access reject */
3411 uint8_t bn = fn2bn(fn);
3412
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003413 rc = gprs_rlcmac_rcv_rts_block(bts, pdch->trx->trx_no, pdch->ts_no, fn, bn);
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003414 OSMO_ASSERT(rc == 0);
3415 }
aravind sirsikare9a138e2017-01-24 12:36:08 +05303416
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003417 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003418 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303419}
3420
aravind sirsikared3413e2016-11-11 17:15:10 +05303421void test_packet_access_rej_epdan()
3422{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003423 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003424 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
aravind sirsikared3413e2016-11-11 17:15:10 +05303425 uint32_t tlli = 0xffeeddcc;
Pau Espin Pedrol2ab840a2021-04-26 17:49:05 +02003426 static uint8_t exp[] = { 0x40, 0x84, 0x7f, 0xf7, 0x6e, 0xe6, 0x7e, 0xab,
Maxd3a0d912019-03-05 16:15:01 +01003427 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
3428 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b
3429 };
aravind sirsikared3413e2016-11-11 17:15:10 +05303430
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003431 fprintf(stderr, "=== start %s ===\n", __func__);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003432 setup_bts(bts, 4);
3433 static gprs_rlcmac_dl_tbf *dl_tbf = tbf_init(bts, 1);
aravind sirsikared3413e2016-11-11 17:15:10 +05303434
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +02003435 ms_confirm_tlli(dl_tbf->ms(), tlli);
aravind sirsikared3413e2016-11-11 17:15:10 +05303436
Pau Espin Pedrol6ad11a62021-07-27 12:27:08 +02003437 osmo_fsm_inst_dispatch(dl_tbf->ul_ass_fsm.fi, TBF_UL_ASS_EV_SCHED_ASS_REJ, NULL);
3438 struct msgb *msg = tbf_ul_ass_create_rlcmac_msg((const struct gprs_rlcmac_tbf*)dl_tbf, 0, 0);
aravind sirsikared3413e2016-11-11 17:15:10 +05303439
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003440 fprintf(stderr, "packet reject: %s\n",
aravind sirsikared3413e2016-11-11 17:15:10 +05303441 osmo_hexdump(msg->data, 23));
3442
Maxd3a0d912019-03-05 16:15:01 +01003443 if (!msgb_eq_data_print(msg, exp, GSM_MACBLOCK_LEN))
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003444 fprintf(stderr, "%s test failed!\n", __func__);
Maxd3a0d912019-03-05 16:15:01 +01003445
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003446 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003447 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikared3413e2016-11-11 17:15:10 +05303448}
3449
3450
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003451int main(int argc, char **argv)
3452{
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003453 struct vty_app_info pcu_vty_info = {0};
3454
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003455 tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile TbfTest context");
3456 if (!tall_pcu_ctx)
3457 abort();
3458
Neels Hofmeyr78ce5912017-02-08 17:07:31 +01003459 msgb_talloc_ctx_init(tall_pcu_ctx, 0);
Neels Hofmeyr42f2d612018-04-01 16:54:40 +02003460 osmo_init_logging2(tall_pcu_ctx, &gprs_log_info);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003461 log_set_use_color(osmo_stderr_target, 0);
Pau Espin Pedrol00f52cc2021-02-19 14:01:52 +01003462 log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
Pau Espin Pedrolb18d2a52021-02-19 14:00:48 +01003463 log_set_print_category(osmo_stderr_target, 0);
3464 log_set_print_category_hex(osmo_stderr_target, 0);
Maxfdd79e92018-01-24 11:04:59 +01003465 log_parse_category_mask(osmo_stderr_target, "DRLCMAC,1:DRLCMACDATA,3:DRLCMACDL,3:DRLCMACUL,3:"
Harald Welte398f60e2020-12-10 13:39:21 +01003466 "DRLCMACSCHED,1:DRLCMACMEAS,3:DNS,3:DLBSSGP,3:DPCU,5:"
Max86e35e42019-03-07 12:20:42 +01003467 "DL1IF,6:DTBF,1:DTBFUL,1:DTBFDL,1:DLGLOBAL,2:");
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02003468 osmo_fsm_log_addr(false);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003469 vty_init(&pcu_vty_info);
Pau Espin Pedrolcd2ac562019-08-05 14:30:44 +02003470 pcu_vty_init();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003471
Vadim Yanitskiy87b6e7d2019-11-08 04:44:04 +07003472 /* Initialize shared UL measurements */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003473 pcu_l1_meas_set_link_qual(&meas, 12);
3474 pcu_l1_meas_set_rssi(&meas, 31);
Vadim Yanitskiy87b6e7d2019-11-08 04:44:04 +07003475
Jacob Erlbeckac89a552015-06-29 14:18:46 +02003476 test_tbf_base();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003477 test_tbf_tlli_update();
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +01003478 test_tbf_final_ack(TEST_MODE_STANDARD);
3479 test_tbf_final_ack(TEST_MODE_REVERSE_FREE);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +01003480 test_tbf_delayed_release();
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +02003481 test_tbf_imsi();
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003482 test_tbf_exhaustion();
Jacob Erlbeck41168642015-06-12 13:41:00 +02003483 test_tbf_dl_llc_loss();
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02003484 test_tbf_single_phase();
Pau Espin Pedrol22b26d82022-10-26 15:44:14 +02003485 test_tbf_single_phase2();
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02003486 test_tbf_two_phase();
Jacob Erlbeckb1395982015-08-21 18:15:38 +02003487 test_tbf_ra_update_rach();
3488 test_tbf_dl_flow_and_rach_two_phase();
3489 test_tbf_dl_flow_and_rach_single_phase();
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02003490 test_tbf_dl_reuse();
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01003491 test_tbf_gprs_egprs();
Jacob Erlbeck36df7742016-01-19 15:53:30 +01003492 test_tbf_ws();
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003493 test_tbf_egprs_two_phase();
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05303494 test_tbf_egprs_two_phase_spb();
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003495 test_tbf_egprs_dl();
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303496 test_tbf_egprs_retx_dl();
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303497 test_tbf_egprs_spb_dl();
Aravind Sirsikar02352b42016-08-25 16:37:30 +05303498 test_tbf_puan_urbb_len();
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05303499 test_tbf_update_ws();
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05303500 test_tbf_li_decoding();
aravind sirsikarf2761382016-10-25 12:45:24 +05303501 test_tbf_epdan_out_of_rx_window();
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05303502 test_immediate_assign_rej();
sivasankari1d8744c2017-01-24 15:53:35 +05303503 test_tbf_egprs_two_phase_puan();
aravind sirsikared3413e2016-11-11 17:15:10 +05303504 test_packet_access_rej_epdan();
aravind sirsikare9a138e2017-01-24 12:36:08 +05303505 test_packet_access_rej_prr();
3506 test_packet_access_rej_prr_no_other_tbfs();
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01003507 test_ms_merge_dl_tbf_different_trx();
Jacob Erlbeck67c38502015-05-11 10:32:40 +02003508
3509 if (getenv("TALLOC_REPORT_FULL"))
3510 talloc_report_full(tall_pcu_ctx, stderr);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003511 return EXIT_SUCCESS;
3512}
3513
3514/*
3515 * stubs that should not be reached
3516 */
3517extern "C" {
3518void l1if_pdch_req() { abort(); }
3519void l1if_connect_pdch() { abort(); }
Philipp Maier72ed3332023-02-27 15:32:00 +01003520void l1if_disconnect_pdch() { abort(); }
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003521void l1if_close_pdch() { abort(); }
3522void l1if_open_pdch() { abort(); }
3523}