blob: 6769165f4ae8eec1d6122ad55d3eec9cacdb0cdb [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
2452 * we'll have it upgrade to multislot on TRX0 later. */
2453 memset(llc_buf, 1, sizeof(llc_buf));
2454 rc = dl_tbf_handle(bts, old_tlli, 0, imsi, ms_class, 0,
2455 delay_csec, llc_buf, sizeof(llc_buf));
2456 OSMO_ASSERT(rc >= 0);
2457
2458 first_ms = bts_ms_store(bts)->get_ms(GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, imsi);
2459 OSMO_ASSERT(first_ms);
2460 dl_tbf = ms_dl_tbf(first_ms);
2461 OSMO_ASSERT(dl_tbf);
2462 OSMO_ASSERT(tbf_get_trx(dl_tbf) == trx1);
2463 OSMO_ASSERT(dl_tbf->control_ts->trx == trx1);
2464 struct gprs_rlcmac_pdch *old_dl_control_ts = dl_tbf->control_ts;
2465
2466 /* Enable PDCHs on TRX0 so that second_ms is allocated on TRX0: */
2467 trx0->pdch[1].enable();
2468 trx0->pdch[2].enable();
2469 trx0->pdch[3].enable();
2470
2471 second_ms = bts_alloc_ms(bts, 0, 0);
2472 ms_set_tlli(second_ms, new_tlli);
2473 ul_tbf = ul_tbf_alloc(bts, second_ms, 0, true);
2474 OSMO_ASSERT(ul_tbf != NULL);
2475 ms_update_announced_tlli(second_ms, new_tlli);
2476
2477 /* Here PCU gets to know the MS are the same and they get merged. */
2478 rc = dl_tbf_handle(bts, new_tlli, old_tlli, imsi, ms_class, 0,
2479 delay_csec, llc_buf, sizeof(llc_buf));
2480 OSMO_ASSERT(rc >= 0);
2481 /* Here we assert DL-TBF is currently moved to the new MS, which is wrong! */
2482 OSMO_ASSERT(dl_tbf == ms_dl_tbf(second_ms));
2483
2484 /* Here BTS would answer with data_cnf and trigger
2485 * bts_rcv_imm_ass_cnf(), which would trigger TBF_EV_ASSIGN_PCUIF_CNF.
2486 * That in turn would set up timer X2002. Finally, X2002 timeout
2487 * moves it to ASSIGN state for multislot upgrade. We set X2002 timeout to 0 here to get
2488 * immediate trigger through osmo_select_main() */
2489 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2002, 0, OSMO_TDEF_MS) == 0);
2490 osmo_fsm_inst_dispatch(ms_dl_tbf(second_ms)->state_fi, TBF_EV_ASSIGN_PCUIF_CNF, NULL);
2491 osmo_select_main(0);
2492 OSMO_ASSERT(dl_tbf == ms_dl_tbf(second_ms));
2493 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_ASSIGN));
2494 /* Here we validate DL-TBF was intially allocated in TRX1 but moved to TRX0 during multislot upgrade: */
2495 OSMO_ASSERT(tbf_get_trx(dl_tbf) == trx0);
2496 OSMO_ASSERT(old_dl_control_ts != dl_tbf->control_ts);
2497
2498 /* dl_tbf is still in the list of trx1 so that the PktDlAss on the old
2499 * TRX/TS can be scheduled to assign the new TRX/TS allocation: */
2500 OSMO_ASSERT(dl_tbf == llist_first_entry_or_null(&trx1->dl_tbfs, struct llist_item, list)->entry);
2501
2502 /* get the PACCH PktDlAss for the DL-TBF: */
2503 request_dl_rlc_block(dl_tbf->bts, dl_tbf->control_ts, &fn);
2504
2505 fprintf(stderr, "=== end %s ===\n", __func__);
2506 TALLOC_FREE(the_pcu);
2507}
2508
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302509static void test_tbf_puan_urbb_len(void)
2510{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002511 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002512 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002513 struct gprs_rlcmac_pdch *pdch;
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302514 int ts_no = 7;
2515 uint32_t fn = 2654218;
2516 uint16_t qta = 31;
2517 uint32_t tlli = 0xf1223344;
2518 const char *imsi = "0011223344";
2519 uint8_t ms_class = 1;
2520 uint8_t egprs_ms_class = 1;
2521 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302522 uint8_t test_data[256];
2523
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002524 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302525
2526 memset(test_data, 1, sizeof(test_data));
2527
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002528 setup_bts(bts, ts_no, 4);
2529 bts->initial_mcs_dl = 9;
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002530 pdch = &bts->trx[0].pdch[ts_no];
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302531
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002532 ul_tbf = puan_urbb_len_issue(bts, pdch, tlli, &fn, qta,
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302533 ms_class, egprs_ms_class);
2534
Max4c112dc2018-02-01 16:49:23 +01002535 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002536 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302537
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002538 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002539 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302540}
2541
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002542static gprs_rlcmac_ul_tbf *tbf_li_decoding(struct gprs_rlcmac_bts *bts,
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002543 struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta,
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302544 uint8_t ms_class, uint8_t egprs_ms_class)
2545{
2546 GprsMs *ms;
2547 uint32_t rach_fn = *fn - 51;
2548 uint32_t sba_fn = *fn + 52;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002549 int tfi = 0;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302550 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302551 RlcMacUplink_t ulreq = {0};
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302552 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302553 Packet_Resource_Request_t *presreq = NULL;
2554 MS_Radio_Access_capability_t *pmsradiocap = NULL;
2555 Multislot_capability_t *pmultislotcap = NULL;
2556
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302557 /* needed to set last_rts_fn in the PDCH object */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002558 request_dl_rlc_block(bts, pdch, fn);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302559
2560 /*
2561 * simulate RACH, this sends an Immediate
2562 * Assignment Uplink on the AGCH
2563 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002564 bts_handle_rach(bts, 0x73, rach_fn, qta);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302565
2566 /* get next free TFI */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002567 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &pdch->trx->trx_no, -1);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302568
2569 /* fake a resource request */
2570 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
2571 presreq = &ulreq.u.Packet_Resource_Request;
2572 presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
2573 presreq->ID.UnionType = 1; /* != 0 */
2574 presreq->ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01002575 presreq->Exist_MS_Radio_Access_capability2 = 1;
2576 pmsradiocap = &presreq->MS_Radio_Access_capability2;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302577 pmsradiocap->Count_MS_RA_capability_value = 1;
2578 pmsradiocap->MS_RA_capability_value[0].u.Content.
2579 Exist_Multislot_capability = 1;
2580 pmultislotcap = &pmsradiocap->MS_RA_capability_value[0].
2581 u.Content.Multislot_capability;
2582
2583 pmultislotcap->Exist_GPRS_multislot_class = 1;
2584 pmultislotcap->GPRS_multislot_class = ms_class;
2585 if (egprs_ms_class) {
2586 pmultislotcap->Exist_EGPRS_multislot_class = 1;
2587 pmultislotcap->EGPRS_multislot_class = ms_class;
2588 }
2589
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002590 send_ul_mac_block(bts, pdch, &ulreq, sba_fn);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302591
2592 /* check the TBF */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002593 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, pdch->trx->trx_no, pdch->ts_no);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302594 OSMO_ASSERT(ul_tbf);
2595 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
2596
2597 /* send packet uplink assignment */
2598 *fn = sba_fn;
2599 request_dl_rlc_block(ul_tbf, fn);
2600
2601 /* send real acknowledgement */
2602 send_control_ack(ul_tbf);
2603
2604 check_tbf(ul_tbf);
2605
2606 uint8_t data_msg[49] = {0};
2607
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002608 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302609 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002610 OSMO_ASSERT(ms_ta(ms) == qta/4);
2611 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302612
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302613 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
2614 egprs3->si = 0;
2615 egprs3->r = 1;
2616 egprs3->cv = 7;
2617 egprs3->tfi_hi = tfi & 0x03;
2618 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
2619 egprs3->bsn1_hi = 0;
2620 egprs3->bsn1_lo = 0;
2621 egprs3->cps_hi = 1;
2622 data_msg[3] = 0xff;
2623 egprs3->pi = 0;
2624 egprs3->cps_lo = 1;
2625 egprs3->rsb = 0;
2626 egprs3->spb = 0;
2627 egprs3->pi = 0;
2628 pdch->rcv_block(data_msg, 49, *fn, &meas);
2629
2630 egprs3->bsn1_hi = 1;
2631 egprs3->bsn1_lo = 0;
2632 data_msg[3] = 0x7f;
2633 egprs3->cps_lo = 1;
2634 egprs3->rsb = 0;
2635 egprs3->spb = 0;
2636 egprs3->pi = 0;
2637 data_msg[4] = 0x2;
2638 data_msg[5] = 0x0;
2639 pdch->rcv_block(data_msg, 49, *fn, &meas);
2640
Pau Espin Pedrol14633832022-03-31 19:08:07 +02002641 OSMO_ASSERT(ul_tbf->m_llc.index == 43);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302642
2643 return ul_tbf;
2644}
2645
2646static void test_tbf_li_decoding(void)
2647{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002648 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002649 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002650 struct gprs_rlcmac_pdch *pdch;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302651 int ts_no = 7;
2652 uint32_t fn = 2654218;
2653 uint16_t qta = 31;
2654 uint32_t tlli = 0xf1223344;
2655 const char *imsi = "0011223344";
2656 uint8_t ms_class = 1;
2657 uint8_t egprs_ms_class = 1;
2658 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302659 uint8_t test_data[256];
2660
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002661 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302662
2663 memset(test_data, 1, sizeof(test_data));
2664
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002665 setup_bts(bts, ts_no, 4);
2666 bts->initial_mcs_dl = 9;
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002667 pdch = &bts->trx[0].pdch[ts_no];
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302668
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002669 ul_tbf = tbf_li_decoding(bts, pdch, tlli, &fn, qta,
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302670 ms_class, egprs_ms_class);
2671
Max4c112dc2018-02-01 16:49:23 +01002672 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002673 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302674
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002675 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002676 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302677}
2678
aravind sirsikarf2761382016-10-25 12:45:24 +05302679/*
2680 * Test that a bit within the uncompressed bitmap whose BSN is not within
2681 * the transmit window shall be ignored. See section 9.1.8.2.4 of 44.060
2682 * version 7.27.0 Release 7.
2683 */
2684static void test_tbf_epdan_out_of_rx_window(void)
2685{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002686 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002687 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
aravind sirsikarf2761382016-10-25 12:45:24 +05302688 uint8_t ms_class = 11;
2689 uint8_t egprs_ms_class = 11;
2690 uint8_t trx_no;
2691 uint32_t tlli = 0xffeeddcc;
2692 gprs_rlcmac_dl_tbf *dl_tbf;
2693 int ts_no = 4;
2694 bitvec *block;
2695 uint8_t bits_data[RLC_EGPRS_MAX_WS/8];
2696 bitvec bits;
2697 int bsn_begin, bsn_end;
2698 EGPRS_PD_AckNack_t *ack_nack;
2699 RlcMacUplink_t ul_control_block;
2700 gprs_rlc_v_b *prlcmvb;
2701 gprs_rlc_dl_window *prlcdlwindow;
Pau Espin Pedrol5e300ce2020-02-03 17:18:03 +01002702 int rc;
aravind sirsikarf2761382016-10-25 12:45:24 +05302703
aravind sirsikarcc4214a2016-12-09 16:12:42 +05302704 memset(&ul_control_block, 0, sizeof(RlcMacUplink_t));
2705
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002706 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikarf2761382016-10-25 12:45:24 +05302707
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002708 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01002709 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
aravind sirsikarf2761382016-10-25 12:45:24 +05302710 /* ARQ II */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01002711 the_pcu->vty.dl_arq_type = EGPRS_ARQ2;
aravind sirsikarf2761382016-10-25 12:45:24 +05302712
2713 /*
2714 * Simulate a message captured during over-the-air testing,
2715 * where the following values were observed:
2716 * v_a = 1176, vs = 1288, max sns = 2048, window size = 480.
2717 */
2718 uint8_t data_msg[23] = {0x40, 0x20, 0x0b, 0xff, 0xd1,
2719 0x61, 0x00, 0x3e, 0x0e, 0x51, 0x9f,
2720 0xff, 0xff, 0xfb, 0x80, 0x00, 0x00,
2721 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
2722
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002723 dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no);
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +02002724 ms_confirm_tlli(dl_tbf->ms(), tlli);
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002725 prlcdlwindow = static_cast<gprs_rlc_dl_window *>(dl_tbf->window());
aravind sirsikarf2761382016-10-25 12:45:24 +05302726 prlcmvb = &prlcdlwindow->m_v_b;
2727 prlcdlwindow->m_v_s = 1288;
2728 prlcdlwindow->m_v_a = 1176;
2729 prlcdlwindow->set_sns(2048);
2730 prlcdlwindow->set_ws(480);
2731 prlcmvb->mark_unacked(1176);
2732 prlcmvb->mark_unacked(1177);
2733 prlcmvb->mark_unacked(1286);
2734 prlcmvb->mark_unacked(1287);
2735
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002736 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
aravind sirsikarf2761382016-10-25 12:45:24 +05302737
Alexander Couzensccde5c92017-02-04 03:10:08 +01002738 block = bitvec_alloc(23, tall_pcu_ctx);
aravind sirsikarf2761382016-10-25 12:45:24 +05302739
2740 bitvec_unpack(block, data_msg);
2741
2742 bits.data = bits_data;
2743 bits.data_len = sizeof(bits_data);
2744 bits.cur_bit = 0;
2745
Pau Espin Pedrol5e300ce2020-02-03 17:18:03 +01002746 rc = decode_gsm_rlcmac_uplink(block, &ul_control_block);
2747 OSMO_ASSERT(rc == 0);
aravind sirsikarf2761382016-10-25 12:45:24 +05302748
2749 ack_nack = &ul_control_block.u.Egprs_Packet_Downlink_Ack_Nack;
2750
2751 OSMO_ASSERT(prlcmvb->is_unacked(1176));
2752 OSMO_ASSERT(prlcmvb->is_unacked(1177));
2753 OSMO_ASSERT(prlcmvb->is_unacked(1286));
2754 OSMO_ASSERT(prlcmvb->is_unacked(1287));
2755
2756 Decoding::decode_egprs_acknack_bits(
2757 &ack_nack->EGPRS_AckNack.Desc, &bits,
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002758 &bsn_begin, &bsn_end, prlcdlwindow);
aravind sirsikarf2761382016-10-25 12:45:24 +05302759
2760 dl_tbf->rcvd_dl_ack(
2761 ack_nack->EGPRS_AckNack.Desc.FINAL_ACK_INDICATION,
2762 bsn_begin, &bits);
aravind sirsikarf2761382016-10-25 12:45:24 +05302763
aravind sirsikarfb41afa2016-11-02 15:48:00 +05302764 OSMO_ASSERT(prlcmvb->is_invalid(1176));
2765 OSMO_ASSERT(prlcmvb->is_invalid(1177));
2766 OSMO_ASSERT(prlcmvb->is_acked(1286));
2767 OSMO_ASSERT(prlcmvb->is_acked(1287));
aravind sirsikarf2761382016-10-25 12:45:24 +05302768
2769 bitvec_free(block);
2770 tbf_free(dl_tbf);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002771 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002772 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikarf2761382016-10-25 12:45:24 +05302773}
2774
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302775static void test_tbf_egprs_two_phase_spb(void)
2776{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002777 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002778 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002779 struct gprs_rlcmac_pdch *pdch;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302780 int ts_no = 7;
2781 uint32_t fn = 2654218;
2782 uint16_t qta = 31;
2783 uint32_t tlli = 0xf1223344;
2784 const char *imsi = "0011223344";
2785 uint8_t ms_class = 1;
2786 uint8_t egprs_ms_class = 1;
2787 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302788 uint8_t test_data[256];
2789
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002790 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302791
2792 memset(test_data, 1, sizeof(test_data));
2793
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002794 setup_bts(bts, ts_no, 4);
2795 bts->initial_mcs_dl = 9;
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002796 pdch = &bts->trx[0].pdch[ts_no];
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302797
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002798 ul_tbf = establish_ul_tbf_two_phase_spb(bts, pdch, tlli, &fn, qta,
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302799 ms_class, egprs_ms_class);
2800
Max4c112dc2018-02-01 16:49:23 +01002801 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002802 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302803
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002804 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002805 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302806}
2807
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002808static void test_tbf_egprs_two_phase()
2809{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002810 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002811 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002812 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002813 int ts_no = 7;
2814 uint32_t fn = 2654218;
2815 uint16_t qta = 31;
2816 uint32_t tlli = 0xf1223344;
2817 const char *imsi = "0011223344";
2818 uint8_t ms_class = 1;
2819 uint8_t egprs_ms_class = 1;
2820 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002821 uint8_t test_data[256];
2822
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002823 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002824
2825 memset(test_data, 1, sizeof(test_data));
2826
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002827 setup_bts(bts, ts_no, 4);
2828 bts->initial_mcs_dl = 9;
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002829 pdch = &bts->trx[0].pdch[ts_no];
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002830
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002831 ul_tbf = establish_ul_tbf_two_phase(bts, pdch, tlli, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002832 ms_class, egprs_ms_class);
2833
Max4c112dc2018-02-01 16:49:23 +01002834 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002835 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002836
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002837 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002838 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002839}
2840
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002841static void establish_and_use_egprs_dl_tbf(struct gprs_rlcmac_bts *bts, int mcs)
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002842{
2843 unsigned i;
2844 uint8_t ms_class = 11;
2845 uint8_t egprs_ms_class = 11;
2846 uint32_t fn = 0;
2847 uint8_t trx_no;
2848 uint32_t tlli = 0xffeeddcc;
2849 uint8_t test_data[512];
2850
2851 uint8_t rbb[64/8];
2852
2853 gprs_rlcmac_dl_tbf *dl_tbf;
2854
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002855 fprintf(stderr, "Testing MCS-%d\n", mcs);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002856
2857 memset(test_data, 1, sizeof(test_data));
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002858 bts->initial_mcs_dl = mcs;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002859
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002860 dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no);
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +02002861 ms_confirm_tlli(dl_tbf->ms(), tlli);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002862
2863 for (i = 0; i < sizeof(llc_data); i++)
2864 llc_data[i] = i%256;
2865
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 /* Schedule a small LLC frame */
Pau Espin Pedrol14beef62022-10-26 19:44:07 +02002869 ms_append_llc_dl_data(dl_tbf->ms(), 1000, test_data, 10);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002870
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002871 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002872
2873 /* Drain the queue */
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01002874 while (dl_tbf->have_data()) {
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002875 /* Request to send one RLC/MAC block */
2876 request_dl_rlc_block(dl_tbf, &fn);
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01002877 }
Pau Espin Pedrol16e16782021-03-29 19:10:19 +02002878 send_empty_block(dl_tbf, dl_tbf->control_ts, fn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002879
2880 /* Schedule a large LLC frame */
Pau Espin Pedrol14beef62022-10-26 19:44:07 +02002881 ms_append_llc_dl_data(dl_tbf->ms(), 1000, test_data, sizeof(test_data));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002882
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002883 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002884
2885 /* Drain the queue */
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01002886 while (dl_tbf->have_data()) {
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002887 /* Request to send one RLC/MAC block */
2888 request_dl_rlc_block(dl_tbf, &fn);
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01002889 }
Pau Espin Pedrol16e16782021-03-29 19:10:19 +02002890 send_empty_block(dl_tbf, dl_tbf->control_ts, fn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002891
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002892 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002893
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +02002894 _rcv_ack(true, dl_tbf, rbb); /* Receive a final ACK */
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002895
2896 /* Clean up and ensure tbfs are in the correct state */
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002897 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_WAIT_RELEASE));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002898 check_tbf(dl_tbf);
2899 tbf_free(dl_tbf);
2900}
2901
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002902static gprs_rlcmac_dl_tbf *tbf_init(struct gprs_rlcmac_bts *bts,
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302903 int mcs)
2904{
2905 unsigned i;
2906 uint8_t ms_class = 11;
2907 uint8_t egprs_ms_class = 11;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302908 uint8_t trx_no;
2909 uint32_t tlli = 0xffeeddcc;
2910 uint8_t test_data[512];
2911
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302912 gprs_rlcmac_dl_tbf *dl_tbf;
2913
2914 memset(test_data, 1, sizeof(test_data));
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002915 bts->initial_mcs_dl = mcs;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302916
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002917 dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no);
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +02002918 ms_confirm_tlli(dl_tbf->ms(), tlli);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302919
2920 for (i = 0; i < sizeof(test_data); i++)
2921 test_data[i] = i%256;
2922
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002923 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302924
2925 /* Schedule a LLC frame
2926 * passing only 100 bytes, since it is enough to construct
2927 * 2 RLC data blocks. Which are enough to test Header Type 1
2928 * cases
2929 */
Pau Espin Pedrol14beef62022-10-26 19:44:07 +02002930 ms_append_llc_dl_data(dl_tbf->ms(), 1000, test_data, 100);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302931
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002932 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302933
2934 return dl_tbf;
2935
2936}
2937
2938static void tbf_cleanup(gprs_rlcmac_dl_tbf *dl_tbf)
2939{
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302940 uint8_t rbb[64/8];
2941
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +02002942 _rcv_ack(true, dl_tbf, rbb); /* Receive a final ACK */
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302943
2944 /* Clean up and ensure tbfs are in the correct state */
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002945 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_WAIT_RELEASE));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302946 check_tbf(dl_tbf);
2947 tbf_free(dl_tbf);
2948
2949}
2950
Max7d32f552017-12-15 11:25:14 +01002951#define NACK(tbf, x) do { \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002952 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
2953 w->m_v_b.mark_nacked(x); \
2954 OSMO_ASSERT(w->m_v_b.is_nacked(x)); \
Max7d32f552017-12-15 11:25:14 +01002955 } while(0)
2956
2957#define CHECK_UNACKED(tbf, cs, bsn) do { \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002958 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
2959 OSMO_ASSERT(w->m_v_b.is_unacked(bsn)); \
Max898dddb2019-03-12 15:50:57 +01002960 OSMO_ASSERT(mcs_chan_code(tbf->m_rlc.block(bsn)->cs_current_trans) == cs - 1); \
Max7d32f552017-12-15 11:25:14 +01002961 } while(0)
2962
2963#define CHECK_NACKED(tbf, cs, bsn) do { \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002964 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
2965 OSMO_ASSERT(w->m_v_b.is_nacked(bsn)); \
Max898dddb2019-03-12 15:50:57 +01002966 OSMO_ASSERT(mcs_chan_code(tbf->m_rlc.block(bsn)->cs_current_trans) == cs - 1); \
Max7d32f552017-12-15 11:25:14 +01002967 } while(0)
2968
2969#define MAKE_ACKED(m, tbf, fn, cs, check_unacked) do { \
Pau Espin Pedrold29a1432022-12-15 18:57:35 +01002970 m = tbf->create_dl_acked_block(fn, tbf->control_ts); \
Max7d32f552017-12-15 11:25:14 +01002971 OSMO_ASSERT(m); \
2972 if (check_unacked) \
2973 CHECK_UNACKED(tbf, cs, 0); \
2974 else \
2975 CHECK_NACKED(tbf, cs, 0); \
2976 } while(0)
2977
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002978static void egprs_spb_to_normal_validation(struct gprs_rlcmac_bts *bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002979 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302980{
2981 uint32_t fn = 0;
2982 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302983 uint16_t bsn1, bsn2, bsn3;
2984 struct msgb *msg;
2985 struct gprs_rlc_dl_header_egprs_3 *egprs3;
2986 struct gprs_rlc_dl_header_egprs_2 *egprs2;
2987
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002988 fprintf(stderr, "Testing retx for MCS %u to reseg_mcs %u\n", mcs, demanded_mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302989
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002990 dl_tbf = tbf_init(bts, mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302991
2992 /*
2993 * Table 10.4.8a.3.1 of 44.060.
2994 * (MCS7, MCS9) to (MCS2, MCS3) is not handled since it is same as
2995 * (MCS5, MCS6) to (MCS2, MCS3) transition
2996 */
2997 if (!(mcs == 6 && demanded_mcs == 3))
2998 return;
2999
3000 fn = fn_add_blocks(fn, 1);
3001 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01003002 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303003
3004 egprs2 = (struct gprs_rlc_dl_header_egprs_2 *) msg->data;
Maxb4d368b2017-12-01 17:54:39 +01003005 bsn1 = (egprs2->bsn1_hi << 9) | (egprs2->bsn1_mid << 1) | (egprs2->bsn1_lo);
Max7d32f552017-12-15 11:25:14 +01003006
3007 NACK(dl_tbf, 0);
3008
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303009 OSMO_ASSERT(bsn1 == 0);
3010
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003011 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303012
3013 fn = fn_add_blocks(fn, 1);
3014
3015 /* Send first segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003016 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, false);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303017 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
3018 == EGPRS_RESEG_FIRST_SEG_SENT);
3019
3020 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
3021 OSMO_ASSERT(egprs3->spb == 2);
3022
3023 /* Table 10.4.8a.3.1 of 44.060 */
3024 OSMO_ASSERT(egprs3->cps == 3);
3025
3026 /* Send second segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003027 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303028 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
3029 == EGPRS_RESEG_SECOND_SEG_SENT);
3030
3031 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
3032 /* Table 10.4.8a.3.1 of 44.060 */
3033 OSMO_ASSERT(egprs3->spb == 3);
Maxb4d368b2017-12-01 17:54:39 +01003034 bsn2 = (egprs3->bsn1_hi << 9) | (egprs3->bsn1_mid << 1) | (egprs3->bsn1_lo);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303035 OSMO_ASSERT(bsn2 == bsn1);
3036
3037 /* Table 10.4.8a.3.1 of 44.060 */
3038 OSMO_ASSERT(egprs3->cps == 3);
3039
3040 /* Handle (MCS3, MCS3) -> MCS6 case */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003041 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303042
Max7d32f552017-12-15 11:25:14 +01003043 NACK(dl_tbf, 0);
3044
Pau Espin Pedrold29a1432022-12-15 18:57:35 +01003045 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303046 egprs2 = (struct gprs_rlc_dl_header_egprs_2 *) msg->data;
3047
3048 /* Table 10.4.8a.3.1 of 44.060 */
3049 OSMO_ASSERT(egprs2->cps == 0);
Maxb4d368b2017-12-01 17:54:39 +01003050 bsn3 = (egprs2->bsn1_hi << 9) | (egprs2->bsn1_mid << 1) | (egprs2->bsn1_lo);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303051 OSMO_ASSERT(bsn3 == bsn2);
3052
3053 tbf_cleanup(dl_tbf);
3054}
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01003055
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003056static void establish_and_use_egprs_dl_tbf_for_spb(struct gprs_rlcmac_bts *bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01003057 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303058{
3059 uint32_t fn = 0;
3060 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303061 struct msgb *msg;
3062 struct gprs_rlc_dl_header_egprs_3 *egprs3;
3063
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003064 fprintf(stderr, "Testing retx for MCS %u to reseg_mcs %u\n", mcs, demanded_mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303065
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003066 dl_tbf = tbf_init(bts, mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303067
3068 /*
3069 * Table 10.4.8a.3.1 of 44.060.
3070 * (MCS7, MCS9) to (MCS2, MCS3) is not handled since it is same as
3071 * (MCS5, MCS6) to (MCS2, MCS3) transition
3072 */
3073 /* TODO: Need to support of MCS8 -> MCS6 ->MCS3 transistion
3074 * Refer commit be881c028fc4da00c4046ecd9296727975c206a3
3075 * dated 2016-02-07 23:45:40 (UTC)
3076 */
3077 if (!(((mcs == 5) && (demanded_mcs == 2)) ||
3078 ((mcs == 6) && (demanded_mcs == 3)) ||
3079 ((mcs == 4) && (demanded_mcs == 1))))
3080 return;
3081
3082 fn = fn_add_blocks(fn, 1);
3083 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01003084 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303085
Max7d32f552017-12-15 11:25:14 +01003086 NACK(dl_tbf, 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303087
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003088 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303089
3090 fn = fn_add_blocks(fn, 1);
3091
3092 /* Send first segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003093 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, false);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303094 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
3095 == EGPRS_RESEG_FIRST_SEG_SENT);
3096
3097 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
3098 OSMO_ASSERT(egprs3->spb == 2);
3099
3100 /* Table 10.4.8a.3.1 of 44.060 */
3101 switch (demanded_mcs) {
3102 case 3:
3103 OSMO_ASSERT(egprs3->cps == 3);
3104 break;
3105 case 2:
3106 OSMO_ASSERT(egprs3->cps == 9);
3107 break;
3108 case 1:
3109 OSMO_ASSERT(egprs3->cps == 11);
3110 break;
3111 default:
3112 OSMO_ASSERT(false);
3113 break;
3114 }
3115
3116 /* Send second segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003117 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303118 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
3119 == EGPRS_RESEG_SECOND_SEG_SENT);
3120
3121 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
3122 /* Table 10.4.8a.3.1 of 44.060 */
3123 OSMO_ASSERT(egprs3->spb == 3);
3124
3125 /* Table 10.4.8a.3.1 of 44.060 */
3126 switch (demanded_mcs) {
3127 case 3:
3128 OSMO_ASSERT(egprs3->cps == 3);
3129 break;
3130 case 2:
3131 OSMO_ASSERT(egprs3->cps == 9);
3132 break;
3133 case 1:
3134 OSMO_ASSERT(egprs3->cps == 11);
3135 break;
3136 default:
3137 OSMO_ASSERT(false);
3138 break;
3139 }
3140 tbf_cleanup(dl_tbf);
3141}
3142
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003143static void establish_and_use_egprs_dl_tbf_for_retx(struct gprs_rlcmac_bts *bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01003144 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303145{
3146 uint32_t fn = 0;
3147 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303148 struct msgb *msg;
3149
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003150 fprintf(stderr, "Testing retx for MCS %u - %u\n", mcs, demanded_mcs);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303151
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003152 dl_tbf = tbf_init(bts, mcs);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303153
3154 /* For MCS reduction cases like MCS9->MCS6, MCS7->MCS5
3155 * The MCS transition are referred from table Table 8.1.1.2
3156 * of TS 44.060
3157 */
3158 /* TODO: Need to support of MCS8 -> MCS6 transistion
3159 * Refer commit be881c028fc4da00c4046ecd9296727975c206a3
3160 * dated 2016-02-07 23:45:40 (UTC)
3161 */
3162 if (((mcs == 9) && (demanded_mcs < 9)) ||
3163 ((mcs == 7) && (demanded_mcs < 7))) {
3164 fn = fn_add_blocks(fn, 1);
3165 /* Send 2 RLC data block */
Max7d32f552017-12-15 11:25:14 +01003166 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3167 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303168
Max7d32f552017-12-15 11:25:14 +01003169 NACK(dl_tbf, 0);
3170 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303171
3172 /* Set the demanded MCS to demanded_mcs */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003173 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303174
3175 fn = fn_add_blocks(fn, 1);
3176 /* Retransmit the first RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003177 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
3178 CHECK_NACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303179
3180 fn = fn_add_blocks(fn, 1);
3181 /* Retransmit the second RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003182 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
3183 CHECK_UNACKED(dl_tbf, demanded_mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303184 } else if (((mcs == 5) && (demanded_mcs > 6)) ||
3185 ((mcs == 6) && (demanded_mcs > 8))) {
3186 fn = fn_add_blocks(fn, 1);
3187 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01003188 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303189
3190 fn = fn_add_blocks(fn, 1);
3191 /* Send second RLC data block BSN 1 */
Max7d32f552017-12-15 11:25:14 +01003192 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3193 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303194
Max7d32f552017-12-15 11:25:14 +01003195 NACK(dl_tbf, 0);
3196 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303197
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003198 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303199
3200 fn = fn_add_blocks(fn, 1);
3201 /* Send first, second RLC data blocks with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003202 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
3203 CHECK_UNACKED(dl_tbf, demanded_mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303204 } else if (mcs > 6) {
3205 /* No Mcs change cases are handled here for mcs > MCS6*/
3206 fn = fn_add_blocks(fn, 1);
3207 /* Send first,second RLC data blocks */
Max7d32f552017-12-15 11:25:14 +01003208 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3209 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303210
Max7d32f552017-12-15 11:25:14 +01003211 NACK(dl_tbf, 0);
3212 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303213
3214 fn = fn_add_blocks(fn, 1);
3215 /* Send first,second RLC data blocks with demanded_mcs*/
Max7d32f552017-12-15 11:25:14 +01003216 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3217 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303218 } else {
3219
3220 /* No MCS change cases are handled here for mcs <= MCS6*/
3221 fn = fn_add_blocks(fn, 1);
3222 /* Send first RLC data block */
Max7d32f552017-12-15 11:25:14 +01003223 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303224
Max7d32f552017-12-15 11:25:14 +01003225 NACK(dl_tbf, 0);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303226
3227 fn = fn_add_blocks(fn, 1);
3228 /* Send first RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003229 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303230 }
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01003231 /* Clean up pending items in UL controller: */
Pau Espin Pedrol16e16782021-03-29 19:10:19 +02003232 send_empty_block(dl_tbf, dl_tbf->control_ts, fn+50);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303233 tbf_cleanup(dl_tbf);
3234}
3235
3236static void test_tbf_egprs_retx_dl(void)
3237{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003238 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003239 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303240 uint8_t ts_no = 4;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303241
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003242 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303243
Pau Espin Pedrolad79b852021-01-14 13:20:55 +01003244 the_pcu->vty.cs_downgrade_threshold = 0;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003245 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01003246 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303247 /* ARQ II */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01003248 the_pcu->vty.dl_arq_type = EGPRS_ARQ2;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303249
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303250
3251 /* First parameter is current MCS, second one is demanded_mcs */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003252 establish_and_use_egprs_dl_tbf_for_retx(bts, 6, 6);
3253 establish_and_use_egprs_dl_tbf_for_retx(bts, 1, 9);
3254 establish_and_use_egprs_dl_tbf_for_retx(bts, 2, 8);
3255 establish_and_use_egprs_dl_tbf_for_retx(bts, 5, 7);
3256 establish_and_use_egprs_dl_tbf_for_retx(bts, 6, 9);
3257 establish_and_use_egprs_dl_tbf_for_retx(bts, 7, 5);
3258 establish_and_use_egprs_dl_tbf_for_retx(bts, 9, 6);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303259
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003260 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003261 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303262}
3263
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303264static void test_tbf_egprs_spb_dl(void)
3265{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003266 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003267 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303268 uint8_t ts_no = 4;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303269
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003270 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303271
Pau Espin Pedrolad79b852021-01-14 13:20:55 +01003272 the_pcu->vty.cs_downgrade_threshold = 0;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003273 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01003274 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303275
3276 /* ARQ I resegmentation support */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01003277 the_pcu->vty.dl_arq_type = EGPRS_ARQ1;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303278
3279 /*
3280 * First parameter is current MCS, second one is demanded_mcs
3281 * currently only MCS5->MCS2, MCS6->3, MCS4->MCS1 is tested in UT
3282 * rest scenarios has been integration tested
3283 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003284 establish_and_use_egprs_dl_tbf_for_spb(bts, 6, 3);
3285 establish_and_use_egprs_dl_tbf_for_spb(bts, 5, 2);
3286 establish_and_use_egprs_dl_tbf_for_spb(bts, 4, 1);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303287 /* check MCS6->(MCS3+MCS3)->MCS6 case */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003288 egprs_spb_to_normal_validation(bts, 6, 3);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303289
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003290 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003291 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303292}
3293
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003294static void test_tbf_egprs_dl()
3295{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003296 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003297 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003298 uint8_t ts_no = 4;
3299 int i;
3300
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003301 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003302
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003303 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01003304 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303305 /* ARQ II */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01003306 the_pcu->vty.dl_arq_type = EGPRS_ARQ2;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003307
3308 for (i = 1; i <= 9; i++)
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003309 establish_and_use_egprs_dl_tbf(bts, i);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003310
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003311 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003312 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003313}
3314
3315
3316
aravind sirsikare9a138e2017-01-24 12:36:08 +05303317static void test_packet_access_rej_prr_no_other_tbfs()
3318{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003319 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003320 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003321 struct gprs_rlcmac_pdch *pdch;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303322 uint32_t fn = 2654218;
3323 int ts_no = 7;
3324 uint8_t trx_no = 0;
3325 uint32_t tlli = 0xffeeddcc;
Pau Espin Pedrol54742f22021-04-26 16:48:34 +02003326 struct gprs_rlcmac_ul_tbf *ul_tbf;
3327 struct GprsMs *ms;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303328
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003329 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303330
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003331 setup_bts(bts, ts_no, 4);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003332 pdch = &bts->trx[trx_no].pdch[ts_no];
Pau Espin Pedrol9d67e722021-07-28 19:25:38 +02003333 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2000, 0, OSMO_TDEF_MS) == 0);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303334
3335 int rc = 0;
3336
Pau Espin Pedrol54742f22021-04-26 16:48:34 +02003337 ms = bts_alloc_ms(bts, 0, 0);
3338 ms_set_tlli(ms, tlli);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003339 ul_tbf = ms_new_ul_tbf_rejected_pacch(ms, pdch);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303340
3341 OSMO_ASSERT(ul_tbf != 0);
3342
3343 /* trigger packet access reject */
3344 uint8_t bn = fn2bn(fn);
3345
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003346 rc = gprs_rlcmac_rcv_rts_block(bts, pdch->trx->trx_no, pdch->ts_no, fn, bn);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303347
3348 OSMO_ASSERT(rc == 0);
Pau Espin Pedrol9d67e722021-07-28 19:25:38 +02003349 osmo_select_main(0);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303350
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003351 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003352 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303353}
3354
3355static void test_packet_access_rej_prr()
3356{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003357 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003358 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003359 struct gprs_rlcmac_pdch *pdch;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303360 uint32_t fn = 2654218;
3361 uint16_t qta = 31;
3362 int ts_no = 7;
3363 uint8_t trx_no = 0;
3364 RlcMacUplink_t ulreq = {0};
3365 Packet_Resource_Request_t *presreq = NULL;
3366 uint8_t ms_class = 11;
3367 uint8_t egprs_ms_class = 11;
3368 uint32_t rach_fn = fn - 51;
3369 uint32_t sba_fn = fn + 52;
3370 uint32_t tlli = 0xffeeddcc;
3371 MS_Radio_Access_capability_t *pmsradiocap = NULL;
3372 Multislot_capability_t *pmultislotcap = NULL;
3373
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003374 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303375
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003376 setup_bts(bts, ts_no, 4);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003377 pdch = &bts->trx[trx_no].pdch[ts_no];
aravind sirsikare9a138e2017-01-24 12:36:08 +05303378
3379 int rc = 0;
3380
3381 /*
3382 * Trigger rach till resources(USF) exhaust
3383 */
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003384 int i;
3385 for (i = 0; i < 8; i++) {
3386 rc = bts_handle_rach(bts, 0x70 + i, rach_fn, qta);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303387 }
3388
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003389 sba_fn = 52;
3390 for (i = 0; i < 8; i++) {
3391 /* fake a resource request */
3392 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
3393 presreq = &ulreq.u.Packet_Resource_Request;
3394 presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
3395 presreq->ID.UnionType = 1; /* != 0 */
3396 presreq->ID.u.TLLI = tlli + i;
3397 presreq->Exist_MS_Radio_Access_capability2 = 1;
3398 pmsradiocap = &presreq->MS_Radio_Access_capability2;
3399 pmsradiocap->Count_MS_RA_capability_value = 1;
3400 pmsradiocap->MS_RA_capability_value[0].u.Content.
3401 Exist_Multislot_capability = 1;
3402 pmultislotcap = &pmsradiocap->MS_RA_capability_value[0].
3403 u.Content.Multislot_capability;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303404
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003405 pmultislotcap->Exist_GPRS_multislot_class = 1;
3406 pmultislotcap->GPRS_multislot_class = ms_class;
3407 if (egprs_ms_class) {
3408 pmultislotcap->Exist_EGPRS_multislot_class = 1;
3409 pmultislotcap->EGPRS_multislot_class = egprs_ms_class;
3410 }
aravind sirsikare9a138e2017-01-24 12:36:08 +05303411
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003412 send_ul_mac_block(bts, pdch, &ulreq, sba_fn);
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003413 sba_fn = fn_next_block(sba_fn);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303414
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003415 /* trigger packet access reject */
3416 uint8_t bn = fn2bn(fn);
3417
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003418 rc = gprs_rlcmac_rcv_rts_block(bts, pdch->trx->trx_no, pdch->ts_no, fn, bn);
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003419 OSMO_ASSERT(rc == 0);
3420 }
aravind sirsikare9a138e2017-01-24 12:36:08 +05303421
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003422 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003423 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303424}
3425
aravind sirsikared3413e2016-11-11 17:15:10 +05303426void test_packet_access_rej_epdan()
3427{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003428 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003429 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
aravind sirsikared3413e2016-11-11 17:15:10 +05303430 uint32_t tlli = 0xffeeddcc;
Pau Espin Pedrol2ab840a2021-04-26 17:49:05 +02003431 static uint8_t exp[] = { 0x40, 0x84, 0x7f, 0xf7, 0x6e, 0xe6, 0x7e, 0xab,
Maxd3a0d912019-03-05 16:15:01 +01003432 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
3433 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b
3434 };
aravind sirsikared3413e2016-11-11 17:15:10 +05303435
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003436 fprintf(stderr, "=== start %s ===\n", __func__);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003437 setup_bts(bts, 4);
3438 static gprs_rlcmac_dl_tbf *dl_tbf = tbf_init(bts, 1);
aravind sirsikared3413e2016-11-11 17:15:10 +05303439
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +02003440 ms_confirm_tlli(dl_tbf->ms(), tlli);
aravind sirsikared3413e2016-11-11 17:15:10 +05303441
Pau Espin Pedrol6ad11a62021-07-27 12:27:08 +02003442 osmo_fsm_inst_dispatch(dl_tbf->ul_ass_fsm.fi, TBF_UL_ASS_EV_SCHED_ASS_REJ, NULL);
3443 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 +05303444
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003445 fprintf(stderr, "packet reject: %s\n",
aravind sirsikared3413e2016-11-11 17:15:10 +05303446 osmo_hexdump(msg->data, 23));
3447
Maxd3a0d912019-03-05 16:15:01 +01003448 if (!msgb_eq_data_print(msg, exp, GSM_MACBLOCK_LEN))
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003449 fprintf(stderr, "%s test failed!\n", __func__);
Maxd3a0d912019-03-05 16:15:01 +01003450
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003451 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003452 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikared3413e2016-11-11 17:15:10 +05303453}
3454
3455
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003456int main(int argc, char **argv)
3457{
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003458 struct vty_app_info pcu_vty_info = {0};
3459
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003460 tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile TbfTest context");
3461 if (!tall_pcu_ctx)
3462 abort();
3463
Neels Hofmeyr78ce5912017-02-08 17:07:31 +01003464 msgb_talloc_ctx_init(tall_pcu_ctx, 0);
Neels Hofmeyr42f2d612018-04-01 16:54:40 +02003465 osmo_init_logging2(tall_pcu_ctx, &gprs_log_info);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003466 log_set_use_color(osmo_stderr_target, 0);
Pau Espin Pedrol00f52cc2021-02-19 14:01:52 +01003467 log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
Pau Espin Pedrolb18d2a52021-02-19 14:00:48 +01003468 log_set_print_category(osmo_stderr_target, 0);
3469 log_set_print_category_hex(osmo_stderr_target, 0);
Maxfdd79e92018-01-24 11:04:59 +01003470 log_parse_category_mask(osmo_stderr_target, "DRLCMAC,1:DRLCMACDATA,3:DRLCMACDL,3:DRLCMACUL,3:"
Harald Welte398f60e2020-12-10 13:39:21 +01003471 "DRLCMACSCHED,1:DRLCMACMEAS,3:DNS,3:DLBSSGP,3:DPCU,5:"
Max86e35e42019-03-07 12:20:42 +01003472 "DL1IF,6:DTBF,1:DTBFUL,1:DTBFDL,1:DLGLOBAL,2:");
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02003473 osmo_fsm_log_addr(false);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003474 vty_init(&pcu_vty_info);
Pau Espin Pedrolcd2ac562019-08-05 14:30:44 +02003475 pcu_vty_init();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003476
Vadim Yanitskiy87b6e7d2019-11-08 04:44:04 +07003477 /* Initialize shared UL measurements */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003478 pcu_l1_meas_set_link_qual(&meas, 12);
3479 pcu_l1_meas_set_rssi(&meas, 31);
Vadim Yanitskiy87b6e7d2019-11-08 04:44:04 +07003480
Jacob Erlbeckac89a552015-06-29 14:18:46 +02003481 test_tbf_base();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003482 test_tbf_tlli_update();
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +01003483 test_tbf_final_ack(TEST_MODE_STANDARD);
3484 test_tbf_final_ack(TEST_MODE_REVERSE_FREE);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +01003485 test_tbf_delayed_release();
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +02003486 test_tbf_imsi();
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003487 test_tbf_exhaustion();
Jacob Erlbeck41168642015-06-12 13:41:00 +02003488 test_tbf_dl_llc_loss();
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02003489 test_tbf_single_phase();
Pau Espin Pedrol22b26d82022-10-26 15:44:14 +02003490 test_tbf_single_phase2();
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02003491 test_tbf_two_phase();
Jacob Erlbeckb1395982015-08-21 18:15:38 +02003492 test_tbf_ra_update_rach();
3493 test_tbf_dl_flow_and_rach_two_phase();
3494 test_tbf_dl_flow_and_rach_single_phase();
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02003495 test_tbf_dl_reuse();
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01003496 test_tbf_gprs_egprs();
Jacob Erlbeck36df7742016-01-19 15:53:30 +01003497 test_tbf_ws();
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003498 test_tbf_egprs_two_phase();
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05303499 test_tbf_egprs_two_phase_spb();
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003500 test_tbf_egprs_dl();
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303501 test_tbf_egprs_retx_dl();
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303502 test_tbf_egprs_spb_dl();
Aravind Sirsikar02352b42016-08-25 16:37:30 +05303503 test_tbf_puan_urbb_len();
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05303504 test_tbf_update_ws();
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05303505 test_tbf_li_decoding();
aravind sirsikarf2761382016-10-25 12:45:24 +05303506 test_tbf_epdan_out_of_rx_window();
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05303507 test_immediate_assign_rej();
sivasankari1d8744c2017-01-24 15:53:35 +05303508 test_tbf_egprs_two_phase_puan();
aravind sirsikared3413e2016-11-11 17:15:10 +05303509 test_packet_access_rej_epdan();
aravind sirsikare9a138e2017-01-24 12:36:08 +05303510 test_packet_access_rej_prr();
3511 test_packet_access_rej_prr_no_other_tbfs();
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01003512 test_ms_merge_dl_tbf_different_trx();
Jacob Erlbeck67c38502015-05-11 10:32:40 +02003513
3514 if (getenv("TALLOC_REPORT_FULL"))
3515 talloc_report_full(tall_pcu_ctx, stderr);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003516 return EXIT_SUCCESS;
3517}
3518
3519/*
3520 * stubs that should not be reached
3521 */
3522extern "C" {
3523void l1if_pdch_req() { abort(); }
3524void l1if_connect_pdch() { abort(); }
3525void l1if_close_pdch() { abort(); }
3526void l1if_open_pdch() { abort(); }
3527}