blob: d921cbeef5b17841fb9161c4570491029e29836e [file] [log] [blame]
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01001/*
2 * TbfTest.cpp
3 *
4 * Copyright (C) 2013 by Holger Hans Peter Freyther
5 *
6 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Affero General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU Affero General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23#include "bts.h"
24#include "tbf.h"
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010025#include "tbf_dl.h"
Pau Espin Pedrol9d1cdb12019-09-25 17:47:02 +020026#include "tbf_ul.h"
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010027#include "gprs_ms.h"
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010028#include "gprs_debug.h"
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010029#include "gprs_ms_storage.h"
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +010030#include "pcu_utils.h"
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020031#include "gprs_bssgp_pcu.h"
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +020032#include "pcu_l1_if.h"
aravind sirsikarf2761382016-10-25 12:45:24 +053033#include "decoding.h"
Max1187a772018-01-26 13:31:42 +010034#include <gprs_rlcmac.h>
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010035
36extern "C" {
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020037#include "pcu_vty.h"
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +020038#include "coding_scheme.h"
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>
Aravind Sirsikar505a86d2016-07-26 18:26:21 +053045#include <osmocom/gprs/protocol/gsm_04_60.h>
bhargava959d1de2016-08-17 15:17:21 +053046#include <osmocom/gsm/l1sap.h>
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010047}
48
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020049#include <errno.h>
50
Philippd935d882016-11-07 13:07:36 +010051#define DUMMY_FN 2654167
52
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010053void *tall_pcu_ctx;
54int16_t spoof_mnc = 0, spoof_mcc = 0;
Neels Hofmeyrbdc55fa2018-02-21 00:39:07 +010055bool spoof_mnc_3_digits = false;
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010056
Vadim Yanitskiy87b6e7d2019-11-08 04:44:04 +070057/* Measurements shared by all unit tests */
58static struct pcu_l1_meas meas;
59
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010060static 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 +070061{
62 struct rach_ind_params rip = {
63 .burst_type = GSM_L1_BURST_TYPE_ACCESS_0,
64 .is_11bit = false,
65 .ra = ra,
66 .trx_nr = 0,
67 .ts_nr = 0,
68 .rfn = Fn,
69 .qta = qta,
70 };
71
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010072 return bts_rcv_rach(bts, &rip);
Vadim Yanitskiya0a0b7f2020-05-21 19:55:46 +070073}
74
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +010075static void check_tbf(gprs_rlcmac_tbf *tbf)
76{
77 OSMO_ASSERT(tbf);
Jacob Erlbeck04e72d32015-08-13 18:36:56 +020078 if (tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE))
Maxee5be3a2017-12-20 17:31:13 +010079 OSMO_ASSERT(tbf->timers_pending(T3191) || tbf->timers_pending(T3193));
Jacob Erlbeck04e72d32015-08-13 18:36:56 +020080 if (tbf->state_is(GPRS_RLCMAC_RELEASING))
Maxee5be3a2017-12-20 17:31:13 +010081 OSMO_ASSERT(tbf->timers_pending(T_MAX));
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +010082}
83
Jacob Erlbeckac89a552015-06-29 14:18:46 +020084static void test_tbf_base()
85{
86
Pau Espin Pedrol474dc772019-09-09 14:09:48 +020087 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckac89a552015-06-29 14:18:46 +020088
89 OSMO_ASSERT(GPRS_RLCMAC_DL_TBF == reverse(GPRS_RLCMAC_UL_TBF));
90 OSMO_ASSERT(GPRS_RLCMAC_UL_TBF == reverse(GPRS_RLCMAC_DL_TBF));
91
Pau Espin Pedrol474dc772019-09-09 14:09:48 +020092 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckac89a552015-06-29 14:18:46 +020093}
94
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010095static void test_tbf_tlli_update()
96{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +010097 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +010098 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck93990462015-05-15 15:50:43 +020099 GprsMs *ms, *ms_new;
100
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200101 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100102
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100103 the_pcu->alloc_algorithm = alloc_algorithm_a;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100104 bts->trx[0].pdch[2].enable();
105 bts->trx[0].pdch[3].enable();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100106
107 /*
108 * Make a uplink and downlink allocation
109 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100110 ms = bts_alloc_ms(bts, 0, 0);
111 gprs_rlcmac_tbf *dl_tbf = tbf_alloc_dl_tbf(bts,
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200112 ms, 0, false);
Jacob Erlbeckc6d4cee2015-06-29 13:03:46 +0200113 OSMO_ASSERT(dl_tbf != NULL);
Jacob Erlbeckbe0cbc12015-05-18 14:35:11 +0200114 dl_tbf->update_ms(0x2342, GPRS_RLCMAC_DL_TBF);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200115 dl_tbf->set_ta(4);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100116 OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200117 OSMO_ASSERT(dl_tbf->ms() == ms);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100118
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100119 gprs_rlcmac_tbf *ul_tbf = tbf_alloc_ul_tbf(bts,
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200120 ms, 0, false);
Jacob Erlbeckc6d4cee2015-06-29 13:03:46 +0200121 OSMO_ASSERT(ul_tbf != NULL);
Jacob Erlbeck0e50ce62015-05-21 16:58:22 +0200122 ul_tbf->update_ms(0x2342, GPRS_RLCMAC_UL_TBF);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100123 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200124 OSMO_ASSERT(ul_tbf->ms() == ms);
125
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100126 OSMO_ASSERT(bts_ms_by_tlli(bts, 0x2342, GSM_RESERVED_TMSI) == ms);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100127
128 /*
129 * Now check.. that DL changes and that the timing advance
130 * has changed.
131 */
Jacob Erlbeck0e50ce62015-05-21 16:58:22 +0200132 dl_tbf->update_ms(0x4232, GPRS_RLCMAC_DL_TBF);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100133
Jacob Erlbeck93990462015-05-15 15:50:43 +0200134 /* It is still there, since the new TLLI has not been used for UL yet */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100135 ms_new = bts_ms_by_tlli(bts, 0x2342, GSM_RESERVED_TMSI);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200136 OSMO_ASSERT(ms == ms_new);
137
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100138 ms_new = bts_ms_by_tlli(bts, 0x4232, GSM_RESERVED_TMSI);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200139 OSMO_ASSERT(ms == ms_new);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100140 OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf);
141 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200142
143 /* Now use the new TLLI for UL */
Jacob Erlbeck0e50ce62015-05-21 16:58:22 +0200144 ul_tbf->update_ms(0x4232, GPRS_RLCMAC_UL_TBF);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100145 ms_new = bts_ms_by_tlli(bts, 0x2342, GSM_RESERVED_TMSI);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200146 OSMO_ASSERT(ms_new == NULL);
Holger Hans Peter Freytherbc1626e2013-10-30 19:50:49 +0100147
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100148 ms_new = bts_ms_by_tlli(bts, 0x4232, GSM_RESERVED_TMSI);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200149 OSMO_ASSERT(ms_new != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100150 OSMO_ASSERT(ms_ta(ms_new) == 4);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200151
152 OSMO_ASSERT(ul_tbf->ta() == 4);
153 OSMO_ASSERT(dl_tbf->ta() == 4);
154
155 ul_tbf->set_ta(6);
156
157 OSMO_ASSERT(ul_tbf->ta() == 6);
158 OSMO_ASSERT(dl_tbf->ta() == 6);
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100159
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200160 fprintf(stderr, "=== end %s ===\n", __func__);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100161 TALLOC_FREE(the_pcu);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100162}
163
Daniel Willmann510d7d32014-08-15 18:19:41 +0200164static uint8_t llc_data[200];
165
Maxa2961182018-01-25 19:47:28 +0100166/* override, requires '-Wl,--wrap=pcu_sock_send' */
167int __real_pcu_sock_send(struct msgb *msg);
Pau Espin Pedrole91c4c72021-01-18 17:54:30 +0100168extern "C" int __wrap_pcu_sock_send(struct msgb *msg)
Daniel Willmann510d7d32014-08-15 18:19:41 +0200169{
170 return 0;
171}
172
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100173static void setup_bts(struct gprs_rlcmac_bts *bts, uint8_t ts_no, uint8_t cs = 1)
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100174{
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100175 gprs_rlcmac_trx *trx;
176
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100177 the_pcu->alloc_algorithm = alloc_algorithm_a;
Jacob Erlbecka700dd92015-06-02 16:00:41 +0200178 bts->initial_cs_dl = cs;
179 bts->initial_cs_ul = cs;
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +0100180 osmo_tdef_set(the_pcu->T_defs, -2030, 0, OSMO_TDEF_S);
181 osmo_tdef_set(the_pcu->T_defs, -2031, 0, OSMO_TDEF_S);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100182 trx = &bts->trx[0];
183
184 trx->pdch[ts_no].enable();
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100185 bts_set_current_frame_number(bts, DUMMY_FN);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100186}
187
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100188static gprs_rlcmac_dl_tbf *create_dl_tbf(struct gprs_rlcmac_bts *bts, uint8_t ms_class,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +0100189 uint8_t egprs_ms_class, uint8_t *trx_no_)
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100190{
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100191 int tfi;
192 uint8_t trx_no;
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200193 GprsMs *ms;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100194 gprs_rlcmac_dl_tbf *dl_tbf;
195
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100196 ms = bts_alloc_ms(bts, ms_class, egprs_ms_class);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100197
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100198 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_DL_TBF, &trx_no, -1);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100199 OSMO_ASSERT(tfi >= 0);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200200 dl_tbf = tbf_alloc_dl_tbf(bts, ms, trx_no, true);
Pau Espin Pedrol983bb7e2020-10-26 14:52:06 +0100201 OSMO_ASSERT(dl_tbf);
Max9bbe1602016-07-18 12:50:18 +0200202 dl_tbf->set_ta(0);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100203 check_tbf(dl_tbf);
204
205 /* "Establish" the DL TBF */
Max0e599802018-01-23 20:09:06 +0100206 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_SEND_ASS);
Max2399b1d2018-01-12 15:48:12 +0100207 TBF_SET_STATE(dl_tbf, GPRS_RLCMAC_FLOW);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100208 dl_tbf->m_wait_confirm = 0;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100209 check_tbf(dl_tbf);
210
211 *trx_no_ = trx_no;
212
213 return dl_tbf;
214}
215
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200216static unsigned fn2bn(unsigned fn)
217{
218 return (fn % 52) / 4;
219}
220
221static unsigned fn_add_blocks(unsigned fn, unsigned blocks)
222{
223 unsigned bn = fn2bn(fn) + blocks;
224 fn = fn - (fn % 52);
225 fn += bn * 4 + bn / 3;
Max9dabfa22017-05-16 16:10:45 +0200226 return fn % GSM_MAX_FN;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200227}
228
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200229static void request_dl_rlc_block(struct gprs_rlcmac_bts *bts,
Max878bd1f2016-07-20 13:05:05 +0200230 uint8_t trx_no, uint8_t ts_no,
Jacob Erlbeckee310902015-08-24 11:55:17 +0200231 uint32_t *fn, uint8_t *block_nr = NULL)
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100232{
Jacob Erlbeckee310902015-08-24 11:55:17 +0200233 uint8_t bn = fn2bn(*fn);
Max878bd1f2016-07-20 13:05:05 +0200234 gprs_rlcmac_rcv_rts_block(bts, trx_no, ts_no, *fn, bn);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200235 *fn = fn_add_blocks(*fn, 1);
Jacob Erlbeckee310902015-08-24 11:55:17 +0200236 bn += 1;
237 if (block_nr)
238 *block_nr = bn;
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100239}
240
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200241static void request_dl_rlc_block(struct gprs_rlcmac_tbf *tbf,
Jacob Erlbeckee310902015-08-24 11:55:17 +0200242 uint32_t *fn, uint8_t *block_nr = NULL)
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200243{
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100244 request_dl_rlc_block(tbf->bts, tbf->trx->trx_no,
Max878bd1f2016-07-20 13:05:05 +0200245 tbf->control_ts, fn, block_nr);
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200246}
247
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100248enum test_tbf_final_ack_mode {
249 TEST_MODE_STANDARD,
250 TEST_MODE_REVERSE_FREE
251};
252
253static void test_tbf_final_ack(enum test_tbf_final_ack_mode test_mode)
Daniel Willmann510d7d32014-08-15 18:19:41 +0200254{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100255 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100256 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100257 uint8_t ts_no = 4;
258 unsigned i;
Daniel Willmann510d7d32014-08-15 18:19:41 +0200259 uint8_t ms_class = 45;
260 uint32_t fn;
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100261 uint8_t block_nr;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100262 uint8_t trx_no;
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200263 GprsMs *ms;
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200264 uint32_t tlli = 0xffeeddcc;
Daniel Willmann510d7d32014-08-15 18:19:41 +0200265
266 uint8_t rbb[64/8];
267
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200268 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100269
Daniel Willmann510d7d32014-08-15 18:19:41 +0200270 gprs_rlcmac_dl_tbf *dl_tbf;
271 gprs_rlcmac_tbf *new_tbf;
272
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100273 setup_bts(bts, ts_no);
274 dl_tbf = create_dl_tbf(bts, ms_class, 0, &trx_no);
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200275 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200276 ms = dl_tbf->ms();
Daniel Willmann510d7d32014-08-15 18:19:41 +0200277
278 for (i = 0; i < sizeof(llc_data); i++)
279 llc_data[i] = i%256;
280
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100281 /* Schedule two LLC frames */
Pau Espin Pedrol758ace82020-10-28 19:58:17 +0100282 dl_tbf->append_data(1000, llc_data, sizeof(llc_data));
283 dl_tbf->append_data(1000, llc_data, sizeof(llc_data));
Daniel Willmann510d7d32014-08-15 18:19:41 +0200284
285
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100286 /* Send only a few RLC/MAC blocks */
Daniel Willmann510d7d32014-08-15 18:19:41 +0200287 fn = 0;
Jacob Erlbeckee310902015-08-24 11:55:17 +0200288 do {
Daniel Willmann510d7d32014-08-15 18:19:41 +0200289 /* Request to send one block */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200290 request_dl_rlc_block(dl_tbf, &fn, &block_nr);
Jacob Erlbeckee310902015-08-24 11:55:17 +0200291 } while (block_nr < 3);
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200292
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100293 OSMO_ASSERT(dl_tbf->have_data());
294 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
Daniel Willmann510d7d32014-08-15 18:19:41 +0200295
296 /* Queue a final ACK */
297 memset(rbb, 0, sizeof(rbb));
298 /* Receive a final ACK */
Max7df82d42017-12-15 11:14:30 +0100299 dl_tbf->rcvd_dl_ack(true, 1, rbb);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200300
301 /* Clean up and ensure tbfs are in the correct state */
302 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100303 new_tbf = ms_dl_tbf(ms);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100304 check_tbf(new_tbf);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200305 OSMO_ASSERT(new_tbf != dl_tbf);
306 OSMO_ASSERT(new_tbf->tfi() == 1);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100307 check_tbf(dl_tbf);
Max0e599802018-01-23 20:09:06 +0100308 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_NONE);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100309 if (test_mode == TEST_MODE_REVERSE_FREE) {
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100310 ms_ref(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100311 tbf_free(new_tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100312 OSMO_ASSERT(ms_dl_tbf(ms) == NULL);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100313 check_tbf(dl_tbf);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100314 tbf_free(dl_tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100315 ms_unref(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100316 } else {
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100317 ms_ref(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100318 tbf_free(dl_tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100319 OSMO_ASSERT(ms_dl_tbf(ms) == new_tbf);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100320 check_tbf(new_tbf);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100321 tbf_free(new_tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100322 OSMO_ASSERT(ms_dl_tbf(ms) == NULL);
323 ms_unref(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100324 }
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100325
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100326 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200327 fprintf(stderr, "=== end %s ===\n", __func__);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200328}
329
Max7d32f552017-12-15 11:25:14 +0100330/* Receive an ACK */
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +0200331#define RCV_ACK(fin, tbf, rbb) do { \
332 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
333 tbf->rcvd_dl_ack(fin, w->v_s(), rbb); \
Max7d32f552017-12-15 11:25:14 +0100334 if (!fin) \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +0200335 OSMO_ASSERT(w->window_empty()); \
Max7d32f552017-12-15 11:25:14 +0100336 } while(0)
337
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100338static void test_tbf_delayed_release()
339{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100340 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100341 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100342 uint8_t ts_no = 4;
343 unsigned i;
344 uint8_t ms_class = 45;
345 uint32_t fn = 0;
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100346 uint8_t trx_no;
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200347 uint32_t tlli = 0xffeeddcc;
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200348 unsigned long dl_tbf_idle_msec;
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100349
350 uint8_t rbb[64/8];
351
352 gprs_rlcmac_dl_tbf *dl_tbf;
353
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200354 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100355
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100356 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +0100357 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100358
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100359 dl_tbf = create_dl_tbf(bts, ms_class, 0, &trx_no);
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200360 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100361
362 for (i = 0; i < sizeof(llc_data); i++)
363 llc_data[i] = i%256;
364
365 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
366
367 /* Schedule two LLC frames */
Pau Espin Pedrol758ace82020-10-28 19:58:17 +0100368 dl_tbf->append_data(1000, llc_data, sizeof(llc_data));
369 dl_tbf->append_data(1000, llc_data, sizeof(llc_data));
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100370
371 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
372
373 /* Drain the queue */
374 while (dl_tbf->have_data())
375 /* Request to send one RLC/MAC block */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200376 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100377
378 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
379
380 /* ACK all blocks */
381 memset(rbb, 0xff, sizeof(rbb));
Max7d32f552017-12-15 11:25:14 +0100382
383 RCV_ACK(false, dl_tbf, rbb); /* Receive an ACK */
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100384
385 /* Force sending of a single block containing an LLC dummy command */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200386 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100387
Max7d32f552017-12-15 11:25:14 +0100388 RCV_ACK(false, dl_tbf, rbb); /* Receive an ACK */
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100389
390 /* Timeout (make sure fn % 52 remains valid) */
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +0100391 dl_tbf_idle_msec = osmo_tdef_get(the_pcu->T_defs, -2031, OSMO_TDEF_MS, -1);
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200392 fn += 52 * ((msecs_to_frames(dl_tbf_idle_msec + 100) + 51)/ 52);
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200393 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100394
395 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FINISHED));
396
Max7d32f552017-12-15 11:25:14 +0100397 RCV_ACK(true, dl_tbf, rbb); /* Receive a final ACK */
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100398
399 /* Clean up and ensure tbfs are in the correct state */
400 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
Max0e599802018-01-23 20:09:06 +0100401 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_NONE);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100402 check_tbf(dl_tbf);
403 tbf_free(dl_tbf);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100404 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200405 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100406}
407
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200408static void test_tbf_imsi()
409{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100410 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100411 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200412 uint8_t ts_no = 4;
413 uint8_t ms_class = 45;
414 uint8_t trx_no;
415 GprsMs *ms1, *ms2;
416
417 gprs_rlcmac_dl_tbf *dl_tbf[2];
418
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200419 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200420
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100421 setup_bts(bts, ts_no);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200422
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100423 dl_tbf[0] = create_dl_tbf(bts, ms_class, 0, &trx_no);
424 dl_tbf[1] = create_dl_tbf(bts, ms_class, 0, &trx_no);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200425
426 dl_tbf[0]->update_ms(0xf1000001, GPRS_RLCMAC_DL_TBF);
427 dl_tbf[1]->update_ms(0xf1000002, GPRS_RLCMAC_DL_TBF);
428
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100429 ms_set_imsi(dl_tbf[0]->ms(), "001001000000001");
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100430 ms1 = bts_ms_store(bts)->get_ms(0, 0, "001001000000001");
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200431 OSMO_ASSERT(ms1 != NULL);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100432 ms2 = bts_ms_store(bts)->get_ms(0xf1000001);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200433 OSMO_ASSERT(ms2 != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100434 OSMO_ASSERT(strcmp(ms_imsi(ms2), "001001000000001") == 0);
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200435 OSMO_ASSERT(ms1 == ms2);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200436
437 /* change the IMSI on TBF 0 */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100438 ms_set_imsi(dl_tbf[0]->ms(), "001001000000002");
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100439 ms1 = bts_ms_store(bts)->get_ms(0, 0, "001001000000001");
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200440 OSMO_ASSERT(ms1 == NULL);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100441 ms1 = bts_ms_store(bts)->get_ms(0, 0, "001001000000002");
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200442 OSMO_ASSERT(ms1 != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100443 OSMO_ASSERT(strcmp(ms_imsi(ms2), "001001000000002") == 0);
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200444 OSMO_ASSERT(ms1 == ms2);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200445
Pau Espin Pedrol528820d2020-10-26 12:40:11 +0100446 /* use the same IMSI on TBF 1 */
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200447 {
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100448 ms_ref(ms2);
449 ms_set_imsi(dl_tbf[1]->ms(), "001001000000002");
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100450 ms1 = bts_ms_store(bts)->get_ms(0, 0, "001001000000002");
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200451 OSMO_ASSERT(ms1 != NULL);
452 OSMO_ASSERT(ms1 != ms2);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100453 OSMO_ASSERT(strcmp(ms_imsi(ms1), "001001000000002") == 0);
454 OSMO_ASSERT(strcmp(ms_imsi(ms2), "") == 0);
455 ms_unref(ms2);
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200456 }
457
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100458 ms2 = bts_ms_store(bts)->get_ms(0xf1000001);
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200459 OSMO_ASSERT(ms2 == NULL);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200460
461 tbf_free(dl_tbf[1]);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100462 ms1 = bts_ms_store(bts)->get_ms(0, 0, "001001000000002");
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200463 OSMO_ASSERT(ms1 == NULL);
464
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100465 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200466 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200467}
468
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200469static void test_tbf_exhaustion()
470{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100471 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100472 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200473 unsigned i;
474 uint8_t ts_no = 4;
475 uint8_t ms_class = 45;
476 int rc = 0;
477
478 uint8_t buf[256] = {0};
479
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200480 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200481
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100482 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
483 if (!bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +0200484 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
485 abort();
486 }
487
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100488 setup_bts(bts, ts_no);
Alexander Couzens290d9032020-09-16 21:52:02 +0200489 gprs_bssgp_init(bts, 1234, 1234, 1, 1, false, 0, 0, 0);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200490
491 for (i = 0; i < 1024; i++) {
492 uint32_t tlli = 0xc0000000 + i;
493 char imsi[16] = {0};
494 unsigned delay_csec = 1000;
495
Jacob Erlbeck9a2845d2015-05-21 12:06:58 +0200496 snprintf(imsi, sizeof(imsi), "001001%09d", i);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200497
Pau Espin Pedrol8a35e642021-01-18 17:14:14 +0100498 rc = dl_tbf_handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200499 delay_csec, buf, sizeof(buf));
500
501 if (rc < 0)
502 break;
503 }
504
505 OSMO_ASSERT(rc == -EBUSY);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200506 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200507
Alexander Couzens290d9032020-09-16 21:52:02 +0200508 gprs_bssgp_destroy(bts);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100509 TALLOC_FREE(the_pcu);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200510}
511
Jacob Erlbeck41168642015-06-12 13:41:00 +0200512static void test_tbf_dl_llc_loss()
513{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100514 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100515 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200516 uint8_t ts_no = 4;
517 uint8_t ms_class = 45;
518 int rc = 0;
519 uint32_t tlli = 0xc0123456;
520 const char *imsi = "001001000123456";
521 unsigned delay_csec = 1000;
522 GprsMs *ms;
523
524 uint8_t buf[19];
525
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100526 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
527 if (!bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +0200528 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
529 abort();
530 }
531
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200532 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200533
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100534 setup_bts(bts, ts_no);
Pau Espin Pedrol63700ea2019-09-09 13:19:06 +0200535 /* keep the MS object 10 seconds */
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +0100536 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2030, 10, OSMO_TDEF_S) == 0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200537
Alexander Couzens290d9032020-09-16 21:52:02 +0200538 gprs_bssgp_init(bts, 2234, 2234, 1, 1, false, 0, 0, 0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200539
540 /* Handle LLC frame 1 */
541 memset(buf, 1, sizeof(buf));
Pau Espin Pedrol8a35e642021-01-18 17:14:14 +0100542 rc = dl_tbf_handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200543 delay_csec, buf, sizeof(buf));
544 OSMO_ASSERT(rc >= 0);
545
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100546 ms = bts_ms_store(bts)->get_ms(0, 0, imsi);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200547 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100548 OSMO_ASSERT(ms_dl_tbf(ms) != NULL);
549 ms_dl_tbf(ms)->set_ta(0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200550
551 /* Handle LLC frame 2 */
552 memset(buf, 2, sizeof(buf));
Pau Espin Pedrol8a35e642021-01-18 17:14:14 +0100553 rc = dl_tbf_handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200554 delay_csec, buf, sizeof(buf));
555 OSMO_ASSERT(rc >= 0);
556
557 /* TBF establishment fails (timeout) */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100558 tbf_free(ms_dl_tbf(ms));
Jacob Erlbeck41168642015-06-12 13:41:00 +0200559
560 /* Handle LLC frame 3 */
561 memset(buf, 3, sizeof(buf));
Pau Espin Pedrol8a35e642021-01-18 17:14:14 +0100562 rc = dl_tbf_handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200563 delay_csec, buf, sizeof(buf));
564 OSMO_ASSERT(rc >= 0);
565
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100566 OSMO_ASSERT(ms_dl_tbf(ms) != NULL);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200567
568 /* Get first BSN */
569 struct msgb *msg;
570 int fn = 0;
571 uint8_t expected_data = 1;
Maxd3a0d912019-03-05 16:15:01 +0100572 static uint8_t exp[][GSM_MACBLOCK_LEN] = {
573 { 0x07, 0x00, 0x00, 0x4d, 0x01, 0x01, 0x01,
574 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
575 { 0x07, 0x00, 0x02, 0x4d, 0x02, 0x02, 0x02,
576 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 },
577 { 0x07, 0x01, 0x04, 0x4d, 0x03, 0x03, 0x03,
578 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 },
579 };
Jacob Erlbeck41168642015-06-12 13:41:00 +0200580
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100581 while (ms_dl_tbf(ms)->have_data()) {
582 msg = ms_dl_tbf(ms)->create_dl_acked_block(fn += 4, 7);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200583 fprintf(stderr, "MSG = %s\n", msgb_hexdump(msg));
Maxd3a0d912019-03-05 16:15:01 +0100584 if (!msgb_eq_data_print(msg, exp[expected_data - 1], GSM_MACBLOCK_LEN))
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200585 fprintf(stderr, "%s failed at %u\n", __func__, expected_data);
Maxd3a0d912019-03-05 16:15:01 +0100586
Jacob Erlbeck41168642015-06-12 13:41:00 +0200587 expected_data += 1;
588 }
Jacob Erlbeck409efa12015-06-12 14:06:09 +0200589 OSMO_ASSERT(expected_data-1 == 3);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200590
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200591 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200592
Alexander Couzens290d9032020-09-16 21:52:02 +0200593 gprs_bssgp_destroy(bts);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100594 TALLOC_FREE(the_pcu);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200595}
596
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100597static gprs_rlcmac_ul_tbf *establish_ul_tbf_single_phase(struct gprs_rlcmac_bts *bts,
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200598 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta)
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200599{
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200600 GprsMs *ms;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200601 int tfi = 0;
602 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200603 uint8_t trx_no = 0;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200604 struct gprs_rlcmac_pdch *pdch;
605
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100606 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200607
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100608 bts_handle_rach(bts, 0x03, *fn, qta);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200609
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100610 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200611 OSMO_ASSERT(ul_tbf != NULL);
612
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200613 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200614
615 uint8_t data_msg[23] = {
616 0x00, /* GPRS_RLCMAC_DATA_BLOCK << 6 */
617 uint8_t(1 | (tfi << 2)),
618 uint8_t(1), /* BSN:7, E:1 */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200619 uint8_t(tlli >> 24), uint8_t(tlli >> 16),
620 uint8_t(tlli >> 8), uint8_t(tlli), /* TLLI */
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200621 };
622
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100623 pdch = &bts->trx[trx_no].pdch[ts_no];
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200624 pdch->rcv_block(&data_msg[0], sizeof(data_msg), *fn, &meas);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200625
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100626 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200627 OSMO_ASSERT(ms != NULL);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200628
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200629 return ul_tbf;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200630}
631
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100632static void send_ul_mac_block(struct gprs_rlcmac_bts *bts, unsigned trx_no, unsigned ts_no,
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200633 RlcMacUplink_t *ulreq, unsigned fn)
634{
635 bitvec *rlc_block;
636 uint8_t buf[64];
637 int num_bytes;
638 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200639
Alexander Couzensccde5c92017-02-04 03:10:08 +0100640 rlc_block = bitvec_alloc(23, tall_pcu_ctx);
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200641
Pau Espin Pedrol5e300ce2020-02-03 17:18:03 +0100642 OSMO_ASSERT(encode_gsm_rlcmac_uplink(rlc_block, ulreq) == 0);
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200643 num_bytes = bitvec_pack(rlc_block, &buf[0]);
644 OSMO_ASSERT(size_t(num_bytes) < sizeof(buf));
645 bitvec_free(rlc_block);
646
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100647 bts_set_current_block_frame_number(bts, fn, 0);
Jacob Erlbeckaf75ce82015-08-26 13:22:28 +0200648
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100649 pdch = &bts->trx[trx_no].pdch[ts_no];
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200650 pdch->rcv_block(&buf[0], num_bytes, fn, &meas);
651}
652
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200653static void send_control_ack(gprs_rlcmac_tbf *tbf)
654{
655 RlcMacUplink_t ulreq = {0};
656
657 OSMO_ASSERT(tbf->poll_fn != 0);
Jacob Erlbeck8eb17142016-01-22 17:58:17 +0100658 OSMO_ASSERT(tbf->is_control_ts(tbf->poll_ts));
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200659
660 ulreq.u.MESSAGE_TYPE = MT_PACKET_CONTROL_ACK;
661 Packet_Control_Acknowledgement_t *ctrl_ack =
662 &ulreq.u.Packet_Control_Acknowledgement;
663
664 ctrl_ack->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
665 ctrl_ack->TLLI = tbf->tlli();
Jacob Erlbeck8eb17142016-01-22 17:58:17 +0100666 send_ul_mac_block(tbf->bts, tbf->trx->trx_no, tbf->poll_ts,
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200667 &ulreq, tbf->poll_fn);
668}
669
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100670static gprs_rlcmac_ul_tbf *puan_urbb_len_issue(struct gprs_rlcmac_bts *bts,
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530671 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
672 uint8_t ms_class, uint8_t egprs_ms_class)
673{
674 GprsMs *ms;
675 uint32_t rach_fn = *fn - 51;
676 uint32_t sba_fn = *fn + 52;
677 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +0100678 int tfi = 0;
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530679 gprs_rlcmac_ul_tbf *ul_tbf;
680 struct gprs_rlcmac_pdch *pdch;
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530681 RlcMacUplink_t ulreq = {0};
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530682 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530683
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530684 /* needed to set last_rts_fn in the PDCH object */
685 request_dl_rlc_block(bts, trx_no, ts_no, fn);
686
687 /*
688 * simulate RACH, this sends an Immediate
689 * Assignment Uplink on the AGCH
690 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100691 bts_handle_rach(bts, 0x73, rach_fn, qta);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530692
693 /* get next free TFI */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100694 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530695
696 /* fake a resource request */
697 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
698 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
699 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
700 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100701 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
702 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530703 Count_MS_RA_capability_value = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100704 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530705 MS_RA_capability_value[0].u.Content.
706 Exist_Multislot_capability = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100707 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530708 MS_RA_capability_value[0].u.Content.Multislot_capability.
709 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100710 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530711 MS_RA_capability_value[0].u.Content.Multislot_capability.
712 GPRS_multislot_class = ms_class;
713 if (egprs_ms_class) {
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100714 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530715 MS_RA_capability_value[0].u.Content.
716 Multislot_capability.Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100717 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530718 MS_RA_capability_value[0].u.Content.
719 Multislot_capability.EGPRS_multislot_class = ms_class;
720 }
721
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100722 send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530723
724 /* check the TBF */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100725 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530726 OSMO_ASSERT(ul_tbf);
727 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
728
729 /* send packet uplink assignment */
730 *fn = sba_fn;
731 request_dl_rlc_block(ul_tbf, fn);
732
733 /* send real acknowledgement */
734 send_control_ack(ul_tbf);
735
736 check_tbf(ul_tbf);
737 /* send fake data */
738 uint8_t data_msg[42] = {
739 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
Neels Hofmeyrd34646a2017-02-08 17:07:40 +0100740 (uint8_t)(tfi << 1),
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530741 1, /* BSN:7, E:1 */
742 };
743
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100744 pdch = &bts->trx[trx_no].pdch[ts_no];
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530745 pdch->rcv_block(&data_msg[0], 23, *fn, &meas);
746
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100747 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530748 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100749 OSMO_ASSERT(ms_ta(ms) == qta/4);
750 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530751
752 /*
753 * TS 44.060, B.8.1
754 * first seg received first, later second seg
755 */
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530756 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
757 egprs3->si = 0;
758 egprs3->r = 1;
759 egprs3->cv = 7;
760 egprs3->tfi_hi = tfi & 0x03;
761 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
762 egprs3->bsn1_hi = 1;
763 egprs3->bsn1_lo = 0;
764 egprs3->cps_hi = 1;
765 data_msg[3] = 0xff;
766 egprs3->pi = 0;
767 egprs3->cps_lo = 1;
768 egprs3->rsb = 0;
769 egprs3->spb = 0;
770 egprs3->pi = 0;
771
772 pdch->rcv_block(data_msg, 42, *fn, &meas);
773
774 struct msgb *msg1 = ul_tbf->create_ul_ack(*fn, ts_no);
775
Pau Espin Pedrol46fd7a02020-11-02 14:36:22 +0100776 static uint8_t exp1[] = { 0x40, 0x24, 0x01, 0x0b, 0x3e, 0x24, 0x46, 0x68, 0x90, 0x87, 0xb0, 0x06,
Maxd3a0d912019-03-05 16:15:01 +0100777 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b
778 };
779
780 if (!msgb_eq_data_print(msg1, exp1, GSM_MACBLOCK_LEN)) {
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200781 fprintf(stderr, "%s test failed on 1st segment!\n", __func__);
Maxd3a0d912019-03-05 16:15:01 +0100782 return NULL;
783 }
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530784
785 egprs3->si = 0;
786 egprs3->r = 1;
787 egprs3->cv = 7;
788 egprs3->tfi_hi = tfi & 0x03;
789 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
790 egprs3->bsn1_hi = 4;
791 egprs3->bsn1_lo = 0;
792 egprs3->cps_hi = 1;
793 data_msg[3] = 0xff;
794 egprs3->pi = 0;
795 egprs3->cps_lo = 1;
796 egprs3->rsb = 0;
797 egprs3->spb = 0;
798
799 pdch->rcv_block(data_msg, 42, *fn, &meas);
800
801 msg1 = ul_tbf->create_ul_ack(*fn, ts_no);
802
Pau Espin Pedrol46fd7a02020-11-02 14:36:22 +0100803 static uint8_t exp2[] = { 0x40, 0x24, 0x01, 0x0b, 0x3e, 0x24, 0x46, 0x68, 0x90, 0x88, 0xb0, 0x06, 0x8b,
Maxd3a0d912019-03-05 16:15:01 +0100804 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b
805 };
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530806
Maxd3a0d912019-03-05 16:15:01 +0100807 if (!msgb_eq_data_print(msg1, exp2, GSM_MACBLOCK_LEN)) {
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200808 fprintf(stderr, "%s test failed on 2nd segment!\n", __func__);
Maxd3a0d912019-03-05 16:15:01 +0100809 return NULL;
810 }
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530811 return ul_tbf;
812}
813
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100814static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(struct gprs_rlcmac_bts *bts,
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530815 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
816 uint8_t ms_class, uint8_t egprs_ms_class)
817{
818 GprsMs *ms;
819 uint32_t rach_fn = *fn - 51;
820 uint32_t sba_fn = *fn + 52;
821 uint8_t trx_no = 0;
822 int tfi = 0, i = 0;
823 gprs_rlcmac_ul_tbf *ul_tbf;
824 struct gprs_rlcmac_pdch *pdch;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530825 RlcMacUplink_t ulreq = {0};
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530826 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530827
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530828 /* needed to set last_rts_fn in the PDCH object */
829 request_dl_rlc_block(bts, trx_no, ts_no, fn);
830
831 /*
832 * simulate RACH, this sends an Immediate
833 * Assignment Uplink on the AGCH
834 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100835 bts_handle_rach(bts, 0x73, rach_fn, qta);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530836
837 /* get next free TFI */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100838 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530839
840 /* fake a resource request */
841 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
842 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
843 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
844 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100845 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
846 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530847 Count_MS_RA_capability_value = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100848 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530849 MS_RA_capability_value[0].u.Content.
850 Exist_Multislot_capability = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100851 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530852 MS_RA_capability_value[0].u.Content.Multislot_capability.
853 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100854 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530855 MS_RA_capability_value[0].u.Content.Multislot_capability.
856 GPRS_multislot_class = ms_class;
857 if (egprs_ms_class) {
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100858 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530859 MS_RA_capability_value[0].u.Content.
860 Multislot_capability.Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100861 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530862 MS_RA_capability_value[0].u.Content.
863 Multislot_capability.EGPRS_multislot_class = ms_class;
864 }
865
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100866 send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530867
868 /* check the TBF */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100869 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530870 OSMO_ASSERT(ul_tbf != NULL);
871 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
872
873 /* send packet uplink assignment */
874 *fn = sba_fn;
875 request_dl_rlc_block(ul_tbf, fn);
876
877 /* send real acknowledgement */
878 send_control_ack(ul_tbf);
879
880 check_tbf(ul_tbf);
881
882 /* send fake data */
883 uint8_t data_msg[42] = {
884 0x00 | 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
885 uint8_t(0 | (tfi << 1)),
886 uint8_t(1), /* BSN:7, E:1 */
887 };
888
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100889 pdch = &bts->trx[trx_no].pdch[ts_no];
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530890 pdch->rcv_block(&data_msg[0], 23, *fn, &meas);
891
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100892 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530893 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100894 OSMO_ASSERT(ms_ta(ms) == qta/4);
895 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530896
897 /*
898 * TS 44.060, B.8.1
899 * first seg received first, later second seg
900 */
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530901 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
902 egprs3->si = 1;
903 egprs3->r = 1;
904 egprs3->cv = 7;
905 egprs3->tfi_hi = tfi & 0x03;
906 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
907 egprs3->bsn1_hi = 1;
908 egprs3->bsn1_lo = 0;
909 egprs3->cps_hi = 1;
910 data_msg[3] = 0xff;
911 egprs3->pi = 0;
912 egprs3->cps_lo = 1;
913 egprs3->rsb = 0;
914 egprs3->spb = 2;
915 egprs3->pi = 0;
916
917 pdch->rcv_block(data_msg, 42, *fn, &meas);
918
919 struct gprs_rlc_data *block = ul_tbf->m_rlc.block(1);
920
921 /* check the status of the block */
922 OSMO_ASSERT(block->spb_status.block_status_ul ==
923 EGPRS_RESEG_FIRST_SEG_RXD);
924
925 egprs3->si = 1;
926 egprs3->r = 1;
927 egprs3->cv = 7;
928 egprs3->tfi_hi = tfi & 0x03;
929 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
930 egprs3->bsn1_hi = 1;
931 egprs3->bsn1_lo = 0;
932 egprs3->cps_hi = 1;
933 data_msg[3] = 0xff;
934 egprs3->pi = 0;
935 egprs3->cps_lo = 1;
936 egprs3->rsb = 0;
937 egprs3->spb = 3;
938
939 pdch->rcv_block(data_msg, 42, *fn, &meas);
940
941 /* check the status of the block */
942 OSMO_ASSERT(block->spb_status.block_status_ul ==
943 EGPRS_RESEG_DEFAULT);
944 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +0100945 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530946 /* Assembled MCS is MCS6. so the size is 74 */
947 OSMO_ASSERT(block->len == 74);
948
949 /*
950 * TS 44.060, B.8.1
951 * second seg first, later first seg
952 */
953 memset(data_msg, 0, sizeof(data_msg));
954
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530955 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
956 egprs3->si = 1;
957 egprs3->r = 1;
958 egprs3->cv = 7;
959 egprs3->tfi_hi = tfi & 0x03;
960 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
961 egprs3->bsn1_hi = 2;
962 egprs3->bsn1_lo = 0;
963 egprs3->cps_hi = 1;
964 data_msg[3] = 0xff;
965 egprs3->pi = 0;
966 egprs3->cps_lo = 1;
967 egprs3->rsb = 0;
968 egprs3->spb = 3;
969 egprs3->pi = 0;
970
971 pdch->rcv_block(data_msg, 42, *fn, &meas);
972
973 block = ul_tbf->m_rlc.block(2);
974 /* check the status of the block */
975 OSMO_ASSERT(block->spb_status.block_status_ul ==
976 EGPRS_RESEG_SECOND_SEG_RXD);
977
978 egprs3->si = 1;
979 egprs3->r = 1;
980 egprs3->cv = 7;
981 egprs3->tfi_hi = tfi & 0x03;
982 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
983 egprs3->bsn1_hi = 2;
984 egprs3->bsn1_lo = 0;
985 egprs3->cps_hi = 1;
986 data_msg[3] = 0xff;
987 egprs3->pi = 0;
988 egprs3->cps_lo = 1;
989 egprs3->rsb = 0;
990 egprs3->spb = 2;
991 egprs3->pi = 0;
992
993 pdch->rcv_block(data_msg, 42, *fn, &meas);
994
995 /* check the status of the block */
996 OSMO_ASSERT(block->spb_status.block_status_ul ==
997 EGPRS_RESEG_DEFAULT);
998 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +0100999 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301000 /* Assembled MCS is MCS6. so the size is 74 */
1001 OSMO_ASSERT(block->len == 74);
1002
1003 /*
1004 * TS 44.060, B.8.1
1005 * Error scenario with spb as 1
1006 */
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301007 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1008 egprs3->si = 1;
1009 egprs3->r = 1;
1010 egprs3->cv = 7;
1011 egprs3->tfi_hi = tfi & 0x03;
1012 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1013 egprs3->bsn1_hi = 3;
1014 egprs3->bsn1_lo = 0;
1015 egprs3->cps_hi = 1;
1016 data_msg[3] = 0xff;
1017 egprs3->pi = 0;
1018 egprs3->cps_lo = 1;
1019 egprs3->rsb = 0;
1020 egprs3->spb = 1;
1021 egprs3->pi = 0;
1022
1023 pdch->rcv_block(data_msg, 42, *fn, &meas);
1024
1025 block = ul_tbf->m_rlc.block(3);
1026 /* check the status of the block */
1027 OSMO_ASSERT(block->spb_status.block_status_ul ==
1028 EGPRS_RESEG_DEFAULT);
1029 /*
1030 * TS 44.060, B.8.1
1031 * comparison of rlc_data for multiple scenarios
1032 * Receive First, the second(BSN 3)
1033 * Receive First, First then Second(BSN 4)
1034 * Receive Second then First(BSN 5)
1035 * after above 3 scenarios are triggered,
1036 * rlc_data of all 3 BSN are compared
1037 */
1038
1039 /* Initialize the data_msg */
1040 for (i = 0; i < 42; i++)
1041 data_msg[i] = i;
1042
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301043 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1044 egprs3->si = 1;
1045 egprs3->r = 1;
1046 egprs3->cv = 7;
1047 egprs3->tfi_hi = tfi & 0x03;
1048 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1049 egprs3->bsn1_hi = 3;
1050 egprs3->bsn1_lo = 0;
1051 egprs3->cps_hi = 1;
1052 data_msg[3] = 0xff;
1053 egprs3->pi = 0;
1054 egprs3->cps_lo = 1;
1055 egprs3->rsb = 0;
1056 egprs3->spb = 2;
1057 egprs3->pi = 0;
1058
1059 pdch->rcv_block(data_msg, 42, *fn, &meas);
1060
1061 block = ul_tbf->m_rlc.block(3);
1062 /* check the status of the block */
1063 OSMO_ASSERT(block->spb_status.block_status_ul ==
1064 EGPRS_RESEG_FIRST_SEG_RXD);
1065
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301066 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1067 egprs3->si = 1;
1068 egprs3->r = 1;
1069 egprs3->cv = 7;
1070 egprs3->tfi_hi = tfi & 0x03;
1071 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1072 egprs3->bsn1_hi = 3;
1073 egprs3->bsn1_lo = 0;
1074 egprs3->cps_hi = 1;
1075 data_msg[3] = 0xff;
1076 egprs3->pi = 0;
1077 egprs3->cps_lo = 1;
1078 egprs3->rsb = 0;
1079 egprs3->spb = 3;
1080 egprs3->pi = 0;
1081
1082 pdch->rcv_block(data_msg, 42, *fn, &meas);
1083
1084 block = ul_tbf->m_rlc.block(3);
1085 /* check the status of the block */
1086 OSMO_ASSERT(block->spb_status.block_status_ul ==
1087 EGPRS_RESEG_DEFAULT);
1088 /* Assembled MCS is MCS6. so the size is 74 */
1089 OSMO_ASSERT(block->len == 74);
1090 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001091 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301092
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301093 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1094 egprs3->si = 1;
1095 egprs3->r = 1;
1096 egprs3->cv = 7;
1097 egprs3->tfi_hi = tfi & 0x03;
1098 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1099 egprs3->bsn1_hi = 4;
1100 egprs3->bsn1_lo = 0;
1101 egprs3->cps_hi = 1;
1102 data_msg[3] = 0xff;
1103 egprs3->pi = 0;
1104 egprs3->cps_lo = 1;
1105 egprs3->rsb = 0;
1106 egprs3->spb = 2;
1107 egprs3->pi = 0;
1108
1109 pdch->rcv_block(data_msg, 42, *fn, &meas);
1110
1111 block = ul_tbf->m_rlc.block(4);
1112 /* check the status of the block */
1113 OSMO_ASSERT(block->spb_status.block_status_ul ==
1114 EGPRS_RESEG_FIRST_SEG_RXD);
1115
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301116 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1117 egprs3->si = 1;
1118 egprs3->r = 1;
1119 egprs3->cv = 7;
1120 egprs3->tfi_hi = tfi & 0x03;
1121 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1122 egprs3->bsn1_hi = 4;
1123 egprs3->bsn1_lo = 0;
1124 egprs3->cps_hi = 1;
1125 data_msg[3] = 0xff;
1126 egprs3->pi = 0;
1127 egprs3->cps_lo = 1;
1128 egprs3->rsb = 0;
1129 egprs3->spb = 2;
1130 egprs3->pi = 0;
1131
1132 pdch->rcv_block(data_msg, 42, *fn, &meas);
1133
1134 block = ul_tbf->m_rlc.block(4);
1135 /* check the status of the block */
1136 OSMO_ASSERT(block->spb_status.block_status_ul ==
1137 EGPRS_RESEG_FIRST_SEG_RXD);
1138
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301139 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1140 egprs3->si = 1;
1141 egprs3->r = 1;
1142 egprs3->cv = 7;
1143 egprs3->tfi_hi = tfi & 0x03;
1144 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1145 egprs3->bsn1_hi = 4;
1146 egprs3->bsn1_lo = 0;
1147 egprs3->cps_hi = 1;
1148 data_msg[3] = 0xff;
1149 egprs3->pi = 0;
1150 egprs3->cps_lo = 1;
1151 egprs3->rsb = 0;
1152 egprs3->spb = 3;
1153 egprs3->pi = 0;
1154
1155 pdch->rcv_block(data_msg, 42, *fn, &meas);
1156
1157 block = ul_tbf->m_rlc.block(4);
1158 /* check the status of the block */
1159 OSMO_ASSERT(block->spb_status.block_status_ul ==
1160 EGPRS_RESEG_DEFAULT);
1161 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001162 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301163 /* Assembled MCS is MCS6. so the size is 74 */
1164 OSMO_ASSERT(block->len == 74);
1165
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301166 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1167 egprs3->si = 1;
1168 egprs3->r = 1;
1169 egprs3->cv = 7;
1170 egprs3->tfi_hi = tfi & 0x03;
1171 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1172 egprs3->bsn1_hi = 5;
1173 egprs3->bsn1_lo = 0;
1174 egprs3->cps_hi = 1;
1175 data_msg[3] = 0xff;
1176 egprs3->pi = 0;
1177 egprs3->cps_lo = 1;
1178 egprs3->rsb = 0;
1179 egprs3->spb = 3;
1180 egprs3->pi = 0;
1181
1182 pdch->rcv_block(data_msg, 42, *fn, &meas);
1183
1184 block = ul_tbf->m_rlc.block(5);
1185 /* check the status of the block */
1186 OSMO_ASSERT(block->spb_status.block_status_ul ==
1187 EGPRS_RESEG_SECOND_SEG_RXD);
1188
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301189 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1190 egprs3->si = 1;
1191 egprs3->r = 1;
1192 egprs3->cv = 7;
1193 egprs3->tfi_hi = tfi & 0x03;
1194 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1195 egprs3->bsn1_hi = 5;
1196 egprs3->bsn1_lo = 0;
1197 egprs3->cps_hi = 1;
1198 data_msg[3] = 0xff;
1199 egprs3->pi = 0;
1200 egprs3->cps_lo = 1;
1201 egprs3->rsb = 0;
1202 egprs3->spb = 2;
1203 egprs3->pi = 0;
1204
1205 pdch->rcv_block(data_msg, 42, *fn, &meas);
1206
1207 block = ul_tbf->m_rlc.block(5);
1208
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
1217 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->len ==
1218 ul_tbf->m_rlc.block(4)->len);
1219 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->len ==
1220 ul_tbf->m_rlc.block(3)->len);
1221
1222 /* Compare the spb status of each BSNs(3,4,5). should be same */
1223 OSMO_ASSERT(
1224 ul_tbf->m_rlc.block(5)->spb_status.block_status_ul ==
1225 ul_tbf->m_rlc.block(4)->spb_status.block_status_ul);
1226 OSMO_ASSERT(
1227 ul_tbf->m_rlc.block(5)->spb_status.block_status_ul ==
1228 ul_tbf->m_rlc.block(3)->spb_status.block_status_ul);
1229
1230 /* Compare the Assembled MCS of each BSNs(3,4,5). should be same */
1231 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->cs_last ==
1232 ul_tbf->m_rlc.block(4)->cs_last);
1233 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->cs_last ==
1234 ul_tbf->m_rlc.block(3)->cs_last);
1235
1236 /* Compare the data of each BSNs(3,4,5). should be same */
1237 OSMO_ASSERT(
1238 !memcmp(ul_tbf->m_rlc.block(5)->block,
1239 ul_tbf->m_rlc.block(4)->block, ul_tbf->m_rlc.block(5)->len
1240 ));
1241 OSMO_ASSERT(
1242 !memcmp(ul_tbf->m_rlc.block(5)->block,
1243 ul_tbf->m_rlc.block(3)->block, ul_tbf->m_rlc.block(5)->len
1244 ));
1245
1246 return ul_tbf;
1247}
1248
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001249static gprs_rlcmac_ul_tbf *establish_ul_tbf(struct gprs_rlcmac_bts *bts,
sivasankari1d8744c2017-01-24 15:53:35 +05301250 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1251 uint8_t ms_class, uint8_t egprs_ms_class)
1252{
sivasankari1d8744c2017-01-24 15:53:35 +05301253 uint32_t rach_fn = *fn - 51;
1254 uint32_t sba_fn = *fn + 52;
1255 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001256 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301257 gprs_rlcmac_ul_tbf *ul_tbf;
sivasankari1d8744c2017-01-24 15:53:35 +05301258 RlcMacUplink_t ulreq = {0};
sivasankari1d8744c2017-01-24 15:53:35 +05301259
sivasankari1d8744c2017-01-24 15:53:35 +05301260 /* needed to set last_rts_fn in the PDCH object */
1261 request_dl_rlc_block(bts, trx_no, ts_no, fn);
1262
1263 /*
1264 * simulate RACH, this sends an Immediate
1265 * Assignment Uplink on the AGCH
1266 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001267 bts_handle_rach(bts, 0x73, rach_fn, qta);
sivasankari1d8744c2017-01-24 15:53:35 +05301268
1269 /* get next free TFI */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001270 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);
sivasankari1d8744c2017-01-24 15:53:35 +05301271
1272 /* fake a resource request */
1273 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
1274 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
1275 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
1276 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001277 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
1278 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301279 Count_MS_RA_capability_value = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001280 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301281 MS_RA_capability_value[0].u.Content.
1282 Exist_Multislot_capability = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001283 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301284 MS_RA_capability_value[0].u.Content.Multislot_capability.
1285 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001286 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301287 MS_RA_capability_value[0].u.Content.Multislot_capability.
1288 GPRS_multislot_class = ms_class;
1289 if (egprs_ms_class) {
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001290 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301291 MS_RA_capability_value[0].u.Content.
1292 Multislot_capability.Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001293 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301294 MS_RA_capability_value[0].u.Content.
1295 Multislot_capability.EGPRS_multislot_class = ms_class;
1296 }
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001297 send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn);
sivasankari1d8744c2017-01-24 15:53:35 +05301298
1299 /* check the TBF */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001300 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);
sivasankari1d8744c2017-01-24 15:53:35 +05301301 /* send packet uplink assignment */
1302 *fn = sba_fn;
1303 request_dl_rlc_block(ul_tbf, fn);
1304
1305 /* send real acknowledgement */
1306 send_control_ack(ul_tbf);
1307
1308 check_tbf(ul_tbf);
1309
1310 return ul_tbf;
1311}
1312
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001313static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_no_length(struct gprs_rlcmac_bts *bts,
sivasankari1d8744c2017-01-24 15:53:35 +05301314 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1315 uint8_t ms_class, uint8_t egprs_ms_class, gprs_rlcmac_ul_tbf *ul_tbf)
1316{
1317 OSMO_ASSERT(ul_tbf);
1318 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1319 GprsMs *ms;
sivasankari1d8744c2017-01-24 15:53:35 +05301320 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001321 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301322 struct gprs_rlcmac_pdch *pdch;
sivasankari1d8744c2017-01-24 15:53:35 +05301323
1324 /* send fake data with cv=0*/
1325 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1326 uint8_t data[49] = {0};
1327
1328 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1329
1330 /*header_construction */
1331 memset(data, 0x2b, sizeof(data));
1332 /* Message with CRBB */
1333 for (int i = 0 ; i < 80; i++) {
1334 hdr3->r = 0;
1335 hdr3->si = 0;
1336 hdr3->cv = 10;
1337 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1338 hdr3->tfi_lo = tfi & 0x7;
1339 hdr3->bsn1_hi = ((i * 2)&0x1f);
1340 hdr3->bsn1_lo = ((i * 2)/32);
1341 hdr3->cps_hi = 0;
1342 hdr3->cps_lo = 0;
1343 hdr3->spb = 0;
1344 hdr3->rsb = 0;
1345 hdr3->pi = 0;
1346 hdr3->spare = 0;
1347 hdr3->dummy = 1;
1348 data[4] = 0x0;
1349 data[5] = 0x0;
1350 data[6] = 0x2b;
1351 data[7] = 0x2b;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001352 pdch = &bts->trx[trx_no].pdch[ts_no];
sivasankari1d8744c2017-01-24 15:53:35 +05301353 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1354 }
1355 ul_tbf->create_ul_ack(*fn, ts_no);
1356 memset(data, 0x2b, sizeof(data));
1357 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1358 hdr3->r = 0;
1359 hdr3->si = 0;
1360 hdr3->cv = 0;
1361 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1362 hdr3->tfi_lo = tfi & 0x7;
1363 hdr3->bsn1_hi = 0;
1364 hdr3->bsn1_lo = 2;
1365 hdr3->cps_hi = 0;
1366 hdr3->cps_lo = 0;
1367 hdr3->spb = 0;
1368 hdr3->rsb = 0;
1369 hdr3->pi = 0;
1370 hdr3->spare = 0;
1371 hdr3->dummy = 1;
1372 data[4] = 0x0;
1373 data[5] = 0x2b;
1374 data[6] = 0x2b;
1375 data[7] = 0x2b;
1376
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001377 pdch = &bts->trx[trx_no].pdch[ts_no];
sivasankari1d8744c2017-01-24 15:53:35 +05301378 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1379
1380 request_dl_rlc_block(ul_tbf, fn);
1381
1382 check_tbf(ul_tbf);
Max088c7df2018-01-23 20:16:23 +01001383 OSMO_ASSERT(ul_tbf->ul_ack_state_is(GPRS_RLCMAC_UL_ACK_NONE));
sivasankari1d8744c2017-01-24 15:53:35 +05301384
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001385 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
sivasankari1d8744c2017-01-24 15:53:35 +05301386 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001387 OSMO_ASSERT(ms_ta(ms) == qta/4);
1388 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
sivasankari1d8744c2017-01-24 15:53:35 +05301389
1390 return ul_tbf;
1391}
1392
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001393static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_with_length(struct gprs_rlcmac_bts *bts,
sivasankari1d8744c2017-01-24 15:53:35 +05301394 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1395 uint8_t ms_class, uint8_t egprs_ms_class, gprs_rlcmac_ul_tbf *ul_tbf)
1396{
1397 OSMO_ASSERT(ul_tbf);
1398 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1399 GprsMs *ms;
sivasankari1d8744c2017-01-24 15:53:35 +05301400 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001401 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301402 struct gprs_rlcmac_pdch *pdch;
sivasankari1d8744c2017-01-24 15:53:35 +05301403
1404 check_tbf(ul_tbf);
1405 /* send fake data with cv=0*/
1406 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1407 uint8_t data[49] = {0};
1408
1409 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1410
1411 /*header_construction */
1412 memset(data, 0x2b, sizeof(data));
1413
1414 /* Message with URBB & URBB length */
1415 for (int i = 0 ; i < 20; i++) {
1416 hdr3->r = 0;
1417 hdr3->si = 0;
1418 hdr3->cv = 10;
1419 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1420 hdr3->tfi_lo = tfi & 0x7;
1421 hdr3->bsn1_hi = ((i * 2)&0x1f);
1422 hdr3->bsn1_lo = ((i * 2)/32);
1423 hdr3->cps_hi = 0;
1424 hdr3->cps_lo = 0;
1425 hdr3->spb = 0;
1426 hdr3->rsb = 0;
1427 hdr3->pi = 0;
1428 hdr3->spare = 0;
1429 hdr3->dummy = 1;
1430 data[4] = 0x0;
1431 data[5] = 0x0;
1432 data[6] = 0x2b;
1433 data[7] = 0x2b;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001434 pdch = &bts->trx[trx_no].pdch[ts_no];
sivasankari1d8744c2017-01-24 15:53:35 +05301435 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1436 }
1437 ul_tbf->create_ul_ack(*fn, ts_no);
1438 memset(data, 0x2b, sizeof(data));
1439 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1440 hdr3->r = 0;
1441 hdr3->si = 0;
1442 hdr3->cv = 0;
1443 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1444 hdr3->tfi_lo = tfi & 0x7;
1445 hdr3->bsn1_hi = 0;
1446 hdr3->bsn1_lo = 2;
1447 hdr3->cps_hi = 0;
1448 hdr3->cps_lo = 0;
1449 hdr3->spb = 0;
1450 hdr3->rsb = 0;
1451 hdr3->pi = 0;
1452 hdr3->spare = 0;
1453 hdr3->dummy = 1;
1454 data[4] = 0x0;
1455 data[5] = 0x2b;
1456 data[6] = 0x2b;
1457 data[7] = 0x2b;
1458
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001459 pdch = &bts->trx[trx_no].pdch[ts_no];
sivasankari1d8744c2017-01-24 15:53:35 +05301460 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
Pau Espin Pedrolc33a0242020-05-15 16:57:48 +02001461 ul_tbf->create_ul_ack(*fn, ts_no);
sivasankari1d8744c2017-01-24 15:53:35 +05301462
1463 request_dl_rlc_block(ul_tbf, fn);
1464
1465 check_tbf(ul_tbf);
Max088c7df2018-01-23 20:16:23 +01001466 OSMO_ASSERT(ul_tbf->ul_ack_state_is(GPRS_RLCMAC_UL_ACK_NONE));
sivasankari1d8744c2017-01-24 15:53:35 +05301467
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001468 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
sivasankari1d8744c2017-01-24 15:53:35 +05301469 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001470 OSMO_ASSERT(ms_ta(ms) == qta/4);
1471 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
sivasankari1d8744c2017-01-24 15:53:35 +05301472
1473 return ul_tbf;
1474}
1475
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001476static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_CRBB(struct gprs_rlcmac_bts *bts,
sivasankari1d8744c2017-01-24 15:53:35 +05301477 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1478 uint8_t ms_class, uint8_t egprs_ms_class)
1479{
1480 GprsMs *ms;
sivasankari1d8744c2017-01-24 15:53:35 +05301481 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001482 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301483 gprs_rlcmac_ul_tbf *ul_tbf;
1484 struct gprs_rlcmac_pdch *pdch;
sivasankari1d8744c2017-01-24 15:53:35 +05301485
1486 /* check the TBF */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001487 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);
sivasankari1d8744c2017-01-24 15:53:35 +05301488 OSMO_ASSERT(ul_tbf);
1489 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1490
1491 /* send fake data with cv=0*/
1492 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1493 uint8_t data[49] = {0};
1494
1495 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1496
1497 /*header_construction */
1498 memset(data, 0x2b, sizeof(data));
1499
1500 /* Message with CRBB */
1501 for (int i = 80 ; i < 160; i++) {
1502 hdr3->r = 0;
1503 hdr3->si = 0;
1504 hdr3->cv = 10;
1505 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1506 hdr3->tfi_lo = tfi & 0x7;
1507 hdr3->bsn1_hi = ((i)&0x1f);
1508 hdr3->bsn1_lo = ((i)/32);
1509 hdr3->cps_hi = 0;
1510 hdr3->cps_lo = 0;
1511 hdr3->spb = 0;
1512 hdr3->rsb = 0;
1513 hdr3->pi = 0;
1514 hdr3->spare = 0;
1515 hdr3->dummy = 1;
1516 data[4] = 0x0;
1517 data[5] = 0x0;
1518 data[6] = 0x2b;
1519 data[7] = 0x2b;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001520 pdch = &bts->trx[trx_no].pdch[ts_no];
sivasankari1d8744c2017-01-24 15:53:35 +05301521 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1522 }
1523 ul_tbf->create_ul_ack(*fn, ts_no);
1524 memset(data, 0x2b, sizeof(data));
1525 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1526 hdr3->r = 0;
1527 hdr3->si = 0;
1528 hdr3->cv = 0;
1529 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1530 hdr3->tfi_lo = tfi & 0x7;
1531 hdr3->bsn1_hi = 0;
1532 hdr3->bsn1_lo = 2;
1533 hdr3->cps_hi = 0;
1534 hdr3->cps_lo = 0;
1535 hdr3->spb = 0;
1536 hdr3->rsb = 0;
1537 hdr3->pi = 0;
1538 hdr3->spare = 0;
1539 hdr3->dummy = 1;
1540 data[4] = 0x0;
1541 data[5] = 0x2b;
1542 data[6] = 0x2b;
1543 data[7] = 0x2b;
1544
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001545 pdch = &bts->trx[trx_no].pdch[ts_no];
sivasankari1d8744c2017-01-24 15:53:35 +05301546 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1547
1548 request_dl_rlc_block(ul_tbf, fn);
1549
1550 check_tbf(ul_tbf);
Max088c7df2018-01-23 20:16:23 +01001551 OSMO_ASSERT(ul_tbf->ul_ack_state_is(GPRS_RLCMAC_UL_ACK_NONE));
sivasankari1d8744c2017-01-24 15:53:35 +05301552
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001553 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
sivasankari1d8744c2017-01-24 15:53:35 +05301554 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001555 OSMO_ASSERT(ms_ta(ms) == qta/4);
1556 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
sivasankari1d8744c2017-01-24 15:53:35 +05301557
1558 return ul_tbf;
1559}
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001560static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase(struct gprs_rlcmac_bts *bts,
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001561 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001562 uint8_t ms_class, uint8_t egprs_ms_class)
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001563{
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001564 GprsMs *ms;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001565 uint32_t rach_fn = *fn - 51;
1566 uint32_t sba_fn = *fn + 52;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001567 uint8_t trx_no = 0;
1568 int tfi = 0;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001569 gprs_rlcmac_ul_tbf *ul_tbf;
1570 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001571 RlcMacUplink_t ulreq = {0};
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001572
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001573 /* needed to set last_rts_fn in the PDCH object */
Max878bd1f2016-07-20 13:05:05 +02001574 request_dl_rlc_block(bts, trx_no, ts_no, fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001575
bhargava959d1de2016-08-17 15:17:21 +05301576 /* simulate RACH, sends an Immediate Assignment Uplink on the AGCH */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001577 bts_handle_rach(bts, 0x73, rach_fn, qta);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001578
1579 /* get next free TFI */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001580 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001581
1582 /* fake a resource request */
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001583 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
1584 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
1585 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
1586 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001587 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
1588 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001589 Count_MS_RA_capability_value = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001590 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001591 MS_RA_capability_value[0].u.Content.Exist_Multislot_capability = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001592 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001593 MS_RA_capability_value[0].u.Content.Multislot_capability.
1594 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001595 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001596 MS_RA_capability_value[0].u.Content.Multislot_capability.
1597 GPRS_multislot_class = ms_class;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001598 if (egprs_ms_class) {
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001599 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001600 MS_RA_capability_value[0].u.Content.Multislot_capability.
1601 Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001602 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001603 MS_RA_capability_value[0].u.Content.Multislot_capability.
1604 EGPRS_multislot_class = ms_class;
1605 }
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001606
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001607 send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001608
1609 /* check the TBF */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001610 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001611 OSMO_ASSERT(ul_tbf != NULL);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +02001612 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001613
1614 /* send packet uplink assignment */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001615 *fn = sba_fn;
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +02001616 request_dl_rlc_block(ul_tbf, fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001617
Jacob Erlbeckaf454732015-08-21 15:03:23 +02001618 /* send real acknowledgement */
1619 send_control_ack(ul_tbf);
1620
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001621 check_tbf(ul_tbf);
1622
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001623 /* send fake data */
1624 uint8_t data_msg[23] = {
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001625 0x00 | 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
1626 uint8_t(0 | (tfi << 1)),
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001627 uint8_t(1), /* BSN:7, E:1 */
1628 };
1629
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001630 pdch = &bts->trx[trx_no].pdch[ts_no];
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001631 pdch->rcv_block(&data_msg[0], sizeof(data_msg), *fn, &meas);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001632
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001633 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001634 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001635 OSMO_ASSERT(ms_ta(ms) == qta/4);
1636 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001637
1638 return ul_tbf;
1639}
1640
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001641static void send_dl_data(struct gprs_rlcmac_bts *bts, uint32_t tlli, const char *imsi,
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001642 const uint8_t *data, unsigned data_size)
1643{
1644 GprsMs *ms, *ms2;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001645
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001646 ms = bts_ms_store(bts)->get_ms(tlli, 0, imsi);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001647
Pau Espin Pedrol8a35e642021-01-18 17:14:14 +01001648 dl_tbf_handle(bts, tlli, 0, imsi, 0, 0,
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001649 1000, data, data_size);
1650
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001651 ms = bts_ms_by_imsi(bts, imsi);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001652 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001653 OSMO_ASSERT(ms_dl_tbf(ms) != NULL);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001654
1655 if (imsi[0] && strcmp(imsi, "000") != 0) {
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001656 ms2 = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001657 OSMO_ASSERT(ms == ms2);
1658 }
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001659}
1660
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001661static void transmit_dl_data(struct gprs_rlcmac_bts *bts, uint32_t tlli, uint32_t *fn,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001662 uint8_t slots = 0xff)
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001663{
1664 gprs_rlcmac_dl_tbf *dl_tbf;
1665 GprsMs *ms;
1666 unsigned ts_no;
1667
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001668 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001669 OSMO_ASSERT(ms);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001670 dl_tbf = ms_dl_tbf(ms);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001671 OSMO_ASSERT(dl_tbf);
1672
1673 while (dl_tbf->have_data()) {
1674 uint8_t bn = fn2bn(*fn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001675 for (ts_no = 0 ; ts_no < 8; ts_no += 1) {
1676 if (!(slots & (1 << ts_no)))
1677 continue;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001678 gprs_rlcmac_rcv_rts_block(bts,
Max878bd1f2016-07-20 13:05:05 +02001679 dl_tbf->trx->trx_no, ts_no,
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001680 *fn, bn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001681 }
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001682 *fn = fn_add_blocks(*fn, 1);
1683 }
1684}
1685
Max4c112dc2018-02-01 16:49:23 +01001686static inline void print_ta_tlli(const gprs_rlcmac_ul_tbf *ul_tbf, bool print_ms)
1687{
1688 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
1689 if (print_ms)
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001690 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 +01001691}
1692
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001693static void test_tbf_single_phase()
1694{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001695 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001696 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001697 int ts_no = 7;
Philippd935d882016-11-07 13:07:36 +01001698 uint32_t fn = DUMMY_FN; /* 17,25,9 */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001699 uint32_t tlli = 0xf1223344;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001700 const char *imsi = "0011223344";
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001701 uint16_t qta = 31;
1702 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001703
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001704 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001705
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001706 setup_bts(bts, ts_no);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001707
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001708 ul_tbf = establish_ul_tbf_single_phase(bts, ts_no, tlli, &fn, qta);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001709
Max4c112dc2018-02-01 16:49:23 +01001710 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001711 send_dl_data(bts, tlli, imsi, (const uint8_t *)"TEST", 4);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001712
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001713 fprintf(stderr, "=== end %s ===\n", __func__);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001714 TALLOC_FREE(the_pcu);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001715}
1716
sivasankari1d8744c2017-01-24 15:53:35 +05301717static void test_tbf_egprs_two_phase_puan(void)
1718{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001719 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001720 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
sivasankari1d8744c2017-01-24 15:53:35 +05301721 int ts_no = 7;
1722 uint32_t fn = 2654218;
1723 uint16_t qta = 31;
1724 uint32_t tlli = 0xf1223344;
1725 const char *imsi = "0011223344";
1726 uint8_t ms_class = 1;
sivasankari1d8744c2017-01-24 15:53:35 +05301727 uint8_t egprs_ms_class = 1;
1728 gprs_rlcmac_ul_tbf *ul_tbf;
sivasankari1d8744c2017-01-24 15:53:35 +05301729 uint8_t test_data[256];
1730
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001731 fprintf(stderr, "=== start %s ===\n", __func__);
sivasankari1d8744c2017-01-24 15:53:35 +05301732
1733 memset(test_data, 1, sizeof(test_data));
1734
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001735 setup_bts(bts, ts_no, 4);
1736 bts->initial_mcs_dl = 9;
Pau Espin Pedrol519d0712021-01-14 14:30:03 +01001737 the_pcu->vty.ws_base = 128;
1738 the_pcu->vty.ws_pdch = 64;
sivasankari1d8744c2017-01-24 15:53:35 +05301739
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001740 ul_tbf = establish_ul_tbf(bts, ts_no, tlli, &fn, qta, ms_class, egprs_ms_class);
sivasankari1d8744c2017-01-24 15:53:35 +05301741 /* Function to generate URBB with no length */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001742 ul_tbf = establish_ul_tbf_two_phase_puan_URBB_no_length(bts, ts_no, tlli, &fn,
sivasankari1d8744c2017-01-24 15:53:35 +05301743 qta, ms_class, egprs_ms_class, ul_tbf);
1744
Max4c112dc2018-02-01 16:49:23 +01001745 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001746 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
sivasankari1d8744c2017-01-24 15:53:35 +05301747
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02001748 static_cast<gprs_rlc_ul_window *>(ul_tbf->window())->reset_state();
sivasankari1d8744c2017-01-24 15:53:35 +05301749 /* Function to generate URBB with length */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001750 ul_tbf = establish_ul_tbf_two_phase_puan_URBB_with_length(bts, ts_no, tlli, &fn,
sivasankari1d8744c2017-01-24 15:53:35 +05301751 qta, ms_class, egprs_ms_class, ul_tbf);
1752
Max4c112dc2018-02-01 16:49:23 +01001753 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001754 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
sivasankari1d8744c2017-01-24 15:53:35 +05301755
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02001756 static_cast<gprs_rlc_ul_window *>(ul_tbf->window())->reset_state();
sivasankari1d8744c2017-01-24 15:53:35 +05301757 /* Function to generate CRBB */
Pau Espin Pedrol519d0712021-01-14 14:30:03 +01001758 the_pcu->vty.ws_base = 128;
1759 the_pcu->vty.ws_pdch = 64;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001760 ul_tbf = establish_ul_tbf_two_phase_puan_CRBB(bts, ts_no, tlli, &fn,
sivasankari1d8744c2017-01-24 15:53:35 +05301761 qta, ms_class, egprs_ms_class);
1762
Max4c112dc2018-02-01 16:49:23 +01001763 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001764 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
sivasankari1d8744c2017-01-24 15:53:35 +05301765
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001766 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001767 fprintf(stderr, "=== end %s ===\n", __func__);
sivasankari1d8744c2017-01-24 15:53:35 +05301768}
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301769/*
1770 * Trigger rach for single block
1771 */
1772static void test_immediate_assign_rej_single_block()
1773{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001774 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001775 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301776 uint32_t fn = 2654218;
1777 uint16_t qta = 31;
1778 int ts_no = 7;
1779
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001780 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301781
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001782 setup_bts(bts, ts_no, 4);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301783
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001784 bts->trx[0].pdch[ts_no].disable();
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301785
1786 uint32_t rach_fn = fn - 51;
1787
1788 int rc = 0;
1789
1790 /*
1791 * simulate RACH, sends an Immediate Assignment
1792 * Uplink reject on the AGCH
1793 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001794 rc = bts_handle_rach(bts, 0x70, rach_fn, qta);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301795
1796 OSMO_ASSERT(rc == -EINVAL);
1797
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001798 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001799 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301800}
1801
1802/*
1803 * Trigger rach till resources(USF) exhaust
1804 */
1805static void test_immediate_assign_rej_multi_block()
1806{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001807 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001808 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301809 uint32_t fn = 2654218;
1810 uint16_t qta = 31;
1811 int ts_no = 7;
1812
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001813 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301814
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001815 setup_bts(bts, ts_no, 4);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301816
1817 uint32_t rach_fn = fn - 51;
1818
1819 int rc = 0;
1820
1821 /*
1822 * simulate RACH, sends an Immediate Assignment Uplink
1823 * reject on the AGCH
1824 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001825 rc = bts_handle_rach(bts, 0x78, rach_fn, qta);
1826 rc = bts_handle_rach(bts, 0x79, rach_fn, qta);
1827 rc = bts_handle_rach(bts, 0x7a, rach_fn, qta);
1828 rc = bts_handle_rach(bts, 0x7b, rach_fn, qta);
1829 rc = bts_handle_rach(bts, 0x7c, rach_fn, qta);
1830 rc = bts_handle_rach(bts, 0x7d, rach_fn, qta);
1831 rc = bts_handle_rach(bts, 0x7e, rach_fn, qta);
1832 rc = bts_handle_rach(bts, 0x7f, rach_fn, qta);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301833
1834 OSMO_ASSERT(rc == -EBUSY);
1835
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001836 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001837 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301838}
1839
1840static void test_immediate_assign_rej()
1841{
1842 test_immediate_assign_rej_multi_block();
1843 test_immediate_assign_rej_single_block();
1844}
1845
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001846static void test_tbf_two_phase()
1847{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001848 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001849 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001850 int ts_no = 7;
1851 uint32_t fn = 2654218;
1852 uint16_t qta = 31;
1853 uint32_t tlli = 0xf1223344;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001854 const char *imsi = "0011223344";
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001855 uint8_t ms_class = 1;
1856 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001857
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001858 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001859
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001860 setup_bts(bts, ts_no, 4);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001861
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001862 ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001863 ms_class, 0);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001864
Max4c112dc2018-02-01 16:49:23 +01001865 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001866 send_dl_data(bts, tlli, imsi, (const uint8_t *)"TEST", 4);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001867
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001868 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001869 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001870}
1871
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001872static inline void print_ms(GprsMs *ms, bool old)
Max4c112dc2018-02-01 16:49:23 +01001873{
1874 fprintf(stderr, "%s MS: TLLI = 0x%08x, TA = %d, IMSI = %s, LLC = %zu\n",
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001875 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 +01001876}
1877
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001878static void test_tbf_ra_update_rach()
1879{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001880 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001881 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001882 int ts_no = 7;
1883 uint32_t fn = 2654218;
1884 uint16_t qta = 31;
1885 uint32_t tlli1 = 0xf1223344;
1886 uint32_t tlli2 = 0xf5667788;
1887 const char *imsi = "0011223344";
1888 uint8_t ms_class = 1;
1889 gprs_rlcmac_ul_tbf *ul_tbf;
1890 GprsMs *ms, *ms1, *ms2;
1891
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001892 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001893
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001894 setup_bts(bts, ts_no, 4);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001895
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001896 ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001897 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001898
1899 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01001900 print_ta_tlli(ul_tbf, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001901
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001902 send_dl_data(bts, tlli1, imsi, (const uint8_t *)"RAU_ACCEPT", 10);
Max4c112dc2018-02-01 16:49:23 +01001903 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001904
Jacob Erlbeckaf454732015-08-21 15:03:23 +02001905 /* Send Packet Downlink Assignment to MS */
1906 request_dl_rlc_block(ul_tbf, &fn);
1907
1908 /* Ack it */
1909 send_control_ack(ul_tbf);
1910
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001911 /* Make sure the RAU Accept gets sent to the MS */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001912 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 1);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001913 transmit_dl_data(bts, tlli1, &fn);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001914 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001915
1916 /* Now establish a new TBF for the RA UPDATE COMPLETE (new TLLI) */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001917 ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli2, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001918 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001919
1920 ms2 = ul_tbf->ms();
1921
1922 /* The PCU cannot know yet, that both TBF belong to the same MS */
1923 OSMO_ASSERT(ms1 != ms2);
Max4c112dc2018-02-01 16:49:23 +01001924 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001925
1926 /* Send some downlink data along with the new TLLI and the IMSI so that
1927 * the PCU can see, that both MS objects belong to same MS */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001928 send_dl_data(bts, tlli2, imsi, (const uint8_t *)"DATA", 4);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001929
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001930 ms = bts_ms_by_imsi(bts, imsi);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001931 OSMO_ASSERT(ms == ms2);
1932
Max4c112dc2018-02-01 16:49:23 +01001933 print_ms(ms2, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001934
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001935 ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001936 OSMO_ASSERT(ms == NULL);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001937 ms = bts_ms_by_tlli(bts, tlli2, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001938 OSMO_ASSERT(ms == ms2);
1939
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001940 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001941 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001942}
1943
1944static void test_tbf_dl_flow_and_rach_two_phase()
1945{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001946 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001947 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001948 int ts_no = 7;
1949 uint32_t fn = 2654218;
1950 uint16_t qta = 31;
1951 uint32_t tlli1 = 0xf1223344;
1952 const char *imsi = "0011223344";
1953 uint8_t ms_class = 1;
1954 gprs_rlcmac_ul_tbf *ul_tbf;
1955 gprs_rlcmac_dl_tbf *dl_tbf;
1956 GprsMs *ms, *ms1, *ms2;
1957
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001958 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001959
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001960 setup_bts(bts, ts_no, 1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001961
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001962 ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001963 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001964
1965 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01001966 print_ta_tlli(ul_tbf, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001967
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001968 send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);
1969 send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);
Max4c112dc2018-02-01 16:49:23 +01001970 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001971
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001972 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 2);
1973 dl_tbf = ms_dl_tbf(ms1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001974 OSMO_ASSERT(dl_tbf != NULL);
1975
1976 /* Get rid of old UL TBF */
1977 tbf_free(ul_tbf);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001978 ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001979 OSMO_ASSERT(ms1 == ms);
1980
1981 /* Now establish a new UL TBF, this will consume one LLC packet */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001982 ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001983 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001984
1985 ms2 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01001986 print_ms(ms2, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001987
1988 /* This should be the same MS object */
1989 OSMO_ASSERT(ms2 == ms1);
1990
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001991 ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001992 OSMO_ASSERT(ms2 == ms);
1993
Jacob Erlbeckc8cbfc22015-09-01 11:38:40 +02001994 /* A DL TBF should still exist */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001995 OSMO_ASSERT(ms_dl_tbf(ms));
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001996
1997 /* No queued packets should be lost */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001998 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms)) == 2);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001999
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002000 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002001 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002002}
2003
2004
2005static void test_tbf_dl_flow_and_rach_single_phase()
2006{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002007 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002008 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002009 int ts_no = 7;
2010 uint32_t fn = 2654218;
2011 uint16_t qta = 31;
2012 uint32_t tlli1 = 0xf1223344;
2013 const char *imsi = "0011223344";
2014 uint8_t ms_class = 1;
2015 gprs_rlcmac_ul_tbf *ul_tbf;
2016 gprs_rlcmac_dl_tbf *dl_tbf;
2017 GprsMs *ms, *ms1, *ms2;
2018
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002019 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002020
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002021 setup_bts(bts, ts_no, 1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002022
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002023 ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002024 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002025
2026 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002027 print_ta_tlli(ul_tbf, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002028
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002029 send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);
2030 send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);
Max4c112dc2018-02-01 16:49:23 +01002031 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002032
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002033 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 2);
2034 dl_tbf = ms_dl_tbf(ms1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002035 OSMO_ASSERT(dl_tbf != NULL);
2036
2037 /* Get rid of old UL TBF */
2038 tbf_free(ul_tbf);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002039 ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002040 OSMO_ASSERT(ms1 == ms);
2041
2042 /* Now establish a new UL TBF */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002043 ul_tbf = establish_ul_tbf_single_phase(bts, ts_no, tlli1, &fn, qta);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002044
2045 ms2 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002046 print_ms(ms2, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002047
2048 /* There should be a different MS object */
2049 OSMO_ASSERT(ms2 != ms1);
2050
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002051 ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002052 OSMO_ASSERT(ms2 == ms);
2053 OSMO_ASSERT(ms1 != ms);
2054
Jacob Erlbeck5f93f852016-01-21 20:48:39 +01002055 /* DL TBF should be removed */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002056 OSMO_ASSERT(!ms_dl_tbf(ms));
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002057
2058 /* No queued packets should be lost */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002059 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms)) == 2);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002060
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002061 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002062 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002063}
2064
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002065static void test_tbf_dl_reuse()
2066{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002067 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002068 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002069 int ts_no = 7;
2070 uint32_t fn = 2654218;
2071 uint16_t qta = 31;
2072 uint32_t tlli1 = 0xf1223344;
2073 const char *imsi = "0011223344";
2074 uint8_t ms_class = 1;
2075 gprs_rlcmac_ul_tbf *ul_tbf;
2076 gprs_rlcmac_dl_tbf *dl_tbf1, *dl_tbf2;
2077 GprsMs *ms1, *ms2;
2078 unsigned i;
2079 RlcMacUplink_t ulreq = {0};
2080
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002081 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002082
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002083 setup_bts(bts, ts_no, 1);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002084
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002085 ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002086 ms_class, 0);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002087
2088 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002089 print_ta_tlli(ul_tbf, false);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002090
2091 /* Send some LLC frames */
2092 for (i = 0; i < 40; i++) {
2093 char buf[32];
2094 int rc;
2095
2096 rc = snprintf(buf, sizeof(buf), "LLC PACKET %02i", i);
2097 OSMO_ASSERT(rc > 0);
2098
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002099 send_dl_data(bts, tlli1, imsi, (const uint8_t *)buf, rc);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002100 }
2101
Max4c112dc2018-02-01 16:49:23 +01002102 print_ms(ms1, true);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002103
2104 /* Send Packet Downlink Assignment to MS */
2105 request_dl_rlc_block(ul_tbf, &fn);
2106
2107 /* Ack it */
2108 send_control_ack(ul_tbf);
2109
2110 /* Transmit all data */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002111 transmit_dl_data(bts, tlli1, &fn);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002112 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 0);
2113 OSMO_ASSERT(ms_dl_tbf(ms1));
2114 OSMO_ASSERT(ms_dl_tbf(ms1)->state_is(GPRS_RLCMAC_FINISHED));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002115
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002116 dl_tbf1 = ms_dl_tbf(ms1);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002117
2118 /* Send some LLC frames */
2119 for (i = 0; i < 10; i++) {
2120 char buf[32];
2121 int rc;
2122
2123 rc = snprintf(buf, sizeof(buf), "LLC PACKET %02i (TBF 2)", i);
2124 OSMO_ASSERT(rc > 0);
2125
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002126 send_dl_data(bts, tlli1, imsi, (const uint8_t *)buf, rc);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002127 }
2128
2129 /* Fake Final DL Ack/Nack */
2130 ulreq.u.MESSAGE_TYPE = MT_PACKET_DOWNLINK_ACK_NACK;
2131 Packet_Downlink_Ack_Nack_t *ack = &ulreq.u.Packet_Downlink_Ack_Nack;
2132
2133 ack->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
2134 ack->DOWNLINK_TFI = dl_tbf1->tfi();
2135 ack->Ack_Nack_Description.FINAL_ACK_INDICATION = 1;
2136
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002137 send_ul_mac_block(bts, 0, dl_tbf1->poll_ts, &ulreq, dl_tbf1->poll_fn);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002138
2139 OSMO_ASSERT(dl_tbf1->state_is(GPRS_RLCMAC_WAIT_RELEASE));
2140
2141 request_dl_rlc_block(dl_tbf1, &fn);
2142
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002143 ms2 = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002144 OSMO_ASSERT(ms2 == ms1);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002145 OSMO_ASSERT(ms_dl_tbf(ms2));
2146 OSMO_ASSERT(ms_dl_tbf(ms2)->state_is(GPRS_RLCMAC_ASSIGN));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002147
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002148 dl_tbf2 = ms_dl_tbf(ms2);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002149
2150 OSMO_ASSERT(dl_tbf1 != dl_tbf2);
2151
2152 send_control_ack(dl_tbf1);
Jacob Erlbeck6835cea2015-08-21 15:24:02 +02002153 OSMO_ASSERT(dl_tbf2->state_is(GPRS_RLCMAC_FLOW));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002154
2155 /* Transmit all data */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002156 transmit_dl_data(bts, tlli1, &fn);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002157 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms2)) == 0);
2158 OSMO_ASSERT(ms_dl_tbf(ms2));
2159 OSMO_ASSERT(ms_dl_tbf(ms2)->state_is(GPRS_RLCMAC_FINISHED));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002160
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002161 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002162 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002163}
2164
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002165static void test_tbf_gprs_egprs()
2166{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002167 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002168 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002169 uint8_t ts_no = 4;
2170 uint8_t ms_class = 45;
2171 int rc = 0;
2172 uint32_t tlli = 0xc0006789;
2173 const char *imsi = "001001123456789";
2174 unsigned delay_csec = 1000;
2175
2176 uint8_t buf[256] = {0};
2177
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002178 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002179
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002180 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
2181 if (!bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +02002182 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
2183 abort();
2184 }
2185
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002186 setup_bts(bts, ts_no);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002187
2188 /* EGPRS-only */
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002189
Alexander Couzens290d9032020-09-16 21:52:02 +02002190 gprs_bssgp_init(bts, 3234, 3234, 1, 1, false, 0, 0, 0);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002191
2192 /* Does not support EGPRS */
Pau Espin Pedrol8a35e642021-01-18 17:14:14 +01002193 rc = dl_tbf_handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002194 delay_csec, buf, sizeof(buf));
2195
Pau Espin Pedrol569f0d22020-10-27 14:45:20 +01002196 OSMO_ASSERT(rc == 0);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002197 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002198
Alexander Couzens290d9032020-09-16 21:52:02 +02002199 gprs_bssgp_destroy(bts);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002200 TALLOC_FREE(the_pcu);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002201}
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02002202
Max4c112dc2018-02-01 16:49:23 +01002203static inline void ws_check(gprs_rlcmac_dl_tbf *dl_tbf, const char *test, uint8_t exp_slots, uint16_t exp_ws,
2204 bool free, bool end)
2205{
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002206 gprs_rlcmac_bts *bts = dl_tbf->bts;
Max4c112dc2018-02-01 16:49:23 +01002207 if (!dl_tbf) {
2208 fprintf(stderr, "%s(): FAILED (NULL TBF)\n", test);
2209 return;
2210 }
2211
2212 fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d",
2213 dl_tbf->dl_slots(),
2214 pcu_bitcount(dl_tbf->dl_slots()),
2215 dl_tbf->window_size());
2216
2217 if (pcu_bitcount(dl_tbf->dl_slots()) != exp_slots || dl_tbf->window_size() != exp_ws)
2218 fprintf(stderr, "%s(): DL TBF FAILED: dl_slots = %u (exp. %u), WS = %u (exp. %u)",
2219 test, pcu_bitcount(dl_tbf->dl_slots()), 4, dl_tbf->window_size(), 128 + 4 * 64);
2220
2221 fprintf(stderr, "\n");
2222
2223 if (free)
2224 tbf_free(dl_tbf);
2225
2226 if (end) {
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002227 fprintf(stderr, "=== end %s ===\n", test);
Alexander Couzens290d9032020-09-16 21:52:02 +02002228 gprs_bssgp_destroy(bts);
Max4c112dc2018-02-01 16:49:23 +01002229 }
2230}
2231
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002232static void test_tbf_ws()
2233{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002234 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002235 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +02002236 GprsMs *ms;
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002237 uint8_t ts_no = 4;
2238 uint8_t ms_class = 12;
2239 gprs_rlcmac_dl_tbf *dl_tbf;
2240
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002241 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002242
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002243 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
2244 if (!bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +02002245 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
2246 abort();
2247 }
2248
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002249 setup_bts(bts, ts_no);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002250
Pau Espin Pedrol519d0712021-01-14 14:30:03 +01002251 the_pcu->vty.ws_base = 128;
2252 the_pcu->vty.ws_pdch = 64;
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002253 the_pcu->alloc_algorithm = alloc_algorithm_b;
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002254 bts->trx[0].pdch[2].enable();
2255 bts->trx[0].pdch[3].enable();
2256 bts->trx[0].pdch[4].enable();
2257 bts->trx[0].pdch[5].enable();
2258
Alexander Couzens290d9032020-09-16 21:52:02 +02002259 gprs_bssgp_init(bts, 4234, 4234, 1, 1, false, 0, 0, 0);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002260
2261 /* Does no support EGPRS */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002262 ms = bts_alloc_ms(bts, ms_class, 0);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +02002263 dl_tbf = tbf_alloc_dl_tbf(bts, ms, 0, false);
Max4c112dc2018-02-01 16:49:23 +01002264
2265 ws_check(dl_tbf, __func__, 4, 64, true, false);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002266
2267 /* EGPRS-only */
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002268
2269 /* Does support EGPRS */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002270 ms = bts_alloc_ms(bts, ms_class, ms_class);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +02002271 dl_tbf = tbf_alloc_dl_tbf(bts, ms, 0, false);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002272
Max4c112dc2018-02-01 16:49:23 +01002273 ws_check(dl_tbf, __func__, 4, 128 + 4 * 64, true, true);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002274 TALLOC_FREE(the_pcu);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002275}
2276
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302277static void test_tbf_update_ws(void)
2278{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002279 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002280 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +02002281 GprsMs *ms;
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302282 uint8_t ts_no = 4;
2283 uint8_t ms_class = 11;
2284 gprs_rlcmac_dl_tbf *dl_tbf;
2285
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002286 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302287
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002288 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
2289 if (!bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +02002290 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
2291 abort();
2292 }
2293
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002294 setup_bts(bts, ts_no);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302295
Pau Espin Pedrol519d0712021-01-14 14:30:03 +01002296 the_pcu->vty.ws_base = 128;
2297 the_pcu->vty.ws_pdch = 64;
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002298 the_pcu->alloc_algorithm = alloc_algorithm_b;
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302299 bts->trx[0].pdch[2].enable();
2300 bts->trx[0].pdch[3].enable();
2301 bts->trx[0].pdch[4].enable();
2302 bts->trx[0].pdch[5].enable();
2303
Alexander Couzens290d9032020-09-16 21:52:02 +02002304 gprs_bssgp_init(bts, 5234, 5234, 1, 1, false, 0, 0, 0);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302305
2306 /* EGPRS-only */
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302307
2308 /* Does support EGPRS */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002309 ms = bts_alloc_ms(bts, ms_class, ms_class);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +02002310 dl_tbf = tbf_alloc_dl_tbf(bts, ms, 0, true);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302311
Max4c112dc2018-02-01 16:49:23 +01002312 ws_check(dl_tbf, __func__, 1, 128 + 1 * 64, false, false);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302313
2314 dl_tbf->update();
2315
Aravind Sirsikar0ee31cf2016-09-15 17:54:46 +05302316 /* window size should be 384 */
Max4c112dc2018-02-01 16:49:23 +01002317 ws_check(dl_tbf, __func__, 4, 128 + 4 * 64, true, true);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002318 TALLOC_FREE(the_pcu);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302319}
2320
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302321static void test_tbf_puan_urbb_len(void)
2322{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002323 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002324 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302325 int ts_no = 7;
2326 uint32_t fn = 2654218;
2327 uint16_t qta = 31;
2328 uint32_t tlli = 0xf1223344;
2329 const char *imsi = "0011223344";
2330 uint8_t ms_class = 1;
2331 uint8_t egprs_ms_class = 1;
2332 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302333 uint8_t test_data[256];
2334
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002335 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302336
2337 memset(test_data, 1, sizeof(test_data));
2338
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002339 setup_bts(bts, ts_no, 4);
2340 bts->initial_mcs_dl = 9;
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302341
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002342 ul_tbf = puan_urbb_len_issue(bts, ts_no, tlli, &fn, qta,
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302343 ms_class, egprs_ms_class);
2344
Max4c112dc2018-02-01 16:49:23 +01002345 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002346 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302347
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002348 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002349 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302350}
2351
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002352static gprs_rlcmac_ul_tbf *tbf_li_decoding(struct gprs_rlcmac_bts *bts,
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302353 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
2354 uint8_t ms_class, uint8_t egprs_ms_class)
2355{
2356 GprsMs *ms;
2357 uint32_t rach_fn = *fn - 51;
2358 uint32_t sba_fn = *fn + 52;
2359 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002360 int tfi = 0;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302361 gprs_rlcmac_ul_tbf *ul_tbf;
2362 struct gprs_rlcmac_pdch *pdch;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302363 RlcMacUplink_t ulreq = {0};
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302364 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302365 Packet_Resource_Request_t *presreq = NULL;
2366 MS_Radio_Access_capability_t *pmsradiocap = NULL;
2367 Multislot_capability_t *pmultislotcap = NULL;
2368
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302369 /* needed to set last_rts_fn in the PDCH object */
2370 request_dl_rlc_block(bts, trx_no, ts_no, fn);
2371
2372 /*
2373 * simulate RACH, this sends an Immediate
2374 * Assignment Uplink on the AGCH
2375 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002376 bts_handle_rach(bts, 0x73, rach_fn, qta);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302377
2378 /* get next free TFI */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002379 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302380
2381 /* fake a resource request */
2382 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
2383 presreq = &ulreq.u.Packet_Resource_Request;
2384 presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
2385 presreq->ID.UnionType = 1; /* != 0 */
2386 presreq->ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01002387 presreq->Exist_MS_Radio_Access_capability2 = 1;
2388 pmsradiocap = &presreq->MS_Radio_Access_capability2;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302389 pmsradiocap->Count_MS_RA_capability_value = 1;
2390 pmsradiocap->MS_RA_capability_value[0].u.Content.
2391 Exist_Multislot_capability = 1;
2392 pmultislotcap = &pmsradiocap->MS_RA_capability_value[0].
2393 u.Content.Multislot_capability;
2394
2395 pmultislotcap->Exist_GPRS_multislot_class = 1;
2396 pmultislotcap->GPRS_multislot_class = ms_class;
2397 if (egprs_ms_class) {
2398 pmultislotcap->Exist_EGPRS_multislot_class = 1;
2399 pmultislotcap->EGPRS_multislot_class = ms_class;
2400 }
2401
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002402 send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302403
2404 /* check the TBF */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002405 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302406 OSMO_ASSERT(ul_tbf);
2407 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
2408
2409 /* send packet uplink assignment */
2410 *fn = sba_fn;
2411 request_dl_rlc_block(ul_tbf, fn);
2412
2413 /* send real acknowledgement */
2414 send_control_ack(ul_tbf);
2415
2416 check_tbf(ul_tbf);
2417
2418 uint8_t data_msg[49] = {0};
2419
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002420 pdch = &bts->trx[trx_no].pdch[ts_no];
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302421
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002422 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302423 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002424 OSMO_ASSERT(ms_ta(ms) == qta/4);
2425 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302426
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302427 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
2428 egprs3->si = 0;
2429 egprs3->r = 1;
2430 egprs3->cv = 7;
2431 egprs3->tfi_hi = tfi & 0x03;
2432 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
2433 egprs3->bsn1_hi = 0;
2434 egprs3->bsn1_lo = 0;
2435 egprs3->cps_hi = 1;
2436 data_msg[3] = 0xff;
2437 egprs3->pi = 0;
2438 egprs3->cps_lo = 1;
2439 egprs3->rsb = 0;
2440 egprs3->spb = 0;
2441 egprs3->pi = 0;
2442 pdch->rcv_block(data_msg, 49, *fn, &meas);
2443
2444 egprs3->bsn1_hi = 1;
2445 egprs3->bsn1_lo = 0;
2446 data_msg[3] = 0x7f;
2447 egprs3->cps_lo = 1;
2448 egprs3->rsb = 0;
2449 egprs3->spb = 0;
2450 egprs3->pi = 0;
2451 data_msg[4] = 0x2;
2452 data_msg[5] = 0x0;
2453 pdch->rcv_block(data_msg, 49, *fn, &meas);
2454
Aravind Sirsikar22a90192016-09-15 17:24:49 +05302455 OSMO_ASSERT(ul_tbf->m_llc.m_index == 43);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302456
2457 return ul_tbf;
2458}
2459
2460static void test_tbf_li_decoding(void)
2461{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002462 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002463 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302464 int ts_no = 7;
2465 uint32_t fn = 2654218;
2466 uint16_t qta = 31;
2467 uint32_t tlli = 0xf1223344;
2468 const char *imsi = "0011223344";
2469 uint8_t ms_class = 1;
2470 uint8_t egprs_ms_class = 1;
2471 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302472 uint8_t test_data[256];
2473
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002474 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302475
2476 memset(test_data, 1, sizeof(test_data));
2477
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002478 setup_bts(bts, ts_no, 4);
2479 bts->initial_mcs_dl = 9;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302480
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002481 ul_tbf = tbf_li_decoding(bts, ts_no, tlli, &fn, qta,
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302482 ms_class, egprs_ms_class);
2483
Max4c112dc2018-02-01 16:49:23 +01002484 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002485 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302486
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002487 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002488 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302489}
2490
aravind sirsikarf2761382016-10-25 12:45:24 +05302491/*
2492 * Test that a bit within the uncompressed bitmap whose BSN is not within
2493 * the transmit window shall be ignored. See section 9.1.8.2.4 of 44.060
2494 * version 7.27.0 Release 7.
2495 */
2496static void test_tbf_epdan_out_of_rx_window(void)
2497{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002498 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002499 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
aravind sirsikarf2761382016-10-25 12:45:24 +05302500 uint8_t ms_class = 11;
2501 uint8_t egprs_ms_class = 11;
2502 uint8_t trx_no;
2503 uint32_t tlli = 0xffeeddcc;
2504 gprs_rlcmac_dl_tbf *dl_tbf;
2505 int ts_no = 4;
2506 bitvec *block;
2507 uint8_t bits_data[RLC_EGPRS_MAX_WS/8];
2508 bitvec bits;
2509 int bsn_begin, bsn_end;
2510 EGPRS_PD_AckNack_t *ack_nack;
2511 RlcMacUplink_t ul_control_block;
2512 gprs_rlc_v_b *prlcmvb;
2513 gprs_rlc_dl_window *prlcdlwindow;
Pau Espin Pedrol5e300ce2020-02-03 17:18:03 +01002514 int rc;
aravind sirsikarf2761382016-10-25 12:45:24 +05302515
aravind sirsikarcc4214a2016-12-09 16:12:42 +05302516 memset(&ul_control_block, 0, sizeof(RlcMacUplink_t));
2517
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002518 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikarf2761382016-10-25 12:45:24 +05302519
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002520 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01002521 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
aravind sirsikarf2761382016-10-25 12:45:24 +05302522 /* ARQ II */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01002523 the_pcu->vty.dl_arq_type = EGPRS_ARQ2;
aravind sirsikarf2761382016-10-25 12:45:24 +05302524
2525 /*
2526 * Simulate a message captured during over-the-air testing,
2527 * where the following values were observed:
2528 * v_a = 1176, vs = 1288, max sns = 2048, window size = 480.
2529 */
2530 uint8_t data_msg[23] = {0x40, 0x20, 0x0b, 0xff, 0xd1,
2531 0x61, 0x00, 0x3e, 0x0e, 0x51, 0x9f,
2532 0xff, 0xff, 0xfb, 0x80, 0x00, 0x00,
2533 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
2534
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002535 dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no);
aravind sirsikarf2761382016-10-25 12:45:24 +05302536 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002537 prlcdlwindow = static_cast<gprs_rlc_dl_window *>(dl_tbf->window());
aravind sirsikarf2761382016-10-25 12:45:24 +05302538 prlcmvb = &prlcdlwindow->m_v_b;
2539 prlcdlwindow->m_v_s = 1288;
2540 prlcdlwindow->m_v_a = 1176;
2541 prlcdlwindow->set_sns(2048);
2542 prlcdlwindow->set_ws(480);
2543 prlcmvb->mark_unacked(1176);
2544 prlcmvb->mark_unacked(1177);
2545 prlcmvb->mark_unacked(1286);
2546 prlcmvb->mark_unacked(1287);
2547
2548 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2549
Alexander Couzensccde5c92017-02-04 03:10:08 +01002550 block = bitvec_alloc(23, tall_pcu_ctx);
aravind sirsikarf2761382016-10-25 12:45:24 +05302551
2552 bitvec_unpack(block, data_msg);
2553
2554 bits.data = bits_data;
2555 bits.data_len = sizeof(bits_data);
2556 bits.cur_bit = 0;
2557
Pau Espin Pedrol5e300ce2020-02-03 17:18:03 +01002558 rc = decode_gsm_rlcmac_uplink(block, &ul_control_block);
2559 OSMO_ASSERT(rc == 0);
aravind sirsikarf2761382016-10-25 12:45:24 +05302560
2561 ack_nack = &ul_control_block.u.Egprs_Packet_Downlink_Ack_Nack;
2562
2563 OSMO_ASSERT(prlcmvb->is_unacked(1176));
2564 OSMO_ASSERT(prlcmvb->is_unacked(1177));
2565 OSMO_ASSERT(prlcmvb->is_unacked(1286));
2566 OSMO_ASSERT(prlcmvb->is_unacked(1287));
2567
2568 Decoding::decode_egprs_acknack_bits(
2569 &ack_nack->EGPRS_AckNack.Desc, &bits,
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002570 &bsn_begin, &bsn_end, prlcdlwindow);
aravind sirsikarf2761382016-10-25 12:45:24 +05302571
2572 dl_tbf->rcvd_dl_ack(
2573 ack_nack->EGPRS_AckNack.Desc.FINAL_ACK_INDICATION,
2574 bsn_begin, &bits);
aravind sirsikarf2761382016-10-25 12:45:24 +05302575
aravind sirsikarfb41afa2016-11-02 15:48:00 +05302576 OSMO_ASSERT(prlcmvb->is_invalid(1176));
2577 OSMO_ASSERT(prlcmvb->is_invalid(1177));
2578 OSMO_ASSERT(prlcmvb->is_acked(1286));
2579 OSMO_ASSERT(prlcmvb->is_acked(1287));
aravind sirsikarf2761382016-10-25 12:45:24 +05302580
2581 bitvec_free(block);
2582 tbf_free(dl_tbf);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002583 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002584 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikarf2761382016-10-25 12:45:24 +05302585}
2586
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302587static void test_tbf_egprs_two_phase_spb(void)
2588{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002589 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002590 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302591 int ts_no = 7;
2592 uint32_t fn = 2654218;
2593 uint16_t qta = 31;
2594 uint32_t tlli = 0xf1223344;
2595 const char *imsi = "0011223344";
2596 uint8_t ms_class = 1;
2597 uint8_t egprs_ms_class = 1;
2598 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302599 uint8_t test_data[256];
2600
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002601 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302602
2603 memset(test_data, 1, sizeof(test_data));
2604
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002605 setup_bts(bts, ts_no, 4);
2606 bts->initial_mcs_dl = 9;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302607
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002608 ul_tbf = establish_ul_tbf_two_phase_spb(bts, ts_no, tlli, &fn, qta,
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302609 ms_class, egprs_ms_class);
2610
Max4c112dc2018-02-01 16:49:23 +01002611 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002612 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302613
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002614 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002615 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302616}
2617
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002618static void test_tbf_egprs_two_phase()
2619{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002620 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002621 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002622 int ts_no = 7;
2623 uint32_t fn = 2654218;
2624 uint16_t qta = 31;
2625 uint32_t tlli = 0xf1223344;
2626 const char *imsi = "0011223344";
2627 uint8_t ms_class = 1;
2628 uint8_t egprs_ms_class = 1;
2629 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002630 uint8_t test_data[256];
2631
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002632 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002633
2634 memset(test_data, 1, sizeof(test_data));
2635
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002636 setup_bts(bts, ts_no, 4);
2637 bts->initial_mcs_dl = 9;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002638
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002639 ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002640 ms_class, egprs_ms_class);
2641
Max4c112dc2018-02-01 16:49:23 +01002642 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002643 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002644
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002645 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002646 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002647}
2648
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002649static void establish_and_use_egprs_dl_tbf(struct gprs_rlcmac_bts *bts, int mcs)
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002650{
2651 unsigned i;
2652 uint8_t ms_class = 11;
2653 uint8_t egprs_ms_class = 11;
2654 uint32_t fn = 0;
2655 uint8_t trx_no;
2656 uint32_t tlli = 0xffeeddcc;
2657 uint8_t test_data[512];
2658
2659 uint8_t rbb[64/8];
2660
2661 gprs_rlcmac_dl_tbf *dl_tbf;
2662
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002663 fprintf(stderr, "Testing MCS-%d\n", mcs);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002664
2665 memset(test_data, 1, sizeof(test_data));
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002666 bts->initial_mcs_dl = mcs;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002667
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002668 dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002669 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
2670
2671 for (i = 0; i < sizeof(llc_data); i++)
2672 llc_data[i] = i%256;
2673
2674 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2675
2676 /* Schedule a small LLC frame */
Pau Espin Pedrol758ace82020-10-28 19:58:17 +01002677 dl_tbf->append_data(1000, test_data, 10);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002678
2679 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2680
2681 /* Drain the queue */
2682 while (dl_tbf->have_data())
2683 /* Request to send one RLC/MAC block */
2684 request_dl_rlc_block(dl_tbf, &fn);
2685
2686 /* Schedule a large LLC frame */
Pau Espin Pedrol758ace82020-10-28 19:58:17 +01002687 dl_tbf->append_data(1000, test_data, sizeof(test_data));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002688
2689 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2690
2691 /* Drain the queue */
2692 while (dl_tbf->have_data())
2693 /* Request to send one RLC/MAC block */
2694 request_dl_rlc_block(dl_tbf, &fn);
2695
2696 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2697
Max7d32f552017-12-15 11:25:14 +01002698 RCV_ACK(true, dl_tbf, rbb); /* Receive a final ACK */
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002699
2700 /* Clean up and ensure tbfs are in the correct state */
2701 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
Max0e599802018-01-23 20:09:06 +01002702 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_NONE);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002703 check_tbf(dl_tbf);
2704 tbf_free(dl_tbf);
2705}
2706
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002707static gprs_rlcmac_dl_tbf *tbf_init(struct gprs_rlcmac_bts *bts,
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302708 int mcs)
2709{
2710 unsigned i;
2711 uint8_t ms_class = 11;
2712 uint8_t egprs_ms_class = 11;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302713 uint8_t trx_no;
2714 uint32_t tlli = 0xffeeddcc;
2715 uint8_t test_data[512];
2716
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302717 gprs_rlcmac_dl_tbf *dl_tbf;
2718
2719 memset(test_data, 1, sizeof(test_data));
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002720 bts->initial_mcs_dl = mcs;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302721
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002722 dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302723 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
2724
2725 for (i = 0; i < sizeof(test_data); i++)
2726 test_data[i] = i%256;
2727
2728 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2729
2730 /* Schedule a LLC frame
2731 * passing only 100 bytes, since it is enough to construct
2732 * 2 RLC data blocks. Which are enough to test Header Type 1
2733 * cases
2734 */
Pau Espin Pedrol758ace82020-10-28 19:58:17 +01002735 dl_tbf->append_data(1000, test_data, 100);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302736
2737 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2738
2739 return dl_tbf;
2740
2741}
2742
2743static void tbf_cleanup(gprs_rlcmac_dl_tbf *dl_tbf)
2744{
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302745 uint8_t rbb[64/8];
2746
Max7d32f552017-12-15 11:25:14 +01002747 RCV_ACK(true, dl_tbf, rbb); /* Receive a final ACK */
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302748
2749 /* Clean up and ensure tbfs are in the correct state */
2750 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
Max0e599802018-01-23 20:09:06 +01002751 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_NONE);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302752 check_tbf(dl_tbf);
2753 tbf_free(dl_tbf);
2754
2755}
2756
Max7d32f552017-12-15 11:25:14 +01002757#define NACK(tbf, x) do { \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002758 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
2759 w->m_v_b.mark_nacked(x); \
2760 OSMO_ASSERT(w->m_v_b.is_nacked(x)); \
Max7d32f552017-12-15 11:25:14 +01002761 } while(0)
2762
2763#define CHECK_UNACKED(tbf, cs, bsn) do { \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002764 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
2765 OSMO_ASSERT(w->m_v_b.is_unacked(bsn)); \
Max898dddb2019-03-12 15:50:57 +01002766 OSMO_ASSERT(mcs_chan_code(tbf->m_rlc.block(bsn)->cs_current_trans) == cs - 1); \
Max7d32f552017-12-15 11:25:14 +01002767 } while(0)
2768
2769#define CHECK_NACKED(tbf, cs, bsn) do { \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002770 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
2771 OSMO_ASSERT(w->m_v_b.is_nacked(bsn)); \
Max898dddb2019-03-12 15:50:57 +01002772 OSMO_ASSERT(mcs_chan_code(tbf->m_rlc.block(bsn)->cs_current_trans) == cs - 1); \
Max7d32f552017-12-15 11:25:14 +01002773 } while(0)
2774
2775#define MAKE_ACKED(m, tbf, fn, cs, check_unacked) do { \
2776 m = tbf->create_dl_acked_block(fn, tbf->control_ts); \
2777 OSMO_ASSERT(m); \
2778 if (check_unacked) \
2779 CHECK_UNACKED(tbf, cs, 0); \
2780 else \
2781 CHECK_NACKED(tbf, cs, 0); \
2782 } while(0)
2783
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002784static void egprs_spb_to_normal_validation(struct gprs_rlcmac_bts *bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002785 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302786{
2787 uint32_t fn = 0;
2788 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302789 uint16_t bsn1, bsn2, bsn3;
2790 struct msgb *msg;
2791 struct gprs_rlc_dl_header_egprs_3 *egprs3;
2792 struct gprs_rlc_dl_header_egprs_2 *egprs2;
2793
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002794 fprintf(stderr, "Testing retx for MCS %u to reseg_mcs %u\n", mcs, demanded_mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302795
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002796 dl_tbf = tbf_init(bts, mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302797
2798 /*
2799 * Table 10.4.8a.3.1 of 44.060.
2800 * (MCS7, MCS9) to (MCS2, MCS3) is not handled since it is same as
2801 * (MCS5, MCS6) to (MCS2, MCS3) transition
2802 */
2803 if (!(mcs == 6 && demanded_mcs == 3))
2804 return;
2805
2806 fn = fn_add_blocks(fn, 1);
2807 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01002808 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302809
2810 egprs2 = (struct gprs_rlc_dl_header_egprs_2 *) msg->data;
Maxb4d368b2017-12-01 17:54:39 +01002811 bsn1 = (egprs2->bsn1_hi << 9) | (egprs2->bsn1_mid << 1) | (egprs2->bsn1_lo);
Max7d32f552017-12-15 11:25:14 +01002812
2813 NACK(dl_tbf, 0);
2814
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302815 OSMO_ASSERT(bsn1 == 0);
2816
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002817 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302818
2819 fn = fn_add_blocks(fn, 1);
2820
2821 /* Send first segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002822 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, false);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302823 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2824 == EGPRS_RESEG_FIRST_SEG_SENT);
2825
2826 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2827 OSMO_ASSERT(egprs3->spb == 2);
2828
2829 /* Table 10.4.8a.3.1 of 44.060 */
2830 OSMO_ASSERT(egprs3->cps == 3);
2831
2832 /* Send second segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002833 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302834 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2835 == EGPRS_RESEG_SECOND_SEG_SENT);
2836
2837 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2838 /* Table 10.4.8a.3.1 of 44.060 */
2839 OSMO_ASSERT(egprs3->spb == 3);
Maxb4d368b2017-12-01 17:54:39 +01002840 bsn2 = (egprs3->bsn1_hi << 9) | (egprs3->bsn1_mid << 1) | (egprs3->bsn1_lo);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302841 OSMO_ASSERT(bsn2 == bsn1);
2842
2843 /* Table 10.4.8a.3.1 of 44.060 */
2844 OSMO_ASSERT(egprs3->cps == 3);
2845
2846 /* Handle (MCS3, MCS3) -> MCS6 case */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002847 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302848
Max7d32f552017-12-15 11:25:14 +01002849 NACK(dl_tbf, 0);
2850
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302851 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
2852 egprs2 = (struct gprs_rlc_dl_header_egprs_2 *) msg->data;
2853
2854 /* Table 10.4.8a.3.1 of 44.060 */
2855 OSMO_ASSERT(egprs2->cps == 0);
Maxb4d368b2017-12-01 17:54:39 +01002856 bsn3 = (egprs2->bsn1_hi << 9) | (egprs2->bsn1_mid << 1) | (egprs2->bsn1_lo);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302857 OSMO_ASSERT(bsn3 == bsn2);
2858
2859 tbf_cleanup(dl_tbf);
2860}
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002861
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002862static void establish_and_use_egprs_dl_tbf_for_spb(struct gprs_rlcmac_bts *bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002863 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302864{
2865 uint32_t fn = 0;
2866 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302867 struct msgb *msg;
2868 struct gprs_rlc_dl_header_egprs_3 *egprs3;
2869
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002870 fprintf(stderr, "Testing retx for MCS %u to reseg_mcs %u\n", mcs, demanded_mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302871
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002872 dl_tbf = tbf_init(bts, mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302873
2874 /*
2875 * Table 10.4.8a.3.1 of 44.060.
2876 * (MCS7, MCS9) to (MCS2, MCS3) is not handled since it is same as
2877 * (MCS5, MCS6) to (MCS2, MCS3) transition
2878 */
2879 /* TODO: Need to support of MCS8 -> MCS6 ->MCS3 transistion
2880 * Refer commit be881c028fc4da00c4046ecd9296727975c206a3
2881 * dated 2016-02-07 23:45:40 (UTC)
2882 */
2883 if (!(((mcs == 5) && (demanded_mcs == 2)) ||
2884 ((mcs == 6) && (demanded_mcs == 3)) ||
2885 ((mcs == 4) && (demanded_mcs == 1))))
2886 return;
2887
2888 fn = fn_add_blocks(fn, 1);
2889 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01002890 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302891
Max7d32f552017-12-15 11:25:14 +01002892 NACK(dl_tbf, 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302893
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002894 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302895
2896 fn = fn_add_blocks(fn, 1);
2897
2898 /* Send first segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002899 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, false);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302900 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2901 == EGPRS_RESEG_FIRST_SEG_SENT);
2902
2903 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2904 OSMO_ASSERT(egprs3->spb == 2);
2905
2906 /* Table 10.4.8a.3.1 of 44.060 */
2907 switch (demanded_mcs) {
2908 case 3:
2909 OSMO_ASSERT(egprs3->cps == 3);
2910 break;
2911 case 2:
2912 OSMO_ASSERT(egprs3->cps == 9);
2913 break;
2914 case 1:
2915 OSMO_ASSERT(egprs3->cps == 11);
2916 break;
2917 default:
2918 OSMO_ASSERT(false);
2919 break;
2920 }
2921
2922 /* Send second segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002923 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302924 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2925 == EGPRS_RESEG_SECOND_SEG_SENT);
2926
2927 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2928 /* Table 10.4.8a.3.1 of 44.060 */
2929 OSMO_ASSERT(egprs3->spb == 3);
2930
2931 /* Table 10.4.8a.3.1 of 44.060 */
2932 switch (demanded_mcs) {
2933 case 3:
2934 OSMO_ASSERT(egprs3->cps == 3);
2935 break;
2936 case 2:
2937 OSMO_ASSERT(egprs3->cps == 9);
2938 break;
2939 case 1:
2940 OSMO_ASSERT(egprs3->cps == 11);
2941 break;
2942 default:
2943 OSMO_ASSERT(false);
2944 break;
2945 }
2946 tbf_cleanup(dl_tbf);
2947}
2948
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002949static void establish_and_use_egprs_dl_tbf_for_retx(struct gprs_rlcmac_bts *bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002950 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302951{
2952 uint32_t fn = 0;
2953 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302954 struct msgb *msg;
2955
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002956 fprintf(stderr, "Testing retx for MCS %u - %u\n", mcs, demanded_mcs);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302957
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002958 dl_tbf = tbf_init(bts, mcs);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302959
2960 /* For MCS reduction cases like MCS9->MCS6, MCS7->MCS5
2961 * The MCS transition are referred from table Table 8.1.1.2
2962 * of TS 44.060
2963 */
2964 /* TODO: Need to support of MCS8 -> MCS6 transistion
2965 * Refer commit be881c028fc4da00c4046ecd9296727975c206a3
2966 * dated 2016-02-07 23:45:40 (UTC)
2967 */
2968 if (((mcs == 9) && (demanded_mcs < 9)) ||
2969 ((mcs == 7) && (demanded_mcs < 7))) {
2970 fn = fn_add_blocks(fn, 1);
2971 /* Send 2 RLC data block */
Max7d32f552017-12-15 11:25:14 +01002972 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
2973 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302974
Max7d32f552017-12-15 11:25:14 +01002975 NACK(dl_tbf, 0);
2976 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302977
2978 /* Set the demanded MCS to demanded_mcs */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002979 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302980
2981 fn = fn_add_blocks(fn, 1);
2982 /* Retransmit the first RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002983 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
2984 CHECK_NACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302985
2986 fn = fn_add_blocks(fn, 1);
2987 /* Retransmit the second RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002988 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
2989 CHECK_UNACKED(dl_tbf, demanded_mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302990 } else if (((mcs == 5) && (demanded_mcs > 6)) ||
2991 ((mcs == 6) && (demanded_mcs > 8))) {
2992 fn = fn_add_blocks(fn, 1);
2993 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01002994 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302995
2996 fn = fn_add_blocks(fn, 1);
2997 /* Send second RLC data block BSN 1 */
Max7d32f552017-12-15 11:25:14 +01002998 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
2999 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303000
Max7d32f552017-12-15 11:25:14 +01003001 NACK(dl_tbf, 0);
3002 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303003
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003004 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303005
3006 fn = fn_add_blocks(fn, 1);
3007 /* Send first, second RLC data blocks with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003008 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
3009 CHECK_UNACKED(dl_tbf, demanded_mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303010 } else if (mcs > 6) {
3011 /* No Mcs change cases are handled here for mcs > MCS6*/
3012 fn = fn_add_blocks(fn, 1);
3013 /* Send first,second RLC data blocks */
Max7d32f552017-12-15 11:25:14 +01003014 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3015 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303016
Max7d32f552017-12-15 11:25:14 +01003017 NACK(dl_tbf, 0);
3018 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303019
3020 fn = fn_add_blocks(fn, 1);
3021 /* Send first,second RLC data blocks with demanded_mcs*/
Max7d32f552017-12-15 11:25:14 +01003022 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3023 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303024 } else {
3025
3026 /* No MCS change cases are handled here for mcs <= MCS6*/
3027 fn = fn_add_blocks(fn, 1);
3028 /* Send first RLC data block */
Max7d32f552017-12-15 11:25:14 +01003029 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303030
Max7d32f552017-12-15 11:25:14 +01003031 NACK(dl_tbf, 0);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303032
3033 fn = fn_add_blocks(fn, 1);
3034 /* Send first RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003035 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303036 }
3037
3038 tbf_cleanup(dl_tbf);
3039}
3040
3041static void test_tbf_egprs_retx_dl(void)
3042{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003043 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003044 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303045 uint8_t ts_no = 4;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303046
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003047 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303048
Pau Espin Pedrolad79b852021-01-14 13:20:55 +01003049 the_pcu->vty.cs_downgrade_threshold = 0;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003050 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01003051 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303052 /* ARQ II */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01003053 the_pcu->vty.dl_arq_type = EGPRS_ARQ2;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303054
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303055
3056 /* First parameter is current MCS, second one is demanded_mcs */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003057 establish_and_use_egprs_dl_tbf_for_retx(bts, 6, 6);
3058 establish_and_use_egprs_dl_tbf_for_retx(bts, 1, 9);
3059 establish_and_use_egprs_dl_tbf_for_retx(bts, 2, 8);
3060 establish_and_use_egprs_dl_tbf_for_retx(bts, 5, 7);
3061 establish_and_use_egprs_dl_tbf_for_retx(bts, 6, 9);
3062 establish_and_use_egprs_dl_tbf_for_retx(bts, 7, 5);
3063 establish_and_use_egprs_dl_tbf_for_retx(bts, 9, 6);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303064
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003065 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003066 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303067}
3068
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303069static void test_tbf_egprs_spb_dl(void)
3070{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003071 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003072 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303073 uint8_t ts_no = 4;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303074
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003075 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303076
Pau Espin Pedrolad79b852021-01-14 13:20:55 +01003077 the_pcu->vty.cs_downgrade_threshold = 0;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003078 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01003079 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303080
3081 /* ARQ I resegmentation support */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01003082 the_pcu->vty.dl_arq_type = EGPRS_ARQ1;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303083
3084 /*
3085 * First parameter is current MCS, second one is demanded_mcs
3086 * currently only MCS5->MCS2, MCS6->3, MCS4->MCS1 is tested in UT
3087 * rest scenarios has been integration tested
3088 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003089 establish_and_use_egprs_dl_tbf_for_spb(bts, 6, 3);
3090 establish_and_use_egprs_dl_tbf_for_spb(bts, 5, 2);
3091 establish_and_use_egprs_dl_tbf_for_spb(bts, 4, 1);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303092 /* check MCS6->(MCS3+MCS3)->MCS6 case */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003093 egprs_spb_to_normal_validation(bts, 6, 3);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303094
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003095 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003096 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303097}
3098
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003099static void test_tbf_egprs_dl()
3100{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003101 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003102 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003103 uint8_t ts_no = 4;
3104 int i;
3105
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003106 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003107
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003108 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01003109 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303110 /* ARQ II */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01003111 the_pcu->vty.dl_arq_type = EGPRS_ARQ2;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003112
3113 for (i = 1; i <= 9; i++)
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003114 establish_and_use_egprs_dl_tbf(bts, i);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003115
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003116 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003117 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003118}
3119
3120
3121
aravind sirsikare9a138e2017-01-24 12:36:08 +05303122static void test_packet_access_rej_prr_no_other_tbfs()
3123{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003124 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003125 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303126 uint32_t fn = 2654218;
3127 int ts_no = 7;
3128 uint8_t trx_no = 0;
3129 uint32_t tlli = 0xffeeddcc;
3130 struct gprs_rlcmac_ul_tbf *ul_tbf = NULL;
3131
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003132 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303133
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003134 setup_bts(bts, ts_no, 4);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303135
3136 int rc = 0;
3137
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003138 ul_tbf = handle_tbf_reject(bts, NULL, tlli,
aravind sirsikare9a138e2017-01-24 12:36:08 +05303139 trx_no, ts_no);
3140
3141 OSMO_ASSERT(ul_tbf != 0);
3142
3143 /* trigger packet access reject */
3144 uint8_t bn = fn2bn(fn);
3145
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003146 rc = gprs_rlcmac_rcv_rts_block(bts,
aravind sirsikare9a138e2017-01-24 12:36:08 +05303147 trx_no, ts_no, fn, bn);
3148
3149 OSMO_ASSERT(rc == 0);
3150
3151 ul_tbf->handle_timeout();
3152
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003153 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003154 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303155}
3156
3157static void test_packet_access_rej_prr()
3158{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003159 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003160 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303161 uint32_t fn = 2654218;
3162 uint16_t qta = 31;
3163 int ts_no = 7;
3164 uint8_t trx_no = 0;
3165 RlcMacUplink_t ulreq = {0};
3166 Packet_Resource_Request_t *presreq = NULL;
3167 uint8_t ms_class = 11;
3168 uint8_t egprs_ms_class = 11;
3169 uint32_t rach_fn = fn - 51;
3170 uint32_t sba_fn = fn + 52;
3171 uint32_t tlli = 0xffeeddcc;
3172 MS_Radio_Access_capability_t *pmsradiocap = NULL;
3173 Multislot_capability_t *pmultislotcap = NULL;
3174
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003175 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303176
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003177 setup_bts(bts, ts_no, 4);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303178
3179 int rc = 0;
3180
3181 /*
3182 * Trigger rach till resources(USF) exhaust
3183 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003184 rc = bts_handle_rach(bts, 0x78, rach_fn, qta);
3185 rc = bts_handle_rach(bts, 0x79, rach_fn, qta);
3186 rc = bts_handle_rach(bts, 0x7a, rach_fn, qta);
3187 rc = bts_handle_rach(bts, 0x7b, rach_fn, qta);
3188 rc = bts_handle_rach(bts, 0x7c, rach_fn, qta);
3189 rc = bts_handle_rach(bts, 0x7d, rach_fn, qta);
3190 rc = bts_handle_rach(bts, 0x7e, rach_fn, qta);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303191
3192 /* fake a resource request */
3193 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
3194 presreq = &ulreq.u.Packet_Resource_Request;
3195 presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
3196 presreq->ID.UnionType = 1; /* != 0 */
3197 presreq->ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01003198 presreq->Exist_MS_Radio_Access_capability2 = 1;
3199 pmsradiocap = &presreq->MS_Radio_Access_capability2;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303200 pmsradiocap->Count_MS_RA_capability_value = 1;
3201 pmsradiocap->MS_RA_capability_value[0].u.Content.
3202 Exist_Multislot_capability = 1;
3203 pmultislotcap = &pmsradiocap->MS_RA_capability_value[0].
3204 u.Content.Multislot_capability;
3205
3206 pmultislotcap->Exist_GPRS_multislot_class = 1;
3207 pmultislotcap->GPRS_multislot_class = ms_class;
3208 if (egprs_ms_class) {
3209 pmultislotcap->Exist_EGPRS_multislot_class = 1;
3210 pmultislotcap->EGPRS_multislot_class = egprs_ms_class;
3211 }
3212
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003213 send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303214
3215 /* trigger packet access reject */
3216 uint8_t bn = fn2bn(fn);
3217
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003218 rc = gprs_rlcmac_rcv_rts_block(bts,
aravind sirsikare9a138e2017-01-24 12:36:08 +05303219 trx_no, ts_no, fn, bn);
3220
3221 OSMO_ASSERT(rc == 0);
3222
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003223 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003224 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303225}
3226
aravind sirsikared3413e2016-11-11 17:15:10 +05303227void test_packet_access_rej_epdan()
3228{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003229 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003230 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
aravind sirsikared3413e2016-11-11 17:15:10 +05303231 uint32_t tlli = 0xffeeddcc;
Maxd3a0d912019-03-05 16:15:01 +01003232 static uint8_t exp[] = { 0x40, 0x84, 0x7f, 0xf7, 0x6e, 0xe6, 0x41, 0x4b,
3233 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
3234 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b
3235 };
aravind sirsikared3413e2016-11-11 17:15:10 +05303236
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003237 fprintf(stderr, "=== start %s ===\n", __func__);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003238 setup_bts(bts, 4);
3239 static gprs_rlcmac_dl_tbf *dl_tbf = tbf_init(bts, 1);
aravind sirsikared3413e2016-11-11 17:15:10 +05303240
3241 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
3242
3243 struct msgb *msg = dl_tbf->create_packet_access_reject();
3244
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003245 fprintf(stderr, "packet reject: %s\n",
aravind sirsikared3413e2016-11-11 17:15:10 +05303246 osmo_hexdump(msg->data, 23));
3247
Maxd3a0d912019-03-05 16:15:01 +01003248 if (!msgb_eq_data_print(msg, exp, GSM_MACBLOCK_LEN))
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003249 fprintf(stderr, "%s test failed!\n", __func__);
Maxd3a0d912019-03-05 16:15:01 +01003250
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003251 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003252 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikared3413e2016-11-11 17:15:10 +05303253}
3254
3255
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003256int main(int argc, char **argv)
3257{
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003258 struct vty_app_info pcu_vty_info = {0};
3259
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003260 tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile TbfTest context");
3261 if (!tall_pcu_ctx)
3262 abort();
3263
Neels Hofmeyr78ce5912017-02-08 17:07:31 +01003264 msgb_talloc_ctx_init(tall_pcu_ctx, 0);
Neels Hofmeyr42f2d612018-04-01 16:54:40 +02003265 osmo_init_logging2(tall_pcu_ctx, &gprs_log_info);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003266 log_set_use_color(osmo_stderr_target, 0);
Pau Espin Pedrol00f52cc2021-02-19 14:01:52 +01003267 log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
Pau Espin Pedrolb18d2a52021-02-19 14:00:48 +01003268 log_set_print_category(osmo_stderr_target, 0);
3269 log_set_print_category_hex(osmo_stderr_target, 0);
Maxfdd79e92018-01-24 11:04:59 +01003270 log_parse_category_mask(osmo_stderr_target, "DRLCMAC,1:DRLCMACDATA,3:DRLCMACDL,3:DRLCMACUL,3:"
Harald Welte398f60e2020-12-10 13:39:21 +01003271 "DRLCMACSCHED,1:DRLCMACMEAS,3:DNS,3:DLBSSGP,3:DPCU,5:"
Max86e35e42019-03-07 12:20:42 +01003272 "DL1IF,6:DTBF,1:DTBFUL,1:DTBFDL,1:DLGLOBAL,2:");
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003273 vty_init(&pcu_vty_info);
Pau Espin Pedrolcd2ac562019-08-05 14:30:44 +02003274 pcu_vty_init();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003275
Vadim Yanitskiy87b6e7d2019-11-08 04:44:04 +07003276 /* Initialize shared UL measurements */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003277 pcu_l1_meas_set_link_qual(&meas, 12);
3278 pcu_l1_meas_set_rssi(&meas, 31);
Vadim Yanitskiy87b6e7d2019-11-08 04:44:04 +07003279
Jacob Erlbeckac89a552015-06-29 14:18:46 +02003280 test_tbf_base();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003281 test_tbf_tlli_update();
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +01003282 test_tbf_final_ack(TEST_MODE_STANDARD);
3283 test_tbf_final_ack(TEST_MODE_REVERSE_FREE);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +01003284 test_tbf_delayed_release();
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +02003285 test_tbf_imsi();
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003286 test_tbf_exhaustion();
Jacob Erlbeck41168642015-06-12 13:41:00 +02003287 test_tbf_dl_llc_loss();
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02003288 test_tbf_single_phase();
3289 test_tbf_two_phase();
Jacob Erlbeckb1395982015-08-21 18:15:38 +02003290 test_tbf_ra_update_rach();
3291 test_tbf_dl_flow_and_rach_two_phase();
3292 test_tbf_dl_flow_and_rach_single_phase();
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02003293 test_tbf_dl_reuse();
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01003294 test_tbf_gprs_egprs();
Jacob Erlbeck36df7742016-01-19 15:53:30 +01003295 test_tbf_ws();
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003296 test_tbf_egprs_two_phase();
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05303297 test_tbf_egprs_two_phase_spb();
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003298 test_tbf_egprs_dl();
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303299 test_tbf_egprs_retx_dl();
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303300 test_tbf_egprs_spb_dl();
Aravind Sirsikar02352b42016-08-25 16:37:30 +05303301 test_tbf_puan_urbb_len();
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05303302 test_tbf_update_ws();
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05303303 test_tbf_li_decoding();
aravind sirsikarf2761382016-10-25 12:45:24 +05303304 test_tbf_epdan_out_of_rx_window();
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05303305 test_immediate_assign_rej();
sivasankari1d8744c2017-01-24 15:53:35 +05303306 test_tbf_egprs_two_phase_puan();
aravind sirsikared3413e2016-11-11 17:15:10 +05303307 test_packet_access_rej_epdan();
aravind sirsikare9a138e2017-01-24 12:36:08 +05303308 test_packet_access_rej_prr();
3309 test_packet_access_rej_prr_no_other_tbfs();
Jacob Erlbeck67c38502015-05-11 10:32:40 +02003310
3311 if (getenv("TALLOC_REPORT_FULL"))
3312 talloc_report_full(tall_pcu_ctx, stderr);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003313 return EXIT_SUCCESS;
3314}
3315
3316/*
3317 * stubs that should not be reached
3318 */
3319extern "C" {
3320void l1if_pdch_req() { abort(); }
3321void l1if_connect_pdch() { abort(); }
3322void l1if_close_pdch() { abort(); }
3323void l1if_open_pdch() { abort(); }
3324}