blob: 42b6d29687b3624c93dccc7f282fefe63562ea80 [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>
Pau Espin Pedrolb5a8a672023-03-14 11:16:22 +010046#include <osmocom/gsm/protocol/gsm_44_060.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 Pedrolbfc97562023-04-17 14:49:29 +0200126 ms = bts_alloc_ms(bts);
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 Pedrolcde18c52023-04-17 18:16:48 +0200142 OSMO_ASSERT(bts_get_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 Pedrolcde18c52023-04-17 18:16:48 +0200151 ms_new = bts_get_ms_by_tlli(bts, 0x2342, GSM_RESERVED_TMSI);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200152 OSMO_ASSERT(ms == ms_new);
153
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +0200154 ms_new = bts_get_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 Pedrolcde18c52023-04-17 18:16:48 +0200161 ms_new = bts_get_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 Pedrolcde18c52023-04-17 18:16:48 +0200164 ms_new = bts_get_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 Pedrolbfc97562023-04-17 14:49:29 +0200209 ms = bts_alloc_ms(bts);
210 ms_set_ms_class(ms, ms_class);
211 ms_set_egprs_ms_class(ms, egprs_ms_class);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100212
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100213 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_DL_TBF, &trx_no, -1);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100214 OSMO_ASSERT(tfi >= 0);
Pau Espin Pedrol87573842022-10-26 20:23:45 +0200215 dl_tbf = dl_tbf_alloc(bts, ms, trx_no, true);
Pau Espin Pedrol983bb7e2020-10-26 14:52:06 +0100216 OSMO_ASSERT(dl_tbf);
Max9bbe1602016-07-18 12:50:18 +0200217 dl_tbf->set_ta(0);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100218 check_tbf(dl_tbf);
219
220 /* "Establish" the DL TBF */
Pau Espin Pedrol49a2f402021-07-27 17:33:07 +0200221 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 +0100222 osmo_fsm_inst_dispatch(dl_tbf->state_fi, TBF_EV_ASSIGN_ADD_CCCH, NULL);
223 osmo_fsm_inst_dispatch(dl_tbf->state_fi, TBF_EV_ASSIGN_ACK_PACCH, NULL);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100224 check_tbf(dl_tbf);
225
226 *trx_no_ = trx_no;
227
228 return dl_tbf;
229}
230
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200231static unsigned fn_add_blocks(unsigned fn, unsigned blocks)
232{
233 unsigned bn = fn2bn(fn) + blocks;
234 fn = fn - (fn % 52);
235 fn += bn * 4 + bn / 3;
Max9dabfa22017-05-16 16:10:45 +0200236 return fn % GSM_MAX_FN;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200237}
238
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200239static void request_dl_rlc_block(struct gprs_rlcmac_bts *bts,
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100240 struct gprs_rlcmac_pdch *pdch,
Jacob Erlbeckee310902015-08-24 11:55:17 +0200241 uint32_t *fn, uint8_t *block_nr = NULL)
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100242{
Jacob Erlbeckee310902015-08-24 11:55:17 +0200243 uint8_t bn = fn2bn(*fn);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100244 gprs_rlcmac_rcv_rts_block(bts, pdch->trx->trx_no, pdch->ts_no, *fn, bn);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200245 *fn = fn_add_blocks(*fn, 1);
Jacob Erlbeckee310902015-08-24 11:55:17 +0200246 bn += 1;
247 if (block_nr)
248 *block_nr = bn;
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100249}
250
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200251static void request_dl_rlc_block(struct gprs_rlcmac_tbf *tbf,
Jacob Erlbeckee310902015-08-24 11:55:17 +0200252 uint32_t *fn, uint8_t *block_nr = NULL)
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200253{
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100254 request_dl_rlc_block(tbf->bts, tbf->control_ts, fn, block_nr);
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200255}
256
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100257enum test_tbf_final_ack_mode {
258 TEST_MODE_STANDARD,
259 TEST_MODE_REVERSE_FREE
260};
261
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +0200262/* Receive an ACK */
263static void _rcv_ack(bool fin, gprs_rlcmac_dl_tbf *tbf, uint8_t *rbb)
264{
265 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window());
266 uint8_t bits_data[RLC_GPRS_WS/8];
267 bitvec bits;
268 Ack_Nack_Description_t ack_nack;
269 int bsn_begin, bsn_end;
270 uint8_t ssn = w->v_s();
271
272 bits.data = bits_data;
273 bits.data_len = sizeof(bits_data);
274 bits.cur_bit = 0;
275 ack_nack.FINAL_ACK_INDICATION = fin;
276 ack_nack.STARTING_SEQUENCE_NUMBER = ssn;
277 memcpy(ack_nack.RECEIVED_BLOCK_BITMAP, rbb, RLC_GPRS_WS/8);
278
279 Decoding::decode_gprs_acknack_bits(
280 &ack_nack, &bits,
281 &bsn_begin, &bsn_end, w);
282
283 tbf->rcvd_dl_ack(fin, bsn_begin, &bits);
284 if (!fin)
285 OSMO_ASSERT(w->window_empty());
286}
287
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100288static void test_tbf_final_ack(enum test_tbf_final_ack_mode test_mode)
Daniel Willmann510d7d32014-08-15 18:19:41 +0200289{
Pau Espin Pedrol945be912021-07-26 14:47:46 +0200290 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100291 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100292 uint8_t ts_no = 4;
293 unsigned i;
Daniel Willmann510d7d32014-08-15 18:19:41 +0200294 uint8_t ms_class = 45;
295 uint32_t fn;
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100296 uint8_t block_nr;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100297 uint8_t trx_no;
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200298 GprsMs *ms;
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200299 uint32_t tlli = 0xffeeddcc;
Daniel Willmann510d7d32014-08-15 18:19:41 +0200300
301 uint8_t rbb[64/8];
302
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200303 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100304
Daniel Willmann510d7d32014-08-15 18:19:41 +0200305 gprs_rlcmac_dl_tbf *dl_tbf;
306 gprs_rlcmac_tbf *new_tbf;
307
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100308 setup_bts(bts, ts_no);
309 dl_tbf = create_dl_tbf(bts, ms_class, 0, &trx_no);
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +0200310 ms_confirm_tlli(dl_tbf->ms(), tlli);
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200311 ms = dl_tbf->ms();
Daniel Willmann510d7d32014-08-15 18:19:41 +0200312
313 for (i = 0; i < sizeof(llc_data); i++)
314 llc_data[i] = i%256;
315
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100316 /* Schedule two LLC frames */
Pau Espin Pedrol14beef62022-10-26 19:44:07 +0200317 ms_append_llc_dl_data(dl_tbf->ms(), 1000, llc_data, sizeof(llc_data));
318 ms_append_llc_dl_data(dl_tbf->ms(), 1000, llc_data, sizeof(llc_data));
Daniel Willmann510d7d32014-08-15 18:19:41 +0200319
320
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100321 /* Send only a few RLC/MAC blocks */
Daniel Willmann510d7d32014-08-15 18:19:41 +0200322 fn = 0;
Jacob Erlbeckee310902015-08-24 11:55:17 +0200323 do {
Daniel Willmann510d7d32014-08-15 18:19:41 +0200324 /* Request to send one block */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200325 request_dl_rlc_block(dl_tbf, &fn, &block_nr);
Jacob Erlbeckee310902015-08-24 11:55:17 +0200326 } while (block_nr < 3);
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200327
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100328 OSMO_ASSERT(dl_tbf->have_data());
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200329 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Daniel Willmann510d7d32014-08-15 18:19:41 +0200330
331 /* Queue a final ACK */
332 memset(rbb, 0, sizeof(rbb));
333 /* Receive a final ACK */
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +0200334 _rcv_ack(true, dl_tbf, rbb);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200335
336 /* Clean up and ensure tbfs are in the correct state */
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200337 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_WAIT_RELEASE));
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100338 new_tbf = ms_dl_tbf(ms);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100339 check_tbf(new_tbf);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200340 OSMO_ASSERT(new_tbf != dl_tbf);
341 OSMO_ASSERT(new_tbf->tfi() == 1);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100342 check_tbf(dl_tbf);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100343 if (test_mode == TEST_MODE_REVERSE_FREE) {
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100344 ms_ref(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100345 tbf_free(new_tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100346 OSMO_ASSERT(ms_dl_tbf(ms) == NULL);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100347 check_tbf(dl_tbf);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100348 tbf_free(dl_tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100349 ms_unref(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100350 } else {
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100351 ms_ref(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100352 tbf_free(dl_tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100353 OSMO_ASSERT(ms_dl_tbf(ms) == new_tbf);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100354 check_tbf(new_tbf);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100355 tbf_free(new_tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100356 OSMO_ASSERT(ms_dl_tbf(ms) == NULL);
357 ms_unref(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100358 }
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100359
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100360 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200361 fprintf(stderr, "=== end %s ===\n", __func__);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200362}
363
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100364static void test_tbf_delayed_release()
365{
Pau Espin Pedrol945be912021-07-26 14:47:46 +0200366 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100367 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100368 uint8_t ts_no = 4;
369 unsigned i;
370 uint8_t ms_class = 45;
371 uint32_t fn = 0;
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100372 uint8_t trx_no;
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200373 uint32_t tlli = 0xffeeddcc;
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200374 unsigned long dl_tbf_idle_msec;
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100375
376 uint8_t rbb[64/8];
377
378 gprs_rlcmac_dl_tbf *dl_tbf;
379
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200380 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100381
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100382 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +0100383 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100384
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100385 dl_tbf = create_dl_tbf(bts, ms_class, 0, &trx_no);
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +0200386 ms_confirm_tlli(dl_tbf->ms(), tlli);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100387
388 for (i = 0; i < sizeof(llc_data); i++)
389 llc_data[i] = i%256;
390
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200391 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100392
393 /* Schedule two LLC frames */
Pau Espin Pedrol14beef62022-10-26 19:44:07 +0200394 ms_append_llc_dl_data(dl_tbf->ms(), 1000, llc_data, sizeof(llc_data));
395 ms_append_llc_dl_data(dl_tbf->ms(), 1000, llc_data, sizeof(llc_data));
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100396
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200397 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100398
399 /* Drain the queue */
400 while (dl_tbf->have_data())
401 /* Request to send one RLC/MAC block */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200402 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100403
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200404 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100405
406 /* ACK all blocks */
407 memset(rbb, 0xff, sizeof(rbb));
Max7d32f552017-12-15 11:25:14 +0100408
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +0200409 _rcv_ack(false, dl_tbf, rbb); /* Receive an ACK */
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100410
411 /* Force sending of a single block containing an LLC dummy command */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200412 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100413
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +0200414 _rcv_ack(false, dl_tbf, rbb); /* Receive an ACK */
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100415
416 /* Timeout (make sure fn % 52 remains valid) */
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +0100417 dl_tbf_idle_msec = osmo_tdef_get(the_pcu->T_defs, -2031, OSMO_TDEF_MS, -1);
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200418 fn += 52 * ((msecs_to_frames(dl_tbf_idle_msec + 100) + 51)/ 52);
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200419 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100420
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200421 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FINISHED));
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100422
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +0200423 _rcv_ack(true, dl_tbf, rbb); /* Receive a final ACK */
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100424
425 /* Clean up and ensure tbfs are in the correct state */
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200426 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_WAIT_RELEASE));
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100427 check_tbf(dl_tbf);
428 tbf_free(dl_tbf);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100429 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200430 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100431}
432
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200433static void test_tbf_imsi()
434{
Pau Espin Pedrol945be912021-07-26 14:47:46 +0200435 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100436 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200437 uint8_t ts_no = 4;
438 uint8_t ms_class = 45;
439 uint8_t trx_no;
440 GprsMs *ms1, *ms2;
441
442 gprs_rlcmac_dl_tbf *dl_tbf[2];
443
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200444 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200445
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100446 setup_bts(bts, ts_no);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200447
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100448 dl_tbf[0] = create_dl_tbf(bts, ms_class, 0, &trx_no);
449 dl_tbf[1] = create_dl_tbf(bts, ms_class, 0, &trx_no);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200450
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +0200451 ms_confirm_tlli(dl_tbf[0]->ms(), 0xf1000001);
452 ms_confirm_tlli(dl_tbf[1]->ms(), 0xf1000002);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200453
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100454 ms_set_imsi(dl_tbf[0]->ms(), "001001000000001");
Pau Espin Pedrol7f360e72022-10-21 14:30:36 +0200455 ms1 = bts_ms_store(bts)->get_ms(GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, "001001000000001");
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200456 OSMO_ASSERT(ms1 != NULL);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100457 ms2 = bts_ms_store(bts)->get_ms(0xf1000001);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200458 OSMO_ASSERT(ms2 != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100459 OSMO_ASSERT(strcmp(ms_imsi(ms2), "001001000000001") == 0);
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200460 OSMO_ASSERT(ms1 == ms2);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200461
462 /* change the IMSI on TBF 0 */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100463 ms_set_imsi(dl_tbf[0]->ms(), "001001000000002");
Pau Espin Pedrol7f360e72022-10-21 14:30:36 +0200464 ms1 = bts_ms_store(bts)->get_ms(GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, "001001000000001");
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200465 OSMO_ASSERT(ms1 == NULL);
Pau Espin Pedrol7f360e72022-10-21 14:30:36 +0200466 ms1 = bts_ms_store(bts)->get_ms(GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, "001001000000002");
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200467 OSMO_ASSERT(ms1 != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100468 OSMO_ASSERT(strcmp(ms_imsi(ms2), "001001000000002") == 0);
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200469 OSMO_ASSERT(ms1 == ms2);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200470
Pau Espin Pedrol528820d2020-10-26 12:40:11 +0100471 /* use the same IMSI on TBF 1 */
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200472 {
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100473 ms_ref(ms2);
474 ms_set_imsi(dl_tbf[1]->ms(), "001001000000002");
Pau Espin Pedrol7f360e72022-10-21 14:30:36 +0200475 ms1 = bts_ms_store(bts)->get_ms(GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, "001001000000002");
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200476 OSMO_ASSERT(ms1 != NULL);
477 OSMO_ASSERT(ms1 != ms2);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100478 OSMO_ASSERT(strcmp(ms_imsi(ms1), "001001000000002") == 0);
479 OSMO_ASSERT(strcmp(ms_imsi(ms2), "") == 0);
480 ms_unref(ms2);
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200481 }
482
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100483 ms2 = bts_ms_store(bts)->get_ms(0xf1000001);
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200484 OSMO_ASSERT(ms2 == NULL);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200485
486 tbf_free(dl_tbf[1]);
Pau Espin Pedrol7f360e72022-10-21 14:30:36 +0200487 ms1 = bts_ms_store(bts)->get_ms(GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, "001001000000002");
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200488 OSMO_ASSERT(ms1 == NULL);
489
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100490 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200491 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200492}
493
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200494static void test_tbf_exhaustion()
495{
Pau Espin Pedrol945be912021-07-26 14:47:46 +0200496 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100497 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200498 unsigned i;
499 uint8_t ts_no = 4;
500 uint8_t ms_class = 45;
501 int rc = 0;
502
503 uint8_t buf[256] = {0};
504
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200505 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200506
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100507 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
508 if (!bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +0200509 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
510 abort();
511 }
512
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100513 setup_bts(bts, ts_no);
Alexander Couzens290d9032020-09-16 21:52:02 +0200514 gprs_bssgp_init(bts, 1234, 1234, 1, 1, false, 0, 0, 0);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200515
516 for (i = 0; i < 1024; i++) {
517 uint32_t tlli = 0xc0000000 + i;
518 char imsi[16] = {0};
519 unsigned delay_csec = 1000;
520
Jacob Erlbeck9a2845d2015-05-21 12:06:58 +0200521 snprintf(imsi, sizeof(imsi), "001001%09d", i);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200522
Pau Espin Pedrol8a35e642021-01-18 17:14:14 +0100523 rc = dl_tbf_handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200524 delay_csec, buf, sizeof(buf));
525
526 if (rc < 0)
527 break;
528 }
529
530 OSMO_ASSERT(rc == -EBUSY);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200531 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200532
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100533 TALLOC_FREE(the_pcu);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200534}
535
Jacob Erlbeck41168642015-06-12 13:41:00 +0200536static void test_tbf_dl_llc_loss()
537{
Pau Espin Pedrol945be912021-07-26 14:47:46 +0200538 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100539 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrold29a1432022-12-15 18:57:35 +0100540 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeck41168642015-06-12 13:41:00 +0200541 uint8_t ts_no = 4;
542 uint8_t ms_class = 45;
543 int rc = 0;
544 uint32_t tlli = 0xc0123456;
545 const char *imsi = "001001000123456";
546 unsigned delay_csec = 1000;
547 GprsMs *ms;
548
549 uint8_t buf[19];
550
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100551 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
552 if (!bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +0200553 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
554 abort();
555 }
556
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200557 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200558
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100559 setup_bts(bts, ts_no);
Pau Espin Pedrold29a1432022-12-15 18:57:35 +0100560 pdch = &bts->trx[0].pdch[ts_no];
Pau Espin Pedrol63700ea2019-09-09 13:19:06 +0200561 /* keep the MS object 10 seconds */
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +0100562 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2030, 10, OSMO_TDEF_S) == 0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200563
Alexander Couzens290d9032020-09-16 21:52:02 +0200564 gprs_bssgp_init(bts, 2234, 2234, 1, 1, false, 0, 0, 0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200565
566 /* Handle LLC frame 1 */
567 memset(buf, 1, sizeof(buf));
Pau Espin Pedrol8a35e642021-01-18 17:14:14 +0100568 rc = dl_tbf_handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200569 delay_csec, buf, sizeof(buf));
570 OSMO_ASSERT(rc >= 0);
571
Pau Espin Pedrol7f360e72022-10-21 14:30:36 +0200572 ms = bts_ms_store(bts)->get_ms(GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, imsi);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200573 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100574 OSMO_ASSERT(ms_dl_tbf(ms) != NULL);
575 ms_dl_tbf(ms)->set_ta(0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200576
577 /* Handle LLC frame 2 */
578 memset(buf, 2, sizeof(buf));
Pau Espin Pedrol8a35e642021-01-18 17:14:14 +0100579 rc = dl_tbf_handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200580 delay_csec, buf, sizeof(buf));
581 OSMO_ASSERT(rc >= 0);
582
583 /* TBF establishment fails (timeout) */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100584 tbf_free(ms_dl_tbf(ms));
Jacob Erlbeck41168642015-06-12 13:41:00 +0200585
586 /* Handle LLC frame 3 */
587 memset(buf, 3, sizeof(buf));
Pau Espin Pedrol8a35e642021-01-18 17:14:14 +0100588 rc = dl_tbf_handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200589 delay_csec, buf, sizeof(buf));
590 OSMO_ASSERT(rc >= 0);
591
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100592 OSMO_ASSERT(ms_dl_tbf(ms) != NULL);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200593
Pau Espin Pedrolef1b9842022-12-15 18:47:39 +0100594 /* Here BTS would answer with data_cnf and trigger
Pau Espin Pedrol32252902021-07-29 16:44:11 +0200595 * bts_rcv_imm_ass_cnf(), which would trigger TBF_EV_ASSIGN_PCUIF_CNF.
596 * That in turn would set up timer X2002. Finally, X2002 timeout
597 * moves it to FLOW state. We set X2002 timeout to 0 here to get
598 * immediate trigger through osmo_select_main() */
599 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2002, 0, OSMO_TDEF_MS) == 0);
Pau Espin Pedrolf197f152022-11-17 20:18:46 +0100600 osmo_fsm_inst_dispatch(ms_dl_tbf(ms)->state_fi, TBF_EV_ASSIGN_PCUIF_CNF, NULL);
Pau Espin Pedrol32252902021-07-29 16:44:11 +0200601 osmo_select_main(0);
Pau Espin Pedrol65bba932021-07-26 12:06:20 +0200602 OSMO_ASSERT(ms_dl_tbf(ms)->state_is(TBF_ST_FLOW));
603
Jacob Erlbeck41168642015-06-12 13:41:00 +0200604 /* Get first BSN */
605 struct msgb *msg;
606 int fn = 0;
607 uint8_t expected_data = 1;
Maxd3a0d912019-03-05 16:15:01 +0100608 static uint8_t exp[][GSM_MACBLOCK_LEN] = {
609 { 0x07, 0x00, 0x00, 0x4d, 0x01, 0x01, 0x01,
610 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
611 { 0x07, 0x00, 0x02, 0x4d, 0x02, 0x02, 0x02,
612 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 },
Pau Espin Pedrolef1b9842022-12-15 18:47:39 +0100613 /* On last DL block, PCU requests polling (DL ACK/NACK): S/P 1 and RRBP 01, hence 0x07 becomes 0xf1 */
614 { 0x1f, 0x01, 0x04, 0x4d, 0x03, 0x03, 0x03,
Maxd3a0d912019-03-05 16:15:01 +0100615 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 },
616 };
Jacob Erlbeck41168642015-06-12 13:41:00 +0200617
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100618 while (ms_dl_tbf(ms)->have_data()) {
Pau Espin Pedrold29a1432022-12-15 18:57:35 +0100619 msg = ms_dl_tbf(ms)->create_dl_acked_block(fn += 4, pdch);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200620 fprintf(stderr, "MSG = %s\n", msgb_hexdump(msg));
Maxd3a0d912019-03-05 16:15:01 +0100621 if (!msgb_eq_data_print(msg, exp[expected_data - 1], GSM_MACBLOCK_LEN))
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200622 fprintf(stderr, "%s failed at %u\n", __func__, expected_data);
Maxd3a0d912019-03-05 16:15:01 +0100623
Jacob Erlbeck41168642015-06-12 13:41:00 +0200624 expected_data += 1;
625 }
Jacob Erlbeck409efa12015-06-12 14:06:09 +0200626 OSMO_ASSERT(expected_data-1 == 3);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200627
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200628 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200629
Pau Espin Pedrol52e2c082022-05-09 17:12:53 +0200630 /* Restore MS release timeout to 0 to make sure it is freed immediately: */
631 ms_set_timeout(ms, 0);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100632 TALLOC_FREE(the_pcu);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200633}
634
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100635static gprs_rlcmac_ul_tbf *establish_ul_tbf_single_phase(struct gprs_rlcmac_bts *bts,
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100636 struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta)
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200637{
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200638 GprsMs *ms;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200639 int tfi = 0;
640 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200641
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100642 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &pdch->trx->trx_no, -1);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200643
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100644 bts_handle_rach(bts, 0x03, *fn, qta);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200645
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100646 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, pdch->trx->trx_no, pdch->ts_no);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200647 OSMO_ASSERT(ul_tbf != NULL);
648
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200649 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200650
651 uint8_t data_msg[23] = {
652 0x00, /* GPRS_RLCMAC_DATA_BLOCK << 6 */
653 uint8_t(1 | (tfi << 2)),
654 uint8_t(1), /* BSN:7, E:1 */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200655 uint8_t(tlli >> 24), uint8_t(tlli >> 16),
656 uint8_t(tlli >> 8), uint8_t(tlli), /* TLLI */
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200657 };
658
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200659 pdch->rcv_block(&data_msg[0], sizeof(data_msg), *fn, &meas);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200660
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +0200661 ms = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200662 OSMO_ASSERT(ms != NULL);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200663
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200664 return ul_tbf;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200665}
666
Pau Espin Pedrol99360a32021-03-09 17:18:12 +0100667static void send_ul_mac_block_buf(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_pdch *pdch,
668 unsigned fn, uint8_t *buf, int num_bytes)
669{
Pau Espin Pedrolfecab502021-03-17 15:26:37 +0100670 bts_set_current_block_frame_number(bts, fn);
Pau Espin Pedrol99360a32021-03-09 17:18:12 +0100671 pdch->rcv_block(buf, num_bytes, fn, &meas);
672 pdch_ulc_expire_fn(pdch->ulc, fn);
673}
674
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100675static void send_ul_mac_block(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_pdch *pdch,
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200676 RlcMacUplink_t *ulreq, unsigned fn)
677{
678 bitvec *rlc_block;
679 uint8_t buf[64];
680 int num_bytes;
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200681
Alexander Couzensccde5c92017-02-04 03:10:08 +0100682 rlc_block = bitvec_alloc(23, tall_pcu_ctx);
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200683
Pau Espin Pedrol5e300ce2020-02-03 17:18:03 +0100684 OSMO_ASSERT(encode_gsm_rlcmac_uplink(rlc_block, ulreq) == 0);
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200685 num_bytes = bitvec_pack(rlc_block, &buf[0]);
686 OSMO_ASSERT(size_t(num_bytes) < sizeof(buf));
687 bitvec_free(rlc_block);
688
Pau Espin Pedrol99360a32021-03-09 17:18:12 +0100689 send_ul_mac_block_buf(bts, pdch, fn, &buf[0], num_bytes);
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200690}
691
Pau Espin Pedrol58046e42021-03-29 19:01:13 +0200692
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100693static uint32_t get_poll_fn(struct gprs_rlcmac_tbf *tbf, struct gprs_rlcmac_pdch *pdch)
Pau Espin Pedrol58046e42021-03-29 19:01:13 +0200694{
Pau Espin Pedrol58046e42021-03-29 19:01:13 +0200695 struct pdch_ulc *ulc = pdch->ulc;
696 struct rb_node *node;
697 struct pdch_ulc_node *item;
698
699 for (node = rb_first(&ulc->tree_root); node; node = rb_next(node)) {
700 item = container_of(node, struct pdch_ulc_node, node);
701 if (item->type == PDCH_ULC_NODE_TBF_POLL && item->tbf_poll.poll_tbf == tbf)
702 return item->fn;
703 }
704 OSMO_ASSERT(0);
705}
706
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200707static void send_control_ack(gprs_rlcmac_tbf *tbf)
708{
709 RlcMacUplink_t ulreq = {0};
710
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200711 ulreq.u.MESSAGE_TYPE = MT_PACKET_CONTROL_ACK;
712 Packet_Control_Acknowledgement_t *ctrl_ack =
713 &ulreq.u.Packet_Control_Acknowledgement;
714
715 ctrl_ack->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
716 ctrl_ack->TLLI = tbf->tlli();
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100717 send_ul_mac_block(tbf->bts, tbf->control_ts,
Pau Espin Pedrol16e16782021-03-29 19:10:19 +0200718 &ulreq, get_poll_fn(tbf, tbf->control_ts));
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200719}
720
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100721static void send_empty_block(gprs_rlcmac_tbf *tbf, struct gprs_rlcmac_pdch *pdch, unsigned fn)
Pau Espin Pedrol99360a32021-03-09 17:18:12 +0100722{
Pau Espin Pedrol99360a32021-03-09 17:18:12 +0100723 send_ul_mac_block_buf(tbf->bts, pdch, fn, NULL, 0);
724}
725
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100726static gprs_rlcmac_ul_tbf *puan_urbb_len_issue(struct gprs_rlcmac_bts *bts,
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100727 struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta,
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530728 uint8_t ms_class, uint8_t egprs_ms_class)
729{
730 GprsMs *ms;
731 uint32_t rach_fn = *fn - 51;
732 uint32_t sba_fn = *fn + 52;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +0100733 int tfi = 0;
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530734 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530735 RlcMacUplink_t ulreq = {0};
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530736 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530737
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530738 /* needed to set last_rts_fn in the PDCH object */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100739 request_dl_rlc_block(bts, pdch, fn);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530740
741 /*
742 * simulate RACH, this sends an Immediate
743 * Assignment Uplink on the AGCH
744 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100745 bts_handle_rach(bts, 0x73, rach_fn, qta);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530746
747 /* get next free TFI */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100748 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &pdch->trx->trx_no, -1);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530749
750 /* fake a resource request */
751 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
752 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
753 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
754 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100755 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
756 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530757 Count_MS_RA_capability_value = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100758 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530759 MS_RA_capability_value[0].u.Content.
760 Exist_Multislot_capability = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100761 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530762 MS_RA_capability_value[0].u.Content.Multislot_capability.
763 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100764 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530765 MS_RA_capability_value[0].u.Content.Multislot_capability.
766 GPRS_multislot_class = ms_class;
767 if (egprs_ms_class) {
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100768 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530769 MS_RA_capability_value[0].u.Content.
770 Multislot_capability.Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100771 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530772 MS_RA_capability_value[0].u.Content.
773 Multislot_capability.EGPRS_multislot_class = ms_class;
774 }
775
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100776 send_ul_mac_block(bts, pdch, &ulreq, sba_fn);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530777
778 /* check the TBF */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100779 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, pdch->trx->trx_no, pdch->ts_no);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530780 OSMO_ASSERT(ul_tbf);
781 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
782
783 /* send packet uplink assignment */
784 *fn = sba_fn;
785 request_dl_rlc_block(ul_tbf, fn);
786
787 /* send real acknowledgement */
788 send_control_ack(ul_tbf);
789
790 check_tbf(ul_tbf);
791 /* send fake data */
792 uint8_t data_msg[42] = {
793 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
Neels Hofmeyrd34646a2017-02-08 17:07:40 +0100794 (uint8_t)(tfi << 1),
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530795 1, /* BSN:7, E:1 */
796 };
797
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530798 pdch->rcv_block(&data_msg[0], 23, *fn, &meas);
799
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +0200800 ms = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530801 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100802 OSMO_ASSERT(ms_ta(ms) == qta/4);
803 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530804
805 /*
806 * TS 44.060, B.8.1
807 * first seg received first, later second seg
808 */
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530809 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
810 egprs3->si = 0;
811 egprs3->r = 1;
812 egprs3->cv = 7;
813 egprs3->tfi_hi = tfi & 0x03;
814 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
815 egprs3->bsn1_hi = 1;
816 egprs3->bsn1_lo = 0;
817 egprs3->cps_hi = 1;
818 data_msg[3] = 0xff;
819 egprs3->pi = 0;
820 egprs3->cps_lo = 1;
821 egprs3->rsb = 0;
822 egprs3->spb = 0;
823 egprs3->pi = 0;
824
825 pdch->rcv_block(data_msg, 42, *fn, &meas);
826
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +0200827 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 +0100828 struct msgb *msg1 = tbf_ul_ack_create_rlcmac_msg(ul_tbf, pdch, *fn);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530829
Pau Espin Pedrolc432e062021-05-11 13:17:31 +0200830 static uint8_t exp1[] = { 0x40, 0x24, 0x01, 0x0b, 0x3e, 0x24, 0x46, 0x68, 0x9c, 0x70, 0x87, 0xb0,
831 0x06, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b
Maxd3a0d912019-03-05 16:15:01 +0100832 };
833
834 if (!msgb_eq_data_print(msg1, exp1, GSM_MACBLOCK_LEN)) {
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200835 fprintf(stderr, "%s test failed on 1st segment!\n", __func__);
Maxd3a0d912019-03-05 16:15:01 +0100836 return NULL;
837 }
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530838
839 egprs3->si = 0;
840 egprs3->r = 1;
841 egprs3->cv = 7;
842 egprs3->tfi_hi = tfi & 0x03;
843 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
844 egprs3->bsn1_hi = 4;
845 egprs3->bsn1_lo = 0;
846 egprs3->cps_hi = 1;
847 data_msg[3] = 0xff;
848 egprs3->pi = 0;
849 egprs3->cps_lo = 1;
850 egprs3->rsb = 0;
851 egprs3->spb = 0;
852
853 pdch->rcv_block(data_msg, 42, *fn, &meas);
854
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +0200855 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 +0100856 msg1 = tbf_ul_ack_create_rlcmac_msg(ul_tbf, pdch, *fn);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530857
Pau Espin Pedrolc432e062021-05-11 13:17:31 +0200858 static uint8_t exp2[] = { 0x40, 0x24, 0x01, 0x0b, 0x3e, 0x24, 0x46, 0x68, 0x9c, 0x70, 0x88, 0xb0,
859 0x06, 0x8b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b
Maxd3a0d912019-03-05 16:15:01 +0100860 };
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530861
Maxd3a0d912019-03-05 16:15:01 +0100862 if (!msgb_eq_data_print(msg1, exp2, GSM_MACBLOCK_LEN)) {
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200863 fprintf(stderr, "%s test failed on 2nd segment!\n", __func__);
Maxd3a0d912019-03-05 16:15:01 +0100864 return NULL;
865 }
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530866 return ul_tbf;
867}
868
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100869static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(struct gprs_rlcmac_bts *bts,
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100870 struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta,
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530871 uint8_t ms_class, uint8_t egprs_ms_class)
872{
873 GprsMs *ms;
874 uint32_t rach_fn = *fn - 51;
875 uint32_t sba_fn = *fn + 52;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530876 int tfi = 0, i = 0;
877 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530878 RlcMacUplink_t ulreq = {0};
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530879 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530880
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530881 /* needed to set last_rts_fn in the PDCH object */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100882 request_dl_rlc_block(bts, pdch, fn);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530883
884 /*
885 * simulate RACH, this sends an Immediate
886 * Assignment Uplink on the AGCH
887 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100888 bts_handle_rach(bts, 0x73, rach_fn, qta);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530889
890 /* get next free TFI */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100891 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &pdch->trx->trx_no, -1);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530892
893 /* fake a resource request */
894 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
895 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
896 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
897 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100898 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
899 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530900 Count_MS_RA_capability_value = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100901 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530902 MS_RA_capability_value[0].u.Content.
903 Exist_Multislot_capability = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100904 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530905 MS_RA_capability_value[0].u.Content.Multislot_capability.
906 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100907 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530908 MS_RA_capability_value[0].u.Content.Multislot_capability.
909 GPRS_multislot_class = ms_class;
910 if (egprs_ms_class) {
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100911 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530912 MS_RA_capability_value[0].u.Content.
913 Multislot_capability.Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100914 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530915 MS_RA_capability_value[0].u.Content.
916 Multislot_capability.EGPRS_multislot_class = ms_class;
917 }
918
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100919 send_ul_mac_block(bts, pdch, &ulreq, sba_fn);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530920
921 /* check the TBF */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100922 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, pdch->trx->trx_no, pdch->ts_no);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530923 OSMO_ASSERT(ul_tbf != NULL);
924 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
925
926 /* send packet uplink assignment */
927 *fn = sba_fn;
928 request_dl_rlc_block(ul_tbf, fn);
929
930 /* send real acknowledgement */
931 send_control_ack(ul_tbf);
932
933 check_tbf(ul_tbf);
934
935 /* send fake data */
936 uint8_t data_msg[42] = {
937 0x00 | 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
938 uint8_t(0 | (tfi << 1)),
939 uint8_t(1), /* BSN:7, E:1 */
940 };
941
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530942 pdch->rcv_block(&data_msg[0], 23, *fn, &meas);
943
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +0200944 ms = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530945 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100946 OSMO_ASSERT(ms_ta(ms) == qta/4);
947 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530948
949 /*
950 * TS 44.060, B.8.1
951 * first seg received first, later second seg
952 */
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530953 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
954 egprs3->si = 1;
955 egprs3->r = 1;
956 egprs3->cv = 7;
957 egprs3->tfi_hi = tfi & 0x03;
958 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
959 egprs3->bsn1_hi = 1;
960 egprs3->bsn1_lo = 0;
961 egprs3->cps_hi = 1;
962 data_msg[3] = 0xff;
963 egprs3->pi = 0;
964 egprs3->cps_lo = 1;
965 egprs3->rsb = 0;
966 egprs3->spb = 2;
967 egprs3->pi = 0;
968
969 pdch->rcv_block(data_msg, 42, *fn, &meas);
970
971 struct gprs_rlc_data *block = ul_tbf->m_rlc.block(1);
972
973 /* check the status of the block */
974 OSMO_ASSERT(block->spb_status.block_status_ul ==
975 EGPRS_RESEG_FIRST_SEG_RXD);
976
977 egprs3->si = 1;
978 egprs3->r = 1;
979 egprs3->cv = 7;
980 egprs3->tfi_hi = tfi & 0x03;
981 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
982 egprs3->bsn1_hi = 1;
983 egprs3->bsn1_lo = 0;
984 egprs3->cps_hi = 1;
985 data_msg[3] = 0xff;
986 egprs3->pi = 0;
987 egprs3->cps_lo = 1;
988 egprs3->rsb = 0;
989 egprs3->spb = 3;
990
991 pdch->rcv_block(data_msg, 42, *fn, &meas);
992
993 /* check the status of the block */
994 OSMO_ASSERT(block->spb_status.block_status_ul ==
995 EGPRS_RESEG_DEFAULT);
996 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +0100997 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530998 /* Assembled MCS is MCS6. so the size is 74 */
999 OSMO_ASSERT(block->len == 74);
1000
1001 /*
1002 * TS 44.060, B.8.1
1003 * second seg first, later first seg
1004 */
1005 memset(data_msg, 0, sizeof(data_msg));
1006
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301007 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1008 egprs3->si = 1;
1009 egprs3->r = 1;
1010 egprs3->cv = 7;
1011 egprs3->tfi_hi = tfi & 0x03;
1012 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1013 egprs3->bsn1_hi = 2;
1014 egprs3->bsn1_lo = 0;
1015 egprs3->cps_hi = 1;
1016 data_msg[3] = 0xff;
1017 egprs3->pi = 0;
1018 egprs3->cps_lo = 1;
1019 egprs3->rsb = 0;
1020 egprs3->spb = 3;
1021 egprs3->pi = 0;
1022
1023 pdch->rcv_block(data_msg, 42, *fn, &meas);
1024
1025 block = ul_tbf->m_rlc.block(2);
1026 /* check the status of the block */
1027 OSMO_ASSERT(block->spb_status.block_status_ul ==
1028 EGPRS_RESEG_SECOND_SEG_RXD);
1029
1030 egprs3->si = 1;
1031 egprs3->r = 1;
1032 egprs3->cv = 7;
1033 egprs3->tfi_hi = tfi & 0x03;
1034 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1035 egprs3->bsn1_hi = 2;
1036 egprs3->bsn1_lo = 0;
1037 egprs3->cps_hi = 1;
1038 data_msg[3] = 0xff;
1039 egprs3->pi = 0;
1040 egprs3->cps_lo = 1;
1041 egprs3->rsb = 0;
1042 egprs3->spb = 2;
1043 egprs3->pi = 0;
1044
1045 pdch->rcv_block(data_msg, 42, *fn, &meas);
1046
1047 /* check the status of the block */
1048 OSMO_ASSERT(block->spb_status.block_status_ul ==
1049 EGPRS_RESEG_DEFAULT);
1050 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001051 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301052 /* Assembled MCS is MCS6. so the size is 74 */
1053 OSMO_ASSERT(block->len == 74);
1054
1055 /*
1056 * TS 44.060, B.8.1
1057 * Error scenario with spb as 1
1058 */
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301059 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1060 egprs3->si = 1;
1061 egprs3->r = 1;
1062 egprs3->cv = 7;
1063 egprs3->tfi_hi = tfi & 0x03;
1064 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1065 egprs3->bsn1_hi = 3;
1066 egprs3->bsn1_lo = 0;
1067 egprs3->cps_hi = 1;
1068 data_msg[3] = 0xff;
1069 egprs3->pi = 0;
1070 egprs3->cps_lo = 1;
1071 egprs3->rsb = 0;
1072 egprs3->spb = 1;
1073 egprs3->pi = 0;
1074
1075 pdch->rcv_block(data_msg, 42, *fn, &meas);
1076
1077 block = ul_tbf->m_rlc.block(3);
1078 /* check the status of the block */
1079 OSMO_ASSERT(block->spb_status.block_status_ul ==
1080 EGPRS_RESEG_DEFAULT);
1081 /*
1082 * TS 44.060, B.8.1
1083 * comparison of rlc_data for multiple scenarios
1084 * Receive First, the second(BSN 3)
1085 * Receive First, First then Second(BSN 4)
1086 * Receive Second then First(BSN 5)
1087 * after above 3 scenarios are triggered,
1088 * rlc_data of all 3 BSN are compared
1089 */
1090
1091 /* Initialize the data_msg */
1092 for (i = 0; i < 42; i++)
1093 data_msg[i] = i;
1094
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301095 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1096 egprs3->si = 1;
1097 egprs3->r = 1;
1098 egprs3->cv = 7;
1099 egprs3->tfi_hi = tfi & 0x03;
1100 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1101 egprs3->bsn1_hi = 3;
1102 egprs3->bsn1_lo = 0;
1103 egprs3->cps_hi = 1;
1104 data_msg[3] = 0xff;
1105 egprs3->pi = 0;
1106 egprs3->cps_lo = 1;
1107 egprs3->rsb = 0;
1108 egprs3->spb = 2;
1109 egprs3->pi = 0;
1110
1111 pdch->rcv_block(data_msg, 42, *fn, &meas);
1112
1113 block = ul_tbf->m_rlc.block(3);
1114 /* check the status of the block */
1115 OSMO_ASSERT(block->spb_status.block_status_ul ==
1116 EGPRS_RESEG_FIRST_SEG_RXD);
1117
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301118 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1119 egprs3->si = 1;
1120 egprs3->r = 1;
1121 egprs3->cv = 7;
1122 egprs3->tfi_hi = tfi & 0x03;
1123 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1124 egprs3->bsn1_hi = 3;
1125 egprs3->bsn1_lo = 0;
1126 egprs3->cps_hi = 1;
1127 data_msg[3] = 0xff;
1128 egprs3->pi = 0;
1129 egprs3->cps_lo = 1;
1130 egprs3->rsb = 0;
1131 egprs3->spb = 3;
1132 egprs3->pi = 0;
1133
1134 pdch->rcv_block(data_msg, 42, *fn, &meas);
1135
1136 block = ul_tbf->m_rlc.block(3);
1137 /* check the status of the block */
1138 OSMO_ASSERT(block->spb_status.block_status_ul ==
1139 EGPRS_RESEG_DEFAULT);
1140 /* Assembled MCS is MCS6. so the size is 74 */
1141 OSMO_ASSERT(block->len == 74);
1142 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001143 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301144
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301145 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1146 egprs3->si = 1;
1147 egprs3->r = 1;
1148 egprs3->cv = 7;
1149 egprs3->tfi_hi = tfi & 0x03;
1150 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1151 egprs3->bsn1_hi = 4;
1152 egprs3->bsn1_lo = 0;
1153 egprs3->cps_hi = 1;
1154 data_msg[3] = 0xff;
1155 egprs3->pi = 0;
1156 egprs3->cps_lo = 1;
1157 egprs3->rsb = 0;
1158 egprs3->spb = 2;
1159 egprs3->pi = 0;
1160
1161 pdch->rcv_block(data_msg, 42, *fn, &meas);
1162
1163 block = ul_tbf->m_rlc.block(4);
1164 /* check the status of the block */
1165 OSMO_ASSERT(block->spb_status.block_status_ul ==
1166 EGPRS_RESEG_FIRST_SEG_RXD);
1167
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301168 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1169 egprs3->si = 1;
1170 egprs3->r = 1;
1171 egprs3->cv = 7;
1172 egprs3->tfi_hi = tfi & 0x03;
1173 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1174 egprs3->bsn1_hi = 4;
1175 egprs3->bsn1_lo = 0;
1176 egprs3->cps_hi = 1;
1177 data_msg[3] = 0xff;
1178 egprs3->pi = 0;
1179 egprs3->cps_lo = 1;
1180 egprs3->rsb = 0;
1181 egprs3->spb = 2;
1182 egprs3->pi = 0;
1183
1184 pdch->rcv_block(data_msg, 42, *fn, &meas);
1185
1186 block = ul_tbf->m_rlc.block(4);
1187 /* check the status of the block */
1188 OSMO_ASSERT(block->spb_status.block_status_ul ==
1189 EGPRS_RESEG_FIRST_SEG_RXD);
1190
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301191 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1192 egprs3->si = 1;
1193 egprs3->r = 1;
1194 egprs3->cv = 7;
1195 egprs3->tfi_hi = tfi & 0x03;
1196 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1197 egprs3->bsn1_hi = 4;
1198 egprs3->bsn1_lo = 0;
1199 egprs3->cps_hi = 1;
1200 data_msg[3] = 0xff;
1201 egprs3->pi = 0;
1202 egprs3->cps_lo = 1;
1203 egprs3->rsb = 0;
1204 egprs3->spb = 3;
1205 egprs3->pi = 0;
1206
1207 pdch->rcv_block(data_msg, 42, *fn, &meas);
1208
1209 block = ul_tbf->m_rlc.block(4);
1210 /* check the status of the block */
1211 OSMO_ASSERT(block->spb_status.block_status_ul ==
1212 EGPRS_RESEG_DEFAULT);
1213 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001214 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301215 /* Assembled MCS is MCS6. so the size is 74 */
1216 OSMO_ASSERT(block->len == 74);
1217
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301218 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1219 egprs3->si = 1;
1220 egprs3->r = 1;
1221 egprs3->cv = 7;
1222 egprs3->tfi_hi = tfi & 0x03;
1223 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1224 egprs3->bsn1_hi = 5;
1225 egprs3->bsn1_lo = 0;
1226 egprs3->cps_hi = 1;
1227 data_msg[3] = 0xff;
1228 egprs3->pi = 0;
1229 egprs3->cps_lo = 1;
1230 egprs3->rsb = 0;
1231 egprs3->spb = 3;
1232 egprs3->pi = 0;
1233
1234 pdch->rcv_block(data_msg, 42, *fn, &meas);
1235
1236 block = ul_tbf->m_rlc.block(5);
1237 /* check the status of the block */
1238 OSMO_ASSERT(block->spb_status.block_status_ul ==
1239 EGPRS_RESEG_SECOND_SEG_RXD);
1240
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301241 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1242 egprs3->si = 1;
1243 egprs3->r = 1;
1244 egprs3->cv = 7;
1245 egprs3->tfi_hi = tfi & 0x03;
1246 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1247 egprs3->bsn1_hi = 5;
1248 egprs3->bsn1_lo = 0;
1249 egprs3->cps_hi = 1;
1250 data_msg[3] = 0xff;
1251 egprs3->pi = 0;
1252 egprs3->cps_lo = 1;
1253 egprs3->rsb = 0;
1254 egprs3->spb = 2;
1255 egprs3->pi = 0;
1256
1257 pdch->rcv_block(data_msg, 42, *fn, &meas);
1258
1259 block = ul_tbf->m_rlc.block(5);
1260
1261 /* check the status of the block */
1262 OSMO_ASSERT(block->spb_status.block_status_ul ==
1263 EGPRS_RESEG_DEFAULT);
1264 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001265 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301266 /* Assembled MCS is MCS6. so the size is 74 */
1267 OSMO_ASSERT(block->len == 74);
1268
1269 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->len ==
1270 ul_tbf->m_rlc.block(4)->len);
1271 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->len ==
1272 ul_tbf->m_rlc.block(3)->len);
1273
1274 /* Compare the spb status of each BSNs(3,4,5). should be same */
1275 OSMO_ASSERT(
1276 ul_tbf->m_rlc.block(5)->spb_status.block_status_ul ==
1277 ul_tbf->m_rlc.block(4)->spb_status.block_status_ul);
1278 OSMO_ASSERT(
1279 ul_tbf->m_rlc.block(5)->spb_status.block_status_ul ==
1280 ul_tbf->m_rlc.block(3)->spb_status.block_status_ul);
1281
1282 /* Compare the Assembled MCS of each BSNs(3,4,5). should be same */
1283 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->cs_last ==
1284 ul_tbf->m_rlc.block(4)->cs_last);
1285 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->cs_last ==
1286 ul_tbf->m_rlc.block(3)->cs_last);
1287
1288 /* Compare the data of each BSNs(3,4,5). should be same */
1289 OSMO_ASSERT(
1290 !memcmp(ul_tbf->m_rlc.block(5)->block,
1291 ul_tbf->m_rlc.block(4)->block, ul_tbf->m_rlc.block(5)->len
1292 ));
1293 OSMO_ASSERT(
1294 !memcmp(ul_tbf->m_rlc.block(5)->block,
1295 ul_tbf->m_rlc.block(3)->block, ul_tbf->m_rlc.block(5)->len
1296 ));
1297
1298 return ul_tbf;
1299}
1300
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001301static gprs_rlcmac_ul_tbf *establish_ul_tbf(struct gprs_rlcmac_bts *bts,
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001302 struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta,
sivasankari1d8744c2017-01-24 15:53:35 +05301303 uint8_t ms_class, uint8_t egprs_ms_class)
1304{
sivasankari1d8744c2017-01-24 15:53:35 +05301305 uint32_t rach_fn = *fn - 51;
1306 uint32_t sba_fn = *fn + 52;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001307 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301308 gprs_rlcmac_ul_tbf *ul_tbf;
sivasankari1d8744c2017-01-24 15:53:35 +05301309 RlcMacUplink_t ulreq = {0};
sivasankari1d8744c2017-01-24 15:53:35 +05301310
sivasankari1d8744c2017-01-24 15:53:35 +05301311 /* needed to set last_rts_fn in the PDCH object */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001312 request_dl_rlc_block(bts, pdch, fn);
sivasankari1d8744c2017-01-24 15:53:35 +05301313
1314 /*
1315 * simulate RACH, this sends an Immediate
1316 * Assignment Uplink on the AGCH
1317 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001318 bts_handle_rach(bts, 0x73, rach_fn, qta);
sivasankari1d8744c2017-01-24 15:53:35 +05301319
1320 /* get next free TFI */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001321 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &pdch->trx->trx_no, -1);
sivasankari1d8744c2017-01-24 15:53:35 +05301322
1323 /* fake a resource request */
1324 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
1325 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
1326 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
1327 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001328 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
1329 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301330 Count_MS_RA_capability_value = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001331 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301332 MS_RA_capability_value[0].u.Content.
1333 Exist_Multislot_capability = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001334 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301335 MS_RA_capability_value[0].u.Content.Multislot_capability.
1336 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001337 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301338 MS_RA_capability_value[0].u.Content.Multislot_capability.
1339 GPRS_multislot_class = ms_class;
1340 if (egprs_ms_class) {
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001341 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301342 MS_RA_capability_value[0].u.Content.
1343 Multislot_capability.Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001344 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301345 MS_RA_capability_value[0].u.Content.
1346 Multislot_capability.EGPRS_multislot_class = ms_class;
1347 }
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001348 send_ul_mac_block(bts, pdch, &ulreq, sba_fn);
sivasankari1d8744c2017-01-24 15:53:35 +05301349
1350 /* check the TBF */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001351 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, pdch->trx->trx_no, pdch->ts_no);
sivasankari1d8744c2017-01-24 15:53:35 +05301352 /* send packet uplink assignment */
1353 *fn = sba_fn;
1354 request_dl_rlc_block(ul_tbf, fn);
1355
1356 /* send real acknowledgement */
1357 send_control_ack(ul_tbf);
1358
1359 check_tbf(ul_tbf);
1360
1361 return ul_tbf;
1362}
1363
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001364static 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 +01001365 struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta,
sivasankari1d8744c2017-01-24 15:53:35 +05301366 uint8_t ms_class, uint8_t egprs_ms_class, gprs_rlcmac_ul_tbf *ul_tbf)
1367{
1368 OSMO_ASSERT(ul_tbf);
1369 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1370 GprsMs *ms;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001371 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301372
1373 /* send fake data with cv=0*/
1374 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1375 uint8_t data[49] = {0};
1376
1377 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1378
1379 /*header_construction */
1380 memset(data, 0x2b, sizeof(data));
1381 /* Message with CRBB */
1382 for (int i = 0 ; i < 80; i++) {
1383 hdr3->r = 0;
1384 hdr3->si = 0;
1385 hdr3->cv = 10;
1386 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1387 hdr3->tfi_lo = tfi & 0x7;
1388 hdr3->bsn1_hi = ((i * 2)&0x1f);
1389 hdr3->bsn1_lo = ((i * 2)/32);
1390 hdr3->cps_hi = 0;
1391 hdr3->cps_lo = 0;
1392 hdr3->spb = 0;
1393 hdr3->rsb = 0;
1394 hdr3->pi = 0;
1395 hdr3->spare = 0;
1396 hdr3->dummy = 1;
1397 data[4] = 0x0;
1398 data[5] = 0x0;
1399 data[6] = 0x2b;
1400 data[7] = 0x2b;
sivasankari1d8744c2017-01-24 15:53:35 +05301401 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1402 }
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +02001403 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 +01001404 tbf_ul_ack_create_rlcmac_msg(ul_tbf, pdch, *fn);
sivasankari1d8744c2017-01-24 15:53:35 +05301405 memset(data, 0x2b, sizeof(data));
1406 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1407 hdr3->r = 0;
1408 hdr3->si = 0;
1409 hdr3->cv = 0;
1410 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1411 hdr3->tfi_lo = tfi & 0x7;
1412 hdr3->bsn1_hi = 0;
1413 hdr3->bsn1_lo = 2;
1414 hdr3->cps_hi = 0;
1415 hdr3->cps_lo = 0;
1416 hdr3->spb = 0;
1417 hdr3->rsb = 0;
1418 hdr3->pi = 0;
1419 hdr3->spare = 0;
1420 hdr3->dummy = 1;
1421 data[4] = 0x0;
1422 data[5] = 0x2b;
1423 data[6] = 0x2b;
1424 data[7] = 0x2b;
1425
sivasankari1d8744c2017-01-24 15:53:35 +05301426 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1427
1428 request_dl_rlc_block(ul_tbf, fn);
1429
1430 check_tbf(ul_tbf);
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +02001431 OSMO_ASSERT(tbf_ul_ack_fi(ul_tbf)->state == TBF_UL_ACK_ST_NONE);
sivasankari1d8744c2017-01-24 15:53:35 +05301432
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02001433 ms = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
sivasankari1d8744c2017-01-24 15:53:35 +05301434 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001435 OSMO_ASSERT(ms_ta(ms) == qta/4);
1436 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
sivasankari1d8744c2017-01-24 15:53:35 +05301437
1438 return ul_tbf;
1439}
1440
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001441static 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 +01001442 struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta,
sivasankari1d8744c2017-01-24 15:53:35 +05301443 uint8_t ms_class, uint8_t egprs_ms_class, gprs_rlcmac_ul_tbf *ul_tbf)
1444{
1445 OSMO_ASSERT(ul_tbf);
1446 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1447 GprsMs *ms;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001448 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301449
1450 check_tbf(ul_tbf);
1451 /* send fake data with cv=0*/
1452 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1453 uint8_t data[49] = {0};
1454
1455 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1456
1457 /*header_construction */
1458 memset(data, 0x2b, sizeof(data));
1459
1460 /* Message with URBB & URBB length */
1461 for (int i = 0 ; i < 20; i++) {
1462 hdr3->r = 0;
1463 hdr3->si = 0;
1464 hdr3->cv = 10;
1465 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1466 hdr3->tfi_lo = tfi & 0x7;
1467 hdr3->bsn1_hi = ((i * 2)&0x1f);
1468 hdr3->bsn1_lo = ((i * 2)/32);
1469 hdr3->cps_hi = 0;
1470 hdr3->cps_lo = 0;
1471 hdr3->spb = 0;
1472 hdr3->rsb = 0;
1473 hdr3->pi = 0;
1474 hdr3->spare = 0;
1475 hdr3->dummy = 1;
1476 data[4] = 0x0;
1477 data[5] = 0x0;
1478 data[6] = 0x2b;
1479 data[7] = 0x2b;
sivasankari1d8744c2017-01-24 15:53:35 +05301480 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1481 }
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +02001482 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 +01001483 tbf_ul_ack_create_rlcmac_msg(ul_tbf, pdch, *fn);
sivasankari1d8744c2017-01-24 15:53:35 +05301484 memset(data, 0x2b, sizeof(data));
1485 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1486 hdr3->r = 0;
1487 hdr3->si = 0;
1488 hdr3->cv = 0;
1489 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1490 hdr3->tfi_lo = tfi & 0x7;
1491 hdr3->bsn1_hi = 0;
1492 hdr3->bsn1_lo = 2;
1493 hdr3->cps_hi = 0;
1494 hdr3->cps_lo = 0;
1495 hdr3->spb = 0;
1496 hdr3->rsb = 0;
1497 hdr3->pi = 0;
1498 hdr3->spare = 0;
1499 hdr3->dummy = 1;
1500 data[4] = 0x0;
1501 data[5] = 0x2b;
1502 data[6] = 0x2b;
1503 data[7] = 0x2b;
1504
sivasankari1d8744c2017-01-24 15:53:35 +05301505 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +02001506 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 +01001507 tbf_ul_ack_create_rlcmac_msg(ul_tbf, pdch, *fn);
sivasankari1d8744c2017-01-24 15:53:35 +05301508
1509 request_dl_rlc_block(ul_tbf, fn);
1510
1511 check_tbf(ul_tbf);
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +02001512 OSMO_ASSERT(tbf_ul_ack_fi(ul_tbf)->state == TBF_UL_ACK_ST_NONE);
sivasankari1d8744c2017-01-24 15:53:35 +05301513
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02001514 ms = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
sivasankari1d8744c2017-01-24 15:53:35 +05301515 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001516 OSMO_ASSERT(ms_ta(ms) == qta/4);
1517 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
sivasankari1d8744c2017-01-24 15:53:35 +05301518
1519 return ul_tbf;
1520}
1521
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001522static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_CRBB(struct gprs_rlcmac_bts *bts,
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001523 struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta,
sivasankari1d8744c2017-01-24 15:53:35 +05301524 uint8_t ms_class, uint8_t egprs_ms_class)
1525{
1526 GprsMs *ms;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001527 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301528 gprs_rlcmac_ul_tbf *ul_tbf;
sivasankari1d8744c2017-01-24 15:53:35 +05301529
1530 /* check the TBF */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001531 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, pdch->trx->trx_no, pdch->ts_no);
sivasankari1d8744c2017-01-24 15:53:35 +05301532 OSMO_ASSERT(ul_tbf);
1533 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1534
1535 /* send fake data with cv=0*/
1536 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1537 uint8_t data[49] = {0};
1538
1539 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1540
1541 /*header_construction */
1542 memset(data, 0x2b, sizeof(data));
1543
1544 /* Message with CRBB */
1545 for (int i = 80 ; i < 160; i++) {
1546 hdr3->r = 0;
1547 hdr3->si = 0;
1548 hdr3->cv = 10;
1549 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1550 hdr3->tfi_lo = tfi & 0x7;
1551 hdr3->bsn1_hi = ((i)&0x1f);
1552 hdr3->bsn1_lo = ((i)/32);
1553 hdr3->cps_hi = 0;
1554 hdr3->cps_lo = 0;
1555 hdr3->spb = 0;
1556 hdr3->rsb = 0;
1557 hdr3->pi = 0;
1558 hdr3->spare = 0;
1559 hdr3->dummy = 1;
1560 data[4] = 0x0;
1561 data[5] = 0x0;
1562 data[6] = 0x2b;
1563 data[7] = 0x2b;
sivasankari1d8744c2017-01-24 15:53:35 +05301564 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1565 }
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +02001566 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 +01001567 tbf_ul_ack_create_rlcmac_msg(ul_tbf, pdch, *fn);
sivasankari1d8744c2017-01-24 15:53:35 +05301568 memset(data, 0x2b, sizeof(data));
1569 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1570 hdr3->r = 0;
1571 hdr3->si = 0;
1572 hdr3->cv = 0;
1573 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1574 hdr3->tfi_lo = tfi & 0x7;
1575 hdr3->bsn1_hi = 0;
1576 hdr3->bsn1_lo = 2;
1577 hdr3->cps_hi = 0;
1578 hdr3->cps_lo = 0;
1579 hdr3->spb = 0;
1580 hdr3->rsb = 0;
1581 hdr3->pi = 0;
1582 hdr3->spare = 0;
1583 hdr3->dummy = 1;
1584 data[4] = 0x0;
1585 data[5] = 0x2b;
1586 data[6] = 0x2b;
1587 data[7] = 0x2b;
1588
sivasankari1d8744c2017-01-24 15:53:35 +05301589 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1590
1591 request_dl_rlc_block(ul_tbf, fn);
1592
1593 check_tbf(ul_tbf);
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +02001594 OSMO_ASSERT(tbf_ul_ack_fi(ul_tbf)->state == TBF_UL_ACK_ST_NONE);
sivasankari1d8744c2017-01-24 15:53:35 +05301595
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02001596 ms = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
sivasankari1d8744c2017-01-24 15:53:35 +05301597 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001598 OSMO_ASSERT(ms_ta(ms) == qta/4);
1599 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
sivasankari1d8744c2017-01-24 15:53:35 +05301600
1601 return ul_tbf;
1602}
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001603static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase(struct gprs_rlcmac_bts *bts,
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001604 struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001605 uint8_t ms_class, uint8_t egprs_ms_class)
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001606{
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001607 GprsMs *ms;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001608 uint32_t rach_fn = *fn - 51;
1609 uint32_t sba_fn = *fn + 52;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001610 int tfi = 0;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001611 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001612 RlcMacUplink_t ulreq = {0};
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001613
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001614 /* needed to set last_rts_fn in the PDCH object */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001615 request_dl_rlc_block(bts, pdch, fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001616
bhargava959d1de2016-08-17 15:17:21 +05301617 /* simulate RACH, sends an Immediate Assignment Uplink on the AGCH */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001618 bts_handle_rach(bts, 0x73, rach_fn, qta);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001619
1620 /* get next free TFI */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001621 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &pdch->trx->trx_no, -1);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001622
1623 /* fake a resource request */
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001624 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
1625 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
1626 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
1627 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001628 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
1629 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001630 Count_MS_RA_capability_value = 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.Exist_Multislot_capability = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001633 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001634 MS_RA_capability_value[0].u.Content.Multislot_capability.
1635 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001636 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001637 MS_RA_capability_value[0].u.Content.Multislot_capability.
1638 GPRS_multislot_class = ms_class;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001639 if (egprs_ms_class) {
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001640 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001641 MS_RA_capability_value[0].u.Content.Multislot_capability.
1642 Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001643 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001644 MS_RA_capability_value[0].u.Content.Multislot_capability.
1645 EGPRS_multislot_class = ms_class;
1646 }
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001647
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001648 send_ul_mac_block(bts, pdch, &ulreq, sba_fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001649
1650 /* check the TBF */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001651 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, pdch->trx->trx_no, pdch->ts_no);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001652 OSMO_ASSERT(ul_tbf != NULL);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +02001653 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001654
1655 /* send packet uplink assignment */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001656 *fn = sba_fn;
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +02001657 request_dl_rlc_block(ul_tbf, fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001658
Jacob Erlbeckaf454732015-08-21 15:03:23 +02001659 /* send real acknowledgement */
1660 send_control_ack(ul_tbf);
1661
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001662 check_tbf(ul_tbf);
1663
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001664 /* send fake data */
1665 uint8_t data_msg[23] = {
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001666 0x00 | 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
1667 uint8_t(0 | (tfi << 1)),
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001668 uint8_t(1), /* BSN:7, E:1 */
1669 };
1670
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001671 pdch->rcv_block(&data_msg[0], sizeof(data_msg), *fn, &meas);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001672
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02001673 ms = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001674 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001675 OSMO_ASSERT(ms_ta(ms) == qta/4);
1676 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001677
1678 return ul_tbf;
1679}
1680
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001681static void send_dl_data(struct gprs_rlcmac_bts *bts, uint32_t tlli, const char *imsi,
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001682 const uint8_t *data, unsigned data_size)
1683{
1684 GprsMs *ms, *ms2;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001685
Pau Espin Pedrol7f360e72022-10-21 14:30:36 +02001686 ms = bts_ms_store(bts)->get_ms(tlli, GSM_RESERVED_TMSI, imsi);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001687
Pau Espin Pedrol8a35e642021-01-18 17:14:14 +01001688 dl_tbf_handle(bts, tlli, 0, imsi, 0, 0,
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001689 1000, data, data_size);
1690
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02001691 ms = bts_get_ms_by_imsi(bts, imsi);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001692 OSMO_ASSERT(ms != NULL);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001693
Pau Espin Pedrol5deac142021-11-12 18:01:50 +01001694 if (imsi[0] != '\0') {
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02001695 ms2 = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001696 OSMO_ASSERT(ms == ms2);
1697 }
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001698}
1699
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001700static void transmit_dl_data(struct gprs_rlcmac_bts *bts, uint32_t tlli, uint32_t *fn,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001701 uint8_t slots = 0xff)
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001702{
1703 gprs_rlcmac_dl_tbf *dl_tbf;
1704 GprsMs *ms;
1705 unsigned ts_no;
1706
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02001707 ms = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001708 OSMO_ASSERT(ms);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001709 dl_tbf = ms_dl_tbf(ms);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001710 OSMO_ASSERT(dl_tbf);
1711
1712 while (dl_tbf->have_data()) {
1713 uint8_t bn = fn2bn(*fn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001714 for (ts_no = 0 ; ts_no < 8; ts_no += 1) {
1715 if (!(slots & (1 << ts_no)))
1716 continue;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001717 gprs_rlcmac_rcv_rts_block(bts,
Max878bd1f2016-07-20 13:05:05 +02001718 dl_tbf->trx->trx_no, ts_no,
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001719 *fn, bn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001720 }
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001721 *fn = fn_add_blocks(*fn, 1);
1722 }
1723}
1724
Max4c112dc2018-02-01 16:49:23 +01001725static inline void print_ta_tlli(const gprs_rlcmac_ul_tbf *ul_tbf, bool print_ms)
1726{
1727 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
1728 if (print_ms)
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001729 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 +01001730}
1731
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001732static void test_tbf_single_phase()
1733{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02001734 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001735 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001736 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001737 int ts_no = 7;
Philippd935d882016-11-07 13:07:36 +01001738 uint32_t fn = DUMMY_FN; /* 17,25,9 */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001739 uint32_t tlli = 0xf1223344;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001740 const char *imsi = "0011223344";
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001741 uint16_t qta = 31;
1742 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001743
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001744 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001745
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001746 setup_bts(bts, ts_no);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001747 pdch = &bts->trx[0].pdch[ts_no];
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001748
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001749 ul_tbf = establish_ul_tbf_single_phase(bts, pdch, tlli, &fn, qta);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001750
Max4c112dc2018-02-01 16:49:23 +01001751 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001752 send_dl_data(bts, tlli, imsi, (const uint8_t *)"TEST", 4);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001753
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001754 fprintf(stderr, "=== end %s ===\n", __func__);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001755 TALLOC_FREE(the_pcu);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001756}
1757
Pau Espin Pedrol22b26d82022-10-26 15:44:14 +02001758static void test_tbf_single_phase2()
1759{
1760 the_pcu = prepare_pcu();
1761 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001762 struct gprs_rlcmac_pdch *pdch;
Pau Espin Pedrol22b26d82022-10-26 15:44:14 +02001763 int ts_no = 7;
1764 uint32_t fn = DUMMY_FN; /* 17,25,9 */
1765 uint32_t tlli = 0xf1223344;
1766 const char *imsi = "0011223344";
1767 uint16_t qta = 31;
1768 gprs_rlcmac_ul_tbf *ul_tbf;
1769
1770 fprintf(stderr, "=== start %s ===\n", __func__);
1771
1772 setup_bts(bts, ts_no);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001773 pdch = &bts->trx[0].pdch[ts_no];
Pau Espin Pedrol22b26d82022-10-26 15:44:14 +02001774
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001775 ul_tbf = establish_ul_tbf_single_phase(bts, pdch, tlli, &fn, qta);
Pau Espin Pedrol22b26d82022-10-26 15:44:14 +02001776
1777 print_ta_tlli(ul_tbf, true);
1778 /* PCU sends CTRL ACK/NCK with FINAL_ACK=1, hence TBF is not in state FINISHED */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001779 request_dl_rlc_block(bts, pdch, &fn);
Pau Espin Pedrol22b26d82022-10-26 15:44:14 +02001780 OSMO_ASSERT(ul_tbf->state_is(TBF_ST_FINISHED));
1781 /* Now data is sent but no DL TBF is created because MS is not reachable for DL Assignment */
1782 send_dl_data(bts, tlli, imsi, (const uint8_t *)"TEST", 4);
1783
1784 /* After MS CTRL ACKs the FINAL_ACK=1 then it releases the TBF and goes
1785 * to packet-idle mode. Hence PCU will trigger ImmAss(PktDlAss) on PCH. */
1786 send_control_ack(ul_tbf);
1787
1788 fprintf(stderr, "=== end %s ===\n", __func__);
1789 TALLOC_FREE(the_pcu);
1790}
1791
sivasankari1d8744c2017-01-24 15:53:35 +05301792static void test_tbf_egprs_two_phase_puan(void)
1793{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02001794 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001795 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
sivasankari1d8744c2017-01-24 15:53:35 +05301796 int ts_no = 7;
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001797 struct gprs_rlcmac_pdch *pdch;
sivasankari1d8744c2017-01-24 15:53:35 +05301798 uint32_t fn = 2654218;
1799 uint16_t qta = 31;
1800 uint32_t tlli = 0xf1223344;
1801 const char *imsi = "0011223344";
1802 uint8_t ms_class = 1;
sivasankari1d8744c2017-01-24 15:53:35 +05301803 uint8_t egprs_ms_class = 1;
1804 gprs_rlcmac_ul_tbf *ul_tbf;
sivasankari1d8744c2017-01-24 15:53:35 +05301805 uint8_t test_data[256];
1806
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001807 fprintf(stderr, "=== start %s ===\n", __func__);
sivasankari1d8744c2017-01-24 15:53:35 +05301808
1809 memset(test_data, 1, sizeof(test_data));
1810
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001811 setup_bts(bts, ts_no, 4);
1812 bts->initial_mcs_dl = 9;
Pau Espin Pedrol519d0712021-01-14 14:30:03 +01001813 the_pcu->vty.ws_base = 128;
1814 the_pcu->vty.ws_pdch = 64;
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001815 pdch = &bts->trx[0].pdch[ts_no];
sivasankari1d8744c2017-01-24 15:53:35 +05301816
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001817 ul_tbf = establish_ul_tbf(bts, pdch, tlli, &fn, qta, ms_class, egprs_ms_class);
sivasankari1d8744c2017-01-24 15:53:35 +05301818 /* Function to generate URBB with no length */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001819 ul_tbf = establish_ul_tbf_two_phase_puan_URBB_no_length(bts, pdch, tlli, &fn,
sivasankari1d8744c2017-01-24 15:53:35 +05301820 qta, ms_class, egprs_ms_class, ul_tbf);
1821
Max4c112dc2018-02-01 16:49:23 +01001822 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001823 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
sivasankari1d8744c2017-01-24 15:53:35 +05301824
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02001825 static_cast<gprs_rlc_ul_window *>(ul_tbf->window())->reset_state();
sivasankari1d8744c2017-01-24 15:53:35 +05301826 /* Function to generate URBB with length */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001827 ul_tbf = establish_ul_tbf_two_phase_puan_URBB_with_length(bts, pdch, tlli, &fn,
sivasankari1d8744c2017-01-24 15:53:35 +05301828 qta, ms_class, egprs_ms_class, ul_tbf);
1829
Max4c112dc2018-02-01 16:49:23 +01001830 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001831 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
sivasankari1d8744c2017-01-24 15:53:35 +05301832
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02001833 static_cast<gprs_rlc_ul_window *>(ul_tbf->window())->reset_state();
sivasankari1d8744c2017-01-24 15:53:35 +05301834 /* Function to generate CRBB */
Pau Espin Pedrol519d0712021-01-14 14:30:03 +01001835 the_pcu->vty.ws_base = 128;
1836 the_pcu->vty.ws_pdch = 64;
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001837 ul_tbf = establish_ul_tbf_two_phase_puan_CRBB(bts, pdch, tlli, &fn,
sivasankari1d8744c2017-01-24 15:53:35 +05301838 qta, ms_class, egprs_ms_class);
1839
Max4c112dc2018-02-01 16:49:23 +01001840 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001841 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
sivasankari1d8744c2017-01-24 15:53:35 +05301842
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001843 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001844 fprintf(stderr, "=== end %s ===\n", __func__);
sivasankari1d8744c2017-01-24 15:53:35 +05301845}
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301846/*
1847 * Trigger rach for single block
1848 */
1849static void test_immediate_assign_rej_single_block()
1850{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02001851 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001852 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301853 uint32_t fn = 2654218;
1854 uint16_t qta = 31;
1855 int ts_no = 7;
1856
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001857 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301858
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001859 setup_bts(bts, ts_no, 4);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301860
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001861 bts->trx[0].pdch[ts_no].disable();
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301862
1863 uint32_t rach_fn = fn - 51;
1864
1865 int rc = 0;
1866
1867 /*
1868 * simulate RACH, sends an Immediate Assignment
1869 * Uplink reject on the AGCH
1870 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001871 rc = bts_handle_rach(bts, 0x70, rach_fn, qta);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301872
Pau Espin Pedrol15c58ac2021-03-08 14:57:58 +01001873 OSMO_ASSERT(rc == -EBUSY);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301874
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001875 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001876 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301877}
1878
1879/*
1880 * Trigger rach till resources(USF) exhaust
1881 */
1882static void test_immediate_assign_rej_multi_block()
1883{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02001884 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001885 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301886 uint32_t fn = 2654218;
1887 uint16_t qta = 31;
1888 int ts_no = 7;
1889
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001890 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301891
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001892 setup_bts(bts, ts_no, 4);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301893
1894 uint32_t rach_fn = fn - 51;
1895
1896 int rc = 0;
1897
1898 /*
1899 * simulate RACH, sends an Immediate Assignment Uplink
1900 * reject on the AGCH
1901 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001902 rc = bts_handle_rach(bts, 0x78, rach_fn, qta);
1903 rc = bts_handle_rach(bts, 0x79, rach_fn, qta);
1904 rc = bts_handle_rach(bts, 0x7a, rach_fn, qta);
1905 rc = bts_handle_rach(bts, 0x7b, rach_fn, qta);
1906 rc = bts_handle_rach(bts, 0x7c, rach_fn, qta);
1907 rc = bts_handle_rach(bts, 0x7d, rach_fn, qta);
1908 rc = bts_handle_rach(bts, 0x7e, rach_fn, qta);
1909 rc = bts_handle_rach(bts, 0x7f, rach_fn, qta);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301910
1911 OSMO_ASSERT(rc == -EBUSY);
1912
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001913 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001914 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301915}
1916
1917static void test_immediate_assign_rej()
1918{
1919 test_immediate_assign_rej_multi_block();
1920 test_immediate_assign_rej_single_block();
1921}
1922
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001923static void test_tbf_two_phase()
1924{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02001925 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001926 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001927 int ts_no = 7;
1928 uint32_t fn = 2654218;
1929 uint16_t qta = 31;
1930 uint32_t tlli = 0xf1223344;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001931 const char *imsi = "0011223344";
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001932 uint8_t ms_class = 1;
1933 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001934
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001935 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001936
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001937 setup_bts(bts, ts_no, 4);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001938
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001939 ul_tbf = establish_ul_tbf_two_phase(bts, &bts->trx[0].pdch[ts_no],
1940 tlli, &fn, qta, ms_class, 0);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001941
Max4c112dc2018-02-01 16:49:23 +01001942 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001943 send_dl_data(bts, tlli, imsi, (const uint8_t *)"TEST", 4);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001944
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001945 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001946 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001947}
1948
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001949static inline void print_ms(GprsMs *ms, bool old)
Max4c112dc2018-02-01 16:49:23 +01001950{
1951 fprintf(stderr, "%s MS: TLLI = 0x%08x, TA = %d, IMSI = %s, LLC = %zu\n",
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001952 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 +01001953}
1954
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001955static void test_tbf_ra_update_rach()
1956{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02001957 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001958 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001959 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001960 int ts_no = 7;
1961 uint32_t fn = 2654218;
1962 uint16_t qta = 31;
1963 uint32_t tlli1 = 0xf1223344;
1964 uint32_t tlli2 = 0xf5667788;
1965 const char *imsi = "0011223344";
1966 uint8_t ms_class = 1;
1967 gprs_rlcmac_ul_tbf *ul_tbf;
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01001968 gprs_rlcmac_dl_tbf *dl_tbf;
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001969 GprsMs *ms, *ms1, *ms2;
1970
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001971 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001972
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001973 setup_bts(bts, ts_no, 4);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001974 pdch = &bts->trx[0].pdch[ts_no];
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001975
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001976 ul_tbf = establish_ul_tbf_two_phase(bts, pdch, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001977 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001978
1979 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01001980 print_ta_tlli(ul_tbf, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001981
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001982 send_dl_data(bts, tlli1, imsi, (const uint8_t *)"RAU_ACCEPT", 10);
Max4c112dc2018-02-01 16:49:23 +01001983 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001984
Jacob Erlbeckaf454732015-08-21 15:03:23 +02001985 /* Send Packet Downlink Assignment to MS */
1986 request_dl_rlc_block(ul_tbf, &fn);
1987
1988 /* Ack it */
1989 send_control_ack(ul_tbf);
1990
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001991 /* Make sure the RAU Accept gets sent to the MS */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001992 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 1);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001993 transmit_dl_data(bts, tlli1, &fn);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001994 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001995
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01001996 dl_tbf = ms_dl_tbf(ms1);
1997 OSMO_ASSERT(dl_tbf);
Pau Espin Pedrol16e16782021-03-29 19:10:19 +02001998 fn = get_poll_fn(dl_tbf, dl_tbf->control_ts);
1999 send_empty_block(dl_tbf, dl_tbf->control_ts, fn);
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01002000 fn = fn_add_blocks(fn, 1);
2001
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002002 /* Now establish a new TBF for the RA UPDATE COMPLETE (new TLLI) */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002003 ul_tbf = establish_ul_tbf_two_phase(bts, pdch, tlli2, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002004 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002005
2006 ms2 = ul_tbf->ms();
2007
2008 /* The PCU cannot know yet, that both TBF belong to the same MS */
2009 OSMO_ASSERT(ms1 != ms2);
Max4c112dc2018-02-01 16:49:23 +01002010 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002011
2012 /* Send some downlink data along with the new TLLI and the IMSI so that
2013 * the PCU can see, that both MS objects belong to same MS */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002014 send_dl_data(bts, tlli2, imsi, (const uint8_t *)"DATA", 4);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002015
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02002016 ms = bts_get_ms_by_imsi(bts, imsi);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002017 OSMO_ASSERT(ms == ms2);
2018
Max4c112dc2018-02-01 16:49:23 +01002019 print_ms(ms2, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002020
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02002021 ms = bts_get_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002022 OSMO_ASSERT(ms == NULL);
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02002023 ms = bts_get_ms_by_tlli(bts, tlli2, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002024 OSMO_ASSERT(ms == ms2);
2025
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002026 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002027 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002028}
2029
2030static void test_tbf_dl_flow_and_rach_two_phase()
2031{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002032 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002033 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002034 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002035 int ts_no = 7;
2036 uint32_t fn = 2654218;
2037 uint16_t qta = 31;
2038 uint32_t tlli1 = 0xf1223344;
2039 const char *imsi = "0011223344";
2040 uint8_t ms_class = 1;
2041 gprs_rlcmac_ul_tbf *ul_tbf;
2042 gprs_rlcmac_dl_tbf *dl_tbf;
2043 GprsMs *ms, *ms1, *ms2;
2044
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002045 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002046
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002047 setup_bts(bts, ts_no, 1);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002048 pdch = &bts->trx[0].pdch[ts_no];
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002049
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002050 ul_tbf = establish_ul_tbf_two_phase(bts, pdch, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002051 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002052
2053 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002054 print_ta_tlli(ul_tbf, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002055
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002056 send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);
2057 send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);
Max4c112dc2018-02-01 16:49:23 +01002058 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002059
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002060 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 2);
2061 dl_tbf = ms_dl_tbf(ms1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002062 OSMO_ASSERT(dl_tbf != NULL);
2063
2064 /* Get rid of old UL TBF */
2065 tbf_free(ul_tbf);
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02002066 ms = bts_get_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002067 OSMO_ASSERT(ms1 == ms);
2068
2069 /* Now establish a new UL TBF, this will consume one LLC packet */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002070 ul_tbf = establish_ul_tbf_two_phase(bts, pdch, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002071 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002072
2073 ms2 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002074 print_ms(ms2, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002075
2076 /* This should be the same MS object */
2077 OSMO_ASSERT(ms2 == ms1);
2078
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02002079 ms = bts_get_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002080 OSMO_ASSERT(ms2 == ms);
2081
Jacob Erlbeckc8cbfc22015-09-01 11:38:40 +02002082 /* A DL TBF should still exist */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002083 OSMO_ASSERT(ms_dl_tbf(ms));
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002084
2085 /* No queued packets should be lost */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002086 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms)) == 2);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002087
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002088 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002089 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002090}
2091
2092
2093static void test_tbf_dl_flow_and_rach_single_phase()
2094{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002095 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002096 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002097 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002098 int ts_no = 7;
2099 uint32_t fn = 2654218;
2100 uint16_t qta = 31;
2101 uint32_t tlli1 = 0xf1223344;
2102 const char *imsi = "0011223344";
2103 uint8_t ms_class = 1;
2104 gprs_rlcmac_ul_tbf *ul_tbf;
2105 gprs_rlcmac_dl_tbf *dl_tbf;
2106 GprsMs *ms, *ms1, *ms2;
2107
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002108 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002109
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002110 setup_bts(bts, ts_no, 1);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002111 pdch = &bts->trx[0].pdch[ts_no];
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002112
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002113 ul_tbf = establish_ul_tbf_two_phase(bts, pdch, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002114 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002115
2116 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002117 print_ta_tlli(ul_tbf, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002118
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002119 send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);
2120 send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);
Max4c112dc2018-02-01 16:49:23 +01002121 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002122
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002123 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 2);
2124 dl_tbf = ms_dl_tbf(ms1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002125 OSMO_ASSERT(dl_tbf != NULL);
2126
2127 /* Get rid of old UL TBF */
2128 tbf_free(ul_tbf);
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02002129 ms = bts_get_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002130 OSMO_ASSERT(ms1 == ms);
2131
2132 /* Now establish a new UL TBF */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002133 ul_tbf = establish_ul_tbf_single_phase(bts, pdch, tlli1, &fn, qta);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002134
2135 ms2 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002136 print_ms(ms2, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002137
2138 /* There should be a different MS object */
2139 OSMO_ASSERT(ms2 != ms1);
2140
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02002141 ms = bts_get_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002142 OSMO_ASSERT(ms2 == ms);
2143 OSMO_ASSERT(ms1 != ms);
2144
Jacob Erlbeck5f93f852016-01-21 20:48:39 +01002145 /* DL TBF should be removed */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002146 OSMO_ASSERT(!ms_dl_tbf(ms));
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002147
2148 /* No queued packets should be lost */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002149 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms)) == 2);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002150
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002151 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002152 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002153}
2154
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002155static void test_tbf_dl_reuse()
2156{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002157 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002158 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002159 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002160 int ts_no = 7;
2161 uint32_t fn = 2654218;
2162 uint16_t qta = 31;
2163 uint32_t tlli1 = 0xf1223344;
2164 const char *imsi = "0011223344";
2165 uint8_t ms_class = 1;
2166 gprs_rlcmac_ul_tbf *ul_tbf;
2167 gprs_rlcmac_dl_tbf *dl_tbf1, *dl_tbf2;
2168 GprsMs *ms1, *ms2;
2169 unsigned i;
2170 RlcMacUplink_t ulreq = {0};
2171
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002172 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002173
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002174 setup_bts(bts, ts_no, 1);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002175 pdch = &bts->trx[0].pdch[ts_no];
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002176
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002177 ul_tbf = establish_ul_tbf_two_phase(bts, pdch, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002178 ms_class, 0);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002179
2180 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002181 print_ta_tlli(ul_tbf, false);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002182
2183 /* Send some LLC frames */
2184 for (i = 0; i < 40; i++) {
2185 char buf[32];
2186 int rc;
2187
2188 rc = snprintf(buf, sizeof(buf), "LLC PACKET %02i", i);
2189 OSMO_ASSERT(rc > 0);
2190
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002191 send_dl_data(bts, tlli1, imsi, (const uint8_t *)buf, rc);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002192 }
2193
Max4c112dc2018-02-01 16:49:23 +01002194 print_ms(ms1, true);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002195
2196 /* Send Packet Downlink Assignment to MS */
2197 request_dl_rlc_block(ul_tbf, &fn);
2198
2199 /* Ack it */
2200 send_control_ack(ul_tbf);
2201
2202 /* Transmit all data */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002203 transmit_dl_data(bts, tlli1, &fn);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002204 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 0);
2205 OSMO_ASSERT(ms_dl_tbf(ms1));
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002206 OSMO_ASSERT(ms_dl_tbf(ms1)->state_is(TBF_ST_FINISHED));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002207
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002208 dl_tbf1 = ms_dl_tbf(ms1);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002209
2210 /* Send some LLC frames */
2211 for (i = 0; i < 10; i++) {
2212 char buf[32];
2213 int rc;
2214
2215 rc = snprintf(buf, sizeof(buf), "LLC PACKET %02i (TBF 2)", i);
2216 OSMO_ASSERT(rc > 0);
2217
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002218 send_dl_data(bts, tlli1, imsi, (const uint8_t *)buf, rc);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002219 }
2220
Pau Espin Pedrol422636d2021-09-28 15:59:35 +02002221 /* Drop first DL_ACK poll queued */
2222 send_empty_block(dl_tbf1, dl_tbf1->control_ts, get_poll_fn(dl_tbf1, dl_tbf1->control_ts));
2223
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002224 /* Fake Final DL Ack/Nack */
2225 ulreq.u.MESSAGE_TYPE = MT_PACKET_DOWNLINK_ACK_NACK;
2226 Packet_Downlink_Ack_Nack_t *ack = &ulreq.u.Packet_Downlink_Ack_Nack;
2227
2228 ack->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
2229 ack->DOWNLINK_TFI = dl_tbf1->tfi();
2230 ack->Ack_Nack_Description.FINAL_ACK_INDICATION = 1;
2231
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002232 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 +02002233
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002234 OSMO_ASSERT(dl_tbf1->state_is(TBF_ST_WAIT_RELEASE));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002235
2236 request_dl_rlc_block(dl_tbf1, &fn);
2237
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02002238 ms2 = bts_get_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002239 OSMO_ASSERT(ms2 == ms1);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002240 OSMO_ASSERT(ms_dl_tbf(ms2));
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002241 OSMO_ASSERT(ms_dl_tbf(ms2)->state_is(TBF_ST_ASSIGN));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002242
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002243 dl_tbf2 = ms_dl_tbf(ms2);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002244
2245 OSMO_ASSERT(dl_tbf1 != dl_tbf2);
2246
2247 send_control_ack(dl_tbf1);
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002248 OSMO_ASSERT(dl_tbf2->state_is(TBF_ST_FLOW));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002249
2250 /* Transmit all data */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002251 transmit_dl_data(bts, tlli1, &fn);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002252 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms2)) == 0);
2253 OSMO_ASSERT(ms_dl_tbf(ms2));
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002254 OSMO_ASSERT(ms_dl_tbf(ms2)->state_is(TBF_ST_FINISHED));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002255
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002256 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002257 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002258}
2259
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002260static void test_tbf_gprs_egprs()
2261{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002262 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002263 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002264 uint8_t ts_no = 4;
2265 uint8_t ms_class = 45;
2266 int rc = 0;
2267 uint32_t tlli = 0xc0006789;
2268 const char *imsi = "001001123456789";
2269 unsigned delay_csec = 1000;
2270
2271 uint8_t buf[256] = {0};
2272
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002273 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002274
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002275 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
2276 if (!bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +02002277 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
2278 abort();
2279 }
2280
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002281 setup_bts(bts, ts_no);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002282
2283 /* EGPRS-only */
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002284
Alexander Couzens290d9032020-09-16 21:52:02 +02002285 gprs_bssgp_init(bts, 3234, 3234, 1, 1, false, 0, 0, 0);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002286
2287 /* Does not support EGPRS */
Pau Espin Pedrol8a35e642021-01-18 17:14:14 +01002288 rc = dl_tbf_handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002289 delay_csec, buf, sizeof(buf));
2290
Pau Espin Pedrol569f0d22020-10-27 14:45:20 +01002291 OSMO_ASSERT(rc == 0);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002292 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002293
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002294 TALLOC_FREE(the_pcu);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002295}
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02002296
Max4c112dc2018-02-01 16:49:23 +01002297static 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 +02002298 bool free)
Max4c112dc2018-02-01 16:49:23 +01002299{
2300 if (!dl_tbf) {
2301 fprintf(stderr, "%s(): FAILED (NULL TBF)\n", test);
2302 return;
2303 }
2304
2305 fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d",
2306 dl_tbf->dl_slots(),
2307 pcu_bitcount(dl_tbf->dl_slots()),
2308 dl_tbf->window_size());
2309
2310 if (pcu_bitcount(dl_tbf->dl_slots()) != exp_slots || dl_tbf->window_size() != exp_ws)
2311 fprintf(stderr, "%s(): DL TBF FAILED: dl_slots = %u (exp. %u), WS = %u (exp. %u)",
2312 test, pcu_bitcount(dl_tbf->dl_slots()), 4, dl_tbf->window_size(), 128 + 4 * 64);
2313
2314 fprintf(stderr, "\n");
2315
2316 if (free)
2317 tbf_free(dl_tbf);
Max4c112dc2018-02-01 16:49:23 +01002318}
2319
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002320static void test_tbf_ws()
2321{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002322 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002323 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +02002324 GprsMs *ms;
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002325 uint8_t ts_no = 4;
2326 uint8_t ms_class = 12;
2327 gprs_rlcmac_dl_tbf *dl_tbf;
2328
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002329 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002330
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002331 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
2332 if (!bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +02002333 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
2334 abort();
2335 }
2336
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002337 setup_bts(bts, ts_no);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002338
Pau Espin Pedrol519d0712021-01-14 14:30:03 +01002339 the_pcu->vty.ws_base = 128;
2340 the_pcu->vty.ws_pdch = 64;
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002341 the_pcu->alloc_algorithm = alloc_algorithm_b;
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002342 bts->trx[0].pdch[2].enable();
2343 bts->trx[0].pdch[3].enable();
Pau Espin Pedrol4f67a9b2021-06-30 16:03:06 +02002344 /* bts->trx[0].pdch[4].enable(); Already enabled during setup_bts() */
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002345 bts->trx[0].pdch[5].enable();
2346
Alexander Couzens290d9032020-09-16 21:52:02 +02002347 gprs_bssgp_init(bts, 4234, 4234, 1, 1, false, 0, 0, 0);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002348
2349 /* Does no support EGPRS */
Pau Espin Pedrolbfc97562023-04-17 14:49:29 +02002350 ms = bts_alloc_ms(bts);
2351 ms_set_ms_class(ms, ms_class);
Pau Espin Pedrol87573842022-10-26 20:23:45 +02002352 dl_tbf = dl_tbf_alloc(bts, ms, 0, false);
Max4c112dc2018-02-01 16:49:23 +01002353
Pau Espin Pedrolbf5e3cb2022-05-09 16:31:22 +02002354 ws_check(dl_tbf, __func__, 4, 64, true);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002355
2356 /* EGPRS-only */
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002357
2358 /* Does support EGPRS */
Pau Espin Pedrolbfc97562023-04-17 14:49:29 +02002359 ms = bts_alloc_ms(bts);
2360 ms_set_ms_class(ms, ms_class);
2361 ms_set_egprs_ms_class(ms, ms_class);
Pau Espin Pedrol87573842022-10-26 20:23:45 +02002362 dl_tbf = dl_tbf_alloc(bts, ms, 0, false);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002363
Pau Espin Pedrolbf5e3cb2022-05-09 16:31:22 +02002364 ws_check(dl_tbf, __func__, 4, 128 + 4 * 64, true);
2365 fprintf(stderr, "=== end %s ===\n", __func__);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002366 TALLOC_FREE(the_pcu);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002367}
2368
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302369static void test_tbf_update_ws(void)
2370{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002371 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002372 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +02002373 GprsMs *ms;
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302374 uint8_t ts_no = 4;
2375 uint8_t ms_class = 11;
2376 gprs_rlcmac_dl_tbf *dl_tbf;
2377
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002378 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302379
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002380 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
2381 if (!bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +02002382 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
2383 abort();
2384 }
2385
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002386 setup_bts(bts, ts_no);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302387
Pau Espin Pedrol519d0712021-01-14 14:30:03 +01002388 the_pcu->vty.ws_base = 128;
2389 the_pcu->vty.ws_pdch = 64;
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002390 the_pcu->alloc_algorithm = alloc_algorithm_b;
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302391 bts->trx[0].pdch[2].enable();
2392 bts->trx[0].pdch[3].enable();
Pau Espin Pedrol4f67a9b2021-06-30 16:03:06 +02002393 /* bts->trx[0].pdch[4].enable(); Already enabled during setup_bts()) */
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302394 bts->trx[0].pdch[5].enable();
2395
Alexander Couzens290d9032020-09-16 21:52:02 +02002396 gprs_bssgp_init(bts, 5234, 5234, 1, 1, false, 0, 0, 0);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302397
2398 /* EGPRS-only */
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302399
2400 /* Does support EGPRS */
Pau Espin Pedrolbfc97562023-04-17 14:49:29 +02002401 ms = bts_alloc_ms(bts);
2402 ms_set_ms_class(ms, ms_class);
2403 ms_set_egprs_ms_class(ms, ms_class);
Pau Espin Pedrol87573842022-10-26 20:23:45 +02002404 dl_tbf = dl_tbf_alloc(bts, ms, 0, true);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302405
Pau Espin Pedrolbf5e3cb2022-05-09 16:31:22 +02002406 ws_check(dl_tbf, __func__, 1, 128 + 1 * 64, false);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302407
Pau Espin Pedrolb7a2b592022-12-13 14:43:59 +01002408 OSMO_ASSERT(dl_tbf_upgrade_to_multislot(dl_tbf) == 0);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302409
Aravind Sirsikar0ee31cf2016-09-15 17:54:46 +05302410 /* window size should be 384 */
Pau Espin Pedrolbf5e3cb2022-05-09 16:31:22 +02002411 ws_check(dl_tbf, __func__, 4, 128 + 4 * 64, true);
2412 fprintf(stderr, "=== end %s ===\n", __func__);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002413 TALLOC_FREE(the_pcu);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302414}
2415
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01002416/* Test DL-TBF first assigned over CCCH ImmAss, then after X2002 timeout, when MS
2417is available to receive from TBF on PACCH, upgrade it to multislot. In the
2418middle the MS would request a new UL-TBF and PCU ends up creating 2 MS objects on
2419different TRX, which are eventually merged.
2420Hence, new multislot DL-TBF allocation (assigned over PACCH) happens on a different TRX
2421than the one which was assigned over CCCH and where the PktDlAss is sent. SYS#6231 */
2422static void test_ms_merge_dl_tbf_different_trx(void)
2423{
2424 the_pcu = prepare_pcu();
2425 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
2426 GprsMs *first_ms, *second_ms;
2427 uint8_t ts_no = 1;
2428 uint8_t ms_class = 11;
2429 struct gprs_rlcmac_trx *trx0 = &bts->trx[0];
2430 struct gprs_rlcmac_trx *trx1 = &bts->trx[1];
2431 uint32_t old_tlli = 0xa3c2f953;
2432 uint32_t new_tlli = 0xecc1f953;
2433 const char *imsi = "001001000000001";
2434 uint8_t llc_buf[19];
2435 int rc;
2436 unsigned delay_csec = 1000;
2437 struct gprs_rlcmac_dl_tbf *dl_tbf;
2438 struct gprs_rlcmac_ul_tbf *ul_tbf;
2439 uint32_t fn = 0;
2440
2441 fprintf(stderr, "=== start %s ===\n", __func__);
2442
2443 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
2444 if (!bts->pcu->nsi) {
2445 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
2446 abort();
2447 }
2448
2449 setup_bts(bts, ts_no);
2450 the_pcu->alloc_algorithm = alloc_algorithm_b;
2451 /* trx0->pdch[ts_no].enable(); Already enabled during setup_bts()) */
2452 trx0->pdch[ts_no].disable();
2453 trx1->pdch[4].enable();
2454 trx1->pdch[5].enable();
2455 trx1->pdch[6].enable();
2456 gprs_bssgp_init(bts, 5234, 5234, 1, 1, false, 0, 0, 0);
2457
2458 /* Handle LLC frame 1. This will create the TBF we want in TRX1 and
Pau Espin Pedrold1058b92022-12-16 18:39:29 +01002459 * we'll have it upgrade to multislot on TRX0 later. This will trigger a
2460 * CCCH Dl ImAss towards BTS PCUIF. The confirmation from BTS is
2461 * injected further below (TBF_EV_ASSIGN_PCUIF_CNF). */
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01002462 memset(llc_buf, 1, sizeof(llc_buf));
2463 rc = dl_tbf_handle(bts, old_tlli, 0, imsi, ms_class, 0,
2464 delay_csec, llc_buf, sizeof(llc_buf));
2465 OSMO_ASSERT(rc >= 0);
2466
2467 first_ms = bts_ms_store(bts)->get_ms(GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, imsi);
2468 OSMO_ASSERT(first_ms);
2469 dl_tbf = ms_dl_tbf(first_ms);
2470 OSMO_ASSERT(dl_tbf);
2471 OSMO_ASSERT(tbf_get_trx(dl_tbf) == trx1);
2472 OSMO_ASSERT(dl_tbf->control_ts->trx == trx1);
2473 struct gprs_rlcmac_pdch *old_dl_control_ts = dl_tbf->control_ts;
2474
2475 /* Enable PDCHs on TRX0 so that second_ms is allocated on TRX0: */
2476 trx0->pdch[1].enable();
2477 trx0->pdch[2].enable();
2478 trx0->pdch[3].enable();
2479
Pau Espin Pedrolbfc97562023-04-17 14:49:29 +02002480 second_ms = bts_alloc_ms(bts);
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01002481 ms_set_tlli(second_ms, new_tlli);
2482 ul_tbf = ul_tbf_alloc(bts, second_ms, 0, true);
2483 OSMO_ASSERT(ul_tbf != NULL);
2484 ms_update_announced_tlli(second_ms, new_tlli);
2485
2486 /* Here PCU gets to know the MS are the same and they get merged. */
2487 rc = dl_tbf_handle(bts, new_tlli, old_tlli, imsi, ms_class, 0,
2488 delay_csec, llc_buf, sizeof(llc_buf));
2489 OSMO_ASSERT(rc >= 0);
Pau Espin Pedrold1058b92022-12-16 18:39:29 +01002490 /* Here we assert a new DL-TBF is created in the new MS (hence old from TRX1 is deleted and new one is in TRX0): */
2491 dl_tbf = ms_dl_tbf(second_ms);
2492 OSMO_ASSERT(tbf_get_trx(dl_tbf) == trx0);
2493 OSMO_ASSERT(dl_tbf->control_ts != old_dl_control_ts);
2494 OSMO_ASSERT(dl_tbf == llist_first_entry_or_null(&trx0->dl_tbfs, struct llist_item, list)->entry);
2495 OSMO_ASSERT(NULL == llist_first_entry_or_null(&trx1->dl_tbfs, struct llist_item, list));
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01002496
2497 /* Here BTS would answer with data_cnf and trigger
2498 * bts_rcv_imm_ass_cnf(), which would trigger TBF_EV_ASSIGN_PCUIF_CNF.
Pau Espin Pedrold1058b92022-12-16 18:39:29 +01002499 * Since that's for an older DL-TBF assignment which no longer exists, it is ignored. */
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01002500 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2002, 0, OSMO_TDEF_MS) == 0);
2501 osmo_fsm_inst_dispatch(ms_dl_tbf(second_ms)->state_fi, TBF_EV_ASSIGN_PCUIF_CNF, NULL);
2502 osmo_select_main(0);
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01002503
Pau Espin Pedrold1058b92022-12-16 18:39:29 +01002504 /* get the PACCH PktDlAss for the DL-TBF, allocated one the UL-TBF from the new MS obj: */
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01002505 request_dl_rlc_block(dl_tbf->bts, dl_tbf->control_ts, &fn);
2506
2507 fprintf(stderr, "=== end %s ===\n", __func__);
2508 TALLOC_FREE(the_pcu);
2509}
2510
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302511static void test_tbf_puan_urbb_len(void)
2512{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002513 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002514 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002515 struct gprs_rlcmac_pdch *pdch;
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302516 int ts_no = 7;
2517 uint32_t fn = 2654218;
2518 uint16_t qta = 31;
2519 uint32_t tlli = 0xf1223344;
2520 const char *imsi = "0011223344";
2521 uint8_t ms_class = 1;
2522 uint8_t egprs_ms_class = 1;
2523 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302524 uint8_t test_data[256];
2525
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002526 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302527
2528 memset(test_data, 1, sizeof(test_data));
2529
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002530 setup_bts(bts, ts_no, 4);
2531 bts->initial_mcs_dl = 9;
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002532 pdch = &bts->trx[0].pdch[ts_no];
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302533
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002534 ul_tbf = puan_urbb_len_issue(bts, pdch, tlli, &fn, qta,
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302535 ms_class, egprs_ms_class);
2536
Max4c112dc2018-02-01 16:49:23 +01002537 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002538 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302539
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002540 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002541 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302542}
2543
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002544static gprs_rlcmac_ul_tbf *tbf_li_decoding(struct gprs_rlcmac_bts *bts,
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002545 struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta,
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302546 uint8_t ms_class, uint8_t egprs_ms_class)
2547{
2548 GprsMs *ms;
2549 uint32_t rach_fn = *fn - 51;
2550 uint32_t sba_fn = *fn + 52;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002551 int tfi = 0;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302552 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302553 RlcMacUplink_t ulreq = {0};
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302554 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302555 Packet_Resource_Request_t *presreq = NULL;
2556 MS_Radio_Access_capability_t *pmsradiocap = NULL;
2557 Multislot_capability_t *pmultislotcap = NULL;
2558
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302559 /* needed to set last_rts_fn in the PDCH object */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002560 request_dl_rlc_block(bts, pdch, fn);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302561
2562 /*
2563 * simulate RACH, this sends an Immediate
2564 * Assignment Uplink on the AGCH
2565 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002566 bts_handle_rach(bts, 0x73, rach_fn, qta);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302567
2568 /* get next free TFI */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002569 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &pdch->trx->trx_no, -1);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302570
2571 /* fake a resource request */
2572 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
2573 presreq = &ulreq.u.Packet_Resource_Request;
2574 presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
2575 presreq->ID.UnionType = 1; /* != 0 */
2576 presreq->ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01002577 presreq->Exist_MS_Radio_Access_capability2 = 1;
2578 pmsradiocap = &presreq->MS_Radio_Access_capability2;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302579 pmsradiocap->Count_MS_RA_capability_value = 1;
2580 pmsradiocap->MS_RA_capability_value[0].u.Content.
2581 Exist_Multislot_capability = 1;
2582 pmultislotcap = &pmsradiocap->MS_RA_capability_value[0].
2583 u.Content.Multislot_capability;
2584
2585 pmultislotcap->Exist_GPRS_multislot_class = 1;
2586 pmultislotcap->GPRS_multislot_class = ms_class;
2587 if (egprs_ms_class) {
2588 pmultislotcap->Exist_EGPRS_multislot_class = 1;
2589 pmultislotcap->EGPRS_multislot_class = ms_class;
2590 }
2591
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002592 send_ul_mac_block(bts, pdch, &ulreq, sba_fn);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302593
2594 /* check the TBF */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002595 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, pdch->trx->trx_no, pdch->ts_no);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302596 OSMO_ASSERT(ul_tbf);
2597 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
2598
2599 /* send packet uplink assignment */
2600 *fn = sba_fn;
2601 request_dl_rlc_block(ul_tbf, fn);
2602
2603 /* send real acknowledgement */
2604 send_control_ack(ul_tbf);
2605
2606 check_tbf(ul_tbf);
2607
2608 uint8_t data_msg[49] = {0};
2609
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02002610 ms = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302611 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002612 OSMO_ASSERT(ms_ta(ms) == qta/4);
2613 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302614
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302615 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
2616 egprs3->si = 0;
2617 egprs3->r = 1;
2618 egprs3->cv = 7;
2619 egprs3->tfi_hi = tfi & 0x03;
2620 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
2621 egprs3->bsn1_hi = 0;
2622 egprs3->bsn1_lo = 0;
2623 egprs3->cps_hi = 1;
2624 data_msg[3] = 0xff;
2625 egprs3->pi = 0;
2626 egprs3->cps_lo = 1;
2627 egprs3->rsb = 0;
2628 egprs3->spb = 0;
2629 egprs3->pi = 0;
2630 pdch->rcv_block(data_msg, 49, *fn, &meas);
2631
2632 egprs3->bsn1_hi = 1;
2633 egprs3->bsn1_lo = 0;
2634 data_msg[3] = 0x7f;
2635 egprs3->cps_lo = 1;
2636 egprs3->rsb = 0;
2637 egprs3->spb = 0;
2638 egprs3->pi = 0;
2639 data_msg[4] = 0x2;
2640 data_msg[5] = 0x0;
2641 pdch->rcv_block(data_msg, 49, *fn, &meas);
2642
Pau Espin Pedrol14633832022-03-31 19:08:07 +02002643 OSMO_ASSERT(ul_tbf->m_llc.index == 43);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302644
2645 return ul_tbf;
2646}
2647
2648static void test_tbf_li_decoding(void)
2649{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002650 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002651 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002652 struct gprs_rlcmac_pdch *pdch;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302653 int ts_no = 7;
2654 uint32_t fn = 2654218;
2655 uint16_t qta = 31;
2656 uint32_t tlli = 0xf1223344;
2657 const char *imsi = "0011223344";
2658 uint8_t ms_class = 1;
2659 uint8_t egprs_ms_class = 1;
2660 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302661 uint8_t test_data[256];
2662
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002663 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302664
2665 memset(test_data, 1, sizeof(test_data));
2666
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002667 setup_bts(bts, ts_no, 4);
2668 bts->initial_mcs_dl = 9;
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002669 pdch = &bts->trx[0].pdch[ts_no];
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302670
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002671 ul_tbf = tbf_li_decoding(bts, pdch, tlli, &fn, qta,
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302672 ms_class, egprs_ms_class);
2673
Max4c112dc2018-02-01 16:49:23 +01002674 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002675 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302676
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002677 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002678 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302679}
2680
aravind sirsikarf2761382016-10-25 12:45:24 +05302681/*
2682 * Test that a bit within the uncompressed bitmap whose BSN is not within
2683 * the transmit window shall be ignored. See section 9.1.8.2.4 of 44.060
2684 * version 7.27.0 Release 7.
2685 */
2686static void test_tbf_epdan_out_of_rx_window(void)
2687{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002688 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002689 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
aravind sirsikarf2761382016-10-25 12:45:24 +05302690 uint8_t ms_class = 11;
2691 uint8_t egprs_ms_class = 11;
2692 uint8_t trx_no;
2693 uint32_t tlli = 0xffeeddcc;
2694 gprs_rlcmac_dl_tbf *dl_tbf;
2695 int ts_no = 4;
2696 bitvec *block;
2697 uint8_t bits_data[RLC_EGPRS_MAX_WS/8];
2698 bitvec bits;
2699 int bsn_begin, bsn_end;
2700 EGPRS_PD_AckNack_t *ack_nack;
2701 RlcMacUplink_t ul_control_block;
2702 gprs_rlc_v_b *prlcmvb;
2703 gprs_rlc_dl_window *prlcdlwindow;
Pau Espin Pedrol5e300ce2020-02-03 17:18:03 +01002704 int rc;
aravind sirsikarf2761382016-10-25 12:45:24 +05302705
aravind sirsikarcc4214a2016-12-09 16:12:42 +05302706 memset(&ul_control_block, 0, sizeof(RlcMacUplink_t));
2707
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002708 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikarf2761382016-10-25 12:45:24 +05302709
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002710 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01002711 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
aravind sirsikarf2761382016-10-25 12:45:24 +05302712 /* ARQ II */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01002713 the_pcu->vty.dl_arq_type = EGPRS_ARQ2;
aravind sirsikarf2761382016-10-25 12:45:24 +05302714
2715 /*
2716 * Simulate a message captured during over-the-air testing,
2717 * where the following values were observed:
2718 * v_a = 1176, vs = 1288, max sns = 2048, window size = 480.
2719 */
2720 uint8_t data_msg[23] = {0x40, 0x20, 0x0b, 0xff, 0xd1,
2721 0x61, 0x00, 0x3e, 0x0e, 0x51, 0x9f,
2722 0xff, 0xff, 0xfb, 0x80, 0x00, 0x00,
2723 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
2724
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002725 dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no);
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +02002726 ms_confirm_tlli(dl_tbf->ms(), tlli);
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002727 prlcdlwindow = static_cast<gprs_rlc_dl_window *>(dl_tbf->window());
aravind sirsikarf2761382016-10-25 12:45:24 +05302728 prlcmvb = &prlcdlwindow->m_v_b;
2729 prlcdlwindow->m_v_s = 1288;
2730 prlcdlwindow->m_v_a = 1176;
2731 prlcdlwindow->set_sns(2048);
2732 prlcdlwindow->set_ws(480);
2733 prlcmvb->mark_unacked(1176);
2734 prlcmvb->mark_unacked(1177);
2735 prlcmvb->mark_unacked(1286);
2736 prlcmvb->mark_unacked(1287);
2737
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002738 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
aravind sirsikarf2761382016-10-25 12:45:24 +05302739
Alexander Couzensccde5c92017-02-04 03:10:08 +01002740 block = bitvec_alloc(23, tall_pcu_ctx);
aravind sirsikarf2761382016-10-25 12:45:24 +05302741
2742 bitvec_unpack(block, data_msg);
2743
2744 bits.data = bits_data;
2745 bits.data_len = sizeof(bits_data);
2746 bits.cur_bit = 0;
2747
Pau Espin Pedrol5e300ce2020-02-03 17:18:03 +01002748 rc = decode_gsm_rlcmac_uplink(block, &ul_control_block);
2749 OSMO_ASSERT(rc == 0);
aravind sirsikarf2761382016-10-25 12:45:24 +05302750
2751 ack_nack = &ul_control_block.u.Egprs_Packet_Downlink_Ack_Nack;
2752
2753 OSMO_ASSERT(prlcmvb->is_unacked(1176));
2754 OSMO_ASSERT(prlcmvb->is_unacked(1177));
2755 OSMO_ASSERT(prlcmvb->is_unacked(1286));
2756 OSMO_ASSERT(prlcmvb->is_unacked(1287));
2757
2758 Decoding::decode_egprs_acknack_bits(
2759 &ack_nack->EGPRS_AckNack.Desc, &bits,
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002760 &bsn_begin, &bsn_end, prlcdlwindow);
aravind sirsikarf2761382016-10-25 12:45:24 +05302761
2762 dl_tbf->rcvd_dl_ack(
2763 ack_nack->EGPRS_AckNack.Desc.FINAL_ACK_INDICATION,
2764 bsn_begin, &bits);
aravind sirsikarf2761382016-10-25 12:45:24 +05302765
aravind sirsikarfb41afa2016-11-02 15:48:00 +05302766 OSMO_ASSERT(prlcmvb->is_invalid(1176));
2767 OSMO_ASSERT(prlcmvb->is_invalid(1177));
2768 OSMO_ASSERT(prlcmvb->is_acked(1286));
2769 OSMO_ASSERT(prlcmvb->is_acked(1287));
aravind sirsikarf2761382016-10-25 12:45:24 +05302770
2771 bitvec_free(block);
2772 tbf_free(dl_tbf);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002773 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002774 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikarf2761382016-10-25 12:45:24 +05302775}
2776
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302777static void test_tbf_egprs_two_phase_spb(void)
2778{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002779 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002780 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002781 struct gprs_rlcmac_pdch *pdch;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302782 int ts_no = 7;
2783 uint32_t fn = 2654218;
2784 uint16_t qta = 31;
2785 uint32_t tlli = 0xf1223344;
2786 const char *imsi = "0011223344";
2787 uint8_t ms_class = 1;
2788 uint8_t egprs_ms_class = 1;
2789 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302790 uint8_t test_data[256];
2791
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002792 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302793
2794 memset(test_data, 1, sizeof(test_data));
2795
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002796 setup_bts(bts, ts_no, 4);
2797 bts->initial_mcs_dl = 9;
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002798 pdch = &bts->trx[0].pdch[ts_no];
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302799
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002800 ul_tbf = establish_ul_tbf_two_phase_spb(bts, pdch, tlli, &fn, qta,
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302801 ms_class, egprs_ms_class);
2802
Max4c112dc2018-02-01 16:49:23 +01002803 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002804 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302805
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002806 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002807 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302808}
2809
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002810static void test_tbf_egprs_two_phase()
2811{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002812 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002813 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002814 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002815 int ts_no = 7;
2816 uint32_t fn = 2654218;
2817 uint16_t qta = 31;
2818 uint32_t tlli = 0xf1223344;
2819 const char *imsi = "0011223344";
2820 uint8_t ms_class = 1;
2821 uint8_t egprs_ms_class = 1;
2822 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002823 uint8_t test_data[256];
2824
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002825 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002826
2827 memset(test_data, 1, sizeof(test_data));
2828
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002829 setup_bts(bts, ts_no, 4);
2830 bts->initial_mcs_dl = 9;
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002831 pdch = &bts->trx[0].pdch[ts_no];
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002832
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002833 ul_tbf = establish_ul_tbf_two_phase(bts, pdch, tlli, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002834 ms_class, egprs_ms_class);
2835
Max4c112dc2018-02-01 16:49:23 +01002836 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002837 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002838
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002839 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002840 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002841}
2842
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002843static void establish_and_use_egprs_dl_tbf(struct gprs_rlcmac_bts *bts, int mcs)
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002844{
2845 unsigned i;
2846 uint8_t ms_class = 11;
2847 uint8_t egprs_ms_class = 11;
2848 uint32_t fn = 0;
2849 uint8_t trx_no;
2850 uint32_t tlli = 0xffeeddcc;
2851 uint8_t test_data[512];
2852
2853 uint8_t rbb[64/8];
2854
2855 gprs_rlcmac_dl_tbf *dl_tbf;
2856
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002857 fprintf(stderr, "Testing MCS-%d\n", mcs);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002858
2859 memset(test_data, 1, sizeof(test_data));
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002860 bts->initial_mcs_dl = mcs;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002861
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002862 dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no);
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +02002863 ms_confirm_tlli(dl_tbf->ms(), tlli);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002864
2865 for (i = 0; i < sizeof(llc_data); i++)
2866 llc_data[i] = i%256;
2867
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002868 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002869
2870 /* Schedule a small LLC frame */
Pau Espin Pedrol14beef62022-10-26 19:44:07 +02002871 ms_append_llc_dl_data(dl_tbf->ms(), 1000, test_data, 10);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002872
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002873 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002874
2875 /* Drain the queue */
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01002876 while (dl_tbf->have_data()) {
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002877 /* Request to send one RLC/MAC block */
2878 request_dl_rlc_block(dl_tbf, &fn);
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01002879 }
Pau Espin Pedrol16e16782021-03-29 19:10:19 +02002880 send_empty_block(dl_tbf, dl_tbf->control_ts, fn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002881
2882 /* Schedule a large LLC frame */
Pau Espin Pedrol14beef62022-10-26 19:44:07 +02002883 ms_append_llc_dl_data(dl_tbf->ms(), 1000, test_data, sizeof(test_data));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002884
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002885 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002886
2887 /* Drain the queue */
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01002888 while (dl_tbf->have_data()) {
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002889 /* Request to send one RLC/MAC block */
2890 request_dl_rlc_block(dl_tbf, &fn);
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01002891 }
Pau Espin Pedrol16e16782021-03-29 19:10:19 +02002892 send_empty_block(dl_tbf, dl_tbf->control_ts, fn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002893
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002894 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002895
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +02002896 _rcv_ack(true, dl_tbf, rbb); /* Receive a final ACK */
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002897
2898 /* Clean up and ensure tbfs are in the correct state */
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002899 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_WAIT_RELEASE));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002900 check_tbf(dl_tbf);
2901 tbf_free(dl_tbf);
2902}
2903
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002904static gprs_rlcmac_dl_tbf *tbf_init(struct gprs_rlcmac_bts *bts,
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302905 int mcs)
2906{
2907 unsigned i;
2908 uint8_t ms_class = 11;
2909 uint8_t egprs_ms_class = 11;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302910 uint8_t trx_no;
2911 uint32_t tlli = 0xffeeddcc;
2912 uint8_t test_data[512];
2913
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302914 gprs_rlcmac_dl_tbf *dl_tbf;
2915
2916 memset(test_data, 1, sizeof(test_data));
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002917 bts->initial_mcs_dl = mcs;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302918
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002919 dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no);
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +02002920 ms_confirm_tlli(dl_tbf->ms(), tlli);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302921
2922 for (i = 0; i < sizeof(test_data); i++)
2923 test_data[i] = i%256;
2924
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002925 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302926
2927 /* Schedule a LLC frame
2928 * passing only 100 bytes, since it is enough to construct
2929 * 2 RLC data blocks. Which are enough to test Header Type 1
2930 * cases
2931 */
Pau Espin Pedrol14beef62022-10-26 19:44:07 +02002932 ms_append_llc_dl_data(dl_tbf->ms(), 1000, test_data, 100);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302933
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002934 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302935
2936 return dl_tbf;
2937
2938}
2939
2940static void tbf_cleanup(gprs_rlcmac_dl_tbf *dl_tbf)
2941{
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302942 uint8_t rbb[64/8];
2943
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +02002944 _rcv_ack(true, dl_tbf, rbb); /* Receive a final ACK */
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302945
2946 /* Clean up and ensure tbfs are in the correct state */
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002947 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_WAIT_RELEASE));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302948 check_tbf(dl_tbf);
2949 tbf_free(dl_tbf);
2950
2951}
2952
Max7d32f552017-12-15 11:25:14 +01002953#define NACK(tbf, x) do { \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002954 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
2955 w->m_v_b.mark_nacked(x); \
2956 OSMO_ASSERT(w->m_v_b.is_nacked(x)); \
Max7d32f552017-12-15 11:25:14 +01002957 } while(0)
2958
2959#define CHECK_UNACKED(tbf, cs, bsn) do { \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002960 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
2961 OSMO_ASSERT(w->m_v_b.is_unacked(bsn)); \
Max898dddb2019-03-12 15:50:57 +01002962 OSMO_ASSERT(mcs_chan_code(tbf->m_rlc.block(bsn)->cs_current_trans) == cs - 1); \
Max7d32f552017-12-15 11:25:14 +01002963 } while(0)
2964
2965#define CHECK_NACKED(tbf, cs, bsn) do { \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002966 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
2967 OSMO_ASSERT(w->m_v_b.is_nacked(bsn)); \
Max898dddb2019-03-12 15:50:57 +01002968 OSMO_ASSERT(mcs_chan_code(tbf->m_rlc.block(bsn)->cs_current_trans) == cs - 1); \
Max7d32f552017-12-15 11:25:14 +01002969 } while(0)
2970
2971#define MAKE_ACKED(m, tbf, fn, cs, check_unacked) do { \
Pau Espin Pedrold29a1432022-12-15 18:57:35 +01002972 m = tbf->create_dl_acked_block(fn, tbf->control_ts); \
Max7d32f552017-12-15 11:25:14 +01002973 OSMO_ASSERT(m); \
2974 if (check_unacked) \
2975 CHECK_UNACKED(tbf, cs, 0); \
2976 else \
2977 CHECK_NACKED(tbf, cs, 0); \
2978 } while(0)
2979
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002980static void egprs_spb_to_normal_validation(struct gprs_rlcmac_bts *bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002981 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302982{
2983 uint32_t fn = 0;
2984 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302985 uint16_t bsn1, bsn2, bsn3;
2986 struct msgb *msg;
2987 struct gprs_rlc_dl_header_egprs_3 *egprs3;
2988 struct gprs_rlc_dl_header_egprs_2 *egprs2;
2989
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002990 fprintf(stderr, "Testing retx for MCS %u to reseg_mcs %u\n", mcs, demanded_mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302991
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002992 dl_tbf = tbf_init(bts, mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302993
2994 /*
2995 * Table 10.4.8a.3.1 of 44.060.
2996 * (MCS7, MCS9) to (MCS2, MCS3) is not handled since it is same as
2997 * (MCS5, MCS6) to (MCS2, MCS3) transition
2998 */
2999 if (!(mcs == 6 && demanded_mcs == 3))
3000 return;
3001
3002 fn = fn_add_blocks(fn, 1);
3003 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01003004 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303005
3006 egprs2 = (struct gprs_rlc_dl_header_egprs_2 *) msg->data;
Maxb4d368b2017-12-01 17:54:39 +01003007 bsn1 = (egprs2->bsn1_hi << 9) | (egprs2->bsn1_mid << 1) | (egprs2->bsn1_lo);
Max7d32f552017-12-15 11:25:14 +01003008
3009 NACK(dl_tbf, 0);
3010
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303011 OSMO_ASSERT(bsn1 == 0);
3012
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003013 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303014
3015 fn = fn_add_blocks(fn, 1);
3016
3017 /* Send first segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003018 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, false);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303019 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
3020 == EGPRS_RESEG_FIRST_SEG_SENT);
3021
3022 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
3023 OSMO_ASSERT(egprs3->spb == 2);
3024
3025 /* Table 10.4.8a.3.1 of 44.060 */
3026 OSMO_ASSERT(egprs3->cps == 3);
3027
3028 /* Send second segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003029 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303030 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
3031 == EGPRS_RESEG_SECOND_SEG_SENT);
3032
3033 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
3034 /* Table 10.4.8a.3.1 of 44.060 */
3035 OSMO_ASSERT(egprs3->spb == 3);
Maxb4d368b2017-12-01 17:54:39 +01003036 bsn2 = (egprs3->bsn1_hi << 9) | (egprs3->bsn1_mid << 1) | (egprs3->bsn1_lo);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303037 OSMO_ASSERT(bsn2 == bsn1);
3038
3039 /* Table 10.4.8a.3.1 of 44.060 */
3040 OSMO_ASSERT(egprs3->cps == 3);
3041
3042 /* Handle (MCS3, MCS3) -> MCS6 case */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003043 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303044
Max7d32f552017-12-15 11:25:14 +01003045 NACK(dl_tbf, 0);
3046
Pau Espin Pedrold29a1432022-12-15 18:57:35 +01003047 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303048 egprs2 = (struct gprs_rlc_dl_header_egprs_2 *) msg->data;
3049
3050 /* Table 10.4.8a.3.1 of 44.060 */
3051 OSMO_ASSERT(egprs2->cps == 0);
Maxb4d368b2017-12-01 17:54:39 +01003052 bsn3 = (egprs2->bsn1_hi << 9) | (egprs2->bsn1_mid << 1) | (egprs2->bsn1_lo);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303053 OSMO_ASSERT(bsn3 == bsn2);
3054
3055 tbf_cleanup(dl_tbf);
3056}
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01003057
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003058static void establish_and_use_egprs_dl_tbf_for_spb(struct gprs_rlcmac_bts *bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01003059 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303060{
3061 uint32_t fn = 0;
3062 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303063 struct msgb *msg;
3064 struct gprs_rlc_dl_header_egprs_3 *egprs3;
3065
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003066 fprintf(stderr, "Testing retx for MCS %u to reseg_mcs %u\n", mcs, demanded_mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303067
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003068 dl_tbf = tbf_init(bts, mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303069
3070 /*
3071 * Table 10.4.8a.3.1 of 44.060.
3072 * (MCS7, MCS9) to (MCS2, MCS3) is not handled since it is same as
3073 * (MCS5, MCS6) to (MCS2, MCS3) transition
3074 */
3075 /* TODO: Need to support of MCS8 -> MCS6 ->MCS3 transistion
3076 * Refer commit be881c028fc4da00c4046ecd9296727975c206a3
3077 * dated 2016-02-07 23:45:40 (UTC)
3078 */
3079 if (!(((mcs == 5) && (demanded_mcs == 2)) ||
3080 ((mcs == 6) && (demanded_mcs == 3)) ||
3081 ((mcs == 4) && (demanded_mcs == 1))))
3082 return;
3083
3084 fn = fn_add_blocks(fn, 1);
3085 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01003086 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303087
Max7d32f552017-12-15 11:25:14 +01003088 NACK(dl_tbf, 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303089
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003090 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303091
3092 fn = fn_add_blocks(fn, 1);
3093
3094 /* Send first segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003095 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, false);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303096 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
3097 == EGPRS_RESEG_FIRST_SEG_SENT);
3098
3099 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
3100 OSMO_ASSERT(egprs3->spb == 2);
3101
3102 /* Table 10.4.8a.3.1 of 44.060 */
3103 switch (demanded_mcs) {
3104 case 3:
3105 OSMO_ASSERT(egprs3->cps == 3);
3106 break;
3107 case 2:
3108 OSMO_ASSERT(egprs3->cps == 9);
3109 break;
3110 case 1:
3111 OSMO_ASSERT(egprs3->cps == 11);
3112 break;
3113 default:
3114 OSMO_ASSERT(false);
3115 break;
3116 }
3117
3118 /* Send second segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003119 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303120 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
3121 == EGPRS_RESEG_SECOND_SEG_SENT);
3122
3123 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
3124 /* Table 10.4.8a.3.1 of 44.060 */
3125 OSMO_ASSERT(egprs3->spb == 3);
3126
3127 /* Table 10.4.8a.3.1 of 44.060 */
3128 switch (demanded_mcs) {
3129 case 3:
3130 OSMO_ASSERT(egprs3->cps == 3);
3131 break;
3132 case 2:
3133 OSMO_ASSERT(egprs3->cps == 9);
3134 break;
3135 case 1:
3136 OSMO_ASSERT(egprs3->cps == 11);
3137 break;
3138 default:
3139 OSMO_ASSERT(false);
3140 break;
3141 }
3142 tbf_cleanup(dl_tbf);
3143}
3144
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003145static void establish_and_use_egprs_dl_tbf_for_retx(struct gprs_rlcmac_bts *bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01003146 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303147{
3148 uint32_t fn = 0;
3149 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303150 struct msgb *msg;
3151
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003152 fprintf(stderr, "Testing retx for MCS %u - %u\n", mcs, demanded_mcs);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303153
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003154 dl_tbf = tbf_init(bts, mcs);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303155
3156 /* For MCS reduction cases like MCS9->MCS6, MCS7->MCS5
3157 * The MCS transition are referred from table Table 8.1.1.2
3158 * of TS 44.060
3159 */
3160 /* TODO: Need to support of MCS8 -> MCS6 transistion
3161 * Refer commit be881c028fc4da00c4046ecd9296727975c206a3
3162 * dated 2016-02-07 23:45:40 (UTC)
3163 */
3164 if (((mcs == 9) && (demanded_mcs < 9)) ||
3165 ((mcs == 7) && (demanded_mcs < 7))) {
3166 fn = fn_add_blocks(fn, 1);
3167 /* Send 2 RLC data block */
Max7d32f552017-12-15 11:25:14 +01003168 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3169 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303170
Max7d32f552017-12-15 11:25:14 +01003171 NACK(dl_tbf, 0);
3172 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303173
3174 /* Set the demanded MCS to demanded_mcs */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003175 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303176
3177 fn = fn_add_blocks(fn, 1);
3178 /* Retransmit the first RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003179 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
3180 CHECK_NACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303181
3182 fn = fn_add_blocks(fn, 1);
3183 /* Retransmit the second RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003184 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
3185 CHECK_UNACKED(dl_tbf, demanded_mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303186 } else if (((mcs == 5) && (demanded_mcs > 6)) ||
3187 ((mcs == 6) && (demanded_mcs > 8))) {
3188 fn = fn_add_blocks(fn, 1);
3189 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01003190 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303191
3192 fn = fn_add_blocks(fn, 1);
3193 /* Send second RLC data block BSN 1 */
Max7d32f552017-12-15 11:25:14 +01003194 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3195 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303196
Max7d32f552017-12-15 11:25:14 +01003197 NACK(dl_tbf, 0);
3198 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303199
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003200 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303201
3202 fn = fn_add_blocks(fn, 1);
3203 /* Send first, second RLC data blocks with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003204 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
3205 CHECK_UNACKED(dl_tbf, demanded_mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303206 } else if (mcs > 6) {
3207 /* No Mcs change cases are handled here for mcs > MCS6*/
3208 fn = fn_add_blocks(fn, 1);
3209 /* Send first,second RLC data blocks */
Max7d32f552017-12-15 11:25:14 +01003210 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3211 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303212
Max7d32f552017-12-15 11:25:14 +01003213 NACK(dl_tbf, 0);
3214 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303215
3216 fn = fn_add_blocks(fn, 1);
3217 /* Send first,second RLC data blocks with demanded_mcs*/
Max7d32f552017-12-15 11:25:14 +01003218 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3219 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303220 } else {
3221
3222 /* No MCS change cases are handled here for mcs <= MCS6*/
3223 fn = fn_add_blocks(fn, 1);
3224 /* Send first RLC data block */
Max7d32f552017-12-15 11:25:14 +01003225 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303226
Max7d32f552017-12-15 11:25:14 +01003227 NACK(dl_tbf, 0);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303228
3229 fn = fn_add_blocks(fn, 1);
3230 /* Send first RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003231 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303232 }
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01003233 /* Clean up pending items in UL controller: */
Pau Espin Pedrol16e16782021-03-29 19:10:19 +02003234 send_empty_block(dl_tbf, dl_tbf->control_ts, fn+50);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303235 tbf_cleanup(dl_tbf);
3236}
3237
3238static void test_tbf_egprs_retx_dl(void)
3239{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003240 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003241 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303242 uint8_t ts_no = 4;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303243
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003244 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303245
Pau Espin Pedrolad79b852021-01-14 13:20:55 +01003246 the_pcu->vty.cs_downgrade_threshold = 0;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003247 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01003248 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303249 /* ARQ II */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01003250 the_pcu->vty.dl_arq_type = EGPRS_ARQ2;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303251
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303252
3253 /* First parameter is current MCS, second one is demanded_mcs */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003254 establish_and_use_egprs_dl_tbf_for_retx(bts, 6, 6);
3255 establish_and_use_egprs_dl_tbf_for_retx(bts, 1, 9);
3256 establish_and_use_egprs_dl_tbf_for_retx(bts, 2, 8);
3257 establish_and_use_egprs_dl_tbf_for_retx(bts, 5, 7);
3258 establish_and_use_egprs_dl_tbf_for_retx(bts, 6, 9);
3259 establish_and_use_egprs_dl_tbf_for_retx(bts, 7, 5);
3260 establish_and_use_egprs_dl_tbf_for_retx(bts, 9, 6);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303261
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003262 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003263 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303264}
3265
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303266static void test_tbf_egprs_spb_dl(void)
3267{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003268 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003269 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303270 uint8_t ts_no = 4;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303271
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003272 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303273
Pau Espin Pedrolad79b852021-01-14 13:20:55 +01003274 the_pcu->vty.cs_downgrade_threshold = 0;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003275 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01003276 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303277
3278 /* ARQ I resegmentation support */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01003279 the_pcu->vty.dl_arq_type = EGPRS_ARQ1;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303280
3281 /*
3282 * First parameter is current MCS, second one is demanded_mcs
3283 * currently only MCS5->MCS2, MCS6->3, MCS4->MCS1 is tested in UT
3284 * rest scenarios has been integration tested
3285 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003286 establish_and_use_egprs_dl_tbf_for_spb(bts, 6, 3);
3287 establish_and_use_egprs_dl_tbf_for_spb(bts, 5, 2);
3288 establish_and_use_egprs_dl_tbf_for_spb(bts, 4, 1);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303289 /* check MCS6->(MCS3+MCS3)->MCS6 case */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003290 egprs_spb_to_normal_validation(bts, 6, 3);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303291
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003292 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003293 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303294}
3295
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003296static void test_tbf_egprs_dl()
3297{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003298 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003299 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003300 uint8_t ts_no = 4;
3301 int i;
3302
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003303 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003304
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003305 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01003306 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303307 /* ARQ II */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01003308 the_pcu->vty.dl_arq_type = EGPRS_ARQ2;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003309
3310 for (i = 1; i <= 9; i++)
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003311 establish_and_use_egprs_dl_tbf(bts, i);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003312
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003313 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003314 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003315}
3316
3317
3318
aravind sirsikare9a138e2017-01-24 12:36:08 +05303319static void test_packet_access_rej_prr_no_other_tbfs()
3320{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003321 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003322 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003323 struct gprs_rlcmac_pdch *pdch;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303324 uint32_t fn = 2654218;
3325 int ts_no = 7;
3326 uint8_t trx_no = 0;
3327 uint32_t tlli = 0xffeeddcc;
Pau Espin Pedrol54742f22021-04-26 16:48:34 +02003328 struct gprs_rlcmac_ul_tbf *ul_tbf;
3329 struct GprsMs *ms;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303330
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003331 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303332
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003333 setup_bts(bts, ts_no, 4);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003334 pdch = &bts->trx[trx_no].pdch[ts_no];
Pau Espin Pedrol9d67e722021-07-28 19:25:38 +02003335 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2000, 0, OSMO_TDEF_MS) == 0);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303336
3337 int rc = 0;
3338
Pau Espin Pedrolbfc97562023-04-17 14:49:29 +02003339 ms = bts_alloc_ms(bts);
Pau Espin Pedrol54742f22021-04-26 16:48:34 +02003340 ms_set_tlli(ms, tlli);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003341 ul_tbf = ms_new_ul_tbf_rejected_pacch(ms, pdch);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303342
3343 OSMO_ASSERT(ul_tbf != 0);
3344
3345 /* trigger packet access reject */
3346 uint8_t bn = fn2bn(fn);
3347
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003348 rc = gprs_rlcmac_rcv_rts_block(bts, pdch->trx->trx_no, pdch->ts_no, fn, bn);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303349
3350 OSMO_ASSERT(rc == 0);
Pau Espin Pedrol9d67e722021-07-28 19:25:38 +02003351 osmo_select_main(0);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303352
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003353 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003354 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303355}
3356
3357static void test_packet_access_rej_prr()
3358{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003359 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003360 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003361 struct gprs_rlcmac_pdch *pdch;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303362 uint32_t fn = 2654218;
3363 uint16_t qta = 31;
3364 int ts_no = 7;
3365 uint8_t trx_no = 0;
3366 RlcMacUplink_t ulreq = {0};
3367 Packet_Resource_Request_t *presreq = NULL;
3368 uint8_t ms_class = 11;
3369 uint8_t egprs_ms_class = 11;
3370 uint32_t rach_fn = fn - 51;
3371 uint32_t sba_fn = fn + 52;
3372 uint32_t tlli = 0xffeeddcc;
3373 MS_Radio_Access_capability_t *pmsradiocap = NULL;
3374 Multislot_capability_t *pmultislotcap = NULL;
3375
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003376 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303377
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003378 setup_bts(bts, ts_no, 4);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003379 pdch = &bts->trx[trx_no].pdch[ts_no];
aravind sirsikare9a138e2017-01-24 12:36:08 +05303380
3381 int rc = 0;
3382
3383 /*
3384 * Trigger rach till resources(USF) exhaust
3385 */
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003386 int i;
3387 for (i = 0; i < 8; i++) {
3388 rc = bts_handle_rach(bts, 0x70 + i, rach_fn, qta);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303389 }
3390
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003391 sba_fn = 52;
3392 for (i = 0; i < 8; i++) {
3393 /* fake a resource request */
3394 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
3395 presreq = &ulreq.u.Packet_Resource_Request;
3396 presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
3397 presreq->ID.UnionType = 1; /* != 0 */
3398 presreq->ID.u.TLLI = tlli + i;
3399 presreq->Exist_MS_Radio_Access_capability2 = 1;
3400 pmsradiocap = &presreq->MS_Radio_Access_capability2;
3401 pmsradiocap->Count_MS_RA_capability_value = 1;
3402 pmsradiocap->MS_RA_capability_value[0].u.Content.
3403 Exist_Multislot_capability = 1;
3404 pmultislotcap = &pmsradiocap->MS_RA_capability_value[0].
3405 u.Content.Multislot_capability;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303406
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003407 pmultislotcap->Exist_GPRS_multislot_class = 1;
3408 pmultislotcap->GPRS_multislot_class = ms_class;
3409 if (egprs_ms_class) {
3410 pmultislotcap->Exist_EGPRS_multislot_class = 1;
3411 pmultislotcap->EGPRS_multislot_class = egprs_ms_class;
3412 }
aravind sirsikare9a138e2017-01-24 12:36:08 +05303413
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003414 send_ul_mac_block(bts, pdch, &ulreq, sba_fn);
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003415 sba_fn = fn_next_block(sba_fn);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303416
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003417 /* trigger packet access reject */
3418 uint8_t bn = fn2bn(fn);
3419
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003420 rc = gprs_rlcmac_rcv_rts_block(bts, pdch->trx->trx_no, pdch->ts_no, fn, bn);
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003421 OSMO_ASSERT(rc == 0);
3422 }
aravind sirsikare9a138e2017-01-24 12:36:08 +05303423
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003424 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003425 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303426}
3427
aravind sirsikared3413e2016-11-11 17:15:10 +05303428void test_packet_access_rej_epdan()
3429{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003430 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003431 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
aravind sirsikared3413e2016-11-11 17:15:10 +05303432 uint32_t tlli = 0xffeeddcc;
Pau Espin Pedrol2ab840a2021-04-26 17:49:05 +02003433 static uint8_t exp[] = { 0x40, 0x84, 0x7f, 0xf7, 0x6e, 0xe6, 0x7e, 0xab,
Maxd3a0d912019-03-05 16:15:01 +01003434 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
3435 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b
3436 };
aravind sirsikared3413e2016-11-11 17:15:10 +05303437
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003438 fprintf(stderr, "=== start %s ===\n", __func__);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003439 setup_bts(bts, 4);
3440 static gprs_rlcmac_dl_tbf *dl_tbf = tbf_init(bts, 1);
aravind sirsikared3413e2016-11-11 17:15:10 +05303441
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +02003442 ms_confirm_tlli(dl_tbf->ms(), tlli);
aravind sirsikared3413e2016-11-11 17:15:10 +05303443
Pau Espin Pedrol6ad11a62021-07-27 12:27:08 +02003444 osmo_fsm_inst_dispatch(dl_tbf->ul_ass_fsm.fi, TBF_UL_ASS_EV_SCHED_ASS_REJ, NULL);
3445 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 +05303446
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003447 fprintf(stderr, "packet reject: %s\n",
aravind sirsikared3413e2016-11-11 17:15:10 +05303448 osmo_hexdump(msg->data, 23));
3449
Maxd3a0d912019-03-05 16:15:01 +01003450 if (!msgb_eq_data_print(msg, exp, GSM_MACBLOCK_LEN))
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003451 fprintf(stderr, "%s test failed!\n", __func__);
Maxd3a0d912019-03-05 16:15:01 +01003452
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003453 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003454 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikared3413e2016-11-11 17:15:10 +05303455}
3456
3457
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003458int main(int argc, char **argv)
3459{
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003460 struct vty_app_info pcu_vty_info = {0};
3461
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003462 tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile TbfTest context");
3463 if (!tall_pcu_ctx)
3464 abort();
3465
Neels Hofmeyr78ce5912017-02-08 17:07:31 +01003466 msgb_talloc_ctx_init(tall_pcu_ctx, 0);
Neels Hofmeyr42f2d612018-04-01 16:54:40 +02003467 osmo_init_logging2(tall_pcu_ctx, &gprs_log_info);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003468 log_set_use_color(osmo_stderr_target, 0);
Pau Espin Pedrol00f52cc2021-02-19 14:01:52 +01003469 log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
Pau Espin Pedrolb18d2a52021-02-19 14:00:48 +01003470 log_set_print_category(osmo_stderr_target, 0);
3471 log_set_print_category_hex(osmo_stderr_target, 0);
Maxfdd79e92018-01-24 11:04:59 +01003472 log_parse_category_mask(osmo_stderr_target, "DRLCMAC,1:DRLCMACDATA,3:DRLCMACDL,3:DRLCMACUL,3:"
Harald Welte398f60e2020-12-10 13:39:21 +01003473 "DRLCMACSCHED,1:DRLCMACMEAS,3:DNS,3:DLBSSGP,3:DPCU,5:"
Max86e35e42019-03-07 12:20:42 +01003474 "DL1IF,6:DTBF,1:DTBFUL,1:DTBFDL,1:DLGLOBAL,2:");
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02003475 osmo_fsm_log_addr(false);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003476 vty_init(&pcu_vty_info);
Pau Espin Pedrolcd2ac562019-08-05 14:30:44 +02003477 pcu_vty_init();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003478
Vadim Yanitskiy87b6e7d2019-11-08 04:44:04 +07003479 /* Initialize shared UL measurements */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003480 pcu_l1_meas_set_link_qual(&meas, 12);
3481 pcu_l1_meas_set_rssi(&meas, 31);
Vadim Yanitskiy87b6e7d2019-11-08 04:44:04 +07003482
Jacob Erlbeckac89a552015-06-29 14:18:46 +02003483 test_tbf_base();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003484 test_tbf_tlli_update();
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +01003485 test_tbf_final_ack(TEST_MODE_STANDARD);
3486 test_tbf_final_ack(TEST_MODE_REVERSE_FREE);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +01003487 test_tbf_delayed_release();
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +02003488 test_tbf_imsi();
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003489 test_tbf_exhaustion();
Jacob Erlbeck41168642015-06-12 13:41:00 +02003490 test_tbf_dl_llc_loss();
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02003491 test_tbf_single_phase();
Pau Espin Pedrol22b26d82022-10-26 15:44:14 +02003492 test_tbf_single_phase2();
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02003493 test_tbf_two_phase();
Jacob Erlbeckb1395982015-08-21 18:15:38 +02003494 test_tbf_ra_update_rach();
3495 test_tbf_dl_flow_and_rach_two_phase();
3496 test_tbf_dl_flow_and_rach_single_phase();
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02003497 test_tbf_dl_reuse();
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01003498 test_tbf_gprs_egprs();
Jacob Erlbeck36df7742016-01-19 15:53:30 +01003499 test_tbf_ws();
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003500 test_tbf_egprs_two_phase();
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05303501 test_tbf_egprs_two_phase_spb();
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003502 test_tbf_egprs_dl();
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303503 test_tbf_egprs_retx_dl();
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303504 test_tbf_egprs_spb_dl();
Aravind Sirsikar02352b42016-08-25 16:37:30 +05303505 test_tbf_puan_urbb_len();
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05303506 test_tbf_update_ws();
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05303507 test_tbf_li_decoding();
aravind sirsikarf2761382016-10-25 12:45:24 +05303508 test_tbf_epdan_out_of_rx_window();
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05303509 test_immediate_assign_rej();
sivasankari1d8744c2017-01-24 15:53:35 +05303510 test_tbf_egprs_two_phase_puan();
aravind sirsikared3413e2016-11-11 17:15:10 +05303511 test_packet_access_rej_epdan();
aravind sirsikare9a138e2017-01-24 12:36:08 +05303512 test_packet_access_rej_prr();
3513 test_packet_access_rej_prr_no_other_tbfs();
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01003514 test_ms_merge_dl_tbf_different_trx();
Jacob Erlbeck67c38502015-05-11 10:32:40 +02003515
3516 if (getenv("TALLOC_REPORT_FULL"))
3517 talloc_report_full(tall_pcu_ctx, stderr);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003518 return EXIT_SUCCESS;
3519}
3520
3521/*
3522 * stubs that should not be reached
3523 */
3524extern "C" {
3525void l1if_pdch_req() { abort(); }
3526void l1if_connect_pdch() { abort(); }
Philipp Maier72ed3332023-02-27 15:32:00 +01003527void l1if_disconnect_pdch() { abort(); }
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003528void l1if_close_pdch() { abort(); }
3529void l1if_open_pdch() { abort(); }
3530}