blob: b48287895bae6b84a5e595c05852d27cd64275de [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"
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +010029#include "pcu_utils.h"
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020030#include "gprs_bssgp_pcu.h"
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +020031#include "pcu_l1_if.h"
aravind sirsikarf2761382016-10-25 12:45:24 +053032#include "decoding.h"
Max1187a772018-01-26 13:31:42 +010033#include <gprs_rlcmac.h>
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010034
35extern "C" {
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020036#include "pcu_vty.h"
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +020037#include "coding_scheme.h"
Pau Espin Pedrolff7c5812022-12-14 18:49:06 +010038#include "alloc_algo.h"
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020039
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010040#include <osmocom/core/application.h>
41#include <osmocom/core/msgb.h>
42#include <osmocom/core/talloc.h>
43#include <osmocom/core/utils.h>
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020044#include <osmocom/vty/vty.h>
Pau Espin Pedrolb5a8a672023-03-14 11:16:22 +010045#include <osmocom/gsm/protocol/gsm_44_060.h>
bhargava959d1de2016-08-17 15:17:21 +053046#include <osmocom/gsm/l1sap.h>
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +020047#include <osmocom/core/fsm.h>
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010048}
49
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020050#include <errno.h>
51
Philippd935d882016-11-07 13:07:36 +010052#define DUMMY_FN 2654167
53
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010054void *tall_pcu_ctx;
55int16_t spoof_mnc = 0, spoof_mcc = 0;
Neels Hofmeyrbdc55fa2018-02-21 00:39:07 +010056bool spoof_mnc_3_digits = false;
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010057
Vadim Yanitskiy87b6e7d2019-11-08 04:44:04 +070058/* Measurements shared by all unit tests */
59static struct pcu_l1_meas meas;
60
Pau Espin Pedrol945be912021-07-26 14:47:46 +020061int gprs_gp_send_test_cb(void *ctx, struct msgb *msg)
62{
63 return 0;
64}
65
66static gprs_pcu *prepare_pcu(void)
67{
68 struct gprs_pcu *pcu = gprs_pcu_alloc(tall_pcu_ctx);
69 bssgp_set_bssgp_callback(gprs_gp_send_test_cb, NULL);
Pau Espin Pedrol9184e852022-05-09 16:13:52 +020070 osmo_tdef_set(pcu->T_defs, -2030, 0, OSMO_TDEF_S);
71 osmo_tdef_set(pcu->T_defs, -2031, 0, OSMO_TDEF_S);
Pau Espin Pedrol945be912021-07-26 14:47:46 +020072 return pcu;
73}
74
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010075static 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 +070076{
77 struct rach_ind_params rip = {
78 .burst_type = GSM_L1_BURST_TYPE_ACCESS_0,
79 .is_11bit = false,
80 .ra = ra,
81 .trx_nr = 0,
82 .ts_nr = 0,
83 .rfn = Fn,
84 .qta = qta,
85 };
86
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010087 return bts_rcv_rach(bts, &rip);
Vadim Yanitskiya0a0b7f2020-05-21 19:55:46 +070088}
89
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +010090static void check_tbf(gprs_rlcmac_tbf *tbf)
91{
92 OSMO_ASSERT(tbf);
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +020093 if (tbf->state_is(TBF_ST_WAIT_RELEASE))
Pau Espin Pedrolf197f152022-11-17 20:18:46 +010094 OSMO_ASSERT(tbf->timers_pending(T3191) || osmo_timer_pending(&tbf->state_fi->timer));
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +020095 if (tbf->state_is(TBF_ST_RELEASING))
Maxee5be3a2017-12-20 17:31:13 +010096 OSMO_ASSERT(tbf->timers_pending(T_MAX));
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +010097}
98
Jacob Erlbeckac89a552015-06-29 14:18:46 +020099static void test_tbf_base()
100{
101
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200102 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckac89a552015-06-29 14:18:46 +0200103
104 OSMO_ASSERT(GPRS_RLCMAC_DL_TBF == reverse(GPRS_RLCMAC_UL_TBF));
105 OSMO_ASSERT(GPRS_RLCMAC_UL_TBF == reverse(GPRS_RLCMAC_DL_TBF));
106
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200107 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckac89a552015-06-29 14:18:46 +0200108}
109
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100110static void test_tbf_tlli_update()
111{
Pau Espin Pedrol945be912021-07-26 14:47:46 +0200112 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100113 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200114 GprsMs *ms, *ms_new;
115
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200116 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100117
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100118 the_pcu->alloc_algorithm = alloc_algorithm_a;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100119 bts->trx[0].pdch[2].enable();
120 bts->trx[0].pdch[3].enable();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100121
122 /*
123 * Make a uplink and downlink allocation
124 */
Pau Espin Pedroleae91472023-04-19 19:42:05 +0200125 ms = ms_alloc(bts, NULL);
Pau Espin Pedrol4d363912023-04-21 19:32:16 +0200126 OSMO_ASSERT(ms_new_dl_tbf_assigned_on_pch(ms) == 0);
127 gprs_rlcmac_tbf *dl_tbf = ms_dl_tbf(ms);
Jacob Erlbeckc6d4cee2015-06-29 13:03:46 +0200128 OSMO_ASSERT(dl_tbf != NULL);
Pau Espin Pedrol4d363912023-04-21 19:32:16 +0200129 OSMO_ASSERT(dl_tbf->ms() == ms);
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);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100132
Pau Espin Pedrol4d363912023-04-21 19:32:16 +0200133 OSMO_ASSERT(ms_new_ul_tbf_assigned_pacch(ms, 0));
134
135 gprs_rlcmac_tbf *ul_tbf = ms_ul_tbf(ms);
Jacob Erlbeckc6d4cee2015-06-29 13:03:46 +0200136 OSMO_ASSERT(ul_tbf != NULL);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200137 OSMO_ASSERT(ul_tbf->ms() == ms);
Pau Espin Pedrol4d363912023-04-21 19:32:16 +0200138 ms_update_announced_tlli(ms, 0x2342);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200139
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +0200140 OSMO_ASSERT(bts_get_ms_by_tlli(bts, 0x2342, GSM_RESERVED_TMSI) == ms);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100141
142 /*
143 * Now check.. that DL changes and that the timing advance
144 * has changed.
145 */
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +0200146 ms_confirm_tlli(dl_tbf->ms(), 0x4232);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100147
Jacob Erlbeck93990462015-05-15 15:50:43 +0200148 /* It is still there, since the new TLLI has not been used for UL yet */
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +0200149 ms_new = bts_get_ms_by_tlli(bts, 0x2342, GSM_RESERVED_TMSI);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200150 OSMO_ASSERT(ms == ms_new);
151
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +0200152 ms_new = bts_get_ms_by_tlli(bts, 0x4232, GSM_RESERVED_TMSI);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200153 OSMO_ASSERT(ms == ms_new);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100154 OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf);
155 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200156
157 /* Now use the new TLLI for UL */
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +0200158 ms_update_announced_tlli(ms, 0x4232);
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +0200159 ms_new = bts_get_ms_by_tlli(bts, 0x2342, GSM_RESERVED_TMSI);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200160 OSMO_ASSERT(ms_new == NULL);
Holger Hans Peter Freytherbc1626e2013-10-30 19:50:49 +0100161
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +0200162 ms_new = bts_get_ms_by_tlli(bts, 0x4232, GSM_RESERVED_TMSI);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200163 OSMO_ASSERT(ms_new != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100164 OSMO_ASSERT(ms_ta(ms_new) == 4);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200165
166 OSMO_ASSERT(ul_tbf->ta() == 4);
167 OSMO_ASSERT(dl_tbf->ta() == 4);
168
169 ul_tbf->set_ta(6);
170
171 OSMO_ASSERT(ul_tbf->ta() == 6);
172 OSMO_ASSERT(dl_tbf->ta() == 6);
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100173
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200174 fprintf(stderr, "=== end %s ===\n", __func__);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100175 TALLOC_FREE(the_pcu);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100176}
177
Daniel Willmann510d7d32014-08-15 18:19:41 +0200178static uint8_t llc_data[200];
179
Maxa2961182018-01-25 19:47:28 +0100180/* override, requires '-Wl,--wrap=pcu_sock_send' */
181int __real_pcu_sock_send(struct msgb *msg);
Pau Espin Pedrole91c4c72021-01-18 17:54:30 +0100182extern "C" int __wrap_pcu_sock_send(struct msgb *msg)
Daniel Willmann510d7d32014-08-15 18:19:41 +0200183{
184 return 0;
185}
186
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100187static void setup_bts(struct gprs_rlcmac_bts *bts, uint8_t ts_no, uint8_t cs = 1)
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100188{
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100189 gprs_rlcmac_trx *trx;
190
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100191 the_pcu->alloc_algorithm = alloc_algorithm_a;
Jacob Erlbecka700dd92015-06-02 16:00:41 +0200192 bts->initial_cs_dl = cs;
193 bts->initial_cs_ul = cs;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100194 trx = &bts->trx[0];
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100195 trx->pdch[ts_no].enable();
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100196 bts_set_current_frame_number(bts, DUMMY_FN);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100197}
198
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100199static gprs_rlcmac_dl_tbf *create_dl_tbf(struct gprs_rlcmac_bts *bts, uint8_t ms_class,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +0100200 uint8_t egprs_ms_class, uint8_t *trx_no_)
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100201{
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100202 int tfi;
203 uint8_t trx_no;
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200204 GprsMs *ms;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100205 gprs_rlcmac_dl_tbf *dl_tbf;
206
Pau Espin Pedroleae91472023-04-19 19:42:05 +0200207 ms = ms_alloc(bts, NULL);
Pau Espin Pedrolbfc97562023-04-17 14:49:29 +0200208 ms_set_ms_class(ms, ms_class);
209 ms_set_egprs_ms_class(ms, egprs_ms_class);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100210
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100211 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_DL_TBF, &trx_no, -1);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100212 OSMO_ASSERT(tfi >= 0);
Pau Espin Pedrol4d363912023-04-21 19:32:16 +0200213 OSMO_ASSERT(ms_new_dl_tbf_assigned_on_pch(ms) == 0);
214 dl_tbf = ms_dl_tbf(ms);
Pau Espin Pedrol983bb7e2020-10-26 14:52:06 +0100215 OSMO_ASSERT(dl_tbf);
Max9bbe1602016-07-18 12:50:18 +0200216 dl_tbf->set_ta(0);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100217 check_tbf(dl_tbf);
218
219 /* "Establish" the DL TBF */
Pau Espin Pedrol49a2f402021-07-27 17:33:07 +0200220 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 +0100221 osmo_fsm_inst_dispatch(dl_tbf->state_fi, TBF_EV_ASSIGN_ADD_CCCH, NULL);
222 osmo_fsm_inst_dispatch(dl_tbf->state_fi, TBF_EV_ASSIGN_ACK_PACCH, NULL);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100223 check_tbf(dl_tbf);
224
225 *trx_no_ = trx_no;
226
227 return dl_tbf;
228}
229
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200230static unsigned fn_add_blocks(unsigned fn, unsigned blocks)
231{
232 unsigned bn = fn2bn(fn) + blocks;
233 fn = fn - (fn % 52);
234 fn += bn * 4 + bn / 3;
Max9dabfa22017-05-16 16:10:45 +0200235 return fn % GSM_MAX_FN;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200236}
237
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200238static void request_dl_rlc_block(struct gprs_rlcmac_bts *bts,
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100239 struct gprs_rlcmac_pdch *pdch,
Jacob Erlbeckee310902015-08-24 11:55:17 +0200240 uint32_t *fn, uint8_t *block_nr = NULL)
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100241{
Jacob Erlbeckee310902015-08-24 11:55:17 +0200242 uint8_t bn = fn2bn(*fn);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100243 gprs_rlcmac_rcv_rts_block(bts, pdch->trx->trx_no, pdch->ts_no, *fn, bn);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200244 *fn = fn_add_blocks(*fn, 1);
Jacob Erlbeckee310902015-08-24 11:55:17 +0200245 bn += 1;
246 if (block_nr)
247 *block_nr = bn;
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100248}
249
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200250static void request_dl_rlc_block(struct gprs_rlcmac_tbf *tbf,
Jacob Erlbeckee310902015-08-24 11:55:17 +0200251 uint32_t *fn, uint8_t *block_nr = NULL)
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200252{
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100253 request_dl_rlc_block(tbf->bts, tbf->control_ts, fn, block_nr);
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200254}
255
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100256enum test_tbf_final_ack_mode {
257 TEST_MODE_STANDARD,
258 TEST_MODE_REVERSE_FREE
259};
260
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +0200261/* Receive an ACK */
262static void _rcv_ack(bool fin, gprs_rlcmac_dl_tbf *tbf, uint8_t *rbb)
263{
264 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window());
265 uint8_t bits_data[RLC_GPRS_WS/8];
266 bitvec bits;
267 Ack_Nack_Description_t ack_nack;
268 int bsn_begin, bsn_end;
269 uint8_t ssn = w->v_s();
270
271 bits.data = bits_data;
272 bits.data_len = sizeof(bits_data);
273 bits.cur_bit = 0;
274 ack_nack.FINAL_ACK_INDICATION = fin;
275 ack_nack.STARTING_SEQUENCE_NUMBER = ssn;
276 memcpy(ack_nack.RECEIVED_BLOCK_BITMAP, rbb, RLC_GPRS_WS/8);
277
278 Decoding::decode_gprs_acknack_bits(
279 &ack_nack, &bits,
280 &bsn_begin, &bsn_end, w);
281
282 tbf->rcvd_dl_ack(fin, bsn_begin, &bits);
283 if (!fin)
284 OSMO_ASSERT(w->window_empty());
285}
286
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100287static void test_tbf_final_ack(enum test_tbf_final_ack_mode test_mode)
Daniel Willmann510d7d32014-08-15 18:19:41 +0200288{
Pau Espin Pedrol945be912021-07-26 14:47:46 +0200289 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100290 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100291 uint8_t ts_no = 4;
292 unsigned i;
Daniel Willmann510d7d32014-08-15 18:19:41 +0200293 uint8_t ms_class = 45;
294 uint32_t fn;
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100295 uint8_t block_nr;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100296 uint8_t trx_no;
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200297 GprsMs *ms;
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200298 uint32_t tlli = 0xffeeddcc;
Daniel Willmann510d7d32014-08-15 18:19:41 +0200299
300 uint8_t rbb[64/8];
301
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200302 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100303
Daniel Willmann510d7d32014-08-15 18:19:41 +0200304 gprs_rlcmac_dl_tbf *dl_tbf;
305 gprs_rlcmac_tbf *new_tbf;
306
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100307 setup_bts(bts, ts_no);
308 dl_tbf = create_dl_tbf(bts, ms_class, 0, &trx_no);
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +0200309 ms_confirm_tlli(dl_tbf->ms(), tlli);
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200310 ms = dl_tbf->ms();
Daniel Willmann510d7d32014-08-15 18:19:41 +0200311
312 for (i = 0; i < sizeof(llc_data); i++)
313 llc_data[i] = i%256;
314
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100315 /* Schedule two LLC frames */
Pau Espin Pedrol14beef62022-10-26 19:44:07 +0200316 ms_append_llc_dl_data(dl_tbf->ms(), 1000, llc_data, sizeof(llc_data));
317 ms_append_llc_dl_data(dl_tbf->ms(), 1000, llc_data, sizeof(llc_data));
Daniel Willmann510d7d32014-08-15 18:19:41 +0200318
319
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100320 /* Send only a few RLC/MAC blocks */
Daniel Willmann510d7d32014-08-15 18:19:41 +0200321 fn = 0;
Jacob Erlbeckee310902015-08-24 11:55:17 +0200322 do {
Daniel Willmann510d7d32014-08-15 18:19:41 +0200323 /* Request to send one block */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200324 request_dl_rlc_block(dl_tbf, &fn, &block_nr);
Jacob Erlbeckee310902015-08-24 11:55:17 +0200325 } while (block_nr < 3);
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200326
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100327 OSMO_ASSERT(dl_tbf->have_data());
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200328 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Daniel Willmann510d7d32014-08-15 18:19:41 +0200329
330 /* Queue a final ACK */
331 memset(rbb, 0, sizeof(rbb));
332 /* Receive a final ACK */
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +0200333 _rcv_ack(true, dl_tbf, rbb);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200334
335 /* Clean up and ensure tbfs are in the correct state */
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200336 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_WAIT_RELEASE));
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100337 new_tbf = ms_dl_tbf(ms);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100338 check_tbf(new_tbf);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200339 OSMO_ASSERT(new_tbf != dl_tbf);
340 OSMO_ASSERT(new_tbf->tfi() == 1);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100341 check_tbf(dl_tbf);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100342 if (test_mode == TEST_MODE_REVERSE_FREE) {
Pau Espin Pedrol403e0482023-04-17 20:28:10 +0200343 ms_ref(ms, __func__);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100344 tbf_free(new_tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100345 OSMO_ASSERT(ms_dl_tbf(ms) == NULL);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100346 check_tbf(dl_tbf);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100347 tbf_free(dl_tbf);
Pau Espin Pedrol403e0482023-04-17 20:28:10 +0200348 ms_unref(ms, __func__);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100349 } else {
Pau Espin Pedrol403e0482023-04-17 20:28:10 +0200350 ms_ref(ms, __func__);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100351 tbf_free(dl_tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100352 OSMO_ASSERT(ms_dl_tbf(ms) == new_tbf);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100353 check_tbf(new_tbf);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100354 tbf_free(new_tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100355 OSMO_ASSERT(ms_dl_tbf(ms) == NULL);
Pau Espin Pedrol403e0482023-04-17 20:28:10 +0200356 ms_unref(ms, __func__);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100357 }
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100358
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100359 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200360 fprintf(stderr, "=== end %s ===\n", __func__);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200361}
362
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100363static void test_tbf_delayed_release()
364{
Pau Espin Pedrol945be912021-07-26 14:47:46 +0200365 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100366 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100367 uint8_t ts_no = 4;
368 unsigned i;
369 uint8_t ms_class = 45;
370 uint32_t fn = 0;
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100371 uint8_t trx_no;
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200372 uint32_t tlli = 0xffeeddcc;
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200373 unsigned long dl_tbf_idle_msec;
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100374
375 uint8_t rbb[64/8];
376
377 gprs_rlcmac_dl_tbf *dl_tbf;
378
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200379 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100380
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100381 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +0100382 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100383
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100384 dl_tbf = create_dl_tbf(bts, ms_class, 0, &trx_no);
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +0200385 ms_confirm_tlli(dl_tbf->ms(), tlli);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100386
387 for (i = 0; i < sizeof(llc_data); i++)
388 llc_data[i] = i%256;
389
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200390 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100391
392 /* Schedule two LLC frames */
Pau Espin Pedrol14beef62022-10-26 19:44:07 +0200393 ms_append_llc_dl_data(dl_tbf->ms(), 1000, llc_data, sizeof(llc_data));
394 ms_append_llc_dl_data(dl_tbf->ms(), 1000, llc_data, sizeof(llc_data));
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100395
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200396 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100397
398 /* Drain the queue */
399 while (dl_tbf->have_data())
400 /* Request to send one RLC/MAC block */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200401 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100402
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200403 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100404
405 /* ACK all blocks */
406 memset(rbb, 0xff, sizeof(rbb));
Max7d32f552017-12-15 11:25:14 +0100407
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +0200408 _rcv_ack(false, dl_tbf, rbb); /* Receive an ACK */
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100409
410 /* Force sending of a single block containing an LLC dummy command */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200411 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100412
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +0200413 _rcv_ack(false, dl_tbf, rbb); /* Receive an ACK */
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100414
415 /* Timeout (make sure fn % 52 remains valid) */
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +0100416 dl_tbf_idle_msec = osmo_tdef_get(the_pcu->T_defs, -2031, OSMO_TDEF_MS, -1);
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200417 fn += 52 * ((msecs_to_frames(dl_tbf_idle_msec + 100) + 51)/ 52);
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200418 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100419
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200420 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FINISHED));
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100421
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +0200422 _rcv_ack(true, dl_tbf, rbb); /* Receive a final ACK */
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100423
424 /* Clean up and ensure tbfs are in the correct state */
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200425 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_WAIT_RELEASE));
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100426 check_tbf(dl_tbf);
427 tbf_free(dl_tbf);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100428 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200429 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100430}
431
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200432static void test_tbf_imsi()
433{
Pau Espin Pedrol945be912021-07-26 14:47:46 +0200434 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100435 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200436 uint8_t ts_no = 4;
437 uint8_t ms_class = 45;
438 uint8_t trx_no;
439 GprsMs *ms1, *ms2;
440
441 gprs_rlcmac_dl_tbf *dl_tbf[2];
442
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200443 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200444
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100445 setup_bts(bts, ts_no);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200446
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100447 dl_tbf[0] = create_dl_tbf(bts, ms_class, 0, &trx_no);
448 dl_tbf[1] = create_dl_tbf(bts, ms_class, 0, &trx_no);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200449
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +0200450 ms_confirm_tlli(dl_tbf[0]->ms(), 0xf1000001);
451 ms_confirm_tlli(dl_tbf[1]->ms(), 0xf1000002);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200452
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100453 ms_set_imsi(dl_tbf[0]->ms(), "001001000000001");
Pau Espin Pedroleb0a0522023-04-17 16:33:35 +0200454 ms1 = bts_get_ms(bts, GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, "001001000000001");
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200455 OSMO_ASSERT(ms1 != NULL);
Pau Espin Pedroleb0a0522023-04-17 16:33:35 +0200456 ms2 = bts_get_ms_by_tlli(bts, 0xf1000001, GSM_RESERVED_TMSI);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200457 OSMO_ASSERT(ms2 != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100458 OSMO_ASSERT(strcmp(ms_imsi(ms2), "001001000000001") == 0);
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200459 OSMO_ASSERT(ms1 == ms2);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200460
461 /* change the IMSI on TBF 0 */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100462 ms_set_imsi(dl_tbf[0]->ms(), "001001000000002");
Pau Espin Pedroleb0a0522023-04-17 16:33:35 +0200463 ms1 = bts_get_ms(bts, GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, "001001000000001");
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200464 OSMO_ASSERT(ms1 == NULL);
Pau Espin Pedroleb0a0522023-04-17 16:33:35 +0200465 ms1 = bts_get_ms(bts, GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, "001001000000002");
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200466 OSMO_ASSERT(ms1 != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100467 OSMO_ASSERT(strcmp(ms_imsi(ms2), "001001000000002") == 0);
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200468 OSMO_ASSERT(ms1 == ms2);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200469
Pau Espin Pedrol528820d2020-10-26 12:40:11 +0100470 /* use the same IMSI on TBF 1 */
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200471 {
Pau Espin Pedrol403e0482023-04-17 20:28:10 +0200472 ms_ref(ms2, __func__);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100473 ms_set_imsi(dl_tbf[1]->ms(), "001001000000002");
Pau Espin Pedroleb0a0522023-04-17 16:33:35 +0200474 ms1 = bts_get_ms(bts, GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, "001001000000002");
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200475 OSMO_ASSERT(ms1 != NULL);
476 OSMO_ASSERT(ms1 != ms2);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100477 OSMO_ASSERT(strcmp(ms_imsi(ms1), "001001000000002") == 0);
478 OSMO_ASSERT(strcmp(ms_imsi(ms2), "") == 0);
Pau Espin Pedrol403e0482023-04-17 20:28:10 +0200479 ms_unref(ms2, __func__);
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200480 }
481
Pau Espin Pedroleb0a0522023-04-17 16:33:35 +0200482 ms2 = bts_get_ms_by_tlli(bts, 0xf1000001, GSM_RESERVED_TMSI);
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200483 OSMO_ASSERT(ms2 == NULL);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200484
485 tbf_free(dl_tbf[1]);
Pau Espin Pedroleb0a0522023-04-17 16:33:35 +0200486 ms1 = bts_get_ms(bts, GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, "001001000000002");
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200487 OSMO_ASSERT(ms1 == NULL);
488
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100489 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200490 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200491}
492
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200493static void test_tbf_exhaustion()
494{
Pau Espin Pedrol945be912021-07-26 14:47:46 +0200495 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100496 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200497 unsigned i;
498 uint8_t ts_no = 4;
499 uint8_t ms_class = 45;
500 int rc = 0;
501
502 uint8_t buf[256] = {0};
503
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200504 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200505
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100506 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
507 if (!bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +0200508 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
509 abort();
510 }
511
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100512 setup_bts(bts, ts_no);
Alexander Couzens290d9032020-09-16 21:52:02 +0200513 gprs_bssgp_init(bts, 1234, 1234, 1, 1, false, 0, 0, 0);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200514
515 for (i = 0; i < 1024; i++) {
516 uint32_t tlli = 0xc0000000 + i;
517 char imsi[16] = {0};
518 unsigned delay_csec = 1000;
519
Jacob Erlbeck9a2845d2015-05-21 12:06:58 +0200520 snprintf(imsi, sizeof(imsi), "001001%09d", i);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200521
Pau Espin Pedrol8a35e642021-01-18 17:14:14 +0100522 rc = dl_tbf_handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200523 delay_csec, buf, sizeof(buf));
524
525 if (rc < 0)
526 break;
527 }
528
529 OSMO_ASSERT(rc == -EBUSY);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200530 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200531
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100532 TALLOC_FREE(the_pcu);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200533}
534
Jacob Erlbeck41168642015-06-12 13:41:00 +0200535static void test_tbf_dl_llc_loss()
536{
Pau Espin Pedrol945be912021-07-26 14:47:46 +0200537 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100538 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrold29a1432022-12-15 18:57:35 +0100539 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeck41168642015-06-12 13:41:00 +0200540 uint8_t ts_no = 4;
541 uint8_t ms_class = 45;
542 int rc = 0;
543 uint32_t tlli = 0xc0123456;
544 const char *imsi = "001001000123456";
545 unsigned delay_csec = 1000;
546 GprsMs *ms;
547
548 uint8_t buf[19];
549
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100550 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
551 if (!bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +0200552 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
553 abort();
554 }
555
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200556 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200557
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100558 setup_bts(bts, ts_no);
Pau Espin Pedrold29a1432022-12-15 18:57:35 +0100559 pdch = &bts->trx[0].pdch[ts_no];
Pau Espin Pedrol63700ea2019-09-09 13:19:06 +0200560 /* keep the MS object 10 seconds */
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +0100561 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2030, 10, OSMO_TDEF_S) == 0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200562
Alexander Couzens290d9032020-09-16 21:52:02 +0200563 gprs_bssgp_init(bts, 2234, 2234, 1, 1, false, 0, 0, 0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200564
565 /* Handle LLC frame 1 */
566 memset(buf, 1, sizeof(buf));
Pau Espin Pedrol8a35e642021-01-18 17:14:14 +0100567 rc = dl_tbf_handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200568 delay_csec, buf, sizeof(buf));
569 OSMO_ASSERT(rc >= 0);
570
Pau Espin Pedroleb0a0522023-04-17 16:33:35 +0200571 ms = bts_get_ms(bts, GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, imsi);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200572 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100573 OSMO_ASSERT(ms_dl_tbf(ms) != NULL);
574 ms_dl_tbf(ms)->set_ta(0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200575
576 /* Handle LLC frame 2 */
577 memset(buf, 2, sizeof(buf));
Pau Espin Pedrol8a35e642021-01-18 17:14:14 +0100578 rc = dl_tbf_handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200579 delay_csec, buf, sizeof(buf));
580 OSMO_ASSERT(rc >= 0);
581
582 /* TBF establishment fails (timeout) */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100583 tbf_free(ms_dl_tbf(ms));
Jacob Erlbeck41168642015-06-12 13:41:00 +0200584
585 /* Handle LLC frame 3 */
586 memset(buf, 3, sizeof(buf));
Pau Espin Pedrol8a35e642021-01-18 17:14:14 +0100587 rc = dl_tbf_handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200588 delay_csec, buf, sizeof(buf));
589 OSMO_ASSERT(rc >= 0);
590
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100591 OSMO_ASSERT(ms_dl_tbf(ms) != NULL);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200592
Pau Espin Pedrolef1b9842022-12-15 18:47:39 +0100593 /* Here BTS would answer with data_cnf and trigger
Pau Espin Pedrol32252902021-07-29 16:44:11 +0200594 * bts_rcv_imm_ass_cnf(), which would trigger TBF_EV_ASSIGN_PCUIF_CNF.
595 * That in turn would set up timer X2002. Finally, X2002 timeout
596 * moves it to FLOW state. We set X2002 timeout to 0 here to get
597 * immediate trigger through osmo_select_main() */
598 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2002, 0, OSMO_TDEF_MS) == 0);
Pau Espin Pedrolf197f152022-11-17 20:18:46 +0100599 osmo_fsm_inst_dispatch(ms_dl_tbf(ms)->state_fi, TBF_EV_ASSIGN_PCUIF_CNF, NULL);
Pau Espin Pedrol32252902021-07-29 16:44:11 +0200600 osmo_select_main(0);
Pau Espin Pedrol65bba932021-07-26 12:06:20 +0200601 OSMO_ASSERT(ms_dl_tbf(ms)->state_is(TBF_ST_FLOW));
602
Jacob Erlbeck41168642015-06-12 13:41:00 +0200603 /* Get first BSN */
604 struct msgb *msg;
605 int fn = 0;
606 uint8_t expected_data = 1;
Maxd3a0d912019-03-05 16:15:01 +0100607 static uint8_t exp[][GSM_MACBLOCK_LEN] = {
608 { 0x07, 0x00, 0x00, 0x4d, 0x01, 0x01, 0x01,
609 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
610 { 0x07, 0x00, 0x02, 0x4d, 0x02, 0x02, 0x02,
611 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 },
Pau Espin Pedrolef1b9842022-12-15 18:47:39 +0100612 /* On last DL block, PCU requests polling (DL ACK/NACK): S/P 1 and RRBP 01, hence 0x07 becomes 0xf1 */
613 { 0x1f, 0x01, 0x04, 0x4d, 0x03, 0x03, 0x03,
Maxd3a0d912019-03-05 16:15:01 +0100614 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 },
615 };
Jacob Erlbeck41168642015-06-12 13:41:00 +0200616
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100617 while (ms_dl_tbf(ms)->have_data()) {
Pau Espin Pedrold29a1432022-12-15 18:57:35 +0100618 msg = ms_dl_tbf(ms)->create_dl_acked_block(fn += 4, pdch);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200619 fprintf(stderr, "MSG = %s\n", msgb_hexdump(msg));
Maxd3a0d912019-03-05 16:15:01 +0100620 if (!msgb_eq_data_print(msg, exp[expected_data - 1], GSM_MACBLOCK_LEN))
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200621 fprintf(stderr, "%s failed at %u\n", __func__, expected_data);
Maxd3a0d912019-03-05 16:15:01 +0100622
Jacob Erlbeck41168642015-06-12 13:41:00 +0200623 expected_data += 1;
624 }
Jacob Erlbeck409efa12015-06-12 14:06:09 +0200625 OSMO_ASSERT(expected_data-1 == 3);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200626
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200627 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200628
Pau Espin Pedrol52e2c082022-05-09 17:12:53 +0200629 /* Restore MS release timeout to 0 to make sure it is freed immediately: */
Pau Espin Pedrolb53230a2023-04-20 16:42:54 +0200630 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2030, 0, OSMO_TDEF_S) == 0);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100631 TALLOC_FREE(the_pcu);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200632}
633
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100634static gprs_rlcmac_ul_tbf *establish_ul_tbf_single_phase(struct gprs_rlcmac_bts *bts,
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100635 struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta)
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200636{
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200637 GprsMs *ms;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200638 int tfi = 0;
639 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200640
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100641 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &pdch->trx->trx_no, -1);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200642
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100643 bts_handle_rach(bts, 0x03, *fn, qta);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200644
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100645 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, pdch->trx->trx_no, pdch->ts_no);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200646 OSMO_ASSERT(ul_tbf != NULL);
647
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200648 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200649
650 uint8_t data_msg[23] = {
651 0x00, /* GPRS_RLCMAC_DATA_BLOCK << 6 */
652 uint8_t(1 | (tfi << 2)),
653 uint8_t(1), /* BSN:7, E:1 */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200654 uint8_t(tlli >> 24), uint8_t(tlli >> 16),
655 uint8_t(tlli >> 8), uint8_t(tlli), /* TLLI */
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200656 };
657
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200658 pdch->rcv_block(&data_msg[0], sizeof(data_msg), *fn, &meas);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200659
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +0200660 ms = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200661 OSMO_ASSERT(ms != NULL);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200662
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200663 return ul_tbf;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200664}
665
Pau Espin Pedrol99360a32021-03-09 17:18:12 +0100666static void send_ul_mac_block_buf(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_pdch *pdch,
667 unsigned fn, uint8_t *buf, int num_bytes)
668{
Pau Espin Pedrolfecab502021-03-17 15:26:37 +0100669 bts_set_current_block_frame_number(bts, fn);
Pau Espin Pedrol99360a32021-03-09 17:18:12 +0100670 pdch->rcv_block(buf, num_bytes, fn, &meas);
671 pdch_ulc_expire_fn(pdch->ulc, fn);
672}
673
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100674static void send_ul_mac_block(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_pdch *pdch,
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200675 RlcMacUplink_t *ulreq, unsigned fn)
676{
677 bitvec *rlc_block;
678 uint8_t buf[64];
679 int num_bytes;
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200680
Alexander Couzensccde5c92017-02-04 03:10:08 +0100681 rlc_block = bitvec_alloc(23, tall_pcu_ctx);
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200682
Pau Espin Pedrol5e300ce2020-02-03 17:18:03 +0100683 OSMO_ASSERT(encode_gsm_rlcmac_uplink(rlc_block, ulreq) == 0);
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200684 num_bytes = bitvec_pack(rlc_block, &buf[0]);
685 OSMO_ASSERT(size_t(num_bytes) < sizeof(buf));
686 bitvec_free(rlc_block);
687
Pau Espin Pedrol99360a32021-03-09 17:18:12 +0100688 send_ul_mac_block_buf(bts, pdch, fn, &buf[0], num_bytes);
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200689}
690
Pau Espin Pedrol58046e42021-03-29 19:01:13 +0200691
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100692static uint32_t get_poll_fn(struct gprs_rlcmac_tbf *tbf, struct gprs_rlcmac_pdch *pdch)
Pau Espin Pedrol58046e42021-03-29 19:01:13 +0200693{
Pau Espin Pedrol58046e42021-03-29 19:01:13 +0200694 struct pdch_ulc *ulc = pdch->ulc;
695 struct rb_node *node;
696 struct pdch_ulc_node *item;
697
698 for (node = rb_first(&ulc->tree_root); node; node = rb_next(node)) {
699 item = container_of(node, struct pdch_ulc_node, node);
700 if (item->type == PDCH_ULC_NODE_TBF_POLL && item->tbf_poll.poll_tbf == tbf)
701 return item->fn;
702 }
703 OSMO_ASSERT(0);
704}
705
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200706static void send_control_ack(gprs_rlcmac_tbf *tbf)
707{
708 RlcMacUplink_t ulreq = {0};
709
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200710 ulreq.u.MESSAGE_TYPE = MT_PACKET_CONTROL_ACK;
711 Packet_Control_Acknowledgement_t *ctrl_ack =
712 &ulreq.u.Packet_Control_Acknowledgement;
713
714 ctrl_ack->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
715 ctrl_ack->TLLI = tbf->tlli();
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100716 send_ul_mac_block(tbf->bts, tbf->control_ts,
Pau Espin Pedrol16e16782021-03-29 19:10:19 +0200717 &ulreq, get_poll_fn(tbf, tbf->control_ts));
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200718}
719
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100720static void send_empty_block(gprs_rlcmac_tbf *tbf, struct gprs_rlcmac_pdch *pdch, unsigned fn)
Pau Espin Pedrol99360a32021-03-09 17:18:12 +0100721{
Pau Espin Pedrol99360a32021-03-09 17:18:12 +0100722 send_ul_mac_block_buf(tbf->bts, pdch, fn, NULL, 0);
723}
724
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100725static gprs_rlcmac_ul_tbf *puan_urbb_len_issue(struct gprs_rlcmac_bts *bts,
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100726 struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta,
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530727 uint8_t ms_class, uint8_t egprs_ms_class)
728{
729 GprsMs *ms;
730 uint32_t rach_fn = *fn - 51;
731 uint32_t sba_fn = *fn + 52;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +0100732 int tfi = 0;
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530733 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530734 RlcMacUplink_t ulreq = {0};
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530735 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530736
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530737 /* needed to set last_rts_fn in the PDCH object */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100738 request_dl_rlc_block(bts, pdch, fn);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530739
740 /*
741 * simulate RACH, this sends an Immediate
742 * Assignment Uplink on the AGCH
743 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100744 bts_handle_rach(bts, 0x73, rach_fn, qta);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530745
746 /* get next free TFI */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100747 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &pdch->trx->trx_no, -1);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530748
749 /* fake a resource request */
750 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
751 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
752 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
753 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100754 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
755 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530756 Count_MS_RA_capability_value = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100757 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530758 MS_RA_capability_value[0].u.Content.
759 Exist_Multislot_capability = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100760 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530761 MS_RA_capability_value[0].u.Content.Multislot_capability.
762 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100763 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530764 MS_RA_capability_value[0].u.Content.Multislot_capability.
765 GPRS_multislot_class = ms_class;
766 if (egprs_ms_class) {
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100767 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530768 MS_RA_capability_value[0].u.Content.
769 Multislot_capability.Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100770 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530771 MS_RA_capability_value[0].u.Content.
772 Multislot_capability.EGPRS_multislot_class = ms_class;
773 }
774
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100775 send_ul_mac_block(bts, pdch, &ulreq, sba_fn);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530776
777 /* check the TBF */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100778 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, pdch->trx->trx_no, pdch->ts_no);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530779 OSMO_ASSERT(ul_tbf);
780 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
781
782 /* send packet uplink assignment */
783 *fn = sba_fn;
784 request_dl_rlc_block(ul_tbf, fn);
785
786 /* send real acknowledgement */
787 send_control_ack(ul_tbf);
788
789 check_tbf(ul_tbf);
790 /* send fake data */
791 uint8_t data_msg[42] = {
792 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
Neels Hofmeyrd34646a2017-02-08 17:07:40 +0100793 (uint8_t)(tfi << 1),
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530794 1, /* BSN:7, E:1 */
795 };
796
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530797 pdch->rcv_block(&data_msg[0], 23, *fn, &meas);
798
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +0200799 ms = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530800 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100801 OSMO_ASSERT(ms_ta(ms) == qta/4);
802 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530803
804 /*
805 * TS 44.060, B.8.1
806 * first seg received first, later second seg
807 */
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530808 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
809 egprs3->si = 0;
810 egprs3->r = 1;
811 egprs3->cv = 7;
812 egprs3->tfi_hi = tfi & 0x03;
813 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
814 egprs3->bsn1_hi = 1;
815 egprs3->bsn1_lo = 0;
816 egprs3->cps_hi = 1;
817 data_msg[3] = 0xff;
818 egprs3->pi = 0;
819 egprs3->cps_lo = 1;
820 egprs3->rsb = 0;
821 egprs3->spb = 0;
822 egprs3->pi = 0;
823
824 pdch->rcv_block(data_msg, 42, *fn, &meas);
825
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +0200826 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 +0100827 struct msgb *msg1 = tbf_ul_ack_create_rlcmac_msg(ul_tbf, pdch, *fn);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530828
Pau Espin Pedrolc432e062021-05-11 13:17:31 +0200829 static uint8_t exp1[] = { 0x40, 0x24, 0x01, 0x0b, 0x3e, 0x24, 0x46, 0x68, 0x9c, 0x70, 0x87, 0xb0,
830 0x06, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b
Maxd3a0d912019-03-05 16:15:01 +0100831 };
832
833 if (!msgb_eq_data_print(msg1, exp1, GSM_MACBLOCK_LEN)) {
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200834 fprintf(stderr, "%s test failed on 1st segment!\n", __func__);
Maxd3a0d912019-03-05 16:15:01 +0100835 return NULL;
836 }
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530837
838 egprs3->si = 0;
839 egprs3->r = 1;
840 egprs3->cv = 7;
841 egprs3->tfi_hi = tfi & 0x03;
842 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
843 egprs3->bsn1_hi = 4;
844 egprs3->bsn1_lo = 0;
845 egprs3->cps_hi = 1;
846 data_msg[3] = 0xff;
847 egprs3->pi = 0;
848 egprs3->cps_lo = 1;
849 egprs3->rsb = 0;
850 egprs3->spb = 0;
851
852 pdch->rcv_block(data_msg, 42, *fn, &meas);
853
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +0200854 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 +0100855 msg1 = tbf_ul_ack_create_rlcmac_msg(ul_tbf, pdch, *fn);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530856
Pau Espin Pedrolc432e062021-05-11 13:17:31 +0200857 static uint8_t exp2[] = { 0x40, 0x24, 0x01, 0x0b, 0x3e, 0x24, 0x46, 0x68, 0x9c, 0x70, 0x88, 0xb0,
858 0x06, 0x8b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b
Maxd3a0d912019-03-05 16:15:01 +0100859 };
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530860
Maxd3a0d912019-03-05 16:15:01 +0100861 if (!msgb_eq_data_print(msg1, exp2, GSM_MACBLOCK_LEN)) {
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200862 fprintf(stderr, "%s test failed on 2nd segment!\n", __func__);
Maxd3a0d912019-03-05 16:15:01 +0100863 return NULL;
864 }
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530865 return ul_tbf;
866}
867
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100868static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(struct gprs_rlcmac_bts *bts,
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100869 struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta,
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530870 uint8_t ms_class, uint8_t egprs_ms_class)
871{
872 GprsMs *ms;
873 uint32_t rach_fn = *fn - 51;
874 uint32_t sba_fn = *fn + 52;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530875 int tfi = 0, i = 0;
876 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530877 RlcMacUplink_t ulreq = {0};
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530878 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530879
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530880 /* needed to set last_rts_fn in the PDCH object */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100881 request_dl_rlc_block(bts, pdch, fn);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530882
883 /*
884 * simulate RACH, this sends an Immediate
885 * Assignment Uplink on the AGCH
886 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100887 bts_handle_rach(bts, 0x73, rach_fn, qta);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530888
889 /* get next free TFI */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100890 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &pdch->trx->trx_no, -1);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530891
892 /* fake a resource request */
893 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
894 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
895 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
896 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100897 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
898 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530899 Count_MS_RA_capability_value = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100900 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530901 MS_RA_capability_value[0].u.Content.
902 Exist_Multislot_capability = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100903 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530904 MS_RA_capability_value[0].u.Content.Multislot_capability.
905 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100906 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530907 MS_RA_capability_value[0].u.Content.Multislot_capability.
908 GPRS_multislot_class = ms_class;
909 if (egprs_ms_class) {
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100910 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530911 MS_RA_capability_value[0].u.Content.
912 Multislot_capability.Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100913 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530914 MS_RA_capability_value[0].u.Content.
915 Multislot_capability.EGPRS_multislot_class = ms_class;
916 }
917
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100918 send_ul_mac_block(bts, pdch, &ulreq, sba_fn);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530919
920 /* check the TBF */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +0100921 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, pdch->trx->trx_no, pdch->ts_no);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530922 OSMO_ASSERT(ul_tbf != NULL);
923 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
924
925 /* send packet uplink assignment */
926 *fn = sba_fn;
927 request_dl_rlc_block(ul_tbf, fn);
928
929 /* send real acknowledgement */
930 send_control_ack(ul_tbf);
931
932 check_tbf(ul_tbf);
933
934 /* send fake data */
935 uint8_t data_msg[42] = {
936 0x00 | 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
937 uint8_t(0 | (tfi << 1)),
938 uint8_t(1), /* BSN:7, E:1 */
939 };
940
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530941 pdch->rcv_block(&data_msg[0], 23, *fn, &meas);
942
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +0200943 ms = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530944 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100945 OSMO_ASSERT(ms_ta(ms) == qta/4);
946 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530947
948 /*
949 * TS 44.060, B.8.1
950 * first seg received first, later second seg
951 */
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530952 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
953 egprs3->si = 1;
954 egprs3->r = 1;
955 egprs3->cv = 7;
956 egprs3->tfi_hi = tfi & 0x03;
957 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
958 egprs3->bsn1_hi = 1;
959 egprs3->bsn1_lo = 0;
960 egprs3->cps_hi = 1;
961 data_msg[3] = 0xff;
962 egprs3->pi = 0;
963 egprs3->cps_lo = 1;
964 egprs3->rsb = 0;
965 egprs3->spb = 2;
966 egprs3->pi = 0;
967
968 pdch->rcv_block(data_msg, 42, *fn, &meas);
969
970 struct gprs_rlc_data *block = ul_tbf->m_rlc.block(1);
971
972 /* check the status of the block */
973 OSMO_ASSERT(block->spb_status.block_status_ul ==
974 EGPRS_RESEG_FIRST_SEG_RXD);
975
976 egprs3->si = 1;
977 egprs3->r = 1;
978 egprs3->cv = 7;
979 egprs3->tfi_hi = tfi & 0x03;
980 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
981 egprs3->bsn1_hi = 1;
982 egprs3->bsn1_lo = 0;
983 egprs3->cps_hi = 1;
984 data_msg[3] = 0xff;
985 egprs3->pi = 0;
986 egprs3->cps_lo = 1;
987 egprs3->rsb = 0;
988 egprs3->spb = 3;
989
990 pdch->rcv_block(data_msg, 42, *fn, &meas);
991
992 /* check the status of the block */
993 OSMO_ASSERT(block->spb_status.block_status_ul ==
994 EGPRS_RESEG_DEFAULT);
995 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +0100996 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530997 /* Assembled MCS is MCS6. so the size is 74 */
998 OSMO_ASSERT(block->len == 74);
999
1000 /*
1001 * TS 44.060, B.8.1
1002 * second seg first, later first seg
1003 */
1004 memset(data_msg, 0, sizeof(data_msg));
1005
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301006 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1007 egprs3->si = 1;
1008 egprs3->r = 1;
1009 egprs3->cv = 7;
1010 egprs3->tfi_hi = tfi & 0x03;
1011 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1012 egprs3->bsn1_hi = 2;
1013 egprs3->bsn1_lo = 0;
1014 egprs3->cps_hi = 1;
1015 data_msg[3] = 0xff;
1016 egprs3->pi = 0;
1017 egprs3->cps_lo = 1;
1018 egprs3->rsb = 0;
1019 egprs3->spb = 3;
1020 egprs3->pi = 0;
1021
1022 pdch->rcv_block(data_msg, 42, *fn, &meas);
1023
1024 block = ul_tbf->m_rlc.block(2);
1025 /* check the status of the block */
1026 OSMO_ASSERT(block->spb_status.block_status_ul ==
1027 EGPRS_RESEG_SECOND_SEG_RXD);
1028
1029 egprs3->si = 1;
1030 egprs3->r = 1;
1031 egprs3->cv = 7;
1032 egprs3->tfi_hi = tfi & 0x03;
1033 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1034 egprs3->bsn1_hi = 2;
1035 egprs3->bsn1_lo = 0;
1036 egprs3->cps_hi = 1;
1037 data_msg[3] = 0xff;
1038 egprs3->pi = 0;
1039 egprs3->cps_lo = 1;
1040 egprs3->rsb = 0;
1041 egprs3->spb = 2;
1042 egprs3->pi = 0;
1043
1044 pdch->rcv_block(data_msg, 42, *fn, &meas);
1045
1046 /* check the status of the block */
1047 OSMO_ASSERT(block->spb_status.block_status_ul ==
1048 EGPRS_RESEG_DEFAULT);
1049 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001050 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301051 /* Assembled MCS is MCS6. so the size is 74 */
1052 OSMO_ASSERT(block->len == 74);
1053
1054 /*
1055 * TS 44.060, B.8.1
1056 * Error scenario with spb as 1
1057 */
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301058 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1059 egprs3->si = 1;
1060 egprs3->r = 1;
1061 egprs3->cv = 7;
1062 egprs3->tfi_hi = tfi & 0x03;
1063 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1064 egprs3->bsn1_hi = 3;
1065 egprs3->bsn1_lo = 0;
1066 egprs3->cps_hi = 1;
1067 data_msg[3] = 0xff;
1068 egprs3->pi = 0;
1069 egprs3->cps_lo = 1;
1070 egprs3->rsb = 0;
1071 egprs3->spb = 1;
1072 egprs3->pi = 0;
1073
1074 pdch->rcv_block(data_msg, 42, *fn, &meas);
1075
1076 block = ul_tbf->m_rlc.block(3);
1077 /* check the status of the block */
1078 OSMO_ASSERT(block->spb_status.block_status_ul ==
1079 EGPRS_RESEG_DEFAULT);
1080 /*
1081 * TS 44.060, B.8.1
1082 * comparison of rlc_data for multiple scenarios
1083 * Receive First, the second(BSN 3)
1084 * Receive First, First then Second(BSN 4)
1085 * Receive Second then First(BSN 5)
1086 * after above 3 scenarios are triggered,
1087 * rlc_data of all 3 BSN are compared
1088 */
1089
1090 /* Initialize the data_msg */
1091 for (i = 0; i < 42; i++)
1092 data_msg[i] = i;
1093
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301094 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1095 egprs3->si = 1;
1096 egprs3->r = 1;
1097 egprs3->cv = 7;
1098 egprs3->tfi_hi = tfi & 0x03;
1099 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1100 egprs3->bsn1_hi = 3;
1101 egprs3->bsn1_lo = 0;
1102 egprs3->cps_hi = 1;
1103 data_msg[3] = 0xff;
1104 egprs3->pi = 0;
1105 egprs3->cps_lo = 1;
1106 egprs3->rsb = 0;
1107 egprs3->spb = 2;
1108 egprs3->pi = 0;
1109
1110 pdch->rcv_block(data_msg, 42, *fn, &meas);
1111
1112 block = ul_tbf->m_rlc.block(3);
1113 /* check the status of the block */
1114 OSMO_ASSERT(block->spb_status.block_status_ul ==
1115 EGPRS_RESEG_FIRST_SEG_RXD);
1116
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301117 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1118 egprs3->si = 1;
1119 egprs3->r = 1;
1120 egprs3->cv = 7;
1121 egprs3->tfi_hi = tfi & 0x03;
1122 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1123 egprs3->bsn1_hi = 3;
1124 egprs3->bsn1_lo = 0;
1125 egprs3->cps_hi = 1;
1126 data_msg[3] = 0xff;
1127 egprs3->pi = 0;
1128 egprs3->cps_lo = 1;
1129 egprs3->rsb = 0;
1130 egprs3->spb = 3;
1131 egprs3->pi = 0;
1132
1133 pdch->rcv_block(data_msg, 42, *fn, &meas);
1134
1135 block = ul_tbf->m_rlc.block(3);
1136 /* check the status of the block */
1137 OSMO_ASSERT(block->spb_status.block_status_ul ==
1138 EGPRS_RESEG_DEFAULT);
1139 /* Assembled MCS is MCS6. so the size is 74 */
1140 OSMO_ASSERT(block->len == 74);
1141 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001142 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301143
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301144 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1145 egprs3->si = 1;
1146 egprs3->r = 1;
1147 egprs3->cv = 7;
1148 egprs3->tfi_hi = tfi & 0x03;
1149 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1150 egprs3->bsn1_hi = 4;
1151 egprs3->bsn1_lo = 0;
1152 egprs3->cps_hi = 1;
1153 data_msg[3] = 0xff;
1154 egprs3->pi = 0;
1155 egprs3->cps_lo = 1;
1156 egprs3->rsb = 0;
1157 egprs3->spb = 2;
1158 egprs3->pi = 0;
1159
1160 pdch->rcv_block(data_msg, 42, *fn, &meas);
1161
1162 block = ul_tbf->m_rlc.block(4);
1163 /* check the status of the block */
1164 OSMO_ASSERT(block->spb_status.block_status_ul ==
1165 EGPRS_RESEG_FIRST_SEG_RXD);
1166
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301167 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1168 egprs3->si = 1;
1169 egprs3->r = 1;
1170 egprs3->cv = 7;
1171 egprs3->tfi_hi = tfi & 0x03;
1172 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1173 egprs3->bsn1_hi = 4;
1174 egprs3->bsn1_lo = 0;
1175 egprs3->cps_hi = 1;
1176 data_msg[3] = 0xff;
1177 egprs3->pi = 0;
1178 egprs3->cps_lo = 1;
1179 egprs3->rsb = 0;
1180 egprs3->spb = 2;
1181 egprs3->pi = 0;
1182
1183 pdch->rcv_block(data_msg, 42, *fn, &meas);
1184
1185 block = ul_tbf->m_rlc.block(4);
1186 /* check the status of the block */
1187 OSMO_ASSERT(block->spb_status.block_status_ul ==
1188 EGPRS_RESEG_FIRST_SEG_RXD);
1189
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301190 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1191 egprs3->si = 1;
1192 egprs3->r = 1;
1193 egprs3->cv = 7;
1194 egprs3->tfi_hi = tfi & 0x03;
1195 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1196 egprs3->bsn1_hi = 4;
1197 egprs3->bsn1_lo = 0;
1198 egprs3->cps_hi = 1;
1199 data_msg[3] = 0xff;
1200 egprs3->pi = 0;
1201 egprs3->cps_lo = 1;
1202 egprs3->rsb = 0;
1203 egprs3->spb = 3;
1204 egprs3->pi = 0;
1205
1206 pdch->rcv_block(data_msg, 42, *fn, &meas);
1207
1208 block = ul_tbf->m_rlc.block(4);
1209 /* check the status of the block */
1210 OSMO_ASSERT(block->spb_status.block_status_ul ==
1211 EGPRS_RESEG_DEFAULT);
1212 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001213 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301214 /* Assembled MCS is MCS6. so the size is 74 */
1215 OSMO_ASSERT(block->len == 74);
1216
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301217 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1218 egprs3->si = 1;
1219 egprs3->r = 1;
1220 egprs3->cv = 7;
1221 egprs3->tfi_hi = tfi & 0x03;
1222 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1223 egprs3->bsn1_hi = 5;
1224 egprs3->bsn1_lo = 0;
1225 egprs3->cps_hi = 1;
1226 data_msg[3] = 0xff;
1227 egprs3->pi = 0;
1228 egprs3->cps_lo = 1;
1229 egprs3->rsb = 0;
1230 egprs3->spb = 3;
1231 egprs3->pi = 0;
1232
1233 pdch->rcv_block(data_msg, 42, *fn, &meas);
1234
1235 block = ul_tbf->m_rlc.block(5);
1236 /* check the status of the block */
1237 OSMO_ASSERT(block->spb_status.block_status_ul ==
1238 EGPRS_RESEG_SECOND_SEG_RXD);
1239
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301240 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1241 egprs3->si = 1;
1242 egprs3->r = 1;
1243 egprs3->cv = 7;
1244 egprs3->tfi_hi = tfi & 0x03;
1245 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1246 egprs3->bsn1_hi = 5;
1247 egprs3->bsn1_lo = 0;
1248 egprs3->cps_hi = 1;
1249 data_msg[3] = 0xff;
1250 egprs3->pi = 0;
1251 egprs3->cps_lo = 1;
1252 egprs3->rsb = 0;
1253 egprs3->spb = 2;
1254 egprs3->pi = 0;
1255
1256 pdch->rcv_block(data_msg, 42, *fn, &meas);
1257
1258 block = ul_tbf->m_rlc.block(5);
1259
1260 /* check the status of the block */
1261 OSMO_ASSERT(block->spb_status.block_status_ul ==
1262 EGPRS_RESEG_DEFAULT);
1263 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001264 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301265 /* Assembled MCS is MCS6. so the size is 74 */
1266 OSMO_ASSERT(block->len == 74);
1267
1268 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->len ==
1269 ul_tbf->m_rlc.block(4)->len);
1270 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->len ==
1271 ul_tbf->m_rlc.block(3)->len);
1272
1273 /* Compare the spb status of each BSNs(3,4,5). should be same */
1274 OSMO_ASSERT(
1275 ul_tbf->m_rlc.block(5)->spb_status.block_status_ul ==
1276 ul_tbf->m_rlc.block(4)->spb_status.block_status_ul);
1277 OSMO_ASSERT(
1278 ul_tbf->m_rlc.block(5)->spb_status.block_status_ul ==
1279 ul_tbf->m_rlc.block(3)->spb_status.block_status_ul);
1280
1281 /* Compare the Assembled MCS of each BSNs(3,4,5). should be same */
1282 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->cs_last ==
1283 ul_tbf->m_rlc.block(4)->cs_last);
1284 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->cs_last ==
1285 ul_tbf->m_rlc.block(3)->cs_last);
1286
1287 /* Compare the data of each BSNs(3,4,5). should be same */
1288 OSMO_ASSERT(
1289 !memcmp(ul_tbf->m_rlc.block(5)->block,
1290 ul_tbf->m_rlc.block(4)->block, ul_tbf->m_rlc.block(5)->len
1291 ));
1292 OSMO_ASSERT(
1293 !memcmp(ul_tbf->m_rlc.block(5)->block,
1294 ul_tbf->m_rlc.block(3)->block, ul_tbf->m_rlc.block(5)->len
1295 ));
1296
1297 return ul_tbf;
1298}
1299
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001300static gprs_rlcmac_ul_tbf *establish_ul_tbf(struct gprs_rlcmac_bts *bts,
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001301 struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta,
sivasankari1d8744c2017-01-24 15:53:35 +05301302 uint8_t ms_class, uint8_t egprs_ms_class)
1303{
sivasankari1d8744c2017-01-24 15:53:35 +05301304 uint32_t rach_fn = *fn - 51;
1305 uint32_t sba_fn = *fn + 52;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001306 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301307 gprs_rlcmac_ul_tbf *ul_tbf;
sivasankari1d8744c2017-01-24 15:53:35 +05301308 RlcMacUplink_t ulreq = {0};
sivasankari1d8744c2017-01-24 15:53:35 +05301309
sivasankari1d8744c2017-01-24 15:53:35 +05301310 /* needed to set last_rts_fn in the PDCH object */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001311 request_dl_rlc_block(bts, pdch, fn);
sivasankari1d8744c2017-01-24 15:53:35 +05301312
1313 /*
1314 * simulate RACH, this sends an Immediate
1315 * Assignment Uplink on the AGCH
1316 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001317 bts_handle_rach(bts, 0x73, rach_fn, qta);
sivasankari1d8744c2017-01-24 15:53:35 +05301318
1319 /* get next free TFI */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001320 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &pdch->trx->trx_no, -1);
sivasankari1d8744c2017-01-24 15:53:35 +05301321
1322 /* fake a resource request */
1323 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
1324 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
1325 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
1326 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001327 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
1328 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301329 Count_MS_RA_capability_value = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001330 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301331 MS_RA_capability_value[0].u.Content.
1332 Exist_Multislot_capability = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001333 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301334 MS_RA_capability_value[0].u.Content.Multislot_capability.
1335 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001336 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301337 MS_RA_capability_value[0].u.Content.Multislot_capability.
1338 GPRS_multislot_class = ms_class;
1339 if (egprs_ms_class) {
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001340 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301341 MS_RA_capability_value[0].u.Content.
1342 Multislot_capability.Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001343 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301344 MS_RA_capability_value[0].u.Content.
1345 Multislot_capability.EGPRS_multislot_class = ms_class;
1346 }
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001347 send_ul_mac_block(bts, pdch, &ulreq, sba_fn);
sivasankari1d8744c2017-01-24 15:53:35 +05301348
1349 /* check the TBF */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001350 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, pdch->trx->trx_no, pdch->ts_no);
sivasankari1d8744c2017-01-24 15:53:35 +05301351 /* send packet uplink assignment */
1352 *fn = sba_fn;
1353 request_dl_rlc_block(ul_tbf, fn);
1354
1355 /* send real acknowledgement */
1356 send_control_ack(ul_tbf);
1357
1358 check_tbf(ul_tbf);
1359
1360 return ul_tbf;
1361}
1362
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001363static 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 +01001364 struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta,
sivasankari1d8744c2017-01-24 15:53:35 +05301365 uint8_t ms_class, uint8_t egprs_ms_class, gprs_rlcmac_ul_tbf *ul_tbf)
1366{
1367 OSMO_ASSERT(ul_tbf);
1368 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1369 GprsMs *ms;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001370 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301371
1372 /* send fake data with cv=0*/
1373 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1374 uint8_t data[49] = {0};
1375
1376 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1377
1378 /*header_construction */
1379 memset(data, 0x2b, sizeof(data));
1380 /* Message with CRBB */
1381 for (int i = 0 ; i < 80; i++) {
1382 hdr3->r = 0;
1383 hdr3->si = 0;
1384 hdr3->cv = 10;
1385 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1386 hdr3->tfi_lo = tfi & 0x7;
1387 hdr3->bsn1_hi = ((i * 2)&0x1f);
1388 hdr3->bsn1_lo = ((i * 2)/32);
1389 hdr3->cps_hi = 0;
1390 hdr3->cps_lo = 0;
1391 hdr3->spb = 0;
1392 hdr3->rsb = 0;
1393 hdr3->pi = 0;
1394 hdr3->spare = 0;
1395 hdr3->dummy = 1;
1396 data[4] = 0x0;
1397 data[5] = 0x0;
1398 data[6] = 0x2b;
1399 data[7] = 0x2b;
sivasankari1d8744c2017-01-24 15:53:35 +05301400 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1401 }
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +02001402 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 +01001403 tbf_ul_ack_create_rlcmac_msg(ul_tbf, pdch, *fn);
sivasankari1d8744c2017-01-24 15:53:35 +05301404 memset(data, 0x2b, sizeof(data));
1405 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1406 hdr3->r = 0;
1407 hdr3->si = 0;
1408 hdr3->cv = 0;
1409 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1410 hdr3->tfi_lo = tfi & 0x7;
1411 hdr3->bsn1_hi = 0;
1412 hdr3->bsn1_lo = 2;
1413 hdr3->cps_hi = 0;
1414 hdr3->cps_lo = 0;
1415 hdr3->spb = 0;
1416 hdr3->rsb = 0;
1417 hdr3->pi = 0;
1418 hdr3->spare = 0;
1419 hdr3->dummy = 1;
1420 data[4] = 0x0;
1421 data[5] = 0x2b;
1422 data[6] = 0x2b;
1423 data[7] = 0x2b;
1424
sivasankari1d8744c2017-01-24 15:53:35 +05301425 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1426
1427 request_dl_rlc_block(ul_tbf, fn);
1428
1429 check_tbf(ul_tbf);
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +02001430 OSMO_ASSERT(tbf_ul_ack_fi(ul_tbf)->state == TBF_UL_ACK_ST_NONE);
sivasankari1d8744c2017-01-24 15:53:35 +05301431
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02001432 ms = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
sivasankari1d8744c2017-01-24 15:53:35 +05301433 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001434 OSMO_ASSERT(ms_ta(ms) == qta/4);
1435 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
sivasankari1d8744c2017-01-24 15:53:35 +05301436
1437 return ul_tbf;
1438}
1439
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001440static 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 +01001441 struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta,
sivasankari1d8744c2017-01-24 15:53:35 +05301442 uint8_t ms_class, uint8_t egprs_ms_class, gprs_rlcmac_ul_tbf *ul_tbf)
1443{
1444 OSMO_ASSERT(ul_tbf);
1445 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1446 GprsMs *ms;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001447 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301448
1449 check_tbf(ul_tbf);
1450 /* send fake data with cv=0*/
1451 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1452 uint8_t data[49] = {0};
1453
1454 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1455
1456 /*header_construction */
1457 memset(data, 0x2b, sizeof(data));
1458
1459 /* Message with URBB & URBB length */
1460 for (int i = 0 ; i < 20; i++) {
1461 hdr3->r = 0;
1462 hdr3->si = 0;
1463 hdr3->cv = 10;
1464 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1465 hdr3->tfi_lo = tfi & 0x7;
1466 hdr3->bsn1_hi = ((i * 2)&0x1f);
1467 hdr3->bsn1_lo = ((i * 2)/32);
1468 hdr3->cps_hi = 0;
1469 hdr3->cps_lo = 0;
1470 hdr3->spb = 0;
1471 hdr3->rsb = 0;
1472 hdr3->pi = 0;
1473 hdr3->spare = 0;
1474 hdr3->dummy = 1;
1475 data[4] = 0x0;
1476 data[5] = 0x0;
1477 data[6] = 0x2b;
1478 data[7] = 0x2b;
sivasankari1d8744c2017-01-24 15:53:35 +05301479 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1480 }
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +02001481 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 +01001482 tbf_ul_ack_create_rlcmac_msg(ul_tbf, pdch, *fn);
sivasankari1d8744c2017-01-24 15:53:35 +05301483 memset(data, 0x2b, sizeof(data));
1484 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1485 hdr3->r = 0;
1486 hdr3->si = 0;
1487 hdr3->cv = 0;
1488 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1489 hdr3->tfi_lo = tfi & 0x7;
1490 hdr3->bsn1_hi = 0;
1491 hdr3->bsn1_lo = 2;
1492 hdr3->cps_hi = 0;
1493 hdr3->cps_lo = 0;
1494 hdr3->spb = 0;
1495 hdr3->rsb = 0;
1496 hdr3->pi = 0;
1497 hdr3->spare = 0;
1498 hdr3->dummy = 1;
1499 data[4] = 0x0;
1500 data[5] = 0x2b;
1501 data[6] = 0x2b;
1502 data[7] = 0x2b;
1503
sivasankari1d8744c2017-01-24 15:53:35 +05301504 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +02001505 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 +01001506 tbf_ul_ack_create_rlcmac_msg(ul_tbf, pdch, *fn);
sivasankari1d8744c2017-01-24 15:53:35 +05301507
1508 request_dl_rlc_block(ul_tbf, fn);
1509
1510 check_tbf(ul_tbf);
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +02001511 OSMO_ASSERT(tbf_ul_ack_fi(ul_tbf)->state == TBF_UL_ACK_ST_NONE);
sivasankari1d8744c2017-01-24 15:53:35 +05301512
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02001513 ms = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
sivasankari1d8744c2017-01-24 15:53:35 +05301514 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001515 OSMO_ASSERT(ms_ta(ms) == qta/4);
1516 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
sivasankari1d8744c2017-01-24 15:53:35 +05301517
1518 return ul_tbf;
1519}
1520
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001521static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_CRBB(struct gprs_rlcmac_bts *bts,
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001522 struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta,
sivasankari1d8744c2017-01-24 15:53:35 +05301523 uint8_t ms_class, uint8_t egprs_ms_class)
1524{
1525 GprsMs *ms;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001526 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301527 gprs_rlcmac_ul_tbf *ul_tbf;
sivasankari1d8744c2017-01-24 15:53:35 +05301528
1529 /* check the TBF */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001530 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, pdch->trx->trx_no, pdch->ts_no);
sivasankari1d8744c2017-01-24 15:53:35 +05301531 OSMO_ASSERT(ul_tbf);
1532 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1533
1534 /* send fake data with cv=0*/
1535 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1536 uint8_t data[49] = {0};
1537
1538 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1539
1540 /*header_construction */
1541 memset(data, 0x2b, sizeof(data));
1542
1543 /* Message with CRBB */
1544 for (int i = 80 ; i < 160; i++) {
1545 hdr3->r = 0;
1546 hdr3->si = 0;
1547 hdr3->cv = 10;
1548 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1549 hdr3->tfi_lo = tfi & 0x7;
1550 hdr3->bsn1_hi = ((i)&0x1f);
1551 hdr3->bsn1_lo = ((i)/32);
1552 hdr3->cps_hi = 0;
1553 hdr3->cps_lo = 0;
1554 hdr3->spb = 0;
1555 hdr3->rsb = 0;
1556 hdr3->pi = 0;
1557 hdr3->spare = 0;
1558 hdr3->dummy = 1;
1559 data[4] = 0x0;
1560 data[5] = 0x0;
1561 data[6] = 0x2b;
1562 data[7] = 0x2b;
sivasankari1d8744c2017-01-24 15:53:35 +05301563 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1564 }
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +02001565 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 +01001566 tbf_ul_ack_create_rlcmac_msg(ul_tbf, pdch, *fn);
sivasankari1d8744c2017-01-24 15:53:35 +05301567 memset(data, 0x2b, sizeof(data));
1568 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1569 hdr3->r = 0;
1570 hdr3->si = 0;
1571 hdr3->cv = 0;
1572 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1573 hdr3->tfi_lo = tfi & 0x7;
1574 hdr3->bsn1_hi = 0;
1575 hdr3->bsn1_lo = 2;
1576 hdr3->cps_hi = 0;
1577 hdr3->cps_lo = 0;
1578 hdr3->spb = 0;
1579 hdr3->rsb = 0;
1580 hdr3->pi = 0;
1581 hdr3->spare = 0;
1582 hdr3->dummy = 1;
1583 data[4] = 0x0;
1584 data[5] = 0x2b;
1585 data[6] = 0x2b;
1586 data[7] = 0x2b;
1587
sivasankari1d8744c2017-01-24 15:53:35 +05301588 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1589
1590 request_dl_rlc_block(ul_tbf, fn);
1591
1592 check_tbf(ul_tbf);
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +02001593 OSMO_ASSERT(tbf_ul_ack_fi(ul_tbf)->state == TBF_UL_ACK_ST_NONE);
sivasankari1d8744c2017-01-24 15:53:35 +05301594
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02001595 ms = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
sivasankari1d8744c2017-01-24 15:53:35 +05301596 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001597 OSMO_ASSERT(ms_ta(ms) == qta/4);
1598 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
sivasankari1d8744c2017-01-24 15:53:35 +05301599
1600 return ul_tbf;
1601}
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001602static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase(struct gprs_rlcmac_bts *bts,
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001603 struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001604 uint8_t ms_class, uint8_t egprs_ms_class)
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001605{
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001606 GprsMs *ms;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001607 uint32_t rach_fn = *fn - 51;
1608 uint32_t sba_fn = *fn + 52;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001609 int tfi = 0;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001610 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001611 RlcMacUplink_t ulreq = {0};
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001612
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001613 /* needed to set last_rts_fn in the PDCH object */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001614 request_dl_rlc_block(bts, pdch, fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001615
bhargava959d1de2016-08-17 15:17:21 +05301616 /* simulate RACH, sends an Immediate Assignment Uplink on the AGCH */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001617 bts_handle_rach(bts, 0x73, rach_fn, qta);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001618
1619 /* get next free TFI */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001620 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &pdch->trx->trx_no, -1);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001621
1622 /* fake a resource request */
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001623 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
1624 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
1625 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
1626 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001627 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
1628 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001629 Count_MS_RA_capability_value = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001630 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001631 MS_RA_capability_value[0].u.Content.Exist_Multislot_capability = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001632 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001633 MS_RA_capability_value[0].u.Content.Multislot_capability.
1634 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001635 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001636 MS_RA_capability_value[0].u.Content.Multislot_capability.
1637 GPRS_multislot_class = ms_class;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001638 if (egprs_ms_class) {
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001639 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001640 MS_RA_capability_value[0].u.Content.Multislot_capability.
1641 Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001642 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001643 MS_RA_capability_value[0].u.Content.Multislot_capability.
1644 EGPRS_multislot_class = ms_class;
1645 }
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001646
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001647 send_ul_mac_block(bts, pdch, &ulreq, sba_fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001648
1649 /* check the TBF */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001650 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, pdch->trx->trx_no, pdch->ts_no);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001651 OSMO_ASSERT(ul_tbf != NULL);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +02001652 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001653
1654 /* send packet uplink assignment */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001655 *fn = sba_fn;
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +02001656 request_dl_rlc_block(ul_tbf, fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001657
Jacob Erlbeckaf454732015-08-21 15:03:23 +02001658 /* send real acknowledgement */
1659 send_control_ack(ul_tbf);
1660
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001661 check_tbf(ul_tbf);
1662
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001663 /* send fake data */
1664 uint8_t data_msg[23] = {
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001665 0x00 | 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
1666 uint8_t(0 | (tfi << 1)),
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001667 uint8_t(1), /* BSN:7, E:1 */
1668 };
1669
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001670 pdch->rcv_block(&data_msg[0], sizeof(data_msg), *fn, &meas);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001671
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02001672 ms = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001673 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001674 OSMO_ASSERT(ms_ta(ms) == qta/4);
1675 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001676
1677 return ul_tbf;
1678}
1679
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001680static void send_dl_data(struct gprs_rlcmac_bts *bts, uint32_t tlli, const char *imsi,
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001681 const uint8_t *data, unsigned data_size)
1682{
1683 GprsMs *ms, *ms2;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001684
Pau Espin Pedroleb0a0522023-04-17 16:33:35 +02001685 ms = bts_get_ms(bts, tlli, GSM_RESERVED_TMSI, imsi);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001686
Pau Espin Pedrol8a35e642021-01-18 17:14:14 +01001687 dl_tbf_handle(bts, tlli, 0, imsi, 0, 0,
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001688 1000, data, data_size);
1689
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02001690 ms = bts_get_ms_by_imsi(bts, imsi);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001691 OSMO_ASSERT(ms != NULL);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001692
Pau Espin Pedrol5deac142021-11-12 18:01:50 +01001693 if (imsi[0] != '\0') {
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02001694 ms2 = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001695 OSMO_ASSERT(ms == ms2);
1696 }
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001697}
1698
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001699static void transmit_dl_data(struct gprs_rlcmac_bts *bts, uint32_t tlli, uint32_t *fn,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001700 uint8_t slots = 0xff)
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001701{
1702 gprs_rlcmac_dl_tbf *dl_tbf;
1703 GprsMs *ms;
1704 unsigned ts_no;
1705
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02001706 ms = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001707 OSMO_ASSERT(ms);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001708 dl_tbf = ms_dl_tbf(ms);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001709 OSMO_ASSERT(dl_tbf);
1710
1711 while (dl_tbf->have_data()) {
1712 uint8_t bn = fn2bn(*fn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001713 for (ts_no = 0 ; ts_no < 8; ts_no += 1) {
1714 if (!(slots & (1 << ts_no)))
1715 continue;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001716 gprs_rlcmac_rcv_rts_block(bts,
Max878bd1f2016-07-20 13:05:05 +02001717 dl_tbf->trx->trx_no, ts_no,
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001718 *fn, bn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001719 }
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001720 *fn = fn_add_blocks(*fn, 1);
1721 }
1722}
1723
Max4c112dc2018-02-01 16:49:23 +01001724static inline void print_ta_tlli(const gprs_rlcmac_ul_tbf *ul_tbf, bool print_ms)
1725{
1726 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
1727 if (print_ms)
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001728 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 +01001729}
1730
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001731static void test_tbf_single_phase()
1732{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02001733 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001734 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001735 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001736 int ts_no = 7;
Philippd935d882016-11-07 13:07:36 +01001737 uint32_t fn = DUMMY_FN; /* 17,25,9 */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001738 uint32_t tlli = 0xf1223344;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001739 const char *imsi = "0011223344";
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001740 uint16_t qta = 31;
1741 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001742
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001743 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001744
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001745 setup_bts(bts, ts_no);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001746 pdch = &bts->trx[0].pdch[ts_no];
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001747
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001748 ul_tbf = establish_ul_tbf_single_phase(bts, pdch, tlli, &fn, qta);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001749
Max4c112dc2018-02-01 16:49:23 +01001750 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001751 send_dl_data(bts, tlli, imsi, (const uint8_t *)"TEST", 4);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001752
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001753 fprintf(stderr, "=== end %s ===\n", __func__);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001754 TALLOC_FREE(the_pcu);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001755}
1756
Pau Espin Pedrol22b26d82022-10-26 15:44:14 +02001757static void test_tbf_single_phase2()
1758{
1759 the_pcu = prepare_pcu();
1760 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001761 struct gprs_rlcmac_pdch *pdch;
Pau Espin Pedrol22b26d82022-10-26 15:44:14 +02001762 int ts_no = 7;
1763 uint32_t fn = DUMMY_FN; /* 17,25,9 */
1764 uint32_t tlli = 0xf1223344;
1765 const char *imsi = "0011223344";
1766 uint16_t qta = 31;
1767 gprs_rlcmac_ul_tbf *ul_tbf;
1768
1769 fprintf(stderr, "=== start %s ===\n", __func__);
1770
1771 setup_bts(bts, ts_no);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001772 pdch = &bts->trx[0].pdch[ts_no];
Pau Espin Pedrol22b26d82022-10-26 15:44:14 +02001773
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001774 ul_tbf = establish_ul_tbf_single_phase(bts, pdch, tlli, &fn, qta);
Pau Espin Pedrol22b26d82022-10-26 15:44:14 +02001775
1776 print_ta_tlli(ul_tbf, true);
1777 /* PCU sends CTRL ACK/NCK with FINAL_ACK=1, hence TBF is not in state FINISHED */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001778 request_dl_rlc_block(bts, pdch, &fn);
Pau Espin Pedrol22b26d82022-10-26 15:44:14 +02001779 OSMO_ASSERT(ul_tbf->state_is(TBF_ST_FINISHED));
1780 /* Now data is sent but no DL TBF is created because MS is not reachable for DL Assignment */
1781 send_dl_data(bts, tlli, imsi, (const uint8_t *)"TEST", 4);
1782
1783 /* After MS CTRL ACKs the FINAL_ACK=1 then it releases the TBF and goes
1784 * to packet-idle mode. Hence PCU will trigger ImmAss(PktDlAss) on PCH. */
1785 send_control_ack(ul_tbf);
1786
1787 fprintf(stderr, "=== end %s ===\n", __func__);
1788 TALLOC_FREE(the_pcu);
1789}
1790
sivasankari1d8744c2017-01-24 15:53:35 +05301791static void test_tbf_egprs_two_phase_puan(void)
1792{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02001793 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001794 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
sivasankari1d8744c2017-01-24 15:53:35 +05301795 int ts_no = 7;
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001796 struct gprs_rlcmac_pdch *pdch;
sivasankari1d8744c2017-01-24 15:53:35 +05301797 uint32_t fn = 2654218;
1798 uint16_t qta = 31;
1799 uint32_t tlli = 0xf1223344;
1800 const char *imsi = "0011223344";
1801 uint8_t ms_class = 1;
sivasankari1d8744c2017-01-24 15:53:35 +05301802 uint8_t egprs_ms_class = 1;
1803 gprs_rlcmac_ul_tbf *ul_tbf;
sivasankari1d8744c2017-01-24 15:53:35 +05301804 uint8_t test_data[256];
1805
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001806 fprintf(stderr, "=== start %s ===\n", __func__);
sivasankari1d8744c2017-01-24 15:53:35 +05301807
1808 memset(test_data, 1, sizeof(test_data));
1809
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001810 setup_bts(bts, ts_no, 4);
1811 bts->initial_mcs_dl = 9;
Pau Espin Pedrol519d0712021-01-14 14:30:03 +01001812 the_pcu->vty.ws_base = 128;
1813 the_pcu->vty.ws_pdch = 64;
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001814 pdch = &bts->trx[0].pdch[ts_no];
sivasankari1d8744c2017-01-24 15:53:35 +05301815
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001816 ul_tbf = establish_ul_tbf(bts, pdch, tlli, &fn, qta, ms_class, egprs_ms_class);
sivasankari1d8744c2017-01-24 15:53:35 +05301817 /* Function to generate URBB with no length */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001818 ul_tbf = establish_ul_tbf_two_phase_puan_URBB_no_length(bts, pdch, tlli, &fn,
sivasankari1d8744c2017-01-24 15:53:35 +05301819 qta, ms_class, egprs_ms_class, ul_tbf);
1820
Max4c112dc2018-02-01 16:49:23 +01001821 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001822 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
sivasankari1d8744c2017-01-24 15:53:35 +05301823
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02001824 static_cast<gprs_rlc_ul_window *>(ul_tbf->window())->reset_state();
sivasankari1d8744c2017-01-24 15:53:35 +05301825 /* Function to generate URBB with length */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001826 ul_tbf = establish_ul_tbf_two_phase_puan_URBB_with_length(bts, pdch, tlli, &fn,
sivasankari1d8744c2017-01-24 15:53:35 +05301827 qta, ms_class, egprs_ms_class, ul_tbf);
1828
Max4c112dc2018-02-01 16:49:23 +01001829 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001830 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
sivasankari1d8744c2017-01-24 15:53:35 +05301831
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02001832 static_cast<gprs_rlc_ul_window *>(ul_tbf->window())->reset_state();
sivasankari1d8744c2017-01-24 15:53:35 +05301833 /* Function to generate CRBB */
Pau Espin Pedrol519d0712021-01-14 14:30:03 +01001834 the_pcu->vty.ws_base = 128;
1835 the_pcu->vty.ws_pdch = 64;
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001836 ul_tbf = establish_ul_tbf_two_phase_puan_CRBB(bts, pdch, tlli, &fn,
sivasankari1d8744c2017-01-24 15:53:35 +05301837 qta, ms_class, egprs_ms_class);
1838
Max4c112dc2018-02-01 16:49:23 +01001839 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001840 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
sivasankari1d8744c2017-01-24 15:53:35 +05301841
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001842 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001843 fprintf(stderr, "=== end %s ===\n", __func__);
sivasankari1d8744c2017-01-24 15:53:35 +05301844}
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301845/*
1846 * Trigger rach for single block
1847 */
1848static void test_immediate_assign_rej_single_block()
1849{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02001850 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001851 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301852 uint32_t fn = 2654218;
1853 uint16_t qta = 31;
1854 int ts_no = 7;
1855
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001856 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301857
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001858 setup_bts(bts, ts_no, 4);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301859
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001860 bts->trx[0].pdch[ts_no].disable();
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301861
1862 uint32_t rach_fn = fn - 51;
1863
1864 int rc = 0;
1865
1866 /*
1867 * simulate RACH, sends an Immediate Assignment
1868 * Uplink reject on the AGCH
1869 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001870 rc = bts_handle_rach(bts, 0x70, rach_fn, qta);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301871
Pau Espin Pedrol15c58ac2021-03-08 14:57:58 +01001872 OSMO_ASSERT(rc == -EBUSY);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301873
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001874 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001875 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301876}
1877
1878/*
1879 * Trigger rach till resources(USF) exhaust
1880 */
1881static void test_immediate_assign_rej_multi_block()
1882{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02001883 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001884 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301885 uint32_t fn = 2654218;
1886 uint16_t qta = 31;
1887 int ts_no = 7;
1888
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001889 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301890
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001891 setup_bts(bts, ts_no, 4);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301892
1893 uint32_t rach_fn = fn - 51;
1894
1895 int rc = 0;
1896
1897 /*
1898 * simulate RACH, sends an Immediate Assignment Uplink
1899 * reject on the AGCH
1900 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001901 rc = bts_handle_rach(bts, 0x78, rach_fn, qta);
1902 rc = bts_handle_rach(bts, 0x79, rach_fn, qta);
1903 rc = bts_handle_rach(bts, 0x7a, rach_fn, qta);
1904 rc = bts_handle_rach(bts, 0x7b, rach_fn, qta);
1905 rc = bts_handle_rach(bts, 0x7c, rach_fn, qta);
1906 rc = bts_handle_rach(bts, 0x7d, rach_fn, qta);
1907 rc = bts_handle_rach(bts, 0x7e, rach_fn, qta);
1908 rc = bts_handle_rach(bts, 0x7f, rach_fn, qta);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301909
1910 OSMO_ASSERT(rc == -EBUSY);
1911
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001912 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001913 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301914}
1915
1916static void test_immediate_assign_rej()
1917{
1918 test_immediate_assign_rej_multi_block();
1919 test_immediate_assign_rej_single_block();
1920}
1921
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001922static void test_tbf_two_phase()
1923{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02001924 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001925 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001926 int ts_no = 7;
1927 uint32_t fn = 2654218;
1928 uint16_t qta = 31;
1929 uint32_t tlli = 0xf1223344;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001930 const char *imsi = "0011223344";
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001931 uint8_t ms_class = 1;
1932 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001933
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001934 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001935
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001936 setup_bts(bts, ts_no, 4);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001937
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001938 ul_tbf = establish_ul_tbf_two_phase(bts, &bts->trx[0].pdch[ts_no],
1939 tlli, &fn, qta, ms_class, 0);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001940
Max4c112dc2018-02-01 16:49:23 +01001941 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001942 send_dl_data(bts, tlli, imsi, (const uint8_t *)"TEST", 4);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001943
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001944 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001945 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001946}
1947
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001948static inline void print_ms(GprsMs *ms, bool old)
Max4c112dc2018-02-01 16:49:23 +01001949{
1950 fprintf(stderr, "%s MS: TLLI = 0x%08x, TA = %d, IMSI = %s, LLC = %zu\n",
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001951 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 +01001952}
1953
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001954static void test_tbf_ra_update_rach()
1955{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02001956 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001957 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001958 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001959 int ts_no = 7;
1960 uint32_t fn = 2654218;
1961 uint16_t qta = 31;
1962 uint32_t tlli1 = 0xf1223344;
1963 uint32_t tlli2 = 0xf5667788;
1964 const char *imsi = "0011223344";
1965 uint8_t ms_class = 1;
1966 gprs_rlcmac_ul_tbf *ul_tbf;
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01001967 gprs_rlcmac_dl_tbf *dl_tbf;
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001968 GprsMs *ms, *ms1, *ms2;
1969
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001970 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001971
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001972 setup_bts(bts, ts_no, 4);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001973 pdch = &bts->trx[0].pdch[ts_no];
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001974
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01001975 ul_tbf = establish_ul_tbf_two_phase(bts, pdch, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001976 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001977
1978 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01001979 print_ta_tlli(ul_tbf, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001980
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001981 send_dl_data(bts, tlli1, imsi, (const uint8_t *)"RAU_ACCEPT", 10);
Max4c112dc2018-02-01 16:49:23 +01001982 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001983
Jacob Erlbeckaf454732015-08-21 15:03:23 +02001984 /* Send Packet Downlink Assignment to MS */
1985 request_dl_rlc_block(ul_tbf, &fn);
1986
1987 /* Ack it */
1988 send_control_ack(ul_tbf);
1989
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001990 /* Make sure the RAU Accept gets sent to the MS */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001991 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 1);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001992 transmit_dl_data(bts, tlli1, &fn);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001993 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001994
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01001995 dl_tbf = ms_dl_tbf(ms1);
1996 OSMO_ASSERT(dl_tbf);
Pau Espin Pedrol16e16782021-03-29 19:10:19 +02001997 fn = get_poll_fn(dl_tbf, dl_tbf->control_ts);
1998 send_empty_block(dl_tbf, dl_tbf->control_ts, fn);
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01001999 fn = fn_add_blocks(fn, 1);
2000
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002001 /* Now establish a new TBF for the RA UPDATE COMPLETE (new TLLI) */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002002 ul_tbf = establish_ul_tbf_two_phase(bts, pdch, tlli2, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002003 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002004
2005 ms2 = ul_tbf->ms();
2006
2007 /* The PCU cannot know yet, that both TBF belong to the same MS */
2008 OSMO_ASSERT(ms1 != ms2);
Max4c112dc2018-02-01 16:49:23 +01002009 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002010
2011 /* Send some downlink data along with the new TLLI and the IMSI so that
2012 * the PCU can see, that both MS objects belong to same MS */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002013 send_dl_data(bts, tlli2, imsi, (const uint8_t *)"DATA", 4);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002014
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02002015 ms = bts_get_ms_by_imsi(bts, imsi);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002016 OSMO_ASSERT(ms == ms2);
2017
Max4c112dc2018-02-01 16:49:23 +01002018 print_ms(ms2, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002019
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02002020 ms = bts_get_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002021 OSMO_ASSERT(ms == NULL);
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02002022 ms = bts_get_ms_by_tlli(bts, tlli2, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002023 OSMO_ASSERT(ms == ms2);
2024
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002025 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002026 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002027}
2028
2029static void test_tbf_dl_flow_and_rach_two_phase()
2030{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002031 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002032 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002033 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002034 int ts_no = 7;
2035 uint32_t fn = 2654218;
2036 uint16_t qta = 31;
2037 uint32_t tlli1 = 0xf1223344;
2038 const char *imsi = "0011223344";
2039 uint8_t ms_class = 1;
2040 gprs_rlcmac_ul_tbf *ul_tbf;
2041 gprs_rlcmac_dl_tbf *dl_tbf;
2042 GprsMs *ms, *ms1, *ms2;
2043
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002044 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002045
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002046 setup_bts(bts, ts_no, 1);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002047 pdch = &bts->trx[0].pdch[ts_no];
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002048
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002049 ul_tbf = establish_ul_tbf_two_phase(bts, pdch, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002050 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002051
2052 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002053 print_ta_tlli(ul_tbf, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002054
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002055 send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);
2056 send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);
Max4c112dc2018-02-01 16:49:23 +01002057 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002058
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002059 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 2);
2060 dl_tbf = ms_dl_tbf(ms1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002061 OSMO_ASSERT(dl_tbf != NULL);
2062
2063 /* Get rid of old UL TBF */
2064 tbf_free(ul_tbf);
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02002065 ms = bts_get_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002066 OSMO_ASSERT(ms1 == ms);
2067
2068 /* Now establish a new UL TBF, this will consume one LLC packet */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002069 ul_tbf = establish_ul_tbf_two_phase(bts, pdch, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002070 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002071
2072 ms2 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002073 print_ms(ms2, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002074
2075 /* This should be the same MS object */
2076 OSMO_ASSERT(ms2 == ms1);
2077
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02002078 ms = bts_get_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002079 OSMO_ASSERT(ms2 == ms);
2080
Jacob Erlbeckc8cbfc22015-09-01 11:38:40 +02002081 /* A DL TBF should still exist */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002082 OSMO_ASSERT(ms_dl_tbf(ms));
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002083
2084 /* No queued packets should be lost */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002085 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms)) == 2);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002086
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002087 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002088 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002089}
2090
2091
2092static void test_tbf_dl_flow_and_rach_single_phase()
2093{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002094 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002095 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002096 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002097 int ts_no = 7;
2098 uint32_t fn = 2654218;
2099 uint16_t qta = 31;
2100 uint32_t tlli1 = 0xf1223344;
2101 const char *imsi = "0011223344";
2102 uint8_t ms_class = 1;
2103 gprs_rlcmac_ul_tbf *ul_tbf;
2104 gprs_rlcmac_dl_tbf *dl_tbf;
2105 GprsMs *ms, *ms1, *ms2;
2106
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002107 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002108
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002109 setup_bts(bts, ts_no, 1);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002110 pdch = &bts->trx[0].pdch[ts_no];
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002111
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002112 ul_tbf = establish_ul_tbf_two_phase(bts, pdch, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002113 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002114
2115 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002116 print_ta_tlli(ul_tbf, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002117
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002118 send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);
2119 send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);
Max4c112dc2018-02-01 16:49:23 +01002120 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002121
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002122 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 2);
2123 dl_tbf = ms_dl_tbf(ms1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002124 OSMO_ASSERT(dl_tbf != NULL);
2125
2126 /* Get rid of old UL TBF */
2127 tbf_free(ul_tbf);
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02002128 ms = bts_get_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002129 OSMO_ASSERT(ms1 == ms);
2130
2131 /* Now establish a new UL TBF */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002132 ul_tbf = establish_ul_tbf_single_phase(bts, pdch, tlli1, &fn, qta);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002133
2134 ms2 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002135 print_ms(ms2, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002136
2137 /* There should be a different MS object */
2138 OSMO_ASSERT(ms2 != ms1);
2139
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02002140 ms = bts_get_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002141 OSMO_ASSERT(ms2 == ms);
2142 OSMO_ASSERT(ms1 != ms);
2143
Jacob Erlbeck5f93f852016-01-21 20:48:39 +01002144 /* DL TBF should be removed */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002145 OSMO_ASSERT(!ms_dl_tbf(ms));
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002146
2147 /* No queued packets should be lost */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002148 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms)) == 2);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002149
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002150 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002151 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002152}
2153
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002154static void test_tbf_dl_reuse()
2155{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002156 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002157 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002158 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002159 int ts_no = 7;
2160 uint32_t fn = 2654218;
2161 uint16_t qta = 31;
2162 uint32_t tlli1 = 0xf1223344;
2163 const char *imsi = "0011223344";
2164 uint8_t ms_class = 1;
2165 gprs_rlcmac_ul_tbf *ul_tbf;
2166 gprs_rlcmac_dl_tbf *dl_tbf1, *dl_tbf2;
2167 GprsMs *ms1, *ms2;
2168 unsigned i;
2169 RlcMacUplink_t ulreq = {0};
2170
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002171 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002172
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002173 setup_bts(bts, ts_no, 1);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002174 pdch = &bts->trx[0].pdch[ts_no];
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002175
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002176 ul_tbf = establish_ul_tbf_two_phase(bts, pdch, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002177 ms_class, 0);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002178
2179 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002180 print_ta_tlli(ul_tbf, false);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002181
2182 /* Send some LLC frames */
2183 for (i = 0; i < 40; i++) {
2184 char buf[32];
2185 int rc;
2186
2187 rc = snprintf(buf, sizeof(buf), "LLC PACKET %02i", i);
2188 OSMO_ASSERT(rc > 0);
2189
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002190 send_dl_data(bts, tlli1, imsi, (const uint8_t *)buf, rc);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002191 }
2192
Max4c112dc2018-02-01 16:49:23 +01002193 print_ms(ms1, true);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002194
2195 /* Send Packet Downlink Assignment to MS */
2196 request_dl_rlc_block(ul_tbf, &fn);
2197
2198 /* Ack it */
2199 send_control_ack(ul_tbf);
2200
2201 /* Transmit all data */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002202 transmit_dl_data(bts, tlli1, &fn);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002203 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 0);
2204 OSMO_ASSERT(ms_dl_tbf(ms1));
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002205 OSMO_ASSERT(ms_dl_tbf(ms1)->state_is(TBF_ST_FINISHED));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002206
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002207 dl_tbf1 = ms_dl_tbf(ms1);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002208
2209 /* Send some LLC frames */
2210 for (i = 0; i < 10; i++) {
2211 char buf[32];
2212 int rc;
2213
2214 rc = snprintf(buf, sizeof(buf), "LLC PACKET %02i (TBF 2)", i);
2215 OSMO_ASSERT(rc > 0);
2216
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002217 send_dl_data(bts, tlli1, imsi, (const uint8_t *)buf, rc);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002218 }
2219
Pau Espin Pedrol422636d2021-09-28 15:59:35 +02002220 /* Drop first DL_ACK poll queued */
2221 send_empty_block(dl_tbf1, dl_tbf1->control_ts, get_poll_fn(dl_tbf1, dl_tbf1->control_ts));
2222
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002223 /* Fake Final DL Ack/Nack */
2224 ulreq.u.MESSAGE_TYPE = MT_PACKET_DOWNLINK_ACK_NACK;
2225 Packet_Downlink_Ack_Nack_t *ack = &ulreq.u.Packet_Downlink_Ack_Nack;
2226
2227 ack->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
2228 ack->DOWNLINK_TFI = dl_tbf1->tfi();
2229 ack->Ack_Nack_Description.FINAL_ACK_INDICATION = 1;
2230
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002231 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 +02002232
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002233 OSMO_ASSERT(dl_tbf1->state_is(TBF_ST_WAIT_RELEASE));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002234
2235 request_dl_rlc_block(dl_tbf1, &fn);
2236
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02002237 ms2 = bts_get_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002238 OSMO_ASSERT(ms2 == ms1);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002239 OSMO_ASSERT(ms_dl_tbf(ms2));
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002240 OSMO_ASSERT(ms_dl_tbf(ms2)->state_is(TBF_ST_ASSIGN));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002241
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002242 dl_tbf2 = ms_dl_tbf(ms2);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002243
2244 OSMO_ASSERT(dl_tbf1 != dl_tbf2);
2245
2246 send_control_ack(dl_tbf1);
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002247 OSMO_ASSERT(dl_tbf2->state_is(TBF_ST_FLOW));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002248
2249 /* Transmit all data */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002250 transmit_dl_data(bts, tlli1, &fn);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002251 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms2)) == 0);
2252 OSMO_ASSERT(ms_dl_tbf(ms2));
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002253 OSMO_ASSERT(ms_dl_tbf(ms2)->state_is(TBF_ST_FINISHED));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002254
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002255 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002256 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002257}
2258
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002259static void test_tbf_gprs_egprs()
2260{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002261 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002262 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002263 uint8_t ts_no = 4;
2264 uint8_t ms_class = 45;
2265 int rc = 0;
2266 uint32_t tlli = 0xc0006789;
2267 const char *imsi = "001001123456789";
2268 unsigned delay_csec = 1000;
2269
2270 uint8_t buf[256] = {0};
2271
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002272 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002273
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002274 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
2275 if (!bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +02002276 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
2277 abort();
2278 }
2279
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002280 setup_bts(bts, ts_no);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002281
2282 /* EGPRS-only */
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002283
Alexander Couzens290d9032020-09-16 21:52:02 +02002284 gprs_bssgp_init(bts, 3234, 3234, 1, 1, false, 0, 0, 0);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002285
2286 /* Does not support EGPRS */
Pau Espin Pedrol8a35e642021-01-18 17:14:14 +01002287 rc = dl_tbf_handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002288 delay_csec, buf, sizeof(buf));
2289
Pau Espin Pedrol569f0d22020-10-27 14:45:20 +01002290 OSMO_ASSERT(rc == 0);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002291 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002292
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002293 TALLOC_FREE(the_pcu);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002294}
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02002295
Max4c112dc2018-02-01 16:49:23 +01002296static 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 +02002297 bool free)
Max4c112dc2018-02-01 16:49:23 +01002298{
2299 if (!dl_tbf) {
2300 fprintf(stderr, "%s(): FAILED (NULL TBF)\n", test);
2301 return;
2302 }
2303
2304 fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d",
2305 dl_tbf->dl_slots(),
2306 pcu_bitcount(dl_tbf->dl_slots()),
2307 dl_tbf->window_size());
2308
2309 if (pcu_bitcount(dl_tbf->dl_slots()) != exp_slots || dl_tbf->window_size() != exp_ws)
2310 fprintf(stderr, "%s(): DL TBF FAILED: dl_slots = %u (exp. %u), WS = %u (exp. %u)",
2311 test, pcu_bitcount(dl_tbf->dl_slots()), 4, dl_tbf->window_size(), 128 + 4 * 64);
2312
2313 fprintf(stderr, "\n");
2314
2315 if (free)
2316 tbf_free(dl_tbf);
Max4c112dc2018-02-01 16:49:23 +01002317}
2318
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002319static void test_tbf_ws()
2320{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002321 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002322 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +02002323 GprsMs *ms;
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002324 uint8_t ts_no = 4;
2325 uint8_t ms_class = 12;
2326 gprs_rlcmac_dl_tbf *dl_tbf;
2327
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002328 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002329
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002330 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
2331 if (!bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +02002332 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
2333 abort();
2334 }
2335
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002336 setup_bts(bts, ts_no);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002337
Pau Espin Pedrol519d0712021-01-14 14:30:03 +01002338 the_pcu->vty.ws_base = 128;
2339 the_pcu->vty.ws_pdch = 64;
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002340 the_pcu->alloc_algorithm = alloc_algorithm_b;
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002341 bts->trx[0].pdch[2].enable();
2342 bts->trx[0].pdch[3].enable();
Pau Espin Pedrol4f67a9b2021-06-30 16:03:06 +02002343 /* bts->trx[0].pdch[4].enable(); Already enabled during setup_bts() */
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002344 bts->trx[0].pdch[5].enable();
2345
Alexander Couzens290d9032020-09-16 21:52:02 +02002346 gprs_bssgp_init(bts, 4234, 4234, 1, 1, false, 0, 0, 0);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002347
2348 /* Does no support EGPRS */
Pau Espin Pedroleae91472023-04-19 19:42:05 +02002349 ms = ms_alloc(bts, NULL);
Pau Espin Pedrolbfc97562023-04-17 14:49:29 +02002350 ms_set_ms_class(ms, ms_class);
Pau Espin Pedrol4d363912023-04-21 19:32:16 +02002351 OSMO_ASSERT(ms_new_dl_tbf_assigned_on_pch(ms) == 0);
2352 dl_tbf = ms_dl_tbf(ms);
2353 OSMO_ASSERT(dl_tbf);
Max4c112dc2018-02-01 16:49:23 +01002354
Pau Espin Pedrolbf5e3cb2022-05-09 16:31:22 +02002355 ws_check(dl_tbf, __func__, 4, 64, true);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002356
2357 /* EGPRS-only */
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002358
2359 /* Does support EGPRS */
Pau Espin Pedroleae91472023-04-19 19:42:05 +02002360 ms = ms_alloc(bts, NULL);
Pau Espin Pedrolbfc97562023-04-17 14:49:29 +02002361 ms_set_ms_class(ms, ms_class);
2362 ms_set_egprs_ms_class(ms, ms_class);
Pau Espin Pedrol4d363912023-04-21 19:32:16 +02002363 OSMO_ASSERT(ms_new_dl_tbf_assigned_on_pch(ms) == 0);
2364 dl_tbf = ms_dl_tbf(ms);
2365 OSMO_ASSERT(dl_tbf);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002366
Pau Espin Pedrolbf5e3cb2022-05-09 16:31:22 +02002367 ws_check(dl_tbf, __func__, 4, 128 + 4 * 64, true);
2368 fprintf(stderr, "=== end %s ===\n", __func__);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002369 TALLOC_FREE(the_pcu);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002370}
2371
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302372static void test_tbf_update_ws(void)
2373{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002374 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002375 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +02002376 GprsMs *ms;
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302377 uint8_t ts_no = 4;
2378 uint8_t ms_class = 11;
2379 gprs_rlcmac_dl_tbf *dl_tbf;
2380
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002381 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302382
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002383 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
2384 if (!bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +02002385 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
2386 abort();
2387 }
2388
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002389 setup_bts(bts, ts_no);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302390
Pau Espin Pedrol519d0712021-01-14 14:30:03 +01002391 the_pcu->vty.ws_base = 128;
2392 the_pcu->vty.ws_pdch = 64;
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002393 the_pcu->alloc_algorithm = alloc_algorithm_b;
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302394 bts->trx[0].pdch[2].enable();
2395 bts->trx[0].pdch[3].enable();
Pau Espin Pedrol4f67a9b2021-06-30 16:03:06 +02002396 /* bts->trx[0].pdch[4].enable(); Already enabled during setup_bts()) */
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302397 bts->trx[0].pdch[5].enable();
2398
Alexander Couzens290d9032020-09-16 21:52:02 +02002399 gprs_bssgp_init(bts, 5234, 5234, 1, 1, false, 0, 0, 0);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302400
2401 /* EGPRS-only */
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302402
2403 /* Does support EGPRS */
Pau Espin Pedroleae91472023-04-19 19:42:05 +02002404 ms = ms_alloc(bts, NULL);
Pau Espin Pedrolbfc97562023-04-17 14:49:29 +02002405 ms_set_ms_class(ms, ms_class);
2406 ms_set_egprs_ms_class(ms, ms_class);
Pau Espin Pedrol4d363912023-04-21 19:32:16 +02002407 OSMO_ASSERT(ms_new_dl_tbf_assigned_on_pch(ms) == 0);
2408 dl_tbf = ms_dl_tbf(ms);
2409 OSMO_ASSERT(dl_tbf);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302410
Pau Espin Pedrolbf5e3cb2022-05-09 16:31:22 +02002411 ws_check(dl_tbf, __func__, 1, 128 + 1 * 64, false);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302412
Pau Espin Pedrolb7a2b592022-12-13 14:43:59 +01002413 OSMO_ASSERT(dl_tbf_upgrade_to_multislot(dl_tbf) == 0);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302414
Aravind Sirsikar0ee31cf2016-09-15 17:54:46 +05302415 /* window size should be 384 */
Pau Espin Pedrolbf5e3cb2022-05-09 16:31:22 +02002416 ws_check(dl_tbf, __func__, 4, 128 + 4 * 64, true);
2417 fprintf(stderr, "=== end %s ===\n", __func__);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002418 TALLOC_FREE(the_pcu);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302419}
2420
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01002421/* Test DL-TBF first assigned over CCCH ImmAss, then after X2002 timeout, when MS
2422is available to receive from TBF on PACCH, upgrade it to multislot. In the
2423middle the MS would request a new UL-TBF and PCU ends up creating 2 MS objects on
2424different TRX, which are eventually merged.
2425Hence, new multislot DL-TBF allocation (assigned over PACCH) happens on a different TRX
2426than the one which was assigned over CCCH and where the PktDlAss is sent. SYS#6231 */
2427static void test_ms_merge_dl_tbf_different_trx(void)
2428{
2429 the_pcu = prepare_pcu();
2430 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
2431 GprsMs *first_ms, *second_ms;
2432 uint8_t ts_no = 1;
2433 uint8_t ms_class = 11;
2434 struct gprs_rlcmac_trx *trx0 = &bts->trx[0];
2435 struct gprs_rlcmac_trx *trx1 = &bts->trx[1];
2436 uint32_t old_tlli = 0xa3c2f953;
2437 uint32_t new_tlli = 0xecc1f953;
2438 const char *imsi = "001001000000001";
2439 uint8_t llc_buf[19];
2440 int rc;
2441 unsigned delay_csec = 1000;
2442 struct gprs_rlcmac_dl_tbf *dl_tbf;
2443 struct gprs_rlcmac_ul_tbf *ul_tbf;
2444 uint32_t fn = 0;
2445
2446 fprintf(stderr, "=== start %s ===\n", __func__);
2447
2448 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
2449 if (!bts->pcu->nsi) {
2450 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
2451 abort();
2452 }
2453
2454 setup_bts(bts, ts_no);
2455 the_pcu->alloc_algorithm = alloc_algorithm_b;
2456 /* trx0->pdch[ts_no].enable(); Already enabled during setup_bts()) */
2457 trx0->pdch[ts_no].disable();
2458 trx1->pdch[4].enable();
2459 trx1->pdch[5].enable();
2460 trx1->pdch[6].enable();
2461 gprs_bssgp_init(bts, 5234, 5234, 1, 1, false, 0, 0, 0);
2462
2463 /* Handle LLC frame 1. This will create the TBF we want in TRX1 and
Pau Espin Pedrold1058b92022-12-16 18:39:29 +01002464 * we'll have it upgrade to multislot on TRX0 later. This will trigger a
2465 * CCCH Dl ImAss towards BTS PCUIF. The confirmation from BTS is
2466 * injected further below (TBF_EV_ASSIGN_PCUIF_CNF). */
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01002467 memset(llc_buf, 1, sizeof(llc_buf));
2468 rc = dl_tbf_handle(bts, old_tlli, 0, imsi, ms_class, 0,
2469 delay_csec, llc_buf, sizeof(llc_buf));
2470 OSMO_ASSERT(rc >= 0);
2471
Pau Espin Pedroleb0a0522023-04-17 16:33:35 +02002472 first_ms = bts_get_ms(bts, GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, imsi);
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01002473 OSMO_ASSERT(first_ms);
2474 dl_tbf = ms_dl_tbf(first_ms);
2475 OSMO_ASSERT(dl_tbf);
2476 OSMO_ASSERT(tbf_get_trx(dl_tbf) == trx1);
2477 OSMO_ASSERT(dl_tbf->control_ts->trx == trx1);
2478 struct gprs_rlcmac_pdch *old_dl_control_ts = dl_tbf->control_ts;
2479
2480 /* Enable PDCHs on TRX0 so that second_ms is allocated on TRX0: */
2481 trx0->pdch[1].enable();
2482 trx0->pdch[2].enable();
2483 trx0->pdch[3].enable();
2484
Pau Espin Pedroleae91472023-04-19 19:42:05 +02002485 second_ms = ms_alloc(bts, NULL);
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01002486 ms_set_tlli(second_ms, new_tlli);
Pau Espin Pedrol4d363912023-04-21 19:32:16 +02002487 OSMO_ASSERT(ms_new_ul_tbf_assigned_pacch(second_ms, 0));
2488 ul_tbf = ms_ul_tbf(second_ms);
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01002489 OSMO_ASSERT(ul_tbf != NULL);
2490 ms_update_announced_tlli(second_ms, new_tlli);
2491
2492 /* Here PCU gets to know the MS are the same and they get merged. */
2493 rc = dl_tbf_handle(bts, new_tlli, old_tlli, imsi, ms_class, 0,
2494 delay_csec, llc_buf, sizeof(llc_buf));
2495 OSMO_ASSERT(rc >= 0);
Pau Espin Pedrold1058b92022-12-16 18:39:29 +01002496 /* 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): */
2497 dl_tbf = ms_dl_tbf(second_ms);
2498 OSMO_ASSERT(tbf_get_trx(dl_tbf) == trx0);
2499 OSMO_ASSERT(dl_tbf->control_ts != old_dl_control_ts);
2500 OSMO_ASSERT(dl_tbf == llist_first_entry_or_null(&trx0->dl_tbfs, struct llist_item, list)->entry);
2501 OSMO_ASSERT(NULL == llist_first_entry_or_null(&trx1->dl_tbfs, struct llist_item, list));
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01002502
2503 /* Here BTS would answer with data_cnf and trigger
2504 * bts_rcv_imm_ass_cnf(), which would trigger TBF_EV_ASSIGN_PCUIF_CNF.
Pau Espin Pedrold1058b92022-12-16 18:39:29 +01002505 * Since that's for an older DL-TBF assignment which no longer exists, it is ignored. */
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01002506 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2002, 0, OSMO_TDEF_MS) == 0);
2507 osmo_fsm_inst_dispatch(ms_dl_tbf(second_ms)->state_fi, TBF_EV_ASSIGN_PCUIF_CNF, NULL);
2508 osmo_select_main(0);
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01002509
Pau Espin Pedrold1058b92022-12-16 18:39:29 +01002510 /* 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 +01002511 request_dl_rlc_block(dl_tbf->bts, dl_tbf->control_ts, &fn);
2512
2513 fprintf(stderr, "=== end %s ===\n", __func__);
2514 TALLOC_FREE(the_pcu);
2515}
2516
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302517static void test_tbf_puan_urbb_len(void)
2518{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002519 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002520 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002521 struct gprs_rlcmac_pdch *pdch;
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302522 int ts_no = 7;
2523 uint32_t fn = 2654218;
2524 uint16_t qta = 31;
2525 uint32_t tlli = 0xf1223344;
2526 const char *imsi = "0011223344";
2527 uint8_t ms_class = 1;
2528 uint8_t egprs_ms_class = 1;
2529 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302530 uint8_t test_data[256];
2531
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002532 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302533
2534 memset(test_data, 1, sizeof(test_data));
2535
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002536 setup_bts(bts, ts_no, 4);
2537 bts->initial_mcs_dl = 9;
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002538 pdch = &bts->trx[0].pdch[ts_no];
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302539
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002540 ul_tbf = puan_urbb_len_issue(bts, pdch, tlli, &fn, qta,
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302541 ms_class, egprs_ms_class);
2542
Max4c112dc2018-02-01 16:49:23 +01002543 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002544 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302545
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002546 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002547 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302548}
2549
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002550static gprs_rlcmac_ul_tbf *tbf_li_decoding(struct gprs_rlcmac_bts *bts,
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002551 struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta,
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302552 uint8_t ms_class, uint8_t egprs_ms_class)
2553{
2554 GprsMs *ms;
2555 uint32_t rach_fn = *fn - 51;
2556 uint32_t sba_fn = *fn + 52;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002557 int tfi = 0;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302558 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302559 RlcMacUplink_t ulreq = {0};
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302560 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302561 Packet_Resource_Request_t *presreq = NULL;
2562 MS_Radio_Access_capability_t *pmsradiocap = NULL;
2563 Multislot_capability_t *pmultislotcap = NULL;
2564
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302565 /* needed to set last_rts_fn in the PDCH object */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002566 request_dl_rlc_block(bts, pdch, fn);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302567
2568 /*
2569 * simulate RACH, this sends an Immediate
2570 * Assignment Uplink on the AGCH
2571 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002572 bts_handle_rach(bts, 0x73, rach_fn, qta);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302573
2574 /* get next free TFI */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002575 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &pdch->trx->trx_no, -1);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302576
2577 /* fake a resource request */
2578 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
2579 presreq = &ulreq.u.Packet_Resource_Request;
2580 presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
2581 presreq->ID.UnionType = 1; /* != 0 */
2582 presreq->ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01002583 presreq->Exist_MS_Radio_Access_capability2 = 1;
2584 pmsradiocap = &presreq->MS_Radio_Access_capability2;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302585 pmsradiocap->Count_MS_RA_capability_value = 1;
2586 pmsradiocap->MS_RA_capability_value[0].u.Content.
2587 Exist_Multislot_capability = 1;
2588 pmultislotcap = &pmsradiocap->MS_RA_capability_value[0].
2589 u.Content.Multislot_capability;
2590
2591 pmultislotcap->Exist_GPRS_multislot_class = 1;
2592 pmultislotcap->GPRS_multislot_class = ms_class;
2593 if (egprs_ms_class) {
2594 pmultislotcap->Exist_EGPRS_multislot_class = 1;
2595 pmultislotcap->EGPRS_multislot_class = ms_class;
2596 }
2597
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002598 send_ul_mac_block(bts, pdch, &ulreq, sba_fn);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302599
2600 /* check the TBF */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002601 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, pdch->trx->trx_no, pdch->ts_no);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302602 OSMO_ASSERT(ul_tbf);
2603 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
2604
2605 /* send packet uplink assignment */
2606 *fn = sba_fn;
2607 request_dl_rlc_block(ul_tbf, fn);
2608
2609 /* send real acknowledgement */
2610 send_control_ack(ul_tbf);
2611
2612 check_tbf(ul_tbf);
2613
2614 uint8_t data_msg[49] = {0};
2615
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02002616 ms = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302617 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002618 OSMO_ASSERT(ms_ta(ms) == qta/4);
2619 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302620
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302621 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
2622 egprs3->si = 0;
2623 egprs3->r = 1;
2624 egprs3->cv = 7;
2625 egprs3->tfi_hi = tfi & 0x03;
2626 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
2627 egprs3->bsn1_hi = 0;
2628 egprs3->bsn1_lo = 0;
2629 egprs3->cps_hi = 1;
2630 data_msg[3] = 0xff;
2631 egprs3->pi = 0;
2632 egprs3->cps_lo = 1;
2633 egprs3->rsb = 0;
2634 egprs3->spb = 0;
2635 egprs3->pi = 0;
2636 pdch->rcv_block(data_msg, 49, *fn, &meas);
2637
2638 egprs3->bsn1_hi = 1;
2639 egprs3->bsn1_lo = 0;
2640 data_msg[3] = 0x7f;
2641 egprs3->cps_lo = 1;
2642 egprs3->rsb = 0;
2643 egprs3->spb = 0;
2644 egprs3->pi = 0;
2645 data_msg[4] = 0x2;
2646 data_msg[5] = 0x0;
2647 pdch->rcv_block(data_msg, 49, *fn, &meas);
2648
Pau Espin Pedrol14633832022-03-31 19:08:07 +02002649 OSMO_ASSERT(ul_tbf->m_llc.index == 43);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302650
2651 return ul_tbf;
2652}
2653
2654static void test_tbf_li_decoding(void)
2655{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002656 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002657 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002658 struct gprs_rlcmac_pdch *pdch;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302659 int ts_no = 7;
2660 uint32_t fn = 2654218;
2661 uint16_t qta = 31;
2662 uint32_t tlli = 0xf1223344;
2663 const char *imsi = "0011223344";
2664 uint8_t ms_class = 1;
2665 uint8_t egprs_ms_class = 1;
2666 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302667 uint8_t test_data[256];
2668
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002669 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302670
2671 memset(test_data, 1, sizeof(test_data));
2672
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002673 setup_bts(bts, ts_no, 4);
2674 bts->initial_mcs_dl = 9;
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002675 pdch = &bts->trx[0].pdch[ts_no];
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302676
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002677 ul_tbf = tbf_li_decoding(bts, pdch, tlli, &fn, qta,
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302678 ms_class, egprs_ms_class);
2679
Max4c112dc2018-02-01 16:49:23 +01002680 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002681 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302682
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002683 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002684 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302685}
2686
aravind sirsikarf2761382016-10-25 12:45:24 +05302687/*
2688 * Test that a bit within the uncompressed bitmap whose BSN is not within
2689 * the transmit window shall be ignored. See section 9.1.8.2.4 of 44.060
2690 * version 7.27.0 Release 7.
2691 */
2692static void test_tbf_epdan_out_of_rx_window(void)
2693{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002694 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002695 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
aravind sirsikarf2761382016-10-25 12:45:24 +05302696 uint8_t ms_class = 11;
2697 uint8_t egprs_ms_class = 11;
2698 uint8_t trx_no;
2699 uint32_t tlli = 0xffeeddcc;
2700 gprs_rlcmac_dl_tbf *dl_tbf;
2701 int ts_no = 4;
2702 bitvec *block;
2703 uint8_t bits_data[RLC_EGPRS_MAX_WS/8];
2704 bitvec bits;
2705 int bsn_begin, bsn_end;
2706 EGPRS_PD_AckNack_t *ack_nack;
2707 RlcMacUplink_t ul_control_block;
2708 gprs_rlc_v_b *prlcmvb;
2709 gprs_rlc_dl_window *prlcdlwindow;
Pau Espin Pedrol5e300ce2020-02-03 17:18:03 +01002710 int rc;
aravind sirsikarf2761382016-10-25 12:45:24 +05302711
aravind sirsikarcc4214a2016-12-09 16:12:42 +05302712 memset(&ul_control_block, 0, sizeof(RlcMacUplink_t));
2713
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002714 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikarf2761382016-10-25 12:45:24 +05302715
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002716 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01002717 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
aravind sirsikarf2761382016-10-25 12:45:24 +05302718 /* ARQ II */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01002719 the_pcu->vty.dl_arq_type = EGPRS_ARQ2;
aravind sirsikarf2761382016-10-25 12:45:24 +05302720
2721 /*
2722 * Simulate a message captured during over-the-air testing,
2723 * where the following values were observed:
2724 * v_a = 1176, vs = 1288, max sns = 2048, window size = 480.
2725 */
2726 uint8_t data_msg[23] = {0x40, 0x20, 0x0b, 0xff, 0xd1,
2727 0x61, 0x00, 0x3e, 0x0e, 0x51, 0x9f,
2728 0xff, 0xff, 0xfb, 0x80, 0x00, 0x00,
2729 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
2730
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002731 dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no);
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +02002732 ms_confirm_tlli(dl_tbf->ms(), tlli);
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002733 prlcdlwindow = static_cast<gprs_rlc_dl_window *>(dl_tbf->window());
aravind sirsikarf2761382016-10-25 12:45:24 +05302734 prlcmvb = &prlcdlwindow->m_v_b;
2735 prlcdlwindow->m_v_s = 1288;
2736 prlcdlwindow->m_v_a = 1176;
2737 prlcdlwindow->set_sns(2048);
2738 prlcdlwindow->set_ws(480);
2739 prlcmvb->mark_unacked(1176);
2740 prlcmvb->mark_unacked(1177);
2741 prlcmvb->mark_unacked(1286);
2742 prlcmvb->mark_unacked(1287);
2743
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002744 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
aravind sirsikarf2761382016-10-25 12:45:24 +05302745
Alexander Couzensccde5c92017-02-04 03:10:08 +01002746 block = bitvec_alloc(23, tall_pcu_ctx);
aravind sirsikarf2761382016-10-25 12:45:24 +05302747
2748 bitvec_unpack(block, data_msg);
2749
2750 bits.data = bits_data;
2751 bits.data_len = sizeof(bits_data);
2752 bits.cur_bit = 0;
2753
Pau Espin Pedrol5e300ce2020-02-03 17:18:03 +01002754 rc = decode_gsm_rlcmac_uplink(block, &ul_control_block);
2755 OSMO_ASSERT(rc == 0);
aravind sirsikarf2761382016-10-25 12:45:24 +05302756
2757 ack_nack = &ul_control_block.u.Egprs_Packet_Downlink_Ack_Nack;
2758
2759 OSMO_ASSERT(prlcmvb->is_unacked(1176));
2760 OSMO_ASSERT(prlcmvb->is_unacked(1177));
2761 OSMO_ASSERT(prlcmvb->is_unacked(1286));
2762 OSMO_ASSERT(prlcmvb->is_unacked(1287));
2763
2764 Decoding::decode_egprs_acknack_bits(
2765 &ack_nack->EGPRS_AckNack.Desc, &bits,
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002766 &bsn_begin, &bsn_end, prlcdlwindow);
aravind sirsikarf2761382016-10-25 12:45:24 +05302767
2768 dl_tbf->rcvd_dl_ack(
2769 ack_nack->EGPRS_AckNack.Desc.FINAL_ACK_INDICATION,
2770 bsn_begin, &bits);
aravind sirsikarf2761382016-10-25 12:45:24 +05302771
aravind sirsikarfb41afa2016-11-02 15:48:00 +05302772 OSMO_ASSERT(prlcmvb->is_invalid(1176));
2773 OSMO_ASSERT(prlcmvb->is_invalid(1177));
2774 OSMO_ASSERT(prlcmvb->is_acked(1286));
2775 OSMO_ASSERT(prlcmvb->is_acked(1287));
aravind sirsikarf2761382016-10-25 12:45:24 +05302776
2777 bitvec_free(block);
2778 tbf_free(dl_tbf);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002779 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002780 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikarf2761382016-10-25 12:45:24 +05302781}
2782
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302783static void test_tbf_egprs_two_phase_spb(void)
2784{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002785 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002786 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002787 struct gprs_rlcmac_pdch *pdch;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302788 int ts_no = 7;
2789 uint32_t fn = 2654218;
2790 uint16_t qta = 31;
2791 uint32_t tlli = 0xf1223344;
2792 const char *imsi = "0011223344";
2793 uint8_t ms_class = 1;
2794 uint8_t egprs_ms_class = 1;
2795 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302796 uint8_t test_data[256];
2797
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002798 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302799
2800 memset(test_data, 1, sizeof(test_data));
2801
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002802 setup_bts(bts, ts_no, 4);
2803 bts->initial_mcs_dl = 9;
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002804 pdch = &bts->trx[0].pdch[ts_no];
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302805
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002806 ul_tbf = establish_ul_tbf_two_phase_spb(bts, pdch, tlli, &fn, qta,
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302807 ms_class, egprs_ms_class);
2808
Max4c112dc2018-02-01 16:49:23 +01002809 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002810 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302811
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002812 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002813 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302814}
2815
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002816static void test_tbf_egprs_two_phase()
2817{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002818 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002819 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002820 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002821 int ts_no = 7;
2822 uint32_t fn = 2654218;
2823 uint16_t qta = 31;
2824 uint32_t tlli = 0xf1223344;
2825 const char *imsi = "0011223344";
2826 uint8_t ms_class = 1;
2827 uint8_t egprs_ms_class = 1;
2828 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002829 uint8_t test_data[256];
2830
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002831 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002832
2833 memset(test_data, 1, sizeof(test_data));
2834
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002835 setup_bts(bts, ts_no, 4);
2836 bts->initial_mcs_dl = 9;
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002837 pdch = &bts->trx[0].pdch[ts_no];
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002838
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002839 ul_tbf = establish_ul_tbf_two_phase(bts, pdch, tlli, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002840 ms_class, egprs_ms_class);
2841
Max4c112dc2018-02-01 16:49:23 +01002842 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002843 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002844
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002845 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002846 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002847}
2848
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002849static void establish_and_use_egprs_dl_tbf(struct gprs_rlcmac_bts *bts, int mcs)
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002850{
2851 unsigned i;
2852 uint8_t ms_class = 11;
2853 uint8_t egprs_ms_class = 11;
2854 uint32_t fn = 0;
2855 uint8_t trx_no;
2856 uint32_t tlli = 0xffeeddcc;
2857 uint8_t test_data[512];
2858
2859 uint8_t rbb[64/8];
2860
2861 gprs_rlcmac_dl_tbf *dl_tbf;
2862
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002863 fprintf(stderr, "Testing MCS-%d\n", mcs);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002864
2865 memset(test_data, 1, sizeof(test_data));
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002866 bts->initial_mcs_dl = mcs;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002867
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002868 dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no);
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +02002869 ms_confirm_tlli(dl_tbf->ms(), tlli);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002870
2871 for (i = 0; i < sizeof(llc_data); i++)
2872 llc_data[i] = i%256;
2873
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002874 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002875
2876 /* Schedule a small LLC frame */
Pau Espin Pedrol14beef62022-10-26 19:44:07 +02002877 ms_append_llc_dl_data(dl_tbf->ms(), 1000, test_data, 10);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002878
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002879 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002880
2881 /* Drain the queue */
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01002882 while (dl_tbf->have_data()) {
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002883 /* Request to send one RLC/MAC block */
2884 request_dl_rlc_block(dl_tbf, &fn);
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01002885 }
Pau Espin Pedrol16e16782021-03-29 19:10:19 +02002886 send_empty_block(dl_tbf, dl_tbf->control_ts, fn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002887
2888 /* Schedule a large LLC frame */
Pau Espin Pedrol14beef62022-10-26 19:44:07 +02002889 ms_append_llc_dl_data(dl_tbf->ms(), 1000, test_data, sizeof(test_data));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002890
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002891 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002892
2893 /* Drain the queue */
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01002894 while (dl_tbf->have_data()) {
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002895 /* Request to send one RLC/MAC block */
2896 request_dl_rlc_block(dl_tbf, &fn);
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01002897 }
Pau Espin Pedrol16e16782021-03-29 19:10:19 +02002898 send_empty_block(dl_tbf, dl_tbf->control_ts, fn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002899
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002900 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002901
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +02002902 _rcv_ack(true, dl_tbf, rbb); /* Receive a final ACK */
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002903
2904 /* Clean up and ensure tbfs are in the correct state */
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002905 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_WAIT_RELEASE));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002906 check_tbf(dl_tbf);
2907 tbf_free(dl_tbf);
2908}
2909
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002910static gprs_rlcmac_dl_tbf *tbf_init(struct gprs_rlcmac_bts *bts,
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302911 int mcs)
2912{
2913 unsigned i;
2914 uint8_t ms_class = 11;
2915 uint8_t egprs_ms_class = 11;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302916 uint8_t trx_no;
2917 uint32_t tlli = 0xffeeddcc;
2918 uint8_t test_data[512];
2919
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302920 gprs_rlcmac_dl_tbf *dl_tbf;
2921
2922 memset(test_data, 1, sizeof(test_data));
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002923 bts->initial_mcs_dl = mcs;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302924
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002925 dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no);
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +02002926 ms_confirm_tlli(dl_tbf->ms(), tlli);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302927
2928 for (i = 0; i < sizeof(test_data); i++)
2929 test_data[i] = i%256;
2930
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002931 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302932
2933 /* Schedule a LLC frame
2934 * passing only 100 bytes, since it is enough to construct
2935 * 2 RLC data blocks. Which are enough to test Header Type 1
2936 * cases
2937 */
Pau Espin Pedrol14beef62022-10-26 19:44:07 +02002938 ms_append_llc_dl_data(dl_tbf->ms(), 1000, test_data, 100);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302939
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002940 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302941
2942 return dl_tbf;
2943
2944}
2945
2946static void tbf_cleanup(gprs_rlcmac_dl_tbf *dl_tbf)
2947{
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302948 uint8_t rbb[64/8];
2949
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +02002950 _rcv_ack(true, dl_tbf, rbb); /* Receive a final ACK */
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302951
2952 /* Clean up and ensure tbfs are in the correct state */
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002953 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_WAIT_RELEASE));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302954 check_tbf(dl_tbf);
2955 tbf_free(dl_tbf);
2956
2957}
2958
Max7d32f552017-12-15 11:25:14 +01002959#define NACK(tbf, x) do { \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002960 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
2961 w->m_v_b.mark_nacked(x); \
2962 OSMO_ASSERT(w->m_v_b.is_nacked(x)); \
Max7d32f552017-12-15 11:25:14 +01002963 } while(0)
2964
2965#define CHECK_UNACKED(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_unacked(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 CHECK_NACKED(tbf, cs, bsn) do { \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002972 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
2973 OSMO_ASSERT(w->m_v_b.is_nacked(bsn)); \
Max898dddb2019-03-12 15:50:57 +01002974 OSMO_ASSERT(mcs_chan_code(tbf->m_rlc.block(bsn)->cs_current_trans) == cs - 1); \
Max7d32f552017-12-15 11:25:14 +01002975 } while(0)
2976
2977#define MAKE_ACKED(m, tbf, fn, cs, check_unacked) do { \
Pau Espin Pedrold29a1432022-12-15 18:57:35 +01002978 m = tbf->create_dl_acked_block(fn, tbf->control_ts); \
Max7d32f552017-12-15 11:25:14 +01002979 OSMO_ASSERT(m); \
2980 if (check_unacked) \
2981 CHECK_UNACKED(tbf, cs, 0); \
2982 else \
2983 CHECK_NACKED(tbf, cs, 0); \
2984 } while(0)
2985
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002986static void egprs_spb_to_normal_validation(struct gprs_rlcmac_bts *bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002987 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302988{
2989 uint32_t fn = 0;
2990 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302991 uint16_t bsn1, bsn2, bsn3;
2992 struct msgb *msg;
2993 struct gprs_rlc_dl_header_egprs_3 *egprs3;
2994 struct gprs_rlc_dl_header_egprs_2 *egprs2;
2995
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002996 fprintf(stderr, "Testing retx for MCS %u to reseg_mcs %u\n", mcs, demanded_mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302997
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002998 dl_tbf = tbf_init(bts, mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302999
3000 /*
3001 * Table 10.4.8a.3.1 of 44.060.
3002 * (MCS7, MCS9) to (MCS2, MCS3) is not handled since it is same as
3003 * (MCS5, MCS6) to (MCS2, MCS3) transition
3004 */
3005 if (!(mcs == 6 && demanded_mcs == 3))
3006 return;
3007
3008 fn = fn_add_blocks(fn, 1);
3009 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01003010 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303011
3012 egprs2 = (struct gprs_rlc_dl_header_egprs_2 *) msg->data;
Maxb4d368b2017-12-01 17:54:39 +01003013 bsn1 = (egprs2->bsn1_hi << 9) | (egprs2->bsn1_mid << 1) | (egprs2->bsn1_lo);
Max7d32f552017-12-15 11:25:14 +01003014
3015 NACK(dl_tbf, 0);
3016
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303017 OSMO_ASSERT(bsn1 == 0);
3018
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003019 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303020
3021 fn = fn_add_blocks(fn, 1);
3022
3023 /* Send first segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003024 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, false);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303025 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
3026 == EGPRS_RESEG_FIRST_SEG_SENT);
3027
3028 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
3029 OSMO_ASSERT(egprs3->spb == 2);
3030
3031 /* Table 10.4.8a.3.1 of 44.060 */
3032 OSMO_ASSERT(egprs3->cps == 3);
3033
3034 /* Send second segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003035 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303036 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
3037 == EGPRS_RESEG_SECOND_SEG_SENT);
3038
3039 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
3040 /* Table 10.4.8a.3.1 of 44.060 */
3041 OSMO_ASSERT(egprs3->spb == 3);
Maxb4d368b2017-12-01 17:54:39 +01003042 bsn2 = (egprs3->bsn1_hi << 9) | (egprs3->bsn1_mid << 1) | (egprs3->bsn1_lo);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303043 OSMO_ASSERT(bsn2 == bsn1);
3044
3045 /* Table 10.4.8a.3.1 of 44.060 */
3046 OSMO_ASSERT(egprs3->cps == 3);
3047
3048 /* Handle (MCS3, MCS3) -> MCS6 case */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003049 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303050
Max7d32f552017-12-15 11:25:14 +01003051 NACK(dl_tbf, 0);
3052
Pau Espin Pedrold29a1432022-12-15 18:57:35 +01003053 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303054 egprs2 = (struct gprs_rlc_dl_header_egprs_2 *) msg->data;
3055
3056 /* Table 10.4.8a.3.1 of 44.060 */
3057 OSMO_ASSERT(egprs2->cps == 0);
Maxb4d368b2017-12-01 17:54:39 +01003058 bsn3 = (egprs2->bsn1_hi << 9) | (egprs2->bsn1_mid << 1) | (egprs2->bsn1_lo);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303059 OSMO_ASSERT(bsn3 == bsn2);
3060
3061 tbf_cleanup(dl_tbf);
3062}
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01003063
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003064static void establish_and_use_egprs_dl_tbf_for_spb(struct gprs_rlcmac_bts *bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01003065 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303066{
3067 uint32_t fn = 0;
3068 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303069 struct msgb *msg;
3070 struct gprs_rlc_dl_header_egprs_3 *egprs3;
3071
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003072 fprintf(stderr, "Testing retx for MCS %u to reseg_mcs %u\n", mcs, demanded_mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303073
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003074 dl_tbf = tbf_init(bts, mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303075
3076 /*
3077 * Table 10.4.8a.3.1 of 44.060.
3078 * (MCS7, MCS9) to (MCS2, MCS3) is not handled since it is same as
3079 * (MCS5, MCS6) to (MCS2, MCS3) transition
3080 */
3081 /* TODO: Need to support of MCS8 -> MCS6 ->MCS3 transistion
3082 * Refer commit be881c028fc4da00c4046ecd9296727975c206a3
3083 * dated 2016-02-07 23:45:40 (UTC)
3084 */
3085 if (!(((mcs == 5) && (demanded_mcs == 2)) ||
3086 ((mcs == 6) && (demanded_mcs == 3)) ||
3087 ((mcs == 4) && (demanded_mcs == 1))))
3088 return;
3089
3090 fn = fn_add_blocks(fn, 1);
3091 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01003092 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303093
Max7d32f552017-12-15 11:25:14 +01003094 NACK(dl_tbf, 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303095
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003096 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303097
3098 fn = fn_add_blocks(fn, 1);
3099
3100 /* Send first segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003101 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, false);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303102 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
3103 == EGPRS_RESEG_FIRST_SEG_SENT);
3104
3105 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
3106 OSMO_ASSERT(egprs3->spb == 2);
3107
3108 /* Table 10.4.8a.3.1 of 44.060 */
3109 switch (demanded_mcs) {
3110 case 3:
3111 OSMO_ASSERT(egprs3->cps == 3);
3112 break;
3113 case 2:
3114 OSMO_ASSERT(egprs3->cps == 9);
3115 break;
3116 case 1:
3117 OSMO_ASSERT(egprs3->cps == 11);
3118 break;
3119 default:
3120 OSMO_ASSERT(false);
3121 break;
3122 }
3123
3124 /* Send second segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003125 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303126 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
3127 == EGPRS_RESEG_SECOND_SEG_SENT);
3128
3129 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
3130 /* Table 10.4.8a.3.1 of 44.060 */
3131 OSMO_ASSERT(egprs3->spb == 3);
3132
3133 /* Table 10.4.8a.3.1 of 44.060 */
3134 switch (demanded_mcs) {
3135 case 3:
3136 OSMO_ASSERT(egprs3->cps == 3);
3137 break;
3138 case 2:
3139 OSMO_ASSERT(egprs3->cps == 9);
3140 break;
3141 case 1:
3142 OSMO_ASSERT(egprs3->cps == 11);
3143 break;
3144 default:
3145 OSMO_ASSERT(false);
3146 break;
3147 }
3148 tbf_cleanup(dl_tbf);
3149}
3150
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003151static void establish_and_use_egprs_dl_tbf_for_retx(struct gprs_rlcmac_bts *bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01003152 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303153{
3154 uint32_t fn = 0;
3155 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303156 struct msgb *msg;
3157
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003158 fprintf(stderr, "Testing retx for MCS %u - %u\n", mcs, demanded_mcs);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303159
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003160 dl_tbf = tbf_init(bts, mcs);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303161
3162 /* For MCS reduction cases like MCS9->MCS6, MCS7->MCS5
3163 * The MCS transition are referred from table Table 8.1.1.2
3164 * of TS 44.060
3165 */
3166 /* TODO: Need to support of MCS8 -> MCS6 transistion
3167 * Refer commit be881c028fc4da00c4046ecd9296727975c206a3
3168 * dated 2016-02-07 23:45:40 (UTC)
3169 */
3170 if (((mcs == 9) && (demanded_mcs < 9)) ||
3171 ((mcs == 7) && (demanded_mcs < 7))) {
3172 fn = fn_add_blocks(fn, 1);
3173 /* Send 2 RLC data block */
Max7d32f552017-12-15 11:25:14 +01003174 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3175 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303176
Max7d32f552017-12-15 11:25:14 +01003177 NACK(dl_tbf, 0);
3178 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303179
3180 /* Set the demanded MCS to demanded_mcs */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003181 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303182
3183 fn = fn_add_blocks(fn, 1);
3184 /* Retransmit the first RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003185 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
3186 CHECK_NACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303187
3188 fn = fn_add_blocks(fn, 1);
3189 /* Retransmit the second RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003190 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
3191 CHECK_UNACKED(dl_tbf, demanded_mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303192 } else if (((mcs == 5) && (demanded_mcs > 6)) ||
3193 ((mcs == 6) && (demanded_mcs > 8))) {
3194 fn = fn_add_blocks(fn, 1);
3195 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01003196 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303197
3198 fn = fn_add_blocks(fn, 1);
3199 /* Send second RLC data block BSN 1 */
Max7d32f552017-12-15 11:25:14 +01003200 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3201 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303202
Max7d32f552017-12-15 11:25:14 +01003203 NACK(dl_tbf, 0);
3204 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303205
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003206 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303207
3208 fn = fn_add_blocks(fn, 1);
3209 /* Send first, second RLC data blocks with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003210 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
3211 CHECK_UNACKED(dl_tbf, demanded_mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303212 } else if (mcs > 6) {
3213 /* No Mcs change cases are handled here for mcs > MCS6*/
3214 fn = fn_add_blocks(fn, 1);
3215 /* Send first,second RLC data blocks */
Max7d32f552017-12-15 11:25:14 +01003216 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3217 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303218
Max7d32f552017-12-15 11:25:14 +01003219 NACK(dl_tbf, 0);
3220 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303221
3222 fn = fn_add_blocks(fn, 1);
3223 /* Send first,second RLC data blocks with demanded_mcs*/
Max7d32f552017-12-15 11:25:14 +01003224 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3225 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303226 } else {
3227
3228 /* No MCS change cases are handled here for mcs <= MCS6*/
3229 fn = fn_add_blocks(fn, 1);
3230 /* Send first RLC data block */
Max7d32f552017-12-15 11:25:14 +01003231 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303232
Max7d32f552017-12-15 11:25:14 +01003233 NACK(dl_tbf, 0);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303234
3235 fn = fn_add_blocks(fn, 1);
3236 /* Send first RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003237 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303238 }
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01003239 /* Clean up pending items in UL controller: */
Pau Espin Pedrol16e16782021-03-29 19:10:19 +02003240 send_empty_block(dl_tbf, dl_tbf->control_ts, fn+50);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303241 tbf_cleanup(dl_tbf);
3242}
3243
3244static void test_tbf_egprs_retx_dl(void)
3245{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003246 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003247 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303248 uint8_t ts_no = 4;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303249
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003250 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303251
Pau Espin Pedrolad79b852021-01-14 13:20:55 +01003252 the_pcu->vty.cs_downgrade_threshold = 0;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003253 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01003254 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303255 /* ARQ II */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01003256 the_pcu->vty.dl_arq_type = EGPRS_ARQ2;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303257
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303258
3259 /* First parameter is current MCS, second one is demanded_mcs */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003260 establish_and_use_egprs_dl_tbf_for_retx(bts, 6, 6);
3261 establish_and_use_egprs_dl_tbf_for_retx(bts, 1, 9);
3262 establish_and_use_egprs_dl_tbf_for_retx(bts, 2, 8);
3263 establish_and_use_egprs_dl_tbf_for_retx(bts, 5, 7);
3264 establish_and_use_egprs_dl_tbf_for_retx(bts, 6, 9);
3265 establish_and_use_egprs_dl_tbf_for_retx(bts, 7, 5);
3266 establish_and_use_egprs_dl_tbf_for_retx(bts, 9, 6);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303267
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003268 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003269 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303270}
3271
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303272static void test_tbf_egprs_spb_dl(void)
3273{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003274 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003275 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303276 uint8_t ts_no = 4;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303277
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003278 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303279
Pau Espin Pedrolad79b852021-01-14 13:20:55 +01003280 the_pcu->vty.cs_downgrade_threshold = 0;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003281 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01003282 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303283
3284 /* ARQ I resegmentation support */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01003285 the_pcu->vty.dl_arq_type = EGPRS_ARQ1;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303286
3287 /*
3288 * First parameter is current MCS, second one is demanded_mcs
3289 * currently only MCS5->MCS2, MCS6->3, MCS4->MCS1 is tested in UT
3290 * rest scenarios has been integration tested
3291 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003292 establish_and_use_egprs_dl_tbf_for_spb(bts, 6, 3);
3293 establish_and_use_egprs_dl_tbf_for_spb(bts, 5, 2);
3294 establish_and_use_egprs_dl_tbf_for_spb(bts, 4, 1);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303295 /* check MCS6->(MCS3+MCS3)->MCS6 case */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003296 egprs_spb_to_normal_validation(bts, 6, 3);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303297
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003298 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003299 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303300}
3301
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003302static void test_tbf_egprs_dl()
3303{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003304 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003305 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003306 uint8_t ts_no = 4;
3307 int i;
3308
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003309 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003310
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003311 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01003312 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303313 /* ARQ II */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01003314 the_pcu->vty.dl_arq_type = EGPRS_ARQ2;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003315
3316 for (i = 1; i <= 9; i++)
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003317 establish_and_use_egprs_dl_tbf(bts, i);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003318
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003319 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003320 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003321}
3322
3323
3324
aravind sirsikare9a138e2017-01-24 12:36:08 +05303325static void test_packet_access_rej_prr_no_other_tbfs()
3326{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003327 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003328 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003329 struct gprs_rlcmac_pdch *pdch;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303330 uint32_t fn = 2654218;
3331 int ts_no = 7;
3332 uint8_t trx_no = 0;
3333 uint32_t tlli = 0xffeeddcc;
Pau Espin Pedrol54742f22021-04-26 16:48:34 +02003334 struct gprs_rlcmac_ul_tbf *ul_tbf;
3335 struct GprsMs *ms;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303336
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003337 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303338
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003339 setup_bts(bts, ts_no, 4);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003340 pdch = &bts->trx[trx_no].pdch[ts_no];
Pau Espin Pedrol9d67e722021-07-28 19:25:38 +02003341 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2000, 0, OSMO_TDEF_MS) == 0);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303342
3343 int rc = 0;
3344
Pau Espin Pedroleae91472023-04-19 19:42:05 +02003345 ms = ms_alloc(bts, NULL);
Pau Espin Pedrol54742f22021-04-26 16:48:34 +02003346 ms_set_tlli(ms, tlli);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003347 ul_tbf = ms_new_ul_tbf_rejected_pacch(ms, pdch);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303348
3349 OSMO_ASSERT(ul_tbf != 0);
3350
3351 /* trigger packet access reject */
3352 uint8_t bn = fn2bn(fn);
3353
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003354 rc = gprs_rlcmac_rcv_rts_block(bts, pdch->trx->trx_no, pdch->ts_no, fn, bn);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303355
3356 OSMO_ASSERT(rc == 0);
Pau Espin Pedrol9d67e722021-07-28 19:25:38 +02003357 osmo_select_main(0);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303358
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003359 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003360 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303361}
3362
3363static void test_packet_access_rej_prr()
3364{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003365 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003366 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003367 struct gprs_rlcmac_pdch *pdch;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303368 uint32_t fn = 2654218;
3369 uint16_t qta = 31;
3370 int ts_no = 7;
3371 uint8_t trx_no = 0;
3372 RlcMacUplink_t ulreq = {0};
3373 Packet_Resource_Request_t *presreq = NULL;
3374 uint8_t ms_class = 11;
3375 uint8_t egprs_ms_class = 11;
3376 uint32_t rach_fn = fn - 51;
3377 uint32_t sba_fn = fn + 52;
3378 uint32_t tlli = 0xffeeddcc;
3379 MS_Radio_Access_capability_t *pmsradiocap = NULL;
3380 Multislot_capability_t *pmultislotcap = NULL;
3381
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003382 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303383
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003384 setup_bts(bts, ts_no, 4);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003385 pdch = &bts->trx[trx_no].pdch[ts_no];
aravind sirsikare9a138e2017-01-24 12:36:08 +05303386
3387 int rc = 0;
3388
3389 /*
3390 * Trigger rach till resources(USF) exhaust
3391 */
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003392 int i;
3393 for (i = 0; i < 8; i++) {
3394 rc = bts_handle_rach(bts, 0x70 + i, rach_fn, qta);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303395 }
3396
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003397 sba_fn = 52;
3398 for (i = 0; i < 8; i++) {
3399 /* fake a resource request */
3400 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
3401 presreq = &ulreq.u.Packet_Resource_Request;
3402 presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
3403 presreq->ID.UnionType = 1; /* != 0 */
3404 presreq->ID.u.TLLI = tlli + i;
3405 presreq->Exist_MS_Radio_Access_capability2 = 1;
3406 pmsradiocap = &presreq->MS_Radio_Access_capability2;
3407 pmsradiocap->Count_MS_RA_capability_value = 1;
3408 pmsradiocap->MS_RA_capability_value[0].u.Content.
3409 Exist_Multislot_capability = 1;
3410 pmultislotcap = &pmsradiocap->MS_RA_capability_value[0].
3411 u.Content.Multislot_capability;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303412
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003413 pmultislotcap->Exist_GPRS_multislot_class = 1;
3414 pmultislotcap->GPRS_multislot_class = ms_class;
3415 if (egprs_ms_class) {
3416 pmultislotcap->Exist_EGPRS_multislot_class = 1;
3417 pmultislotcap->EGPRS_multislot_class = egprs_ms_class;
3418 }
aravind sirsikare9a138e2017-01-24 12:36:08 +05303419
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003420 send_ul_mac_block(bts, pdch, &ulreq, sba_fn);
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003421 sba_fn = fn_next_block(sba_fn);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303422
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003423 /* trigger packet access reject */
3424 uint8_t bn = fn2bn(fn);
3425
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003426 rc = gprs_rlcmac_rcv_rts_block(bts, pdch->trx->trx_no, pdch->ts_no, fn, bn);
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003427 OSMO_ASSERT(rc == 0);
3428 }
aravind sirsikare9a138e2017-01-24 12:36:08 +05303429
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003430 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003431 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303432}
3433
aravind sirsikared3413e2016-11-11 17:15:10 +05303434void test_packet_access_rej_epdan()
3435{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003436 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003437 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
aravind sirsikared3413e2016-11-11 17:15:10 +05303438 uint32_t tlli = 0xffeeddcc;
Pau Espin Pedrol2ab840a2021-04-26 17:49:05 +02003439 static uint8_t exp[] = { 0x40, 0x84, 0x7f, 0xf7, 0x6e, 0xe6, 0x7e, 0xab,
Maxd3a0d912019-03-05 16:15:01 +01003440 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
3441 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b
3442 };
aravind sirsikared3413e2016-11-11 17:15:10 +05303443
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003444 fprintf(stderr, "=== start %s ===\n", __func__);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003445 setup_bts(bts, 4);
3446 static gprs_rlcmac_dl_tbf *dl_tbf = tbf_init(bts, 1);
aravind sirsikared3413e2016-11-11 17:15:10 +05303447
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +02003448 ms_confirm_tlli(dl_tbf->ms(), tlli);
aravind sirsikared3413e2016-11-11 17:15:10 +05303449
Pau Espin Pedrol6ad11a62021-07-27 12:27:08 +02003450 osmo_fsm_inst_dispatch(dl_tbf->ul_ass_fsm.fi, TBF_UL_ASS_EV_SCHED_ASS_REJ, NULL);
3451 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 +05303452
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003453 fprintf(stderr, "packet reject: %s\n",
aravind sirsikared3413e2016-11-11 17:15:10 +05303454 osmo_hexdump(msg->data, 23));
3455
Maxd3a0d912019-03-05 16:15:01 +01003456 if (!msgb_eq_data_print(msg, exp, GSM_MACBLOCK_LEN))
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003457 fprintf(stderr, "%s test failed!\n", __func__);
Maxd3a0d912019-03-05 16:15:01 +01003458
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003459 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003460 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikared3413e2016-11-11 17:15:10 +05303461}
3462
3463
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003464int main(int argc, char **argv)
3465{
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003466 struct vty_app_info pcu_vty_info = {0};
3467
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003468 tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile TbfTest context");
3469 if (!tall_pcu_ctx)
3470 abort();
3471
Neels Hofmeyr78ce5912017-02-08 17:07:31 +01003472 msgb_talloc_ctx_init(tall_pcu_ctx, 0);
Neels Hofmeyr42f2d612018-04-01 16:54:40 +02003473 osmo_init_logging2(tall_pcu_ctx, &gprs_log_info);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003474 log_set_use_color(osmo_stderr_target, 0);
Pau Espin Pedrol00f52cc2021-02-19 14:01:52 +01003475 log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
Pau Espin Pedrolb18d2a52021-02-19 14:00:48 +01003476 log_set_print_category(osmo_stderr_target, 0);
3477 log_set_print_category_hex(osmo_stderr_target, 0);
Maxfdd79e92018-01-24 11:04:59 +01003478 log_parse_category_mask(osmo_stderr_target, "DRLCMAC,1:DRLCMACDATA,3:DRLCMACDL,3:DRLCMACUL,3:"
Harald Welte398f60e2020-12-10 13:39:21 +01003479 "DRLCMACSCHED,1:DRLCMACMEAS,3:DNS,3:DLBSSGP,3:DPCU,5:"
Pau Espin Pedrolfe4d2f72023-04-19 20:38:40 +02003480 "DL1IF,6:DMS,1:DTBF,1:DTBFUL,1:DTBFDL,1:DLGLOBAL,2:");
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02003481 osmo_fsm_log_addr(false);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003482 vty_init(&pcu_vty_info);
Pau Espin Pedrolcd2ac562019-08-05 14:30:44 +02003483 pcu_vty_init();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003484
Vadim Yanitskiy87b6e7d2019-11-08 04:44:04 +07003485 /* Initialize shared UL measurements */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003486 pcu_l1_meas_set_link_qual(&meas, 12);
3487 pcu_l1_meas_set_rssi(&meas, 31);
Vadim Yanitskiy87b6e7d2019-11-08 04:44:04 +07003488
Jacob Erlbeckac89a552015-06-29 14:18:46 +02003489 test_tbf_base();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003490 test_tbf_tlli_update();
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +01003491 test_tbf_final_ack(TEST_MODE_STANDARD);
3492 test_tbf_final_ack(TEST_MODE_REVERSE_FREE);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +01003493 test_tbf_delayed_release();
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +02003494 test_tbf_imsi();
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003495 test_tbf_exhaustion();
Jacob Erlbeck41168642015-06-12 13:41:00 +02003496 test_tbf_dl_llc_loss();
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02003497 test_tbf_single_phase();
Pau Espin Pedrol22b26d82022-10-26 15:44:14 +02003498 test_tbf_single_phase2();
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02003499 test_tbf_two_phase();
Jacob Erlbeckb1395982015-08-21 18:15:38 +02003500 test_tbf_ra_update_rach();
3501 test_tbf_dl_flow_and_rach_two_phase();
3502 test_tbf_dl_flow_and_rach_single_phase();
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02003503 test_tbf_dl_reuse();
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01003504 test_tbf_gprs_egprs();
Jacob Erlbeck36df7742016-01-19 15:53:30 +01003505 test_tbf_ws();
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003506 test_tbf_egprs_two_phase();
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05303507 test_tbf_egprs_two_phase_spb();
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003508 test_tbf_egprs_dl();
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303509 test_tbf_egprs_retx_dl();
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303510 test_tbf_egprs_spb_dl();
Aravind Sirsikar02352b42016-08-25 16:37:30 +05303511 test_tbf_puan_urbb_len();
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05303512 test_tbf_update_ws();
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05303513 test_tbf_li_decoding();
aravind sirsikarf2761382016-10-25 12:45:24 +05303514 test_tbf_epdan_out_of_rx_window();
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05303515 test_immediate_assign_rej();
sivasankari1d8744c2017-01-24 15:53:35 +05303516 test_tbf_egprs_two_phase_puan();
aravind sirsikared3413e2016-11-11 17:15:10 +05303517 test_packet_access_rej_epdan();
aravind sirsikare9a138e2017-01-24 12:36:08 +05303518 test_packet_access_rej_prr();
3519 test_packet_access_rej_prr_no_other_tbfs();
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01003520 test_ms_merge_dl_tbf_different_trx();
Jacob Erlbeck67c38502015-05-11 10:32:40 +02003521
3522 if (getenv("TALLOC_REPORT_FULL"))
3523 talloc_report_full(tall_pcu_ctx, stderr);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003524 return EXIT_SUCCESS;
3525}
3526
3527/*
3528 * stubs that should not be reached
3529 */
3530extern "C" {
3531void l1if_pdch_req() { abort(); }
3532void l1if_connect_pdch() { abort(); }
Philipp Maier72ed3332023-02-27 15:32:00 +01003533void l1if_disconnect_pdch() { abort(); }
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003534void l1if_close_pdch() { abort(); }
3535void l1if_open_pdch() { abort(); }
3536}