blob: e67bd17c93e20c569275637b1dd9a0fd3da3666d [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 Pedrol9da06862023-04-17 19:00:04 +0200125 ms = ms_alloc(bts);
Pau Espin Pedrol87573842022-10-26 20:23:45 +0200126 gprs_rlcmac_tbf *dl_tbf = dl_tbf_alloc(bts,
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200127 ms, 0, false);
Jacob Erlbeckc6d4cee2015-06-29 13:03:46 +0200128 OSMO_ASSERT(dl_tbf != NULL);
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +0200129 ms_confirm_tlli(ms, 0x2342);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200130 dl_tbf->set_ta(4);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100131 OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200132 OSMO_ASSERT(dl_tbf->ms() == ms);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100133
Pau Espin Pedrolbda7bb72022-10-31 14:33:09 +0100134 gprs_rlcmac_tbf *ul_tbf = ul_tbf_alloc(bts,
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200135 ms, 0, false);
Jacob Erlbeckc6d4cee2015-06-29 13:03:46 +0200136 OSMO_ASSERT(ul_tbf != NULL);
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +0200137 ms_update_announced_tlli(ms, 0x2342);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100138 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200139 OSMO_ASSERT(ul_tbf->ms() == ms);
140
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +0200141 OSMO_ASSERT(bts_get_ms_by_tlli(bts, 0x2342, GSM_RESERVED_TMSI) == ms);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100142
143 /*
144 * Now check.. that DL changes and that the timing advance
145 * has changed.
146 */
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +0200147 ms_confirm_tlli(dl_tbf->ms(), 0x4232);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100148
Jacob Erlbeck93990462015-05-15 15:50:43 +0200149 /* It is still there, since the new TLLI has not been used for UL yet */
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +0200150 ms_new = bts_get_ms_by_tlli(bts, 0x2342, GSM_RESERVED_TMSI);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200151 OSMO_ASSERT(ms == ms_new);
152
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +0200153 ms_new = bts_get_ms_by_tlli(bts, 0x4232, GSM_RESERVED_TMSI);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200154 OSMO_ASSERT(ms == ms_new);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100155 OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf);
156 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200157
158 /* Now use the new TLLI for UL */
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +0200159 ms_update_announced_tlli(ms, 0x4232);
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +0200160 ms_new = bts_get_ms_by_tlli(bts, 0x2342, GSM_RESERVED_TMSI);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200161 OSMO_ASSERT(ms_new == NULL);
Holger Hans Peter Freytherbc1626e2013-10-30 19:50:49 +0100162
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +0200163 ms_new = bts_get_ms_by_tlli(bts, 0x4232, GSM_RESERVED_TMSI);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200164 OSMO_ASSERT(ms_new != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100165 OSMO_ASSERT(ms_ta(ms_new) == 4);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200166
167 OSMO_ASSERT(ul_tbf->ta() == 4);
168 OSMO_ASSERT(dl_tbf->ta() == 4);
169
170 ul_tbf->set_ta(6);
171
172 OSMO_ASSERT(ul_tbf->ta() == 6);
173 OSMO_ASSERT(dl_tbf->ta() == 6);
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100174
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200175 fprintf(stderr, "=== end %s ===\n", __func__);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100176 TALLOC_FREE(the_pcu);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100177}
178
Daniel Willmann510d7d32014-08-15 18:19:41 +0200179static uint8_t llc_data[200];
180
Maxa2961182018-01-25 19:47:28 +0100181/* override, requires '-Wl,--wrap=pcu_sock_send' */
182int __real_pcu_sock_send(struct msgb *msg);
Pau Espin Pedrole91c4c72021-01-18 17:54:30 +0100183extern "C" int __wrap_pcu_sock_send(struct msgb *msg)
Daniel Willmann510d7d32014-08-15 18:19:41 +0200184{
185 return 0;
186}
187
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100188static void setup_bts(struct gprs_rlcmac_bts *bts, uint8_t ts_no, uint8_t cs = 1)
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100189{
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100190 gprs_rlcmac_trx *trx;
191
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100192 the_pcu->alloc_algorithm = alloc_algorithm_a;
Jacob Erlbecka700dd92015-06-02 16:00:41 +0200193 bts->initial_cs_dl = cs;
194 bts->initial_cs_ul = cs;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100195 trx = &bts->trx[0];
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100196 trx->pdch[ts_no].enable();
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100197 bts_set_current_frame_number(bts, DUMMY_FN);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100198}
199
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100200static gprs_rlcmac_dl_tbf *create_dl_tbf(struct gprs_rlcmac_bts *bts, uint8_t ms_class,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +0100201 uint8_t egprs_ms_class, uint8_t *trx_no_)
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100202{
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100203 int tfi;
204 uint8_t trx_no;
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200205 GprsMs *ms;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100206 gprs_rlcmac_dl_tbf *dl_tbf;
207
Pau Espin Pedrol9da06862023-04-17 19:00:04 +0200208 ms = ms_alloc(bts);
Pau Espin Pedrolbfc97562023-04-17 14:49:29 +0200209 ms_set_ms_class(ms, ms_class);
210 ms_set_egprs_ms_class(ms, egprs_ms_class);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100211
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100212 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_DL_TBF, &trx_no, -1);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100213 OSMO_ASSERT(tfi >= 0);
Pau Espin Pedrol87573842022-10-26 20:23:45 +0200214 dl_tbf = dl_tbf_alloc(bts, ms, trx_no, true);
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: */
630 ms_set_timeout(ms, 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 Pedrol9da06862023-04-17 19:00:04 +02002349 ms = ms_alloc(bts);
Pau Espin Pedrolbfc97562023-04-17 14:49:29 +02002350 ms_set_ms_class(ms, ms_class);
Pau Espin Pedrol87573842022-10-26 20:23:45 +02002351 dl_tbf = dl_tbf_alloc(bts, ms, 0, false);
Max4c112dc2018-02-01 16:49:23 +01002352
Pau Espin Pedrolbf5e3cb2022-05-09 16:31:22 +02002353 ws_check(dl_tbf, __func__, 4, 64, true);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002354
2355 /* EGPRS-only */
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002356
2357 /* Does support EGPRS */
Pau Espin Pedrol9da06862023-04-17 19:00:04 +02002358 ms = ms_alloc(bts);
Pau Espin Pedrolbfc97562023-04-17 14:49:29 +02002359 ms_set_ms_class(ms, ms_class);
2360 ms_set_egprs_ms_class(ms, ms_class);
Pau Espin Pedrol87573842022-10-26 20:23:45 +02002361 dl_tbf = dl_tbf_alloc(bts, ms, 0, false);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002362
Pau Espin Pedrolbf5e3cb2022-05-09 16:31:22 +02002363 ws_check(dl_tbf, __func__, 4, 128 + 4 * 64, true);
2364 fprintf(stderr, "=== end %s ===\n", __func__);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002365 TALLOC_FREE(the_pcu);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002366}
2367
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302368static void test_tbf_update_ws(void)
2369{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002370 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002371 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +02002372 GprsMs *ms;
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302373 uint8_t ts_no = 4;
2374 uint8_t ms_class = 11;
2375 gprs_rlcmac_dl_tbf *dl_tbf;
2376
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002377 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302378
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002379 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
2380 if (!bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +02002381 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
2382 abort();
2383 }
2384
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002385 setup_bts(bts, ts_no);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302386
Pau Espin Pedrol519d0712021-01-14 14:30:03 +01002387 the_pcu->vty.ws_base = 128;
2388 the_pcu->vty.ws_pdch = 64;
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002389 the_pcu->alloc_algorithm = alloc_algorithm_b;
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302390 bts->trx[0].pdch[2].enable();
2391 bts->trx[0].pdch[3].enable();
Pau Espin Pedrol4f67a9b2021-06-30 16:03:06 +02002392 /* bts->trx[0].pdch[4].enable(); Already enabled during setup_bts()) */
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302393 bts->trx[0].pdch[5].enable();
2394
Alexander Couzens290d9032020-09-16 21:52:02 +02002395 gprs_bssgp_init(bts, 5234, 5234, 1, 1, false, 0, 0, 0);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302396
2397 /* EGPRS-only */
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302398
2399 /* Does support EGPRS */
Pau Espin Pedrol9da06862023-04-17 19:00:04 +02002400 ms = ms_alloc(bts);
Pau Espin Pedrolbfc97562023-04-17 14:49:29 +02002401 ms_set_ms_class(ms, ms_class);
2402 ms_set_egprs_ms_class(ms, ms_class);
Pau Espin Pedrol87573842022-10-26 20:23:45 +02002403 dl_tbf = dl_tbf_alloc(bts, ms, 0, true);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302404
Pau Espin Pedrolbf5e3cb2022-05-09 16:31:22 +02002405 ws_check(dl_tbf, __func__, 1, 128 + 1 * 64, false);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302406
Pau Espin Pedrolb7a2b592022-12-13 14:43:59 +01002407 OSMO_ASSERT(dl_tbf_upgrade_to_multislot(dl_tbf) == 0);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302408
Aravind Sirsikar0ee31cf2016-09-15 17:54:46 +05302409 /* window size should be 384 */
Pau Espin Pedrolbf5e3cb2022-05-09 16:31:22 +02002410 ws_check(dl_tbf, __func__, 4, 128 + 4 * 64, true);
2411 fprintf(stderr, "=== end %s ===\n", __func__);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002412 TALLOC_FREE(the_pcu);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302413}
2414
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01002415/* Test DL-TBF first assigned over CCCH ImmAss, then after X2002 timeout, when MS
2416is available to receive from TBF on PACCH, upgrade it to multislot. In the
2417middle the MS would request a new UL-TBF and PCU ends up creating 2 MS objects on
2418different TRX, which are eventually merged.
2419Hence, new multislot DL-TBF allocation (assigned over PACCH) happens on a different TRX
2420than the one which was assigned over CCCH and where the PktDlAss is sent. SYS#6231 */
2421static void test_ms_merge_dl_tbf_different_trx(void)
2422{
2423 the_pcu = prepare_pcu();
2424 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
2425 GprsMs *first_ms, *second_ms;
2426 uint8_t ts_no = 1;
2427 uint8_t ms_class = 11;
2428 struct gprs_rlcmac_trx *trx0 = &bts->trx[0];
2429 struct gprs_rlcmac_trx *trx1 = &bts->trx[1];
2430 uint32_t old_tlli = 0xa3c2f953;
2431 uint32_t new_tlli = 0xecc1f953;
2432 const char *imsi = "001001000000001";
2433 uint8_t llc_buf[19];
2434 int rc;
2435 unsigned delay_csec = 1000;
2436 struct gprs_rlcmac_dl_tbf *dl_tbf;
2437 struct gprs_rlcmac_ul_tbf *ul_tbf;
2438 uint32_t fn = 0;
2439
2440 fprintf(stderr, "=== start %s ===\n", __func__);
2441
2442 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
2443 if (!bts->pcu->nsi) {
2444 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
2445 abort();
2446 }
2447
2448 setup_bts(bts, ts_no);
2449 the_pcu->alloc_algorithm = alloc_algorithm_b;
2450 /* trx0->pdch[ts_no].enable(); Already enabled during setup_bts()) */
2451 trx0->pdch[ts_no].disable();
2452 trx1->pdch[4].enable();
2453 trx1->pdch[5].enable();
2454 trx1->pdch[6].enable();
2455 gprs_bssgp_init(bts, 5234, 5234, 1, 1, false, 0, 0, 0);
2456
2457 /* Handle LLC frame 1. This will create the TBF we want in TRX1 and
Pau Espin Pedrold1058b92022-12-16 18:39:29 +01002458 * we'll have it upgrade to multislot on TRX0 later. This will trigger a
2459 * CCCH Dl ImAss towards BTS PCUIF. The confirmation from BTS is
2460 * injected further below (TBF_EV_ASSIGN_PCUIF_CNF). */
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01002461 memset(llc_buf, 1, sizeof(llc_buf));
2462 rc = dl_tbf_handle(bts, old_tlli, 0, imsi, ms_class, 0,
2463 delay_csec, llc_buf, sizeof(llc_buf));
2464 OSMO_ASSERT(rc >= 0);
2465
Pau Espin Pedroleb0a0522023-04-17 16:33:35 +02002466 first_ms = bts_get_ms(bts, GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, imsi);
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01002467 OSMO_ASSERT(first_ms);
2468 dl_tbf = ms_dl_tbf(first_ms);
2469 OSMO_ASSERT(dl_tbf);
2470 OSMO_ASSERT(tbf_get_trx(dl_tbf) == trx1);
2471 OSMO_ASSERT(dl_tbf->control_ts->trx == trx1);
2472 struct gprs_rlcmac_pdch *old_dl_control_ts = dl_tbf->control_ts;
2473
2474 /* Enable PDCHs on TRX0 so that second_ms is allocated on TRX0: */
2475 trx0->pdch[1].enable();
2476 trx0->pdch[2].enable();
2477 trx0->pdch[3].enable();
2478
Pau Espin Pedrol9da06862023-04-17 19:00:04 +02002479 second_ms = ms_alloc(bts);
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01002480 ms_set_tlli(second_ms, new_tlli);
2481 ul_tbf = ul_tbf_alloc(bts, second_ms, 0, true);
2482 OSMO_ASSERT(ul_tbf != NULL);
2483 ms_update_announced_tlli(second_ms, new_tlli);
2484
2485 /* Here PCU gets to know the MS are the same and they get merged. */
2486 rc = dl_tbf_handle(bts, new_tlli, old_tlli, imsi, ms_class, 0,
2487 delay_csec, llc_buf, sizeof(llc_buf));
2488 OSMO_ASSERT(rc >= 0);
Pau Espin Pedrold1058b92022-12-16 18:39:29 +01002489 /* 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): */
2490 dl_tbf = ms_dl_tbf(second_ms);
2491 OSMO_ASSERT(tbf_get_trx(dl_tbf) == trx0);
2492 OSMO_ASSERT(dl_tbf->control_ts != old_dl_control_ts);
2493 OSMO_ASSERT(dl_tbf == llist_first_entry_or_null(&trx0->dl_tbfs, struct llist_item, list)->entry);
2494 OSMO_ASSERT(NULL == llist_first_entry_or_null(&trx1->dl_tbfs, struct llist_item, list));
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01002495
2496 /* Here BTS would answer with data_cnf and trigger
2497 * bts_rcv_imm_ass_cnf(), which would trigger TBF_EV_ASSIGN_PCUIF_CNF.
Pau Espin Pedrold1058b92022-12-16 18:39:29 +01002498 * Since that's for an older DL-TBF assignment which no longer exists, it is ignored. */
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01002499 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2002, 0, OSMO_TDEF_MS) == 0);
2500 osmo_fsm_inst_dispatch(ms_dl_tbf(second_ms)->state_fi, TBF_EV_ASSIGN_PCUIF_CNF, NULL);
2501 osmo_select_main(0);
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01002502
Pau Espin Pedrold1058b92022-12-16 18:39:29 +01002503 /* 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 +01002504 request_dl_rlc_block(dl_tbf->bts, dl_tbf->control_ts, &fn);
2505
2506 fprintf(stderr, "=== end %s ===\n", __func__);
2507 TALLOC_FREE(the_pcu);
2508}
2509
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302510static void test_tbf_puan_urbb_len(void)
2511{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002512 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002513 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002514 struct gprs_rlcmac_pdch *pdch;
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302515 int ts_no = 7;
2516 uint32_t fn = 2654218;
2517 uint16_t qta = 31;
2518 uint32_t tlli = 0xf1223344;
2519 const char *imsi = "0011223344";
2520 uint8_t ms_class = 1;
2521 uint8_t egprs_ms_class = 1;
2522 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302523 uint8_t test_data[256];
2524
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002525 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302526
2527 memset(test_data, 1, sizeof(test_data));
2528
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002529 setup_bts(bts, ts_no, 4);
2530 bts->initial_mcs_dl = 9;
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002531 pdch = &bts->trx[0].pdch[ts_no];
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302532
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002533 ul_tbf = puan_urbb_len_issue(bts, pdch, tlli, &fn, qta,
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302534 ms_class, egprs_ms_class);
2535
Max4c112dc2018-02-01 16:49:23 +01002536 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002537 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302538
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002539 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002540 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302541}
2542
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002543static gprs_rlcmac_ul_tbf *tbf_li_decoding(struct gprs_rlcmac_bts *bts,
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002544 struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta,
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302545 uint8_t ms_class, uint8_t egprs_ms_class)
2546{
2547 GprsMs *ms;
2548 uint32_t rach_fn = *fn - 51;
2549 uint32_t sba_fn = *fn + 52;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002550 int tfi = 0;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302551 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302552 RlcMacUplink_t ulreq = {0};
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302553 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302554 Packet_Resource_Request_t *presreq = NULL;
2555 MS_Radio_Access_capability_t *pmsradiocap = NULL;
2556 Multislot_capability_t *pmultislotcap = NULL;
2557
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302558 /* needed to set last_rts_fn in the PDCH object */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002559 request_dl_rlc_block(bts, pdch, fn);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302560
2561 /*
2562 * simulate RACH, this sends an Immediate
2563 * Assignment Uplink on the AGCH
2564 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002565 bts_handle_rach(bts, 0x73, rach_fn, qta);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302566
2567 /* get next free TFI */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002568 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &pdch->trx->trx_no, -1);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302569
2570 /* fake a resource request */
2571 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
2572 presreq = &ulreq.u.Packet_Resource_Request;
2573 presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
2574 presreq->ID.UnionType = 1; /* != 0 */
2575 presreq->ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01002576 presreq->Exist_MS_Radio_Access_capability2 = 1;
2577 pmsradiocap = &presreq->MS_Radio_Access_capability2;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302578 pmsradiocap->Count_MS_RA_capability_value = 1;
2579 pmsradiocap->MS_RA_capability_value[0].u.Content.
2580 Exist_Multislot_capability = 1;
2581 pmultislotcap = &pmsradiocap->MS_RA_capability_value[0].
2582 u.Content.Multislot_capability;
2583
2584 pmultislotcap->Exist_GPRS_multislot_class = 1;
2585 pmultislotcap->GPRS_multislot_class = ms_class;
2586 if (egprs_ms_class) {
2587 pmultislotcap->Exist_EGPRS_multislot_class = 1;
2588 pmultislotcap->EGPRS_multislot_class = ms_class;
2589 }
2590
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002591 send_ul_mac_block(bts, pdch, &ulreq, sba_fn);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302592
2593 /* check the TBF */
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002594 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, pdch->trx->trx_no, pdch->ts_no);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302595 OSMO_ASSERT(ul_tbf);
2596 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
2597
2598 /* send packet uplink assignment */
2599 *fn = sba_fn;
2600 request_dl_rlc_block(ul_tbf, fn);
2601
2602 /* send real acknowledgement */
2603 send_control_ack(ul_tbf);
2604
2605 check_tbf(ul_tbf);
2606
2607 uint8_t data_msg[49] = {0};
2608
Pau Espin Pedrolcde18c52023-04-17 18:16:48 +02002609 ms = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302610 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002611 OSMO_ASSERT(ms_ta(ms) == qta/4);
2612 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302613
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302614 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
2615 egprs3->si = 0;
2616 egprs3->r = 1;
2617 egprs3->cv = 7;
2618 egprs3->tfi_hi = tfi & 0x03;
2619 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
2620 egprs3->bsn1_hi = 0;
2621 egprs3->bsn1_lo = 0;
2622 egprs3->cps_hi = 1;
2623 data_msg[3] = 0xff;
2624 egprs3->pi = 0;
2625 egprs3->cps_lo = 1;
2626 egprs3->rsb = 0;
2627 egprs3->spb = 0;
2628 egprs3->pi = 0;
2629 pdch->rcv_block(data_msg, 49, *fn, &meas);
2630
2631 egprs3->bsn1_hi = 1;
2632 egprs3->bsn1_lo = 0;
2633 data_msg[3] = 0x7f;
2634 egprs3->cps_lo = 1;
2635 egprs3->rsb = 0;
2636 egprs3->spb = 0;
2637 egprs3->pi = 0;
2638 data_msg[4] = 0x2;
2639 data_msg[5] = 0x0;
2640 pdch->rcv_block(data_msg, 49, *fn, &meas);
2641
Pau Espin Pedrol14633832022-03-31 19:08:07 +02002642 OSMO_ASSERT(ul_tbf->m_llc.index == 43);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302643
2644 return ul_tbf;
2645}
2646
2647static void test_tbf_li_decoding(void)
2648{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002649 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002650 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002651 struct gprs_rlcmac_pdch *pdch;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302652 int ts_no = 7;
2653 uint32_t fn = 2654218;
2654 uint16_t qta = 31;
2655 uint32_t tlli = 0xf1223344;
2656 const char *imsi = "0011223344";
2657 uint8_t ms_class = 1;
2658 uint8_t egprs_ms_class = 1;
2659 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302660 uint8_t test_data[256];
2661
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002662 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302663
2664 memset(test_data, 1, sizeof(test_data));
2665
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002666 setup_bts(bts, ts_no, 4);
2667 bts->initial_mcs_dl = 9;
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002668 pdch = &bts->trx[0].pdch[ts_no];
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302669
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002670 ul_tbf = tbf_li_decoding(bts, pdch, tlli, &fn, qta,
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302671 ms_class, egprs_ms_class);
2672
Max4c112dc2018-02-01 16:49:23 +01002673 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002674 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302675
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002676 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002677 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302678}
2679
aravind sirsikarf2761382016-10-25 12:45:24 +05302680/*
2681 * Test that a bit within the uncompressed bitmap whose BSN is not within
2682 * the transmit window shall be ignored. See section 9.1.8.2.4 of 44.060
2683 * version 7.27.0 Release 7.
2684 */
2685static void test_tbf_epdan_out_of_rx_window(void)
2686{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002687 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002688 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
aravind sirsikarf2761382016-10-25 12:45:24 +05302689 uint8_t ms_class = 11;
2690 uint8_t egprs_ms_class = 11;
2691 uint8_t trx_no;
2692 uint32_t tlli = 0xffeeddcc;
2693 gprs_rlcmac_dl_tbf *dl_tbf;
2694 int ts_no = 4;
2695 bitvec *block;
2696 uint8_t bits_data[RLC_EGPRS_MAX_WS/8];
2697 bitvec bits;
2698 int bsn_begin, bsn_end;
2699 EGPRS_PD_AckNack_t *ack_nack;
2700 RlcMacUplink_t ul_control_block;
2701 gprs_rlc_v_b *prlcmvb;
2702 gprs_rlc_dl_window *prlcdlwindow;
Pau Espin Pedrol5e300ce2020-02-03 17:18:03 +01002703 int rc;
aravind sirsikarf2761382016-10-25 12:45:24 +05302704
aravind sirsikarcc4214a2016-12-09 16:12:42 +05302705 memset(&ul_control_block, 0, sizeof(RlcMacUplink_t));
2706
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002707 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikarf2761382016-10-25 12:45:24 +05302708
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002709 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01002710 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
aravind sirsikarf2761382016-10-25 12:45:24 +05302711 /* ARQ II */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01002712 the_pcu->vty.dl_arq_type = EGPRS_ARQ2;
aravind sirsikarf2761382016-10-25 12:45:24 +05302713
2714 /*
2715 * Simulate a message captured during over-the-air testing,
2716 * where the following values were observed:
2717 * v_a = 1176, vs = 1288, max sns = 2048, window size = 480.
2718 */
2719 uint8_t data_msg[23] = {0x40, 0x20, 0x0b, 0xff, 0xd1,
2720 0x61, 0x00, 0x3e, 0x0e, 0x51, 0x9f,
2721 0xff, 0xff, 0xfb, 0x80, 0x00, 0x00,
2722 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
2723
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002724 dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no);
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +02002725 ms_confirm_tlli(dl_tbf->ms(), tlli);
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002726 prlcdlwindow = static_cast<gprs_rlc_dl_window *>(dl_tbf->window());
aravind sirsikarf2761382016-10-25 12:45:24 +05302727 prlcmvb = &prlcdlwindow->m_v_b;
2728 prlcdlwindow->m_v_s = 1288;
2729 prlcdlwindow->m_v_a = 1176;
2730 prlcdlwindow->set_sns(2048);
2731 prlcdlwindow->set_ws(480);
2732 prlcmvb->mark_unacked(1176);
2733 prlcmvb->mark_unacked(1177);
2734 prlcmvb->mark_unacked(1286);
2735 prlcmvb->mark_unacked(1287);
2736
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002737 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
aravind sirsikarf2761382016-10-25 12:45:24 +05302738
Alexander Couzensccde5c92017-02-04 03:10:08 +01002739 block = bitvec_alloc(23, tall_pcu_ctx);
aravind sirsikarf2761382016-10-25 12:45:24 +05302740
2741 bitvec_unpack(block, data_msg);
2742
2743 bits.data = bits_data;
2744 bits.data_len = sizeof(bits_data);
2745 bits.cur_bit = 0;
2746
Pau Espin Pedrol5e300ce2020-02-03 17:18:03 +01002747 rc = decode_gsm_rlcmac_uplink(block, &ul_control_block);
2748 OSMO_ASSERT(rc == 0);
aravind sirsikarf2761382016-10-25 12:45:24 +05302749
2750 ack_nack = &ul_control_block.u.Egprs_Packet_Downlink_Ack_Nack;
2751
2752 OSMO_ASSERT(prlcmvb->is_unacked(1176));
2753 OSMO_ASSERT(prlcmvb->is_unacked(1177));
2754 OSMO_ASSERT(prlcmvb->is_unacked(1286));
2755 OSMO_ASSERT(prlcmvb->is_unacked(1287));
2756
2757 Decoding::decode_egprs_acknack_bits(
2758 &ack_nack->EGPRS_AckNack.Desc, &bits,
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002759 &bsn_begin, &bsn_end, prlcdlwindow);
aravind sirsikarf2761382016-10-25 12:45:24 +05302760
2761 dl_tbf->rcvd_dl_ack(
2762 ack_nack->EGPRS_AckNack.Desc.FINAL_ACK_INDICATION,
2763 bsn_begin, &bits);
aravind sirsikarf2761382016-10-25 12:45:24 +05302764
aravind sirsikarfb41afa2016-11-02 15:48:00 +05302765 OSMO_ASSERT(prlcmvb->is_invalid(1176));
2766 OSMO_ASSERT(prlcmvb->is_invalid(1177));
2767 OSMO_ASSERT(prlcmvb->is_acked(1286));
2768 OSMO_ASSERT(prlcmvb->is_acked(1287));
aravind sirsikarf2761382016-10-25 12:45:24 +05302769
2770 bitvec_free(block);
2771 tbf_free(dl_tbf);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002772 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002773 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikarf2761382016-10-25 12:45:24 +05302774}
2775
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302776static void test_tbf_egprs_two_phase_spb(void)
2777{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002778 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002779 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002780 struct gprs_rlcmac_pdch *pdch;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302781 int ts_no = 7;
2782 uint32_t fn = 2654218;
2783 uint16_t qta = 31;
2784 uint32_t tlli = 0xf1223344;
2785 const char *imsi = "0011223344";
2786 uint8_t ms_class = 1;
2787 uint8_t egprs_ms_class = 1;
2788 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302789 uint8_t test_data[256];
2790
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002791 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302792
2793 memset(test_data, 1, sizeof(test_data));
2794
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002795 setup_bts(bts, ts_no, 4);
2796 bts->initial_mcs_dl = 9;
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002797 pdch = &bts->trx[0].pdch[ts_no];
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302798
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002799 ul_tbf = establish_ul_tbf_two_phase_spb(bts, pdch, tlli, &fn, qta,
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302800 ms_class, egprs_ms_class);
2801
Max4c112dc2018-02-01 16:49:23 +01002802 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002803 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302804
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002805 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002806 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302807}
2808
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002809static void test_tbf_egprs_two_phase()
2810{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002811 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002812 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002813 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002814 int ts_no = 7;
2815 uint32_t fn = 2654218;
2816 uint16_t qta = 31;
2817 uint32_t tlli = 0xf1223344;
2818 const char *imsi = "0011223344";
2819 uint8_t ms_class = 1;
2820 uint8_t egprs_ms_class = 1;
2821 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002822 uint8_t test_data[256];
2823
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002824 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002825
2826 memset(test_data, 1, sizeof(test_data));
2827
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002828 setup_bts(bts, ts_no, 4);
2829 bts->initial_mcs_dl = 9;
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002830 pdch = &bts->trx[0].pdch[ts_no];
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002831
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01002832 ul_tbf = establish_ul_tbf_two_phase(bts, pdch, tlli, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002833 ms_class, egprs_ms_class);
2834
Max4c112dc2018-02-01 16:49:23 +01002835 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002836 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002837
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002838 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002839 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002840}
2841
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002842static void establish_and_use_egprs_dl_tbf(struct gprs_rlcmac_bts *bts, int mcs)
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002843{
2844 unsigned i;
2845 uint8_t ms_class = 11;
2846 uint8_t egprs_ms_class = 11;
2847 uint32_t fn = 0;
2848 uint8_t trx_no;
2849 uint32_t tlli = 0xffeeddcc;
2850 uint8_t test_data[512];
2851
2852 uint8_t rbb[64/8];
2853
2854 gprs_rlcmac_dl_tbf *dl_tbf;
2855
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002856 fprintf(stderr, "Testing MCS-%d\n", mcs);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002857
2858 memset(test_data, 1, sizeof(test_data));
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002859 bts->initial_mcs_dl = mcs;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002860
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002861 dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no);
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +02002862 ms_confirm_tlli(dl_tbf->ms(), tlli);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002863
2864 for (i = 0; i < sizeof(llc_data); i++)
2865 llc_data[i] = i%256;
2866
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002867 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002868
2869 /* Schedule a small LLC frame */
Pau Espin Pedrol14beef62022-10-26 19:44:07 +02002870 ms_append_llc_dl_data(dl_tbf->ms(), 1000, test_data, 10);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002871
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002872 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002873
2874 /* Drain the queue */
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01002875 while (dl_tbf->have_data()) {
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002876 /* Request to send one RLC/MAC block */
2877 request_dl_rlc_block(dl_tbf, &fn);
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01002878 }
Pau Espin Pedrol16e16782021-03-29 19:10:19 +02002879 send_empty_block(dl_tbf, dl_tbf->control_ts, fn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002880
2881 /* Schedule a large LLC frame */
Pau Espin Pedrol14beef62022-10-26 19:44:07 +02002882 ms_append_llc_dl_data(dl_tbf->ms(), 1000, test_data, sizeof(test_data));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002883
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002884 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002885
2886 /* Drain the queue */
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01002887 while (dl_tbf->have_data()) {
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002888 /* Request to send one RLC/MAC block */
2889 request_dl_rlc_block(dl_tbf, &fn);
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01002890 }
Pau Espin Pedrol16e16782021-03-29 19:10:19 +02002891 send_empty_block(dl_tbf, dl_tbf->control_ts, fn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002892
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002893 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002894
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +02002895 _rcv_ack(true, dl_tbf, rbb); /* Receive a final ACK */
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002896
2897 /* Clean up and ensure tbfs are in the correct state */
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002898 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_WAIT_RELEASE));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002899 check_tbf(dl_tbf);
2900 tbf_free(dl_tbf);
2901}
2902
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002903static gprs_rlcmac_dl_tbf *tbf_init(struct gprs_rlcmac_bts *bts,
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302904 int mcs)
2905{
2906 unsigned i;
2907 uint8_t ms_class = 11;
2908 uint8_t egprs_ms_class = 11;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302909 uint8_t trx_no;
2910 uint32_t tlli = 0xffeeddcc;
2911 uint8_t test_data[512];
2912
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302913 gprs_rlcmac_dl_tbf *dl_tbf;
2914
2915 memset(test_data, 1, sizeof(test_data));
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002916 bts->initial_mcs_dl = mcs;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302917
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002918 dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no);
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +02002919 ms_confirm_tlli(dl_tbf->ms(), tlli);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302920
2921 for (i = 0; i < sizeof(test_data); i++)
2922 test_data[i] = i%256;
2923
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002924 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302925
2926 /* Schedule a LLC frame
2927 * passing only 100 bytes, since it is enough to construct
2928 * 2 RLC data blocks. Which are enough to test Header Type 1
2929 * cases
2930 */
Pau Espin Pedrol14beef62022-10-26 19:44:07 +02002931 ms_append_llc_dl_data(dl_tbf->ms(), 1000, test_data, 100);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302932
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002933 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302934
2935 return dl_tbf;
2936
2937}
2938
2939static void tbf_cleanup(gprs_rlcmac_dl_tbf *dl_tbf)
2940{
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302941 uint8_t rbb[64/8];
2942
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +02002943 _rcv_ack(true, dl_tbf, rbb); /* Receive a final ACK */
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302944
2945 /* Clean up and ensure tbfs are in the correct state */
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002946 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_WAIT_RELEASE));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302947 check_tbf(dl_tbf);
2948 tbf_free(dl_tbf);
2949
2950}
2951
Max7d32f552017-12-15 11:25:14 +01002952#define NACK(tbf, x) do { \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002953 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
2954 w->m_v_b.mark_nacked(x); \
2955 OSMO_ASSERT(w->m_v_b.is_nacked(x)); \
Max7d32f552017-12-15 11:25:14 +01002956 } while(0)
2957
2958#define CHECK_UNACKED(tbf, cs, bsn) do { \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002959 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
2960 OSMO_ASSERT(w->m_v_b.is_unacked(bsn)); \
Max898dddb2019-03-12 15:50:57 +01002961 OSMO_ASSERT(mcs_chan_code(tbf->m_rlc.block(bsn)->cs_current_trans) == cs - 1); \
Max7d32f552017-12-15 11:25:14 +01002962 } while(0)
2963
2964#define CHECK_NACKED(tbf, cs, bsn) do { \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002965 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
2966 OSMO_ASSERT(w->m_v_b.is_nacked(bsn)); \
Max898dddb2019-03-12 15:50:57 +01002967 OSMO_ASSERT(mcs_chan_code(tbf->m_rlc.block(bsn)->cs_current_trans) == cs - 1); \
Max7d32f552017-12-15 11:25:14 +01002968 } while(0)
2969
2970#define MAKE_ACKED(m, tbf, fn, cs, check_unacked) do { \
Pau Espin Pedrold29a1432022-12-15 18:57:35 +01002971 m = tbf->create_dl_acked_block(fn, tbf->control_ts); \
Max7d32f552017-12-15 11:25:14 +01002972 OSMO_ASSERT(m); \
2973 if (check_unacked) \
2974 CHECK_UNACKED(tbf, cs, 0); \
2975 else \
2976 CHECK_NACKED(tbf, cs, 0); \
2977 } while(0)
2978
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002979static void egprs_spb_to_normal_validation(struct gprs_rlcmac_bts *bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002980 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302981{
2982 uint32_t fn = 0;
2983 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302984 uint16_t bsn1, bsn2, bsn3;
2985 struct msgb *msg;
2986 struct gprs_rlc_dl_header_egprs_3 *egprs3;
2987 struct gprs_rlc_dl_header_egprs_2 *egprs2;
2988
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002989 fprintf(stderr, "Testing retx for MCS %u to reseg_mcs %u\n", mcs, demanded_mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302990
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002991 dl_tbf = tbf_init(bts, mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302992
2993 /*
2994 * Table 10.4.8a.3.1 of 44.060.
2995 * (MCS7, MCS9) to (MCS2, MCS3) is not handled since it is same as
2996 * (MCS5, MCS6) to (MCS2, MCS3) transition
2997 */
2998 if (!(mcs == 6 && demanded_mcs == 3))
2999 return;
3000
3001 fn = fn_add_blocks(fn, 1);
3002 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01003003 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303004
3005 egprs2 = (struct gprs_rlc_dl_header_egprs_2 *) msg->data;
Maxb4d368b2017-12-01 17:54:39 +01003006 bsn1 = (egprs2->bsn1_hi << 9) | (egprs2->bsn1_mid << 1) | (egprs2->bsn1_lo);
Max7d32f552017-12-15 11:25:14 +01003007
3008 NACK(dl_tbf, 0);
3009
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303010 OSMO_ASSERT(bsn1 == 0);
3011
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003012 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303013
3014 fn = fn_add_blocks(fn, 1);
3015
3016 /* Send first segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003017 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, false);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303018 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
3019 == EGPRS_RESEG_FIRST_SEG_SENT);
3020
3021 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
3022 OSMO_ASSERT(egprs3->spb == 2);
3023
3024 /* Table 10.4.8a.3.1 of 44.060 */
3025 OSMO_ASSERT(egprs3->cps == 3);
3026
3027 /* Send second segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003028 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303029 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
3030 == EGPRS_RESEG_SECOND_SEG_SENT);
3031
3032 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
3033 /* Table 10.4.8a.3.1 of 44.060 */
3034 OSMO_ASSERT(egprs3->spb == 3);
Maxb4d368b2017-12-01 17:54:39 +01003035 bsn2 = (egprs3->bsn1_hi << 9) | (egprs3->bsn1_mid << 1) | (egprs3->bsn1_lo);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303036 OSMO_ASSERT(bsn2 == bsn1);
3037
3038 /* Table 10.4.8a.3.1 of 44.060 */
3039 OSMO_ASSERT(egprs3->cps == 3);
3040
3041 /* Handle (MCS3, MCS3) -> MCS6 case */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003042 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303043
Max7d32f552017-12-15 11:25:14 +01003044 NACK(dl_tbf, 0);
3045
Pau Espin Pedrold29a1432022-12-15 18:57:35 +01003046 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303047 egprs2 = (struct gprs_rlc_dl_header_egprs_2 *) msg->data;
3048
3049 /* Table 10.4.8a.3.1 of 44.060 */
3050 OSMO_ASSERT(egprs2->cps == 0);
Maxb4d368b2017-12-01 17:54:39 +01003051 bsn3 = (egprs2->bsn1_hi << 9) | (egprs2->bsn1_mid << 1) | (egprs2->bsn1_lo);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303052 OSMO_ASSERT(bsn3 == bsn2);
3053
3054 tbf_cleanup(dl_tbf);
3055}
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01003056
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003057static void establish_and_use_egprs_dl_tbf_for_spb(struct gprs_rlcmac_bts *bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01003058 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303059{
3060 uint32_t fn = 0;
3061 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303062 struct msgb *msg;
3063 struct gprs_rlc_dl_header_egprs_3 *egprs3;
3064
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003065 fprintf(stderr, "Testing retx for MCS %u to reseg_mcs %u\n", mcs, demanded_mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303066
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003067 dl_tbf = tbf_init(bts, mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303068
3069 /*
3070 * Table 10.4.8a.3.1 of 44.060.
3071 * (MCS7, MCS9) to (MCS2, MCS3) is not handled since it is same as
3072 * (MCS5, MCS6) to (MCS2, MCS3) transition
3073 */
3074 /* TODO: Need to support of MCS8 -> MCS6 ->MCS3 transistion
3075 * Refer commit be881c028fc4da00c4046ecd9296727975c206a3
3076 * dated 2016-02-07 23:45:40 (UTC)
3077 */
3078 if (!(((mcs == 5) && (demanded_mcs == 2)) ||
3079 ((mcs == 6) && (demanded_mcs == 3)) ||
3080 ((mcs == 4) && (demanded_mcs == 1))))
3081 return;
3082
3083 fn = fn_add_blocks(fn, 1);
3084 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01003085 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303086
Max7d32f552017-12-15 11:25:14 +01003087 NACK(dl_tbf, 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303088
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003089 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303090
3091 fn = fn_add_blocks(fn, 1);
3092
3093 /* Send first segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003094 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, false);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303095 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
3096 == EGPRS_RESEG_FIRST_SEG_SENT);
3097
3098 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
3099 OSMO_ASSERT(egprs3->spb == 2);
3100
3101 /* Table 10.4.8a.3.1 of 44.060 */
3102 switch (demanded_mcs) {
3103 case 3:
3104 OSMO_ASSERT(egprs3->cps == 3);
3105 break;
3106 case 2:
3107 OSMO_ASSERT(egprs3->cps == 9);
3108 break;
3109 case 1:
3110 OSMO_ASSERT(egprs3->cps == 11);
3111 break;
3112 default:
3113 OSMO_ASSERT(false);
3114 break;
3115 }
3116
3117 /* Send second segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003118 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303119 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
3120 == EGPRS_RESEG_SECOND_SEG_SENT);
3121
3122 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
3123 /* Table 10.4.8a.3.1 of 44.060 */
3124 OSMO_ASSERT(egprs3->spb == 3);
3125
3126 /* Table 10.4.8a.3.1 of 44.060 */
3127 switch (demanded_mcs) {
3128 case 3:
3129 OSMO_ASSERT(egprs3->cps == 3);
3130 break;
3131 case 2:
3132 OSMO_ASSERT(egprs3->cps == 9);
3133 break;
3134 case 1:
3135 OSMO_ASSERT(egprs3->cps == 11);
3136 break;
3137 default:
3138 OSMO_ASSERT(false);
3139 break;
3140 }
3141 tbf_cleanup(dl_tbf);
3142}
3143
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003144static void establish_and_use_egprs_dl_tbf_for_retx(struct gprs_rlcmac_bts *bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01003145 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303146{
3147 uint32_t fn = 0;
3148 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303149 struct msgb *msg;
3150
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003151 fprintf(stderr, "Testing retx for MCS %u - %u\n", mcs, demanded_mcs);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303152
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003153 dl_tbf = tbf_init(bts, mcs);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303154
3155 /* For MCS reduction cases like MCS9->MCS6, MCS7->MCS5
3156 * The MCS transition are referred from table Table 8.1.1.2
3157 * of TS 44.060
3158 */
3159 /* TODO: Need to support of MCS8 -> MCS6 transistion
3160 * Refer commit be881c028fc4da00c4046ecd9296727975c206a3
3161 * dated 2016-02-07 23:45:40 (UTC)
3162 */
3163 if (((mcs == 9) && (demanded_mcs < 9)) ||
3164 ((mcs == 7) && (demanded_mcs < 7))) {
3165 fn = fn_add_blocks(fn, 1);
3166 /* Send 2 RLC data block */
Max7d32f552017-12-15 11:25:14 +01003167 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3168 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303169
Max7d32f552017-12-15 11:25:14 +01003170 NACK(dl_tbf, 0);
3171 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303172
3173 /* Set the demanded MCS to demanded_mcs */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003174 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303175
3176 fn = fn_add_blocks(fn, 1);
3177 /* Retransmit the first RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003178 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
3179 CHECK_NACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303180
3181 fn = fn_add_blocks(fn, 1);
3182 /* Retransmit the second RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003183 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
3184 CHECK_UNACKED(dl_tbf, demanded_mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303185 } else if (((mcs == 5) && (demanded_mcs > 6)) ||
3186 ((mcs == 6) && (demanded_mcs > 8))) {
3187 fn = fn_add_blocks(fn, 1);
3188 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01003189 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303190
3191 fn = fn_add_blocks(fn, 1);
3192 /* Send second RLC data block BSN 1 */
Max7d32f552017-12-15 11:25:14 +01003193 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3194 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303195
Max7d32f552017-12-15 11:25:14 +01003196 NACK(dl_tbf, 0);
3197 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303198
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003199 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303200
3201 fn = fn_add_blocks(fn, 1);
3202 /* Send first, second RLC data blocks with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003203 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
3204 CHECK_UNACKED(dl_tbf, demanded_mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303205 } else if (mcs > 6) {
3206 /* No Mcs change cases are handled here for mcs > MCS6*/
3207 fn = fn_add_blocks(fn, 1);
3208 /* Send first,second RLC data blocks */
Max7d32f552017-12-15 11:25:14 +01003209 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3210 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303211
Max7d32f552017-12-15 11:25:14 +01003212 NACK(dl_tbf, 0);
3213 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303214
3215 fn = fn_add_blocks(fn, 1);
3216 /* Send first,second RLC data blocks with demanded_mcs*/
Max7d32f552017-12-15 11:25:14 +01003217 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3218 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303219 } else {
3220
3221 /* No MCS change cases are handled here for mcs <= MCS6*/
3222 fn = fn_add_blocks(fn, 1);
3223 /* Send first RLC data block */
Max7d32f552017-12-15 11:25:14 +01003224 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303225
Max7d32f552017-12-15 11:25:14 +01003226 NACK(dl_tbf, 0);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303227
3228 fn = fn_add_blocks(fn, 1);
3229 /* Send first RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003230 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303231 }
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01003232 /* Clean up pending items in UL controller: */
Pau Espin Pedrol16e16782021-03-29 19:10:19 +02003233 send_empty_block(dl_tbf, dl_tbf->control_ts, fn+50);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303234 tbf_cleanup(dl_tbf);
3235}
3236
3237static void test_tbf_egprs_retx_dl(void)
3238{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003239 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003240 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303241 uint8_t ts_no = 4;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303242
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003243 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303244
Pau Espin Pedrolad79b852021-01-14 13:20:55 +01003245 the_pcu->vty.cs_downgrade_threshold = 0;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003246 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01003247 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303248 /* ARQ II */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01003249 the_pcu->vty.dl_arq_type = EGPRS_ARQ2;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303250
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303251
3252 /* First parameter is current MCS, second one is demanded_mcs */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003253 establish_and_use_egprs_dl_tbf_for_retx(bts, 6, 6);
3254 establish_and_use_egprs_dl_tbf_for_retx(bts, 1, 9);
3255 establish_and_use_egprs_dl_tbf_for_retx(bts, 2, 8);
3256 establish_and_use_egprs_dl_tbf_for_retx(bts, 5, 7);
3257 establish_and_use_egprs_dl_tbf_for_retx(bts, 6, 9);
3258 establish_and_use_egprs_dl_tbf_for_retx(bts, 7, 5);
3259 establish_and_use_egprs_dl_tbf_for_retx(bts, 9, 6);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303260
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003261 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003262 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303263}
3264
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303265static void test_tbf_egprs_spb_dl(void)
3266{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003267 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003268 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303269 uint8_t ts_no = 4;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303270
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003271 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303272
Pau Espin Pedrolad79b852021-01-14 13:20:55 +01003273 the_pcu->vty.cs_downgrade_threshold = 0;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003274 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01003275 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303276
3277 /* ARQ I resegmentation support */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01003278 the_pcu->vty.dl_arq_type = EGPRS_ARQ1;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303279
3280 /*
3281 * First parameter is current MCS, second one is demanded_mcs
3282 * currently only MCS5->MCS2, MCS6->3, MCS4->MCS1 is tested in UT
3283 * rest scenarios has been integration tested
3284 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003285 establish_and_use_egprs_dl_tbf_for_spb(bts, 6, 3);
3286 establish_and_use_egprs_dl_tbf_for_spb(bts, 5, 2);
3287 establish_and_use_egprs_dl_tbf_for_spb(bts, 4, 1);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303288 /* check MCS6->(MCS3+MCS3)->MCS6 case */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003289 egprs_spb_to_normal_validation(bts, 6, 3);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303290
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003291 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003292 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303293}
3294
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003295static void test_tbf_egprs_dl()
3296{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003297 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003298 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003299 uint8_t ts_no = 4;
3300 int i;
3301
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003302 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003303
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003304 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01003305 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303306 /* ARQ II */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01003307 the_pcu->vty.dl_arq_type = EGPRS_ARQ2;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003308
3309 for (i = 1; i <= 9; i++)
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003310 establish_and_use_egprs_dl_tbf(bts, i);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003311
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003312 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003313 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003314}
3315
3316
3317
aravind sirsikare9a138e2017-01-24 12:36:08 +05303318static void test_packet_access_rej_prr_no_other_tbfs()
3319{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003320 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003321 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003322 struct gprs_rlcmac_pdch *pdch;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303323 uint32_t fn = 2654218;
3324 int ts_no = 7;
3325 uint8_t trx_no = 0;
3326 uint32_t tlli = 0xffeeddcc;
Pau Espin Pedrol54742f22021-04-26 16:48:34 +02003327 struct gprs_rlcmac_ul_tbf *ul_tbf;
3328 struct GprsMs *ms;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303329
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003330 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303331
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003332 setup_bts(bts, ts_no, 4);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003333 pdch = &bts->trx[trx_no].pdch[ts_no];
Pau Espin Pedrol9d67e722021-07-28 19:25:38 +02003334 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2000, 0, OSMO_TDEF_MS) == 0);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303335
3336 int rc = 0;
3337
Pau Espin Pedrol9da06862023-04-17 19:00:04 +02003338 ms = ms_alloc(bts);
Pau Espin Pedrol54742f22021-04-26 16:48:34 +02003339 ms_set_tlli(ms, tlli);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003340 ul_tbf = ms_new_ul_tbf_rejected_pacch(ms, pdch);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303341
3342 OSMO_ASSERT(ul_tbf != 0);
3343
3344 /* trigger packet access reject */
3345 uint8_t bn = fn2bn(fn);
3346
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003347 rc = gprs_rlcmac_rcv_rts_block(bts, pdch->trx->trx_no, pdch->ts_no, fn, bn);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303348
3349 OSMO_ASSERT(rc == 0);
Pau Espin Pedrol9d67e722021-07-28 19:25:38 +02003350 osmo_select_main(0);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303351
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003352 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003353 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303354}
3355
3356static void test_packet_access_rej_prr()
3357{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003358 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003359 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003360 struct gprs_rlcmac_pdch *pdch;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303361 uint32_t fn = 2654218;
3362 uint16_t qta = 31;
3363 int ts_no = 7;
3364 uint8_t trx_no = 0;
3365 RlcMacUplink_t ulreq = {0};
3366 Packet_Resource_Request_t *presreq = NULL;
3367 uint8_t ms_class = 11;
3368 uint8_t egprs_ms_class = 11;
3369 uint32_t rach_fn = fn - 51;
3370 uint32_t sba_fn = fn + 52;
3371 uint32_t tlli = 0xffeeddcc;
3372 MS_Radio_Access_capability_t *pmsradiocap = NULL;
3373 Multislot_capability_t *pmultislotcap = NULL;
3374
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003375 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303376
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003377 setup_bts(bts, ts_no, 4);
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003378 pdch = &bts->trx[trx_no].pdch[ts_no];
aravind sirsikare9a138e2017-01-24 12:36:08 +05303379
3380 int rc = 0;
3381
3382 /*
3383 * Trigger rach till resources(USF) exhaust
3384 */
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003385 int i;
3386 for (i = 0; i < 8; i++) {
3387 rc = bts_handle_rach(bts, 0x70 + i, rach_fn, qta);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303388 }
3389
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003390 sba_fn = 52;
3391 for (i = 0; i < 8; i++) {
3392 /* fake a resource request */
3393 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
3394 presreq = &ulreq.u.Packet_Resource_Request;
3395 presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
3396 presreq->ID.UnionType = 1; /* != 0 */
3397 presreq->ID.u.TLLI = tlli + i;
3398 presreq->Exist_MS_Radio_Access_capability2 = 1;
3399 pmsradiocap = &presreq->MS_Radio_Access_capability2;
3400 pmsradiocap->Count_MS_RA_capability_value = 1;
3401 pmsradiocap->MS_RA_capability_value[0].u.Content.
3402 Exist_Multislot_capability = 1;
3403 pmultislotcap = &pmsradiocap->MS_RA_capability_value[0].
3404 u.Content.Multislot_capability;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303405
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003406 pmultislotcap->Exist_GPRS_multislot_class = 1;
3407 pmultislotcap->GPRS_multislot_class = ms_class;
3408 if (egprs_ms_class) {
3409 pmultislotcap->Exist_EGPRS_multislot_class = 1;
3410 pmultislotcap->EGPRS_multislot_class = egprs_ms_class;
3411 }
aravind sirsikare9a138e2017-01-24 12:36:08 +05303412
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003413 send_ul_mac_block(bts, pdch, &ulreq, sba_fn);
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003414 sba_fn = fn_next_block(sba_fn);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303415
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003416 /* trigger packet access reject */
3417 uint8_t bn = fn2bn(fn);
3418
Pau Espin Pedrole2ed40d2022-12-15 17:35:05 +01003419 rc = gprs_rlcmac_rcv_rts_block(bts, pdch->trx->trx_no, pdch->ts_no, fn, bn);
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003420 OSMO_ASSERT(rc == 0);
3421 }
aravind sirsikare9a138e2017-01-24 12:36:08 +05303422
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003423 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003424 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303425}
3426
aravind sirsikared3413e2016-11-11 17:15:10 +05303427void test_packet_access_rej_epdan()
3428{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003429 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003430 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
aravind sirsikared3413e2016-11-11 17:15:10 +05303431 uint32_t tlli = 0xffeeddcc;
Pau Espin Pedrol2ab840a2021-04-26 17:49:05 +02003432 static uint8_t exp[] = { 0x40, 0x84, 0x7f, 0xf7, 0x6e, 0xe6, 0x7e, 0xab,
Maxd3a0d912019-03-05 16:15:01 +01003433 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
3434 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b
3435 };
aravind sirsikared3413e2016-11-11 17:15:10 +05303436
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003437 fprintf(stderr, "=== start %s ===\n", __func__);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003438 setup_bts(bts, 4);
3439 static gprs_rlcmac_dl_tbf *dl_tbf = tbf_init(bts, 1);
aravind sirsikared3413e2016-11-11 17:15:10 +05303440
Pau Espin Pedrol8abe13c2022-10-21 18:49:48 +02003441 ms_confirm_tlli(dl_tbf->ms(), tlli);
aravind sirsikared3413e2016-11-11 17:15:10 +05303442
Pau Espin Pedrol6ad11a62021-07-27 12:27:08 +02003443 osmo_fsm_inst_dispatch(dl_tbf->ul_ass_fsm.fi, TBF_UL_ASS_EV_SCHED_ASS_REJ, NULL);
3444 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 +05303445
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003446 fprintf(stderr, "packet reject: %s\n",
aravind sirsikared3413e2016-11-11 17:15:10 +05303447 osmo_hexdump(msg->data, 23));
3448
Maxd3a0d912019-03-05 16:15:01 +01003449 if (!msgb_eq_data_print(msg, exp, GSM_MACBLOCK_LEN))
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003450 fprintf(stderr, "%s test failed!\n", __func__);
Maxd3a0d912019-03-05 16:15:01 +01003451
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003452 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003453 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikared3413e2016-11-11 17:15:10 +05303454}
3455
3456
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003457int main(int argc, char **argv)
3458{
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003459 struct vty_app_info pcu_vty_info = {0};
3460
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003461 tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile TbfTest context");
3462 if (!tall_pcu_ctx)
3463 abort();
3464
Neels Hofmeyr78ce5912017-02-08 17:07:31 +01003465 msgb_talloc_ctx_init(tall_pcu_ctx, 0);
Neels Hofmeyr42f2d612018-04-01 16:54:40 +02003466 osmo_init_logging2(tall_pcu_ctx, &gprs_log_info);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003467 log_set_use_color(osmo_stderr_target, 0);
Pau Espin Pedrol00f52cc2021-02-19 14:01:52 +01003468 log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
Pau Espin Pedrolb18d2a52021-02-19 14:00:48 +01003469 log_set_print_category(osmo_stderr_target, 0);
3470 log_set_print_category_hex(osmo_stderr_target, 0);
Maxfdd79e92018-01-24 11:04:59 +01003471 log_parse_category_mask(osmo_stderr_target, "DRLCMAC,1:DRLCMACDATA,3:DRLCMACDL,3:DRLCMACUL,3:"
Harald Welte398f60e2020-12-10 13:39:21 +01003472 "DRLCMACSCHED,1:DRLCMACMEAS,3:DNS,3:DLBSSGP,3:DPCU,5:"
Max86e35e42019-03-07 12:20:42 +01003473 "DL1IF,6:DTBF,1:DTBFUL,1:DTBFDL,1:DLGLOBAL,2:");
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02003474 osmo_fsm_log_addr(false);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003475 vty_init(&pcu_vty_info);
Pau Espin Pedrolcd2ac562019-08-05 14:30:44 +02003476 pcu_vty_init();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003477
Vadim Yanitskiy87b6e7d2019-11-08 04:44:04 +07003478 /* Initialize shared UL measurements */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003479 pcu_l1_meas_set_link_qual(&meas, 12);
3480 pcu_l1_meas_set_rssi(&meas, 31);
Vadim Yanitskiy87b6e7d2019-11-08 04:44:04 +07003481
Jacob Erlbeckac89a552015-06-29 14:18:46 +02003482 test_tbf_base();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003483 test_tbf_tlli_update();
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +01003484 test_tbf_final_ack(TEST_MODE_STANDARD);
3485 test_tbf_final_ack(TEST_MODE_REVERSE_FREE);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +01003486 test_tbf_delayed_release();
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +02003487 test_tbf_imsi();
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003488 test_tbf_exhaustion();
Jacob Erlbeck41168642015-06-12 13:41:00 +02003489 test_tbf_dl_llc_loss();
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02003490 test_tbf_single_phase();
Pau Espin Pedrol22b26d82022-10-26 15:44:14 +02003491 test_tbf_single_phase2();
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02003492 test_tbf_two_phase();
Jacob Erlbeckb1395982015-08-21 18:15:38 +02003493 test_tbf_ra_update_rach();
3494 test_tbf_dl_flow_and_rach_two_phase();
3495 test_tbf_dl_flow_and_rach_single_phase();
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02003496 test_tbf_dl_reuse();
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01003497 test_tbf_gprs_egprs();
Jacob Erlbeck36df7742016-01-19 15:53:30 +01003498 test_tbf_ws();
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003499 test_tbf_egprs_two_phase();
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05303500 test_tbf_egprs_two_phase_spb();
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003501 test_tbf_egprs_dl();
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303502 test_tbf_egprs_retx_dl();
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303503 test_tbf_egprs_spb_dl();
Aravind Sirsikar02352b42016-08-25 16:37:30 +05303504 test_tbf_puan_urbb_len();
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05303505 test_tbf_update_ws();
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05303506 test_tbf_li_decoding();
aravind sirsikarf2761382016-10-25 12:45:24 +05303507 test_tbf_epdan_out_of_rx_window();
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05303508 test_immediate_assign_rej();
sivasankari1d8744c2017-01-24 15:53:35 +05303509 test_tbf_egprs_two_phase_puan();
aravind sirsikared3413e2016-11-11 17:15:10 +05303510 test_packet_access_rej_epdan();
aravind sirsikare9a138e2017-01-24 12:36:08 +05303511 test_packet_access_rej_prr();
3512 test_packet_access_rej_prr_no_other_tbfs();
Pau Espin Pedrol0aacd212022-12-16 16:15:34 +01003513 test_ms_merge_dl_tbf_different_trx();
Jacob Erlbeck67c38502015-05-11 10:32:40 +02003514
3515 if (getenv("TALLOC_REPORT_FULL"))
3516 talloc_report_full(tall_pcu_ctx, stderr);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003517 return EXIT_SUCCESS;
3518}
3519
3520/*
3521 * stubs that should not be reached
3522 */
3523extern "C" {
3524void l1if_pdch_req() { abort(); }
3525void l1if_connect_pdch() { abort(); }
Philipp Maier72ed3332023-02-27 15:32:00 +01003526void l1if_disconnect_pdch() { abort(); }
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003527void l1if_close_pdch() { abort(); }
3528void l1if_open_pdch() { abort(); }
3529}